idnits 2.17.00 (12 Aug 2021) /tmp/idnits12813/draft-ietf-suit-manifest-02.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 60 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 (November 04, 2019) is 928 days in the past. Is this intentional? Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) -- Looks like a reference, but probably isn't: '1' on line 3988 -- Looks like a reference, but probably isn't: '2' on line 3990 -- Looks like a reference, but probably isn't: '3' on line 3992 == Missing Reference: '-1' is mentioned on line 1747, but not defined == Missing Reference: '-2' is mentioned on line 1749, but not defined == Missing Reference: '-3' is mentioned on line 1753, but not defined -- Looks like a reference, but probably isn't: '4' on line 1753 == Outdated reference: draft-ietf-suit-architecture has been published as RFC 9019 == Outdated reference: draft-ietf-suit-information-model has been published as RFC 9124 Summary: 1 error (**), 0 flaws (~~), 7 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: Standards Track Arm Limited 5 Expires: May 7, 2020 H. Birkholz 6 Fraunhofer SIT 7 November 04, 2019 9 A Concise Binary Object Representation (CBOR)-based Serialization Format 10 for the Software Updates for Internet of Things (SUIT) Manifest 11 draft-ietf-suit-manifest-02 13 Abstract 15 This specification describes the format of a manifest. A manifest is 16 a bundle of metadata about the firmware for an IoT device, where to 17 find the firmware, the devices to which it applies, and cryptographic 18 information protecting the manifest. 20 Status of This Memo 22 This Internet-Draft is submitted in full conformance with the 23 provisions of BCP 78 and BCP 79. 25 Internet-Drafts are working documents of the Internet Engineering 26 Task Force (IETF). Note that other groups may also distribute 27 working documents as Internet-Drafts. The list of current Internet- 28 Drafts is at https://datatracker.ietf.org/drafts/current/. 30 Internet-Drafts are draft documents valid for a maximum of six months 31 and may be updated, replaced, or obsoleted by other documents at any 32 time. It is inappropriate to use Internet-Drafts as reference 33 material or to cite them other than as "work in progress." 35 This Internet-Draft will expire on May 7, 2020. 37 Copyright Notice 39 Copyright (c) 2019 IETF Trust and the persons identified as the 40 document authors. All rights reserved. 42 This document is subject to BCP 78 and the IETF Trust's Legal 43 Provisions Relating to IETF Documents 44 (https://trustee.ietf.org/license-info) in effect on the date of 45 publication of this document. Please review these documents 46 carefully, as they describe your rights and restrictions with respect 47 to this document. Code Components extracted from this document must 48 include Simplified BSD License text as described in Section 4.e of 49 the Trust Legal Provisions and are provided without warranty as 50 described in the Simplified BSD License. 52 This document may contain material from IETF Documents or IETF 53 Contributions published or made publicly available before November 54 10, 2008. The person(s) controlling the copyright in some of this 55 material may not have granted the IETF Trust the right to allow 56 modifications of such material outside the IETF Standards Process. 57 Without obtaining an adequate license from the person(s) controlling 58 the copyright in such materials, this document may not be modified 59 outside the IETF Standards Process, and derivative works of it may 60 not be created outside the IETF Standards Process, except to format 61 it for publication as an RFC or to translate it into languages other 62 than English. 64 Table of Contents 66 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4 67 2. Conventions and Terminology . . . . . . . . . . . . . . . . . 5 68 3. How to use this document . . . . . . . . . . . . . . . . . . 6 69 4. Background . . . . . . . . . . . . . . . . . . . . . . . . . 6 70 4.1. Landscape . . . . . . . . . . . . . . . . . . . . . . . . 6 71 4.2. Update Workflow Model . . . . . . . . . . . . . . . . . . 7 72 4.3. SUIT Manifest goals . . . . . . . . . . . . . . . . . . . 8 73 4.4. SUIT manifest design summary . . . . . . . . . . . . . . 9 74 5. Interpreter Behaviour . . . . . . . . . . . . . . . . . . . . 10 75 5.1. Interpreter Setup . . . . . . . . . . . . . . . . . . . . 10 76 5.2. Required Checks . . . . . . . . . . . . . . . . . . . . . 11 77 5.3. Interpreter fundamental properties . . . . . . . . . . . 12 78 5.4. Abstract Machine Description . . . . . . . . . . . . . . 12 79 5.4.1. Parameters . . . . . . . . . . . . . . . . . . . . . 13 80 5.4.2. Commands . . . . . . . . . . . . . . . . . . . . . . 13 81 5.4.3. Command Behaviour . . . . . . . . . . . . . . . . . . 15 82 5.5. Serialized Processing Interpreter . . . . . . . . . . . . 16 83 5.6. Parallel Processing Interpreter . . . . . . . . . . . . . 16 84 5.7. Processing Dependencies . . . . . . . . . . . . . . . . . 17 85 6. Creating Manifests . . . . . . . . . . . . . . . . . . . . . 17 86 6.1. Manifest Source Material . . . . . . . . . . . . . . . . 18 87 6.2. Required Template: Compatibility Check . . . . . . . . . 18 88 6.3. Use Case Template: XIP Secure Boot . . . . . . . . . . . 19 89 6.4. Use Case Template: Firmware Download . . . . . . . . . . 19 90 6.5. Use Case Template: Load from External Storage . . . . . . 20 91 6.6. Use Case Template Load & Decompress from External Storage 20 92 6.7. Use Case Template: Dependency . . . . . . . . . . . . . . 20 93 7. Manifest Structure . . . . . . . . . . . . . . . . . . . . . 21 94 7.1. Severable Elements . . . . . . . . . . . . . . . . . . . 22 95 7.2. Outer wrapper . . . . . . . . . . . . . . . . . . . . . . 23 96 7.3. Manifest . . . . . . . . . . . . . . . . . . . . . . . . 24 97 7.4. SUIT_Dependency . . . . . . . . . . . . . . . . . . . . . 27 98 7.5. SUIT_Component_Reference . . . . . . . . . . . . . . . . 28 99 7.6. Manifest Parameters . . . . . . . . . . . . . . . . . . . 28 100 7.6.1. SUIT_Parameter_Strict_Order . . . . . . . . . . . . . 30 101 7.6.2. SUIT_Parameter_Soft_Failure . . . . . . . . . . . . . 31 102 7.7. SUIT_Parameter_Encryption_Info . . . . . . . . . . . . . 31 103 7.8. SUIT_Parameter_Compression_Info . . . . . . . . . . . . . 31 104 7.9. SUIT_Parameter_Unpack_Info . . . . . . . . . . . . . . . 31 105 7.10. SUIT_Parameters CDDL . . . . . . . . . . . . . . . . . . 32 106 7.11. SUIT_Command_Sequence . . . . . . . . . . . . . . . . . . 33 107 7.12. SUIT_Condition . . . . . . . . . . . . . . . . . . . . . 35 108 7.12.1. Identifier Conditions . . . . . . . . . . . . . . . 36 109 7.12.2. suit-condition-image-match . . . . . . . . . . . . . 36 110 7.12.3. suit-condition-image-not-match . . . . . . . . . . . 36 111 7.12.4. suit-condition-use-before . . . . . . . . . . . . . 36 112 7.12.5. suit-condition-minimum-battery . . . . . . . . . . . 36 113 7.12.6. suit-condition-update-authorised . . . . . . . . . . 37 114 7.12.7. suit-condition-version . . . . . . . . . . . . . . . 37 115 7.12.8. SUIT_Condition_Custom . . . . . . . . . . . . . . . 38 116 7.12.9. Identifiers . . . . . . . . . . . . . . . . . . . . 38 117 7.12.10. SUIT_Condition CDDL . . . . . . . . . . . . . . . . 40 118 7.13. SUIT_Directive . . . . . . . . . . . . . . . . . . . . . 40 119 7.13.1. suit-directive-set-component-index . . . . . . . . . 41 120 7.13.2. suit-directive-set-dependency-index . . . . . . . . 42 121 7.13.3. suit-directive-abort . . . . . . . . . . . . . . . . 42 122 7.13.4. suit-directive-run-sequence . . . . . . . . . . . . 42 123 7.13.5. suit-directive-try-each . . . . . . . . . . . . . . 43 124 7.13.6. suit-directive-process-dependency . . . . . . . . . 43 125 7.13.7. suit-directive-set-parameters . . . . . . . . . . . 44 126 7.13.8. suit-directive-override-parameters . . . . . . . . . 44 127 7.13.9. suit-directive-fetch . . . . . . . . . . . . . . . . 45 128 7.13.10. suit-directive-copy . . . . . . . . . . . . . . . . 45 129 7.13.11. suit-directive-swap . . . . . . . . . . . . . . . . 46 130 7.13.12. suit-directive-run . . . . . . . . . . . . . . . . . 46 131 7.13.13. suit-directive-wait . . . . . . . . . . . . . . . . 47 132 7.13.14. SUIT_Directive CDDL . . . . . . . . . . . . . . . . 48 133 7.14. SUIT_Text_Map . . . . . . . . . . . . . . . . . . . . . . 50 134 8. Access Control Lists . . . . . . . . . . . . . . . . . . . . 50 135 9. SUIT digest container . . . . . . . . . . . . . . . . . . . . 51 136 10. Creating conditional sequences . . . . . . . . . . . . . . . 52 137 11. Full CDDL . . . . . . . . . . . . . . . . . . . . . . . . . . 54 138 12. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . 61 139 12.1. Example 0: . . . . . . . . . . . . . . . . . . . . . . . 61 140 12.2. Example 1: . . . . . . . . . . . . . . . . . . . . . . . 64 141 12.3. Example 2: . . . . . . . . . . . . . . . . . . . . . . . 66 142 12.4. Example 3: . . . . . . . . . . . . . . . . . . . . . . . 69 143 12.5. Example 4: . . . . . . . . . . . . . . . . . . . . . . . 73 144 12.6. Example 5: . . . . . . . . . . . . . . . . . . . . . . . 77 145 12.7. Example 6: . . . . . . . . . . . . . . . . . . . . . . . 81 146 13. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 86 147 14. Security Considerations . . . . . . . . . . . . . . . . . . . 86 148 15. Mailing List Information . . . . . . . . . . . . . . . . . . 86 149 16. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 86 150 17. References . . . . . . . . . . . . . . . . . . . . . . . . . 87 151 17.1. Normative References . . . . . . . . . . . . . . . . . . 87 152 17.2. Informative References . . . . . . . . . . . . . . . . . 87 153 17.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 88 154 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 88 156 1. Introduction 158 A firmware update mechanism is an essential security feature for IoT 159 devices to deal with vulnerabilities. While the transport of 160 firmware images to the devices themselves is important there are 161 already various techniques available, such as the Lightweight 162 Machine-to-Machine (LwM2M) protocol offering device management of IoT 163 devices. Equally important is the inclusion of meta-data about the 164 conveyed firmware image (in the form of a manifest) and the use of 165 end-to-end security protection to detect modifications and 166 (optionally) to make reverse engineering more difficult. End-to-end 167 security allows the author, who builds the firmware image, to be sure 168 that no other party (including potential adversaries) can install 169 firmware updates on IoT devices without adequate privileges. This 170 authorization process is ensured by the use of dedicated symmetric or 171 asymmetric keys installed on the IoT device: for use cases where only 172 integrity protection is required it is sufficient to install a trust 173 anchor on the IoT device. For confidentiality protected firmware 174 images it is additionally required to install either one or multiple 175 symmetric or asymmetric keys on the IoT device. Starting security 176 protection at the author is a risk mitigation technique so firmware 177 images and manifests can be stored on untrusted respositories; it 178 also reduces the scope of a compromise of any repository or 179 intermediate system to be no worse than a denial of service. 181 It is assumed that the reader is familiar with the high-level 182 firmware update architecture [I-D.ietf-suit-architecture]. 184 The SUIT manifest is heavily optimised for consumption by constrained 185 devices. This means that it is not constructed as a conventional 186 descriptive document. Instead, of describing what an update IS, it 187 describes what a recipient should DO. 189 While the SUIT manifest is informed by and optimised for firmware 190 update use cases, there is nothing in the 191 [I-D.ietf-suit-information-model] that restricts its use to only 192 firmware use cases. Software update and delivery of arbitrary data 193 can equally be managed by SUIT-based metadata. 195 2. Conventions and Terminology 197 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 198 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 199 "OPTIONAL" in this document are to be interpreted as described in 200 BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all 201 capitals, as shown here. 203 - SUIT: Sofware Update for the Internet of Things, the IETF working 204 group for this standard. 206 - Payload: A piece of information to be delivered. Typically 207 Firmware for the purposes of SUIT. 209 - Resource: A piece of information that is used to construct a 210 payload. 212 - Manifest: A piece of information that describes one or more 213 payloads, one or more resources, and the processors needed to 214 transform resources into payloads. 216 - Update: One or more manifests that describe one or more payloads. 218 - Update Authority: The owner of a cryptographic key used to sign 219 updates, trusted by recipient devices. 221 - Recipient: The system, typically an IoT device, that receives a 222 manifest. 224 - Condition: A test for a property of the Recipient or its 225 components. 227 - Directive: An action for the Recipient to perform. 229 - Command: A Condition or a Directive. 231 - Trusted Execution: A process by which a system ensures that only 232 trusted code is executed, for example secure boot. 234 - A/B images: Dividing a device's storage into two or more bootable 235 images, at different offsets, such that the active image can write 236 to the inactive image(s). 238 The map indices in this encoding are reset to 1 for each map within 239 the structure. This is to keep the indices as small as possible. 241 The goal is to keep the index objects to single bytes (CBOR positive 242 integers 1-23). 244 Wherever enumerations are used, they are started at 1. This allows 245 detection of several common software errors that are caused by 246 uninitialised variables. Positive numbers in enumerations are 247 reserved for IANA registration. Negative numbers are used to 248 identify application-specific implementations. 250 CDDL names are hyphenated and CDDL structures follow the convention 251 adopted in COSE [RFC8152]: SUIT_Structure_Name. 253 3. How to use this document 255 For information about firmware update in general and the background 256 of the suit manifest, see Section 4. To implement an updatable 257 device, see Section 5 and Section 7. To implement a tool that 258 generates updates, see Section 6 and Section 7. 260 4. Background 262 Distributing firmware updates to diverse devices with diverse trust 263 anchors in a coordinated system presents unique challenges. Devices 264 have a broad set of constraints, requiring different metadata to make 265 appropriate decisions. There may be many actors in production IoT 266 systems, each of whom has some authority. Distributing firmware in 267 such a multi-party environment presents additional challenges. Each 268 party requires a different subset of data. Some data may not be 269 accessible to all parties. Multiple signatures may be required from 270 parties with different authorities. This topic is covered in more 271 depth in [I-D.ietf-suit-architecture]. 273 4.1. Landscape 275 The various constraints on IoT devices creates a broad set of use- 276 case requirements. For example, devices with: 278 - limited processing power and storage may require a simple 279 representation of metadata. 281 - bandwidth constraints may require firmware compression or partial 282 update support. 284 - bootloader complexity constraints may require simple selection 285 between two bootable images. 287 - small internal storage may require external storage support. 289 - multiple processors may require coordinated update of all 290 applications. 292 - large storage and complex functionality may require parallel 293 update of many software components. 295 - mesh networks may require multicast distribution. 297 Supporting the requirements introduced by the constraints on IoT 298 devices requires the flexibility to represent a diverse set of 299 possible metadata, but also requires that the encoding is kept 300 simple. 302 4.2. Update Workflow Model 304 There are several fundamental assumptions that inform the model of 305 the firmware update workflow: 307 - Compatibility must be checked before any other operation is 308 performed 310 - All dependency manifests should be present before any payload is 311 fetched 313 - In some applications, payloads must be fetched and validated prior 314 to installation 316 There are several fundamental assumptions that inform the model of 317 the secure boot workflow: 319 - Compatibility must be checked before any other operation is 320 performed 322 - All dependencies and payloads must be validated prior to loading 324 - All loaded images must be validated prior to execution 326 Based on these assumptions, the manifest is structured to work with a 327 pull parser, where each section of the manifest is used in sequence. 328 The expected workflow for a device installing an update can be broken 329 down into 5 steps: 331 1. Verify the signature of the manifest 333 2. Verify the applicability of the manifest 335 3. Resolve dependencies 336 4. Fetch payload(s) 338 5. Install payload(s) 340 When installation is complete, similar information can be used for 341 validating and running images in a further 3 steps: 343 1. Verify image(s) 345 2. Load image(s) 347 3. Run image(s) 349 If verification and running is implemented in bootloader, then the 351 When multiple manifests are used for an update, each manifest's steps 352 occur in a lockstep fashion; all manifests have dependency resolution 353 performed before any manifest performs a payload fetch, etc. 355 4.3. SUIT Manifest goals 357 The manifest described in this document is intended to meet several 358 goals, as described below. 360 1. Meet the requirements defined in 361 [I-D.ietf-suit-information-model]. 363 2. Simple to parse on a constrained node 365 3. Simple to process on a constrained node 367 4. Compact encoding 369 5. Comprehensible by an intermediate system 371 6. Expressive enough to enable advanced use cases on advanced nodes 373 7. Extensible 375 The SUIT manifest can be used for a variety of purposes throughout 376 its lifecycle. The manifest allows: 378 1. the Firmware Author to reason about releasing a firmware. 380 2. the Network Operator to reason about compatibility of a firmware. 382 3. the Device Operator to reason about the impact of a firmware. 384 4. the Device Operator to manage distribution of firmware to 385 devices. 387 5. the Plant Manager to reason about timing and acceptance of 388 firmware updates. 390 6. the device to reason about the authority & authenticity of a 391 firmware prior to installation. 393 7. the device to reason about the applicability of a firmware. 395 8. the device to reason about the installation of a firmware. 397 9. the device to reason about the authenticity & encoding of a 398 firmware at boot. 400 Each of these uses happens at a different stage of the manifest 401 lifecycle, so each has different requirements. 403 4.4. SUIT manifest design summary 405 In order to provide flexible behaviour to constrained devices, while 406 still allowing more powerful devices to use their full capabilities, 407 the SUIT manifest encodes the required behaviour of a Recipient 408 device. Behaviour is encoded as a specialised byte code, contained 409 in a CBOR list. This promotes a flat encoding, which simplifies the 410 parser. The information encoded by this byte code closely matches 411 the operations that a device will perform, which promotes ease of 412 processing. The core operations used by most update and trusted 413 execution operations are represented in the byte code. The byte code 414 can be extended by registering new operations. 416 The specialised byte code approach gives benefits equivalent to those 417 provided by a scripting language or conventional byte code, with two 418 substantial differences. First, the language is extremely high 419 level, consisting of only the operations that a device may perform 420 during update and trusted execution of a firmware image. Second, the 421 language specifies behaviours in a linearised form, without reverse 422 branches. Conditional processing is supported, and parallel and out- 423 of-order processing may be performed by sufficiently capable devices. 425 By structuring the data in this way, the manifest processor becomes a 426 very simple engine that uses a pull parser to interpret the manifest. 427 This pull parser invokes a series of command handlers that evaluate a 428 Condition or execute a Directive. Most data is structured in a 429 highly regular pattern, which simplifies the parser. 431 The results of this allow a Recipient to implement a very small 432 parser for constrained applications. If needed, such a parser also 433 allows the Recipient to perform complex updates with reduced 434 overhead. Conditional execution of commands allows a simple device 435 to perform important decisions at validation-time. 437 Dependency handling is vastly simplified as well. Dependencies 438 function like subroutines of the language. When a manifest has a 439 dependency, it can invoke that dependency's commands and modify their 440 behaviour by setting parameters. Because some parameters come with 441 security implications, the dependencies also have a mechanism to 442 reject modifications to parameters on a fine-grained level. 444 Developing a robust permissions system works in this model too. The 445 Recipient can use a simple ACL that is a table of Identities and 446 Component Identifier permissions to ensure that only manifests 447 authenticated by the appropriate identity have access to operate on a 448 component. 450 Capability reporting is similarly simplified. A Recipient can report 451 the Commands, Parameters, Algorithms, and Component Identifiers that 452 it supports. This is sufficiently precise for a manifest author to 453 create a manifest that the Recipient can accept. 455 The simplicity of design in the Recipient due to all of these 456 benefits allows even a highly constrained platform to use advanced 457 update capabilities. 459 5. Interpreter Behaviour 461 This section describes the behaviour of the manifest interpreter. 462 This section focuses primarily on interpreting commands in the 463 manifest. However, there are several other important behaviours of 464 the interpreter: encoding version detection, rollback protection, and 465 authenticity verification are chief among these. 467 5.1. Interpreter Setup 469 Prior to executing any command sequence, the interpreter or its host 470 application MUST inspect the manifest version field and fail when it 471 encounters an unsupported encoding version. Next, the interpreter or 472 its host application MUST extract the manifest sequence number and 473 perform a rollback check using this sequence number. The exact logic 474 of rollback protection may vary by application, but it has the 475 following properties: 477 - Whenever the interpreter can choose between several manifests, it 478 MUST select the latest valid manifest, authentic manifest. 480 - If the latest valid, authentic manifest fails, it MAY select the 481 next latest valid, authentic manifest. 483 Here, valid means that a manifest has a supported encoding version 484 AND it has not been excluded for other reasons. Reasons for 485 excluding typically involve first executing the manifest and MAY 486 include: 488 - Test failed (e.g. Vendor ID/Class ID) 490 - Unsupported command encountered 492 - Unsupported parameter encountered 494 - Unsupported component ID encountered 496 - Payload not available (update interpreter) 498 - Dependency not available (update interpreter) 500 - Application crashed when executed (bootloader interpreter) 502 - Watchdog timeout occurred (bootloader interpreter) 504 - Dependency or Payload verification failed (bootloader interpreter) 506 These failure reasons MAY be combined with retry mechanisms prior to 507 marking a manifest as invalid. 509 Following these initial tests, the interpreter clears all parameter 510 storage. This ensures that the interpreter begins without any leaked 511 data. 513 5.2. Required Checks 515 Once a valid, authentic manifest has been selected, the interpreter 516 MUST examine the component list and verify that its maximum number of 517 components is not exceeded and that each listed component ID is 518 supported. 520 For each listed component, the interpreter MUST provide storage for 521 the supported parameters (Section 5.4.1). If the interpreter does 522 not have sufficient temporary storage to process the parameters for 523 all components, it MAY process components serially for each command 524 sequence. See Section 5.5 for more details. 526 The interpreter SHOULD check that the common section contains at 527 least one vendor ID check and at least one class ID check. 529 If the manifest contains more than one component, each command 530 sequence MUST begin with a Set Current Component command. 532 If a dependency is specified, then the interpreter MUST perform the 533 following checks: 535 1. At the beginning of each section in the dependent: all previous 536 sections of each dependency have been executed. 538 2. At the end of each section in the dependent: The corresponding 539 section in each dependency has been executed. 541 If the interpreter does not support dependencies and a manifest 542 specifies a dependency, then the interpreter MUST reject the 543 manifest. 545 5.3. Interpreter fundamental properties 547 The interpreter has a small set of design goals: 549 1. Executing an update MUST either result in an error, or a 550 verifiably correct system state. 552 2. Executing a secure boot MUST either result in an error, or a 553 booted system. 555 3. Executing the same manifest on multiple devices MUST result in 556 the same system state. 558 NOTE: when using A/B images, the manifest functions as two (or more) 559 logical manifests, each of which applies to a system in a particular 560 starting state. With that provision, design goal 3 holds. 562 5.4. Abstract Machine Description 564 The byte code that forms the bulk of the manifest is processed by an 565 interpreter. This interpreter can be modelled as a simple abstract 566 machine. This machine consists of several data storage locations 567 that are modified by commands. Certain commands also affect the 568 machine's behaviour. 570 Every command that modifies system state targets a specific 571 component. Components are units of code or data that can be targeted 572 by an update. They are identified by Component identifiers, arrays 573 of binary-strings-effectively a binary path. Each component has a 574 corresponding set of configuration, Parameters. Parameters are used 575 as the inputs to commands. 577 5.4.1. Parameters 579 Some parameters are REQUIRED to implement. These parameters allow a 580 device to perform core functions. 582 - Vendor ID 584 - Class ID 586 - Image Digest 588 Some parameters are RECOMMENDED to implement. These parameters are 589 needed for most use-cases. 591 - Image Size 593 - URI 595 Other parameters are OPTIONAL to implement. These parameters allow a 596 device to implement specific use-cases. 598 - Strict Order 600 - Soft Failure 602 - Device ID 604 - Encryption Info 606 - Unpack Info 608 - Source Component 610 - URI List 612 - Custom Parameters 614 5.4.2. Commands 616 Commands define the behaviour of a device. The commands are divided 617 into two groups: those that modify state (directives) and those that 618 perform tests (conditions). There are also several Control Flow 619 operations. 621 Some commands are REQUIRED to implement. These commands allow a 622 device to perform core functions 624 - Check Vendor Identifier (cvid) 625 - Check Class Identifier (ccid) 627 - Verify Image (cimg) 629 - Set Current Component (setc) 631 - Override Parameters (ovrp) 633 NOTE: on systems that support only a single component, Set Current 634 Component has no effect. 636 Some commands are RECOMMENDED to implement. These commands are 637 needed for most use-cases 639 - Set Current Dependency (setd) 641 - Set Parameters (setp) 643 - Process Dependency (pdep) 645 - Run (run) 647 - Fetch (getc) 649 Other commands are OPTIONAL to implement. These commands allow a 650 device to implement specific use-cases. 652 - Use Before (ubf) 654 - Check Component Offset (cco) 656 - Check Device Identifier (cdid) 658 - Check Image Not Match (nimg) 660 - Check Minimum Battery (minb) 662 - Check Update Authorised (auth) 664 - Check Version (cver) 666 - Abort (abrt) 668 - Try Each (try) 670 - Copy (copy) 672 - Swap (swap) 673 - Wait For Event (wfe) 675 - Run Sequence (srun) mandatory component set 677 - Run with Arguments (arun) 679 5.4.3. Command Behaviour 681 The following table describes the behaviour of each command. "params" 682 represents the parameters for the current component or dependency. 684 +------+------------------------------------------------------------+ 685 | Code | Operation | 686 +------+------------------------------------------------------------+ 687 | cvid | binary-match(component, params[vendor-id]) | 688 | | | 689 | ccid | binary-match(component, params[class-id]) | 690 | | | 691 | cimg | binary-match(digest(component), params[digest]) | 692 | | | 693 | setc | component := components[arg] | 694 | | | 695 | ovrp | params[k] := v for k,v in arg | 696 | | | 697 | setd | dependency := dependencies[arg] | 698 | | | 699 | setp | params[k] := v if not k in params for k,v in arg | 700 | | | 701 | pdep | exec(dependency[common]); exec(dependency[current- | 702 | | segment]) | 703 | | | 704 | run | run(component) | 705 | | | 706 | getc | store(component, fetch(params[uri])) | 707 | | | 708 | ubf | assert(now() < arg) | 709 | | | 710 | cco | assert(offsetof(component) == arg) | 711 | | | 712 | cdid | binary-match(component, params[device-id]) | 713 | | | 714 | nimg | not binary-match(digest(component), params[digest]) | 715 | | | 716 | minb | assert(battery >= arg) | 717 | | | 718 | auth | assert(isAuthorised()) | 719 | | | 720 | cver | assert(version_check(component, arg)) | 721 | | | 722 | abrt | assert(0) | 723 | | | 724 | try | break if exec(seq) is not error for seq in arg | 725 | | | 726 | copy | store(component, params[src-component]) | 727 | | | 728 | swap | swap(component, params[src-component]) | 729 | | | 730 | wfe | until event(arg), wait | 731 | | | 732 | srun | exec(arg) | 733 | | | 734 | arun | run(component, arg) | 735 +------+------------------------------------------------------------+ 737 5.5. Serialized Processing Interpreter 739 Because each manifest has a list of components and a list of 740 components defined by its dependencies, it is possible for the 741 manifest processor to handle one component at a time, traversing the 742 manifest tree once for each listed component. In this mode, the 743 interpreter ignores any commands executed while the component index 744 is not the current component. This reduces the overall volatile 745 storage required to process the update so that the only limit on 746 number of components is the size of the manifest. However, this 747 approach requires additional processing power. 749 5.6. Parallel Processing Interpreter 751 Advanced devices may make use of the Strict Order parameter and 752 enable parallel processing of some segments, or it may reorder some 753 segments. To perform parallel processing, once the Strict Order 754 parameter is set to False, the device may fork a process for each 755 command until the Strict Order parameter is returned to True or the 756 command sequence ends. Then, it joins all forked processes before 757 continuing processing of commands. To perform out-of-order 758 processing, a similar approach is used, except the device consumes 759 all commands after the Strict Order parameter is set to False, then 760 it sorts these commands into its preferred order, invokes them all, 761 then continues processing. 763 Under each of these scenarios the parallel processing must halt: 765 - Set Parameters 767 - Override Parameters 768 - Set Strict Order = True 770 - Set Dependency Index 772 - Set Component Index 774 To perform more useful parallel operations, sequences of commands may 775 be collected in a suit-directive-run-sequence. Then, each of these 776 sequences may be run in parallel. Each sequence defaults to Strict 777 Order = True. To isolate each sequence from each other sequence, 778 each sequence must declare a single target component. Set Component 779 Index is not permitted inside this sequence. 781 5.7. Processing Dependencies 783 As described in Section 5.2, each manifest must invoke each of its 784 dependencies sections from the corresponding section of the 785 dependent. Any changes made to parameters by the dependency persist 786 in the dependent. 788 When a Process Depdendency command is encountered, the interpreter 789 loads the dependency identified by the Current Dependency Index. The 790 interpreter first executes the common-sequence section of the 791 identified dependency, then it executes the section of the dependency 792 that corresponds to the currently executing section of the dependent. 794 The interpreter also performs the checks described in Section 5.2 to 795 ensure that the dependent is processing the dependency correctly. 797 6. Creating Manifests 799 Manifests are created using tools for constructing COSE structures, 800 calculating cryptographic values and compiling desired system state 801 into a sequence of operations required to achieve that state. The 802 process of constructing COSE structures is covered in [RFC8152] and 803 the calculation of cryptographic values is beyond the scope of this 804 document. 806 Compiling desired system state into a sequence of operations can be 807 accomplished in many ways, however several templates are provided 808 here to cover common use-cases. Many of these templates can be 809 aggregated to produce more complex behaviour. 811 NOTE: On systems that support only a single component, Set Current 812 Component has no effect and can be omitted. 814 NOTE: Digest should always be set using Override Parameters, since 815 this prevents a less-privileged dependent from replacing the digest. 817 6.1. Manifest Source Material 819 When a manifest is constructed from a descriptive document, the 820 descriptive document SHOULD be included in the severable text 821 section. This section MAY be pruned from the manifest prior to 822 distribution to a device. The inclusion of text source material 823 enables several use-cases on unconstrained intermediate systems, 824 where small manifest size, low parser complexity, and pull parsing 825 are not required. 827 An unconstrained system that makes decisions based on the manifest 828 can use the source material instead so that it does not need to 829 execute the manifest. 831 An unconstrained system that presents data to a user can do so 832 according to typical usage patterns without first executing the 833 manifest, and can trust that information with the same level of 834 confidence as the manifest itself. 836 A verifier can be constructed to emulate execution the manifest and 837 compare the results of that execution to the source material, 838 providing a check that the manifest performs its stated objectives 839 and that the manifest does not exceed the capabilities of the target 840 device. 842 6.2. Required Template: Compatibility Check 844 The compatibility check ensures that devices only install compatible 845 images. 847 Common: Set Current Component Check Vendor Identifier Check Class 848 Identifier 850 All manifests MUST contain the compatibility check template, except 851 as outlined below. 853 If a device class has a unique trust anchor, and every element in its 854 trust chain is unique-different from every element in any other 855 device class, then it MAY include the compatibility check. 857 If a manifest includes a dependency that performs a compatibility 858 check, then the dependent manifest MAY include the compatibility 859 check. 861 The compatibility check template contains a data dependency: Vendor 862 Identifier and Class Identifier MUST be set prior to executing the 863 template. One examples of the full template is included below, 864 however Parameters may be set within a Try-Each block as well. They 865 may also be inherited from a dependent manifest. 867 - Common: 869 o Set Current Component 871 o Set Parameters: 873 * Vendor ID 875 * Class ID 877 o Check Vendor Identifier 879 o Check Class Identifier 881 6.3. Use Case Template: XIP Secure Boot 883 - Common: 885 o Set Current Component 887 o Override Parameters: 889 * Digest 891 * Size 893 - Run: 895 o Set Current Component 897 o Check Image Match 899 o Directive Run 901 6.4. Use Case Template: Firmware Download 903 - Common: 905 o Set Current Component 907 o Override Parameters: 909 * Digest 911 * Size 913 - Install: 915 o Set Current Component 917 o Set Parameters: 919 * URI 921 o Fetch 923 6.5. Use Case Template: Load from External Storage 925 - Load: 927 o Set Current Component 929 o Set Parameters: 931 * Source Index 933 o Copy 935 6.6. Use Case Template Load & Decompress from External Storage 937 - Load: 939 o Set Current Component 941 o Set Parameters: 943 * Source Index 945 * Compression Info 947 o Copy 949 6.7. Use Case Template: Dependency 951 - Dependency Resolution: 953 o Set Current Dependency 955 o Set Parameters: 957 * URI 959 o Fetch 960 o Check Image Match 962 o Process Dependency 964 - Validate: 966 o Set Current Dependency 968 o Check Image Match 970 o Process Dependency 972 For any other section that the dependency has, the dependent MUST 973 invoke Process Dependency. 975 NOTE: Any changes made to parameters in a dependency persist in the 976 dependent. 978 7. Manifest Structure 980 The manifest is divided into several sections in a hierarchy as 981 follows: 983 1. The outer wrapper 985 1. The authentication wrapper 987 2. The manifest 989 1. Critical Information 991 2. Information shared by all command sequences 993 1. List of dependencies 995 2. List of payloads 997 3. List of payloads in dependencies 999 4. Common list of conditions, directives 1001 3. Dependency resolution Reference or list of conditions, 1002 directives 1004 4. Payload fetch Reference or list of conditions, 1005 directives 1007 5. Installation Reference or list of conditions, directives 1008 6. Verification conditions/directives 1010 7. Load conditions/directives 1012 8. Run conditions/directives 1014 9. Text / Reference 1016 10. COSWID / Reference 1018 3. Dependency resolution conditions/directives 1020 4. Payload fetch conditions/directives 1022 5. Installation conditions/directives 1024 6. Text 1026 7. COSWID / Reference 1028 8. Intermediate Certificate(s) / CWTs 1030 9. Inline Payload(s) 1032 7.1. Severable Elements 1034 Because the manifest can be used by different actors at different 1035 times, some parts of the manifest can be removed without affecting 1036 later stages of the lifecycle. This is called "Severing." Severing 1037 of information is achieved by separating that information from the 1038 signed container so that removing it does not affect the signature. 1039 This means that ensuring authenticity of severable parts of the 1040 manifest is a requirement for the signed portion of the manifest. 1041 Severing some parts makes it possible to discard parts of the 1042 manifest that are no longer necessary. This is important because it 1043 allows the storage used by the manifest to be greatly reduced. For 1044 example, no text size limits are needed if text is removed from the 1045 manifest prior to delivery to a constrained device. 1047 Elements are made severable by removing them from the manifest, 1048 encoding them in a bstr, and placing a SUIT_Digest of the bstr in the 1049 manifest so that they can still be authenticated. The SUIT_Digest 1050 typically consumes 4 bytes more than the size of the raw digest, 1051 therefore elements smaller than (Digest Bits)/8 + 4 SHOULD never be 1052 severable. Elements larger than (Digest Bits)/8 + 4 MAY be 1053 severable, while elements that are much larger than (Digest Bits)/8 + 1054 4 SHOULD be severable. 1056 Because of this, all command sequences in the manifest are encoded in 1057 a bstr so that there is a single code path needed for all command 1058 sequences 1060 7.2. Outer wrapper 1062 This object is a container for the other pieces of the manifest to 1063 provide a common mechanism to find each of the parts. All elements 1064 of the outer wrapper are contained in bstr objects. Wherever the 1065 manifest references an object in the outer wrapper, the bstr is 1066 included in the digest calculation. 1068 The CDDL that describes the wrapper is below 1070 SUIT_Outer_Wrapper = { 1071 suit-authentication-wrapper => bstr .cbor 1072 SUIT_Authentication_Wrapper / nil, 1073 $SUIT_Manifest_Wrapped, 1074 ? suit-dependency-resolution => bstr .cbor SUIT_Command_Sequence, 1075 ? suit-payload-fetch => bstr .cbor SUIT_Command_Sequence, 1076 ? suit-install => bstr .cbor SUIT_Command_Sequence, 1077 ? suit-text => bstr .cbor SUIT_Text_Map, 1078 ? suit-coswid => bstr .cbor COSWID 1079 } 1081 SUIT_Authentication_Wrapper = [ + (COSE_Mac_Tagged / COSE_Sign_Tagged / 1082 COSE_Mac0_Tagged / COSE_Sign1_Tagged)] 1083 SUIT_Encryption_Wrapper = COSE_Encrypt_Tagged / COSE_Encrypt0_Tagged 1085 SUIT_Manifest_Wrapped //= (suit-manifest => bstr .cbor SUIT_Manifest) 1086 SUIT_Manifest_Wrapped //= ( 1087 suit-manifest-encryption-info => bstr .cbor SUIT_Encryption_Wrapper, 1088 suit-manifest-encrypted => bstr 1089 ) 1091 All elements of the outer wrapper must be wrapped in a bstr to 1092 minimize the complexity of the code that evaluates the cryptographic 1093 integrity of the element and to ensure correct serialisation for 1094 integrity and authenticity checks. 1096 The suit-authentication-wrapper contains a list of 1 or more 1097 cryptographic authentication wrappers for the core part of the 1098 manifest. These are implemented as COSE_Mac_Tagged or 1099 COSE_Sign_Tagged blocks. The Manifest is authenticated by these 1100 blocks in "detached payload" mode. The COSE_Mac_Tagged and 1101 COSE_Sign_Tagged blocks are described in RFC 8152 [RFC8152] and are 1102 beyond the scope of this document. The suit-authentication-wrapper 1103 MUST come first in the SUIT_Outer_Wrapper, regardless of canonical 1104 encoding of CBOR. All validators MUST reject any SUIT_Outer_Wrapper 1105 that begins with any element other than a suit-authentication- 1106 wrapper. 1108 A manifest that has not had authentication information added MUST 1109 still contain the suit-authentication-wrapper element, but the 1110 content MUST be nil. 1112 The outer wrapper MUST contain only one of 1114 - a plaintext manifest: SUIT_Manifest 1116 - an encrypted manifest: both a SUIT_Encryption_Wrapper and the 1117 ciphertext of a manifest. 1119 When the outer wrapper contains SUIT_Encryption_Wrapper, the suit- 1120 authentication-wrapper MUST authenticate the plaintext of suit- 1121 manifest-encrypted. 1123 suit-manifest contains a SUIT_Manifest structure, which describes the 1124 payload(s) to be installed and any dependencies on other manifests. 1126 suit-manifest-encryption-info contains a SUIT_Encryption_Wrapper, a 1127 COSE object that describes the information required to decrypt a 1128 ciphertext manifest. 1130 suit-manifest-encrypted contains a ciphertext manifest. 1132 Each of suit-dependency-resolution, suit-payload-fetch, and suit- 1133 payload-installation contain the severable contents of the 1134 identically named portions of the manifest, described in Section 7.3. 1136 suit-text contains all the human-readable information that describes 1137 any and all parts of the manifest, its payload(s) and its 1138 resource(s). 1140 suit-coswid contains a Concise Software Identifier. This may be 1141 discarded by the recipient if not needed. 1143 7.3. Manifest 1145 The manifest describes the critical metadata for the referenced 1146 payload(s). In addition, it contains: 1148 1. a version number for the manifest structure itself 1150 2. a sequence number 1151 3. a list of dependencies 1153 4. a list of components affected 1155 5. a list of components affected by dependencies 1157 6. a reference for each of the severable blocks. 1159 7. a list of actions that the recipient should perform. 1161 The following CDDL fragment defines the manifest. 1163 SUIT_Manifest = { 1164 suit-manifest-version => 1, 1165 suit-manifest-sequence-number => uint, 1166 suit-common => bstr .cbor SUIT_Common, 1167 ? suit-dependency-resolution => Digest / bstr .cbor SUIT_Command_Sequence, 1168 ? suit-payload-fetch => Digest / bstr .cbor SUIT_Command_Sequence, 1169 ? suit-install => Digest / bstr .cbor SUIT_Command_Sequence, 1170 ? suit-validate => bstr .cbor SUIT_Command_Sequence, 1171 ? suit-load => bstr .cbor SUIT_Command_Sequence, 1172 ? suit-run => bstr .cbor SUIT_Command_Sequence, 1173 ? suit-text => Digest, 1174 ? suit-coswid => Digest / bstr .cbor concise-software-identity, 1175 } 1177 SUIT_Common = { 1178 ? suit-dependencies => bstr .cbor [ + SUIT_Dependency ], 1179 ? suit-components => bstr .cbor [ + SUIT_Component_Identifier ], 1180 ? suit-dependency-components => bstr .cbor [ + SUIT_Component_Reference ], 1181 ? suit-common-sequence => bstr .cbor SUIT_Command_Sequence, 1182 } 1184 Several fields in the Manifest can be either a CBOR structure or a 1185 SUIT_Digest. In each of these cases, the SUIT_Digest provides for a 1186 severable field. Severable fields are RECOMMENDED to implement. In 1187 particular, text SHOULD be severable, since most useful text elements 1188 occupy more space than a SUIT_Digest, but are not needed by recipient 1189 devices. Because SUIT_Digest is a CBOR Array and each severable 1190 element is a CBOR bstr, it is straight-forward for a recipient to 1191 determine whether an element is been severable. The key used for a 1192 severable element is the same in the SUIT_Manifest and in the 1193 SUIT_Outer_Wrapper so that a recipient can easily identify the 1194 correct data in the outer wrapper. 1196 The suit-manifest-version indicates the version of serialisation used 1197 to encode the manifest. Version 1 is the version described in this 1198 document. suit-manifest-version is REQUIRED. 1200 The suit-manifest-sequence-number is a monotonically increasing anti- 1201 rollback counter. It also helps devices to determine which in a set 1202 of manifests is the "root" manifest in a given update. Each manifest 1203 MUST have a sequence number higher than each of its dependencies. 1204 Each recipient MUST reject any manifest that has a sequence number 1205 lower than its current sequence number. It MAY be convenient to use 1206 a UTC timestamp in seconds as the sequence number. suit-manifest- 1207 sequence-number is REQUIRED. 1209 suit-common encodes all the information that is shared between each 1210 of the command sequences, including: suit-dependencies, suit- 1211 components, suit-dependency-components, and suit-common-sequence. 1212 suit-common is REQUIRED to implement. 1214 suit-dependencies is a list of SUIT_Dependency blocks that specify 1215 manifests that must be present before the current manifest can be 1216 processed. suit-dependencies is OPTIONAL to implement. 1218 In order to distinguish between components that are affected by the 1219 current manifest and components that are affected by a dependency, 1220 they are kept in separate lists. Components affected by the current 1221 manifest only list the component identifier. Components affected by 1222 a dependency include the component identifier and the index of the 1223 dependency that defines the component. 1225 suit-components is a list of SUIT_Component blocks that specify the 1226 component identifiers that will be affected by the content of the 1227 current manifest. suit-components is OPTIONAL, but at least one 1228 manifest MUST contain a suit-components block. 1230 suit-dependency-components is a list of SUIT_Component_Reference 1231 blocks that specify component identifiers that will be affected by 1232 the content of a dependency of the current manifest. suit-dependency- 1233 components is OPTIONAL. 1235 suit-common-sequence is a SUIT_Command_Sequence to execute prior to 1236 executing any other command sequence. Typical actions in suit- 1237 common-sequence include setting expected device identity and image 1238 digests when they are conditional (see Section 10 for more 1239 information on conditional sequences). suit-common-sequence is 1240 RECOMMENDED. 1242 suit-dependency-resolution is a SUIT_Command_Sequence to execute in 1243 order to perform dependency resolution. Typical actions include 1244 configuring URIs of dependency manifests, fetching dependency 1245 manifests, and validating dependency manifests' contents. suit- 1246 dependency-resolution is REQUIRED when suit-dependencies is present. 1248 suit-payload-fetch is a SUIT_Command_Sequence to execute in order to 1249 obtain a payload. Some manifests may include these actions in the 1250 suit-install section instead if they operate in a streaming 1251 installation mode. This is particularly relevant for constrained 1252 devices without any temporary storage for staging the update. suit- 1253 payload-fetch is OPTIONAL. 1255 suit-install is a SUIT_Command_Sequence to execute in order to 1256 install a payload. Typical actions include verifying a payload 1257 stored in temporary storage, copying a staged payload from temporary 1258 storage, and unpacking a payload. suit-install is OPTIONAL. 1260 suit-validate is a SUIT_Command_Sequence to execute in order to 1261 validate that the result of applying the update is correct. Typical 1262 actions involve image validation and manifest validation. suit- 1263 validate is REQUIRED. If the manifest contains dependencies, one 1264 process-dependency invocation per dependency or one process- 1265 dependency invocation targeting all dependencies SHOULD be present in 1266 validate. 1268 suit-load is a SUIT_Command_Sequence to execute in order to prepare a 1269 payload for execution. Typical actions include copying an image from 1270 permanent storage into RAM, optionally including actions such as 1271 decryption or decompression. suit-load is OPTIONAL. 1273 suit-run is a SUIT_Command_Sequence to execute in order to run an 1274 image. suit-run typically contains a single instruction: either the 1275 "run" directive for the bootable manifest or the "process 1276 dependencies" directive for any dependents of the bootable manifest. 1277 suit-run is OPTIONAL. Only one manifest in an update may contain the 1278 "run" directive. 1280 suit-text is a digest that uniquely identifies the content of the 1281 Text that is packaged in the OuterWrapper. text is OPTIONAL. 1283 suit-coswid is a digest that uniquely identifies the content of the 1284 concise-software-identifier that is packaged in the OuterWrapper. 1285 coswid is OPTIONAL. 1287 7.4. SUIT_Dependency 1289 SUIT_Dependency specifies a manifest that describes a dependency of 1290 the current manifest. 1292 The following CDDL describes the SUIT_Dependency structure. 1294 SUIT_Dependency = { 1295 suit-dependency-digest => SUIT_Digest, 1296 ? suit-dependency-prefix => SUIT_Component_Identifier, 1297 } 1299 The suit-dependency-digest specifies the dependency manifest uniquely 1300 by identifying a particular Manifest structure. The digest is 1301 calculated over the Manifest structure instead of the COSE 1302 Sig_structure or Mac_structure. This means that a digest may need to 1303 be calculated more than once, however this is necessary to ensure 1304 that removing a signature from a manifest does not break dependencies 1305 due to missing signature elements. This is also necessary to support 1306 the trusted intermediary use case, where an intermediary re-signs the 1307 Manifest, removing the original signature, potentially with a 1308 different algorithm, or trading COSE_Sign for COSE_Mac. 1310 The suit-dependency-prefix element contains a 1311 SUIT_Component_Identifier. This specifies the scope at which the 1312 dependency operates. This allows the dependency to be forwarded on 1313 to a component that is capable of parsing its own manifests. It also 1314 allows one manifest to be deployed to multiple dependent devices 1315 without those devices needing consistent component hierarchy. This 1316 element is OPTIONAL. 1318 7.5. SUIT_Component_Reference 1320 The SUIT_Component_Reference describes an image that is defined by 1321 another manifest. This is useful for overriding the behaviour of 1322 another manifest, for example by directing the recipient to look at a 1323 different URI for the image or by changing the expected format, such 1324 as when a gateway performs decryption on behalf of a constrained 1325 device. The following CDDL describes the SUIT_Component_Reference. 1327 SUIT_Component_Reference = { 1328 suit-component-identifier => SUIT_Component_Identifier, 1329 suit-component-dependency-index => uint 1330 } 1332 7.6. Manifest Parameters 1334 Many conditions and directives require additional information. That 1335 information is contained within parameters that can be set in a 1336 consistent way. This allows reduction of manifest size and 1337 replacement of parameters from one manifest to the next. 1339 The defined manifest parameters are described below. 1341 +-----+--------+-------------------+------------+-------------------+ 1342 | ID | CBOR | Scope | Name | Description | 1343 | | Type | | | | 1344 +-----+--------+-------------------+------------+-------------------+ 1345 | 1 | boolea | Global | Strict | Requires that the | 1346 | | n | | Order | manifest is | 1347 | | | | | processed in a | 1348 | | | | | strictly linear | 1349 | | | | | fashion. Set to 0 | 1350 | | | | | to enable | 1351 | | | | | parallel handling | 1352 | | | | | of manifest | 1353 | | | | | directives. | 1354 | | | | | | 1355 | 2 | boolea | Command Segment | Soft | Condition | 1356 | | n | | Failure | failures only | 1357 | | | | | terminate the | 1358 | | | | | current command | 1359 | | | | | segment. | 1360 | | | | | | 1361 | 3 | bstr | Component/Global | Vendor ID | A RFC4122 UUID | 1362 | | | | | representing the | 1363 | | | | | vendor of the | 1364 | | | | | device or | 1365 | | | | | component | 1366 | | | | | | 1367 | 4 | bstr | Component/Global | Class ID | A RFC4122 UUID | 1368 | | | | | representing the | 1369 | | | | | class of the | 1370 | | | | | device or | 1371 | | | | | component | 1372 | | | | | | 1373 | 5 | bstr | Component/Global | Device ID | A RFC4122 UUID | 1374 | | | | | representing the | 1375 | | | | | device or | 1376 | | | | | component | 1377 | | | | | | 1378 | 6 | tstr | Component/Depende | URI | A URI from which | 1379 | | | ncy | | to fetch a | 1380 | | | | | resource | 1381 | | | | | | 1382 | 7 | bstr | Component/Depende | Encryption | A COSE object | 1383 | | | ncy | Info | defining the | 1384 | | | | | encryption mode | 1385 | | | | | of a resource | 1386 | | | | | | 1387 | 8 | bstr | Component | Compressio | The information | 1388 | | | | n Info | required to | 1389 | | | | | decompress the | 1390 | | | | | image | 1391 | | | | | | 1392 | 9 | bstr | Component | Unpack | The information | 1393 | | | | Info | required to | 1394 | | | | | unpack the image | 1395 | | | | | | 1396 | 10 | uint | Component | Source | A Component Index | 1397 | | | | Component | | 1398 | | | | | | 1399 | 11 | bstr | Component/Depende | Image | A SUIT_Digest | 1400 | | | ncy | Digest | | 1401 | | | | | | 1402 | 12 | uint | Component/Depende | Image Size | Integer size | 1403 | | | ncy | | | 1404 | | | | | | 1405 | 24 | bstr | Component/Depende | URI List | A CBOR encoded | 1406 | | | ncy | | list of ranked | 1407 | | | | | URIs | 1408 | | | | | | 1409 | 25 | boolea | Component/Depende | URI List | A CBOR encoded | 1410 | | n | ncy | Append | list of ranked | 1411 | | | | | URIs | 1412 | | | | | | 1413 | nin | int/bs | Custom | Custom | Application- | 1414 | t | tr | | Parameter | defined parameter | 1415 +-----+--------+-------------------+------------+-------------------+ 1417 CBOR-encoded object parameters are still wrapped in a bstr. This is 1418 because it allows a parser that is aggregating parameters to 1419 reference the object with a single pointer and traverse it without 1420 understanding the contents. This is important for modularisation and 1421 division of responsibility within a pull parser. The same 1422 consideration does not apply to Conditions and Directives because 1423 those elements are invoked with their arguments immediately 1425 7.6.1. SUIT_Parameter_Strict_Order 1427 The Strict Order Parameter allows a manifest to govern when 1428 directives can be executed out-of-order. This allows for systems 1429 that have a sensitivity to order of updates to choose the order in 1430 which they are executed. It also allows for more advanced systems to 1431 parallelise their handling of updates. Strict Order defaults to 1432 True. It MAY be set to False when the order of operations does not 1433 matter. When arriving at the end of a command sequence, ALL commands 1434 MUST have completed, regardless of the state of 1435 SUIT_Parameter_Strict_Order. If SUIT_Parameter_Strict_Order is 1436 returned to True, ALL preceding commands MUST complete before the 1437 next command is executed. 1439 7.6.2. SUIT_Parameter_Soft_Failure 1441 When executing a command sequence inside SUIT_Directive_Try_Each and 1442 a condition failure occurs, the manifest processor aborts the 1443 sequence. If Soft Failure is True, it returns Success. Otherwise, 1444 it returns the original condition failure. 1445 SUIT_Parameter_Soft_Failure is scoped to the enclosing 1446 SUIT_Command_Sequence. Its value is discarded when 1447 SUIT_Command_Sequence terminates. 1449 7.7. SUIT_Parameter_Encryption_Info 1451 Encryption Info defines the mechanism that Fetch or Copy should use 1452 to decrypt the data they transfer. SUIT_Parameter_Encryption_Info is 1453 encoded as a COSE_Encrypt_Tagged or a COSE_Encrypt0_Tagged, wrapped 1454 in a bstr 1456 7.8. SUIT_Parameter_Compression_Info 1458 Compression Info defines any information that is required for a 1459 device to perform decompression operations. Typically, this includes 1460 the algorithm identifier. 1462 SUIT_Parameter_Compression_Info is defined by the following CDDL: 1464 SUIT_Compression_Info = { 1465 suit-compression-algorithm => SUIT_Compression_Algorithms 1466 ? suit-compression-parameters => bstr 1467 } 1469 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_gzip 1470 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_bzip2 1471 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_deflate 1472 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_LZ4 1473 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_lzma 1475 7.9. SUIT_Parameter_Unpack_Info 1477 SUIT_Unpack_Info defines the information required for a device to 1478 interpret a packed format, such as elf, hex, or binary diff. 1479 SUIT_Unpack_Info is defined by the following CDDL: 1481 SUIT_Unpack_Info = { 1482 suit-unpack-algorithm => SUIT_Unpack_Algorithms 1483 ? suit-unpack-parameters => bstr 1484 } 1486 SUIT_Unpack_Algorithms //= SUIT_Unpack_Algorithm_Delta 1487 SUIT_Unpack_Algorithms //= SUIT_Unpack_Algorithm_Hex 1488 SUIT_Unpack_Algorithms //= SUIT_Unpack_Algorithm_Elf 1490 7.10. SUIT_Parameters CDDL 1492 The following CDDL describes all SUIT_Parameters. 1494 SUIT_Parameters //= (suit-parameter-strict-order => bool) 1495 SUIT_Parameters //= (suit-parameter-soft-failure => bool) 1496 SUIT_Parameters //= (suit-parameter-vendor-id => bstr) 1497 SUIT_Parameters //= (suit-parameter-class-id => bstr) 1498 SUIT_Parameters //= (suit-parameter-device-id => bstr) 1499 SUIT_Parameters //= (suit-parameter-uri => tstr) 1500 SUIT_Parameters //= (suit-parameter-encryption-info => bstr .cbor SUIT_Encryption_Info) 1501 SUIT_Parameters //= (suit-parameter-compression-info => bstr .cbor SUIT_Compression_Info) 1502 SUIT_Parameters //= (suit-parameter-unpack-info => bstr .cbor SUIT_Unpack_Info) 1503 SUIT_Parameters //= (suit-parameter-source-component => uint) 1504 SUIT_Parameters //= (suit-parameter-image-digest => bstr .cbor SUIT_Digest) 1505 SUIT_Parameters //= (suit-parameter-image-size => uint) 1506 SUIT_Parameters //= (suit-parameter-uri-list => bstr .cbor SUIT_Component_URI_List) 1507 SUIT_Parameters //= (suit-parameter-custom => int/bool/tstr/bstr) 1509 SUIT_Component_URI_List = [ + [priority: int, uri: tstr] ] 1511 SUIT_Encryption_Info= COSE_Encrypt_Tagged/COSE_Encrypt0_Tagged 1512 SUIT_Compression_Info = { 1513 suit-compression-algorithm => SUIT_Compression_Algorithms 1514 ? suit-compression-parameters => bstr 1515 } 1517 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_gzip 1518 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_bzip2 1519 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_deflate 1520 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_LZ4 1521 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_lzma 1523 SUIT_Unpack_Info = { 1524 suit-unpack-algorithm => SUIT_Unpack_Algorithms 1525 ? suit-unpack-parameters => bstr 1526 } 1528 SUIT_Unpack_Algorithms //= SUIT_Unpack_Algorithm_Delta 1529 SUIT_Unpack_Algorithms //= SUIT_Unpack_Algorithm_Hex 1530 SUIT_Unpack_Algorithms //= SUIT_Unpack_Algorithm_Elf 1532 7.11. SUIT_Command_Sequence 1534 A SUIT_Command_Sequence defines a series of actions that the 1535 recipient MUST take to accomplish a particular goal. These goals are 1536 defined in the manifest and include: 1538 1. Dependency Resolution 1540 2. Payload Fetch 1541 3. Payload Installation 1543 4. Image Validation 1545 5. Image Loading 1547 6. Run or Boot 1549 Each of these follows exactly the same structure to ensure that the 1550 parser is as simple as possible. 1552 Lists of commands are constructed from two kinds of element: 1554 1. Conditions that MUST be true-any failure is treated as a failure 1555 of the update/load/boot 1557 2. Directives that MUST be executed. 1559 The lists of commands are logically structured into sequences of zero 1560 or more conditions followed by zero or more directives. The 1561 *logical* structure is described by the following CDDL: 1563 Command_Sequence = { 1564 conditions => [ * Condition], 1565 directives => [ * Directive] 1566 } 1568 This introduces significant complexity in the parser, however, so the 1569 structure is flattened to make parsing simpler: 1571 SUIT_Command_Sequence = [ + (SUIT_Condition/SUIT_Directive) ] 1573 Each condition and directive is composed of: 1575 1. A command code identifier 1577 2. An argument block 1579 Argument blocks are defined for each type of command. 1581 Many conditions and directives apply to a given component, and these 1582 generally grouped together. Therefore, a special command to set the 1583 current component index is provided with a matching command to set 1584 the current dependency index. This index is a numeric index into the 1585 component ID tables defined at the beginning of the document. For 1586 the purpose of setting the index, the two component ID tables are 1587 considered to be concatenated together. 1589 To facilitate optional conditions, a special directive is provided. 1590 It runs several new lists of conditions/directives, one after 1591 another, that are contained as an argument to the directive. By 1592 default, it assumes that a failure of a condition should not indicate 1593 a failure of the update/boot, but a parameter is provided to override 1594 this behaviour. 1596 7.12. SUIT_Condition 1598 Conditions are used to define mandatory properties of a system in 1599 order for an update to be applied. They can be pre-conditions or 1600 post-conditons of any directive or series of directives, depending on 1601 where they are placed in the list. Conditions include: 1603 +----------------+-------------------+----------------------------+ 1604 | Condition Code | Condition Name | Argument Type | 1605 +----------------+-------------------+----------------------------+ 1606 | 1 | Vendor Identifier | nil | 1607 | | | | 1608 | 2 | Class Identifier | nil | 1609 | | | | 1610 | 3 | Image Match | nil | 1611 | | | | 1612 | 4 | Use Before | Unsigned Integer timestamp | 1613 | | | | 1614 | 5 | Component Offset | Unsigned Integer | 1615 | | | | 1616 | 24 | Device Identifier | nil | 1617 | | | | 1618 | 25 | Image Not Match | nil | 1619 | | | | 1620 | 26 | Minimum Battery | Unsigned Integer | 1621 | | | | 1622 | 27 | Update Authorised | Integer | 1623 | | | | 1624 | 28 | Version | List of Integers | 1625 | | | | 1626 | nint | Custom Condition | bstr | 1627 +----------------+-------------------+----------------------------+ 1629 Each condition MUST report a success code on completion. If a 1630 condition reports failure, then the current sequence of commands MUST 1631 terminate. If a recipient encounters an unknown Condition Code, it 1632 MUST report a failure. 1634 Positive Condition numbers are reserved for IANA registration. 1635 Negative numbers are reserved for proprietary, application-specific 1636 directives. 1638 7.12.1. Identifier Conditions 1640 There are three identifier-based conditions: suit-condition-vendor- 1641 identifier, suit-condition-class-identifier, and suit-condition- 1642 device-identifier. Each of these conditions match a RFC 4122 1643 [RFC4122] UUID that MUST have already been set as a parameter. The 1644 installing device MUST match the specified UUID in order to consider 1645 the manifest valid. These identifiers MAY be scoped by component. 1647 The recipient uses the ID parameter that has already been set using 1648 the Set Parameters directive. If no ID has been set, this condition 1649 fails. suit-condition-class-identifier and suit-condition-vendor- 1650 identifier are REQUIRED to implement. suit-condition-device- 1651 identifier is OPTIONAL to implement. 1653 7.12.2. suit-condition-image-match 1655 Verify that the current component matches the digest parameter for 1656 the current component. The digest is verified against the digest 1657 specified in the Component's parameters list. If no digest is 1658 specified, the condition fails. suit-condition-image-match is 1659 REQUIRED to implement. 1661 7.12.3. suit-condition-image-not-match 1663 Verify that the current component does not match the supplied digest. 1664 If no digest is specified, then the digest is compared against the 1665 digest specified in the Components list. If no digest is specified 1666 and the component is not present in the Components list, the 1667 condition fails. suit-condition-image-not-match is OPTIONAL to 1668 implement. 1670 7.12.4. suit-condition-use-before 1672 Verify that the current time is BEFORE the specified time. suit- 1673 condition-use-before is used to specify the last time at which an 1674 update should be installed. One argument is required, encoded as a 1675 POSIX timestamp, that is seconds after 1970-01-01 00:00:00. 1676 Timestamp conditions MUST be evaluated in 64 bits, regardless of 1677 encoded CBOR size. suit-condition-use-before is OPTIONAL to 1678 implement. 1680 7.12.5. suit-condition-minimum-battery 1682 suit-condition-minimum-battery provides a mechanism to test a 1683 device's battery level before installing an update. This condition 1684 is for use in primary-cell applications, where the battery is only 1685 ever discharged. For batteries that are charged, suit-directive-wait 1686 is more appropriate, since it defines a "wait" until the battery 1687 level is sufficient to install the update. suit-condition-minimum- 1688 battery is specified in mWh. suit-condition-minimum-battery is 1689 OPTIONAL to implement. 1691 7.12.6. suit-condition-update-authorised 1693 Request Authorisation from the application and fail if not 1694 authorised. This can allow a user to decline an update. Argument is 1695 an integer priority level. Priorities are application defined. suit- 1696 condition-update-authorised is OPTIONAL to implement. 1698 7.12.7. suit-condition-version 1700 suit-condition-version allows comparing versions of firmware. 1701 Verifying image digests is preferred to version checks because 1702 digests are more precise. The image can be compared as: 1704 - Greater 1706 - Greater or Equal 1708 - Equal 1710 - Lesser or Equal 1712 - Lesser 1714 Versions are encoded as a CBOR list of integers. Comparisons are 1715 done on each integer in sequence. Comparison stops after all 1716 integers in the list defined by the manifest have been consumed OR 1717 after a non-equal match has occured. For example, if the manifest 1718 defines a comparison, "Equal [1]", then this will match all version 1719 sequences starting with 1. If a manifest defines both "Greater or 1720 Equal [1,0]" and "Lesser [1,10]", then it will match versions 1.0.x 1721 up to, but not including 1.10. 1723 The following CDDL describes SUIT_Condition_Version_Argument 1725 SUIT_Condition_Version_Argument = [ 1726 suit-condition-version-comparison: SUIT_Condition_Version_Comparison_Types, 1727 suit-condition-version-comparison: SUIT_Condition_Version_Comparison_Value 1728 ] 1729 SUIT_Condition_Version_Comparison_Types /= SUIT_Condition_Version_Comparison_Greater 1730 SUIT_Condition_Version_Comparison_Types /= SUIT_Condition_Version_Comparison_Greater_Equal 1731 SUIT_Condition_Version_Comparison_Types /= SUIT_Condition_Version_Comparison_Equal 1732 SUIT_Condition_Version_Comparison_Types /= SUIT_Condition_Version_Comparison_Lesser_Equal 1733 SUIT_Condition_Version_Comparison_Types /= SUIT_Condition_Version_Comparison_Lesser 1734 SUIT_Condition_Version_Comparison_Greater = 1 1735 SUIT_Condition_Version_Comparison_Greater_Equal = 2 1736 SUIT_Condition_Version_Comparison_Equal = 3 1737 SUIT_Condition_Version_Comparison_Lesser_Equal = 4 1738 SUIT_Condition_Version_Comparison_Lesser = 5 1740 SUIT_Condition_Version_Comparison_Value = [+int] 1742 While the exact encoding of versions is application-defined, semantic 1743 versions map conveniently. For example, 1745 - 1.2.3 = [1,2,3] 1747 - 1.2-rc3 = [1,2,-1,3] 1749 - 1.2-beta = [1,2,-2] 1751 - 1.2-alpha = [1,2,-3] 1753 - 1.2-alpha4 = [1,2,-3,4] 1755 suit-condition-version is OPTIONAL to implement. 1757 7.12.8. SUIT_Condition_Custom 1759 SUIT_Condition_Custom describes any proprietary, application specific 1760 condition. This is encoded as a negative integer, chosen by the 1761 firmware developer, and a bstr that encodes the parameters passed to 1762 the system that evaluates the condition matching that integer. 1763 SUIT_Condition_Custom is OPTIONAL to implement. 1765 7.12.9. Identifiers 1767 Many conditions use identifiers to determine whether a manifest 1768 matches a given recipient or not. These identifiers are defined to 1769 be RFC 4122 [RFC4122] UUIDs. These UUIDs are explicitly NOT human- 1770 readable. They are for machine-based matching only. 1772 A device may match any number of UUIDs for vendor or class 1773 identifier. This may be relevant to physical or software modules. 1774 For example, a device that has an OS and one or more applications 1775 might list one Vendor ID for the OS and one or more additional Vendor 1776 IDs for the applications. This device might also have a Class ID 1777 that must be matched for the OS and one or more Class IDs for the 1778 applications. 1780 A more complete example: A device has the following physical 1781 components: 1. A host MCU 2. A WiFi module 1783 This same device has three software modules: 1. An operating system 1784 2. A WiFi module interface driver 3. An application 1786 Suppose that the WiFi module's firmware has a proprietary update 1787 mechanism and doesn't support manifest processing. This device can 1788 report four class IDs: 1790 1. hardware model/revision 1792 2. OS 1794 3. WiFi module model/revision 1796 4. Application 1798 This allows the OS, WiFi module, and application to be updated 1799 independently. To combat possible incompatibilities, the OS class ID 1800 can be changed each time the OS has a change to its API. 1802 This approach allows a vendor to target, for example, all devices 1803 with a particular WiFi module with an update, which is a very 1804 powerful mechanism, particularly when used for security updates. 1806 7.12.9.1. Creating UUIDs: 1808 UUIDs MUST be created according to RFC 4122 [RFC4122]. UUIDs SHOULD 1809 use versions 3, 4, or 5, as described in RFC4122. Versions 1 and 2 1810 do not provide a tangible benefit over version 4 for this 1811 application. 1813 The RECOMMENDED method to create a vendor ID is: Vendor ID = 1814 UUID5(DNS_PREFIX, vendor domain name) 1816 The RECOMMENDED method to create a class ID is: Class ID = 1817 UUID5(Vendor ID, Class-Specific-Information) 1818 Class-specific information is composed of a variety of data, for 1819 example: 1821 - Model number 1823 - Hardware revision 1825 - Bootloader version (for immutable bootloaders) 1827 7.12.10. SUIT_Condition CDDL 1829 The following CDDL describes SUIT_Condition: 1831 SUIT_Condition //= (suit-condition-vendor-identifier, nil) 1832 SUIT_Condition //= (suit-condition-class-identifier, nil) 1833 SUIT_Condition //= (suit-condition-device-identifier, nil) 1834 SUIT_Condition //= (suit-condition-image-match, nil) 1835 SUIT_Condition //= (suit-condition-image-not-match, nil) 1836 SUIT_Condition //= (suit-condition-use-before, uint) 1837 SUIT_Condition //= (suit-condition-minimum-battery, uint) 1838 SUIT_Condition //= (suit-condition-update-authorised, int) 1839 SUIT_Condition //= (suit-condition-version, SUIT_Condition_Version_Argument) 1840 SUIT_Condition //= (suit-condition-component-offset, uint) 1841 SUIT_Condition //= (suit-condition-custom, bstr) 1843 SUIT_Condition_Version_Argument = [ 1844 suit-condition-version-comparison: SUIT_Condition_Version_Comparison_Types, 1845 suit-condition-version-comparison: SUIT_Condition_Version_Comparison_Value 1846 ] 1847 SUIT_Condition_Version_Comparison_Types /= suit-condition-version-comparison-greater 1848 SUIT_Condition_Version_Comparison_Types /= suit-condition-version-comparison-greater-equal 1849 SUIT_Condition_Version_Comparison_Types /= suit-condition-version-comparison-equal 1850 SUIT_Condition_Version_Comparison_Types /= suit-condition-version-comparison-lesser-equal 1851 SUIT_Condition_Version_Comparison_Types /= suit-condition-version-comparison-lesser 1853 SUIT_Condition_Version_Comparison_Value = [+int] 1855 7.13. SUIT_Directive 1857 Directives are used to define the behaviour of the recipient. 1858 Directives include: 1860 +----------------+----------------------+ 1861 | Directive Code | Directive Name | 1862 +----------------+----------------------+ 1863 | 12 | Set Component Index | 1864 | | | 1865 | 13 | Set Dependency Index | 1866 | | | 1867 | 14 | Abort | 1868 | | | 1869 | 15 | Try Each | 1870 | | | 1871 | 16 | Reserved | 1872 | | | 1873 | 17 | Reserved | 1874 | | | 1875 | 18 | Process Dependency | 1876 | | | 1877 | 19 | Set Parameters | 1878 | | | 1879 | 20 | Override Parameters | 1880 | | | 1881 | 21 | Fetch | 1882 | | | 1883 | 22 | Copy | 1884 | | | 1885 | 23 | Run | 1886 | | | 1887 | 29 | Wait | 1888 | | | 1889 | 30 | Run Sequence | 1890 | | | 1891 | 31 | Run with Arguments | 1892 | | | 1893 | 32 | Swap | 1894 +----------------+----------------------+ 1896 When a Recipient executes a Directive, it MUST report a success code. 1897 If the Directive reports failure, then the current Command Sequence 1898 MUST terminate. 1900 7.13.1. suit-directive-set-component-index 1902 Set Component Index defines the component to which successive 1903 directives and conditions will apply. The supplied argument MUST be 1904 either a boolean or an unsigned integer index into the concatenation 1905 of suit-components and suit-dependency-components. If the following 1906 directives apply to ALL components, then the boolean value "True" is 1907 used instead of an index. True does not apply to dependency 1908 components. If the following directives apply to NO components, then 1909 the boolean value "False" is used. When suit-directive-set- 1910 dependency-index is used, suit-directive-set-component-index = False 1911 is implied. When suit-directive-set-component-index is used, suit- 1912 directive-set-dependency-index = False is implied. 1914 The following CDDL describes the argument to suit-directive-set- 1915 component-index. 1917 SUIT_Directive_Set_Component_Index_Argument = uint/bool 1919 7.13.2. suit-directive-set-dependency-index 1921 Set Dependency Index defines the manifest to which successive 1922 directives and conditions will apply. The supplied argument MUST be 1923 either a boolean or an unsigned integer index into the dependencies. 1924 If the following directives apply to ALL dependencies, then the 1925 boolean value "True" is used instead of an index. If the following 1926 directives apply to NO dependencies, then the boolean value "False" 1927 is used. When suit-directive-set-component-index is used, suit- 1928 directive-set-dependency-index = False is implied. When suit- 1929 directive-set-dependency-index is used, suit-directive-set-component- 1930 index = False is implied. 1932 Typical operations that require suit-directive-set-dependency-index 1933 include setting a source URI, invoking "Fetch," or invoking "Process 1934 Dependency" for an individual dependency. 1936 The following CDDL describes the argument to suit-directive-set- 1937 dependency-index. 1939 SUIT_Directive_Set_Manifest_Index_Argument = uint/bool 1941 7.13.3. suit-directive-abort 1943 Unconditionally fail. This operation is typically used in 1944 conjunction with suit-directive-try-each. 1946 7.13.4. suit-directive-run-sequence 1948 To enable conditional commands, and to allow several strictly ordered 1949 sequences to be executed out-of-order, suit-directive-run-sequence 1950 allows the manifest processor to execute its argument as a 1951 SUIT_Command_Sequence. The argument must be wrapped in a bstr. 1953 When a sequence is executed, any failure of a condition causes 1954 immediate termination of the sequence. 1956 The following CDDL describes the SUIT_Run_Sequence argument. 1958 SUIT_Directive_Run_Sequence_Argument = bstr .cbor SUIT_Command_Sequence 1960 When suit-directive-run-sequence completes, it forwards the last 1961 status code that occurred in the sequence. If the Soft Failure 1962 parameter is true, then suit-directive-run-sequence only fails when a 1963 directive in the argument sequence fails. 1965 SUIT_Parameter_Soft_Failure defaults to False when suit-directive- 1966 run-sequence begins. Its value is discarded when suit-directive-run- 1967 sequence terminates. 1969 7.13.5. suit-directive-try-each 1971 This command runs several SUIT_Command_Sequence, one after another, 1972 in a strict order. Use this command to implement a "try/catch-try/ 1973 catch" sequence. Manifest processors MAY implement this command. 1975 SUIT_Parameter_Soft_Failure is initialised to True at the beginning 1976 of each sequence. If one sequence aborts due to a condition failure, 1977 the next is started. If no sequence completes without condition 1978 failure, then suit-directive-try-each returns an error. If a 1979 particular application calls for all sequences to fail and still 1980 continue, then an empty sequence (nil) can be added to the Try Each 1981 Argument. 1983 The following CDDL describes the SUIT_Try_Each argument. 1985 SUIT_Directive_Try_Each_Argument = [ 1986 + bstr .cbor SUIT_Command_Sequence, 1987 nil / bstr .cbor SUIT_Command_Sequence 1988 ] 1990 7.13.6. suit-directive-process-dependency 1992 Execute the commands in the common section of the current dependency, 1993 followed by the commands in the equivalent section of the current 1994 dependency. For example, if the current section is "fetch payload," 1995 this will execute "common" in the current dependency, then "fetch 1996 payload" in the current dependency. Once this is complete, the 1997 command following suit-directive-process-dependency will be 1998 processed. 2000 If the current dependency is False, this directive has no effect. If 2001 the current dependency is True, then this directive applies to all 2002 dependencies. If the current section is "common," this directive 2003 MUST have no effect. 2005 When SUIT_Process_Dependency completes, it forwards the last status 2006 code that occurred in the dependency. 2008 The argument to suit-directive-process-dependency is defined in the 2009 following CDDL. 2011 SUIT_Directive_Process_Dependency_Argument = nil 2013 7.13.7. suit-directive-set-parameters 2015 suit-directive-set-parameters allows the manifest to configure 2016 behaviour of future directives by changing parameters that are read 2017 by those directives. When dependencies are used, suit-directive-set- 2018 parameters also allows a manifest to modify the behaviour of its 2019 dependencies. 2021 Available parameters are defined in Section 7.6. 2023 If a parameter is already set, suit-directive-set-parameters will 2024 skip setting the parameter to its argument. This provides the core 2025 of the override mechanism, allowing dependent manifests to change the 2026 behaviour of a manifest. 2028 The argument to suit-directive-set-parameters is defined in the 2029 following CDDL. 2031 SUIT_Directive_Set_Parameters_Argument = {+ SUIT_Parameters} 2033 N.B.: A directive code is reserved for an optimisation: a way to set 2034 a parameter to the contents of another parameter, optionally with 2035 another component ID. 2037 7.13.8. suit-directive-override-parameters 2039 suit-directive-override-parameters replaces any listed parameters 2040 that are already set with the values that are provided in its 2041 argument. This allows a manifest to prevent replacement of critical 2042 parameters. 2044 Available parameters are defined in Section 7.6. 2046 The argument to suit-directive-override-parameters is defined in the 2047 following CDDL. 2049 SUIT_Directive_Override_Parameters_Argument = {+ SUIT_Parameters} 2051 7.13.9. suit-directive-fetch 2053 suit-directive-fetch instructs the manifest processor to obtain one 2054 or more manifests or payloads, as specified by the manifest index and 2055 component index, respectively. 2057 suit-directive-fetch can target one or more manifests and one or more 2058 payloads. suit-directive-fetch retrieves each component and each 2059 manifest listed in component-index and manifest-index, respectively. 2060 If component-index or manifest-index is True, instead of an integer, 2061 then all current manifest components/manifests are fetched. The 2062 current manifest's dependent-components are not automatically 2063 fetched. In order to pre-fetch these, they MUST be specified in a 2064 component-index integer. 2066 suit-directive-fetch typically takes no arguments unless one is 2067 needed to modify fetch behaviour. If an argument is needed, it must 2068 be wrapped in a bstr. 2070 suit-directive-fetch reads the URI or URI List parameter to find the 2071 source of the fetch it performs. 2073 The behaviour of suit-directive-fetch can be modified by setting one 2074 or more of SUIT_Parameter_Encryption_Info, 2075 SUIT_Parameter_Compression_Info, SUIT_Parameter_Unpack_Info. These 2076 three parameters each activate and configure a processing step that 2077 can be applied to the data that is transferred during suit-directive- 2078 fetch. 2080 The argument to suit-directive-fetch is defined in the following 2081 CDDL. 2083 SUIT_Directive_Fetch_Argument = nil/bstr 2085 7.13.10. suit-directive-copy 2087 suit-directive-copy instructs the manifest processor to obtain one or 2088 more payloads, as specified by the component index. suit-directive- 2089 copy retrieves each component listed in component-index, 2090 respectively. If component-index is True, instead of an integer, 2091 then all current manifest components are copied. The current 2092 manifest's dependent-components are not automatically copied. In 2093 order to copy these, they MUST be specified in a component-index 2094 integer. 2096 The behaviour of suit-directive-copy can be modified by setting one 2097 or more of SUIT_Parameter_Encryption_Info, 2098 SUIT_Parameter_Compression_Info, SUIT_Parameter_Unpack_Info. These 2099 three parameters each activate and configure a processing step that 2100 can be applied to the data that is transferred during suit-directive- 2101 copy. 2103 *N.B.* Fetch and Copy are very similar. Merging them into one 2104 command may be appropriate. 2106 suit-directive-copy reads its source from 2107 SUIT_Parameter_Source_Component. 2109 The argument to suit-directive-copy is defined in the following CDDL. 2111 SUIT_Directive_Copy_Argument = nil 2113 7.13.11. suit-directive-swap 2115 suit-directive-swap instructs the manifest processor to move the 2116 source to the destination and the destination to the source 2117 simultaneously. Swap has nearly identical semantics to suit- 2118 directive-copy except that suit-directive-swap replaces the source 2119 with the current contents of the destination in an application- 2120 defined way. If SUIT_Parameter_Compression_Info or 2121 SUIT_Parameter_Encryption_Info are present, they must be handled in a 2122 symmetric way, so that the source is decompressed into the 2123 destination and the destination is compressed into the source. The 2124 source is decrypted into the destination and the destination is 2125 encrypted into the source. suit-directive-swap is OPTIONAL to 2126 implement. 2128 7.13.12. suit-directive-run 2130 suit-directive-run directs the manifest processor to transfer 2131 execution to the current Component Index. When this is invoked, the 2132 manifest processor MAY be unloaded and execution continues in the 2133 Component Index. Arguments provided to Run are forwarded to the 2134 executable code located in Component Index, in an application- 2135 specific way. For example, this could form the Linux Kernel Command 2136 Line if booting a linux device. 2138 If the executable code at Component Index is constructed in such a 2139 way that it does not unload the manifest processor, then the manifest 2140 processor may resume execution after the executable completes. This 2141 allows the manifest processor to invoke suitable helpers and to 2142 verify them with image conditions. 2144 The argument to suit-directive-run is defined in the following CDDL. 2146 SUIT_Directive_Run_Argument = nil/bstr 2148 7.13.13. suit-directive-wait 2150 suit-directive-wait directs the manifest processor to pause until a 2151 specified event occurs. Some possible events include: 2153 1. Authorisation 2155 2. External Power 2157 3. Network availability 2159 4. Other Device Firmware Version 2161 5. Time 2163 6. Time of Day 2165 7. Day of Week 2167 The following CDDL defines the encoding of these events. 2169 SUIT_Wait_Events //= (suit-wait-event-authorisation => int) 2170 SUIT_Wait_Events //= (suit-wait-event-power => int) 2171 SUIT_Wait_Events //= (suit-wait-event-network => int) 2172 SUIT_Wait_Events //= (suit-wait-event-other-device-version 2173 => SUIT_Wait_Event_Argument_Other_Device_Version) 2174 SUIT_Wait_Events //= (suit-wait-event-time => uint); Timestamp 2175 SUIT_Wait_Events //= (suit-wait-event-time-of-day 2176 => uint); Time of Day (seconds since 00:00:00) 2177 SUIT_Wait_Events //= (suit-wait-event-day-of-week 2178 => uint); Days since Sunday 2180 SUIT_Wait_Event_Argument_Authorisation = int ; priority 2181 SUIT_Wait_Event_Argument_Power = int ; Power Level 2182 SUIT_Wait_Event_Argument_Network = int ; Network State 2183 SUIT_Wait_Event_Argument_Other_Device_Version = [ 2184 other-device: bstr, 2185 other-device-version: [+int] 2186 ] 2187 SUIT_Wait_Event_Argument_Time = uint ; Timestamp 2188 SUIT_Wait_Event_Argument_Time_Of_Day = uint ; Time of Day (seconds since 00:00:00) 2189 SUIT_Wait_Event_Argument_Day_Of_Week = uint ; Days since Sunday 2190 7.13.14. SUIT_Directive CDDL 2192 The following CDDL describes SUIT_Directive: 2194 SUIT_Directive //= (suit-directive-set-component-index, uint/bool) 2195 SUIT_Directive //= (suit-directive-set-dependency-index, uint/bool) 2196 SUIT_Directive //= (suit-directive-run-sequence, 2197 bstr .cbor SUIT_Command_Sequence) 2198 SUIT_Directive //= (suit-directive-try-each, 2199 SUIT_Directive_Try_Each_Argument) 2200 SUIT_Directive //= (suit-directive-process-dependency, nil) 2201 SUIT_Directive //= (suit-directive-set-parameters, 2202 {+ SUIT_Parameters}) 2203 SUIT_Directive //= (suit-directive-override-parameters, 2204 {+ SUIT_Parameters}) 2205 SUIT_Directive //= (suit-directive-fetch, nil) 2206 SUIT_Directive //= (suit-directive-copy, nil) 2207 SUIT_Directive //= (suit-directive-run, nil) 2208 SUIT_Directive //= (suit-directive-wait, 2209 { + SUIT_Wait_Events }) 2210 SUIT_Directive //= (suit-directive-run-with-arguments, bstr) 2212 SUIT_Directive_Try_Each_Argument = [ 2213 + bstr .cbor SUIT_Command_Sequence, 2214 nil / bstr .cbor SUIT_Command_Sequence 2215 ] 2217 SUIT_Wait_Events //= (suit-wait-event-authorisation => int) 2218 SUIT_Wait_Events //= (suit-wait-event-power => int) 2219 SUIT_Wait_Events //= (suit-wait-event-network => int) 2220 SUIT_Wait_Events //= (suit-wait-event-other-device-version 2221 => SUIT_Wait_Event_Argument_Other_Device_Version) 2222 SUIT_Wait_Events //= (suit-wait-event-time => uint); Timestamp 2223 SUIT_Wait_Events //= (suit-wait-event-time-of-day 2224 => uint); Time of Day (seconds since 00:00:00) 2225 SUIT_Wait_Events //= (suit-wait-event-day-of-week 2226 => uint); Days since Sunday 2228 SUIT_Wait_Event_Argument_Authorisation = int ; priority 2229 SUIT_Wait_Event_Argument_Power = int ; Power Level 2230 SUIT_Wait_Event_Argument_Network = int ; Network State 2231 SUIT_Wait_Event_Argument_Other_Device_Version = [ 2232 other-device: bstr, 2233 other-device-version: [+int] 2234 ] 2235 SUIT_Wait_Event_Argument_Time = uint ; Timestamp 2236 SUIT_Wait_Event_Argument_Time_Of_Day = uint ; Time of Day (seconds since 00:00:00) 2237 SUIT_Wait_Event_Argument_Day_Of_Week = uint ; Days since Sunday 2238 7.14. SUIT_Text_Map 2240 The SUIT_Text_Map contains all text descriptions needed for this 2241 manifest. The text section is typically severable, allowing 2242 manifests to be distributed without the text, since end-nodes do not 2243 require text. The meaning of each field is described below. 2245 Each section MAY be present. If present, each section MUST be as 2246 described. Negative integer IDs are reserved for application- 2247 specific text values. 2249 +----+-----------------------+--------------------------------------+ 2250 | ID | Name | Summary | 2251 +----+-----------------------+--------------------------------------+ 2252 | 1 | manifest-description | Free text description of the | 2253 | | | manifest | 2254 | | | | 2255 | 2 | update-description | Free text description of the update | 2256 | | | | 2257 | 3 | vendor-name | Free text vendor name | 2258 | | | | 2259 | 4 | model-name | Free text model name | 2260 | | | | 2261 | 5 | vendor-domain | The domain used to create the | 2262 | | | vendor-id (Section 7.12.9.1) | 2263 | | | | 2264 | 6 | model-info | The information used to create the | 2265 | | | class-id (Section 7.12.9.1) | 2266 | | | | 2267 | 7 | component-description | Free text description of each | 2268 | | | component in the manifest | 2269 | | | | 2270 | 8 | json-source | The JSON-formated document that was | 2271 | | | used to create the manifest | 2272 | | | | 2273 | 9 | yaml-source | The yaml-formated document that was | 2274 | | | used to create the manifest | 2275 | | | | 2276 | 10 | version-dependencies | List of component versions required | 2277 | | | by the manifest | 2278 +----+-----------------------+--------------------------------------+ 2280 8. Access Control Lists 2282 To manage permissions in the manifest, there are three models that 2283 can be used. 2285 First, the simplest model requires that all manifests are 2286 authenticated by a single trusted key. This mode has the advantage 2287 that only a root manifest needs to be authenticated, since all of its 2288 dependencies have digests included in the root manifest. 2290 This simplest model can be extended by adding key delegation without 2291 much increase in complexity. 2293 A second model requires an ACL to be presented to the device, 2294 authenticated by a trusted party or stored on the device. This ACL 2295 grants access rights for specific component IDs or component ID 2296 prefixes to the listed identities or identity groups. Any identity 2297 may verify an image digest, but fetching into or fetching from a 2298 component ID requires approval from the ACL. 2300 A third model allows a device to provide even more fine-grained 2301 controls: The ACL lists the component ID or component ID prefix that 2302 an identity may use, and also lists the commands that the identity 2303 may use in combination with that component ID. 2305 9. SUIT digest container 2307 RFC 8152 [RFC8152] provides containers for signature, MAC, and 2308 encryption, but no basic digest container. The container needed for 2309 a digest requires a type identifier and a container for the raw 2310 digest data. Some forms of digest may require additional parameters. 2311 These can be added following the digest. This structure is described 2312 by the following CDDL. 2314 The algorithms listed are sufficient for verifying integrity of 2315 Firmware Updates as of this writing, however this may change over 2316 time. 2318 SUIT_Digest = [ 2319 suit-digest-algorithm-id : $suit-digest-algorithm-ids, 2320 suit-digest-bytes : bytes, 2321 ? suit-digest-parameters : any 2322 ] 2324 digest-algorithm-ids /= algorithm-id-sha224 2325 digest-algorithm-ids /= algorithm-id-sha256 2326 digest-algorithm-ids /= algorithm-id-sha384 2327 digest-algorithm-ids /= algorithm-id-sha512 2328 digest-algorithm-ids /= algorithm-id-sha3-224 2329 digest-algorithm-ids /= algorithm-id-sha3-256 2330 digest-algorithm-ids /= algorithm-id-sha3-384 2331 digest-algorithm-ids /= algorithm-id-sha3-512 2333 algorithm-id-sha224 = 1 2334 algorithm-id-sha256 = 2 2335 algorithm-id-sha384 = 3 2336 algorithm-id-sha512 = 4 2337 algorithm-id-sha3-224 = 5 2338 algorithm-id-sha3-256 = 6 2339 algorithm-id-sha3-384 = 7 2340 algorithm-id-sha3-512 = 8 2342 10. Creating conditional sequences 2344 For some use cases, it is important to provide a sequence that can 2345 fail without terminating an update. For example, a dual-image XIP 2346 MCU may require an update that can be placed at one of two offsets. 2347 This has two implications, first, the digest of each offset will be 2348 different. Second, the image fetched for each offset will have a 2349 different URI. Conditional sequences allow this to be resolved in a 2350 simple way. 2352 The following JSON representation of a manifest demonstrates how this 2353 would be represented. It assumes that the bootloader and manifest 2354 processor take care of A/B switching and that the manifest is not 2355 aware of this distinction. 2357 { 2358 "structure-version" : 1, 2359 "sequence-number" : 7, 2360 "common" :{ 2361 "components" : [ 2362 [b'0'] 2363 ], 2364 "common-sequence" : [ 2365 { 2366 "directive-set-var" : { 2367 "size": 32567 2368 }, 2369 }, 2370 { 2371 "try-each" : [ 2372 [ 2373 {"condition-component-offset" : ""}, 2374 { 2375 "directive-set-var": { 2376 "digest" : "" 2377 } 2378 } 2379 ], 2380 [ 2381 {"condition-component-offset" : ""}, 2382 { 2383 "directive-set-var": { 2384 "digest" : "" 2385 } 2386 } 2387 ], 2388 [{ "abort" : null }] 2389 ] 2390 } 2391 ] 2392 } 2393 "fetch" : [ 2394 { 2395 "try-each" : [ 2396 [ 2397 {"condition-component-offset" : ""}, 2398 { 2399 "directive-set-var": { 2400 "uri" : "" 2401 } 2402 } 2403 ], 2404 [ 2405 {"condition-component-offset" : ""}, 2406 { 2407 "directive-set-var": { 2408 "uri" : "" 2409 } 2410 } 2411 ], 2412 [{ "directive-abort" : null }] 2413 ] 2415 }, 2416 "fetch" : null 2417 ] 2418 } 2420 11. Full CDDL 2422 In order to create a valid SUIT Manifest document the structure of 2423 the corresponding CBOR message MUST adhere to the following CDDL data 2424 definition. 2426 SUIT_Outer_Wrapper = { 2427 suit-authentication-wrapper => bstr .cbor SUIT_Authentication_Wrapper / nil, 2428 $$SUIT_Manifest_Wrapped, 2429 suit-dependency-resolution => bstr .cbor SUIT_Command_Sequence, 2430 suit-payload-fetch => bstr .cbor SUIT_Command_Sequence, 2431 suit-install => bstr .cbor SUIT_Command_Sequence, 2432 suit-text => bstr .cbor SUIT_Text_Map, 2433 suit-coswid => bstr .cbor concise-software-identity 2434 } 2436 SUIT_Authentication_Wrapper = [ + ( 2437 COSE_Mac_Tagged / 2438 COSE_Sign_Tagged / 2439 COSE_Mac0_Tagged / 2440 COSE_Sign1_Tagged) 2441 ] 2443 SUIT_Encryption_Wrapper = COSE_Encrypt_Tagged / COSE_Encrypt0_Tagged 2445 $$SUIT_Manifest_Wrapped //= (suit-manifest => bstr .cbor SUIT_Manifest) 2446 $$SUIT_Manifest_Wrapped //= ( 2447 suit-manifest-encryption-info => bstr .cbor SUIT_Encryption_Wrapper, 2448 suit-manifest-encrypted => bstr 2449 ) 2451 COSE_Mac_Tagged = any 2452 COSE_Sign_Tagged = any 2453 COSE_Mac0_Tagged = any 2454 COSE_Sign1_Tagged = any 2455 COSE_Encrypt_Tagged = any 2456 COSE_Encrypt0_Tagged = any 2458 SUIT_Digest = [ 2459 suit-digest-algorithm-id : $suit-digest-algorithm-ids, 2460 suit-digest-bytes : bstr, 2461 ? suit-digest-parameters : any 2462 ] 2463 ; Named Information Hash Algorithm Identifiers 2464 suit-digest-algorithm-ids /= algorithm-id-sha224 2465 suit-digest-algorithm-ids /= algorithm-id-sha256 2466 suit-digest-algorithm-ids /= algorithm-id-sha384 2467 suit-digest-algorithm-ids /= algorithm-id-sha512 2468 suit-digest-algorithm-ids /= algorithm-id-sha3-224 2469 suit-digest-algorithm-ids /= algorithm-id-sha3-256 2470 suit-digest-algorithm-ids /= algorithm-id-sha3-384 2471 suit-digest-algorithm-ids /= algorithm-id-sha3-512 2473 algorithm-id-sha224 = 1 2474 algorithm-id-sha256 = 2 2475 algorithm-id-sha384 = 3 2476 algorithm-id-sha512 = 4 2477 algorithm-id-sha3-224 = 5 2478 algorithm-id-sha3-256 = 6 2479 algorithm-id-sha3-384 = 7 2480 algorithm-id-sha3-512 = 8 2482 SUIT_Manifest = { 2483 suit-manifest-version => 1, 2484 suit-manifest-sequence-number => uint, 2485 ? suit-common => bstr .cbor SUIT_Common, 2486 ? suit-dependency-resolution => SUIT_Digest / bstr .cbor SUIT_Command_Sequence, 2487 ? suit-payload-fetch => SUIT_Digest / bstr .cbor SUIT_Command_Sequence, 2488 ? suit-install => SUIT_Digest / bstr .cbor SUIT_Command_Sequence, 2489 ? suit-validate => bstr .cbor SUIT_Command_Sequence, 2490 ? suit-load => bstr .cbor SUIT_Command_Sequence, 2491 ? suit-run => bstr .cbor SUIT_Command_Sequence, 2492 ? suit-text => SUIT_Digest, 2493 ? suit-coswid => SUIT_Digest / bstr .cbor concise-software-identity, 2494 } 2496 SUIT_Common = { 2497 ? suit-dependencies => bstr .cbor SUIT_Dependencies, 2498 ? suit-components => bstr .cbor SUIT_Components, 2499 ? suit-dependency-components => bstr .cbor SUIT_Component_References, 2500 ? suit-common-sequence => bstr .cbor SUIT_Command_Sequence, 2501 } 2503 SUIT_Dependencies = [ + SUIT_Dependency ] 2504 SUIT_Components = [ + SUIT_Component_Identifier ] 2505 SUIT_Component_References = [ + SUIT_Component_Reference ] 2507 concise-software-identity = any 2509 SUIT_Dependency = { 2510 suit-dependency-digest => SUIT_Digest, 2511 suit-dependency-prefix => SUIT_Component_Identifier, 2512 } 2514 SUIT_Component_Identifier = [* bstr] 2516 SUIT_Component_Reference = { 2517 suit-component-identifier => SUIT_Component_Identifier, 2518 suit-component-dependency-index => uint 2519 } 2521 SUIT_Command_Sequence = [ + (SUIT_Condition // SUIT_Directive // SUIT_Command_Custom) ] 2523 SUIT_Command_Custom = (nint, bstr) 2524 SUIT_Condition //= (suit-condition-vendor-identifier, nil) 2525 SUIT_Condition //= (suit-condition-class-identifier, nil) 2526 SUIT_Condition //= (suit-condition-device-identifier, nil) 2527 SUIT_Condition //= (suit-condition-image-match, nil) 2528 SUIT_Condition //= (suit-condition-image-not-match, nil) 2529 SUIT_Condition //= (suit-condition-use-before, uint) 2530 SUIT_Condition //= (suit-condition-minimum-battery, uint) 2531 SUIT_Condition //= (suit-condition-update-authorised, int) 2532 SUIT_Condition //= (suit-condition-version, SUIT_Condition_Version_Argument) 2533 SUIT_Condition //= (suit-condition-component-offset, uint) 2534 SUIT_Condition //= (suit-condition-custom, bstr) 2536 RFC4122_UUID = bstr .size 16 2538 SUIT_Condition_Version_Argument = [ 2539 suit-condition-version-comparison-type: SUIT_Condition_Version_Comparison_Types, 2540 suit-condition-version-comparison-value: SUIT_Condition_Version_Comparison_Value 2541 ] 2542 SUIT_Condition_Version_Comparison_Types /= suit-condition-version-comparison-greater 2543 SUIT_Condition_Version_Comparison_Types /= suit-condition-version-comparison-greater-equal 2544 SUIT_Condition_Version_Comparison_Types /= suit-condition-version-comparison-equal 2545 SUIT_Condition_Version_Comparison_Types /= suit-condition-version-comparison-lesser-equal 2546 SUIT_Condition_Version_Comparison_Types /= suit-condition-version-comparison-lesser 2548 suit-condition-version-comparison-greater = 1 2549 suit-condition-version-comparison-greater-equal = 2 2550 suit-condition-version-comparison-equal = 3 2551 suit-condition-version-comparison-lesser-equal = 4 2552 suit-condition-version-comparison-lesser = 5 2554 SUIT_Condition_Version_Comparison_Value = [+int] 2556 SUIT_Directive //= (suit-directive-set-component-index, uint/bool) 2557 SUIT_Directive //= (suit-directive-set-dependency-index, uint/bool) 2558 SUIT_Directive //= (suit-directive-run-sequence, bstr .cbor SUIT_Command_Sequence) 2559 SUIT_Directive //= (suit-directive-try-each, SUIT_Directive_Try_Each_Argument) 2560 SUIT_Directive //= (suit-directive-process-dependency, nil) 2561 SUIT_Directive //= (suit-directive-set-parameters, {+ SUIT_Parameters}) 2562 SUIT_Directive //= (suit-directive-override-parameters, {+ SUIT_Parameters}) 2563 SUIT_Directive //= (suit-directive-fetch, nil) 2564 SUIT_Directive //= (suit-directive-copy, nil) 2565 SUIT_Directive //= (suit-directive-swap, nil) 2566 SUIT_Directive //= (suit-directive-run, nil) 2567 SUIT_Directive //= (suit-directive-wait, { + SUIT_Wait_Events }) 2568 SUIT_Directive //= (suit-directive-run-with-arguments, bstr) 2570 SUIT_Directive_Try_Each_Argument = [ 2571 + bstr .cbor SUIT_Command_Sequence, 2572 nil / bstr .cbor SUIT_Command_Sequence 2573 ] 2575 SUIT_Wait_Events //= (suit-wait-event-authorisation => int) 2576 SUIT_Wait_Events //= (suit-wait-event-power => int) 2577 SUIT_Wait_Events //= (suit-wait-event-network => int) 2578 SUIT_Wait_Events //= (suit-wait-event-other-device-version 2579 => SUIT_Wait_Event_Argument_Other_Device_Version) 2580 SUIT_Wait_Events //= (suit-wait-event-time => uint); Timestamp 2581 SUIT_Wait_Events //= (suit-wait-event-time-of-day 2582 => uint); Time of Day (seconds since 00:00:00) 2583 SUIT_Wait_Events //= (suit-wait-event-day-of-week 2584 => uint); Days since Sunday 2586 SUIT_Wait_Event_Argument_Authorisation = int ; priority 2587 SUIT_Wait_Event_Argument_Power = int ; Power Level 2588 SUIT_Wait_Event_Argument_Network = int ; Network State 2589 SUIT_Wait_Event_Argument_Other_Device_Version = [ 2590 other-device: bstr, 2591 other-device-version: [+int] 2592 ] 2593 SUIT_Wait_Event_Argument_Time = uint ; Timestamp 2594 SUIT_Wait_Event_Argument_Time_Of_Day = uint ; Time of Day (seconds since 00:00:00) 2595 SUIT_Wait_Event_Argument_Day_Of_Week = uint ; Days since Sunday 2597 SUIT_Parameters //= (suit-parameter-strict-order => bool) 2598 SUIT_Parameters //= (suit-parameter-soft-failure => bool) 2599 SUIT_Parameters //= (suit-parameter-vendor-id => bstr) 2600 SUIT_Parameters //= (suit-parameter-class-id => bstr) 2601 SUIT_Parameters //= (suit-parameter-device-id => bstr) 2602 SUIT_Parameters //= (suit-parameter-uri => tstr) 2603 SUIT_Parameters //= (suit-parameter-encryption-info => bstr .cbor SUIT_Encryption_Info) 2604 SUIT_Parameters //= (suit-parameter-compression-info => bstr .cbor SUIT_Compression_Info) 2605 SUIT_Parameters //= (suit-parameter-unpack-info => bstr .cbor SUIT_Unpack_Info) 2606 SUIT_Parameters //= (suit-parameter-source-component => uint) 2607 SUIT_Parameters //= (suit-parameter-image-digest => bstr .cbor SUIT_Digest) 2608 SUIT_Parameters //= (suit-parameter-image-size => uint) 2609 SUIT_Parameters //= (suit-parameter-uri-list => bstr .cbor SUIT_Component_URI_List) 2610 SUIT_Parameters //= (suit-parameter-custom => int/bool/tstr/bstr) 2612 SUIT_Component_URI_List = [ + [priority: int, uri: tstr] ] 2613 SUIT_Priority_Parameter_List = [ + [priority: int, parameters: { + SUIT_Parameters }] ] 2615 SUIT_Encryption_Info = COSE_Encrypt_Tagged/COSE_Encrypt0_Tagged 2616 SUIT_Compression_Info = { 2617 suit-compression-algorithm => SUIT_Compression_Algorithms, 2618 ? suit-compression-parameters => bstr 2619 } 2621 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_gzip 2622 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_bzip2 2623 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_lz4 2624 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_lzma 2626 SUIT_Compression_Algorithm_gzip = 1 2627 SUIT_Compression_Algorithm_bzip2 = 2 2628 SUIT_Compression_Algorithm_deflate = 3 2629 SUIT_Compression_Algorithm_lz4 = 4 2630 SUIT_Compression_Algorithm_lzma = 7 2632 SUIT_Unpack_Info = { 2633 suit-unpack-algorithm => SUIT_Unpack_Algorithms, 2634 ? suit-unpack-parameters => bstr 2635 } 2637 SUIT_Unpack_Algorithms /= SUIT_Unpack_Algorithm_Delta 2638 SUIT_Unpack_Algorithms /= SUIT_Unpack_Algorithm_Hex 2639 SUIT_Unpack_Algorithms /= SUIT_Unpack_Algorithm_Elf 2641 SUIT_Unpack_Algorithm_Delta = 1 2642 SUIT_Unpack_Algorithm_Hex = 2 2643 SUIT_Unpack_Algorithm_Elf = 3 2645 SUIT_Text_Map = {int => tstr} 2647 suit-authentication-wrapper = 1 2648 suit-manifest = 2 2650 suit-manifest-encryption-info = 3 2651 suit-manifest-encrypted = 4 2652 suit-manifest-version = 1 2653 suit-manifest-sequence-number = 2 2654 suit-common = 3 2655 suit-dependency-resolution = 7 2656 suit-payload-fetch = 8 2657 suit-install = 9 2658 suit-validate = 10 2659 suit-load = 11 2660 suit-run = 12 2661 suit-text = 13 2662 suit-coswid = 14 2664 suit-dependencies = 1 2665 suit-components = 2 2666 suit-dependency-components = 3 2667 suit-common-sequence = 4 2669 suit-dependency-digest = 1 2670 suit-dependency-prefix = 2 2672 suit-component-identifier = 1 2673 suit-component-dependency-index = 2 2675 suit-command-custom = nint 2677 suit-condition-vendor-identifier = 1 2678 suit-condition-class-identifier = 2 2679 suit-condition-image-match = 3 2680 suit-condition-use-before = 4 2681 suit-condition-component-offset = 5 2682 suit-condition-custom = 6 2684 suit-condition-device-identifier = 24 2685 suit-condition-image-not-match = 25 2686 suit-condition-minimum-battery = 26 2687 suit-condition-update-authorised = 27 2688 suit-condition-version = 28 2690 suit-directive-set-component-index = 12 2691 suit-directive-set-dependency-index = 13 2692 suit-directive-abort = 14 2693 suit-directive-try-each = 15 2694 suit-directive-do-each = 16 ; TBD 2695 suit-directive-map-filter = 17 ; TBD 2696 suit-directive-process-dependency = 18 2697 suit-directive-set-parameters = 19 2698 suit-directive-override-parameters = 20 2699 suit-directive-fetch = 21 2700 suit-directive-copy = 22 2701 suit-directive-run = 23 2703 suit-directive-wait = 29 2704 suit-directive-run-sequence = 30 2705 suit-directive-run-with-arguments = 31 2706 suit-directive-swap = 32 2708 suit-wait-event-argument-authorisation = 1 2709 suit-wait-event-power = 2 2710 suit-wait-event-network = 3 2711 suit-wait-event-other-device-version = 4 2712 suit-wait-event-time = 5 2713 suit-wait-event-time-of-day = 6 2714 suit-wait-event-day-of-week = 7 2715 suit-wait-event-authorisation = 8 2717 suit-parameter-strict-order = 1 2718 suit-parameter-soft-failure = 2 2719 suit-parameter-vendor-id = 3 2720 suit-parameter-class-id = 4 2721 suit-parameter-device-id = 5 2722 suit-parameter-uri = 6 2723 suit-parameter-encryption-info = 7 2724 suit-parameter-compression-info = 8 2725 suit-parameter-unpack-info = 9 2726 suit-parameter-source-component = 10 2727 suit-parameter-image-digest = 11 2728 suit-parameter-image-size = 12 2730 suit-parameter-uri-list = 24 2731 suit-parameter-uri-list-append = 25 2732 suit-parameter-prioritised-parameters = 26 2734 suit-parameter-custom = nint 2736 suit-compression-algorithm = 1 2737 suit-compression-parameters = 2 2739 suit-unpack-algorithm = 1 2740 suit-unpack-parameters = 2 2742 suit-text-manifest-description = 1 2743 suit-text-update-description = 2 2744 suit-text-vendor-name = 3 2745 suit-text-model-name = 4 2746 suit-text-vendor-domain = 5 2747 suit-text-model-info = 6 2748 suit-text-component-description = 7 2749 suit-text-manifest-json-source = 8 2750 suit-text-manifest-yaml-source = 9 2751 suit-text-version-dependencies = 10 2753 12. Examples 2755 The following examples demonstrate a small subset of the 2756 functionality of the manifest. However, despite this, even a simple 2757 manifest processor can execute most of these manifests. 2759 The examples are signed using the following ECDSA secp256r1 key: 2761 -----BEGIN PRIVATE KEY----- 2762 MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgApZYjZCUGLM50VBC 2763 CjYStX+09jGmnyJPrpDLTz/hiXOhRANCAASEloEarguqq9JhVxie7NomvqqL8Rtv 2764 P+bitWWchdvArTsfKktsCYExwKNtrNHXi9OB3N+wnAUtszmR23M4tKiW 2765 -----END PRIVATE KEY----- 2767 The corresponding public key can be used to verify these examples: 2769 -----BEGIN PUBLIC KEY----- 2770 MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEhJaBGq4LqqvSYVcYnuzaJr6qi/Eb 2771 bz/m4rVlnIXbwK07HypLbAmBMcCjbazR14vTgdzfsJwFLbM5kdtzOLSolg== 2772 -----END PUBLIC KEY----- 2774 12.1. Example 0: 2776 Secure boot only. 2778 The following JSON shows the intended behaviour of the manifest. 2780 { 2781 "structure-version": 1, 2782 "sequence-number": 1, 2783 "run-image": [ 2784 { "directive-set-component": 0 }, 2785 { "condition-image": null }, 2786 { "directive-run": null } 2787 ], 2788 "common": { 2789 "common-sequence": [ 2790 { 2791 "directive-set-var": { 2792 "digest": "00112233445566778899aabbccddeeff" 2793 "0123456789abcdeffedcba9876543210", 2794 "size": 34768 2795 } 2796 } 2797 ], 2798 "components": [ 2799 [ 2800 "Flash", 2801 78848 2802 ] 2803 ] 2804 } 2805 } 2807 Converted into the SUIT manifest, this produces: 2809 { 2810 / auth object / 1 : h'd28443a10126a1044874657374206b6579f65840ebec' 2811 h'b66cbecb19dcedacf8459c1a22a1453781ba98d8ffb9' 2812 h'd4e2912f29d23bac5ae3d51f1ff0c1b1df05e207ca17' 2813 h'483a57ede914cf826b73599137881c8364c8', 2814 / manifest / 2 : h'a401010201035840a2024c818245466c6173684300340104' 2815 h'582e8213a20b58248202582000112233445566778899aabb' 2816 h'ccddeeff0123456789abcdeffedcba98765432100c1987d0' 2817 h'0c47860c0003f617f6' \ 2818 { 2819 / structure-version / 1 : 1, 2820 / sequence-number / 2 : 1, 2821 / common / 3 : h'a2024c818245466c6173684300340104582e8213a20b58' 2822 h'248202582000112233445566778899aabbccddeeff0123' 2823 h'456789abcdeffedcba98765432100c1987d0' \ { 2824 / components / 2 : h'818245466c61736843003401' \ 2825 [ 2826 [h'466c617368', h'003401'], 2827 ], 2828 / common-sequence / 4 : h'8213a20b582482025820001122334455' 2829 h'66778899aabbccddeeff0123456789ab' 2830 h'cdeffedcba98765432100c1987d0' \ [ 2831 / set-vars / 19, { 2832 / digest / 11 : h'8202582000112233445566778899aabb' 2833 h'ccddeeff0123456789abcdeffedcba98' 2834 h'76543210' \ 2835 [ 2, h'00112233445566778899aabbccddeeff01234567' 2836 h'89abcdeffedcba9876543210' ], 2837 / size / 12 : 34768, 2838 }, 2839 ], 2840 }, 2841 / run-image / 12 : h'860c0003f617f6' \ [ 2842 / set-component-index / 12, 0, 2843 / condition-image / 3, None, 2844 / run / 23, None, 2845 ], 2846 } 2847 } 2849 Total size of outer wrapper without COSE authentication object: 87 2851 Outer: 2853 a201f6025851a401010201035840a2024c818245466c6173684300340104582e8213a20b 2854 58248202582000112233445566778899aabbccddeeff0123456789abcdeffedcba987654 2855 32100c1987d00c47860c0003f617f6 2856 Total size of outer wrapper with COSE authentication object: 172 2858 Signed Outer: 2860 a2015854d28443a10126a1044874657374206b6579f65840ebecb66cbecb19dcedacf845 2861 9c1a22a1453781ba98d8ffb9d4e2912f29d23bac5ae3d51f1ff0c1b1df05e207ca17483a 2862 57ede914cf826b73599137881c8364c8025851a401010201035840a2024c818245466c61 2863 73684300340104582e8213a20b58248202582000112233445566778899aabbccddeeff01 2864 23456789abcdeffedcba98765432100c1987d00c47860c0003f617f6 2866 12.2. Example 1: 2868 Simultaneous download and installation of payload. 2870 The following JSON shows the intended behaviour of the manifest. 2872 { 2873 "structure-version": 1, 2874 "sequence-number": 2, 2875 "apply-image": [ 2876 { "directive-set-component": 0 }, 2877 { 2878 "directive-set-var": { 2879 "uri": "http://example.com/file.bin" 2880 } 2881 }, 2882 { "directive-fetch": null } 2883 ], 2884 "common": { 2885 "common-sequence": [ 2886 { 2887 "directive-set-var": { 2888 "digest": "00112233445566778899aabbccddeeff" 2889 "0123456789abcdeffedcba9876543210", 2890 "size": 34768 2891 } 2892 } 2893 ], 2894 "components": [ 2895 [ 2896 "Flash", 2897 78848 2898 ] 2899 ] 2900 } 2901 } 2903 Converted into the SUIT manifest, this produces: 2905 { 2906 / auth object / 1 : h'd28443a10126a1044874657374206b6579f65840b531' 2907 h'42132ebddbf0c523378d16fc904badc56553e41c6713' 2908 h'b758dbd39f47effec5e7a583c418129f456d0aaaa3c4' 2909 h'3fe06dd30d664b709edf0ad05b70dad38bc2', 2910 / manifest / 2 : h'a401010202035840a2024c818245466c6173684300340104' 2911 h'582e8213a20b58248202582000112233445566778899aabb' 2912 h'ccddeeff0123456789abcdeffedcba98765432100c1987d0' 2913 h'095825860c0013a106781b687474703a2f2f6578616d706c' 2914 h'652e636f6d2f66696c652e62696e15f6' \ 2915 { 2916 / structure-version / 1 : 1, 2917 / sequence-number / 2 : 2, 2918 / common / 3 : h'a2024c818245466c6173684300340104582e8213a20b58' 2919 h'248202582000112233445566778899aabbccddeeff0123' 2920 h'456789abcdeffedcba98765432100c1987d0' \ { 2921 / components / 2 : h'818245466c61736843003401' \ 2922 [ 2923 [h'466c617368', h'003401'], 2924 ], 2925 / common-sequence / 4 : h'8213a20b582482025820001122334455' 2926 h'66778899aabbccddeeff0123456789ab' 2927 h'cdeffedcba98765432100c1987d0' \ [ 2928 / set-vars / 19, { 2929 / digest / 11 : h'8202582000112233445566778899aabb' 2930 h'ccddeeff0123456789abcdeffedcba98' 2931 h'76543210' \ 2932 [ 2, h'00112233445566778899aabbccddeeff01234567' 2933 h'89abcdeffedcba9876543210' ], 2934 / size / 12 : 34768, 2935 }, 2936 ], 2937 }, 2938 / apply-image / 9 : h'860c0013a106781b687474703a2f2f6578616d70' 2939 h'6c652e636f6d2f66696c652e62696e15f6' \ [ 2940 / set-component-index / 12, 0, 2941 / set-vars / 19, { 2942 / uri / 6 : http://example.com/file.bin, 2943 }, 2944 / fetch / 21, None, 2945 ], 2946 } 2947 } 2949 Total size of outer wrapper without COSE authentication object: 118 2951 Outer: 2953 a201f6025870a401010202035840a2024c818245466c6173684300340104582e8213a20b 2954 58248202582000112233445566778899aabbccddeeff0123456789abcdeffedcba987654 2955 32100c1987d0095825860c0013a106781b687474703a2f2f6578616d706c652e636f6d2f 2956 66696c652e62696e15f6 2958 Total size of outer wrapper with COSE authentication object: 203 2960 Signed Outer: 2962 a2015854d28443a10126a1044874657374206b6579f65840b53142132ebddbf0c523378d 2963 16fc904badc56553e41c6713b758dbd39f47effec5e7a583c418129f456d0aaaa3c43fe0 2964 6dd30d664b709edf0ad05b70dad38bc2025870a401010202035840a2024c818245466c61 2965 73684300340104582e8213a20b58248202582000112233445566778899aabbccddeeff01 2966 23456789abcdeffedcba98765432100c1987d0095825860c0013a106781b687474703a2f 2967 2f6578616d706c652e636f6d2f66696c652e62696e15f6 2969 12.3. Example 2: 2971 Compatibility test, simultaneous download and installation, and 2972 secure boot. 2974 The following JSON shows the intended behaviour of the manifest. 2976 { 2977 "structure-version": 1, 2978 "sequence-number": 3, 2979 "common": { 2980 "common-sequence": [ 2981 { 2982 "directive-set-var": { 2983 "vendor-id": "fa6b4a53-d5ad-5fdf-be9d-e663e4d41ffe", 2984 "class-id": "1492af14-2569-5e48-bf42-9b2d51f2ab45", 2985 "digest": "00112233445566778899aabbccddeeff" 2986 "0123456789abcdeffedcba9876543210", 2987 "size": 34768 2988 } 2989 }, 2990 { "condition-vendor-id": null }, 2991 { "condition-class-id": null } 2992 ], 2993 "components": [ 2994 [ 2995 "Flash", 2996 78848 2997 ] 2998 ] 2999 }, 3000 "apply-image": [ 3001 { "directive-set-component": 0 }, 3002 { 3003 "directive-set-var": { 3004 "uri": "http://example.com/file.bin" 3005 } 3006 }, 3007 { "directive-fetch": null } 3008 ], 3009 "run-image": [ 3010 { "directive-set-component": 0 }, 3011 { "condition-image": null }, 3012 { "directive-run": null } 3013 ] 3014 } 3016 Converted into the SUIT manifest, this produces: 3018 { 3019 / auth object / 1 : h'd28443a10126a1044874657374206b6579f658400014' 3020 h'750c013f7e1cdbec6f14b99b49195e081d1030508a6b' 3021 h'8d271bd99dfb382a7767dc45f20c9943ed22a1eaac9d' 3022 h'07a041ec1acfc10ad7e45e6424629ff3e3e5', 3023 / manifest / 2 : h'a501010203035868a2024c818245466c6173684300340104' 3024 h'58568613a40350fa6b4a53d5ad5fdfbe9de663e4d41ffe04' 3025 h'501492af1425695e48bf429b2d51f2ab450b582482025820' 3026 h'00112233445566778899aabbccddeeff0123456789abcdef' 3027 h'fedcba98765432100c1987d001f602f6095825860c0013a1' 3028 h'06781b687474703a2f2f6578616d706c652e636f6d2f6669' 3029 h'6c652e62696e15f60c47860c0003f617f6' \ 3030 { 3031 / structure-version / 1 : 1, 3032 / sequence-number / 2 : 3, 3033 / common / 3 : h'a2024c818245466c617368430034010458568613a40350' 3034 h'fa6b4a53d5ad5fdfbe9de663e4d41ffe04501492af1425' 3035 h'695e48bf429b2d51f2ab450b5824820258200011223344' 3036 h'5566778899aabbccddeeff0123456789abcdeffedcba98' 3037 h'765432100c1987d001f602f6' \ { 3038 / components / 2 : h'818245466c61736843003401' \ 3039 [ 3040 [h'466c617368', h'003401'], 3041 ], 3042 / common-sequence / 4 : h'8613a40350fa6b4a53d5ad5fdfbe9de6' 3043 h'63e4d41ffe04501492af1425695e48bf' 3044 h'429b2d51f2ab450b5824820258200011' 3045 h'2233445566778899aabbccddeeff0123' 3046 h'456789abcdeffedcba98765432100c19' 3047 h'87d001f602f6' \ [ 3048 / set-vars / 19, { 3049 / vendor-id / 3 : h'fa6b4a53d5ad5fdfbe9de663e4d41f' 3050 h'fe', 3051 / class-id / 4 : h'1492af1425695e48bf429b2d51f2ab45', 3052 / digest / 11 : h'8202582000112233445566778899aabb' 3053 h'ccddeeff0123456789abcdeffedcba98' 3054 h'76543210' \ 3055 [ 2, h'00112233445566778899aabbccddeeff01234567' 3056 h'89abcdeffedcba9876543210' ], 3057 / size / 12 : 34768, 3058 }, 3059 / condition-vendor-id / 1, None, 3060 / condition-class-id / 2, None, 3061 ], 3062 }, 3063 / apply-image / 9 : h'860c0013a106781b687474703a2f2f6578616d70' 3064 h'6c652e636f6d2f66696c652e62696e15f6' \ [ 3065 / set-component-index / 12, 0, 3066 / set-vars / 19, { 3067 / uri / 6 : http://example.com/file.bin, 3068 }, 3069 / fetch / 21, None, 3070 ], 3071 / run-image / 12 : h'860c0003f617f6' \ [ 3072 / set-component-index / 12, 0, 3073 / condition-image / 3, None, 3074 / run / 23, None, 3075 ], 3076 } 3077 } 3079 Total size of outer wrapper without COSE authentication object: 167 3081 Outer: 3083 a201f60258a1a501010203035868a2024c818245466c617368430034010458568613a403 3084 50fa6b4a53d5ad5fdfbe9de663e4d41ffe04501492af1425695e48bf429b2d51f2ab450b 3085 58248202582000112233445566778899aabbccddeeff0123456789abcdeffedcba987654 3086 32100c1987d001f602f6095825860c0013a106781b687474703a2f2f6578616d706c652e 3087 636f6d2f66696c652e62696e15f60c47860c0003f617f6 3089 Total size of outer wrapper with COSE authentication object: 252 3091 Signed Outer: 3093 a2015854d28443a10126a1044874657374206b6579f658400014750c013f7e1cdbec6f14 3094 b99b49195e081d1030508a6b8d271bd99dfb382a7767dc45f20c9943ed22a1eaac9d07a0 3095 41ec1acfc10ad7e45e6424629ff3e3e50258a1a501010203035868a2024c818245466c61 3096 7368430034010458568613a40350fa6b4a53d5ad5fdfbe9de663e4d41ffe04501492af14 3097 25695e48bf429b2d51f2ab450b58248202582000112233445566778899aabbccddeeff01 3098 23456789abcdeffedcba98765432100c1987d001f602f6095825860c0013a106781b6874 3099 74703a2f2f6578616d706c652e636f6d2f66696c652e62696e15f60c47860c0003f617f6 3101 12.4. Example 3: 3103 Compatibility test, simultaneous download and installation, load from 3104 external storage, and secure boot. 3106 The following JSON shows the intended behaviour of the manifest. 3108 { 3109 "structure-version": 1, 3110 "sequence-number": 4, 3111 "common": { 3112 "common-sequence": [ 3113 { 3114 "directive-set-var": { 3115 "vendor-id": "fa6b4a53-d5ad-5fdf-be9d-e663e4d41ffe", 3116 "class-id": "1492af14-2569-5e48-bf42-9b2d51f2ab45" 3117 } 3118 }, 3119 { "directive-set-component": 0 }, 3120 { 3121 "directive-set-var": { 3122 "digest": "00112233445566778899aabbccddeeff" 3123 "0123456789abcdeffedcba9876543210", 3124 "size": 34768 3125 } 3126 }, 3127 { "directive-set-component": 1 }, 3128 { 3129 "directive-set-var": { 3130 "digest": "00112233445566778899aabbccddeeff" 3131 "0123456789abcdeffedcba9876543210", 3132 "size": 34768 3133 } 3134 }, 3135 { "condition-vendor-id": null }, 3136 { "condition-class-id": null } 3137 ], 3138 "components": [ 3139 [ 3140 "Flash", 3141 78848 3142 ], 3143 [ 3144 "RAM", 3145 1024 3146 ] 3147 ] 3148 }, 3149 "apply-image": [ 3150 { "directive-set-component": 0 }, 3151 { 3152 "directive-set-var": { 3153 "uri": "http://example.com/file.bin" 3154 } 3155 }, 3156 { "directive-fetch": null } 3157 ], 3158 "run-image": [ 3159 { "directive-set-component": 0 }, 3160 { "condition-image": null }, 3161 { "directive-set-component": 1 }, 3162 { 3163 "directive-set-var": { 3164 "source-index": 0 3165 } 3166 }, 3167 { "directive-fetch": null }, 3168 { "condition-image": null }, 3169 { "directive-run": null } 3170 ] 3171 } 3173 Converted into the SUIT manifest, this produces: 3175 { 3176 / auth object / 1 : h'd28443a10126a1044874657374206b6579f6584070eb' 3177 h'70f2552533fc954e934f50f42bdd9b6f7d4fd7e11463' 3178 h'6b9cdbef2a065f9640243a7857f66c4389aea906c4f3' 3179 h'b45150c8e55461e9bfda945904033fc70a84', 3180 / manifest / 2 : h'a5010102040358a3a20254828245466c6173684300340182' 3181 h'4352414d4200040458898e13a20350fa6b4a53d5ad5fdfbe' 3182 h'9de663e4d41ffe04501492af1425695e48bf429b2d51f2ab' 3183 h'450c0013a20b58248202582000112233445566778899aabb' 3184 h'ccddeeff0123456789abcdeffedcba98765432100c1987d0' 3185 h'0c0113a20b58248202582000112233445566778899aabbcc' 3186 h'ddeeff0123456789abcdeffedcba98765432100c1987d001' 3187 h'f602f6095825860c0013a106781b687474703a2f2f657861' 3188 h'6d706c652e636f6d2f66696c652e62696e15f60c518e0c00' 3189 h'03f60c0113a10a0015f603f617f6' \ 3190 { 3191 / structure-version / 1 : 1, 3192 / sequence-number / 2 : 4, 3193 / common / 3 : h'a20254828245466c61736843003401824352414d420004' 3194 h'0458898e13a20350fa6b4a53d5ad5fdfbe9de663e4d41f' 3195 h'fe04501492af1425695e48bf429b2d51f2ab450c0013a2' 3196 h'0b58248202582000112233445566778899aabbccddeeff' 3197 h'0123456789abcdeffedcba98765432100c1987d00c0113' 3198 h'a20b58248202582000112233445566778899aabbccddee' 3199 h'ff0123456789abcdeffedcba98765432100c1987d001f6' 3200 h'02f6' \ { 3201 / components / 2 : h'828245466c61736843003401824352414d4200' 3202 h'04' \ 3203 [ 3204 [h'466c617368', h'003401'], 3205 [h'52414d', h'0004'], 3206 ], 3207 / common-sequence / 4 : h'8e13a20350fa6b4a53d5ad5fdfbe9de6' 3208 h'63e4d41ffe04501492af1425695e48bf' 3209 h'429b2d51f2ab450c0013a20b58248202' 3210 h'582000112233445566778899aabbccdd' 3211 h'eeff0123456789abcdeffedcba987654' 3212 h'32100c1987d00c0113a20b5824820258' 3213 h'2000112233445566778899aabbccddee' 3214 h'ff0123456789abcdeffedcba98765432' 3215 h'100c1987d001f602f6' \ [ 3217 / set-vars / 19, { 3218 / vendor-id / 3 : h'fa6b4a53d5ad5fdfbe9de663e4d41f' 3219 h'fe', 3220 / class-id / 4 : h'1492af1425695e48bf429b2d51f2ab45', 3221 }, 3222 / set-component-index / 12, 0, 3223 / set-vars / 19, { 3224 / digest / 11 : h'8202582000112233445566778899aabb' 3225 h'ccddeeff0123456789abcdeffedcba98' 3226 h'76543210' \ 3227 [ 2, h'00112233445566778899aabbccddeeff01234567' 3228 h'89abcdeffedcba9876543210' ], 3229 / size / 12 : 34768, 3230 }, 3231 / set-component-index / 12, 1, 3232 / set-vars / 19, { 3233 / digest / 11 : h'8202582000112233445566778899aabb' 3234 h'ccddeeff0123456789abcdeffedcba98' 3235 h'76543210' \ 3236 [ 2, h'00112233445566778899aabbccddeeff01234567' 3237 h'89abcdeffedcba9876543210' ], 3238 / size / 12 : 34768, 3239 }, 3240 / condition-vendor-id / 1, None, 3241 / condition-class-id / 2, None, 3242 ], 3243 }, 3244 / apply-image / 9 : h'860c0013a106781b687474703a2f2f6578616d70' 3245 h'6c652e636f6d2f66696c652e62696e15f6' \ [ 3246 / set-component-index / 12, 0, 3247 / set-vars / 19, { 3248 / uri / 6 : http://example.com/file.bin, 3249 }, 3250 / fetch / 21, None, 3251 ], 3252 / run-image / 12 : h'8e0c0003f60c0113a10a0015f603f617f6' \ [ 3253 / set-component-index / 12, 0, 3254 / condition-image / 3, None, 3255 / set-component-index / 12, 1, 3256 / set-vars / 19, { 3257 / source-component / 10 : 0, 3258 }, 3259 / fetch / 21, None, 3260 / condition-image / 3, None, 3261 / run / 23, None, 3262 ], 3263 } 3264 } 3265 Total size of outer wrapper without COSE authentication object: 236 3267 Outer: 3269 a201f60258e6a5010102040358a3a20254828245466c61736843003401824352414d4200 3270 040458898e13a20350fa6b4a53d5ad5fdfbe9de663e4d41ffe04501492af1425695e48bf 3271 429b2d51f2ab450c0013a20b58248202582000112233445566778899aabbccddeeff0123 3272 456789abcdeffedcba98765432100c1987d00c0113a20b58248202582000112233445566 3273 778899aabbccddeeff0123456789abcdeffedcba98765432100c1987d001f602f6095825 3274 860c0013a106781b687474703a2f2f6578616d706c652e636f6d2f66696c652e62696e15 3275 f60c518e0c0003f60c0113a10a0015f603f617f6 3277 Total size of outer wrapper with COSE authentication object: 321 3279 Signed Outer: 3281 a2015854d28443a10126a1044874657374206b6579f6584070eb70f2552533fc954e934f 3282 50f42bdd9b6f7d4fd7e114636b9cdbef2a065f9640243a7857f66c4389aea906c4f3b451 3283 50c8e55461e9bfda945904033fc70a840258e6a5010102040358a3a20254828245466c61 3284 736843003401824352414d4200040458898e13a20350fa6b4a53d5ad5fdfbe9de663e4d4 3285 1ffe04501492af1425695e48bf429b2d51f2ab450c0013a20b5824820258200011223344 3286 5566778899aabbccddeeff0123456789abcdeffedcba98765432100c1987d00c0113a20b 3287 58248202582000112233445566778899aabbccddeeff0123456789abcdeffedcba987654 3288 32100c1987d001f602f6095825860c0013a106781b687474703a2f2f6578616d706c652e 3289 636f6d2f66696c652e62696e15f60c518e0c0003f60c0113a10a0015f603f617f6 3291 12.5. Example 4: 3293 Compatibility test, simultaneous download and installation, load and 3294 decompress from external storage, and secure boot. 3296 The following JSON shows the intended behaviour of the manifest. 3298 { 3299 "structure-version": 1, 3300 "sequence-number": 5, 3301 "common": { 3302 "common-sequence": [ 3303 { 3304 "directive-set-var": { 3305 "vendor-id": "fa6b4a53-d5ad-5fdf-be9d-e663e4d41ffe", 3306 "class-id": "1492af14-2569-5e48-bf42-9b2d51f2ab45" 3307 } 3308 }, 3309 { "directive-set-component": 0 }, 3310 { 3311 "directive-set-var": { 3312 "digest": "00112233445566778899aabbccddeeff" 3313 "0123456789abcdeffedcba9876543210", 3314 "size": 34768 3315 } 3316 }, 3317 { "directive-set-component": 1 }, 3318 { 3319 "directive-set-var": { 3320 "digest": "0123456789abcdeffedcba9876543210" 3321 "00112233445566778899aabbccddeeff", 3322 "size": 34768 3323 } 3324 }, 3325 { "condition-vendor-id": null }, 3326 { "condition-class-id": null } 3327 ], 3328 "components": [ 3329 [ 3330 "Flash", 3331 78848 3332 ], 3333 [ 3334 "RAM", 3335 1024 3336 ] 3337 ] 3338 }, 3339 "apply-image": [ 3340 { "directive-set-component": 0 }, 3341 { 3342 "directive-set-var": { 3343 "uri": "http://example.com/file.bin" 3344 } 3345 }, 3346 { "directive-fetch": null } 3347 ], 3348 "load-image": [ 3349 { "directive-set-component": 0 }, 3350 { "condition-image": null }, 3351 { "directive-set-component": 1 }, 3352 { 3353 "directive-set-var": { 3354 "source-index": 0, 3355 "compression-info": { 3356 "algorithm": "gzip" 3357 } 3358 } 3359 }, 3360 { "directive-copy": null } 3362 ], 3363 "run-image": [ 3364 { "condition-image": null }, 3365 { "directive-run": null } 3366 ] 3367 } 3369 Converted into the SUIT manifest, this produces: 3371 { 3372 / auth object / 1 : h'd28443a10126a1044874657374206b6579f658403491' 3373 h'5619c1ef02b4a7ffbbb69083e8b3fb82febd9ecd6feb' 3374 h'f666d700fb981b208ec6d3df8735f36fd4a0a84e0189' 3375 h'43ef80e25f57fc130a43e57c6634f337b7fa', 3376 / manifest / 2 : h'a6010102050358a3a20254828245466c6173684300340182' 3377 h'4352414d4200040458898e13a20350fa6b4a53d5ad5fdfbe' 3378 h'9de663e4d41ffe04501492af1425695e48bf429b2d51f2ab' 3379 h'450c0013a20b58248202582000112233445566778899aabb' 3380 h'ccddeeff0123456789abcdeffedcba98765432100c1987d0' 3381 h'0c0113a20b5824820258200123456789abcdeffedcba9876' 3382 h'54321000112233445566778899aabbccddeeff0c1987d001' 3383 h'f602f6095825860c0013a106781b687474703a2f2f657861' 3384 h'6d706c652e636f6d2f66696c652e62696e15f60b528a0c00' 3385 h'03f60c0113a20843a101010a0016f60c458403f617f6' \ 3386 { 3387 / structure-version / 1 : 1, 3388 / sequence-number / 2 : 5, 3389 / common / 3 : h'a20254828245466c61736843003401824352414d420004' 3390 h'0458898e13a20350fa6b4a53d5ad5fdfbe9de663e4d41f' 3391 h'fe04501492af1425695e48bf429b2d51f2ab450c0013a2' 3392 h'0b58248202582000112233445566778899aabbccddeeff' 3393 h'0123456789abcdeffedcba98765432100c1987d00c0113' 3394 h'a20b5824820258200123456789abcdeffedcba98765432' 3395 h'1000112233445566778899aabbccddeeff0c1987d001f6' 3396 h'02f6' \ { 3397 / components / 2 : h'828245466c61736843003401824352414d4200' 3398 h'04' \ 3399 [ 3400 [h'466c617368', h'003401'], 3401 [h'52414d', h'0004'], 3402 ], 3403 / common-sequence / 4 : h'8e13a20350fa6b4a53d5ad5fdfbe9de6' 3404 h'63e4d41ffe04501492af1425695e48bf' 3405 h'429b2d51f2ab450c0013a20b58248202' 3406 h'582000112233445566778899aabbccdd' 3407 h'eeff0123456789abcdeffedcba987654' 3408 h'32100c1987d00c0113a20b5824820258' 3409 h'200123456789abcdeffedcba98765432' 3410 h'1000112233445566778899aabbccddee' 3411 h'ff0c1987d001f602f6' \ [ 3412 / set-vars / 19, { 3413 / vendor-id / 3 : h'fa6b4a53d5ad5fdfbe9de663e4d41f' 3414 h'fe', 3415 / class-id / 4 : h'1492af1425695e48bf429b2d51f2ab45', 3416 }, 3417 / set-component-index / 12, 0, 3418 / set-vars / 19, { 3419 / digest / 11 : h'8202582000112233445566778899aabb' 3420 h'ccddeeff0123456789abcdeffedcba98' 3421 h'76543210' \ 3422 [ 2, h'00112233445566778899aabbccddeeff01234567' 3423 h'89abcdeffedcba9876543210' ], 3424 / size / 12 : 34768, 3425 }, 3426 / set-component-index / 12, 1, 3427 / set-vars / 19, { 3428 / digest / 11 : h'820258200123456789abcdeffedcba98' 3429 h'7654321000112233445566778899aabb' 3430 h'ccddeeff' \ 3431 [ 2, h'0123456789abcdeffedcba987654321000112233' 3432 h'445566778899aabbccddeeff' ], 3433 / size / 12 : 34768, 3434 }, 3435 / condition-vendor-id / 1, None, 3436 / condition-class-id / 2, None, 3437 ], 3438 }, 3439 / apply-image / 9 : h'860c0013a106781b687474703a2f2f6578616d70' 3440 h'6c652e636f6d2f66696c652e62696e15f6' \ [ 3441 / set-component-index / 12, 0, 3442 / set-vars / 19, { 3443 / uri / 6 : http://example.com/file.bin, 3444 }, 3445 / fetch / 21, None, 3446 ], 3447 / load-image / 11 : h'8a0c0003f60c0113a20843a101010a0016f6' \ [ 3448 / set-component-index / 12, 0, 3449 / condition-image / 3, None, 3450 / set-component-index / 12, 1, 3451 / set-vars / 19, { 3452 / compression-info / 8 : h'a10101', 3453 / source-component / 10 : 0, 3454 }, 3455 / copy / 22, None, 3456 ], 3457 / run-image / 12 : h'8403f617f6' \ [ 3458 / condition-image / 3, None, 3459 / run / 23, None, 3460 ], 3461 } 3462 } 3464 Total size of outer wrapper without COSE authentication object: 244 3466 Outer: 3468 a201f60258eea6010102050358a3a20254828245466c61736843003401824352414d4200 3469 040458898e13a20350fa6b4a53d5ad5fdfbe9de663e4d41ffe04501492af1425695e48bf 3470 429b2d51f2ab450c0013a20b58248202582000112233445566778899aabbccddeeff0123 3471 456789abcdeffedcba98765432100c1987d00c0113a20b5824820258200123456789abcd 3472 effedcba987654321000112233445566778899aabbccddeeff0c1987d001f602f6095825 3473 860c0013a106781b687474703a2f2f6578616d706c652e636f6d2f66696c652e62696e15 3474 f60b528a0c0003f60c0113a20843a101010a0016f60c458403f617f6 3476 Total size of outer wrapper with COSE authentication object: 329 3478 Signed Outer: 3480 a2015854d28443a10126a1044874657374206b6579f6584034915619c1ef02b4a7ffbbb6 3481 9083e8b3fb82febd9ecd6febf666d700fb981b208ec6d3df8735f36fd4a0a84e018943ef 3482 80e25f57fc130a43e57c6634f337b7fa0258eea6010102050358a3a20254828245466c61 3483 736843003401824352414d4200040458898e13a20350fa6b4a53d5ad5fdfbe9de663e4d4 3484 1ffe04501492af1425695e48bf429b2d51f2ab450c0013a20b5824820258200011223344 3485 5566778899aabbccddeeff0123456789abcdeffedcba98765432100c1987d00c0113a20b 3486 5824820258200123456789abcdeffedcba987654321000112233445566778899aabbccdd 3487 eeff0c1987d001f602f6095825860c0013a106781b687474703a2f2f6578616d706c652e 3488 636f6d2f66696c652e62696e15f60b528a0c0003f60c0113a20843a101010a0016f60c45 3489 8403f617f6 3491 12.6. Example 5: 3493 Compatibility test, download, installation, and secure boot. 3495 The following JSON shows the intended behaviour of the manifest. 3497 { 3498 "structure-version": 1, 3499 "sequence-number": 6, 3500 "common": { 3501 "common-sequence": [ 3502 { 3503 "directive-set-var": { 3504 "vendor-id": "fa6b4a53-d5ad-5fdf-be9d-e663e4d41ffe", 3505 "class-id": "1492af14-2569-5e48-bf42-9b2d51f2ab45" 3507 } 3508 }, 3509 { "directive-set-component": 0 }, 3510 { 3511 "directive-set-var": { 3512 "digest": "00112233445566778899aabbccddeeff" 3513 "0123456789abcdeffedcba9876543210", 3514 "size": 34768 3515 } 3516 }, 3517 { "directive-set-component": 1 }, 3518 { 3519 "directive-set-var": { 3520 "digest": "0123456789abcdeffedcba9876543210" 3521 "00112233445566778899aabbccddeeff", 3522 "size": 34768 3523 } 3524 }, 3525 { "condition-vendor-id": null }, 3526 { "condition-class-id": null } 3527 ], 3528 "components": [ 3529 [ 3530 "ext-Flash", 3531 78848 3532 ], 3533 [ 3534 "Flash", 3535 1024 3536 ] 3537 ] 3538 }, 3539 "apply-image": [ 3540 { "directive-set-component": 0 }, 3541 { 3542 "directive-set-var": { 3543 "uri": "http://example.com/file.bin" 3544 } 3545 }, 3546 { "directive-fetch": null } 3547 ], 3548 "load-image": [ 3549 { "directive-set-component": 1 }, 3550 { "condition-not-image": null }, 3551 { "directive-set-component": 0 }, 3552 { "condition-image": null }, 3553 { "directive-set-component": 1 }, 3554 { 3555 "directive-set-var": { 3556 "source-index": 0 3557 } 3558 }, 3559 { "directive-fetch": null } 3560 ], 3561 "run-image": [ 3562 { "directive-set-component": 1 }, 3563 { "condition-image": null }, 3564 { "directive-run": null } 3565 ] 3566 } 3568 Converted into the SUIT manifest, this produces: 3570 { 3571 / auth object / 1 : h'd28443a10126a1044874657374206b6579f65840a516' 3572 h'466c62602aa017422f23d1469339e40c5cf06f9090da' 3573 h'09bd9939ecfc4c1ffe3e6ce50e0620fe9948f76552da' 3574 h'703a4c0bf2532d073be2d1f215ec83483f46', 3575 / manifest / 2 : h'a6010102060358a6a202578282467b1b4595ab2143003401' 3576 h'8245466c6173684200040458898e13a20350fa6b4a53d5ad' 3577 h'5fdfbe9de663e4d41ffe04501492af1425695e48bf429b2d' 3578 h'51f2ab450c0013a20b582482025820001122334455667788' 3579 h'99aabbccddeeff0123456789abcdeffedcba98765432100c' 3580 h'1987d00c0113a20b5824820258200123456789abcdeffedc' 3581 h'ba987654321000112233445566778899aabbccddeeff0c19' 3582 h'87d001f602f6095825860c0013a106781b687474703a2f2f' 3583 h'6578616d706c652e636f6d2f66696c652e62696e15f60b52' 3584 h'8e0c011819f60c0003f60c0113a10a0015f60c47860c0103' 3585 h'f617f6' \ 3586 { 3587 / structure-version / 1 : 1, 3588 / sequence-number / 2 : 6, 3589 / common / 3 : h'a202578282467b1b4595ab21430034018245466c617368' 3590 h'4200040458898e13a20350fa6b4a53d5ad5fdfbe9de663' 3591 h'e4d41ffe04501492af1425695e48bf429b2d51f2ab450c' 3592 h'0013a20b58248202582000112233445566778899aabbcc' 3593 h'ddeeff0123456789abcdeffedcba98765432100c1987d0' 3594 h'0c0113a20b5824820258200123456789abcdeffedcba98' 3595 h'7654321000112233445566778899aabbccddeeff0c1987' 3596 h'd001f602f6' \ { 3597 / components / 2 : h'8282467b1b4595ab21430034018245466c6173' 3598 h'68420004' \ 3599 [ 3600 [h'7b1b4595ab21', h'003401'], 3601 [h'466c617368', h'0004'], 3602 ], 3603 / common-sequence / 4 : h'8e13a20350fa6b4a53d5ad5fdfbe9de6' 3604 h'63e4d41ffe04501492af1425695e48bf' 3605 h'429b2d51f2ab450c0013a20b58248202' 3606 h'582000112233445566778899aabbccdd' 3607 h'eeff0123456789abcdeffedcba987654' 3608 h'32100c1987d00c0113a20b5824820258' 3609 h'200123456789abcdeffedcba98765432' 3610 h'1000112233445566778899aabbccddee' 3611 h'ff0c1987d001f602f6' \ [ 3612 / set-vars / 19, { 3613 / vendor-id / 3 : h'fa6b4a53d5ad5fdfbe9de663e4d41f' 3614 h'fe', 3615 / class-id / 4 : h'1492af1425695e48bf429b2d51f2ab45', 3616 }, 3617 / set-component-index / 12, 0, 3618 / set-vars / 19, { 3619 / digest / 11 : h'8202582000112233445566778899aabb' 3620 h'ccddeeff0123456789abcdeffedcba98' 3621 h'76543210' \ 3622 [ 2, h'00112233445566778899aabbccddeeff01234567' 3623 h'89abcdeffedcba9876543210' ], 3624 / size / 12 : 34768, 3625 }, 3626 / set-component-index / 12, 1, 3627 / set-vars / 19, { 3628 / digest / 11 : h'820258200123456789abcdeffedcba98' 3629 h'7654321000112233445566778899aabb' 3630 h'ccddeeff' \ 3631 [ 2, h'0123456789abcdeffedcba987654321000112233' 3632 h'445566778899aabbccddeeff' ], 3633 / size / 12 : 34768, 3634 }, 3635 / condition-vendor-id / 1, None, 3636 / condition-class-id / 2, None, 3637 ], 3638 }, 3639 / apply-image / 9 : h'860c0013a106781b687474703a2f2f6578616d70' 3640 h'6c652e636f6d2f66696c652e62696e15f6' \ [ 3641 / set-component-index / 12, 0, 3642 / set-vars / 19, { 3643 / uri / 6 : http://example.com/file.bin, 3644 }, 3645 / fetch / 21, None, 3646 ], 3647 / load-image / 11 : h'8e0c011819f60c0003f60c0113a10a0015f6' \ [ 3648 / set-component-index / 12, 1, 3649 / condition-not-image / 25, None, 3650 / set-component-index / 12, 0, 3651 / condition-image / 3, None, 3652 / set-component-index / 12, 1, 3653 / set-vars / 19, { 3654 / source-component / 10 : 0, 3655 }, 3656 / fetch / 21, None, 3657 ], 3658 / run-image / 12 : h'860c0103f617f6' \ [ 3659 / set-component-index / 12, 1, 3660 / condition-image / 3, None, 3661 / run / 23, None, 3662 ], 3663 } 3664 } 3666 Total size of outer wrapper without COSE authentication object: 249 3668 Outer: 3670 a201f60258f3a6010102060358a6a202578282467b1b4595ab21430034018245466c6173 3671 684200040458898e13a20350fa6b4a53d5ad5fdfbe9de663e4d41ffe04501492af142569 3672 5e48bf429b2d51f2ab450c0013a20b58248202582000112233445566778899aabbccddee 3673 ff0123456789abcdeffedcba98765432100c1987d00c0113a20b58248202582001234567 3674 89abcdeffedcba987654321000112233445566778899aabbccddeeff0c1987d001f602f6 3675 095825860c0013a106781b687474703a2f2f6578616d706c652e636f6d2f66696c652e62 3676 696e15f60b528e0c011819f60c0003f60c0113a10a0015f60c47860c0103f617f6 3678 Total size of outer wrapper with COSE authentication object: 334 3680 Signed Outer: 3682 a2015854d28443a10126a1044874657374206b6579f65840a516466c62602aa017422f23 3683 d1469339e40c5cf06f9090da09bd9939ecfc4c1ffe3e6ce50e0620fe9948f76552da703a 3684 4c0bf2532d073be2d1f215ec83483f460258f3a6010102060358a6a202578282467b1b45 3685 95ab21430034018245466c6173684200040458898e13a20350fa6b4a53d5ad5fdfbe9de6 3686 63e4d41ffe04501492af1425695e48bf429b2d51f2ab450c0013a20b5824820258200011 3687 2233445566778899aabbccddeeff0123456789abcdeffedcba98765432100c1987d00c01 3688 13a20b5824820258200123456789abcdeffedcba987654321000112233445566778899aa 3689 bbccddeeff0c1987d001f602f6095825860c0013a106781b687474703a2f2f6578616d70 3690 6c652e636f6d2f66696c652e62696e15f60b528e0c011819f60c0003f60c0113a10a0015 3691 f60c47860c0103f617f6 3693 12.7. Example 6: 3695 Compatibility test, 2 images, simultaneous download and installation, 3696 and secure boot. 3698 The following JSON shows the intended behaviour of the manifest. 3700 { 3701 "structure-version": 1, 3702 "sequence-number": 7, 3703 "common": { 3704 "common-sequence": [ 3705 { 3706 "directive-set-var": { 3707 "vendor-id": "fa6b4a53-d5ad-5fdf-be9d-e663e4d41ffe", 3708 "class-id": "1492af14-2569-5e48-bf42-9b2d51f2ab45" 3709 } 3710 }, 3711 { "directive-set-component": 0 }, 3712 { 3713 "directive-set-var": { 3714 "digest": "00112233445566778899aabbccddeeff" 3715 "0123456789abcdeffedcba9876543210", 3716 "size": 34768 3717 } 3718 }, 3719 { "directive-set-component": 1 }, 3720 { 3721 "directive-set-var": { 3722 "digest": "0123456789abcdeffedcba9876543210" 3723 "00112233445566778899aabbccddeeff", 3724 "size": 76834 3725 } 3726 }, 3727 { "condition-vendor-id": null }, 3728 { "condition-class-id": null } 3729 ], 3730 "components": [ 3731 [ 3732 "Flash", 3733 78848 3734 ], 3735 [ 3736 "Flash", 3737 132096 3738 ] 3739 ] 3740 }, 3741 "apply-image": [ 3742 { "directive-set-component": 0 }, 3743 { 3744 "directive-set-var": { 3745 "uri": "http://example.com/file1.bin" 3746 } 3747 }, 3748 { "directive-set-component": 1 }, 3749 { 3750 "directive-set-var": { 3751 "uri": "http://example.com/file2.bin" 3752 } 3753 }, 3754 { "directive-set-component": true }, 3755 { "directive-fetch": null } 3756 ], 3757 "run-image": [ 3758 { "directive-set-component": true }, 3759 { "condition-image": null }, 3760 { "directive-set-component": 0 }, 3761 { "directive-run": null } 3762 ] 3763 } 3765 Converted into the SUIT manifest, this produces: 3767 { 3768 / auth object / 1 : h'd28443a10126a1044874657374206b6579f658400d44' 3769 h'c766566a88c5bbe61b544edd14effa7d53c9a6d43221' 3770 h'99c6285490460b910c8e96c6a1065cc1be9cfa438f7b' 3771 h'eeaffa9922e2ae440d6c8d0b9cb26bed2ffe', 3772 / manifest / 2 : h'a5010102070358a8a20257828245466c6173684300340182' 3773 h'45466c6173684300040204588b8e13a20350fa6b4a53d5ad' 3774 h'5fdfbe9de663e4d41ffe04501492af1425695e48bf429b2d' 3775 h'51f2ab450c0013a20b582482025820001122334455667788' 3776 h'99aabbccddeeff0123456789abcdeffedcba98765432100c' 3777 h'1987d00c0113a20b5824820258200123456789abcdeffedc' 3778 h'ba987654321000112233445566778899aabbccddeeff0c1a' 3779 h'00012c2201f602f609584b8c0c0013a106781c687474703a' 3780 h'2f2f6578616d706c652e636f6d2f66696c65312e62696e0c' 3781 h'0113a106781c687474703a2f2f6578616d706c652e636f6d' 3782 h'2f66696c65322e62696e0cf515f60c49880cf503f60c0017' 3783 h'f6' \ 3784 { 3785 / structure-version / 1 : 1, 3786 / sequence-number / 2 : 7, 3787 / common / 3 : h'a20257828245466c617368430034018245466c61736843' 3788 h'00040204588b8e13a20350fa6b4a53d5ad5fdfbe9de663' 3789 h'e4d41ffe04501492af1425695e48bf429b2d51f2ab450c' 3790 h'0013a20b58248202582000112233445566778899aabbcc' 3791 h'ddeeff0123456789abcdeffedcba98765432100c1987d0' 3792 h'0c0113a20b5824820258200123456789abcdeffedcba98' 3793 h'7654321000112233445566778899aabbccddeeff0c1a00' 3794 h'012c2201f602f6' \ { 3795 / components / 2 : h'828245466c617368430034018245466c617368' 3796 h'43000402' \ 3797 [ 3798 [h'466c617368', h'003401'], 3799 [h'466c617368', h'000402'], 3800 ], 3801 / common-sequence / 4 : h'8e13a20350fa6b4a53d5ad5fdfbe9de6' 3802 h'63e4d41ffe04501492af1425695e48bf' 3803 h'429b2d51f2ab450c0013a20b58248202' 3804 h'582000112233445566778899aabbccdd' 3805 h'eeff0123456789abcdeffedcba987654' 3806 h'32100c1987d00c0113a20b5824820258' 3807 h'200123456789abcdeffedcba98765432' 3808 h'1000112233445566778899aabbccddee' 3809 h'ff0c1a00012c2201f602f6' \ [ 3810 / set-vars / 19, { 3811 / vendor-id / 3 : h'fa6b4a53d5ad5fdfbe9de663e4d41f' 3812 h'fe', 3813 / class-id / 4 : h'1492af1425695e48bf429b2d51f2ab45', 3814 }, 3815 / set-component-index / 12, 0, 3816 / set-vars / 19, { 3817 / digest / 11 : h'8202582000112233445566778899aabb' 3818 h'ccddeeff0123456789abcdeffedcba98' 3819 h'76543210' \ 3820 [ 2, h'00112233445566778899aabbccddeeff01234567' 3821 h'89abcdeffedcba9876543210' ], 3822 / size / 12 : 34768, 3823 }, 3824 / set-component-index / 12, 1, 3825 / set-vars / 19, { 3826 / digest / 11 : h'820258200123456789abcdeffedcba98' 3827 h'7654321000112233445566778899aabb' 3828 h'ccddeeff' \ 3829 [ 2, h'0123456789abcdeffedcba987654321000112233' 3830 h'445566778899aabbccddeeff' ], 3831 / size / 12 : 76834, 3832 }, 3833 / condition-vendor-id / 1, None, 3834 / condition-class-id / 2, None, 3835 ], 3836 }, 3837 / apply-image / 9 : h'8c0c0013a106781c687474703a2f2f6578616d70' 3838 h'6c652e636f6d2f66696c65312e62696e0c0113a1' 3839 h'06781c687474703a2f2f6578616d706c652e636f' 3840 h'6d2f66696c65322e62696e0cf515f6' \ [ 3841 / set-component-index / 12, 0, 3842 / set-vars / 19, { 3843 / uri / 6 : http://example.com/file1.bin, 3845 }, 3846 / set-component-index / 12, 1, 3847 / set-vars / 19, { 3848 / uri / 6 : http://example.com/file2.bin, 3849 }, 3850 / set-component-index / 12, True, 3851 / fetch / 21, None, 3852 ], 3853 / run-image / 12 : h'880cf503f60c0017f6' \ [ 3854 / set-component-index / 12, True, 3855 / condition-image / 3, None, 3856 / set-component-index / 12, 0, 3857 / run / 23, None, 3858 ], 3859 } 3860 } 3862 Total size of outer wrapper without COSE authentication object: 272 3864 Outer: 3866 a201f602590109a5010102070358a8a20257828245466c617368430034018245466c6173 3867 684300040204588b8e13a20350fa6b4a53d5ad5fdfbe9de663e4d41ffe04501492af1425 3868 695e48bf429b2d51f2ab450c0013a20b58248202582000112233445566778899aabbccdd 3869 eeff0123456789abcdeffedcba98765432100c1987d00c0113a20b582482025820012345 3870 6789abcdeffedcba987654321000112233445566778899aabbccddeeff0c1a00012c2201 3871 f602f609584b8c0c0013a106781c687474703a2f2f6578616d706c652e636f6d2f66696c 3872 65312e62696e0c0113a106781c687474703a2f2f6578616d706c652e636f6d2f66696c65 3873 322e62696e0cf515f60c49880cf503f60c0017f6 3875 Total size of outer wrapper with COSE authentication object: 357 3877 Signed Outer: 3879 a2015854d28443a10126a1044874657374206b6579f658400d44c766566a88c5bbe61b54 3880 4edd14effa7d53c9a6d4322199c6285490460b910c8e96c6a1065cc1be9cfa438f7beeaf 3881 fa9922e2ae440d6c8d0b9cb26bed2ffe02590109a5010102070358a8a20257828245466c 3882 617368430034018245466c6173684300040204588b8e13a20350fa6b4a53d5ad5fdfbe9d 3883 e663e4d41ffe04501492af1425695e48bf429b2d51f2ab450c0013a20b58248202582000 3884 112233445566778899aabbccddeeff0123456789abcdeffedcba98765432100c1987d00c 3885 0113a20b5824820258200123456789abcdeffedcba987654321000112233445566778899 3886 aabbccddeeff0c1a00012c2201f602f609584b8c0c0013a106781c687474703a2f2f6578 3887 616d706c652e636f6d2f66696c65312e62696e0c0113a106781c687474703a2f2f657861 3888 6d706c652e636f6d2f66696c65322e62696e0cf515f60c49880cf503f60c0017f6 3889 13. IANA Considerations 3891 Several registries will be required for: 3893 - standard Commands 3895 - standard Parameters 3897 - standard Algorithm identifiers 3899 - standard text values 3901 14. Security Considerations 3903 This document is about a manifest format describing and protecting 3904 firmware images and as such it is part of a larger solution for 3905 offering a standardized way of delivering firmware updates to IoT 3906 devices. A more detailed discussion about security can be found in 3907 the architecture document [I-D.ietf-suit-architecture] and in 3908 [I-D.ietf-suit-information-model]. 3910 15. Mailing List Information 3912 The discussion list for this document is located at the e-mail 3913 address suit@ietf.org [1]. Information on the group and information 3914 on how to subscribe to the list is at 3915 https://www1.ietf.org/mailman/listinfo/suit [2] 3917 Archives of the list can be found at: https://www.ietf.org/mail- 3918 archive/web/suit/current/index.html [3] 3920 16. Acknowledgements 3922 We would like to thank the following persons for their support in 3923 designing this mechanism: 3925 - Milosch Meriac 3927 - Geraint Luff 3929 - Dan Ros 3931 - John-Paul Stanford 3933 - Hugo Vincent 3935 - Carsten Bormann 3936 - Oeyvind Roenningstad 3938 - Frank Audun Kvamtroe 3940 - Krzysztof Chruściński 3942 - Andrzej Puzdrowski 3944 - Michael Richardson 3946 - David Brown 3948 - Emmanuel Baccelli 3950 17. References 3952 17.1. Normative References 3954 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 3955 Requirement Levels", BCP 14, RFC 2119, 3956 DOI 10.17487/RFC2119, March 1997, 3957 . 3959 [RFC4122] Leach, P., Mealling, M., and R. Salz, "A Universally 3960 Unique IDentifier (UUID) URN Namespace", RFC 4122, 3961 DOI 10.17487/RFC4122, July 2005, 3962 . 3964 [RFC8152] Schaad, J., "CBOR Object Signing and Encryption (COSE)", 3965 RFC 8152, DOI 10.17487/RFC8152, July 2017, 3966 . 3968 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 3969 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 3970 May 2017, . 3972 17.2. Informative References 3974 [I-D.ietf-suit-architecture] 3975 Moran, B., Meriac, M., Tschofenig, H., and D. Brown, "A 3976 Firmware Update Architecture for Internet of Things 3977 Devices", draft-ietf-suit-architecture-07 (work in 3978 progress), October 2019. 3980 [I-D.ietf-suit-information-model] 3981 Moran, B., Tschofenig, H., and H. Birkholz, "An 3982 Information Model for Firmware Updates in IoT Devices", 3983 draft-ietf-suit-information-model-04 (work in progress), 3984 October 2019. 3986 17.3. URIs 3988 [1] mailto:suit@ietf.org 3990 [2] https://www1.ietf.org/mailman/listinfo/suit 3992 [3] https://www.ietf.org/mail-archive/web/suit/current/index.html 3994 Authors' Addresses 3996 Brendan Moran 3997 Arm Limited 3999 EMail: Brendan.Moran@arm.com 4001 Hannes Tschofenig 4002 Arm Limited 4004 EMail: hannes.tschofenig@arm.com 4006 Henk Birkholz 4007 Fraunhofer SIT 4009 EMail: henk.birkholz@sit.fraunhofer.de