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