idnits 2.17.1 draft-moran-suit-manifest-04.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 56 instances of too long lines in the document, the longest one being 29 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 (March 11, 2019) is 1871 days in the past. Is this intentional? Checking references for intended status: Informational ---------------------------------------------------------------------------- -- Looks like a reference, but probably isn't: '1' on line 2978 -- Looks like a reference, but probably isn't: '2' on line 2980 -- Looks like a reference, but probably isn't: '3' on line 2982 == Missing Reference: '-1' is mentioned on line 1261, but not defined == Missing Reference: '-2' is mentioned on line 1263, but not defined == Missing Reference: '-3' is mentioned on line 1267, but not defined -- Looks like a reference, but probably isn't: '4' on line 1267 -- Looks like a reference, but probably isn't: '0' on line 1832 -- Looks like a reference, but probably isn't: '32567' on line 1833 ** Obsolete normative reference: RFC 8152 (Obsoleted by RFC 9052, RFC 9053) == Outdated reference: A later version (-16) exists of draft-ietf-suit-architecture-02 == Outdated reference: A later version (-13) exists of draft-ietf-suit-information-model-02 Summary: 2 errors (**), 0 flaws (~~), 7 warnings (==), 7 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 SUIT B. Moran 3 Internet-Draft H. Tschofenig 4 Intended status: Informational Arm Limited 5 Expires: September 12, 2019 H. Birkholz 6 Fraunhofer SIT 7 March 11, 2019 9 SUIT CBOR manifest serialisation format 10 draft-moran-suit-manifest-04 12 Abstract 14 This specification describes the format of a manifest. A manifest is 15 a bundle of metadata about the firmware for an IoT device, where to 16 find the firmware, the devices to which it applies, and cryptographic 17 information protecting the manifest. 19 Status of This Memo 21 This Internet-Draft is submitted in full conformance with the 22 provisions of BCP 78 and BCP 79. 24 Internet-Drafts are working documents of the Internet Engineering 25 Task Force (IETF). Note that other groups may also distribute 26 working documents as Internet-Drafts. The list of current Internet- 27 Drafts is at https://datatracker.ietf.org/drafts/current/. 29 Internet-Drafts are draft documents valid for a maximum of six months 30 and may be updated, replaced, or obsoleted by other documents at any 31 time. It is inappropriate to use Internet-Drafts as reference 32 material or to cite them other than as "work in progress." 34 This Internet-Draft will expire on September 12, 2019. 36 Copyright Notice 38 Copyright (c) 2019 IETF Trust and the persons identified as the 39 document authors. All rights reserved. 41 This document is subject to BCP 78 and the IETF Trust's Legal 42 Provisions Relating to IETF Documents 43 (https://trustee.ietf.org/license-info) in effect on the date of 44 publication of this document. Please review these documents 45 carefully, as they describe your rights and restrictions with respect 46 to this document. Code Components extracted from this document must 47 include Simplified BSD License text as described in Section 4.e of 48 the Trust Legal Provisions and are provided without warranty as 49 described in the Simplified BSD License. 51 This document may contain material from IETF Documents or IETF 52 Contributions published or made publicly available before November 53 10, 2008. The person(s) controlling the copyright in some of this 54 material may not have granted the IETF Trust the right to allow 55 modifications of such material outside the IETF Standards Process. 56 Without obtaining an adequate license from the person(s) controlling 57 the copyright in such materials, this document may not be modified 58 outside the IETF Standards Process, and derivative works of it may 59 not be created outside the IETF Standards Process, except to format 60 it for publication as an RFC or to translate it into languages other 61 than English. 63 Table of Contents 65 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 66 2. Conventions and Terminology . . . . . . . . . . . . . . . . . 4 67 3. SUIT digest container . . . . . . . . . . . . . . . . . . . . 5 68 4. Distributing firmware . . . . . . . . . . . . . . . . . . . . 6 69 5. Workflow of a device applying a firmware update . . . . . . . 6 70 6. SUIT manifest goals . . . . . . . . . . . . . . . . . . . . . 6 71 7. SUIT manifest design overview . . . . . . . . . . . . . . . . 8 72 7.1. Severable Elements . . . . . . . . . . . . . . . . . . . 9 73 7.2. Conventions . . . . . . . . . . . . . . . . . . . . . . . 9 74 7.3. Payloads . . . . . . . . . . . . . . . . . . . . . . . . 10 75 8. Manifest Structure . . . . . . . . . . . . . . . . . . . . . 10 76 8.1. Outer wrapper . . . . . . . . . . . . . . . . . . . . . . 12 77 8.2. Manifest . . . . . . . . . . . . . . . . . . . . . . . . 13 78 8.3. SUIT_Dependency . . . . . . . . . . . . . . . . . . . . . 16 79 8.4. SUIT_Component . . . . . . . . . . . . . . . . . . . . . 17 80 8.5. SUIT_Component_Reference . . . . . . . . . . . . . . . . 17 81 8.6. Manifest Parameters . . . . . . . . . . . . . . . . . . . 18 82 8.6.1. SUIT_Parameter_Strict_Order . . . . . . . . . . . . . 20 83 8.6.2. SUIT_Parameter_Coerce_Condition_Failure . . . . . . . 20 84 8.7. SUIT_Parameter_Encryption_Info . . . . . . . . . . . . . 20 85 8.8. SUIT_Parameter_Compression_Info . . . . . . . . . . . . . 20 86 8.9. SUIT_Parameter_Unpack_Info . . . . . . . . . . . . . . . 21 87 8.10. SUIT_Parameters CDDL . . . . . . . . . . . . . . . . . . 21 88 8.11. SUIT_Command_Sequence . . . . . . . . . . . . . . . . . . 23 89 8.12. SUIT_Condition . . . . . . . . . . . . . . . . . . . . . 24 90 8.12.1. ID Conditions . . . . . . . . . . . . . . . . . . . 25 91 8.12.2. SUIT_Condition_Image_Match . . . . . . . . . . . . . 26 92 8.12.3. SUIT_Condition_Image_Not_Match . . . . . . . . . . . 26 93 8.12.4. SUIT_Condition_Use_Before . . . . . . . . . . . . . 26 94 8.12.5. SUIT_Condition_Minimum_Battery . . . . . . . . . . . 26 95 8.12.6. SUIT_Condition_Update_Authorised . . . . . . . . . . 27 96 8.12.7. SUIT_Condition_Version . . . . . . . . . . . . . . . 27 97 8.12.8. SUIT_Condition_Custom . . . . . . . . . . . . . . . 28 98 8.12.9. Identifiers . . . . . . . . . . . . . . . . . . . . 28 99 8.12.10. SUIT_Condition CDDL . . . . . . . . . . . . . . . . 29 100 8.13. SUIT_Directive . . . . . . . . . . . . . . . . . . . . . 30 101 8.13.1. SUIT_Directive_Set_Component_Index . . . . . . . . . 31 102 8.13.2. SUIT_Directive_Set_Manifest_Index . . . . . . . . . 32 103 8.13.3. SUIT_Directive_Run_Sequence . . . . . . . . . . . . 32 104 8.13.4. SUIT_Directive_Run_Sequence_Conditional . . . . . . 33 105 8.13.5. SUIT_Directive_Process_Dependency . . . . . . . . . 33 106 8.13.6. SUIT_Directive_Set_Parameters . . . . . . . . . . . 33 107 8.13.7. SUIT_Directive_Set_Parameter_State_Append . . . . . 34 108 8.13.8. SUIT_Directive_Override_Parameters . . . . . . . . . 34 109 8.13.9. SUIT_Directive_Fetch . . . . . . . . . . . . . . . . 34 110 8.13.10. SUIT_Directive_Copy . . . . . . . . . . . . . . . . 35 111 8.13.11. SUIT_Directive_Run . . . . . . . . . . . . . . . . . 36 112 8.13.12. SUIT_Directive_Wait . . . . . . . . . . . . . . . . 36 113 8.13.13. SUIT_Directive CDDL . . . . . . . . . . . . . . . . 37 114 9. Dependency processing . . . . . . . . . . . . . . . . . . . . 39 115 10. Access Control Lists . . . . . . . . . . . . . . . . . . . . 40 116 11. Creating conditional sequences . . . . . . . . . . . . . . . 40 117 12. Full CDDL . . . . . . . . . . . . . . . . . . . . . . . . . . 41 118 13. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . 46 119 13.1. Example 0: . . . . . . . . . . . . . . . . . . . . . . . 47 120 13.2. Example 1: . . . . . . . . . . . . . . . . . . . . . . . 48 121 13.3. Example 2: . . . . . . . . . . . . . . . . . . . . . . . 50 122 13.4. Example 3: . . . . . . . . . . . . . . . . . . . . . . . 53 123 13.5. Example 4: . . . . . . . . . . . . . . . . . . . . . . . 56 124 13.6. Example 5: . . . . . . . . . . . . . . . . . . . . . . . 59 125 13.7. Example 6: . . . . . . . . . . . . . . . . . . . . . . . 62 126 14. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 65 127 15. Security Considerations . . . . . . . . . . . . . . . . . . . 65 128 16. Mailing List Information . . . . . . . . . . . . . . . . . . 66 129 17. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 66 130 18. References . . . . . . . . . . . . . . . . . . . . . . . . . 66 131 18.1. Normative References . . . . . . . . . . . . . . . . . . 66 132 18.2. Informative References . . . . . . . . . . . . . . . . . 67 133 18.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 67 134 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 68 136 1. Introduction 138 A firmware update mechanism is an essential security feature for IoT 139 devices to deal with vulnerabilities. While the transport of 140 firmware images to the devices themselves is important there are 141 already various techniques available, such as the Lightweight 142 Machine-to-Machine (LwM2M) protocol offering device management of IoT 143 devices. Equally important is the inclusion of meta-data about the 144 conveyed firmware image (in the form of a manifest) and the use of 145 end-to-end security protection to detect modifications and 146 (optionally) to make reverse engineering more difficult. End-to-end 147 security allows the author, who builds the firmware image, to be sure 148 that no other party (including potential adversaries) can install 149 firmware updates on IoT devices without adequate privileges. This 150 authorization process is ensured by the use of dedicated symmetric or 151 asymmetric keys installed on the IoT device: for use cases where only 152 integrity protection is required it is sufficient to install a trust 153 anchor on the IoT device. For confidentiality protected firmware 154 images it is additionally required to install either one or multiple 155 symmetric or asymmetric keys on the IoT device. Starting security 156 protection at the author is a risk mitigation technique so firmware 157 images and manifests can be stored on untrusted respositories; it 158 also reduces the scope of a compromise of any repository or 159 intermediate system to be no worse than a denial of service. 161 It is assumed that the reader is familiar with the high-level 162 firmware update architecture [Architecture]. This document is 163 structured as follows: In Section 8 we describe the main building 164 blocks of the manifest and Section 12 contains the description of the 165 CBOR of the manifest. 167 The SUIT manifest is heavily optimised for consumption by constrained 168 devices. This means that it is not constructed as a conventional 169 descriptive document, as described in [Behaviour]. This means that a 170 user viewing the contents of the document will require tooling to 171 view the contents in a more descriptive way. 173 2. Conventions and Terminology 175 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 176 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 177 "OPTIONAL" in this document are to be interpreted as described in 178 BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all 179 capitals, as shown here. 181 - SUIT: Sofware Update for the Internet of Things, the IETF working 182 group for this standard. 184 - Payload: A piece of information to be delivered. Typically 185 Firmware for the purposes of SUIT. 187 - Resource: A piece of information that is used to construct a 188 payload. 190 - Manifest: A piece of information that describes one or more 191 payloads, one or more resources, and the processors needed to 192 transform resources into payloads. 194 - Update: One or more manifests that describe one or more payloads. 196 - Update Authority: The owner of a cryptographic key used to sign 197 updates, trusted by recipient devices. 199 - Recipient: The system, typically an IoT device, that receives a 200 manifest. 202 - Condition: A test for a property of the Recipient or its 203 components. 205 - Directive: An action for the Recipient to perform. 207 - Command: A Condition or a Directive. 209 3. SUIT digest container 211 RFC 8152 [RFC8152] provides containers for signature, MAC, and 212 encryption, but no basic digest container. The container needed for 213 a digest requires a type identifier and a container for the raw 214 digest data. Some forms of digest may require additional parameters. 215 These can be added following the digest. Algorithm identifiers 216 defined in RFC 6920 [RFC6920] are reused for this digest container. 217 This structure is described by the following CDDL: 219 SUIT_Digest = [ 220 suit-digest-algorithm-id : $suit-digest-algorithm-ids, 221 suit-digest-bytes : bytes, 222 ? suit-digest-parameters : any 223 ] 225 ; Named Information Hash Algorithm Identifiers 226 digest-algorithm-ids /= algorithm-id-sha256 227 digest-algorithm-ids /= algorithm-id-sha256-128 228 digest-algorithm-ids /= algorithm-id-sha256-120 229 digest-algorithm-ids /= algorithm-id-sha256-96 230 digest-algorithm-ids /= algorithm-id-sha256-64 231 digest-algorithm-ids /= algorithm-id-sha256-32 232 digest-algorithm-ids /= algorithm-id-sha384 233 digest-algorithm-ids /= algorithm-id-sha512 234 digest-algorithm-ids /= algorithm-id-sha3-224 235 digest-algorithm-ids /= algorithm-id-sha3-256 236 digest-algorithm-ids /= algorithm-id-sha3-384 237 digest-algorithm-ids /= algorithm-id-sha3-512 239 4. Distributing firmware 241 Distributing firmware in a multi-party environment is a difficult 242 operation. Each party requires a different subset of data. Some 243 data may not be accessible to all parties. Multiple signatures may 244 be required from parties with different authorities. This topic is 245 covered in more depth in [Architecture] 247 5. Workflow of a device applying a firmware update 249 The manifest is designed to work with a pull parser, where each 250 section of the manifest is used in sequence. The expected workflow 251 for a device installing an update can be broken down into 5 steps: 253 1. Verify the signature of the manifest 255 2. Verify the applicability of the manifest 257 3. Resolve dependencies 259 4. Fetch payload(s) 261 5. Install payload(s) 263 When installation is complete, similar information can be used for 264 validating and running images in a further three steps: 266 1. Verify image(s) 268 2. Load image(s) 270 3. Run image(s) 272 When multiple manifests are used for an update, each manifest's steps 273 occur in a lockstep fashion; all manifests have dependency resolution 274 performed before any manifest performs a payload fetch, etc. 276 6. SUIT manifest goals 278 The manifest described in this document is intended to simplify the 279 construction of constrained device firmware update solutions. It is 280 also intended to allow update authors to describe complex update 281 processes for complex devices. 283 Manifests implemented as descriptive documents require changes to the 284 parser and the information model whenever a new feature is added. 285 This is particularly accentuated when the parser is a fixed-function 286 minimal parser (or a pull parser) such as the type that is typically 287 used in a bootloader or in a constrained client. The issue is not as 288 significant in devices that can use general purpose parsers. 290 The manifest detailed in this document aims to address these and more 291 problems by changing the processing model from a piece of software 292 that loads a manifest, interprets the data, then performs some 293 actions, into a model in which the software performs exactly the 294 operations stated in the manifest, in order. This allows the 295 manifest to encode data in a way that matches precisely with what the 296 parser expects. It also makes inflexible code, like a bootloader, 297 more flexible in what it can do; because the manifest defines part of 298 the "program," the manifest's execution defines part of the behaviour 299 of the system. Further detail on this approach is covered in 300 [Behaviour] 302 The SUIT manifest can be used for a variety of purposes throughout 303 its lifecycle. The manifest allows: 305 1. the Firmware Author to reason about releasing a firmware. 307 2. the Network Operator to reason about compatibility of a firmware. 309 3. the Device Operator to reason about the impact of a firmware. 311 4. the Device Operator to manage distribution of firmware to 312 devices. 314 5. the Plant Manager to reason about timing and acceptance of 315 firmware updates. 317 6. the device to reason about the authority & authenticity of a 318 firmware prior to installation. 320 7. the device to reason about the applicability of a firmware. 322 8. the device to reason about the installation of a firmware. 324 9. the device to reason about the authenticity of a firmware at 325 boot. 327 Each of these uses happens at a different stage of the manifest 328 lifecycle, so each has different requirements. 330 To verify authenticity at boot time, only the smallest portion of the 331 manifest is required. This core part of the manifest describes only 332 the fully installed firmware and any of its dependencies. 334 7. SUIT manifest design overview 336 In order to provide flexible behaviour to constrained devices, while 337 still allowing more powerful devices to use their full capabilities, 338 the SUIT manifest takes a new approach, encoding the required 339 behaviour of a Recipient device, instead of just presenting the 340 information used to determine that behaviour. This gives benefits 341 equivalent to those provided by a scripting language or byte code, 342 with two substantial differences. First, the language is extremely 343 high level, consisting of only the operations that a device may 344 perform during update and secure boot of a firmware image. The 345 language specifies behaviours in a linearised form, without branches 346 or loops. Conditional processing is supported, and parallel and out- 347 of-order processing may be performed by sufficiently capable devices. 349 By structuring the data in this way, the manifest processor becomes a 350 very simple engine that uses a pull parser to interpret the manifest. 351 This pull parser invokes a series of command handlers that evaluate a 352 Condition or execute a Directive. Most data is structured in a 353 highly regular pattern, which simplifies the parser. 355 The results of this allow a Recipient with minimal functionality to 356 perform complex updates with reduced overhead. Conditional execution 357 of commands allows a simple device to perform important decisions at 358 validation-time, such as which differential update to download for a 359 given current version, or which hash to check, based on the 360 installation address. 362 Dependency handling is vastly simplified as well. Dependencies 363 function like subroutines of the language. When a manifest has a 364 dependency, it can invoke that dependency's commands and modify their 365 behaviour by setting parameters. Because some parameters come with 366 security implications, the dependencies also have a mechanism to 367 reject modifications to parameters on a fine-grained level. 369 Developing a robust permissions system works in this model too. The 370 Recipient can use a simple ACL that is a table of Identities and 371 Component Identifier permissions to ensure that only manifests 372 authenticated by the appropriate identity have access to define a 373 component. 375 Capability reporting is similarly simplified. A Recipient can report 376 the Commands and Parameters that it supports. This is sufficiently 377 precise for a manifest author to create a manifest that the Recipient 378 can accept. 380 The simplicity of design in the Recipient due to all of these 381 benefits allows even a highly constrained platform to use advanced 382 update capabilities. 384 7.1. Severable Elements 386 Because the manifest can be used by different actors at different 387 times, some parts of the manifest can be removed without affecting 388 later stages of the lifecycle. This is called "Severing." Severing 389 of information is achieved by separating that information from the 390 signed container so that removing it does not affect the signature. 391 This means that ensuring authenticity of severable parts of the 392 manifest is a requirement for the signed portion of the manifest. 393 Severing some parts makes it possible to discard parts of the 394 manifest that are no longer necessary. This is important because it 395 allows the storage used by the manifest to be greatly reduced. For 396 example, no text size limits are needed if text is removed from the 397 manifest prior to delivery to a constrained device. 399 Elements are made severable by removing them from the manifest, 400 encoding them in a bstr, and placing a SUIT_Digest of the bstr in the 401 manifest so that they can still be authenticated. The SUIT_Digest 402 typically consumes 4 bytes more than the size of the raw digest, 403 therefore elements smaller than (Digest Bits)/8 + 4 SHOULD never be 404 severable. Elements larger than (Digest Bits)/8 + 4 MAY be 405 severable, while elements that are much larger than (Digest Bits)/8 + 406 4 SHOULD be severable. 408 7.2. Conventions 410 The map indices in this encoding are reset to 1 for each map within 411 the structure. This is to keep the indices as small as possible. 412 The goal is to keep the index objects to single bytes (CBOR positive 413 integers 1-23). 415 Wherever enumerations are used, they are started at 1. This allows 416 detection of several common software errors that are caused by 417 uninitialised variables. Positive numbers in enumerations are 418 reserved for IANA registration. Negative numbers are used to 419 identify application-specific implementations. 421 CDDL names are hyphenated and CDDL structures follow the convention 422 adopted in COSE [RFC8152]: SUIT_Structure_Name. 424 7.3. Payloads 426 Payloads can take many forms, for example, binary, hex, s-record, 427 elf, binary diff, PEM certificate, CBOR Web Token, serialised 428 configuration. These payloads fall into two broad categories: those 429 that require installation-time unpacking and those that do not. 430 Binary, PEM certificate, and CBOR Web Token do not require 431 installation-time unpacking. Hex, s-record, elf, and serialised 432 configuration require installation-time unpacking. 434 Some payloads cannot be directly converted to a writable binary 435 stream. Hex, s-record, and elf may contain gaps and they have no 436 guarantee of monotonic increase of address, which makes pre- 437 processing them into a binary stream difficult on constrained 438 platforms. Serialised configuration may be unpacked into a 439 configuration database, which makes it impossible to preprocess into 440 a binary stream, suitable for direct writing. 442 Where a specialised unpacking algorithm is needed, a digest is not 443 always calculable over an installed payload. For example, an elf, 444 s-record or hex file may contain gaps that can contain any data, 445 while not changing whether or not an installed payload is valid. 446 Serialised configuration may update only some device data rather than 447 all of it. This means that the digest cannot always be calculated 448 over an installed payload when a specialised installer is used. 450 This presents two problems for the manifest: first, it must indicate 451 that a specialised installer is needed and, second, it cannot provide 452 a hash of the payload that is checkable after installation. These 453 two problems are resolved in two ways: 455 1. Payloads that need a specialised installer must indicate this in 456 suit-payload-info-unpack. 458 2. Payloads that need specialised verification must indicate this in 459 the SUIT_Payload section or SUIT_Parameter_Image_Digest by 460 indicating a SUIT_Digest algorithm that correctly validates their 461 information. 463 8. Manifest Structure 465 The manifest is divided into several sections in a hierarchy as 466 follows: 468 1. The outer wrapper 470 1. The authentication wrapper 471 2. The manifest 473 1. Critical Information 475 2. List of dependencies 477 3. List of payloads 479 4. List of payloads in dependencies 481 5. Common list of conditions, directives 483 6. Dependency resolution Reference or list of conditions, 484 directives 486 7. Payload fetch Reference or list of conditions, 487 directives 489 8. Installation Reference or list of conditions, directives 491 9. Verification conditions/directives 493 10. Load conditions/directives 495 11. Run conditions/directives 497 12. Text / Reference 499 13. COSWID / Reference 501 3. Dependency resolution conditions/directives 503 4. Payload fetch conditions/directives 505 5. Installation conditions/directives 507 6. Text 509 7. COSWID / Reference 511 8. Intermediate Certificate(s) / CWTs 513 9. Small Payload(s) 515 8.1. Outer wrapper 517 This object is a container for the other pieces of the manifest to 518 provide a common mechanism to find each of the parts. All elements 519 of the outer wrapper are contained in bstr objects. Wherever the 520 manifest references an object in the outer wrapper, the bstr is 521 included in the digest calculation. 523 The CDDL that describes the wrapper is below 525 SUIT_Outer_Wrapper = { 526 suit-authentication-wrapper => bstr .cbor 527 SUIT_Authentication_Wrapper / nil, 528 suit-manifest => bstr .cbor Manifest, 529 suit-dependency-resolution => bstr .cbor SUIT_Command_Sequence, 530 suit-payload-fetch => bstr .cbor SUIT_Command_Sequence, 531 suit-install => bstr .cbor SUIT_Command_Sequence, 532 suit-text-external => bstr .cbor SUIT_Text_Info, 533 suit-coswid-external => bstr .cbor COSWID 534 } 535 suit-authentication-wrapper = 1 536 suit-manifest = 2 537 suit-dependency-resolution = 7 538 suit-payload-fetch = 8 539 suit-install = 9 540 suit-text = 13 541 suit-coswid = 14 543 SUIT_Authentication_Wrapper = [ * (COSE_Mac_Tagged / COSE_Sign_Tagged / 544 COSE_Mac0_Tagged / COSE_Sign1_Tagged)] 546 All elements of the outer wrapper must be wrapped in a bstr to 547 minimize the complexity of the code that evaluates the cryptographic 548 integrity of the element and to ensure correct serialisation for 549 integrity and authenticity checks. 551 The suit-authentication-wrapper contains a list of 1 or more 552 cryptographic authentication wrappers for the core part of the 553 manifest. These are implemented as COSE_Mac_Tagged or 554 COSE_Sign_Tagged blocks. The Manifest is authenticated by these 555 blocks in "detached payload" mode. The COSE_Mac_Tagged and 556 COSE_Sign_Tagged blocks are described in RFC 8152 [RFC8152] and are 557 beyond the scope of this document. The suit-authentication-wrapper 558 MUST come first in the SUIT_Outer_Wrapper, regardless of canonical 559 encoding of CBOR. All validators MUST reject any SUIT_Outer_Wrapper 560 that begins with any element other than a suit-authentication- 561 wrapper. 563 A manifest that has not had authentication information added MUST 564 still contain the suit-authentication-wrapper element, but the 565 content MUST be null. 567 suit-manifest contains a Manifest structure, which describes the 568 payload(s) to be installed and any dependencies on other manifests. 570 Each of suit-dependency-resolution, suit-payload-fetch, and suit- 571 payload-installation contain the severable contents of the 572 identically named portions of the manifest, described in Section 8.2. 574 suit-text contains all the human-readable information that describes 575 any and all parts of the manifest, its payload(s) and its 576 resource(s). 578 suit-coswid contains a Concise Software Identifier. This may be 579 discarded by the recipient if not needed. 581 8.2. Manifest 583 The manifest describes the critical metadata for the referenced 584 payload(s). In addition, it contains: 586 1. a version number for the manifest structure itself 588 2. a sequence number 590 3. a list of dependencies 592 4. a list of components affected 594 5. a list of components affected by dependencies 596 6. a reference for each of the severable blocks. 598 7. a list of actions that the recipient should perform. 600 The following CDDL fragment defines the manifest. 602 SUIT_Manifest = { 603 suit-manifest-version => 1, 604 suit-manifest-sequence-number => uint, 605 ? suit-dependencies => [ + SUIT_Dependency ], 606 ? suit-components => [ + SUIT_Component ], 607 ? suit-dependency-components => [ + SUIT_Component_Reference ], 608 ? suit-common => bstr .cbor SUIT_Command_Sequence, 609 ? suit-dependency-resolution => Digest / bstr .cbor SUIT_Command_Sequence, 610 ? suit-payload-fetch => Digest / bstr .cbor SUIT_Command_Sequence, 611 ? suit-install => Digest / bstr .cbor SUIT_Command_Sequence 612 ? suit-validate => bstr .cbor SUIT_Command_Sequence 613 ? suit-load => bstr .cbor SUIT_Command_Sequence 614 ? suit-run => bstr .cbor SUIT_Command_Sequence 615 ? suit-text-info => Digest / bstr .cbor SUIT_Text_Map 616 ? suit-coswid => Digest / bstr .cbor COSWID 617 } 619 suit-manifest-version = 1 620 suit-manifest-sequence-number = 2 621 suit-dependencies = 3 622 suit-components = 4 623 suit-dependency-components = 5 624 suit-common = 6 625 suit-dependency-resolution = 7 626 suit-payload-fetch = 8 627 suit-install = 9 628 suit-validate = 10 629 suit-load = 11 630 suit-run = 12 631 suit-text-info = 13 632 suit-coswid = 14 634 Several fields in the Manifest can be either a CBOR structure or a 635 SUIT_Digest. In each of these cases, the SUIT_Digest provides for a 636 severable field. Severable fields are RECOMMENDED to implement. In 637 particular, text SHOULD be severable, since most useful text elements 638 occupy more space than a SUIT_Digest, but are not needed by recipient 639 devices. Because SUIT_Digest is a CBOR Array and each severable 640 element is a CBOR bstr, it is straight-forward for a recipient to 641 determine whether an element has been severed. 643 The suit-manifest-version indicates the version of serialisation used 644 to encode the manifest. Version 1 is the version described in this 645 document. suit-manifest-version is MANDATORY. 647 The suit-manifest-sequence-number is a monotonically increasing anti- 648 rollback counter. It also helps devices to determine which in a set 649 of manifests is the "root" manifest in a given update. Each manifest 650 MUST have a sequence number higher than each of its dependencies. 651 Each recipient MUST reject any manifest that has a sequence number 652 lower than its current sequence number. It MAY be convenient to use 653 a UTC timestamp in seconds as the sequence number. suit-manifest- 654 sequence-number is MANDATORY. 656 suit-dependencies is a list of SUIT_Dependency blocks that specify 657 manifests that must be present before the current manifest can be 658 processed. suit-dependencies is OPTIONAL. 660 In order to distinguish between components that are affected by the 661 current manifest and components that are affected by a dependency, 662 they are kept in separate lists. Components affected by the current 663 manifest include the digest and size of the result. Components 664 affected by a manifest only include the component identifier and the 665 index of the manifest that fully defines the component. 667 suit-components is a list of SUIT_Component blocks that specify the 668 vital information about the content a component identifier should 669 contain following the update. These are the component identifiers 670 that will be affected by the content of the current manifest. suit- 671 components is OPTIONAL, but at least one manifest MUST contain a 672 suit-components block. 674 suit-dependency-components is a list of SUIT_Component_Reference 675 blocks that specify component identifiers that will be affected by 676 the content of a dependency of the current manifest. suit-dependency- 677 components is OPTIONAL. 679 suit-common is a SUIT_Command_Sequence to execute prior to executing 680 any other command sequence. Typical actions in suit-common include 681 setting expected device identity and image digests when they are 682 conditional (see Section 11 for more information on conditional 683 sequences). suit-common is OPTIONAL. 685 suit-dependency-resolution is a SUIT_Command_Sequence to execute in 686 order to perform dependency resolution. Typical actions include 687 configuring URIs of dependency manifests, fetching dependency 688 manifests, and validating dependency manifests' contents. suit- 689 dependency-resolution is MANDATORY when suit-dependencies is present. 691 suit-payload-fetch is a SUIT_Command_Sequence to execute in order to 692 obtain a payload. Some manifests may include these actions in the 693 suit-install section instead if they operate in a streaming 694 installation mode. This is particularly relevant for constrained 695 devices without any temporary storage for staging the update. suit- 696 payload-fetch is OPTIONAL. 698 suit-install is a SUIT_Command_Sequence to execute in order to 699 install a payload. Typical actions include verifying a payload 700 stored in temporary storage, copying a staged payload from temporary 701 storage, and unpacking a payload. suit-install is OPTIONAL. 703 suit-validate is a SUIT_Command_Sequence to execute in order to 704 validate that the result of applying the update is correct. Typical 705 actions involve image validation and manifest validation. suit- 706 validate is MANDATORY. If the manifest contains dependencies, one 707 process-dependency invocation per dependency or one process- 708 dependency invocation targeting all dependencies SHOULD be present in 709 validate. 711 suit-load is a SUIT_Command_Sequence to execute in order to prepare a 712 payload for execution. Typical actions include copying an image from 713 permanent storage into RAM, optionally including actions such as 714 decryption or decompression. suit-load is OPTIONAL. 716 suit-run is a SUIT_Command_Sequence to execute in order to run an 717 image. suit-run typically contains a single instruction: either the 718 "run" directive for the bootable manifest or the "process 719 dependencies" directive for any dependents of the bootable manifest. 720 suit-run is OPTIONAL. Only one manifest in an update may contain the 721 "run" directive. 723 suit-text-info is a digest that uniquely identifies the content of 724 the Text that is packaged in the OuterWrapper. text is OPTIONAL. 726 suit-coswid is a digest that uniquely identifies the content of the 727 concise-software-identifier that is packaged in the OuterWrapper. 728 coswid is OPTIONAL. 730 8.3. SUIT_Dependency 732 SUIT_Dependency specifies a manifest that describes a dependency of 733 the current manifest. 735 The following CDDL describes the SUIT_Dependency structure. 737 SUIT_Dependency = { 738 suit-dependency-digest => SUIT_Digest, 739 suit-dependency-prefix => SUIT_Component_Identifier, 740 } 742 The suit-dependency-digest specifies the dependency manifest uniquely 743 by identifying a particular Manifest structure. The digest is 744 calculated over the Manifest structure instead of the COSE 745 Sig_structure or Mac_structure. This means that a digest may need to 746 be calculated more than once, however this is necessary to ensure 747 that removing a signature from a manifest does not break dependencies 748 due to missing 'body_protected' and 'body_signed' elements. This is 749 also necessary to support the trusted intermediary use case, where an 750 intermediary re-signs the Manifest, removing the original signature, 751 potentially with a different algorithm, or trading COSE_Sign for 752 COSE_Mac. 754 The suit-dependency-prefix element contains a 755 SUIT_Component_Identifier. This specifies the scope at which the 756 dependency operates. This allows the dependency to be forwarded on 757 to a component that is capable of parsing its own manifests. It also 758 allows one manifest to be deployed to multiple dependent devices 759 without those devices needing consistent component hierarchy. This 760 element is OPTIONAL. 762 8.4. SUIT_Component 764 The SUIT_Component describes an image that is uniquely defined by the 765 current manifest. It consists of three elemnts: the component 766 identifier that represents a component that will be affected by this 767 manifest. This excludes components that are affected by 768 dependencies. The following CDDL describes the SUIT_Component. 770 SUIT_Component = { 771 suit-component-identifier => SUIT_Component_Identifier, 772 ? suit-component-size => uint, 773 ? suit-component-digest => Digest, 774 } 776 Because suit-component-size and suit-component-digest can be 777 dependent on installation offset, they cannot be exclusively 778 contained in SUIT_Component. However, since these are security 779 critical parameters, these parameters are updated to match the 780 contents of suit-components prior to processing suit-common. If 781 absent, these are set to Zero and NULL, respectively. This enforces 782 that the manifest defining a component is the only manifest that can 783 describe its contents. 785 8.5. SUIT_Component_Reference 787 The SUIT_Component_Reference describes an image that is defined by 788 another manifest. This is useful for overriding the behaviour of 789 another manifest, for example by directing the recipient to look at a 790 different URI for the image or by changing the expected format, such 791 as when a gateway performs decryption on behalf of a constrained 792 device. The following CDDL describes the SUIT_Component_Reference. 794 SUIT_Component_Reference = { 795 suit-component-identifier => SUIT_Component_Identifier, 796 suit-component-dependency-index => uint 797 } 799 8.6. Manifest Parameters 801 Many conditions and directives require additional information. That 802 information is contained within parameters that can be set in a 803 consistent way. Parameters MUST only be: 805 1. Integers 806 2. Byte strings 807 3. Booleans 809 This allows reduction of manifest size and replacement of parameters 810 from one manifest to the next. Byte strings MAY contain CBOR-encoded 811 objects. 813 The defined manifest parameters are described below. 815 +-------+-------+------+---------------+---------+------------------+ 816 | Param | CBOR | Defa | Scope | Name | Description | 817 | eter | Type | ult | | | | 818 | Code | | | | | | 819 +-------+-------+------+---------------+---------+------------------+ 820 | 1 | boole | 1 | Global | Strict | Requires that | 821 | | an | | | Order | the manifest is | 822 | | | | | | processed in a | 823 | | | | | | strictly linear | 824 | | | | | | fashion. Set to | 825 | | | | | | 0 to enable | 826 | | | | | | parallel | 827 | | | | | | handling of | 828 | | | | | | manifest | 829 | | | | | | directives. | 830 | | | | | | | 831 | 2 | boole | 0 | Global | Coerce | Coerces the | 832 | | an | | | Conditi | success code of | 833 | | | | | on | a command | 834 | | | | | Failure | segment to | 835 | | | | | | success even | 836 | | | | | | when aborted due | 837 | | | | | | to a condition | 838 | | | | | | failure. | 839 | | | | | | | 840 | 3 | bstr | nil | Component/Glo | Vendor | A RFC4122 UUID | 841 | | | | bal | ID | representing the | 842 | | | | | | vendor of the | 843 | | | | | | device or | 844 | | | | | | component | 845 | | | | | | | 846 | 4 | bstr | nil | Component/Glo | Class | A RFC4122 UUID | 847 | | | | bal | ID | representing the | 848 | | | | | | class of the | 849 | | | | | | device or | 850 | | | | | | component | 851 | | | | | | | 852 | 5 | bstr | nil | Component/Glo | Device | A RFC4122 UUID | 853 | | | | bal | ID | representing the | 854 | | | | | | device or | 855 | | | | | | component | 856 | | | | | | | 857 | 6 | bstr | nil | Component/Dep | URI | A CBOR encoded | 858 | | | | endency | List | list of ranked | 859 | | | | | | URIs | 860 | | | | | | | 861 | 7 | bstr | nil | Component/Dep | Encrypt | A COSE object | 862 | | | | endency | ion | defining the | 863 | | | | | Info | encryption mode | 864 | | | | | | of the target | 865 | | | | | | | 866 | 8 | bstr | nil | Component | Compres | A SUIT_Compressi | 867 | | | | | sion | on_Info object | 868 | | | | | Info | | 869 | | | | | | | 870 | 9 | bstr | nil | Component | Unpack | A | 871 | | | | | Info | SUIT_Unpack_Info | 872 | | | | | | object | 873 | | | | | | | 874 | 10 | int/b | nil | Component | Source | A SUIT_Component | 875 | | str | | | Compone | _Identifier or | 876 | | | | | nt | Component Index | 877 | | | | | | | 878 | 11 | bstr | nil | Component/Dep | Image | A SUIT_Digest | 879 | | | | endency | Digest | | 880 | | | | | | | 881 | 12 | bstr | nil | Component/Dep | Image | Integer size | 882 | | | | endency | Size | | 883 | | | | | | | 884 | nint | int/b | nil | Custom | Custom | Application- | 885 | | str | | | Paramet | defined | 886 | | | | | er | parameter | 887 +-------+-------+------+---------------+---------+------------------+ 888 Each parameter contains a Skip/Append flag. Append is an advanced 889 feature that is not available on highly constrained platforms. The 890 mechanism for setting the Append flag is TBD. 892 CBOR-encoded object parameters are still wrapped in a bstr. This is 893 because it allows a parser that is aggregating parameters to 894 reference the object with a single pointer and traverse it without 895 understanding the contents. This is important for modularisation and 896 division of responsibility within a pull parser. The same 897 consideration does not apply to Conditions and Directives because 898 those elements are invoked with their arguments immediately 900 8.6.1. SUIT_Parameter_Strict_Order 902 The Strict Order Parameter allows a manifest to govern when 903 directives can be executed out-of-order. This allows for systems 904 that have a sensitivity to order of updates to choose the order in 905 which they are executed. It also allows for more advanced systems to 906 parallelise their handling of updates. Strict Order defaults to 907 True. It MAY be set to False when the order of operations does not 908 matter. When arriving at the end of a command sequence, ALL commands 909 MUST have completed, regardless of the state of 910 SUIT_Parameter_Strict_Order. If SUIT_Parameter_Strict_Order is 911 returned to True, ALL preceding commands MUST complete before the 912 next command is executed. 914 8.6.2. SUIT_Parameter_Coerce_Condition_Failure 916 When executing a command sequence inside SUIT_Run_Sequence and a 917 condition failure occurs, the manifest processor aborts the sequence. 918 If Coerce Condition Failure is True, it returns Success. Otherwise, 919 it returns the original condition failure. 920 SUIT_Parameter_Coerce_Condition_Failure is scoped to the enclosing 921 SUIT_Directive_Run_Sequence. Its value is discarded when 922 SUIT_Directive_Run_Sequence terminates. 924 8.7. SUIT_Parameter_Encryption_Info 926 Encryption Info defines the mechanism that Fetch or Copy should use 927 to decrypt the data they transfer. SUIT_Parameter_Encryption_Info is 928 encoded as a COSE_Encrypt_Tagged or a COSE_Encrypt0_Tagged, wrapped 929 in a bstr 931 8.8. SUIT_Parameter_Compression_Info 933 Compression Info defines any information that is required for a 934 device to perform decompression operations. Typically, this includes 935 the algorithm identifier. 937 SUIT_Parameter_Compression_Info is defined by the following CDDL: 939 SUIT_Compression_Info = { 940 suit-compression-algorithm => SUIT_Compression_Algorithms 941 ? suit-compression-parameters => bstr 942 } 943 suit-compression-algorithm = 1 944 suit-compression-parameters = 2 946 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_gzip 947 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_bzip2 948 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_deflate 949 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_LZ4 950 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_lzma 952 SUIT_Compression_Algorithm_gzip = 1 953 SUIT_Compression_Algorithm_bzip2 = 2 954 SUIT_Compression_Algorithm_deflate = 3 955 SUIT_Compression_Algorithm_lz4 = 4 956 SUIT_Compression_Algorithm_lzma = 7 958 8.9. SUIT_Parameter_Unpack_Info 960 SUIT_Unpack_Info defines the information required for a device to 961 interpret a packed format, such as elf, hex, or binary diff. 962 SUIT_Unpack_Info is defined by the following CDDL: 964 SUIT_Unpack_Info = { 965 suit-unpack-algorithm => SUIT_Unpack_Algorithms 966 ? suit-unpack-parameters => bstr 967 } 968 suit-unpack-algorithm = 1 969 suit-unpack-parameters = 2 971 SUIT_Unpack_Algorithms //= SUIT_Unpack_Algorithm_Delta 972 SUIT_Unpack_Algorithms //= SUIT_Unpack_Algorithm_Hex 973 SUIT_Unpack_Algorithms //= SUIT_Unpack_Algorithm_Elf 975 SUIT_Unpack_Algorithm_Delta = 1 976 SUIT_Unpack_Algorithm_Hex = 2 977 SUIT_Unpack_Algorithm_Elf = 3 979 8.10. SUIT_Parameters CDDL 981 The following CDDL describes all SUIT_Parameters. 983 SUIT_Parameters //= SUIT_Parameter_Strict_Order 984 SUIT_Parameters //= SUIT_Parameter_Coerce_Condition_Failure 985 SUIT_Parameters //= SUIT_Parameter_Vendor_ID 986 SUIT_Parameters //= SUIT_Parameter_Class_ID 987 SUIT_Parameters //= SUIT_Parameter_Device_ID 988 SUIT_Parameters //= SUIT_Parameter_URI_List 989 SUIT_Parameters //= SUIT_Parameter_Encryption_Info 990 SUIT_Parameters //= SUIT_Parameter_Compression_Info 991 SUIT_Parameters //= SUIT_Parameter_Unpack_Info 992 SUIT_Parameters //= SUIT_Parameter_Source_Component 993 SUIT_Parameters //= SUIT_Parameter_Image_Digest 994 SUIT_Parameters //= SUIT_Parameter_Image_Size 995 SUIT_Parameters //= SUIT_Parameter_Custom 997 SUIT_Parameter_Strict_Order = (1 => bool) 998 SUIT_Parameter_Coerce_Condition_Failure = (2 => bool) 999 SUIT_Parameter_Vendor_ID = (3 => bstr) 1000 SUIT_Parameter_Class_ID = (4 => bstr) 1001 SUIT_Parameter_Device_ID = (5 => bstr) 1002 SUIT_Parameter_URI_List = (6 => bstr .cbor SUIT_URI_List) 1003 SUIT_Parameter_Encryption_Info = (7 => bstr .cbor SUIT_Encryption_Info) 1004 SUIT_Parameter_Compression_Info = (8 => bstr .cbor SUIT_Compression_Info) 1005 SUIT_Parameter_Unpack_Info = (9 => bstr .cbor SUIT_Unpack_Info) 1006 SUIT_Parameter_Source_Component = (10 => bstr .cbor SUIT_Component_Identifier) 1007 SUIT_Parameter_Image_Digest = (11 => bstr .cbor SUIT_Digest) 1008 SUIT_Parameter_Image_Size = (12 => uint) 1009 SUIT_Parameter_Custom = (nint => int/bool/bstr) 1011 SUIT_URI_List = [ + [priority: int, uri: tstr] ] 1013 SUIT_Encryption_Info= COSE_Encrypt_Tagged/COSE_Encrypt0_Tagged 1014 SUIT_Compression_Info = { 1015 suit-compression-algorithm => SUIT_Compression_Algorithms 1016 ? suit-compression-parameters => bstr 1017 } 1018 suit-compression-algorithm = 1 1019 suit-compression-parameters = 2 1021 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_gzip 1022 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_bzip2 1023 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_deflate 1024 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_LZ4 1025 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_lzma 1027 SUIT_Compression_Algorithm_gzip = 1 1028 SUIT_Compression_Algorithm_bzip2 = 2 1029 SUIT_Compression_Algorithm_deflate = 3 1030 SUIT_Compression_Algorithm_lz4 = 4 1031 SUIT_Compression_Algorithm_lzma = 7 1032 SUIT_Unpack_Info = { 1033 suit-unpack-algorithm => SUIT_Unpack_Algorithms 1034 ? suit-unpack-parameters => bstr 1035 } 1036 suit-unpack-algorithm = 1 1037 suit-unpack-parameters = 2 1039 SUIT_Unpack_Algorithms //= SUIT_Unpack_Algorithm_Delta 1040 SUIT_Unpack_Algorithms //= SUIT_Unpack_Algorithm_Hex 1041 SUIT_Unpack_Algorithms //= SUIT_Unpack_Algorithm_Elf 1043 SUIT_Unpack_Algorithm_Delta = 1 1044 SUIT_Unpack_Algorithm_Hex = 2 1045 SUIT_Unpack_Algorithm_Elf = 3 1047 8.11. SUIT_Command_Sequence 1049 A SUIT_Command_Sequence defines a series of actions that the 1050 recipient MUST take to accomplish a particular goal. These goals are 1051 defined in the manifest and include: 1053 1. Dependency Resolution 1055 2. Payload Fetch 1057 3. Payload Installation 1059 4. Image Validation 1061 5. Image Loading 1063 6. Run or Boot 1065 Each of these follows exactly the same structure to ensure that the 1066 parser is as simple as possible. 1068 Lists of commands are constructed from two kinds of element: 1070 1. Conditions that MUST be true-any failure is treated as a failure 1071 of the update/load/boot 1073 2. Directives that MUST be executed. 1075 The lists of commands are logically structured into sequences of zero 1076 or more conditions followed by zero or more directives. The 1077 *logical* structure is described by the following CDDL: 1079 Command_Sequence = { 1080 conditions => [ * Condition], 1081 directives => [ * Directive] 1082 } 1084 This introduces significant complexity in the parser, however, so the 1085 structure is flattened to make parsing simpler: 1087 SUIT_Command_Sequence = [ + (SUIT_Condition/SUIT_Directive) ] 1089 Each condition and directive is composed of: 1091 1. A command code identifier 1093 2. An argument block 1095 Argument blocks are defined for each type of command. 1097 Many conditions and directives apply to a given component, and these 1098 generally grouped together. Therefore, a special command to set the 1099 current component index is provided with a matching command to set 1100 the current manifest index. This index is a numeric index into the 1101 component ID tables defined at the beginning of the document. For 1102 the purpose of setting the index, the two component ID tables are 1103 considered to be concatenated together. 1105 To facilitate optional conditions, a special directive is provided. 1106 It runs a new list of conditions/directives that are contained as an 1107 argument to the directive. It also contains a flag that indicates 1108 whether or not a failure of a condition should indicate a failure of 1109 the update/boot. 1111 8.12. SUIT_Condition 1113 Conditions are used to define mandatory properties of a system in 1114 order for an update to be applied. They can be pre-conditions or 1115 post-conditons of any directive or series of directives, depending on 1116 where they are placed in the list. Conditions include: 1118 +----------------+-------------------+------------------------------+ 1119 | Condition Code | Condition Name | Argument Type | 1120 +----------------+-------------------+------------------------------+ 1121 | 1 | Vendor Identifier | RFC4122 UUID wrapped in a | 1122 | | | bstr | 1123 | | | | 1124 | 2 | Class Identifier | RFC4122 UUID wrapped in a | 1125 | | | bstr | 1126 | | | | 1127 | 3 | Device Identifier | RFC4122 UUID wrapped in a | 1128 | | | bstr | 1129 | | | | 1130 | 4 | Image Match | SUIT_Digest | 1131 | | | | 1132 | 5 | Image Not Match | SUIT_Digest | 1133 | | | | 1134 | 6 | Use Before | Unsigned Integer timestamp | 1135 | | | | 1136 | 7 | Minimum Battery | Unsigned Integer | 1137 | | | | 1138 | 8 | Update Authorised | Integer | 1139 | | | | 1140 | 9 | Version | List of Integers | 1141 | | | | 1142 | 10 | Component Offset | Unsigned Integer | 1143 | | | | 1144 | nint | Custom Condition | bstr | 1145 +----------------+-------------------+------------------------------+ 1147 Each condition MUST report a success code on completion. If a 1148 condition reports failure, then the current sequence of commands MUST 1149 terminate. If a recipient encounters an unknown Condition Code, it 1150 MUST report a failure. 1152 Positive Condition numbers are reserved for IANA registration. 1153 Negative numbers are reserved for proprietary, application-specific 1154 directives. 1156 8.12.1. ID Conditions 1158 There are three identifier-based conditions: 1159 SUIT_Condition_Vendor_Identifier, SUIT_Condition_Class_Identifier, 1160 and SUIT_Condition_Device_Identifier. Each of these conditions 1161 present a RFC 4122 [RFC4122] UUID that MUST be matched by the 1162 installing device in order to consider the manifest valid. 1164 These conditions MAY be used with or without an argument. If an 1165 argument is supplied, then it must be the RFC 4122 [RFC4122] UUID 1166 that must be matched for the condition to succeed. If no argument is 1167 supplied, then the recipient uses the ID parameter that has already 1168 been set using the Set Parameters directive. If no ID has been set, 1169 this condition fails. SUIT_Condition_Class_Identifier and 1170 SUIT_Condition_Vendor_Identifier are MANDATORY to implement. 1171 SUIT_Condition_Device_Identifier is OPTIONAL to implement. 1173 8.12.2. SUIT_Condition_Image_Match 1175 Verify that the current component matches the supplied digest. If no 1176 digest is specified, then the digest is verified against the digest 1177 specified in the Components list. If no digest is specified and the 1178 component is not present in the Components list, the condition fails. 1179 SUIT_Condition_Image_Match is MANDATORY to implement. 1181 8.12.3. SUIT_Condition_Image_Not_Match 1183 Verify that the current component does not match the supplied digest. 1184 If no digest is specified, then the digest is compared against the 1185 digest specified in the Components list. If no digest is specified 1186 and the component is not present in the Components list, the 1187 condition fails. SUIT_Condition_Image_Not_Match is OPTIONAL to 1188 implement. 1190 8.12.4. SUIT_Condition_Use_Before 1192 Verify that the current time is BEFORE the specified time. 1193 SUIT_Condition_Use_Before is used to specify the last time at which 1194 an update should be installed. One argument is required, encoded as 1195 a POSIX timestamp, that is seconds after 1970-01-01 00:00:00. 1196 Timestamp conditions MUST be evaluated in 64 bits, regardless of 1197 encoded CBOR size. SUIT_Condition_Use_Before is OPTIONAL to 1198 implement. 1200 8.12.5. SUIT_Condition_Minimum_Battery 1202 SUIT_Condition_Minimum_Battery provides a mechanism to test a 1203 device's battery level before installing an update. This condition 1204 is for use in primary-cell applications, where the battery is only 1205 ever discharged. For batteries that are charged, 1206 SUIT_Directive_Wait_Event is more appropriate, since it defines a 1207 "wait" until the battery level is sufficient to install the update. 1208 SUIT_Condition_Minimum_Battery is specified in mWh. 1209 SUIT_Condition_Minimum_Battery is OPTIONAL to implement. 1211 8.12.6. SUIT_Condition_Update_Authorised 1213 Request Authorisation from the application and fail if not 1214 authorised. This can allow a user to decline an update. Argument is 1215 an integer priority level. Priorities are application defined. 1216 SUIT_Condition_Update_Authorised is OPTIONAL to implement. 1218 8.12.7. SUIT_Condition_Version 1220 SUIT_Condition_Version allows comparing versions of firmware. 1221 Verifying image digests is preferred to version checks because 1222 digests are more precise. The image can be compared as: 1224 - Greater 1226 - Greater or Equal 1228 - Equal 1230 - Lesser or Equal 1232 - Lesser 1234 Versions are encoded as a CBOR list of integers. Comparisons are 1235 done on each integer in sequence. 1237 The following CDDL describes SUIT_Condition_Version_Argument 1239 SUIT_Condition_Version_Argument = [ 1240 suit-condition-version-comparison: SUIT_Condition_Version_Comparison_Types, 1241 suit-condition-version-comparison: SUIT_Condition_Version_Comparison_Value 1242 ] 1243 SUIT_Condition_Version_Comparison_Types /= SUIT_Condition_Version_Comparison_Greater 1244 SUIT_Condition_Version_Comparison_Types /= SUIT_Condition_Version_Comparison_Greater_Equal 1245 SUIT_Condition_Version_Comparison_Types /= SUIT_Condition_Version_Comparison_Equal 1246 SUIT_Condition_Version_Comparison_Types /= SUIT_Condition_Version_Comparison_Lesser_Equal 1247 SUIT_Condition_Version_Comparison_Types /= SUIT_Condition_Version_Comparison_Lesser 1248 SUIT_Condition_Version_Comparison_Greater = 1 1249 SUIT_Condition_Version_Comparison_Greater_Equal = 2 1250 SUIT_Condition_Version_Comparison_Equal = 3 1251 SUIT_Condition_Version_Comparison_Lesser_Equal = 4 1252 SUIT_Condition_Version_Comparison_Lesser = 5 1254 SUIT_Condition_Version_Comparison_Value = [+int] 1256 While the exact encoding of versions is application-defined, semantic 1257 versions map directly: 1259 - 1.2.3 = [1,2,3] 1261 - 1.2-rc3 = [1,2,-1,3] 1263 - 1.2-beta = [1,2,-2] 1265 - 1.2-alpha = [1,2,-3] 1267 - 1.2-alpha4 = [1,2,-3,4] 1269 SUIT_Condition_Version is OPTIONAL to implement. 1271 8.12.8. SUIT_Condition_Custom 1273 SUIT_Condition_Custom describes any proprietary, application specific 1274 condition. This is encoded as a negative integer, chosen by the 1275 firmware developer, and a bstr that encodes the parameters passed to 1276 the system that evaluates the condition matching that integer. 1277 SUIT_Condition_Custom is OPTIONAL to implement. 1279 8.12.9. Identifiers 1281 Many conditions use identifiers to determine whether a manifest 1282 matches a given recipient or not. These identifiers are defined to 1283 be RFC 4122 [RFC4122] UUIDs. These UUIDs are explicitly NOT human- 1284 readable. They are for machine-based matching only. 1286 A device may match any number of UUIDs for vendor or class 1287 identifier. This may be relevant to physical or software modules. 1288 For example, a device that has an OS and one or more applications 1289 might list one Vendor ID for the OS and one or more additional Vendor 1290 IDs for the applications. This device might also have a Class ID 1291 that must be matched for the OS and one or more Class IDs for the 1292 applications. 1294 A more complete example: A device has the following physical 1295 components: 1. A host MCU 2. A WiFi module 1297 This same device has three software modules: 1. An operating system 1298 2. A WiFi module interface driver 3. An application 1300 Suppose that the WiFi module's firmware has a proprietary update 1301 mechanism and doesn't support manifest processing. This device can 1302 report four class IDs: 1304 1. hardware model/revision 1306 2. OS 1307 3. WiFi module model/revision 1309 4. Application 1311 This allows the OS, WiFi module, and application to be updated 1312 independently. To combat possible incompatibilities, the OS class ID 1313 can be changed each time the OS has a change to its API. 1315 This approach allows a vendor to target, for example, all devices 1316 with a particular WiFi module with an update, which is a very 1317 powerful mechanism, particularly when used for security updates. 1319 8.12.9.1. Creating UUIDs: 1321 UUIDs MUST be created according to RFC 4122 [RFC4122]. UUIDs SHOULD 1322 use versions 3, 4, or 5, as described in RFC4122. Versions 1 and 2 1323 do not provide a tangible benefit over version 4 for this 1324 application. 1326 The RECOMMENDED method to create a vendor ID is: Vendor ID = 1327 UUID5(DNS_PREFIX, vendor domain name) 1329 The RECOMMENDED method to create a class ID is: Class ID = 1330 UUID5(Vendor ID, Class-Specific-Information) 1332 Class-specific information is composed of a variety of data, for 1333 example: 1335 - Model number 1337 - Hardware revision 1339 - Bootloader version (for immutable bootloaders) 1341 8.12.10. SUIT_Condition CDDL 1343 The following CDDL describes SUIT_Condition: 1345 SUIT_Condition //= (nint => bstr) 1346 SUIT_Condition //= SUIT_Condition_Vendor_Identifier 1347 SUIT_Condition //= SUIT_Condition_Class_Identifier 1348 SUIT_Condition //= SUIT_Condition_Device_Identifier 1349 SUIT_Condition //= SUIT_Condition_Image_Match 1350 SUIT_Condition //= SUIT_Condition_Image_Not_Match 1351 SUIT_Condition //= SUIT_Condition_Use_Before 1352 SUIT_Condition //= SUIT_Condition_Minimum_Battery 1353 SUIT_Condition //= SUIT_Condition_Update_Authorised 1354 SUIT_Condition //= SUIT_Condition_Version 1355 SUIT_Condition //= SUIT_Condition_Component_Offset 1356 SUIT_Condition //= SUIT_Condition_Custom 1358 SUIT_Condition_Vendor_Identifier = (1 => bstr .size 16) 1359 SUIT_Condition_Class_Identifier = (2 => bstr .size 16) 1360 SUIT_Condition_Device_Identifier = (3 => bstr .size 16) 1361 SUIT_Condition_Image_Match = (4 => SUIT_Digest) 1362 SUIT_Condition_Image_Not_Match = (5 => SUIT_Digest) 1363 SUIT_Condition_Use_Before = (6 => uint) 1364 SUIT_Condition_Minimum_Battery = (7 => uint) 1365 SUIT_Condition_Update_Authorised = (8 => int) 1366 SUIT_Condition_Version = (9 => SUIT_Condition_Version_Argument) 1367 SUIT_Condition_Component_Offset = (10 => uint) 1368 SUIT_Condition_Custom = (nint => bstr) 1370 SUIT_Condition_Version_Argument = [ 1371 suit-condition-version-comparison: SUIT_Condition_Version_Comparison_Types, 1372 suit-condition-version-comparison: SUIT_Condition_Version_Comparison_Value 1373 ] 1374 SUIT_Condition_Version_Comparison_Types /= SUIT_Condition_Version_Comparison_Greater 1375 SUIT_Condition_Version_Comparison_Types /= SUIT_Condition_Version_Comparison_Greater_Equal 1376 SUIT_Condition_Version_Comparison_Types /= SUIT_Condition_Version_Comparison_Equal 1377 SUIT_Condition_Version_Comparison_Types /= SUIT_Condition_Version_Comparison_Lesser_Equal 1378 SUIT_Condition_Version_Comparison_Types /= SUIT_Condition_Version_Comparison_Lesser 1380 SUIT_Condition_Version_Comparison_Greater = 1 1381 SUIT_Condition_Version_Comparison_Greater_Equal = 2 1382 SUIT_Condition_Version_Comparison_Equal = 3 1383 SUIT_Condition_Version_Comparison_Lesser_Equal = 4 1384 SUIT_Condition_Version_Comparison_Lesser = 5 1386 SUIT_Condition_Version_Comparison_Value = [+int] 1388 8.13. SUIT_Directive 1390 Directives are used to define the behaviour of the recipient. 1391 Directives include: 1393 +----------------+--------------------------+ 1394 | Directive Code | Directive Name | 1395 +----------------+--------------------------+ 1396 | 11 | Set Component Index | 1397 | | | 1398 | 12 | Set Manifest Index | 1399 | | | 1400 | 13 | Run Sequence | 1401 | | | 1402 | 14 | Run Sequence Conditional | 1403 | | | 1404 | 15 | Process Dependency | 1405 | | | 1406 | 16 | Set Parameters | 1407 | | | 1408 | 17 | Reserved | 1409 | | | 1410 | 18 | Reserved | 1411 | | | 1412 | 19 | Override Parameters | 1413 | | | 1414 | 20 | Fetch | 1415 | | | 1416 | 21 | Copy | 1417 | | | 1418 | 22 | Run | 1419 | | | 1420 | 23 | Wait | 1421 +----------------+--------------------------+ 1423 When a Recipient executes a Directive, it MUST report a success code. 1424 If the Directive reports failure, then the current Command Sequence 1425 MUST terminate. 1427 8.13.1. SUIT_Directive_Set_Component_Index 1429 Set Component Index defines the component to which successive 1430 directives and conditions will apply. The supplied argument MUST be 1431 either a boolean or an unsigned integer index into the concatenation 1432 of suit-components and suit-dependency-components. If the following 1433 directives apply to ALL components, then the boolean value "True" is 1434 used instead of an index. True does not apply to dependency 1435 components. If the following directives apply to NO components, then 1436 the boolean value "False" is used. When 1437 SUIT_Directive_Set_Manifest_Index is used, 1438 SUIT_Directive_Set_Component_Index = False is implied. When 1439 SUIT_Directive_Set_Component_Index is used, 1440 SUIT_Directive_Set_Manifest_Index = False is implied. 1442 The following CDDL describes the argument to 1443 SUIT_Directive_Set_Component_Index. 1445 SUIT_Directive_Set_Component_Index_Argument = uint/bool 1447 8.13.2. SUIT_Directive_Set_Manifest_Index 1449 Set Manifest Index defines the manifest to which successive 1450 directives and conditions will apply. The supplied argument MUST be 1451 either a boolean or an unsigned integer index into the dependencies. 1452 If the following directives apply to ALL dependencies, then the 1453 boolean value "True" is used instead of an index. If the following 1454 directives apply to NO dependencies, then the boolean value "False" 1455 is used. When SUIT_Directive_Set_Component_Index is used, 1456 SUIT_Directive_Set_Manifest_Index = False is implied. When 1457 SUIT_Directive_Set_Manifest_Index is used, 1458 SUIT_Directive_Set_Component_Index = False is implied. 1460 Typical operations that require SUIT_Directive_Set_Manifest_Index 1461 include setting a source URI, invoking "Fetch," or invoking "Process 1462 Dependency" for an individual dependency. 1464 The following CDDL describes the argument to 1465 SUIT_Directive_Set_Manifest_Index. 1467 SUIT_Directive_Set_Manifest_Index_Argument = uint/bool 1469 8.13.3. SUIT_Directive_Run_Sequence 1471 To enable conditional commands, and to allow several strictly ordered 1472 sequences to be executed out-of-order, SUIT_Run_Sequence allows the 1473 manifest processor to execute its argument as a 1474 SUIT_Command_Sequence. The argument must be wrapped in a bstr. 1476 When a sequence is executed, any failure of a condition causes 1477 immediate termination of the sequence. 1479 The following CDDL describes the SUIT_Run_Sequence argument. 1481 SUIT_Directive_Run_Sequence_Argument = bstr .cbor SUIT_Command_Sequence 1483 When SUIT_Directive_Run_Sequence completes, it forwards the last 1484 status code that occurred in the sequence. If the Coerce on 1485 Condition Failure parameter is true, then SUIT_Directive_Run_Sequence 1486 only fails when a directive in the argument sequence fails. 1488 SUIT_Parameter_Coerce_Condition_Failure defaults to False when 1489 SUIT_Directive_Run_Sequence begins. Its value is discarded when 1490 SUIT_Directive_Run_Sequence terminates. 1492 8.13.4. SUIT_Directive_Run_Sequence_Conditional 1494 This command is exactly the same as SUIT_Directive_Run_Sequence, 1495 except that it initialises Coerce on Condition Failure to True. 1497 SUIT_Parameter_Coerce_Condition_Failure defaults to True when 1498 SUIT_Directive_Run_Sequence_Conditional begins. Its value is 1499 discarded when SUIT_Directive_Run_Sequence_Conditional terminates. 1501 8.13.5. SUIT_Directive_Process_Dependency 1503 Execute the commands in the common section of the current dependency, 1504 followed by the commands in the equivalent section of the current 1505 dependency. For example, if the current section is "fetch payload," 1506 this will execute "common" in the current dependency, then "fetch 1507 payload" in the current dependency. Once this is complete, the 1508 command following SUIT_Directive_Process_Dependency will be 1509 processed. 1511 If the current dependency is False, this directive has no effect. If 1512 the current dependency is True, then this directive applies to all 1513 dependencies. If the current section is "common," this directive 1514 MUST have no effect. 1516 When SUIT_Process_Dependency completes, it forwards the last status 1517 code that occurred in the dependency. 1519 The argument to SUIT_Directive_Process_Dependency is defined in the 1520 following CDDL. 1522 SUIT_Directive_Process_Dependency_Argument = nil 1524 8.13.6. SUIT_Directive_Set_Parameters 1526 SUIT_Directive_Set_Parameters allows the manifest to configure 1527 behaviour of future directives by changing parameters that are read 1528 by those directives. When dependencies are used, 1529 SUIT_Directive_Set_Parameters also allows a manifest to modify the 1530 behaviour of its dependencies. 1532 Available parameters are defined in Section 8.6. 1534 If a parameter is already set, SUIT_Directive_Set_Parameters will 1535 skip setting the parameter to its argument. This provides the core 1536 of the override mechanism, allowing dependent manifests to change the 1537 behaviour of a manifest. 1539 The argument to SUIT_Directive_Set_Parameters is defined in the 1540 following CDDL. 1542 SUIT_Directive_Set_Parameters_Argument = {+ SUIT_Parameters} 1544 N.B.: A directive code is reserved for an optimisation: a way to set 1545 a parameter to the contents of another parameter, optionally with 1546 another component ID. 1548 8.13.7. SUIT_Directive_Set_Parameter_State_Append 1550 This command is reserved for future use. It will provide a mechanism 1551 to override the "set if unset" logic of SUIT_Directive_Set_Parameters 1552 on a per-parameter basis. This will allow certain parameters to be 1553 treated as lists, rather than fixed values. This enables a feature 1554 for an advanced device to fail over from URIs defined in one manifest 1555 to those defined in another. 1557 8.13.8. SUIT_Directive_Override_Parameters 1559 SUIT_Directive_Override_Parameters replaces any listed parameters 1560 that are already set with the values that are provided in its 1561 argument. This allows a manifest to prevent replacement of critical 1562 parameters. 1564 Available parameters are defined in Section 8.6. 1566 The argument to SUIT_Directive_Override_Parameters is defined in the 1567 following CDDL. 1569 SUIT_Directive_Override_Parameters_Argument = {+ SUIT_Parameters} 1571 8.13.9. SUIT_Directive_Fetch 1573 SUIT_Directive_Fetch instructs the manifest processor to obtain one 1574 or more manifests or payloads, as specified by the manifest index and 1575 component index, respectively. 1577 SUIT_Directive_Fetch can target one or more manifests and one or more 1578 payloads. SUIT_Directive_Fetch retrieves each component and each 1579 manifest listed in component-index and manifest-index, respectively. 1580 If component-index or manifest-index is True, instead of an integer, 1581 then all current manifest components/manifests are fetched. The 1582 current manifest's dependent-components are not automatically 1583 fetched. In order to pre-fetch these, they MUST be specified in a 1584 component-index integer. 1586 SUIT_Directive_Fetch typically takes no arguments unless one is 1587 needed to modify fetch behaviour. If an argument is needed, it must 1588 be wrapped in a bstr. 1590 SUIT_Directive_Fetch reads the URI List parameter to find the source 1591 of the fetch it performs. 1593 The behaviour of SUIT_Directive_Fetch can be modified by setting one 1594 or more of SUIT_Parameter_Encryption_Info, 1595 SUIT_Parameter_Compression_Info, SUIT_Parameter_Unpack_Info. These 1596 three parameters each activate and configure a processing step that 1597 can be applied to the data that is transferred during 1598 SUIT_Directive_Fetch. 1600 The argument to SUIT_Directive_Fetch is defined in the following 1601 CDDL. 1603 SUIT_Directive_Fetch_Argument = nil/bstr 1605 8.13.10. SUIT_Directive_Copy 1607 SUIT_Directive_Copy instructs the manifest processor to obtain one or 1608 more payloads, as specified by the component index. 1609 SUIT_Directive_Copy retrieves each component listed in component- 1610 index, respectively. If component-index is True, instead of an 1611 integer, then all current manifest components are copied. The 1612 current manifest's dependent-components are not automatically copied. 1613 In order to copy these, they MUST be specified in a component-index 1614 integer. 1616 The behaviour of SUIT_Directive_Copy can be modified by setting one 1617 or more of SUIT_Parameter_Encryption_Info, 1618 SUIT_Parameter_Compression_Info, SUIT_Parameter_Unpack_Info. These 1619 three parameters each activate and configure a processing step that 1620 can be applied to the data that is transferred during 1621 SUIT_Directive_Copy. 1623 *N.B.* Fetch and Copy are very similar. Merging them into one 1624 command may be appropriate. 1626 SUIT_Directive_Copy reads its source from 1627 SUIT_Parameter_Source_Component. 1629 The argument to SUIT_Directive_Copy is defined in the following CDDL. 1631 SUIT_Directive_Copy_Argument = nil 1633 8.13.11. SUIT_Directive_Run 1635 SUIT_Directive_Run directs the manifest processor to transfer 1636 execution to the current Component Index. When this is invoked, the 1637 manifest processor MAY be unloaded and execution continues in the 1638 Component Index. Arguments provided to Run are forwarded to the 1639 executable code located in Component Index, in an application- 1640 specific way. For example, this could form the Linux Kernel Command 1641 Line if booting a linux device. 1643 If the executable code at Component Index is constructed in such a 1644 way that it does not unload the manifest processor, then the manifest 1645 processor may resume execution after the executable completes. This 1646 allows the manifest processor to invoke suitable helpers and to 1647 verify them with image conditions. 1649 The argument to SUIT_Directive_Run is defined in the following CDDL. 1651 SUIT_Directive_Run_Argument = nil/bstr 1653 8.13.12. SUIT_Directive_Wait 1655 SUIT_Directive_Wait directs the manifest processor to pause until a 1656 specified event occurs. Some possible events include: 1658 1. Authorisation 1660 2. External Power 1662 3. Network availability 1664 4. Other Device Firmware Version 1666 5. Time 1668 6. Time of Day 1670 7. Day of Week 1672 The following CDDL defines the encoding of these events. 1674 SUIT_Directive_Wait_Argument = { 1675 SUIT_Wait_Events 1676 } 1677 SUIT_Wait_Events //= (1 => SUIT_Wait_Event_Argument_Authorisation) 1678 SUIT_Wait_Events //= (2 => SUIT_Wait_Event_Argument_Power) 1679 SUIT_Wait_Events //= (3 => SUIT_Wait_Event_Argument_Network) 1680 SUIT_Wait_Events //= (4 => SUIT_Wait_Event_Argument_Other_Device_Version) 1681 SUIT_Wait_Events //= (5 => SUIT_Wait_Event_Argument_Time) 1682 SUIT_Wait_Events //= (6 => SUIT_Wait_Event_Argument_Time_Of_Day) 1683 SUIT_Wait_Events //= (7 => SUIT_Wait_Event_Argument_Day_Of_Week) 1685 SUIT_Wait_Event_Argument_Authorisation = int ; priority 1686 SUIT_Wait_Event_Argument_Power = int ; Power Level 1687 SUIT_Wait_Event_Argument_Network = int ; Network State 1688 SUIT_Wait_Event_Argument_Other_Device_Version = [ 1689 other-device: bstr, 1690 other-device-version: [+int] 1691 ] 1692 SUIT_Wait_Event_Argument_Time = uint ; Timestamp 1693 SUIT_Wait_Event_Argument_Time_Of_Day = uint ; Time of Day (seconds since 00:00:00) 1694 SUIT_Wait_Event_Argument_Day_Of_Week = uint ; Days since Sunday 1696 8.13.13. SUIT_Directive CDDL 1698 The following CDDL describes SUIT_Directive: 1700 SUIT_Directive //= SUIT_Directive_Set_Component_Index 1701 SUIT_Directive //= SUIT_Directive_Set_Manifest_Index 1702 SUIT_Directive //= SUIT_Directive_Run_Sequence 1703 SUIT_Directive //= SUIT_Directive_Run_Sequence_Conditional 1704 SUIT_Directive //= SUIT_Directive_Process_Dependency 1705 SUIT_Directive //= SUIT_Directive_Set_Parameters 1706 SUIT_Directive //= SUIT_Directive_Override_Parameters 1707 SUIT_Directive //= SUIT_Directive_Fetch 1708 SUIT_Directive //= SUIT_Directive_Copy 1709 SUIT_Directive //= SUIT_Directive_Run 1710 SUIT_Directive //= SUIT_Directive_Wait 1712 SUIT_Directive_Set_Component_Index = (11 => uint/bool) 1713 SUIT_Directive_Set_Manifest_Index = (12 => uint/bool) 1714 SUIT_Directive_Run_Sequence = (13 => bstr .cbor SUIT_Command_Sequence) 1715 SUIT_Directive_Run_Sequence_Conditional = (14 => bstr .cbor SUIT_Command_Sequence) 1716 SUIT_Directive_Process_Dependency = (15 => nil) 1717 SUIT_Directive_Set_Parameters = (16 => {+ SUIT_Parameters}) 1718 SUIT_Directive_Override_Parameters = (19 => {+ SUIT_Parameters}) 1719 SUIT_Directive_Fetch = (20 => nil/bstr) 1720 SUIT_Directive_Copy = (21 => nil/bstr) 1721 SUIT_Directive_Run = (22 => nil/bstr) 1722 SUIT_Directive_Wait = (23 => { + SUIT_Wait_Events }) 1724 SUIT_Wait_Events //= (1 => SUIT_Wait_Event_Argument_Authorisation) 1725 SUIT_Wait_Events //= (2 => SUIT_Wait_Event_Argument_Power) 1726 SUIT_Wait_Events //= (3 => SUIT_Wait_Event_Argument_Network) 1727 SUIT_Wait_Events //= (4 => SUIT_Wait_Event_Argument_Other_Device_Version) 1728 SUIT_Wait_Events //= (5 => SUIT_Wait_Event_Argument_Time) 1729 SUIT_Wait_Events //= (6 => SUIT_Wait_Event_Argument_Time_Of_Day) 1730 SUIT_Wait_Events //= (7 => SUIT_Wait_Event_Argument_Day_Of_Week) 1732 SUIT_Wait_Event_Argument_Authorisation = int ; priority 1733 SUIT_Wait_Event_Argument_Power = int ; Power Level 1734 SUIT_Wait_Event_Argument_Network = int ; Network State 1735 SUIT_Wait_Event_Argument_Other_Device_Version = [ 1736 other-device: bstr, 1737 other-device-version: [+int] 1738 ] 1739 SUIT_Wait_Event_Argument_Time = uint ; Timestamp 1740 SUIT_Wait_Event_Argument_Time_Of_Day = uint ; Time of Day (seconds since 00:00:00) 1741 SUIT_Wait_Event_Argument_Day_Of_Week = uint ; Days since Sunday 1742 9. Dependency processing 1744 Dependencies need careful handling on constrained systems. A 1745 dependency tree that is too deep can cause recursive handling to 1746 overflow stack space. Systems that parse all dependencies into an 1747 object tree can easily fill up available memory. Too many 1748 dependencies can overrun available storage space. 1750 The dependency handling system in this document is designed to 1751 address as many of these problems as possible. 1753 Dependencies MAY be addressed in one of three ways: 1755 1. Iterate by component 1757 2. Iterate by manifest 1759 3. Out-of-order 1761 Because each manifest has a list of components and a list of 1762 components defined by its dependencies, it is possible for the 1763 manifest processor to handle one component at a time, traversing the 1764 manifest tree once for each listed component. This, however consumes 1765 significant processing power. 1767 Alternatively, it is possible for a device with sufficient memory to 1768 accumulate all parameters for all listed component IDs. This will 1769 naturally consume more memory, but it allows the device to process 1770 the manifests in a single pass. 1772 It is expected that the simplest and most power sensitive devices 1773 will use option 2, with a fixed maximum number of components. 1775 Advanced devices may make use of the Strict Order parameter and 1776 enable parallel processing of some segments, or it may reorder some 1777 segments. To perform parallel processing, once the Strict Order 1778 parameter is set to False, the device may fork a process for each 1779 command until the Strict Order parameter is returned to True or the 1780 command sequence ends. Then, it joins all forked processes before 1781 continuing processing of commands. To perform out-of-order 1782 processing, a similar approach is used, except the device consumes 1783 all commands after the Strict Order parameter is set to False, then 1784 it sorts these commands into its prefered order, invokes them all, 1785 then continues processing. 1787 10. Access Control Lists 1789 To manage permissions in the manifest, there are three models that 1790 can be used. 1792 First, the simplest model requires that all manifests are 1793 authenticated by a single trusted key. This mode has the advantage 1794 that only a root manifest needs to be authenticated, since all of its 1795 dependencies have digests included in the root manifest. 1797 This simplest model can be extended by adding key delegation without 1798 much increase in complexity. 1800 A second model requires an ACL to be presented to the device, 1801 authenticated by a trusted party or stored on the device. This ACL 1802 grants access rights for specific component IDs or component ID 1803 prefixes to the listed identities or identity groups. Any identity 1804 may verify an image digest, but fetching into or fetching from a 1805 component ID requires approval from the ACL. 1807 A third model allows a device to provide even more fine-grained 1808 controls: The ACL lists the component ID or component ID prefix that 1809 an identity may use, and also lists the commands that the identity 1810 may use in combination with that component ID. 1812 11. Creating conditional sequences 1814 For some use cases, it is important to provide a sequence that can 1815 fail without terminating an update. For example, a dual-image XIP 1816 MCU may require an update that can be placed at one of two offsets. 1817 This has two implications, first, the digest of each offset will be 1818 different. Second, the image fetched for each offset will have a 1819 different URI. Conditional sequences allow this to be resolved in a 1820 simple way. 1822 The following JSON representation of a manifest demonstrates how this 1823 would be represented. It assumes that the bootloader and manifest 1824 processor take care of A/B switching and that the manifest is not 1825 aware of this distinction. 1827 { 1828 "structure-version" : 1, 1829 "sequence-number" : 7, 1830 "components" : [ 1831 { 1832 "component-identifier" : [0], 1833 "component-size" : [32567], 1834 }, 1835 ], 1836 "common" : [ 1837 "set-component-index" : 0, 1838 "do-sequence" : [ 1839 "condition-component-offset" : "", 1840 "set-parameters": { 1841 "component-digest" : "" 1842 } 1843 ], 1844 "do-sequence" : [ 1845 "condition-component-offset" : "", 1846 "set-parameters": { 1847 "component-digest" : "" 1848 } 1849 ] 1850 ], 1851 "fetch" : [ 1852 "set-component-index" : 0, 1853 "do-sequence" : [ 1854 "condition-component-offset" : "", 1855 "set-parameters": { 1856 "uri-list" : [[0, ""]] 1857 } 1858 ], 1859 "do-sequence" : [ 1860 "condition-component-offset" : "", 1861 "set-parameters": { 1862 "uri-list" : [[0, ""]] 1863 } 1864 ], 1865 "fetch" : null 1866 ] 1867 } 1869 12. Full CDDL 1871 In order to create a valid SUIT Manifest document the structure of 1872 the corresponding CBOR message MUST adhere to the following CDDL data 1873 definition. 1875 SUIT_Outer_Wrapper = { 1876 suit-authentication-wrapper => bstr .cbor SUIT_Authentication_Wrapper / nil, 1877 suit-manifest => bstr .cbor SUIT_Manifest, 1878 suit-dependency-resolution => bstr .cbor SUIT_Command_Sequence, 1879 suit-payload-fetch => bstr .cbor SUIT_Command_Sequence, 1880 suit-install => bstr .cbor SUIT_Command_Sequence, 1881 suit-text => bstr .cbor SUIT_Text_Map, 1882 suit-coswid => bstr .cbor concise-software-identity 1883 } 1884 suit-authentication-wrapper = 1 1885 suit-manifest = 2 1886 suit-dependency-resolution = 7 1887 suit-payload-fetch = 8 1888 suit-install = 9 1889 suit-text = 13 1890 suit-coswid = 14 1892 SUIT_Authentication_Wrapper = [ * ( 1893 COSE_Mac_Tagged / 1894 COSE_Sign_Tagged / 1895 COSE_Mac0_Tagged / 1896 COSE_Sign1_Tagged)] 1898 COSE_Mac_Tagged = any 1899 COSE_Sign_Tagged = any 1900 COSE_Mac0_Tagged = any 1901 COSE_Sign1_Tagged = any 1902 COSE_Encrypt_Tagged = any 1903 COSE_Encrypt0_Tagged = any 1905 SUIT_Digest = [ 1906 suit-digest-algorithm-id : $suit-digest-algorithm-ids, 1907 suit-digest-bytes : bytes, 1908 ? suit-digest-parameters : any 1909 ] 1911 ; Named Information Hash Algorithm Identifiers 1912 suit-digest-algorithm-ids /= algorithm-id-sha256 1913 suit-digest-algorithm-ids /= algorithm-id-sha256-128 1914 suit-digest-algorithm-ids /= algorithm-id-sha256-120 1915 suit-digest-algorithm-ids /= algorithm-id-sha256-96 1916 suit-digest-algorithm-ids /= algorithm-id-sha256-64 1917 suit-digest-algorithm-ids /= algorithm-id-sha256-32 1918 suit-digest-algorithm-ids /= algorithm-id-sha384 1919 suit-digest-algorithm-ids /= algorithm-id-sha512 1920 suit-digest-algorithm-ids /= algorithm-id-sha3-224 1921 suit-digest-algorithm-ids /= algorithm-id-sha3-256 1922 suit-digest-algorithm-ids /= algorithm-id-sha3-384 1923 suit-digest-algorithm-ids /= algorithm-id-sha3-512 1925 SUIT_Manifest = { 1926 suit-manifest-version => 1, 1927 suit-manifest-sequence-number => uint, 1928 ? suit-dependencies => [ + SUIT_Dependency ], 1929 ? suit-components => [ + SUIT_Component ], 1930 ? suit-dependency-components => [ + SUIT_Component_Reference ], 1931 ? suit-common => bstr .cbor SUIT_Command_Sequence, 1932 ? suit-dependency-resolution => SUIT_Digest / bstr .cbor SUIT_Command_Sequence, 1933 ? suit-payload-fetch => SUIT_Digest / bstr .cbor SUIT_Command_Sequence, 1934 ? suit-install => SUIT_Digest / bstr .cbor SUIT_Command_Sequence 1935 ? suit-validate => bstr .cbor SUIT_Command_Sequence 1936 ? suit-load => bstr .cbor SUIT_Command_Sequence 1937 ? suit-run => bstr .cbor SUIT_Command_Sequence 1938 ? suit-text-info => SUIT_Digest / bstr .cbor SUIT_Text_Map 1939 ? suit-coswid => SUIT_Digest / bstr .cbor concise-software-identity 1940 } 1942 suit-manifest-version = 1 1943 suit-manifest-sequence-number = 2 1944 suit-dependencies = 3 1945 suit-components = 4 1946 suit-dependency-components = 5 1947 suit-common = 6 1948 suit-dependency-resolution = 7 1949 suit-payload-fetch = 8 1950 suit-install = 9 1951 suit-validate = 10 1952 suit-load = 11 1953 suit-run = 12 1954 suit-text-info = 13 1955 suit-coswid = 14 1957 concise-software-identity = any 1959 SUIT_Dependency = { 1960 suit-dependency-digest => SUIT_Digest, 1961 suit-dependency-prefix => SUIT_Component_Identifier, 1962 } 1964 suit-dependency-digest = 1 1965 suit-dependency-prefix = 2 1967 SUIT_Component_Identifier = [* bstr] 1969 SUIT_Component = { 1970 suit-component-identifier => SUIT_Component_Identifier, 1971 ? suit-component-size => uint, 1972 ? suit-component-digest => SUIT_Digest, 1973 } 1975 suit-component-identifier = 1 1976 suit-component-size = 2 1977 suit-component-digest = 3 1979 SUIT_Component_Reference = { 1980 suit-component-identifier => SUIT_Component_Identifier, 1981 suit-component-dependency-index => uint 1982 } 1984 suit-component-dependency-index = 2 1986 SUIT_Command_Sequence = [ + { SUIT_Condition // SUIT_Directive // SUIT_Command_Custom} ] 1988 SUIT_Command_Custom = (nint => bstr) 1990 SUIT_Condition //= (1 => RFC4122_UUID) ; SUIT_Condition_Vendor_Identifier 1991 SUIT_Condition //= (2 => RFC4122_UUID) ; SUIT_Condition_Class_Identifier 1992 SUIT_Condition //= (3 => RFC4122_UUID) ; SUIT_Condition_Device_Identifier 1993 SUIT_Condition //= (4 => SUIT_Digest) ; SUIT_Condition_Image_Match 1994 SUIT_Condition //= (5 => SUIT_Digest) ; SUIT_Condition_Image_Not_Match 1995 SUIT_Condition //= (6 => uint) ; SUIT_Condition_Use_Before 1996 SUIT_Condition //= (7 => uint) ; SUIT_Condition_Minimum_Battery 1997 SUIT_Condition //= (8 => int) ; SUIT_Condition_Update_Authorised 1998 SUIT_Condition //= (9 => SUIT_Condition_Version_Argument) ; SUIT_Condition_Version 1999 SUIT_Condition //= (10 => uint) ; SUIT_Condition_Component_Offset 2000 SUIT_Condition //= (nint => bstr) ; SUIT_Condition_Custom 2002 RFC4122_UUID = bstr .size 16 2004 SUIT_Condition_Version_Argument = [ 2005 suit-condition-version-comparison: SUIT_Condition_Version_Comparison_Types, 2006 suit-condition-version-comparison: SUIT_Condition_Version_Comparison_Value 2007 ] 2008 SUIT_Condition_Version_Comparison_Types /= SUIT_Condition_Version_Comparison_Greater 2009 SUIT_Condition_Version_Comparison_Types /= SUIT_Condition_Version_Comparison_Greater_Equal 2010 SUIT_Condition_Version_Comparison_Types /= SUIT_Condition_Version_Comparison_Equal 2011 SUIT_Condition_Version_Comparison_Types /= SUIT_Condition_Version_Comparison_Lesser_Equal 2012 SUIT_Condition_Version_Comparison_Types /= SUIT_Condition_Version_Comparison_Lesser 2014 SUIT_Condition_Version_Comparison_Greater = 1 2015 SUIT_Condition_Version_Comparison_Greater_Equal = 2 2016 SUIT_Condition_Version_Comparison_Equal = 3 2017 SUIT_Condition_Version_Comparison_Lesser_Equal = 4 2018 SUIT_Condition_Version_Comparison_Lesser = 5 2020 SUIT_Condition_Version_Comparison_Value = [+int] 2022 SUIT_Directive //= (11 => uint/bool) ; SUIT_Directive_Set_Component_Index 2023 SUIT_Directive //= (12 => uint/bool) ; SUIT_Directive_Set_Manifest_Index 2024 SUIT_Directive //= (13 => bstr .cbor SUIT_Command_Sequence) ; SUIT_Directive_Run_Sequence 2025 SUIT_Directive //= (14 => bstr .cbor SUIT_Command_Sequence) ; SUIT_Directive_Run_Sequence_Conditional 2026 SUIT_Directive //= (15 => nil) ; SUIT_Directive_Process_Dependency 2027 SUIT_Directive //= (16 => {+ SUIT_Parameters}) ; SUIT_Directive_Set_Parameters 2028 SUIT_Directive //= (19 => {+ SUIT_Parameters}) ; SUIT_Directive_Override_Parameters 2029 SUIT_Directive //= (20 => nil/bstr) ; SUIT_Directive_Fetch 2030 SUIT_Directive //= (21 => nil/bstr) ; SUIT_Directive_Copy 2031 SUIT_Directive //= (22 => nil/bstr) ; SUIT_Directive_Run 2032 SUIT_Directive //= (23 => { + SUIT_Wait_Events }) ; SUIT_Directive_Wait 2034 SUIT_Wait_Events //= (1 => SUIT_Wait_Event_Argument_Authorisation) 2035 SUIT_Wait_Events //= (2 => SUIT_Wait_Event_Argument_Power) 2036 SUIT_Wait_Events //= (3 => SUIT_Wait_Event_Argument_Network) 2037 SUIT_Wait_Events //= (4 => SUIT_Wait_Event_Argument_Other_Device_Version) 2038 SUIT_Wait_Events //= (5 => SUIT_Wait_Event_Argument_Time) 2039 SUIT_Wait_Events //= (6 => SUIT_Wait_Event_Argument_Time_Of_Day) 2040 SUIT_Wait_Events //= (7 => SUIT_Wait_Event_Argument_Day_Of_Week) 2042 SUIT_Wait_Event_Argument_Authorisation = int ; priority 2043 SUIT_Wait_Event_Argument_Power = int ; Power Level 2044 SUIT_Wait_Event_Argument_Network = int ; Network State 2045 SUIT_Wait_Event_Argument_Other_Device_Version = [ 2046 other-device: bstr, 2047 other-device-version: [+int] 2048 ] 2049 SUIT_Wait_Event_Argument_Time = uint ; Timestamp 2050 SUIT_Wait_Event_Argument_Time_Of_Day = uint ; Time of Day (seconds since 00:00:00) 2051 SUIT_Wait_Event_Argument_Day_Of_Week = uint ; Days since Sunday 2053 SUIT_Parameters //= (1 => bool) ; SUIT_Parameter_Strict_Order 2054 SUIT_Parameters //= (2 => bool) ; SUIT_Parameter_Coerce_Condition_Failure 2055 SUIT_Parameters //= (3 => bstr) ; SUIT_Parameter_Vendor_ID 2056 SUIT_Parameters //= (4 => bstr) ; SUIT_Parameter_Class_ID 2057 SUIT_Parameters //= (5 => bstr) ; SUIT_Parameter_Device_ID 2058 SUIT_Parameters //= (6 => bstr .cbor SUIT_URI_List) ; SUIT_Parameter_URI_List 2059 SUIT_Parameters //= (7 => bstr .cbor SUIT_Encryption_Info) ; SUIT_Parameter_Encryption_Info 2060 SUIT_Parameters //= (8 => bstr .cbor SUIT_Compression_Info) ; SUIT_Parameter_Compression_Info 2061 SUIT_Parameters //= (9 => bstr .cbor SUIT_Unpack_Info) ; SUIT_Parameter_Unpack_Info 2062 SUIT_Parameters //= (10 => bstr .cbor SUIT_Component_Identifier) ; SUIT_Parameter_Source_Component 2063 SUIT_Parameters //= (11 => bstr .cbor SUIT_Digest) ; SUIT_Parameter_Image_Digest 2064 SUIT_Parameters //= (12 => uint) ; SUIT_Parameter_Image_Size 2065 SUIT_Parameters //= (nint => int/bool/bstr) ; SUIT_Parameter_Custom 2067 SUIT_URI_List = [ + [priority: int, uri: tstr] ] 2069 SUIT_Encryption_Info = COSE_Encrypt_Tagged/COSE_Encrypt0_Tagged 2070 SUIT_Compression_Info = { 2071 suit-compression-algorithm => SUIT_Compression_Algorithms 2072 ? suit-compression-parameters => bstr 2073 } 2074 suit-compression-algorithm = 1 2075 suit-compression-parameters = 2 2077 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_gzip 2078 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_bzip2 2079 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_lz4 2080 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_lzma 2082 SUIT_Compression_Algorithm_gzip = 1 2083 SUIT_Compression_Algorithm_bzip2 = 2 2084 SUIT_Compression_Algorithm_deflate = 3 2085 SUIT_Compression_Algorithm_lz4 = 4 2086 SUIT_Compression_Algorithm_lzma = 7 2088 SUIT_Unpack_Info = { 2089 suit-unpack-algorithm => SUIT_Unpack_Algorithms 2090 ? suit-unpack-parameters => bstr 2091 } 2092 suit-unpack-algorithm = 1 2093 suit-unpack-parameters = 2 2095 SUIT_Unpack_Algorithms /= SUIT_Unpack_Algorithm_Delta 2096 SUIT_Unpack_Algorithms /= SUIT_Unpack_Algorithm_Hex 2097 SUIT_Unpack_Algorithms /= SUIT_Unpack_Algorithm_Elf 2099 SUIT_Unpack_Algorithm_Delta = 1 2100 SUIT_Unpack_Algorithm_Hex = 2 2101 SUIT_Unpack_Algorithm_Elf = 3 2103 SUIT_Text_Map = {int => tstr} 2105 13. Examples 2107 The following examples demonstrate a small subset of the 2108 functionality of the manifest. However, despite this, even a simple 2109 manifest processor can execute most of these manifests. 2111 None of these examples include authentication. This is provided via 2112 RFC 8152 [RFC8152], and is omitted for clarity. 2114 13.1. Example 0: 2116 Secure boot only. 2118 The following JSON shows the intended behaviour of the manifest. 2120 { 2121 "structure-version": 1, 2122 "sequence-number": 1, 2123 "components": [ 2124 { 2125 "id": ["Flash",78848], 2126 "digest": "00112233445566778899aabbccddeeff" 2127 "0123456789abcdeffedcba9876543210", 2128 "size": 34768 2129 } 2130 ], 2131 "run-image": [ 2132 {"directive-set-component": 0}, 2133 {"condition-image": null}, 2134 {"directive-run": null} 2135 ] 2136 } 2138 Converted into the SUIT manifest, this produces: 2140 { 2141 / auth object / 1 : None 2142 / manifest / 2 : h'a4010102010481a3018245466c61736843003401021987' 2143 h'd0038201582000112233445566778899aabbccddeeff0123456789abcdef' 2144 h'fedcba98765432100c4a83a10b00a104f6a116f6' \ 2145 { 2146 / structure-version / 1 : 1 2147 / sequence-number / 2 : 1 2148 / components / 4 : [ 2149 { 2150 / component-identifier / 1 : [h'466c617368', h'003401'], 2151 / component-size / 3 : 34768 2152 / component-digest / 2 : [ 2153 / sha-256 / 1, 2154 h'00112233445566778899aabbccddeeff0123456789abcdef' 2155 h'fedcba9876543210'], 2156 } 2157 ], 2158 / run-image / 12 : [ 2159 {/ set-component-index / 11 : 0} 2160 {/ condition-image / 4 : None} 2161 {/ run / 22 : None} 2162 ], 2163 } 2164 } 2166 Total size of outer wrapper without COSE authentication object: 79 2168 Outer: 2170 a201f6025849a4010102010481a3018245466c61736843003401021987d00382015820 2171 00112233445566778899aabbccddeeff0123456789abcdeffedcba98765432100c4a83 2172 a10b00a104f6a116f6 2174 13.2. Example 1: 2176 Simultaneous download and installation of payload. 2178 The following JSON shows the intended behaviour of the manifest. 2180 { 2181 "structure-version": 1, 2182 "sequence-number": 2, 2183 "components": [ 2184 { 2185 "id": ["Flash",78848], 2186 "digest": "00112233445566778899aabbccddeeff" 2187 "0123456789abcdeffedcba9876543210", 2188 "size": 34768 2189 } 2190 ], 2191 "apply-image": [ 2192 {"directive-set-component": 0}, 2193 {"directive-set-var": { 2194 "uris": [[ 0, "http://example.com/file.bin"]] 2195 }}, 2196 {"directive-fetch": null} 2197 ] 2198 } 2200 Converted into the SUIT manifest, this produces: 2202 { 2203 / auth object / 1 : None 2204 / manifest / 2 : h'a4010102020481a3018245466c61736843003401021987' 2205 h'd0038201582000112233445566778899aabbccddeeff0123456789abcdef' 2206 h'fedcba987654321009582d83a10b00a110a1065820818200781b68747470' 2207 h'3a2f2f6578616d706c652e636f6d2f66696c652e62696ea114f6' \ 2208 { 2209 / structure-version / 1 : 1 2210 / sequence-number / 2 : 2 2211 / components / 4 : [ 2212 { 2213 / component-identifier / 1 : [h'466c617368', h'003401'], 2214 / component-size / 3 : 34768 2215 / component-digest / 2 : [ 2216 / sha-256 / 1, 2217 h'00112233445566778899aabbccddeeff' 2218 h'0123456789abcdeffedcba9876543210' 2219 ], 2220 } 2221 ], 2222 / apply-image / 9 : [ 2223 {/ set-component-index / 11 : 0} 2224 {/ set-vars / 16 : { 2225 / uris / 6 : h'818200781b687474703a2f2f6578616d706c' 2226 h'652e636f6d2f66696c652e62696e' / 2227 [[0, 'http://example.com/file.bin']] / 2228 }}, 2229 {/ fetch / 20 : None} 2230 ], 2231 } 2232 } 2234 Total size of outer wrapper without COSE authentication object: 115 2236 Outer: 2238 a201f602586da4010102020481a3018245466c61736843003401021987d00382015820 2239 00112233445566778899aabbccddeeff0123456789abcdeffedcba987654321009582d 2240 83a10b00a110a1065820818200781b687474703a2f2f6578616d706c652e636f6d2f66 2241 696c652e62696ea114f6 2243 13.3. Example 2: 2245 Compatibility test, simultaneous download and installation, and 2246 secure boot. 2248 The following JSON shows the intended behaviour of the manifest. 2250 { 2251 "structure-version": 1, 2252 "sequence-number": 3, 2253 "components": [ 2254 { 2255 "id": [ 2256 "Flash", 2257 78848 2258 ], 2259 "digest": "00112233445566778899aabbccddeeff" 2260 "0123456789abcdeffedcba9876543210", 2261 "size": 34768 2262 } 2263 ], 2264 "common": [ 2265 {"condition-vendor-id": "fa6b4a53-d5ad-5fdf-be9d-e663e4d41ffe"}, 2266 {"condition-class-id": "1492af14-2569-5e48-bf42-9b2d51f2ab45"} 2267 ], 2268 "apply-image": [ 2269 {"directive-set-component": 0}, 2270 {"directive-set-var": { 2271 "uris": [[ 0, "http://example.com/file.bin" ]] 2272 }}, 2273 {"directive-fetch": null} 2274 ], 2275 "run-image": [ 2276 {"directive-set-component": 0}, 2277 {"condition-image": null}, 2278 {"directive-run": null} 2279 ] 2280 } 2282 Converted into the SUIT manifest, this produces: 2284 { 2285 / auth object / 1 : None 2286 / manifest / 2 : h'a6010102030481a3018245466c61736843003401021987' 2287 h'd0038201582000112233445566778899aabbccddeeff0123456789abcdef' 2288 h'fedcba987654321006582782a10150fa6b4a53d5ad5fdfbe9de663e4d41f' 2289 h'fea102501492af1425695e48bf429b2d51f2ab4509582d83a10b00a110a1' 2290 h'065820818200781b687474703a2f2f6578616d706c652e636f6d2f66696c' 2291 h'652e62696ea114f60c4a83a10b00a104f6a116f6' \ 2292 { 2293 / structure-version / 1 : 1 2294 / sequence-number / 2 : 3 2295 / components / 4 : [ 2296 { 2297 / component-identifier / 1 : [h'466c617368', h'003401'], 2298 / component-size / 3 : 34768 2299 / component-digest / 2 : [ 2300 / sha-256 / 1, 2301 h'00112233445566778899aabbccddeeff' 2302 h'0123456789abcdeffedcba9876543210' 2303 ], 2304 } 2305 ], 2306 / common / 6 : [ 2307 {/ vendor-id / 1 : h'fa6b4a53d5ad5fdfbe9de663e4d41ffe' \ 2308 fa6b4a53-d5ad-5fdf-be9d-e663e4d41ffe}, 2309 {/ class-id / 2 : h'1492af1425695e48bf429b2d51f2ab45' \ 2310 1492af14-2569-5e48-bf42-9b2d51f2ab45} 2311 ], 2312 / apply-image / 9 : [ 2313 {/ set-component-index / 11 : 0} 2314 {/ set-vars / 16 : { 2315 / uris / 6 : h'818200781b687474703a2f2f6578616d706c65' 2316 h'2e636f6d2f66696c652e62696e' / 2317 [[0, 'http://example.com/file.bin']] / 2318 }}, 2319 {/ fetch / 20 : None} 2320 ], 2321 / run-image / 12 : [ 2322 {/ set-component-index / 11 : 0} 2323 {/ condition-image / 4 : None} 2324 {/ run / 22 : None} 2325 ], 2326 } 2327 } 2329 Total size of outer wrapper without COSE authentication object: 169 2331 Outer: 2333 a201f60258a3a6010102030481a3018245466c61736843003401021987d00382015820 2334 00112233445566778899aabbccddeeff0123456789abcdeffedcba9876543210065827 2335 82a10150fa6b4a53d5ad5fdfbe9de663e4d41ffea102501492af1425695e48bf429b2d 2336 51f2ab4509582d83a10b00a110a1065820818200781b687474703a2f2f6578616d706c 2337 652e636f6d2f66696c652e62696ea114f60c4a83a10b00a104f6a116f6 2339 13.4. Example 3: 2341 Compatibility test, simultaneous download and installation, load from 2342 external storage, and secure boot. 2344 The following JSON shows the intended behaviour of the manifest. 2346 { 2347 "structure-version": 1, 2348 "sequence-number": 4, 2349 "components": [ 2350 { 2351 "id": ["Flash",78848], 2352 "digest": "00112233445566778899aabbccddeeff" 2353 "0123456789abcdeffedcba9876543210", 2354 "size": 34768 2355 }, 2356 { 2357 "id": ["RAM",1024], 2358 "digest": "00112233445566778899aabbccddeeff" 2359 "0123456789abcdeffedcba9876543210", 2360 "size": 34768 2361 } 2362 ], 2363 "common": [ 2364 {"condition-vendor-id": "fa6b4a53-d5ad-5fdf-be9d-e663e4d41ffe"}, 2365 {"condition-class-id": "1492af14-2569-5e48-bf42-9b2d51f2ab45"} 2366 ], 2367 "apply-image": [ 2368 {"directive-set-component": 0}, 2369 {"directive-set-var": { 2370 "uris": [[0, "http://example.com/file.bin"]] 2371 }}, 2372 {"directive-fetch": null} 2373 ], 2374 "run-image": [ 2375 {"directive-set-component": 0}, 2376 {"condition-image": null}, 2377 {"directive-set-component": 1}, 2378 {"directive-set-var": { 2379 "source-index": 0 2380 }}, 2381 {"directive-fetch": null}, 2382 {"condition-image": null}, 2383 {"directive-run": null} 2384 ] 2385 } 2387 Converted into the SUIT manifest, this produces: 2389 { 2390 / auth object / 1 : None 2391 / manifest / 2 : h'a6010102040482a3018245466c61736843003401021987' 2392 h'd0038201582000112233445566778899aabbccddeeff0123456789abcdef' 2393 h'fedcba9876543210a301824352414d420004021987d00382015820001122' 2394 h'33445566778899aabbccddeeff0123456789abcdeffedcba987654321006' 2395 h'582782a10150fa6b4a53d5ad5fdfbe9de663e4d41ffea102501492af1425' 2396 h'695e48bf429b2d51f2ab4509582d83a10b00a110a1065820818200781b68' 2397 h'7474703a2f2f6578616d706c652e636f6d2f66696c652e62696ea114f60c' 2398 h'581887a10b00a104f6a10b01a110a10a00a114f6a104f6a116f6' \ 2399 { 2400 / structure-version / 1 : 1 2401 / sequence-number / 2 : 4 2402 / components / 4 : [ 2403 { 2404 / component-identifier / 1 : [h'466c617368', h'003401'], 2405 / component-size / 3 : 34768 2406 / component-digest / 2 : [ 2407 / sha-256 / 1, 2408 h'00112233445566778899aabbccddeeff' 2409 h'0123456789abcdeffedcba9876543210' 2410 ], 2411 }, 2412 { 2413 / component-identifier / 1 : [h'52414d', h'0004'], 2414 / component-size / 3 : 34768 2415 / component-digest / 2 : [ 2416 / sha-256 / 1, 2417 h'00112233445566778899aabbccddeeff' 2418 h'0123456789abcdeffedcba9876543210' 2419 ], 2420 } 2421 ], 2422 / common / 6 : [ 2423 {/ vendor-id / 1 : h'fa6b4a53d5ad5fdfbe9de663e4d41ffe' \ 2424 fa6b4a53-d5ad-5fdf-be9d-e663e4d41ffe} 2425 {/ class-id / 2 : h'1492af1425695e48bf429b2d51f2ab45' \ 2426 1492af14-2569-5e48-bf42-9b2d51f2ab45} 2427 ], 2428 / apply-image / 9 : [ 2429 {/ set-component-index / 11 : 0} 2430 {/ set-vars / 16 : { 2431 / uris / 6 : h'818200781b687474703a2f2f6578616d706c65' 2432 h'2e636f6d2f66696c652e62696e' / 2433 [[0, 'http://example.com/file.bin']] / 2434 }}, 2435 {/ fetch / 20 : None} 2436 ], 2437 / run-image / 12 : [ 2438 {/ set-component-index / 11 : 0} 2439 {/ condition-image / 4 : None} 2440 {/ set-component-index / 11 : 1} 2441 {/ set-vars / 16 : { 2442 / source-component / 10 : 0 2443 }}, 2444 {/ fetch / 20 : None} 2445 {/ condition-image / 4 : None} 2446 {/ run / 22 : None} 2447 ], 2448 } 2449 } 2451 Total size of outer wrapper without COSE authentication object: 235 2453 Outer: 2455 a201f60258e5a6010102040482a3018245466c61736843003401021987d00382015820 2456 00112233445566778899aabbccddeeff0123456789abcdeffedcba9876543210a30182 2457 4352414d420004021987d0038201582000112233445566778899aabbccddeeff012345 2458 6789abcdeffedcba987654321006582782a10150fa6b4a53d5ad5fdfbe9de663e4d41f 2459 fea102501492af1425695e48bf429b2d51f2ab4509582d83a10b00a110a10658208182 2460 00781b687474703a2f2f6578616d706c652e636f6d2f66696c652e62696ea114f60c58 2461 1887a10b00a104f6a10b01a110a10a00a114f6a104f6a116f6 2463 13.5. Example 4: 2465 Compatibility test, simultaneous download and installation, load and 2466 decompress from external storage, and secure boot. 2468 The following JSON shows the intended behaviour of the manifest. 2470 { 2471 "structure-version": 1, 2472 "sequence-number": 5, 2473 "components": [ 2474 { 2475 "id": ["Flash",78848], 2476 "digest": "00112233445566778899aabbccddeeff" 2477 "0123456789abcdeffedcba9876543210", 2478 "size": 34768 2479 }, 2480 { 2481 "id": ["RAM",1024], 2482 "digest": "0123456789abcdeffedcba9876543210" 2483 "00112233445566778899aabbccddeeff", 2484 "size": 34768 2485 } 2486 ], 2487 "common": [ 2488 {"condition-vendor-id": "fa6b4a53-d5ad-5fdf-be9d-e663e4d41ffe"}, 2489 {"condition-class-id": "1492af14-2569-5e48-bf42-9b2d51f2ab45"} 2490 ], 2491 "apply-image": [ 2492 {"directive-set-component": 0}, 2493 {"directive-set-var": { 2494 "uris": [[ 0, "http://example.com/file.bin" ]] 2495 }}, 2496 {"directive-fetch": null} 2497 ], 2498 "load-image": [ 2499 {"directive-set-component": 0}, 2500 {"condition-image": null}, 2501 {"directive-set-component": 1}, 2502 {"directive-set-var": { 2503 "source-index": 0, 2504 "compression-info": { 2505 "algorithm": "gzip" 2506 } 2507 }}, 2508 {"directive-copy": null} 2509 ], 2510 "run-image": [ 2511 {"condition-image": null}, 2512 {"directive-run": null} 2513 ] 2514 } 2516 Converted into the SUIT manifest, this produces: 2518 { 2519 / auth object / 1 : None 2520 / manifest / 2 : h'a7010102050482a3018245466c61736843003401021987' 2521 h'd0038201582000112233445566778899aabbccddeeff0123456789abcdef' 2522 h'fedcba9876543210a301824352414d420004021987d00382015820012345' 2523 h'6789abcdeffedcba987654321000112233445566778899aabbccddeeff06' 2524 h'582782a10150fa6b4a53d5ad5fdfbe9de663e4d41ffea102501492af1425' 2525 h'695e48bf429b2d51f2ab4509582d83a10b00a110a1065820818200781b68' 2526 h'7474703a2f2f6578616d706c652e636f6d2f66696c652e62696ea114f60b' 2527 h'5585a10b00a104f6a10b01a110a20841f60a00a115f60c4782a104f6a116' 2528 h'f6' \ 2529 { 2530 / structure-version / 1 : 1 2531 / sequence-number / 2 : 5 2532 / components / 4 : [ 2533 { 2534 / component-identifier / 1 : [h'466c617368', h'003401'], 2535 / component-size / 3 : 34768 2536 / component-digest / 2 : [ 2537 / sha-256 / 1, 2538 h'00112233445566778899aabbccddeeff' 2539 h'0123456789abcdeffedcba9876543210' 2540 ], 2541 }, 2542 { 2543 / component-identifier / 1 : [h'52414d', h'0004'], 2544 / component-size / 3 : 34768 2545 / component-digest / 2 : [ 2546 / sha-256 / 1, 2547 h'0123456789abcdeffedcba9876543210' 2548 h'00112233445566778899aabbccddeeff' 2549 ], 2550 } 2551 ], 2552 / common / 6 : [ 2553 {/ vendor-id / 1 : h'fa6b4a53d5ad5fdfbe9de663e4d41ffe' \ 2554 fa6b4a53-d5ad-5fdf-be9d-e663e4d41ffe}, 2555 {/ class-id / 2 : h'1492af1425695e48bf429b2d51f2ab45' \ 2556 1492af14-2569-5e48-bf42-9b2d51f2ab45} 2557 ], 2558 / apply-image / 9 : [ 2559 {/ set-component-index / 11 : 0} 2560 {/ set-vars / 16 : { 2561 / uris / 6 : h'818200781b687474703a2f2f6578616d706c65' 2562 h'2e636f6d2f66696c652e62696e' / 2563 [[0, 'http://example.com/file.bin']] / 2564 }}, 2565 {/ fetch / 20 : None} 2567 ], 2568 / load-image / 11 : [ 2569 {/ set-component-index / 11 : 0} 2570 {/ condition-image / 4 : None} 2571 {/ set-component-index / 11 : 1} 2572 {/ set-vars / 16 : { 2573 / unknown / 8 : b'\xf6' 2574 / source-component / 10 : 0 2575 }}, 2576 {/ copy / 21 : None} 2577 ], 2578 / run-image / 12 : [ 2579 {/ condition-image / 4 : None} 2580 {/ run / 22 : None} 2581 ], 2582 } 2583 } 2585 Total size of outer wrapper without COSE authentication object: 240 2587 Outer: 2589 a201f60258eaa7010102050482a3018245466c61736843003401021987d00382015820 2590 00112233445566778899aabbccddeeff0123456789abcdeffedcba9876543210a30182 2591 4352414d420004021987d003820158200123456789abcdeffedcba9876543210001122 2592 33445566778899aabbccddeeff06582782a10150fa6b4a53d5ad5fdfbe9de663e4d41f 2593 fea102501492af1425695e48bf429b2d51f2ab4509582d83a10b00a110a10658208182 2594 00781b687474703a2f2f6578616d706c652e636f6d2f66696c652e62696ea114f60b55 2595 85a10b00a104f6a10b01a110a20841f60a00a115f60c4782a104f6a116f6 2597 13.6. Example 5: 2599 Compatibility test, download, installation, and secure boot. 2601 The following JSON shows the intended behaviour of the manifest. 2603 { 2604 "structure-version": 1, 2605 "sequence-number": 6, 2606 "components": [ 2607 { 2608 "id": [ "ext-Flash", 78848 ], 2609 "digest": "00112233445566778899aabbccddeeff" 2610 "0123456789abcdeffedcba9876543210", 2611 "size": 34768 2612 }, 2613 { 2614 "id": ["Flash",1024], 2615 "digest": "0123456789abcdeffedcba9876543210" 2616 "00112233445566778899aabbccddeeff", 2617 "size": 34768 2618 } 2619 ], 2620 "common": [ 2621 {"condition-vendor-id": "fa6b4a53-d5ad-5fdf-be9d-e663e4d41ffe"}, 2622 {"condition-class-id": "1492af14-2569-5e48-bf42-9b2d51f2ab45"} 2623 ], 2624 "apply-image": [ 2625 {"directive-set-component": 0}, 2626 {"directive-set-var": { 2627 "uris": [[0, "http://example.com/file.bin"]] 2628 }}, 2629 {"directive-fetch": null} 2630 ], 2631 "load-image": [ 2632 {"directive-run-conditional": [ 2633 {"directive-set-component": 1}, 2634 {"condition-not-image": null}, 2635 {"directive-set-component": 0}, 2636 {"condition-image": null}, 2637 {"directive-set-component": 1}, 2638 {"directive-set-var": { 2639 "source-index": 0 2640 }}, 2641 {"directive-fetch": null} 2642 ]} 2643 ], 2644 "run-image": [ 2645 {"directive-set-component": 1}, 2646 {"condition-image": null}, 2647 {"directive-run": null} 2648 ] 2649 } 2650 Converted into the SUIT manifest, this produces: 2652 { 2653 / auth object / 1 : None 2654 / manifest / 2 : h'a7010102060482a30182496578742d466c617368430034' 2655 h'01021987d0038201582000112233445566778899aabbccddeeff01234567' 2656 h'89abcdeffedcba9876543210a3018245466c617368420004021987d00382' 2657 h'0158200123456789abcdeffedcba987654321000112233445566778899aa' 2658 h'bbccddeeff06582782a10150fa6b4a53d5ad5fdfbe9de663e4d41ffea102' 2659 h'501492af1425695e48bf429b2d51f2ab4509582d83a10b00a110a1065820' 2660 h'818200781b687474703a2f2f6578616d706c652e636f6d2f66696c652e62' 2661 h'696ea114f60b581d81a10e581887a10b01a105f6a10b00a104f6a10b01a1' 2662 h'10a10a00a114f60c4a83a10b01a104f6a116f6' \ 2663 { 2664 / structure-version / 1 : 1 2665 / sequence-number / 2 : 6 2666 / components / 4 : [ 2667 { 2668 / component-identifier / 1 : [ 2669 h'6578742d466c617368', 2670 h'003401' 2671 ], 2672 / component-size / 3 : 34768 2673 / component-digest / 2 : [ 2674 / sha-256 / 1, 2675 h'00112233445566778899aabbccddeeff' 2676 h'0123456789abcdeffedcba9876543210' 2677 ], 2678 } 2679 { 2680 / component-identifier / 1 : [h'466c617368', h'0004'], 2681 / component-size / 3 : 34768 2682 / component-digest / 2 : [ 2683 / sha-256 / 1, 2684 h'0123456789abcdeffedcba9876543210' 2685 h'00112233445566778899aabbccddeeff' 2686 ], 2687 } 2688 ], 2689 / common / 6 : [ 2690 {/ vendor-id / 1 : h'fa6b4a53d5ad5fdfbe9de663e4d41ffe' \ 2691 fa6b4a53-d5ad-5fdf-be9d-e663e4d41ffe} 2692 {/ class-id / 2 : h'1492af1425695e48bf429b2d51f2ab45' \ 2693 1492af14-2569-5e48-bf42-9b2d51f2ab45} 2694 ], 2695 / apply-image / 9 : [ 2696 {/ set-component-index / 11 : 0} 2697 {/ set-vars / 16 : { 2698 / uris / 6 : h'818200781b687474703a2f2f6578616d706c65' 2699 h'2e636f6d2f66696c652e62696e' / 2700 [[0, 'http://example.com/file.bin']] / 2701 }}, 2702 {/ fetch / 20 : None} 2703 ], 2704 / load-image / 11 : [ 2705 / conditional-sequence / 14 : [ 2706 {/ set-component-index / 11 : 1} 2707 {/ condition-not-image / 5 : None} 2708 {/ set-component-index / 11 : 0} 2709 {/ condition-image / 4 : None} 2710 {/ set-component-index / 11 : 1} 2711 {/ set-vars / 16 : { 2712 / source-component / 10 : 0 2713 }}, 2714 {/ fetch / 20 : None} 2715 ], 2716 ], 2717 / run-image / 12 : [ 2718 {/ set-component-index / 11 : 1} 2719 {/ condition-image / 4 : None} 2720 {/ run / 22 : None} 2721 ], 2722 } 2723 } 2725 Total size of outer wrapper without COSE authentication object: 258 2727 Outer: 2729 a201f60258fca7010102060482a30182496578742d466c61736843003401021987d003 2730 8201582000112233445566778899aabbccddeeff0123456789abcdeffedcba98765432 2731 10a3018245466c617368420004021987d003820158200123456789abcdeffedcba9876 2732 54321000112233445566778899aabbccddeeff06582782a10150fa6b4a53d5ad5fdfbe 2733 9de663e4d41ffea102501492af1425695e48bf429b2d51f2ab4509582d83a10b00a110 2734 a1065820818200781b687474703a2f2f6578616d706c652e636f6d2f66696c652e6269 2735 6ea114f60b581d81a10e581887a10b01a105f6a10b00a104f6a10b01a110a10a00a114 2736 f60c4a83a10b01a104f6a116f6 2738 13.7. Example 6: 2740 Compatibility test, 2 images, simultaneous download and installation, 2741 and secure boot. 2743 The following JSON shows the intended behaviour of the manifest. 2745 { 2746 "structure-version": 1, 2747 "sequence-number": 7, 2748 "components": [ 2749 { 2750 "id": ["Flash",78848], 2751 "digest": "00112233445566778899aabbccddeeff" 2752 "0123456789abcdeffedcba9876543210", 2753 "size": 34768 2754 }, 2755 { 2756 "id": ["Flash",132096], 2757 "digest": "0123456789abcdeffedcba9876543210" 2758 "00112233445566778899aabbccddeeff", 2759 "size": 76834 2760 } 2761 ], 2762 "common": [ 2763 {"condition-vendor-id": "fa6b4a53-d5ad-5fdf-be9d-e663e4d41ffe"}, 2764 {"condition-class-id": "1492af14-2569-5e48-bf42-9b2d51f2ab45"} 2765 ], 2766 "apply-image": [ 2767 {"directive-set-component": 0}, 2768 {"directive-set-var": { 2769 "uris": [[ 0, "http://example.com/file1.bin" ]] 2770 }}, 2771 {"directive-set-component": 1}, 2772 {"directive-set-var": { 2773 "uris": [[ 0, "http://example.com/file2.bin" ]] 2774 }}, 2775 {"directive-set-component": true}, 2776 {"directive-fetch": null} 2777 ], 2778 "run-image": [ 2779 {"directive-set-component": true}, 2780 {"condition-image": null}, 2781 {"directive-set-component": 0}, 2782 {"directive-run": null} 2783 ] 2784 } 2786 Converted into the SUIT manifest, this produces: 2788 { 2789 / auth object / 1 : None 2790 / manifest / 2 : h'a6010102070482a3018245466c61736843003401021987' 2791 h'd0038201582000112233445566778899aabbccddeeff0123456789abcdef' 2792 h'fedcba9876543210a3018245466c61736843000402021a00012c22038201' 2793 h'58200123456789abcdeffedcba987654321000112233445566778899aabb' 2794 h'ccddeeff06582782a10150fa6b4a53d5ad5fdfbe9de663e4d41ffea10250' 2795 h'1492af1425695e48bf429b2d51f2ab4509585b86a10b00a110a106582181' 2796 h'8200781c687474703a2f2f6578616d706c652e636f6d2f66696c65312e62' 2797 h'696ea10b01a110a1065821818200781c687474703a2f2f6578616d706c65' 2798 h'2e636f6d2f66696c65322e62696ea10bf5a114f60c4d84a10bf5a104f6a1' 2799 h'0b00a116f6' \ 2800 { 2801 / structure-version / 1 : 1 2802 / sequence-number / 2 : 7 2803 / components / 4 : [ 2804 { 2805 / component-identifier / 1 : [h'466c617368', h'003401'], 2806 / component-size / 3 : 34768 2807 / component-digest / 2 : [ 2808 / sha-256 / 1, 2809 h'00112233445566778899aabbccddeeff' 2810 h'0123456789abcdeffedcba9876543210' 2811 ], 2812 } 2813 { 2814 / component-identifier / 1 : [h'466c617368', h'000402'], 2815 / component-size / 3 : 76834 2816 / component-digest / 2 : [ 2817 / sha-256 / 1, 2818 h'0123456789abcdeffedcba9876543210' 2819 h'00112233445566778899aabbccddeeff' 2820 ], 2821 } 2822 ], 2823 / common / 6 : [ 2824 {/ vendor-id / 1 : h'fa6b4a53d5ad5fdfbe9de663e4d41ffe' \ 2825 fa6b4a53-d5ad-5fdf-be9d-e663e4d41ffe} 2826 {/ class-id / 2 : h'1492af1425695e48bf429b2d51f2ab45' \ 2827 1492af14-2569-5e48-bf42-9b2d51f2ab45} 2828 ], 2829 / apply-image / 9 : [ 2830 {/ set-component-index / 11 : 0} 2831 {/ set-vars / 16 : { 2832 / uris / 6 : h'818200781c687474703a2f2f6578616d706c' 2833 h'652e636f6d2f66696c65312e62696e' / 2834 [[0, 'http://example.com/file1.bin']] / 2835 }}, 2836 {/ set-component-index / 11 : 1} 2837 {/ set-vars / 16 : { 2838 / uris / 6 : h'818200781c687474703a2f2f6578616d706c 2839 h'652e636f6d2f66696c65322e62696e' / 2840 [[0, 'http://example.com/file2.bin']] / 2842 }}, 2843 {/ set-component-index / 11 : True} 2844 {/ fetch / 20 : None} 2845 ], 2846 / run-image / 12 : [ 2847 {/ set-component-index / 11 : True} 2848 {/ condition-image / 4 : None} 2849 {/ set-component-index / 11 : 0} 2850 {/ run / 22 : None} 2851 ], 2852 } 2853 } 2855 Total size of outer wrapper without COSE authentication object: 275 2857 Outer: 2859 a201f60259010ca6010102070482a3018245466c61736843003401021987d003820158 2860 2000112233445566778899aabbccddeeff0123456789abcdeffedcba9876543210a301 2861 8245466c61736843000402021a00012c2203820158200123456789abcdeffedcba9876 2862 54321000112233445566778899aabbccddeeff06582782a10150fa6b4a53d5ad5fdfbe 2863 9de663e4d41ffea102501492af1425695e48bf429b2d51f2ab4509585b86a10b00a110 2864 a1065821818200781c687474703a2f2f6578616d706c652e636f6d2f66696c65312e62 2865 696ea10b01a110a1065821818200781c687474703a2f2f6578616d706c652e636f6d2f 2866 66696c65322e62696ea10bf5a114f60c4d84a10bf5a104f6a10b00a116f6 2868 14. IANA Considerations 2870 Several registries will be required for: 2872 - standard Commands 2874 - standard Parameters 2876 - standard Algorithm identifiers 2878 - standard text values 2880 15. Security Considerations 2882 This document is about a manifest format describing and protecting 2883 firmware images and as such it is part of a larger solution for 2884 offering a standardized way of delivering firmware updates to IoT 2885 devices. A more detailed discussion about security can be found in 2886 the architecture document [Architecture] and in [Information]. 2888 16. Mailing List Information 2890 The discussion list for this document is located at the e-mail 2891 address suit@ietf.org [1]. Information on the group and information 2892 on how to subscribe to the list is at 2893 https://www1.ietf.org/mailman/listinfo/suit [2] 2895 Archives of the list can be found at: https://www.ietf.org/mail- 2896 archive/web/suit/current/index.html [3] 2898 17. Acknowledgements 2900 We would like to thank the following persons for their support in 2901 designing this mechanism: 2903 - Milosch Meriac 2905 - Geraint Luff 2907 - Dan Ros 2909 - John-Paul Stanford 2911 - Hugo Vincent 2913 - Carsten Bormann 2915 - Oeyvind Roenningstad 2917 - Frank Audun Kvamtroe 2919 - Krzysztof Chruściński 2921 - Andrzej Puzdrowski 2923 - Michael Richardson 2925 - David Brown 2927 - Emmanuel Baccelli 2929 18. References 2931 18.1. Normative References 2933 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 2934 Requirement Levels", BCP 14, RFC 2119, 2935 DOI 10.17487/RFC2119, March 1997, 2936 . 2938 [RFC4122] Leach, P., Mealling, M., and R. Salz, "A Universally 2939 Unique IDentifier (UUID) URN Namespace", RFC 4122, 2940 DOI 10.17487/RFC4122, July 2005, 2941 . 2943 [RFC8152] Schaad, J., "CBOR Object Signing and Encryption (COSE)", 2944 RFC 8152, DOI 10.17487/RFC8152, July 2017, 2945 . 2947 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2948 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 2949 May 2017, . 2951 18.2. Informative References 2953 [Architecture] 2954 Moran, B., "A Firmware Update Architecture for Internet of 2955 Things Devices", January 2019, 2956 . 2959 [Behaviour] 2960 Moran, B., "An Information Model for Behavioural 2961 Description of Firmware Update and Related Operations", 2962 March 2019, . 2965 [Information] 2966 Moran, B., "Firmware Updates for Internet of Things 2967 Devices - An Information Model for Manifests", January 2968 2019, . 2971 [RFC6920] Farrell, S., Kutscher, D., Dannewitz, C., Ohlman, B., 2972 Keranen, A., and P. Hallam-Baker, "Naming Things with 2973 Hashes", RFC 6920, DOI 10.17487/RFC6920, April 2013, 2974 . 2976 18.3. URIs 2978 [1] mailto:suit@ietf.org 2980 [2] https://www1.ietf.org/mailman/listinfo/suit 2982 [3] https://www.ietf.org/mail-archive/web/suit/current/index.html 2984 Authors' Addresses 2986 Brendan Moran 2987 Arm Limited 2989 EMail: Brendan.Moran@arm.com 2991 Hannes Tschofenig 2992 Arm Limited 2994 EMail: hannes.tschofenig@arm.com 2996 Henk Birkholz 2997 Fraunhofer SIT 2999 EMail: henk.birkholz@sit.fraunhofer.de