David Hu | c042793 | 2020-04-09 23:03:49 +0800 | [diff] [blame] | 1 | ################################################# |
| 2 | Symmetric key algorithm based Initial Attestation |
| 3 | ################################################# |
| 4 | |
Anton Komlev | 19b9071 | 2021-10-19 16:28:02 +0100 | [diff] [blame] | 5 | :Author: David Hu |
David Hu | c042793 | 2020-04-09 23:03:49 +0800 | [diff] [blame] | 6 | :Organization: Arm Limited |
| 7 | :Contact: david.hu@arm.com |
| 8 | |
| 9 | ************ |
| 10 | Introduction |
| 11 | ************ |
| 12 | |
| 13 | This document proposes a design of symmetric key algorithm based Initial |
| 14 | Attestation in TF-M. |
| 15 | |
| 16 | Symmetric key algorithm based Initial Attestation |
| 17 | (*symmetric Initial Attestation* for short) signs and verifies Initial |
Edison Ai | f7990c8 | 2020-07-16 18:31:48 +0800 | [diff] [blame] | 18 | Attestation Token (IAT) with a symmetric cryptography signature scheme, such as |
David Hu | c042793 | 2020-04-09 23:03:49 +0800 | [diff] [blame] | 19 | HMAC. |
| 20 | It can reduce TF-M binary size and memory footprint on ultra-constrained devices |
| 21 | without integrating asymmetric ciphers. |
| 22 | |
| 23 | This 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 | *************** |
| 34 | Design overview |
| 35 | *************** |
| 36 | |
| 37 | The symmetric Initial Attestation follows the existing IAT generation sequence |
| 38 | for Initial Attestation based on asymmetric key algorithm |
| 39 | (*asymmetric Initial Attestation* for short). |
| 40 | |
| 41 | As Profile Small design [2]_ requests, a configuration flag |
| 42 | ``SYMMETRIC_INITIAL_ATTESTATION`` selects symmetric initial attestation during |
| 43 | build. |
| 44 | |
| 45 | The top-level design is shown in :ref:`overall-diagram-figure` below. |
| 46 | |
| 47 | .. _overall-diagram-figure: |
| 48 | |
Anton Komlev | b3f6466 | 2023-01-28 11:53:05 +0000 | [diff] [blame] | 49 | .. figure:: /design_docs/media/symmetric_initial_attest/overall_diagram.png |
David Hu | c042793 | 2020-04-09 23:03:49 +0800 | [diff] [blame] | 50 | :align: center |
| 51 | |
| 52 | Overall design diagram |
| 53 | |
| 54 | Symmetric Initial Attestation adds its own implementations of some steps in IAT |
| 55 | generation in Initial Attestation secure service. More details are covered in |
| 56 | `IAT generation in Initial Attestation secure service`_. |
| 57 | |
| 58 | The interfaces and procedures of Initial Attestation secure service are not |
| 59 | affected. Refer to Initial Attestation Service Integration Guide [3]_ for |
| 60 | details of the implementation of Initial Attestation secure service. |
| 61 | |
| 62 | Symmetric Initial Attestation invokes ``t_cose`` library to build up |
David Vincze | a7bcb8a | 2023-08-09 14:35:32 +0200 | [diff] [blame] | 63 | ``COSE_Mac0`` structure. ``COSE_Mac0`` support was originally added to the |
David Vincze | 581f104 | 2025-02-19 10:25:54 +0000 | [diff] [blame] | 64 | ``t_cose`` library fork in TF-M, however since ``t_cose 2.0`` it is part of |
| 65 | the upstream library [4]_ which is already used by TF-M too. |
David Hu | c042793 | 2020-04-09 23:03:49 +0800 | [diff] [blame] | 66 | |
| 67 | Several HAL APIs are defined to fetch platform specific assets required by |
| 68 | Symmetric Initial Attestation. For example, ``tfm_plat_get_symmetric_iak()`` |
| 69 | fetches symmetric Initial Attestation Key (IAK). Those HAL APIs are summarized |
| 70 | in `HAL APIs`_. |
| 71 | |
| 72 | Decoding and verification of symmetric Initial Attestation is also included in |
| 73 | this proposal for regression test. |
| 74 | The test suites and IAT decoding are discussed in `TF-M Test suite`_. |
| 75 | |
| 76 | ``QCBOR`` library and Crypto service are also invoked. But this proposal doesn't |
| 77 | require any modification to either ``QCBOR`` or Crypto service. Therefore, |
| 78 | descriptions of ``QCBOR`` and Crypto service are skipped in this document. |
| 79 | |
| 80 | **************************************************** |
| 81 | IAT generation in Initial Attestation secure service |
| 82 | **************************************************** |
| 83 | |
| 84 | The sequence of IAT generation of symmetric Initial Attestation is shown in |
Raef Coles | b3adfeb | 2022-03-02 14:00:57 +0000 | [diff] [blame] | 85 | :ref:`ia-service-figure` below. Note that the ``Register symmetric IAK`` stage |
| 86 | is no longer required due to changes in the Crypto partition |
| 87 | (``attest_symmetric_key.c`` is now responsible only for calculating the instance |
| 88 | ID). |
David Hu | c042793 | 2020-04-09 23:03:49 +0800 | [diff] [blame] | 89 | |
| 90 | .. _ia-service-figure: |
| 91 | |
Anton Komlev | b3f6466 | 2023-01-28 11:53:05 +0000 | [diff] [blame] | 92 | .. figure:: /design_docs/media/symmetric_initial_attest/ia_service_flow.png |
David Hu | c042793 | 2020-04-09 23:03:49 +0800 | [diff] [blame] | 93 | :align: center |
| 94 | |
| 95 | Symmetric IAT generation flow in Initial Attestation secure service |
| 96 | |
| 97 | In Initial Attestation secure service, symmetric Initial Attestation implements |
| 98 | the following steps in ``attest_create_token()``, which are different from those |
| 99 | of asymmetric Initial Attestation. |
| 100 | |
David Vincze | 581f104 | 2025-02-19 10:25:54 +0000 | [diff] [blame] | 101 | - ``attest_token_start()``, |
| 102 | - Instance ID claims, |
| 103 | - ``attest_token_finish()``. |
David Hu | c042793 | 2020-04-09 23:03:49 +0800 | [diff] [blame] | 104 | |
| 105 | If ``SYMMETRIC_INITIAL_ATTESTATION`` is selected, symmetric Initial Attestation |
| 106 | dedicated implementations of those steps are included in build. |
| 107 | Otherwise, asymmetric Initial Attestation dedicated implementations are included |
David Vincze | 581f104 | 2025-02-19 10:25:54 +0000 | [diff] [blame] | 108 | instead. Symmetric Initial Attestation implementation resides a new file |
Raef Coles | b3adfeb | 2022-03-02 14:00:57 +0000 | [diff] [blame] | 109 | ``attest_symmetric_key.c`` to handle symmetric Instance ID related operations. |
David Hu | c042793 | 2020-04-09 23:03:49 +0800 | [diff] [blame] | 110 | Symmetric Initial Attestation dedicated ``attest_token_start()`` and |
| 111 | ``attest_token_finish()`` are added in ``attestation_token.c``. |
David Hu | c042793 | 2020-04-09 23:03:49 +0800 | [diff] [blame] | 112 | The details are covered in following sections. |
| 113 | |
Raef Coles | b3adfeb | 2022-03-02 14:00:57 +0000 | [diff] [blame] | 114 | Symmetric Instance ID |
| 115 | ===================== |
David Hu | c042793 | 2020-04-09 23:03:49 +0800 | [diff] [blame] | 116 | |
Raef Coles | b3adfeb | 2022-03-02 14:00:57 +0000 | [diff] [blame] | 117 | Symmetric Initial Attestation dedicated ``attest_symmetric_key.c`` implements |
| 118 | the ``attest_get_instance_id()`` function. This function returns the Instance ID |
| 119 | value, calculating it if it has not already been calculated. Refer to |
David Vincze | 581f104 | 2025-02-19 10:25:54 +0000 | [diff] [blame] | 120 | `Instance ID claim`_ for more details. |
David Hu | c042793 | 2020-04-09 23:03:49 +0800 | [diff] [blame] | 121 | |
| 122 | .. note :: |
| 123 | |
| 124 | Only symmetric IAK for HMAC algorithm is allowed so far. |
| 125 | |
| 126 | Instance ID calculation |
| 127 | ----------------------- |
| 128 | |
Raef Coles | b3adfeb | 2022-03-02 14:00:57 +0000 | [diff] [blame] | 129 | In symmetric Initial Attestation, Instance ID is also calculated the first time |
| 130 | it is requested. It can protect critical symmetric IAK from being frequently |
| 131 | fetched, which increases the risk of asset disclosure. |
David Hu | c042793 | 2020-04-09 23:03:49 +0800 | [diff] [blame] | 132 | |
| 133 | The Instance ID value is the output of hashing symmetric IAK raw data *twice*, |
| 134 | as requested in PSA Attestation API [1]_. HMAC-SHA256 may be hard-coded as the |
| 135 | hash algorithm of Instance ID calculation. |
| 136 | |
| 137 | .. note :: |
| 138 | |
David Vincze | 581f104 | 2025-02-19 10:25:54 +0000 | [diff] [blame] | 139 | According to RFC2104 [5]_, if a HMAC key is longer than the HMAC block size, |
David Hu | c042793 | 2020-04-09 23:03:49 +0800 | [diff] [blame] | 140 | the key will be first hashed. The hash output is used as the key in HMAC |
| 141 | computation. |
| 142 | |
| 143 | In current design, HMAC is used to calculate the authentication tag of |
| 144 | ``COSE_Mac0``. Assume that symmetric IAK is longer than HMAC block size |
| 145 | (HMAC-SHA256 by default), the Instance ID is actually the HMAC key for |
| 146 | ``COSE_Mac0`` authentication tag generation, if Instance ID value is the |
| 147 | output of hashing IAK only *once*. |
| 148 | Therefore, attackers may request an valid IAT from device and fake malicious |
| 149 | ones by using Instance ID to calculate valid authentication tags, to cheat |
| 150 | others. |
| 151 | |
| 152 | As a result, symmetric IAK raw data should be hashed *twice* to generate the |
| 153 | Instance ID value. |
| 154 | |
| 155 | The Instance ID calculation result is stored in a static buffer. |
| 156 | Token generation process can call ``attest_get_instance_id()`` to |
| 157 | fetch the data from that static buffer. |
| 158 | |
| 159 | attest_token_start() |
| 160 | ==================== |
| 161 | |
| 162 | Symmetric Initial Attestation dedicated ``attest_token_start()`` initializes the |
David Vincze | a7bcb8a | 2023-08-09 14:35:32 +0200 | [diff] [blame] | 163 | ``COSE_Mac0`` computation context and builds up the ``COSE_Mac0`` Header. |
David Hu | c042793 | 2020-04-09 23:03:49 +0800 | [diff] [blame] | 164 | |
| 165 | The workflow inside ``attest_token_start()`` is shown in |
| 166 | :ref:`attest-token-start-figure` below. |
| 167 | |
| 168 | .. _attest-token-start-figure: |
| 169 | |
Anton Komlev | b3f6466 | 2023-01-28 11:53:05 +0000 | [diff] [blame] | 170 | .. figure:: /design_docs/media/symmetric_initial_attest/attest_token_start.png |
David Hu | c042793 | 2020-04-09 23:03:49 +0800 | [diff] [blame] | 171 | :align: center |
| 172 | |
| 173 | Workflow in symmetric Initial Attestation ``attest_token_start()`` |
| 174 | |
| 175 | Descriptions of each step are listed below: |
| 176 | |
| 177 | #. ``t_cose_mac0_sign_init()`` is invoked to initialize ``COSE_Mac0`` signing |
| 178 | context in ``t_cose``. |
| 179 | |
David Hu | c042793 | 2020-04-09 23:03:49 +0800 | [diff] [blame] | 180 | #. The symmetric IAK handle is set into ``COSE_Mac0`` signing context via |
| 181 | ``t_cose_mac0_set_signing_key()``. |
| 182 | |
| 183 | #. Initialize ``QCBOR`` encoder. |
| 184 | |
| 185 | #. The header parameters are encoded into ``COSE_Mac0`` structure in |
| 186 | ``t_cose_mac0_encode_parameters()``. |
| 187 | |
| 188 | #. ``QCBOREncode_OpenMap()`` prepares for encoding the ``COSE_Mac0`` payload, |
| 189 | which is filled with IAT claims. |
| 190 | |
David Vincze | 581f104 | 2025-02-19 10:25:54 +0000 | [diff] [blame] | 191 | For detailed description and documentation of the ``COSE_Mac0`` functionalities |
| 192 | please refer to the ``t_cose`` repository [4]_. |
David Hu | c042793 | 2020-04-09 23:03:49 +0800 | [diff] [blame] | 193 | |
| 194 | Instance ID claim |
| 195 | ================= |
| 196 | |
| 197 | Symmetric Initial Attestation also implements Instance ID claims in |
David Vincze | 581f104 | 2025-02-19 10:25:54 +0000 | [diff] [blame] | 198 | ``attest_add_instance_id_claim()``. The Instance ID value is fetched via |
| 199 | ``attest_get_instance_id()``. The value has already been calculated during |
| 200 | symmetric IAK registration. See `Instance ID calculation`_ for details. |
David Hu | c042793 | 2020-04-09 23:03:49 +0800 | [diff] [blame] | 201 | |
| 202 | The other steps are the same as those in asymmetric Initial Attestation |
| 203 | implementation. The UEID type byte is set to 0x01. |
| 204 | |
| 205 | attest_token_finish() |
| 206 | ===================== |
| 207 | |
| 208 | Symmetric Initial Attestation dedicated ``attest_token_finish()`` calls |
| 209 | ``t_cose_mac0_encode_tag()`` to calculate and encode the authentication tag of |
David Vincze | 581f104 | 2025-02-19 10:25:54 +0000 | [diff] [blame] | 210 | ``COSE_Mac0`` structure. The whole COSE and CBOR encoding are completed in |
| 211 | ``attest_token_finish()``. The simplified flow in ``attest_token_finish()`` is |
| 212 | shown in :ref:`attest-token-finish-figure` below. |
David Hu | c042793 | 2020-04-09 23:03:49 +0800 | [diff] [blame] | 213 | |
| 214 | .. _attest-token-finish-figure: |
| 215 | |
Anton Komlev | b3f6466 | 2023-01-28 11:53:05 +0000 | [diff] [blame] | 216 | .. figure:: /design_docs/media/symmetric_initial_attest/attest_token_finish.png |
David Hu | c042793 | 2020-04-09 23:03:49 +0800 | [diff] [blame] | 217 | :align: center |
| 218 | |
| 219 | Workflow in symmetric Initial Attestation ``attest_token_finish()`` |
| 220 | |
David Hu | c042793 | 2020-04-09 23:03:49 +0800 | [diff] [blame] | 221 | *************** |
| 222 | TF-M Test suite |
| 223 | *************** |
| 224 | |
| 225 | Symmetric Initial Attestation adds dedicated non-secure and secure test suites. |
| 226 | The test suites also follow asymmetric Initial Attestation test suites |
| 227 | implementation but optimize the memory footprint. |
| 228 | Symmetric Initial Attestation non-secure and secure test suites request Initial |
| 229 | Attestation secure service to generate IATs. After IATs are generated |
| 230 | successfully, test suites decode IATs and parse the claims. |
| 231 | Secure test suite also verifies the authentication tag in ``COSE_Mac0`` |
| 232 | structure. |
| 233 | |
| 234 | Symmetric Initial Attestation implements its dedicated |
| 235 | ``attest_token_decode_validate_token()`` in ``attest_symmetric_iat_decoded.c`` |
| 236 | to perform IAT decoding required by test suites. |
| 237 | If ``SYMMETRIC_INITIAL_ATTESTATION`` is selected, |
| 238 | ``attest_symmetric_iat_decoded.c`` is included in build. |
| 239 | Otherwise, asymmetric Initial Attestation dedicated implementations are included |
| 240 | instead. |
| 241 | |
| 242 | The workflow of symmetric Initial Attestation dedicated |
| 243 | ``attest_token_decode_validate_token()`` is shown below. |
| 244 | |
| 245 | .. _iat-decode-figure: |
| 246 | |
Anton Komlev | b3f6466 | 2023-01-28 11:53:05 +0000 | [diff] [blame] | 247 | .. figure:: /design_docs/media/symmetric_initial_attest/iat_decode.png |
David Hu | c042793 | 2020-04-09 23:03:49 +0800 | [diff] [blame] | 248 | :align: center |
| 249 | |
| 250 | Workflow in symmetric Initial Attestation ``attest_token_decode_validate_token()`` |
| 251 | |
| 252 | If the decoding is required from secure test suite, |
| 253 | ``attest_token_decode_validate_token()`` will fetch symmetric IAK to verify the |
| 254 | authentication tag in ``COSE_Mac0`` structure. |
| 255 | If the decoding is required from non-secure test suite, |
David Vincze | 581f104 | 2025-02-19 10:25:54 +0000 | [diff] [blame] | 256 | ``attest_token_decode_validate_token()`` will only decode ``COSE_Mac0`` by |
David Hu | c042793 | 2020-04-09 23:03:49 +0800 | [diff] [blame] | 257 | setting ``T_COSE_OPT_DECODE_ONLY`` option flag. Non-secure must not access the |
| 258 | symmetric IAK. |
| 259 | |
| 260 | ******** |
| 261 | HAL APIs |
| 262 | ******** |
| 263 | |
| 264 | HAL APIs are summarized below. |
| 265 | |
| 266 | Fetch device symmetric IAK |
| 267 | ========================== |
| 268 | |
| 269 | ``tfm_plat_get_symmetric_iak()`` fetches device symmetric IAK. |
| 270 | |
| 271 | .. code-block:: c |
| 272 | |
| 273 | enum tfm_plat_err_t tfm_plat_get_symmetric_iak(uint8_t *key_buf, |
| 274 | size_t buf_len, |
| 275 | size_t *key_len, |
| 276 | psa_algorithm_t *key_alg); |
| 277 | |
| 278 | **Parameters:** |
| 279 | |
| 280 | +-------------+-----------------------------------------------------------+ |
| 281 | | ``key_buf`` | Buffer to store the symmetric IAK. | |
| 282 | +-------------+-----------------------------------------------------------+ |
| 283 | | ``buf_len`` | The length of ``key_buf``. | |
| 284 | +-------------+-----------------------------------------------------------+ |
| 285 | | ``key_len`` | The length of the symmetric IAK. | |
| 286 | +-------------+-----------------------------------------------------------+ |
| 287 | | ``key_alg`` | The key algorithm. Only HMAC SHA-256 is supported so far. | |
| 288 | +-------------+-----------------------------------------------------------+ |
| 289 | |
| 290 | It returns error code specified in ``enum tfm_plat_err_t``. |
| 291 | |
| 292 | Get symmetric IAK key identifier |
| 293 | ================================ |
| 294 | |
| 295 | ``attest_plat_get_symmetric_iak_id()`` gets the key identifier of the symmetric |
| 296 | IAK as the ``kid`` parameter in COSE Header. |
| 297 | |
| 298 | Optional if device doesn't install a key identifier for symmetric IAK. |
| 299 | |
| 300 | .. code-block:: c |
| 301 | |
| 302 | enum tfm_plat_err_t attest_plat_get_symmetric_iak_id(void *kid_buf, |
| 303 | size_t buf_len, |
| 304 | size_t *kid_len); |
| 305 | |
| 306 | **Parameters:** |
| 307 | |
| 308 | +-------------+-------------------------------------+ |
| 309 | | ``kid_buf`` | Buffer to store the IAK identifier. | |
| 310 | +-------------+-------------------------------------+ |
| 311 | | ``buf_len`` | The length of ``kid_buf``. | |
| 312 | +-------------+-------------------------------------+ |
| 313 | | ``kid_len`` | The length of the IAK identifier. | |
| 314 | +-------------+-------------------------------------+ |
| 315 | |
| 316 | It returns error code specified in ``enum tfm_plat_err_t``. |
| 317 | |
| 318 | ********* |
| 319 | Reference |
| 320 | ********* |
| 321 | |
| 322 | .. [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>`_ |
| 323 | |
Anton Komlev | affe14f | 2022-11-01 00:07:41 +0000 | [diff] [blame] | 324 | .. [2] :doc:`Trusted Firmware-M Profile Small Design </configuration/profiles/tfm_profile_small>` |
David Hu | c042793 | 2020-04-09 23:03:49 +0800 | [diff] [blame] | 325 | |
Anton Komlev | 3356ba3 | 2022-03-31 22:02:11 +0100 | [diff] [blame] | 326 | .. [3] :doc:`Initial Attestation Service Integration Guide </integration_guide/services/tfm_attestation_integration_guide>` |
David Hu | c042793 | 2020-04-09 23:03:49 +0800 | [diff] [blame] | 327 | |
Matthew Dalzell | 988bbd6 | 2025-06-05 15:49:26 +0100 | [diff] [blame] | 328 | .. [4] `MAC compute in t_cose library <https://github.com/laurencelundblade/t_cose/blob/v2.0-alpha-2/inc/t_cose/t_cose_mac_compute.h>`_ |
David Hu | c042793 | 2020-04-09 23:03:49 +0800 | [diff] [blame] | 329 | |
David Vincze | 581f104 | 2025-02-19 10:25:54 +0000 | [diff] [blame] | 330 | .. [5] `HMAC: Keyed-Hashing for Message Authentication <https://tools.ietf.org/html/rfc2104>`_ |
David Vincze | a7bcb8a | 2023-08-09 14:35:32 +0200 | [diff] [blame] | 331 | |
David Hu | c042793 | 2020-04-09 23:03:49 +0800 | [diff] [blame] | 332 | ---------------- |
| 333 | |
David Vincze | 581f104 | 2025-02-19 10:25:54 +0000 | [diff] [blame] | 334 | *Copyright (c) 2020-2025 Arm Limited. All Rights Reserved.* |