blob: d68f51f520303e143cce8bb3acca05f19b148d59 [file] [log] [blame]
Raef Coles6b692552022-03-15 13:38:16 +00001#################
2TF-M builtin keys
3#################
4
5:Author: Raef Coles
6:Organization: Arm Limited
7:Contact: raef.coles@arm.com
8
9************
10Introduction
11************
12
Antonio de Angelis01a93bc2023-01-20 11:17:14 +000013When TF-M is integrated on a platform, the platform itself can provide several
14keys for usage which are bound to the device instead of being owned by a
15specific secure partition. When those keys are readable by the secure
16processing environment, the platform must provide a function to load these keys
17in the HAL layer, either loading them from OTP or another platform specific
18location or subsystem. These keys are henceforth referred to as "builtin keys",
19and might include (but are not limited to) the following:
Raef Coles6b692552022-03-15 13:38:16 +000020
Antonio de Angelis01a93bc2023-01-20 11:17:14 +000021 1. The Hardware Unique Key (HUK)
22 2. The Initial Attestation Key (IAK)
Raef Coles6b692552022-03-15 13:38:16 +000023
Antonio de Angelis01a93bc2023-01-20 11:17:14 +000024The ``tfm_builtin_key_loader`` component implements a mechanism to discover
25those keys and make them available to the PSA Crypto APIs for usage. Note that
26if a key is stored in a subsystem which can't be read by the secure
27processing environment, a full opaque driver must be used to be able to use
28those keys through the PSA Crypto APIs. This document focuses only on the case
29where the keys can be read by the SPE and processed by the driver described in
30this document.
31
32In TF-M's legacy solution, the IAK is loaded by the attestation service as a
33volatile key, which requires some key-loading logic to be implemented by that
34partition. The HUK is not loaded in the crypto service, and is instead used by
35an implementation of a TF-M specific KDF algorithm which then loads the key and
36invokes Mbed TLS directly. Both solutions are far from ideal as they require an
37effort to load (and duplicate) the keys per each user, or require a dedicated
38code in TF-M that directly interacts with the HAL layer and invokes functions
39from the crypto library bypassing the PSA Crypto interface. The aim of the
40``tfm_builtin_key_loader`` driver is to provide a uniform interface to use the
41builtin keys available in a platform.
42
43Implementing a driver to deal with builtin keys allows to expand the legacy
44solution for dealing with this type of keys in several ways. For example, it
45avoid the need for partitions to implement dedicated mechanisms for probing the
46HAL layer for builtin keys and load them as volatile. It removes the need to
47have implementation specific call flows for deriving keys from the HUK (as that
48requirement now is fulfilled by the driver itself transparently). It allows
49uniform access to the keys also from the NS world (in any case, subject to the
50policy dictated by the platform). Correctly abstracts away details of the key
51handling mechanism from TF-M partitions into the PSA Crypto core key management
52subsystem.
Raef Coles6b692552022-03-15 13:38:16 +000053
54****************
55PSA builtin keys
56****************
57
58The PSA Cryptographic API provides a mechanism for accessing keys that are
Antonio de Angelis01a93bc2023-01-20 11:17:14 +000059stored in platform-specific locations (often hardware accelerators or OTP). A
60builtin key is assigned a specific key_id, i.e. a handle, which is hardcoded at
61build time and must be selected in the range [MBEDTLS_PSA_KEY_ID_BUILTIN_MIN,
62MBEDLTS_PSA_KEY_ID_BUILTIN_MAX]. A user of the PSA Crypto API can reference
63those keys directly by using these handles. It is up to the platform to specify
64policy restrictions for specific users of the keys, e.g. an NS entity, or a
65secure partition. The PSA Crypto core will then check those policies to grant
66or deny access to the builtin key for that user.
Raef Coles6b692552022-03-15 13:38:16 +000067
Antonio de Angelis01a93bc2023-01-20 11:17:14 +000068******************************
69PSA cryptoprocessor driver API
70******************************
Raef Coles6b692552022-03-15 13:38:16 +000071
Antonio de Angelis01a93bc2023-01-20 11:17:14 +000072The PSA specification allows the PSA Crypto APIs to defer their operation to an
73accelerator driver, through a mechanism described in the PSA cryptoprocessor
74driver interface specification [1]_. This specification defines the concept of
75PSA Crypto core, i.e. "An implementation of the PSA Cryptography API is
76composed of a core and zero or more drivers". The PSA specification also has
77the concept of storage locations for keys, through the type
78``psa_key_location_t``, which is used to access keys that don't have local
79storage [2]_. This is leveraged mainly by opaque drivers mainly that use keys
80for which the key material is not readable by the PSA crypto core layer.
Raef Coles6b692552022-03-15 13:38:16 +000081
Antonio de Angelis01a93bc2023-01-20 11:17:14 +000082TF-M defines a software driver called ``tfm_builtin_key_loader`` that provides
83no acceleration but just defines a dedicated key location defined through the
84``TFM_BUILTIN_KEY_LOADER_KEY_LOCATION`` define. By resorting to the entry points
85provided by this driver, the PSA Crypto core slot management subsystem can
86access keys stored in the underlying platform, validate key usage policies and
87allow PSA Crypto APIs to uniformly access builtin keys using the same call flows
88used with traditional local-storage keys.
Raef Coles6b692552022-03-15 13:38:16 +000089
Antonio de Angelis01a93bc2023-01-20 11:17:14 +000090This is implemented by hooking the entry points defined by the driver into the
91``library/psa_crypto_driver_wrappers.c`` file provided by the PSA Crypto core.
92This is currently done manually but eventually could be just autogenerated by
93parsing a description of the driver entry points in the JSON format. These entry
94points are:
Raef Coles6b692552022-03-15 13:38:16 +000095
Antonio de Angelis01a93bc2023-01-20 11:17:14 +000096 1. ``tfm_builtin_key_loader_init``
97 2. ``tfm_builtin_key_loader_get_key_buffer_size``
98 3. ``tfm_builtin_key_loader_get_builtin_key``
Raef Coles6b692552022-03-15 13:38:16 +000099
Antonio de Angelis01a93bc2023-01-20 11:17:14 +0000100The call flow for the entry points from the driver wrapper layer is as follows:
Raef Coles6b692552022-03-15 13:38:16 +0000101
Antonio de Angelis01a93bc2023-01-20 11:17:14 +0000102 1. During the driver initialisation phase started by the PSA Crypto Core init,
103 the ``tfm_builtin_key_loader_init`` function is called to probe the
104 platform HAL and retrieve the builtin keys. Those keys are described by
105 the types defined in the HAL layer interface header
106 ``tfm_plat_crypto_keys.h``. In particular global tables describing key
107 properties and user policies must be implemented by each platform and are
108 retrieved by the two accessor functions
109 ``tfm_plat_builtin_key_get_desc_table_ptr()`` and
110 ``tfm_plat_builtin_key_get_policy_table_ptr()``. The keys are loaded from
111 the platform in secure RAM in the TF-M Crypto partition with associated
112 metadata. It's worth to note that the keys are loaded through callback
113 functions which the platform lists in the key descriptor table.
114 2. Once the TF-M Crypto service is initialised, at runtime it might receive a
115 request through an API call to use one of the builtin key IDs. Those IDs
116 are described in the ``tfm_builtin_key_ids.h`` header. Platforms can
117 override the default values providing their own header.
118 3. When the PSA Crypto core in the ``psa_get_and_lock_key_slot()`` function
119 checks that the ``key_id`` being requested is in the builtin range region,
120 it probes the platform through the function
121 ``mbedtls_psa_platform_get_builtin_key`` which must be implemented by the
122 TF-M Crypto service library abstraction layer. This function just checks
123 the key descriptor table from the HAL to understand if such ``key_id`` is
124 available in the platform and what are the corresponding ``slot`` and
125 ``lifetime`` values associated to it. The lifetime contains the location of
126 the key, which determines which driver is responsible for dealing with it
127 (for the ``tfm_builtin_key_loader`` driver, that is
128 ``TFM_BUILTIN_KEY_LOADER_KEY_LOCATION``), while the ``slot`` value maps the
129 key to the slot in the driver internal storage.
130 4. At this point, the PSA Crypto core knows that the key exists and is bound
131 to the location associated to the driver. By calling into the driver
132 wrappers layer is then able to retrieve the key attributes stored in the
133 platform for that key ID, and the size required to allocate in its
134 internal slot management system in order to load the key material in the
135 core. This is done by calling ``tfm_builtin_key_loader_get_builtin_key``
136 just with a valid key attributes pointer (and nothing else), to retrieve
137 the attributes. Once the attributes are available, the required size is
138 retrieved through the driver wrapper by calling
139 ``tfm_builtin_key_loader_get_key_buffer_size``.
140 5. At this stage, the slot management subsystem calls again into the driver
141 wrapper layer through ``tfm_builtin_key_loader_get_builtin_key`` with a
142 valid buffer to hold the key material returned by the
143 ``tfm_builtin_key_loader`` driver. When loading the key, the user
144 requiring that key_id is validated by the driver code against the policies
145 defined by the platform. If the policies match, the builtin key material
146 and metadata is loaded and is used like a transparent key available to the
147 PSA Crypto core slot management subsystem.
Raef Coles6b692552022-03-15 13:38:16 +0000148
149*****************
150Technical details
151*****************
152
153------------------------------
154Builtin key IDs and overriding
155------------------------------
156
Antonio de Angelis01a93bc2023-01-20 11:17:14 +0000157TF-M builtin key IDs are defined in
158``interface/include/crypto_keys/tfm_builtin_key_ids.h`` through the enum
159``tfm_key_id_builtin_t``. They are allocated inside the range that PSA
160specifies for the builtin keys, i.e. between ``MBEDTLS_PSA_KEY_ID_BUILTIN_MIN``
161and ``MBEDLTS_PSA_KEY_ID_BUILTIN_MAX``. A platform can specify extra builtin key
162IDs by setting the ``PLATFORM_DEFAULT_CRYPTO_KEYS`` variable to ``OFF``,
163creating the header ``tfm_builtin_key_ids.h``, and specifying new keys and IDs.
Raef Coles6b692552022-03-15 13:38:16 +0000164
165--------------------------
166Builtin key access control
167--------------------------
168
Antonio de Angelis01a93bc2023-01-20 11:17:14 +0000169A builtin key is accessible by all callers since the ``key_id`` associated to it
170is public information. Access to the keys must be mediated, which is done by
171matching the user requesting the ``key_id`` against the policies available for
172that user on that particular key in the policy table. If no policies are
173specified for a specific combination of user and ``key_id``, the usage flags in
174the key attributes will be all set to zeros, meaning the key will be unusable
175for any operation for that particular user.
Raef Coles6b692552022-03-15 13:38:16 +0000176
177------------------------------
178Multi-partition key derivation
179------------------------------
180
181The HUK is used for key derivation by any secure partition or NS caller that
182requires keys that are bound to a particular context. For example, Protected
183Storage derives keys uniquely for each user of the service which are used to
Antonio de Angelis01a93bc2023-01-20 11:17:14 +0000184encrypt user files. In order to provide HUK derivation to every secure
Raef Coles6b692552022-03-15 13:38:16 +0000185partition / NS caller, it must be ensured that no service that utilises HUK
Antonio de Angelis01a93bc2023-01-20 11:17:14 +0000186derivation can derive the same key as another service (simply by using the same
187inputs for the KDF APIs, i.e. accessing the same base key for derivation).
Raef Coles6b692552022-03-15 13:38:16 +0000188
189This is accomplished by deriving a further "platform key" for each builtin key
Antonio de Angelis01a93bc2023-01-20 11:17:14 +0000190that has ``PSA_KEY_USAGE_DERIVE`` set in its attributes. These platform keys
191are derived from the builtin key, using the partition ID as a KDF input, and
192can then be used for safely for further derivations by the user, without risks
193to derive the same keys as other users. This is enforced directly by the
194``tfm_builtin_key_loader`` driver.
Raef Coles6b692552022-03-15 13:38:16 +0000195
196.. Note::
197 If the NS client ID feature is disabled, all NS callers share a partition ID
198 of ``-1``, and therefore will share a platform key and be therefore be able
199 to derive the same keys as other NS callers.
200
201For keys that are not exposed outside the device, this is transparent to the
202service that is using the key derivation, as they have no access to the builtin
203key material and cannot distinguish between keys derived directly from it and
204keys derived from the platform key. For some builtin keys, deriving platform
205keys is not acceptable, as the key is used outside the device (i.e. the IAK
206public key is used to verify attestation tokens) so the actual builtin key is
207used.
208
209The decision has been taken to derive platform keys for any key that can be used
210for key derivation (``PSA_KEY_USAGE_DERIVE``), and not derive platform keys
211otherwise. For builtin keys that do not derive platform keys but are directly
212used, care must be taken with access control where multiple partitions have
Antonio de Angelis01a93bc2023-01-20 11:17:14 +0000213access to the same raw key material.
Raef Coles6b692552022-03-15 13:38:16 +0000214
215---------------------------------
216Mbed TLS transparent builtin keys
217---------------------------------
218
219Mbed TLS does not natively support transparent builtin keys (transparent keys
Antonio de Angelis01a93bc2023-01-20 11:17:14 +0000220are keys where the key material is directly accessible by the PSA Crypto core),
Raef Coles6b692552022-03-15 13:38:16 +0000221so some modifications had to be made. Opaque keyslots have the same basic
Antonio de Angelis01a93bc2023-01-20 11:17:14 +0000222structure as standard transparent key slots, and can be passed to the functions
223usually reserved for transparent keys, though this is a private implementation
224detail of the mbed TLS library and is not specified in the driver interface.
225Therefore, the only modification required currently is to allow keys that have
226the location ``TFM_BUILTIN_KEY_LOADER_KEY_LOCATION`` to be passed to the
227functions that usually accept transparent keys only, i.e. with the location
228``PSA_KEY_LOCATION_LOCAL_STORAGE``. This is due to the fact that the standard
229assumption of the PSA Crypto core is that, if a driver that provides an
230additional location, will also provide dedicated cryptographic mechanisms to act
231on those keys, but this is not the case of the ``tfm_builtin_key_loader``, as it
232just provides a mechanism to load keys (which act as a transparent key with
233local storage, once loaded), but mbed TLS does not support such "transparent
234builtin key" concept.
235
236References
237----------
238
239.. [1] PSA cryptoprocessor driver interface\ https://github.com/Mbed-TLS/mbedtls/blob/development/docs/proposed/psa-driver-interface.md
240.. [2] Definition of psa_key_location_t type in the PSA spec: \ https://armmbed.github.io/mbed-crypto/html/api/keys/lifetimes.html#c.psa_key_location_t
Raef Coles6b692552022-03-15 13:38:16 +0000241
242--------------
243
Antonio de Angelis01a93bc2023-01-20 11:17:14 +0000244*Copyright (c) 2022-2023, Arm Limited. All rights reserved.*