1################################################# 2Symmetric key algorithm based Initial Attestation 3################################################# 4 5:Author: David Hu 6:Organization: Arm Limited 7:Contact: david.hu@arm.com 8 9************ 10Introduction 11************ 12 13This document proposes a design of symmetric key algorithm based Initial 14Attestation in TF-M. 15 16Symmetric key algorithm based Initial Attestation 17(*symmetric Initial Attestation* for short) signs and verifies Initial 18Attestation Token (IAT) with a symmetric cryptography signature scheme, such as 19HMAC. 20It can reduce TF-M binary size and memory footprint on ultra-constrained devices 21without integrating asymmetric ciphers. 22 23This proposal follows PSA Attestation API document [1]_. 24 25.. note :: 26 27 As pointed out by PSA Attestation API [1]_, the use cases of Initial 28 Attestation based on symmetric key algorithms can be limited due to 29 the associated infrastructure costs for key management and operational 30 complexities. It may also restrict the ability to interoperate with 31 scenarios that involve third parties. 32 33*************** 34Design overview 35*************** 36 37The symmetric Initial Attestation follows the existing IAT generation sequence 38for Initial Attestation based on asymmetric key algorithm 39(*asymmetric Initial Attestation* for short). 40 41As Profile Small design [2]_ requests, a configuration flag 42``SYMMETRIC_INITIAL_ATTESTATION`` selects symmetric initial attestation during 43build. 44 45The top-level design is shown in :ref:`overall-diagram-figure` below. 46 47.. _overall-diagram-figure: 48 49.. figure:: /design_docs/media/symmetric_initial_attest/overall_diagram.png 50 :align: center 51 52 Overall design diagram 53 54Symmetric Initial Attestation adds its own implementations of some steps in IAT 55generation in Initial Attestation secure service. More details are covered in 56`IAT generation in Initial Attestation secure service`_. 57 58The interfaces and procedures of Initial Attestation secure service are not 59affected. Refer to Initial Attestation Service Integration Guide [3]_ for 60details of the implementation of Initial Attestation secure service. 61 62Symmetric Initial Attestation invokes ``t_cose`` library to build up 63``COSE_Mac0`` structure. 64``COSE_Mac0`` support is added to ``t_cose`` library in TF-M since official 65``t_cose`` hasn't supported ``COSE_Mac0`` yet. The design of ``COSE_Mac0`` 66support is covered in `COSE_Mac0 support in t_cose`_. 67 68.. note :: 69 70 The ``COSE_Mac0`` implementation in this proposal is a prototype only for 71 Proof of Concept so far. It may be replaced after ``t_cose`` officially 72 supports ``COSE_Mac0`` message. 73 74Several HAL APIs are defined to fetch platform specific assets required by 75Symmetric Initial Attestation. For example, ``tfm_plat_get_symmetric_iak()`` 76fetches symmetric Initial Attestation Key (IAK). Those HAL APIs are summarized 77in `HAL APIs`_. 78 79Decoding and verification of symmetric Initial Attestation is also included in 80this proposal for regression test. 81The test suites and IAT decoding are discussed in `TF-M Test suite`_. 82 83``QCBOR`` library and Crypto service are also invoked. But this proposal doesn't 84require any modification to either ``QCBOR`` or Crypto service. Therefore, 85descriptions of ``QCBOR`` and Crypto service are skipped in this document. 86 87**************************************************** 88IAT generation in Initial Attestation secure service 89**************************************************** 90 91The sequence of IAT generation of symmetric Initial Attestation is shown in 92:ref:`ia-service-figure` below. Note that the ``Register symmetric IAK`` stage 93is no longer required due to changes in the Crypto partition 94(``attest_symmetric_key.c`` is now responsible only for calculating the instance 95ID). 96 97.. _ia-service-figure: 98 99.. figure:: /design_docs/media/symmetric_initial_attest/ia_service_flow.png 100 :align: center 101 102 Symmetric IAT generation flow in Initial Attestation secure service 103 104In Initial Attestation secure service, symmetric Initial Attestation implements 105the following steps in ``attest_create_token()``, which are different from those 106of asymmetric Initial Attestation. 107 108 - ``attest_token_start()`` 109 - Instance ID claims 110 - ``attest_token_finish()`` 111 112If ``SYMMETRIC_INITIAL_ATTESTATION`` is selected, symmetric Initial Attestation 113dedicated implementations of those steps are included in build. 114Otherwise, asymmetric Initial Attestation dedicated implementations are included 115instead. 116 117Symmetric Initial Attestation implementation resides a new file 118``attest_symmetric_key.c`` to handle symmetric Instance ID related operations. 119Symmetric Initial Attestation dedicated ``attest_token_start()`` and 120``attest_token_finish()`` are added in ``attestation_token.c``. 121 122The details are covered in following sections. 123 124Symmetric Instance ID 125===================== 126 127Symmetric Initial Attestation dedicated ``attest_symmetric_key.c`` implements 128the ``attest_get_instance_id()`` function. This function returns the Instance ID 129value, calculating it if it has not already been calculated. Refer to 130`Instance ID claim_` for more details. 131 132.. note :: 133 134 Only symmetric IAK for HMAC algorithm is allowed so far. 135 136Instance ID calculation 137----------------------- 138 139In symmetric Initial Attestation, Instance ID is also calculated the first time 140it is requested. It can protect critical symmetric IAK from being frequently 141fetched, which increases the risk of asset disclosure. 142 143The Instance ID value is the output of hashing symmetric IAK raw data *twice*, 144as requested in PSA Attestation API [1]_. HMAC-SHA256 may be hard-coded as the 145hash algorithm of Instance ID calculation. 146 147.. note :: 148 149 According to RFC2104 [4]_, if a HMAC key is longer than the HMAC block size, 150 the key will be first hashed. The hash output is used as the key in HMAC 151 computation. 152 153 In current design, HMAC is used to calculate the authentication tag of 154 ``COSE_Mac0``. Assume that symmetric IAK is longer than HMAC block size 155 (HMAC-SHA256 by default), the Instance ID is actually the HMAC key for 156 ``COSE_Mac0`` authentication tag generation, if Instance ID value is the 157 output of hashing IAK only *once*. 158 Therefore, attackers may request an valid IAT from device and fake malicious 159 ones by using Instance ID to calculate valid authentication tags, to cheat 160 others. 161 162 As a result, symmetric IAK raw data should be hashed *twice* to generate the 163 Instance ID value. 164 165The Instance ID calculation result is stored in a static buffer. 166Token generation process can call ``attest_get_instance_id()`` to 167fetch the data from that static buffer. 168 169attest_token_start() 170==================== 171 172Symmetric Initial Attestation dedicated ``attest_token_start()`` initializes the 173``COSE_Mac0`` signing context and builds up the ``COSE_Mac0`` Header. 174 175The workflow inside ``attest_token_start()`` is shown in 176:ref:`attest-token-start-figure` below. 177 178.. _attest-token-start-figure: 179 180.. figure:: /design_docs/media/symmetric_initial_attest/attest_token_start.png 181 :align: center 182 183 Workflow in symmetric Initial Attestation ``attest_token_start()`` 184 185Descriptions of each step are listed below: 186 187#. ``t_cose_mac0_sign_init()`` is invoked to initialize ``COSE_Mac0`` signing 188 context in ``t_cose``. 189 190#. The symmetric IAK handle is set into ``COSE_Mac0`` signing context via 191 ``t_cose_mac0_set_signing_key()``. 192 193#. Initialize ``QCBOR`` encoder. 194 195#. The header parameters are encoded into ``COSE_Mac0`` structure in 196 ``t_cose_mac0_encode_parameters()``. 197 198#. ``QCBOREncode_OpenMap()`` prepares for encoding the ``COSE_Mac0`` payload, 199 which is filled with IAT claims. 200 201All the ``COSE_Mac0`` functionalities in ``t_cose`` are covered in 202`COSE_Mac0 support in t_cose`_. 203 204Instance ID claim 205================= 206 207Symmetric Initial Attestation also implements Instance ID claims in 208``attest_add_instance_id_claim()``. 209 210The Instance ID value is fetched via ``attest_get_instance_id()``. 211The value has already been calculated during symmetric IAK registration. See 212`Instance ID calculation`_ for details. 213 214The other steps are the same as those in asymmetric Initial Attestation 215implementation. The UEID type byte is set to 0x01. 216 217attest_token_finish() 218===================== 219 220Symmetric Initial Attestation dedicated ``attest_token_finish()`` calls 221``t_cose_mac0_encode_tag()`` to calculate and encode the authentication tag of 222``COSE_Mac0`` structure. 223 224The whole COSE and CBOR encoding are completed in ``attest_token_finish()``. 225 226The simplified flow in ``attest_token_finish()`` is shown in 227:ref:`attest-token-finish-figure` below. 228 229.. _attest-token-finish-figure: 230 231.. figure:: /design_docs/media/symmetric_initial_attest/attest_token_finish.png 232 :align: center 233 234 Workflow in symmetric Initial Attestation ``attest_token_finish()`` 235 236*************************** 237COSE_Mac0 support in t_cose 238*************************** 239 240``COSE_Mac0`` supports in ``t_cose`` in TF-M include the following major 241functionalities: 242 243 - Encoding ``COSE_Mac0`` structure 244 - Decoding and verifying ``COSE_Mac0`` structure 245 - HMAC computation to generate and verify authentication tag 246 - Short-circuit tagging for test mode 247 248According to RFC8152 [5]_, ``COSE_Mac0`` and ``COSE_Sign1`` have similar 249structures. Therefore, the prototype follows ``COSE_Sign1`` implementation to 250build up ``COSE_Mac0`` file structure and implement ``COSE_Mac0`` encoding and 251decoding. 252 253Although ``COSE_Mac0`` can share lots of data types, APIs and encoding/decoding 254steps with ``COSE_Sign1`` in implementation, this prototype separates 255``COSE_Mac0`` implementation from ``COSE_Sign1``. ``COSE_Mac0`` owns its 256dedicated signing/verification contexts, APIs and encoding/decoding process. 257The purposes of separating ``COSE_Mac0`` and ``COSE_Sign1`` are listed below 258 259- It can keep changes to ``COSE_Sign1`` as small as possible and avoid conflicts 260 with development in ``COSE_Sign1```. It can decrease conflicts if ``t_cose`` 261 in TF-M is synchronized with original ``t_cose`` repository later. 262- ``COSE_Mac0`` and ``COSE_Sign1`` are exclusive in TF-M use cases. 263 It cannot decrease TF-M memory footprint by extracting the common components 264 shared by ``COSE_Mac0`` and ``COSE_Sign1`` but can make the design 265 over-complicated. 266 267.. note :: 268 269 Only HMAC is supported in current ``COSE_Mac0`` prototype. 270 271File structure 272============== 273 274New files are added to implement the functionalities listed above. The structure 275of files is shown in the table below. 276 277.. table:: New files in ``t_cose`` 278 :widths: auto 279 :align: center 280 281 +---------------------+--------------------------------+----------------------------------------------+ 282 | Directory | Files | Descriptions | 283 +=====================+================================+==============================================+ 284 | ``src`` | ``t_cose_mac0_sign.c`` | Encode ``COSE_Mac0`` structure | 285 | +--------------------------------+----------------------------------------------+ 286 | | ``t_cose_mac0_verify.c`` | Decode and verify ``COSE_Mac0`` structure. | 287 +---------------------+--------------------------------+----------------------------------------------+ 288 | ``inc`` | ``t_cose_mac0_sign.h`` | Data type definitions and function | 289 | | | declarations of encoding and signing | 290 | | | ``COSE_Mac0`` message. | 291 | +--------------------------------+----------------------------------------------+ 292 | | ``t_cose_mac0_verify.h`` | Data type definitions and function | 293 | | | declarations of verifying ``COSE_Mac0`` | 294 | | | message. | 295 +---------------------+--------------------------------+----------------------------------------------+ 296 297Other ``t_cose`` files may also be changed to add ``COSE_Mac0`` associated data 298types and function declarations. 299 300HMAC operations are added in ``crypto_adapters/t_cose_psa_crypto.c``. 301Preprocessor flags are added to select corresponding crypto for COSE message 302signing and verification. 303 304 - ``T_COSE_ENABLE_SIGN1`` selects ECDSA and Hash operations for 305 ``COSE_Sign1``. 306 - ``T_COSE_ENABLE_MAC0`` selects HMAC operations for ``COSE_Mac0``. 307 308Encoding COSE_Mac0 309================== 310 311Following ``COSE_Sign1`` implementation, ``COSE_Mac0`` encoding exports similar 312functions to Initial Attestation secure service. 313The major functions are listed below. 314 315Initialize signing context 316-------------------------- 317 318``t_cose_mac0_sign_init()`` initializes ``COSE_Mac0`` signing context and 319configures option flags and algorithm used in signing. 320 321.. code-block:: c 322 323 static void 324 t_cose_mac0_sign_init(struct t_cose_mac0_sign_ctx *me, 325 int32_t option_flags, 326 int32_t cose_algorithm_id); 327 328The ``COSE_Mac0`` signing context is defined as 329 330.. code-block:: c 331 332 struct t_cose_mac0_sign_ctx { 333 /* Private data structure */ 334 uint8_t protected_parameters_buffer[ 335 T_COSE_MAC0_MAX_SIZE_PROTECTED_PARAMETERS]; 336 struct q_useful_buf_c protected_parameters; /* The encoded protected parameters */ 337 int32_t cose_algorithm_id; 338 struct t_cose_key signing_key; 339 int32_t option_flags; 340 struct q_useful_buf_c kid; 341 ... 342 }; 343 344Set signing key 345--------------- 346 347``t_cose_mac0_set_signing_key()`` sets the key used in ``COSE_Mac0`` signing. 348Optional ``kid``, as a key identifer, will be encoded into ``COSE_Mac0`` Header 349unprotected bucket. 350 351.. code-block:: c 352 353 static void 354 t_cose_mac0_set_signing_key(struct t_cose_mac0_sign_ctx *me, 355 struct t_cose_key signing_key, 356 struct q_useful_buf_c kid); 357 358Encode Header parameters 359------------------------ 360 361``t_cose_mac0_encode_parameters()`` encodes the ``COSE_Mac0`` Header parameters 362and outputs the encoded context to ``cbor_encode_ctx``. 363 364.. code-block:: c 365 366 enum t_cose_err_t 367 t_cose_mac0_encode_parameters(struct t_cose_mac0_sign_ctx *context, 368 QCBOREncodeContext *cbor_encode_ctx); 369 370Calculate and add authentication tag 371------------------------------------ 372 373``t_cose_mac0_encode_tag()`` calculates the authentication tag and finishes the 374``COSE_Mac0`` message. 375 376.. code-block:: c 377 378 enum t_cose_err_t 379 t_cose_mac0_encode_tag(struct t_cose_mac0_sign_ctx *context, 380 QCBOREncodeContext *cbor_encode_ctx); 381 382Decoding COSE_Mac0 383================== 384 385Following ``COSE_Sign1`` implementation, ``COSE_Mac0`` decoding exports similar 386functions to test suite of Initial Attestation. 387The major functions are listed below. 388 389Initialize verification context 390------------------------------- 391 392``t_cose_mac0_verify_init()`` initializes ``COSE_Mac0`` verification context and 393configures option flags in verification. 394 395.. code-block:: c 396 397 static void 398 t_cose_mac0_verify_init(struct t_cose_mac0_verify_ctx *context, 399 int32_t option_flags); 400 401The ``COSE_Mac0`` verification context is defined as 402 403.. code-block:: c 404 405 struct t_cose_mac0_verify_ctx { 406 /* Private data structure */ 407 struct t_cose_key verification_key; 408 int32_t option_flags; 409 }; 410 411Set verification key 412-------------------- 413 414``t_cose_mac0_set_verify_key()`` sets the key for verifying ``COSE_Mac0`` 415authentication tag. 416 417.. code-block:: c 418 419 static void 420 t_cose_mac0_set_verify_key(struct t_cose_mac0_verify_ctx *context, 421 struct t_cose_key verify_key); 422 423Decode and verify COSE_Mac0 424--------------------------- 425 426``t_cose_mac0_verify()`` decodes the ``COSE_Mac0`` structure and verifies the 427authentication tag. 428 429.. code-block:: c 430 431 enum t_cose_err_t 432 t_cose_mac0_verify(struct t_cose_mac0_verify_ctx *context, 433 struct q_useful_buf_c cose_mac0, 434 struct q_useful_buf_c *payload, 435 struct t_cose_parameters *parameters); 436 437Short-circuit tagging 438===================== 439 440If ``T_COSE_OPT_SHORT_CIRCUIT_TAG`` option is enabled, ``COSE_Mac0`` encoding 441will hash the ``COSE_Mac0`` content and add the hash output as an authentication 442tag. It is useful when critical symmetric IAK is unavailable or cannot be 443accessed, perhaps because it has not been provisioned or configured for the 444particular device. It is only for test and must not be used in actual use case. 445The ``kid`` parameter will either be skipped in ``COSE_Mac0`` Header. 446 447If ``T_COSE_OPT_ALLOW_SHORT_CIRCUIT`` option is enabled, ``COSE_Mac0`` decoding 448will only verify the hash output, without requiring symmetric key for 449authentication tag verification. 450 451*************** 452TF-M Test suite 453*************** 454 455Symmetric Initial Attestation adds dedicated non-secure and secure test suites. 456The test suites also follow asymmetric Initial Attestation test suites 457implementation but optimize the memory footprint. 458Symmetric Initial Attestation non-secure and secure test suites request Initial 459Attestation secure service to generate IATs. After IATs are generated 460successfully, test suites decode IATs and parse the claims. 461Secure test suite also verifies the authentication tag in ``COSE_Mac0`` 462structure. 463 464Symmetric Initial Attestation implements its dedicated 465``attest_token_decode_validate_token()`` in ``attest_symmetric_iat_decoded.c`` 466to perform IAT decoding required by test suites. 467If ``SYMMETRIC_INITIAL_ATTESTATION`` is selected, 468``attest_symmetric_iat_decoded.c`` is included in build. 469Otherwise, asymmetric Initial Attestation dedicated implementations are included 470instead. 471 472The workflow of symmetric Initial Attestation dedicated 473``attest_token_decode_validate_token()`` is shown below. 474 475.. _iat-decode-figure: 476 477.. figure:: /design_docs/media/symmetric_initial_attest/iat_decode.png 478 :align: center 479 480 Workflow in symmetric Initial Attestation ``attest_token_decode_validate_token()`` 481 482If the decoding is required from secure test suite, 483``attest_token_decode_validate_token()`` will fetch symmetric IAK to verify the 484authentication tag in ``COSE_Mac0`` structure. 485If the decoding is required from non-secure test suite, 486``attest_token_decode_validate_token()`` will decode ``COSE_Mac0`` only by 487setting ``T_COSE_OPT_DECODE_ONLY`` option flag. Non-secure must not access the 488symmetric IAK. 489 490******** 491HAL APIs 492******** 493 494HAL APIs are summarized below. 495 496Fetch device symmetric IAK 497========================== 498 499``tfm_plat_get_symmetric_iak()`` fetches device symmetric IAK. 500 501 .. code-block:: c 502 503 enum tfm_plat_err_t tfm_plat_get_symmetric_iak(uint8_t *key_buf, 504 size_t buf_len, 505 size_t *key_len, 506 psa_algorithm_t *key_alg); 507 508 **Parameters:** 509 510 +-------------+-----------------------------------------------------------+ 511 | ``key_buf`` | Buffer to store the symmetric IAK. | 512 +-------------+-----------------------------------------------------------+ 513 | ``buf_len`` | The length of ``key_buf``. | 514 +-------------+-----------------------------------------------------------+ 515 | ``key_len`` | The length of the symmetric IAK. | 516 +-------------+-----------------------------------------------------------+ 517 | ``key_alg`` | The key algorithm. Only HMAC SHA-256 is supported so far. | 518 +-------------+-----------------------------------------------------------+ 519 520It returns error code specified in ``enum tfm_plat_err_t``. 521 522Get symmetric IAK key identifier 523================================ 524 525``attest_plat_get_symmetric_iak_id()`` gets the key identifier of the symmetric 526IAK as the ``kid`` parameter in COSE Header. 527 528Optional if device doesn't install a key identifier for symmetric IAK. 529 530 .. code-block:: c 531 532 enum tfm_plat_err_t attest_plat_get_symmetric_iak_id(void *kid_buf, 533 size_t buf_len, 534 size_t *kid_len); 535 536 **Parameters:** 537 538 +-------------+-------------------------------------+ 539 | ``kid_buf`` | Buffer to store the IAK identifier. | 540 +-------------+-------------------------------------+ 541 | ``buf_len`` | The length of ``kid_buf``. | 542 +-------------+-------------------------------------+ 543 | ``kid_len`` | The length of the IAK identifier. | 544 +-------------+-------------------------------------+ 545 546It returns error code specified in ``enum tfm_plat_err_t``. 547 548********* 549Reference 550********* 551 552.. [1] `PSA Attestation API 1.0 (ARM IHI 0085) <https://developer.arm.com/-/media/Files/pdf/PlatformSecurityArchitecture/Implement/IHI0085-PSA_Attestation_API-1.0.2.pdf?revision=eef78753-c77e-4b24-bcf0-65596213b4c1&la=en&hash=E5E0353D612077AFDCE3F2F3708A50C77A74B2A3>`_ 553 554.. [2] :doc:`Trusted Firmware-M Profile Small Design </configuration/profiles/tfm_profile_small>` 555 556.. [3] :doc:`Initial Attestation Service Integration Guide </integration_guide/services/tfm_attestation_integration_guide>` 557 558.. [4] `HMAC: Keyed-Hashing for Message Authentication <https://tools.ietf.org/html/rfc2104>`_ 559 560.. [5] `CBOR Object Signing and Encryption (COSE) <https://tools.ietf.org/html/rfc8152>`_ 561 562---------------- 563 564*Copyright (c) 2020-2022 Arm Limited. All Rights Reserved.* 565