blob: 00642b87ec40700f51ec19d3a8c2d44fe5ca39bf [file] [log] [blame]
David Huc0427932020-04-09 23:03:49 +08001#################################################
2Symmetric key algorithm based Initial Attestation
3#################################################
4
5:Authors: 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
Edison Aif7990c82020-07-16 18:31:48 +080018Attestation Token (IAT) with a symmetric cryptography signature scheme, such as
David Huc0427932020-04-09 23:03:49 +080019HMAC.
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:: 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.
93
94.. _ia-service-figure:
95
96.. figure:: media/symmetric_initial_attest/ia_service_flow.png
97 :align: center
98
99 Symmetric IAT generation flow in Initial Attestation secure service
100
101In Initial Attestation secure service, symmetric Initial Attestation implements
102the following steps in ``attest_create_token()``, which are different from those
103of asymmetric Initial Attestation.
104
105 - Fetch and register IAK
106 - ``attest_token_start()``
107 - Instance ID claims
108 - ``attest_token_finish()``
109
110If ``SYMMETRIC_INITIAL_ATTESTATION`` is selected, symmetric Initial Attestation
111dedicated implementations of those steps are included in build.
112Otherwise, asymmetric Initial Attestation dedicated implementations are included
113instead.
114
115Symmetric Initial Attestation implementation resides a new file
116``attest_symmetric_key.c`` to handle symmetric IAK and Instance ID related
117operations.
118Symmetric Initial Attestation dedicated ``attest_token_start()`` and
119``attest_token_finish()`` are added in ``attestation_token.c``.
120
121The details are covered in following sections.
122
123Register symmetric IAK
124======================
125
126Symmetric Initial Attestation dedicated ``attest_symmetric_key.c`` implements 4
127major functions. The functions are listed in the table below.
128
129.. table:: Functions in ``attest_symmetric_key.c``
130 :widths: auto
131 :align: center
132
133 +-------------------------------------------------+----------------------------------------------------+
134 | Functions | Descriptions |
135 +=================================================+====================================================+
136 | ``attest_register_initial_attestation_key()`` | Fetches device symmetric IAK, imports it into |
137 | | Crypto service and get the handle. |
138 | | The handle will be used to compute the |
139 | | authentication tag of IAT. |
140 | | Invokes HAL API ``tfm_plat_get_symmetric_iak()`` |
141 | | to fetch symmetric IAK from device. |
142 | | |
143 | | Refer to `HAL APIs`_ for more details. |
144 +-------------------------------------------------+----------------------------------------------------+
145 | ``attest_unregister_initial_attestation_key()`` | Destroys the symmetric IAK handle after IAT |
146 | | generation completes. |
147 +-------------------------------------------------+----------------------------------------------------+
148 | ``attest_get_signing_key_handle()`` | Return the IAK handle registered in |
149 | | ``attest_register_initial_attestation_key()``. |
150 +-------------------------------------------------+----------------------------------------------------+
151 | ``attest_get_instance_id()`` | Return the Instance ID value calculated in |
152 | | ``attest_register_initial_attestation_key()``. |
153 | | |
154 | | Refer to `Instance ID claim`_ for more details. |
155 +-------------------------------------------------+----------------------------------------------------+
156
157``attest_register_initial_attestation_key()`` and
158``attest_unregister_initial_attestation_key()`` share the same API declarations
159with asymmetric Initial Attestation.
160
161``attest_get_signing_key_handle()`` and ``attest_get_instance_id()`` are defined
162by symmetric Initial Attestation but can be shared with asymmetric Initial
163Attestation later.
164
165.. note ::
166
167 Only symmetric IAK for HMAC algorithm is allowed so far.
168
169Instance ID calculation
170-----------------------
171
172In symmetric Initial Attestation, Instance ID is also calculated in
173``attest_register_initial_attestation_key()``, after IAK handle is registered.
174It can protect critical symmetric IAK from being frequently fetched, which
175increases the risk of asset disclosure.
176
177The Instance ID value is the output of hashing symmetric IAK raw data *twice*,
178as requested in PSA Attestation API [1]_. HMAC-SHA256 may be hard-coded as the
179hash algorithm of Instance ID calculation.
180
181.. note ::
182
183 According to RFC2104 [4]_, if a HMAC key is longer than the HMAC block size,
184 the key will be first hashed. The hash output is used as the key in HMAC
185 computation.
186
187 In current design, HMAC is used to calculate the authentication tag of
188 ``COSE_Mac0``. Assume that symmetric IAK is longer than HMAC block size
189 (HMAC-SHA256 by default), the Instance ID is actually the HMAC key for
190 ``COSE_Mac0`` authentication tag generation, if Instance ID value is the
191 output of hashing IAK only *once*.
192 Therefore, attackers may request an valid IAT from device and fake malicious
193 ones by using Instance ID to calculate valid authentication tags, to cheat
194 others.
195
196 As a result, symmetric IAK raw data should be hashed *twice* to generate the
197 Instance ID value.
198
199The Instance ID calculation result is stored in a static buffer.
200Token generation process can call ``attest_get_instance_id()`` to
201fetch the data from that static buffer.
202
203attest_token_start()
204====================
205
206Symmetric Initial Attestation dedicated ``attest_token_start()`` initializes the
207``COSE_Mac0`` signing context and builds up the ``COSE_Mac0`` Header.
208
209The workflow inside ``attest_token_start()`` is shown in
210:ref:`attest-token-start-figure` below.
211
212.. _attest-token-start-figure:
213
214.. figure:: media/symmetric_initial_attest/attest_token_start.png
215 :align: center
216
217 Workflow in symmetric Initial Attestation ``attest_token_start()``
218
219Descriptions of each step are listed below:
220
221#. ``t_cose_mac0_sign_init()`` is invoked to initialize ``COSE_Mac0`` signing
222 context in ``t_cose``.
223
224#. The symmetric IAK handle is returned by ``attest_get_signing_key_handle()``.
225 See the details in `Register symmetric IAK`_.
226
227#. The symmetric IAK handle is set into ``COSE_Mac0`` signing context via
228 ``t_cose_mac0_set_signing_key()``.
229
230#. Initialize ``QCBOR`` encoder.
231
232#. The header parameters are encoded into ``COSE_Mac0`` structure in
233 ``t_cose_mac0_encode_parameters()``.
234
235#. ``QCBOREncode_OpenMap()`` prepares for encoding the ``COSE_Mac0`` payload,
236 which is filled with IAT claims.
237
238All the ``COSE_Mac0`` functionalities in ``t_cose`` are covered in
239`COSE_Mac0 support in t_cose`_.
240
241Instance ID claim
242=================
243
244Symmetric Initial Attestation also implements Instance ID claims in
245``attest_add_instance_id_claim()``.
246
247The Instance ID value is fetched via ``attest_get_instance_id()``.
248The value has already been calculated during symmetric IAK registration. See
249`Instance ID calculation`_ for details.
250
251The other steps are the same as those in asymmetric Initial Attestation
252implementation. The UEID type byte is set to 0x01.
253
254attest_token_finish()
255=====================
256
257Symmetric Initial Attestation dedicated ``attest_token_finish()`` calls
258``t_cose_mac0_encode_tag()`` to calculate and encode the authentication tag of
259``COSE_Mac0`` structure.
260
261The whole COSE and CBOR encoding are completed in ``attest_token_finish()``.
262
263The simplified flow in ``attest_token_finish()`` is shown in
264:ref:`attest-token-finish-figure` below.
265
266.. _attest-token-finish-figure:
267
268.. figure:: media/symmetric_initial_attest/attest_token_finish.png
269 :align: center
270
271 Workflow in symmetric Initial Attestation ``attest_token_finish()``
272
273***************************
274COSE_Mac0 support in t_cose
275***************************
276
277``COSE_Mac0`` supports in ``t_cose`` in TF-M include the following major
278functionalities:
279
280 - Encoding ``COSE_Mac0`` structure
281 - Decoding and verifying ``COSE_Mac0`` structure
282 - HMAC computation to generate and verify authentication tag
283 - Short-circuit tagging for test mode
284
285According to RFC8152 [5]_, ``COSE_Mac0`` and ``COSE_Sign1`` have similar
286structures. Therefore, the prototype follows ``COSE_Sign1`` implementation to
287build up ``COSE_Mac0`` file structure and implement ``COSE_Mac0`` encoding and
288decoding.
289
290Although ``COSE_Mac0`` can share lots of data types, APIs and encoding/decoding
291steps with ``COSE_Sign1`` in implementation, this prototype separates
292``COSE_Mac0`` implementation from ``COSE_Sign1``. ``COSE_Mac0`` owns its
293dedicated signing/verification contexts, APIs and encoding/decoding process.
294The purposes of separating ``COSE_Mac0`` and ``COSE_Sign1`` are listed below
295
296- It can keep changes to ``COSE_Sign1`` as small as possible and avoid conflicts
297 with development in ``COSE_Sign1```. It can decrease conflicts if ``t_cose``
298 in TF-M is synchronized with original ``t_cose`` repository later.
299- ``COSE_Mac0`` and ``COSE_Sign1`` are exclusive in TF-M use cases.
300 It cannot decrease TF-M memory footprint by extracting the common components
301 shared by ``COSE_Mac0`` and ``COSE_Sign1`` but can make the design
302 over-complicated.
303
304.. note ::
305
306 Only HMAC is supported in current ``COSE_Mac0`` prototype.
307
308File structure
309==============
310
311New files are added to implement the functionalities listed above. The structure
312of files is shown in the table below.
313
314.. table:: New files in ``t_cose``
315 :widths: auto
316 :align: center
317
318 +---------------------+--------------------------------+----------------------------------------------+
319 | Directory | Files | Descriptions |
320 +=====================+================================+==============================================+
321 | ``src`` | ``t_cose_mac0_sign.c`` | Encode ``COSE_Mac0`` structure |
322 | +--------------------------------+----------------------------------------------+
323 | | ``t_cose_mac0_verify.c`` | Decode and verify ``COSE_Mac0`` structure. |
324 +---------------------+--------------------------------+----------------------------------------------+
325 | ``inc`` | ``t_cose_mac0_sign.h`` | Data type definitions and function |
326 | | | declarations of encoding and signing |
327 | | | ``COSE_Mac0`` message. |
328 | +--------------------------------+----------------------------------------------+
329 | | ``t_cose_mac0_verify.h`` | Data type definitions and function |
330 | | | declarations of verifying ``COSE_Mac0`` |
331 | | | message. |
332 +---------------------+--------------------------------+----------------------------------------------+
333
334Other ``t_cose`` files may also be changed to add ``COSE_Mac0`` associated data
335types and function declarations.
336
337HMAC operations are added in ``crypto_adapters/t_cose_psa_crypto.c``.
338Preprocessor flags are added to select corresponding crypto for COSE message
339signing and verification.
340
341 - ``T_COSE_ENABLE_SIGN1`` selects ECDSA and Hash operations for
342 ``COSE_Sign1``.
343 - ``T_COSE_ENABLE_MAC0`` selects HMAC operations for ``COSE_Mac0``.
344
345Encoding COSE_Mac0
346==================
347
348Following ``COSE_Sign1`` implementation, ``COSE_Mac0`` encoding exports similar
349functions to Initial Attestation secure service.
350The major functions are listed below.
351
352Initialize signing context
353--------------------------
354
355``t_cose_mac0_sign_init()`` initializes ``COSE_Mac0`` signing context and
356configures option flags and algorithm used in signing.
357
358.. code-block:: c
359
360 static void
361 t_cose_mac0_sign_init(struct t_cose_mac0_sign_ctx *me,
362 int32_t option_flags,
363 int32_t cose_algorithm_id);
364
365The ``COSE_Mac0`` signing context is defined as
366
367.. code-block:: c
368
369 struct t_cose_mac0_sign_ctx {
370 /* Private data structure */
371 uint8_t protected_parameters_buffer[
372 T_COSE_MAC0_MAX_SIZE_PROTECTED_PARAMETERS];
373 struct q_useful_buf_c protected_parameters; /* The encoded protected parameters */
374 int32_t cose_algorithm_id;
375 struct t_cose_key signing_key;
376 int32_t option_flags;
377 struct q_useful_buf_c kid;
378 ...
379 };
380
381Set signing key
382---------------
383
384``t_cose_mac0_set_signing_key()`` sets the key used in ``COSE_Mac0`` signing.
385Optional ``kid``, as a key identifer, will be encoded into ``COSE_Mac0`` Header
386unprotected bucket.
387
388.. code-block:: c
389
390 static void
391 t_cose_mac0_set_signing_key(struct t_cose_mac0_sign_ctx *me,
392 struct t_cose_key signing_key,
393 struct q_useful_buf_c kid);
394
395Encode Header parameters
396------------------------
397
398``t_cose_mac0_encode_parameters()`` encodes the ``COSE_Mac0`` Header parameters
399and outputs the encoded context to ``cbor_encode_ctx``.
400
401.. code-block:: c
402
403 enum t_cose_err_t
404 t_cose_mac0_encode_parameters(struct t_cose_mac0_sign_ctx *context,
405 QCBOREncodeContext *cbor_encode_ctx);
406
407Calculate and add authentication tag
408------------------------------------
409
410``t_cose_mac0_encode_tag()`` calculates the authentication tag and finishes the
411``COSE_Mac0`` message.
412
413.. code-block:: c
414
415 enum t_cose_err_t
416 t_cose_mac0_encode_tag(struct t_cose_mac0_sign_ctx *context,
417 QCBOREncodeContext *cbor_encode_ctx);
418
419Decoding COSE_Mac0
420==================
421
422Following ``COSE_Sign1`` implementation, ``COSE_Mac0`` decoding exports similar
423functions to test suite of Initial Attestation.
424The major functions are listed below.
425
426Initialize verification context
427-------------------------------
428
429``t_cose_mac0_verify_init()`` initializes ``COSE_Mac0`` verification context and
430configures option flags in verification.
431
432.. code-block:: c
433
434 static void
435 t_cose_mac0_verify_init(struct t_cose_mac0_verify_ctx *context,
436 int32_t option_flags);
437
438The ``COSE_Mac0`` verification context is defined as
439
440.. code-block:: c
441
442 struct t_cose_mac0_verify_ctx {
443 /* Private data structure */
444 struct t_cose_key verification_key;
445 int32_t option_flags;
446 };
447
448Set verification key
449--------------------
450
451``t_cose_mac0_set_verify_key()`` sets the key for verifying ``COSE_Mac0``
452authentication tag.
453
454.. code-block:: c
455
456 static void
457 t_cose_mac0_set_verify_key(struct t_cose_mac0_verify_ctx *context,
458 struct t_cose_key verify_key);
459
460Decode and verify COSE_Mac0
461---------------------------
462
463``t_cose_mac0_verify()`` decodes the ``COSE_Mac0`` structure and verifies the
464authentication tag.
465
466.. code-block:: c
467
468 enum t_cose_err_t
469 t_cose_mac0_verify(struct t_cose_mac0_verify_ctx *context,
470 struct q_useful_buf_c cose_mac0,
471 struct q_useful_buf_c *payload,
472 struct t_cose_parameters *parameters);
473
474Short-circuit tagging
475=====================
476
477If ``T_COSE_OPT_SHORT_CIRCUIT_TAG`` option is enabled, ``COSE_Mac0`` encoding
478will hash the ``COSE_Mac0`` content and add the hash output as an authentication
479tag. It is useful when critical symmetric IAK is unavailable or cannot be
480accessed, perhaps because it has not been provisioned or configured for the
481particular device. It is only for test and must not be used in actual use case.
482The ``kid`` parameter will either be skipped in ``COSE_Mac0`` Header.
483
484If ``T_COSE_OPT_ALLOW_SHORT_CIRCUIT`` option is enabled, ``COSE_Mac0`` decoding
485will only verify the hash output, without requiring symmetric key for
486authentication tag verification.
487
488***************
489TF-M Test suite
490***************
491
492Symmetric Initial Attestation adds dedicated non-secure and secure test suites.
493The test suites also follow asymmetric Initial Attestation test suites
494implementation but optimize the memory footprint.
495Symmetric Initial Attestation non-secure and secure test suites request Initial
496Attestation secure service to generate IATs. After IATs are generated
497successfully, test suites decode IATs and parse the claims.
498Secure test suite also verifies the authentication tag in ``COSE_Mac0``
499structure.
500
501Symmetric Initial Attestation implements its dedicated
502``attest_token_decode_validate_token()`` in ``attest_symmetric_iat_decoded.c``
503to perform IAT decoding required by test suites.
504If ``SYMMETRIC_INITIAL_ATTESTATION`` is selected,
505``attest_symmetric_iat_decoded.c`` is included in build.
506Otherwise, asymmetric Initial Attestation dedicated implementations are included
507instead.
508
509The workflow of symmetric Initial Attestation dedicated
510``attest_token_decode_validate_token()`` is shown below.
511
512.. _iat-decode-figure:
513
514.. figure:: media/symmetric_initial_attest/iat_decode.png
515 :align: center
516
517 Workflow in symmetric Initial Attestation ``attest_token_decode_validate_token()``
518
519If the decoding is required from secure test suite,
520``attest_token_decode_validate_token()`` will fetch symmetric IAK to verify the
521authentication tag in ``COSE_Mac0`` structure.
522If the decoding is required from non-secure test suite,
523``attest_token_decode_validate_token()`` will decode ``COSE_Mac0`` only by
524setting ``T_COSE_OPT_DECODE_ONLY`` option flag. Non-secure must not access the
525symmetric IAK.
526
527********
528HAL APIs
529********
530
531HAL APIs are summarized below.
532
533Fetch device symmetric IAK
534==========================
535
536``tfm_plat_get_symmetric_iak()`` fetches device symmetric IAK.
537
538 .. code-block:: c
539
540 enum tfm_plat_err_t tfm_plat_get_symmetric_iak(uint8_t *key_buf,
541 size_t buf_len,
542 size_t *key_len,
543 psa_algorithm_t *key_alg);
544
545 **Parameters:**
546
547 +-------------+-----------------------------------------------------------+
548 | ``key_buf`` | Buffer to store the symmetric IAK. |
549 +-------------+-----------------------------------------------------------+
550 | ``buf_len`` | The length of ``key_buf``. |
551 +-------------+-----------------------------------------------------------+
552 | ``key_len`` | The length of the symmetric IAK. |
553 +-------------+-----------------------------------------------------------+
554 | ``key_alg`` | The key algorithm. Only HMAC SHA-256 is supported so far. |
555 +-------------+-----------------------------------------------------------+
556
557It returns error code specified in ``enum tfm_plat_err_t``.
558
559Get symmetric IAK key identifier
560================================
561
562``attest_plat_get_symmetric_iak_id()`` gets the key identifier of the symmetric
563IAK as the ``kid`` parameter in COSE Header.
564
565Optional if device doesn't install a key identifier for symmetric IAK.
566
567 .. code-block:: c
568
569 enum tfm_plat_err_t attest_plat_get_symmetric_iak_id(void *kid_buf,
570 size_t buf_len,
571 size_t *kid_len);
572
573 **Parameters:**
574
575 +-------------+-------------------------------------+
576 | ``kid_buf`` | Buffer to store the IAK identifier. |
577 +-------------+-------------------------------------+
578 | ``buf_len`` | The length of ``kid_buf``. |
579 +-------------+-------------------------------------+
580 | ``kid_len`` | The length of the IAK identifier. |
581 +-------------+-------------------------------------+
582
583It returns error code specified in ``enum tfm_plat_err_t``.
584
585*********
586Reference
587*********
588
589.. [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>`_
590
David Hu561cd9c2020-06-23 17:05:28 +0800591.. [2] :doc:`Trusted Firmware-M Profile Small Design </docs/design_documents/profiles/tfm_profile_small>`
David Huc0427932020-04-09 23:03:49 +0800592
Minos Galanakise4094012020-06-12 14:25:34 +0100593.. [3] :doc:`Initial Attestation Service Integration Guide </docs/reference/services/tfm_attestation_integration_guide>`
David Huc0427932020-04-09 23:03:49 +0800594
595.. [4] `HMAC: Keyed-Hashing for Message Authentication <https://tools.ietf.org/html/rfc2104>`_
596
597.. [5] `CBOR Object Signing and Encryption (COSE) <https://tools.ietf.org/html/rfc8152>`_
598
599----------------
600
601*Copyright (c) 2020 Arm Limited. All Rights Reserved.*