Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 1 | Abstracting a Chain of Trust |
| 2 | ============================ |
| 3 | |
| 4 | |
| 5 | .. section-numbering:: |
| 6 | :suffix: . |
| 7 | |
| 8 | .. contents:: |
| 9 | |
Dan Handley | 610e7e1 | 2018-03-01 18:44:00 +0000 | [diff] [blame] | 10 | The aim of this document is to describe the authentication framework |
| 11 | implemented in Trusted Firmware-A (TF-A). This framework fulfills the |
| 12 | following requirements: |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 13 | |
| 14 | #. It should be possible for a platform port to specify the Chain of Trust in |
| 15 | terms of certificate hierarchy and the mechanisms used to verify a |
| 16 | particular image/certificate. |
| 17 | |
| 18 | #. The framework should distinguish between: |
| 19 | |
| 20 | - The mechanism used to encode and transport information, e.g. DER encoded |
| 21 | X.509v3 certificates to ferry Subject Public Keys, hashes and non-volatile |
| 22 | counters. |
| 23 | |
| 24 | - The mechanism used to verify the transported information i.e. the |
| 25 | cryptographic libraries. |
| 26 | |
| 27 | The framework has been designed following a modular approach illustrated in the |
| 28 | next diagram: |
| 29 | |
| 30 | :: |
| 31 | |
| 32 | +---------------+---------------+------------+ |
| 33 | | Trusted | Trusted | Trusted | |
| 34 | | Firmware | Firmware | Firmware | |
| 35 | | Generic | IO Framework | Platform | |
| 36 | | Code i.e. | (IO) | Port | |
| 37 | | BL1/BL2 (GEN) | | (PP) | |
| 38 | +---------------+---------------+------------+ |
| 39 | ^ ^ ^ |
| 40 | | | | |
| 41 | v v v |
| 42 | +-----------+ +-----------+ +-----------+ |
| 43 | | | | | | Image | |
| 44 | | Crypto | | Auth | | Parser | |
| 45 | | Module |<->| Module |<->| Module | |
| 46 | | (CM) | | (AM) | | (IPM) | |
| 47 | | | | | | | |
| 48 | +-----------+ +-----------+ +-----------+ |
| 49 | ^ ^ |
| 50 | | | |
| 51 | v v |
| 52 | +----------------+ +-----------------+ |
| 53 | | Cryptographic | | Image Parser | |
| 54 | | Libraries (CL) | | Libraries (IPL) | |
| 55 | +----------------+ +-----------------+ |
| 56 | | | |
| 57 | | | |
| 58 | | | |
| 59 | v v |
| 60 | +-----------------+ |
| 61 | | Misc. Libs e.g. | |
| 62 | | ASN.1 decoder | |
| 63 | | | |
| 64 | +-----------------+ |
| 65 | |
| 66 | DIAGRAM 1. |
| 67 | |
| 68 | This document describes the inner details of the authentication framework and |
| 69 | the abstraction mechanisms available to specify a Chain of Trust. |
| 70 | |
| 71 | Framework design |
| 72 | ---------------- |
| 73 | |
| 74 | This section describes some aspects of the framework design and the rationale |
| 75 | behind them. These aspects are key to verify a Chain of Trust. |
| 76 | |
| 77 | Chain of Trust |
| 78 | ~~~~~~~~~~~~~~ |
| 79 | |
| 80 | A CoT is basically a sequence of authentication images which usually starts with |
| 81 | a root of trust and culminates in a single data image. The following diagram |
| 82 | illustrates how this maps to a CoT for the BL31 image described in the |
| 83 | TBBR-Client specification. |
| 84 | |
| 85 | :: |
| 86 | |
| 87 | +------------------+ +-------------------+ |
| 88 | | ROTPK/ROTPK Hash |------>| Trusted Key | |
| 89 | +------------------+ | Certificate | |
| 90 | | (Auth Image) | |
| 91 | /+-------------------+ |
| 92 | / | |
| 93 | / | |
| 94 | / | |
| 95 | / | |
| 96 | L v |
| 97 | +------------------+ +-------------------+ |
| 98 | | Trusted World |------>| BL31 Key | |
| 99 | | Public Key | | Certificate | |
| 100 | +------------------+ | (Auth Image) | |
| 101 | +-------------------+ |
| 102 | / | |
| 103 | / | |
| 104 | / | |
| 105 | / | |
| 106 | / v |
| 107 | +------------------+ L +-------------------+ |
| 108 | | BL31 Content |------>| BL31 Content | |
| 109 | | Certificate PK | | Certificate | |
| 110 | +------------------+ | (Auth Image) | |
| 111 | +-------------------+ |
| 112 | / | |
| 113 | / | |
| 114 | / | |
| 115 | / | |
| 116 | / v |
| 117 | +------------------+ L +-------------------+ |
| 118 | | BL31 Hash |------>| BL31 Image | |
| 119 | | | | (Data Image) | |
| 120 | +------------------+ | | |
| 121 | +-------------------+ |
| 122 | |
| 123 | DIAGRAM 2. |
| 124 | |
| 125 | The root of trust is usually a public key (ROTPK) that has been burnt in the |
| 126 | platform and cannot be modified. |
| 127 | |
| 128 | Image types |
| 129 | ~~~~~~~~~~~ |
| 130 | |
| 131 | Images in a CoT are categorised as authentication and data images. An |
| 132 | authentication image contains information to authenticate a data image or |
| 133 | another authentication image. A data image is usually a boot loader binary, but |
| 134 | it could be any other data that requires authentication. |
| 135 | |
| 136 | Component responsibilities |
| 137 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 138 | |
| 139 | For every image in a Chain of Trust, the following high level operations are |
| 140 | performed to verify it: |
| 141 | |
| 142 | #. Allocate memory for the image either statically or at runtime. |
| 143 | |
| 144 | #. Identify the image and load it in the allocated memory. |
| 145 | |
| 146 | #. Check the integrity of the image as per its type. |
| 147 | |
| 148 | #. Authenticate the image as per the cryptographic algorithms used. |
| 149 | |
| 150 | #. If the image is an authentication image, extract the information that will |
| 151 | be used to authenticate the next image in the CoT. |
| 152 | |
| 153 | In Diagram 1, each component is responsible for one or more of these operations. |
| 154 | The responsibilities are briefly described below. |
| 155 | |
Dan Handley | 610e7e1 | 2018-03-01 18:44:00 +0000 | [diff] [blame] | 156 | TF-A Generic code and IO framework (GEN/IO) |
| 157 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 158 | |
| 159 | These components are responsible for initiating the authentication process for a |
| 160 | particular image in BL1 or BL2. For each BL image that requires authentication, |
| 161 | the Generic code asks recursively the Authentication module what is the parent |
| 162 | image until either an authenticated image or the ROT is reached. Then the |
| 163 | Generic code calls the IO framewotk to load the image and calls the |
| 164 | Authentication module to authenticate it, following the CoT from ROT to Image. |
| 165 | |
Dan Handley | 610e7e1 | 2018-03-01 18:44:00 +0000 | [diff] [blame] | 166 | TF-A Platform Port (PP) |
| 167 | ^^^^^^^^^^^^^^^^^^^^^^^ |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 168 | |
| 169 | The platform is responsible for: |
| 170 | |
| 171 | #. Specifying the CoT for each image that needs to be authenticated. Details of |
| 172 | how a CoT can be specified by the platform are explained later. The platform |
| 173 | also specifies the authentication methods and the parsing method used for |
| 174 | each image. |
| 175 | |
| 176 | #. Statically allocating memory for each parameter in each image which is |
| 177 | used for verifying the CoT, e.g. memory for public keys, hashes etc. |
| 178 | |
| 179 | #. Providing the ROTPK or a hash of it. |
| 180 | |
| 181 | #. Providing additional information to the IPM to enable it to identify and |
| 182 | extract authentication parameters contained in an image, e.g. if the |
| 183 | parameters are stored as X509v3 extensions, the corresponding OID must be |
| 184 | provided. |
| 185 | |
| 186 | #. Fulfill any other memory requirements of the IPM and the CM (not currently |
| 187 | described in this document). |
| 188 | |
| 189 | #. Export functions to verify an image which uses an authentication method that |
| 190 | cannot be interpreted by the CM, e.g. if an image has to be verified using a |
| 191 | NV counter, then the value of the counter to compare with can only be |
| 192 | provided by the platform. |
| 193 | |
| 194 | #. Export a custom IPM if a proprietary image format is being used (described |
| 195 | later). |
| 196 | |
| 197 | Authentication Module (AM) |
| 198 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 199 | |
| 200 | It is responsible for: |
| 201 | |
| 202 | #. Providing the necessary abstraction mechanisms to describe a CoT. Amongst |
| 203 | other things, the authentication and image parsing methods must be specified |
| 204 | by the PP in the CoT. |
| 205 | |
| 206 | #. Verifying the CoT passed by GEN by utilising functionality exported by the |
| 207 | PP, IPM and CM. |
| 208 | |
| 209 | #. Tracking which images have been verified. In case an image is a part of |
| 210 | multiple CoTs then it should be verified only once e.g. the Trusted World |
| 211 | Key Certificate in the TBBR-Client spec. contains information to verify |
| 212 | SCP\_BL2, BL31, BL32 each of which have a separate CoT. (This |
| 213 | responsibility has not been described in this document but should be |
| 214 | trivial to implement). |
| 215 | |
| 216 | #. Reusing memory meant for a data image to verify authentication images e.g. |
| 217 | in the CoT described in Diagram 2, each certificate can be loaded and |
| 218 | verified in the memory reserved by the platform for the BL31 image. By the |
| 219 | time BL31 (the data image) is loaded, all information to authenticate it |
| 220 | will have been extracted from the parent image i.e. BL31 content |
| 221 | certificate. It is assumed that the size of an authentication image will |
| 222 | never exceed the size of a data image. It should be possible to verify this |
| 223 | at build time using asserts. |
| 224 | |
| 225 | Cryptographic Module (CM) |
| 226 | ^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 227 | |
| 228 | The CM is responsible for providing an API to: |
| 229 | |
| 230 | #. Verify a digital signature. |
| 231 | #. Verify a hash. |
| 232 | |
| 233 | The CM does not include any cryptography related code, but it relies on an |
| 234 | external library to perform the cryptographic operations. A Crypto-Library (CL) |
| 235 | linking the CM and the external library must be implemented. The following |
| 236 | functions must be provided by the CL: |
| 237 | |
| 238 | .. code:: c |
| 239 | |
| 240 | void (*init)(void); |
| 241 | int (*verify_signature)(void *data_ptr, unsigned int data_len, |
| 242 | void *sig_ptr, unsigned int sig_len, |
| 243 | void *sig_alg, unsigned int sig_alg_len, |
| 244 | void *pk_ptr, unsigned int pk_len); |
| 245 | int (*verify_hash)(void *data_ptr, unsigned int data_len, |
| 246 | void *digest_info_ptr, unsigned int digest_info_len); |
| 247 | |
| 248 | These functions are registered in the CM using the macro: |
| 249 | |
| 250 | .. code:: c |
| 251 | |
| 252 | REGISTER_CRYPTO_LIB(_name, _init, _verify_signature, _verify_hash); |
| 253 | |
| 254 | ``_name`` must be a string containing the name of the CL. This name is used for |
| 255 | debugging purposes. |
| 256 | |
| 257 | Image Parser Module (IPM) |
| 258 | ^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 259 | |
| 260 | The IPM is responsible for: |
| 261 | |
| 262 | #. Checking the integrity of each image loaded by the IO framework. |
| 263 | #. Extracting parameters used for authenticating an image based upon a |
| 264 | description provided by the platform in the CoT descriptor. |
| 265 | |
| 266 | Images may have different formats (for example, authentication images could be |
| 267 | x509v3 certificates, signed ELF files or any other platform specific format). |
| 268 | The IPM allows to register an Image Parser Library (IPL) for every image format |
| 269 | used in the CoT. This library must implement the specific methods to parse the |
| 270 | image. The IPM obtains the image format from the CoT and calls the right IPL to |
| 271 | check the image integrity and extract the authentication parameters. |
| 272 | |
| 273 | See Section "Describing the image parsing methods" for more details about the |
| 274 | mechanism the IPM provides to define and register IPLs. |
| 275 | |
| 276 | Authentication methods |
| 277 | ~~~~~~~~~~~~~~~~~~~~~~ |
| 278 | |
| 279 | The AM supports the following authentication methods: |
| 280 | |
| 281 | #. Hash |
| 282 | #. Digital signature |
| 283 | |
| 284 | The platform may specify these methods in the CoT in case it decides to define |
| 285 | a custom CoT instead of reusing a predefined one. |
| 286 | |
| 287 | If a data image uses multiple methods, then all the methods must be a part of |
| 288 | the same CoT. The number and type of parameters are method specific. These |
| 289 | parameters should be obtained from the parent image using the IPM. |
| 290 | |
| 291 | #. Hash |
| 292 | |
| 293 | Parameters: |
| 294 | |
| 295 | #. A pointer to data to hash |
| 296 | #. Length of the data |
| 297 | #. A pointer to the hash |
| 298 | #. Length of the hash |
| 299 | |
| 300 | The hash will be represented by the DER encoding of the following ASN.1 |
| 301 | type: |
| 302 | |
| 303 | :: |
| 304 | |
| 305 | DigestInfo ::= SEQUENCE { |
| 306 | digestAlgorithm DigestAlgorithmIdentifier, |
| 307 | digest Digest |
| 308 | } |
| 309 | |
| 310 | This ASN.1 structure makes it possible to remove any assumption about the |
| 311 | type of hash algorithm used as this information accompanies the hash. This |
| 312 | should allow the Cryptography Library (CL) to support multiple hash |
| 313 | algorithm implementations. |
| 314 | |
| 315 | #. Digital Signature |
| 316 | |
| 317 | Parameters: |
| 318 | |
| 319 | #. A pointer to data to sign |
| 320 | #. Length of the data |
| 321 | #. Public Key Algorithm |
| 322 | #. Public Key value |
| 323 | #. Digital Signature Algorithm |
| 324 | #. Digital Signature value |
| 325 | |
| 326 | The Public Key parameters will be represented by the DER encoding of the |
| 327 | following ASN.1 type: |
| 328 | |
| 329 | :: |
| 330 | |
| 331 | SubjectPublicKeyInfo ::= SEQUENCE { |
| 332 | algorithm AlgorithmIdentifier{PUBLIC-KEY,{PublicKeyAlgorithms}}, |
| 333 | subjectPublicKey BIT STRING } |
| 334 | |
| 335 | The Digital Signature Algorithm will be represented by the DER encoding of |
| 336 | the following ASN.1 types. |
| 337 | |
| 338 | :: |
| 339 | |
| 340 | AlgorithmIdentifier {ALGORITHM:IOSet } ::= SEQUENCE { |
| 341 | algorithm ALGORITHM.&id({IOSet}), |
| 342 | parameters ALGORITHM.&Type({IOSet}{@algorithm}) OPTIONAL |
| 343 | } |
| 344 | |
| 345 | The digital signature will be represented by: |
| 346 | |
| 347 | :: |
| 348 | |
| 349 | signature ::= BIT STRING |
| 350 | |
| 351 | The authentication framework will use the image descriptor to extract all the |
| 352 | information related to authentication. |
| 353 | |
| 354 | Specifying a Chain of Trust |
| 355 | --------------------------- |
| 356 | |
| 357 | A CoT can be described as a set of image descriptors linked together in a |
| 358 | particular order. The order dictates the sequence in which they must be |
| 359 | verified. Each image has a set of properties which allow the AM to verify it. |
| 360 | These properties are described below. |
| 361 | |
| 362 | The PP is responsible for defining a single or multiple CoTs for a data image. |
| 363 | Unless otherwise specified, the data structures described in the following |
| 364 | sections are populated by the PP statically. |
| 365 | |
| 366 | Describing the image parsing methods |
| 367 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 368 | |
| 369 | The parsing method refers to the format of a particular image. For example, an |
| 370 | authentication image that represents a certificate could be in the X.509v3 |
| 371 | format. A data image that represents a boot loader stage could be in raw binary |
| 372 | or ELF format. The IPM supports three parsing methods. An image has to use one |
| 373 | of the three methods described below. An IPL is responsible for interpreting a |
| 374 | single parsing method. There has to be one IPL for every method used by the |
| 375 | platform. |
| 376 | |
| 377 | #. Raw format: This format is effectively a nop as an image using this method |
Dan Handley | 610e7e1 | 2018-03-01 18:44:00 +0000 | [diff] [blame] | 378 | is treated as being in raw binary format e.g. boot loader images used by |
| 379 | TF-A. This method should only be used by data images. |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 380 | |
| 381 | #. X509V3 method: This method uses industry standards like X.509 to represent |
| 382 | PKI certificates (authentication images). It is expected that open source |
| 383 | libraries will be available which can be used to parse an image represented |
| 384 | by this method. Such libraries can be used to write the corresponding IPL |
| 385 | e.g. the X.509 parsing library code in mbed TLS. |
| 386 | |
| 387 | #. Platform defined method: This method caters for platform specific |
| 388 | proprietary standards to represent authentication or data images. For |
| 389 | example, The signature of a data image could be appended to the data image |
| 390 | raw binary. A header could be prepended to the combined blob to specify the |
| 391 | extents of each component. The platform will have to implement the |
| 392 | corresponding IPL to interpret such a format. |
| 393 | |
| 394 | The following enum can be used to define these three methods. |
| 395 | |
| 396 | .. code:: c |
| 397 | |
| 398 | typedef enum img_type_enum { |
| 399 | IMG_RAW, /* Binary image */ |
| 400 | IMG_PLAT, /* Platform specific format */ |
| 401 | IMG_CERT, /* X509v3 certificate */ |
| 402 | IMG_MAX_TYPES, |
| 403 | } img_type_t; |
| 404 | |
| 405 | An IPL must provide functions with the following prototypes: |
| 406 | |
| 407 | .. code:: c |
| 408 | |
| 409 | void init(void); |
| 410 | int check_integrity(void *img, unsigned int img_len); |
| 411 | int get_auth_param(const auth_param_type_desc_t *type_desc, |
| 412 | void *img, unsigned int img_len, |
| 413 | void **param, unsigned int *param_len); |
| 414 | |
| 415 | An IPL for each type must be registered using the following macro: |
| 416 | |
| 417 | :: |
| 418 | |
| 419 | REGISTER_IMG_PARSER_LIB(_type, _name, _init, _check_int, _get_param) |
| 420 | |
| 421 | - ``_type``: one of the types described above. |
| 422 | - ``_name``: a string containing the IPL name for debugging purposes. |
| 423 | - ``_init``: initialization function pointer. |
| 424 | - ``_check_int``: check image integrity function pointer. |
| 425 | - ``_get_param``: extract authentication parameter funcion pointer. |
| 426 | |
| 427 | The ``init()`` function will be used to initialize the IPL. |
| 428 | |
| 429 | The ``check_integrity()`` function is passed a pointer to the memory where the |
| 430 | image has been loaded by the IO framework and the image length. It should ensure |
| 431 | that the image is in the format corresponding to the parsing method and has not |
| 432 | been tampered with. For example, RFC-2459 describes a validation sequence for an |
| 433 | X.509 certificate. |
| 434 | |
| 435 | The ``get_auth_param()`` function is passed a parameter descriptor containing |
| 436 | information about the parameter (``type_desc`` and ``cookie``) to identify and |
| 437 | extract the data corresponding to that parameter from an image. This data will |
| 438 | be used to verify either the current or the next image in the CoT sequence. |
| 439 | |
| 440 | Each image in the CoT will specify the parsing method it uses. This information |
| 441 | will be used by the IPM to find the right parser descriptor for the image. |
| 442 | |
| 443 | Describing the authentication method(s) |
| 444 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 445 | |
| 446 | As part of the CoT, each image has to specify one or more authentication methods |
| 447 | which will be used to verify it. As described in the Section "Authentication |
| 448 | methods", there are three methods supported by the AM. |
| 449 | |
| 450 | .. code:: c |
| 451 | |
| 452 | typedef enum { |
| 453 | AUTH_METHOD_NONE, |
| 454 | AUTH_METHOD_HASH, |
| 455 | AUTH_METHOD_SIG, |
| 456 | AUTH_METHOD_NUM |
| 457 | } auth_method_type_t; |
| 458 | |
| 459 | The AM defines the type of each parameter used by an authentication method. It |
| 460 | uses this information to: |
| 461 | |
| 462 | #. Specify to the ``get_auth_param()`` function exported by the IPM, which |
| 463 | parameter should be extracted from an image. |
| 464 | |
| 465 | #. Correctly marshall the parameters while calling the verification function |
| 466 | exported by the CM and PP. |
| 467 | |
| 468 | #. Extract authentication parameters from a parent image in order to verify a |
| 469 | child image e.g. to verify the certificate image, the public key has to be |
| 470 | obtained from the parent image. |
| 471 | |
| 472 | .. code:: c |
| 473 | |
| 474 | typedef enum { |
| 475 | AUTH_PARAM_NONE, |
| 476 | AUTH_PARAM_RAW_DATA, /* Raw image data */ |
| 477 | AUTH_PARAM_SIG, /* The image signature */ |
| 478 | AUTH_PARAM_SIG_ALG, /* The image signature algorithm */ |
| 479 | AUTH_PARAM_HASH, /* A hash (including the algorithm) */ |
| 480 | AUTH_PARAM_PUB_KEY, /* A public key */ |
| 481 | } auth_param_type_t; |
| 482 | |
| 483 | The AM defines the following structure to identify an authentication parameter |
| 484 | required to verify an image. |
| 485 | |
| 486 | .. code:: c |
| 487 | |
| 488 | typedef struct auth_param_type_desc_s { |
| 489 | auth_param_type_t type; |
| 490 | void *cookie; |
| 491 | } auth_param_type_desc_t; |
| 492 | |
| 493 | ``cookie`` is used by the platform to specify additional information to the IPM |
| 494 | which enables it to uniquely identify the parameter that should be extracted |
| 495 | from an image. For example, the hash of a BL3x image in its corresponding |
| 496 | content certificate is stored in an X509v3 custom extension field. An extension |
| 497 | field can only be identified using an OID. In this case, the ``cookie`` could |
| 498 | contain the pointer to the OID defined by the platform for the hash extension |
| 499 | field while the ``type`` field could be set to ``AUTH_PARAM_HASH``. A value of 0 for |
| 500 | the ``cookie`` field means that it is not used. |
| 501 | |
| 502 | For each method, the AM defines a structure with the parameters required to |
| 503 | verify the image. |
| 504 | |
| 505 | .. code:: c |
| 506 | |
| 507 | /* |
| 508 | * Parameters for authentication by hash matching |
| 509 | */ |
| 510 | typedef struct auth_method_param_hash_s { |
| 511 | auth_param_type_desc_t *data; /* Data to hash */ |
| 512 | auth_param_type_desc_t *hash; /* Hash to match with */ |
| 513 | } auth_method_param_hash_t; |
| 514 | |
| 515 | /* |
| 516 | * Parameters for authentication by signature |
| 517 | */ |
| 518 | typedef struct auth_method_param_sig_s { |
| 519 | auth_param_type_desc_t *pk; /* Public key */ |
| 520 | auth_param_type_desc_t *sig; /* Signature to check */ |
| 521 | auth_param_type_desc_t *alg; /* Signature algorithm */ |
| 522 | auth_param_type_desc_t *tbs; /* Data signed */ |
| 523 | } auth_method_param_sig_t; |
| 524 | |
| 525 | The AM defines the following structure to describe an authentication method for |
| 526 | verifying an image |
| 527 | |
| 528 | .. code:: c |
| 529 | |
| 530 | /* |
| 531 | * Authentication method descriptor |
| 532 | */ |
| 533 | typedef struct auth_method_desc_s { |
| 534 | auth_method_type_t type; |
| 535 | union { |
| 536 | auth_method_param_hash_t hash; |
| 537 | auth_method_param_sig_t sig; |
| 538 | } param; |
| 539 | } auth_method_desc_t; |
| 540 | |
| 541 | Using the method type specified in the ``type`` field, the AM finds out what field |
| 542 | needs to access within the ``param`` union. |
| 543 | |
| 544 | Storing Authentication parameters |
| 545 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 546 | |
| 547 | A parameter described by ``auth_param_type_desc_t`` to verify an image could be |
| 548 | obtained from either the image itself or its parent image. The memory allocated |
| 549 | for loading the parent image will be reused for loading the child image. Hence |
| 550 | parameters which are obtained from the parent for verifying a child image need |
| 551 | to have memory allocated for them separately where they can be stored. This |
| 552 | memory must be statically allocated by the platform port. |
| 553 | |
| 554 | The AM defines the following structure to store the data corresponding to an |
| 555 | authentication parameter. |
| 556 | |
| 557 | .. code:: c |
| 558 | |
| 559 | typedef struct auth_param_data_desc_s { |
| 560 | void *auth_param_ptr; |
| 561 | unsigned int auth_param_len; |
| 562 | } auth_param_data_desc_t; |
| 563 | |
| 564 | The ``auth_param_ptr`` field is initialized by the platform. The ``auth_param_len`` |
| 565 | field is used to specify the length of the data in the memory. |
| 566 | |
| 567 | For parameters that can be obtained from the child image itself, the IPM is |
| 568 | responsible for populating the ``auth_param_ptr`` and ``auth_param_len`` fields |
| 569 | while executing the ``img_get_auth_param()`` function. |
| 570 | |
| 571 | The AM defines the following structure to enable an image to describe the |
| 572 | parameters that should be extracted from it and used to verify the next image |
| 573 | (child) in a CoT. |
| 574 | |
| 575 | .. code:: c |
| 576 | |
| 577 | typedef struct auth_param_desc_s { |
| 578 | auth_param_type_desc_t type_desc; |
| 579 | auth_param_data_desc_t data; |
| 580 | } auth_param_desc_t; |
| 581 | |
| 582 | Describing an image in a CoT |
| 583 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 584 | |
| 585 | An image in a CoT is a consolidation of the following aspects of a CoT described |
| 586 | above. |
| 587 | |
| 588 | #. A unique identifier specified by the platform which allows the IO framework |
| 589 | to locate the image in a FIP and load it in the memory reserved for the data |
| 590 | image in the CoT. |
| 591 | |
| 592 | #. A parsing method which is used by the AM to find the appropriate IPM. |
| 593 | |
| 594 | #. Authentication methods and their parameters as described in the previous |
| 595 | section. These are used to verify the current image. |
| 596 | |
| 597 | #. Parameters which are used to verify the next image in the current CoT. These |
| 598 | parameters are specified only by authentication images and can be extracted |
| 599 | from the current image once it has been verified. |
| 600 | |
| 601 | The following data structure describes an image in a CoT. |
| 602 | |
| 603 | .. code:: c |
| 604 | |
| 605 | typedef struct auth_img_desc_s { |
| 606 | unsigned int img_id; |
| 607 | const struct auth_img_desc_s *parent; |
| 608 | img_type_t img_type; |
| 609 | auth_method_desc_t img_auth_methods[AUTH_METHOD_NUM]; |
| 610 | auth_param_desc_t authenticated_data[COT_MAX_VERIFIED_PARAMS]; |
| 611 | } auth_img_desc_t; |
| 612 | |
| 613 | A CoT is defined as an array of ``auth_image_desc_t`` structures linked together |
| 614 | by the ``parent`` field. Those nodes with no parent must be authenticated using |
| 615 | the ROTPK stored in the platform. |
| 616 | |
| 617 | Implementation example |
| 618 | ---------------------- |
| 619 | |
| 620 | This section is a detailed guide explaining a trusted boot implementation using |
| 621 | the authentication framework. This example corresponds to the Applicative |
| 622 | Functional Mode (AFM) as specified in the TBBR-Client document. It is |
| 623 | recommended to read this guide along with the source code. |
| 624 | |
| 625 | The TBBR CoT |
| 626 | ~~~~~~~~~~~~ |
| 627 | |
| 628 | The CoT can be found in ``drivers/auth/tbbr/tbbr_cot.c``. This CoT consists of an |
| 629 | array of image descriptors and it is registered in the framework using the macro |
| 630 | ``REGISTER_COT(cot_desc)``, where 'cot\_desc' must be the name of the array |
| 631 | (passing a pointer or any other type of indirection will cause the registration |
| 632 | process to fail). |
| 633 | |
| 634 | The number of images participating in the boot process depends on the CoT. There |
Dan Handley | 610e7e1 | 2018-03-01 18:44:00 +0000 | [diff] [blame] | 635 | is, however, a minimum set of images that are mandatory in TF-A and thus all |
| 636 | CoTs must present: |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 637 | |
| 638 | - ``BL2`` |
| 639 | - ``SCP_BL2`` (platform specific) |
| 640 | - ``BL31`` |
| 641 | - ``BL32`` (optional) |
| 642 | - ``BL33`` |
| 643 | |
| 644 | The TBBR specifies the additional certificates that must accompany these images |
| 645 | for a proper authentication. Details about the TBBR CoT may be found in the |
| 646 | `Trusted Board Boot`_ document. |
| 647 | |
| 648 | Following the `Platform Porting Guide`_, a platform must provide unique |
| 649 | identifiers for all the images and certificates that will be loaded during the |
| 650 | boot process. If a platform is using the TBBR as a reference for trusted boot, |
| 651 | these identifiers can be obtained from ``include/common/tbbr/tbbr_img_def.h``. |
Dan Handley | 610e7e1 | 2018-03-01 18:44:00 +0000 | [diff] [blame] | 652 | Arm platforms include this file in ``include/plat/arm/common/arm_def.h``. Other |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 653 | platforms may also include this file or provide their own identifiers. |
| 654 | |
| 655 | **Important**: the authentication module uses these identifiers to index the |
| 656 | CoT array, so the descriptors location in the array must match the identifiers. |
| 657 | |
| 658 | Each image descriptor must specify: |
| 659 | |
| 660 | - ``img_id``: the corresponding image unique identifier defined by the platform. |
| 661 | - ``img_type``: the image parser module uses the image type to call the proper |
| 662 | parsing library to check the image integrity and extract the required |
| 663 | authentication parameters. Three types of images are currently supported: |
| 664 | |
| 665 | - ``IMG_RAW``: image is a raw binary. No parsing functions are available, |
| 666 | other than reading the whole image. |
| 667 | - ``IMG_PLAT``: image format is platform specific. The platform may use this |
| 668 | type for custom images not directly supported by the authentication |
| 669 | framework. |
| 670 | - ``IMG_CERT``: image is an x509v3 certificate. |
| 671 | |
| 672 | - ``parent``: pointer to the parent image descriptor. The parent will contain |
| 673 | the information required to authenticate the current image. If the parent |
| 674 | is NULL, the authentication parameters will be obtained from the platform |
| 675 | (i.e. the BL2 and Trusted Key certificates are signed with the ROT private |
| 676 | key, whose public part is stored in the platform). |
| 677 | - ``img_auth_methods``: this array defines the authentication methods that must |
| 678 | be checked to consider an image authenticated. Each method consists of a |
| 679 | type and a list of parameter descriptors. A parameter descriptor consists of |
| 680 | a type and a cookie which will point to specific information required to |
| 681 | extract that parameter from the image (i.e. if the parameter is stored in an |
| 682 | x509v3 extension, the cookie will point to the extension OID). Depending on |
| 683 | the method type, a different number of parameters must be specified. |
| 684 | Supported methods are: |
| 685 | |
| 686 | - ``AUTH_METHOD_HASH``: the hash of the image must match the hash extracted |
| 687 | from the parent image. The following parameter descriptors must be |
| 688 | specified: |
| 689 | |
| 690 | - ``data``: data to be hashed (obtained from current image) |
| 691 | - ``hash``: reference hash (obtained from parent image) |
| 692 | |
| 693 | - ``AUTH_METHOD_SIG``: the image (usually a certificate) must be signed with |
| 694 | the private key whose public part is extracted from the parent image (or |
| 695 | the platform if the parent is NULL). The following parameter descriptors |
| 696 | must be specified: |
| 697 | |
| 698 | - ``pk``: the public key (obtained from parent image) |
| 699 | - ``sig``: the digital signature (obtained from current image) |
| 700 | - ``alg``: the signature algorithm used (obtained from current image) |
| 701 | - ``data``: the data to be signed (obtained from current image) |
| 702 | |
| 703 | - ``authenticated_data``: this array indicates what authentication parameters |
| 704 | must be extracted from an image once it has been authenticated. Each |
| 705 | parameter consists of a parameter descriptor and the buffer address/size |
| 706 | to store the parameter. The CoT is responsible for allocating the required |
| 707 | memory to store the parameters. |
| 708 | |
| 709 | In the ``tbbr_cot.c`` file, a set of buffers are allocated to store the parameters |
| 710 | extracted from the certificates. In the case of the TBBR CoT, these parameters |
| 711 | are hashes and public keys. In DER format, an RSA-2048 public key requires 294 |
| 712 | bytes, and a hash requires 51 bytes. Depending on the CoT and the authentication |
| 713 | process, some of the buffers may be reused at different stages during the boot. |
| 714 | |
| 715 | Next in that file, the parameter descriptors are defined. These descriptors will |
| 716 | be used to extract the parameter data from the corresponding image. |
| 717 | |
| 718 | Example: the BL31 Chain of Trust |
| 719 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 720 | |
| 721 | Four image descriptors form the BL31 Chain of Trust: |
| 722 | |
| 723 | .. code:: asm |
| 724 | |
| 725 | [TRUSTED_KEY_CERT_ID] = { |
| 726 | .img_id = TRUSTED_KEY_CERT_ID, |
| 727 | .img_type = IMG_CERT, |
| 728 | .parent = NULL, |
| 729 | .img_auth_methods = { |
| 730 | [0] = { |
| 731 | .type = AUTH_METHOD_SIG, |
| 732 | .param.sig = { |
| 733 | .pk = &subject_pk, |
| 734 | .sig = &sig, |
| 735 | .alg = &sig_alg, |
| 736 | .data = &raw_data, |
| 737 | } |
| 738 | } |
| 739 | }, |
| 740 | .authenticated_data = { |
| 741 | [0] = { |
| 742 | .type_desc = &trusted_world_pk, |
| 743 | .data = { |
| 744 | .ptr = (void *)trusted_world_pk_buf, |
| 745 | .len = (unsigned int)PK_DER_LEN |
| 746 | } |
| 747 | }, |
| 748 | [1] = { |
| 749 | .type_desc = &non_trusted_world_pk, |
| 750 | .data = { |
| 751 | .ptr = (void *)non_trusted_world_pk_buf, |
| 752 | .len = (unsigned int)PK_DER_LEN |
| 753 | } |
| 754 | } |
| 755 | } |
| 756 | }, |
| 757 | [SOC_FW_KEY_CERT_ID] = { |
| 758 | .img_id = SOC_FW_KEY_CERT_ID, |
| 759 | .img_type = IMG_CERT, |
| 760 | .parent = &cot_desc[TRUSTED_KEY_CERT_ID], |
| 761 | .img_auth_methods = { |
| 762 | [0] = { |
| 763 | .type = AUTH_METHOD_SIG, |
| 764 | .param.sig = { |
| 765 | .pk = &trusted_world_pk, |
| 766 | .sig = &sig, |
| 767 | .alg = &sig_alg, |
| 768 | .data = &raw_data, |
| 769 | } |
| 770 | } |
| 771 | }, |
| 772 | .authenticated_data = { |
| 773 | [0] = { |
| 774 | .type_desc = &soc_fw_content_pk, |
| 775 | .data = { |
| 776 | .ptr = (void *)content_pk_buf, |
| 777 | .len = (unsigned int)PK_DER_LEN |
| 778 | } |
| 779 | } |
| 780 | } |
| 781 | }, |
| 782 | [SOC_FW_CONTENT_CERT_ID] = { |
| 783 | .img_id = SOC_FW_CONTENT_CERT_ID, |
| 784 | .img_type = IMG_CERT, |
| 785 | .parent = &cot_desc[SOC_FW_KEY_CERT_ID], |
| 786 | .img_auth_methods = { |
| 787 | [0] = { |
| 788 | .type = AUTH_METHOD_SIG, |
| 789 | .param.sig = { |
| 790 | .pk = &soc_fw_content_pk, |
| 791 | .sig = &sig, |
| 792 | .alg = &sig_alg, |
| 793 | .data = &raw_data, |
| 794 | } |
| 795 | } |
| 796 | }, |
| 797 | .authenticated_data = { |
| 798 | [0] = { |
| 799 | .type_desc = &soc_fw_hash, |
| 800 | .data = { |
| 801 | .ptr = (void *)soc_fw_hash_buf, |
| 802 | .len = (unsigned int)HASH_DER_LEN |
| 803 | } |
| 804 | } |
| 805 | } |
| 806 | }, |
| 807 | [BL31_IMAGE_ID] = { |
| 808 | .img_id = BL31_IMAGE_ID, |
| 809 | .img_type = IMG_RAW, |
| 810 | .parent = &cot_desc[SOC_FW_CONTENT_CERT_ID], |
| 811 | .img_auth_methods = { |
| 812 | [0] = { |
| 813 | .type = AUTH_METHOD_HASH, |
| 814 | .param.hash = { |
| 815 | .data = &raw_data, |
| 816 | .hash = &soc_fw_hash, |
| 817 | } |
| 818 | } |
| 819 | } |
| 820 | } |
| 821 | |
| 822 | The **Trusted Key certificate** is signed with the ROT private key and contains |
| 823 | the Trusted World public key and the Non-Trusted World public key as x509v3 |
| 824 | extensions. This must be specified in the image descriptor using the |
| 825 | ``img_auth_methods`` and ``authenticated_data`` arrays, respectively. |
| 826 | |
| 827 | The Trusted Key certificate is authenticated by checking its digital signature |
| 828 | using the ROTPK. Four parameters are required to check a signature: the public |
| 829 | key, the algorithm, the signature and the data that has been signed. Therefore, |
| 830 | four parameter descriptors must be specified with the authentication method: |
| 831 | |
| 832 | - ``subject_pk``: parameter descriptor of type ``AUTH_PARAM_PUB_KEY``. This type |
| 833 | is used to extract a public key from the parent image. If the cookie is an |
| 834 | OID, the key is extracted from the corresponding x509v3 extension. If the |
| 835 | cookie is NULL, the subject public key is retrieved. In this case, because |
| 836 | the parent image is NULL, the public key is obtained from the platform |
| 837 | (this key will be the ROTPK). |
| 838 | - ``sig``: parameter descriptor of type ``AUTH_PARAM_SIG``. It is used to extract |
| 839 | the signature from the certificate. |
| 840 | - ``sig_alg``: parameter descriptor of type ``AUTH_PARAM_SIG``. It is used to |
| 841 | extract the signature algorithm from the certificate. |
| 842 | - ``raw_data``: parameter descriptor of type ``AUTH_PARAM_RAW_DATA``. It is used |
| 843 | to extract the data to be signed from the certificate. |
| 844 | |
| 845 | Once the signature has been checked and the certificate authenticated, the |
| 846 | Trusted World public key needs to be extracted from the certificate. A new entry |
| 847 | is created in the ``authenticated_data`` array for that purpose. In that entry, |
| 848 | the corresponding parameter descriptor must be specified along with the buffer |
| 849 | address to store the parameter value. In this case, the ``tz_world_pk`` descriptor |
| 850 | is used to extract the public key from an x509v3 extension with OID |
| 851 | ``TRUSTED_WORLD_PK_OID``. The BL31 key certificate will use this descriptor as |
| 852 | parameter in the signature authentication method. The key is stored in the |
| 853 | ``plat_tz_world_pk_buf`` buffer. |
| 854 | |
| 855 | The **BL31 Key certificate** is authenticated by checking its digital signature |
| 856 | using the Trusted World public key obtained previously from the Trusted Key |
| 857 | certificate. In the image descriptor, we specify a single authentication method |
| 858 | by signature whose public key is the ``tz_world_pk``. Once this certificate has |
| 859 | been authenticated, we have to extract the BL31 public key, stored in the |
| 860 | extension specified by ``bl31_content_pk``. This key will be copied to the |
| 861 | ``plat_content_pk`` buffer. |
| 862 | |
| 863 | The **BL31 certificate** is authenticated by checking its digital signature |
| 864 | using the BL31 public key obtained previously from the BL31 Key certificate. |
| 865 | We specify the authentication method using ``bl31_content_pk`` as public key. |
| 866 | After authentication, we need to extract the BL31 hash, stored in the extension |
| 867 | specified by ``bl31_hash``. This hash will be copied to the ``plat_bl31_hash_buf`` |
| 868 | buffer. |
| 869 | |
| 870 | The **BL31 image** is authenticated by calculating its hash and matching it |
| 871 | with the hash obtained from the BL31 certificate. The image descriptor contains |
| 872 | a single authentication method by hash. The parameters to the hash method are |
| 873 | the reference hash, ``bl31_hash``, and the data to be hashed. In this case, it is |
| 874 | the whole image, so we specify ``raw_data``. |
| 875 | |
| 876 | The image parser library |
| 877 | ~~~~~~~~~~~~~~~~~~~~~~~~ |
| 878 | |
| 879 | The image parser module relies on libraries to check the image integrity and |
| 880 | extract the authentication parameters. The number and type of parser libraries |
| 881 | depend on the images used in the CoT. Raw images do not need a library, so |
| 882 | only an x509v3 library is required for the TBBR CoT. |
| 883 | |
Dan Handley | 610e7e1 | 2018-03-01 18:44:00 +0000 | [diff] [blame] | 884 | Arm platforms will use an x509v3 library based on mbed TLS. This library may be |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 885 | found in ``drivers/auth/mbedtls/mbedtls_x509_parser.c``. It exports three |
| 886 | functions: |
| 887 | |
| 888 | .. code:: c |
| 889 | |
| 890 | void init(void); |
| 891 | int check_integrity(void *img, unsigned int img_len); |
| 892 | int get_auth_param(const auth_param_type_desc_t *type_desc, |
| 893 | void *img, unsigned int img_len, |
| 894 | void **param, unsigned int *param_len); |
| 895 | |
| 896 | The library is registered in the framework using the macro |
| 897 | ``REGISTER_IMG_PARSER_LIB()``. Each time the image parser module needs to access |
| 898 | an image of type ``IMG_CERT``, it will call the corresponding function exported |
| 899 | in this file. |
| 900 | |
| 901 | The build system must be updated to include the corresponding library and |
Dan Handley | 610e7e1 | 2018-03-01 18:44:00 +0000 | [diff] [blame] | 902 | mbed TLS sources. Arm platforms use the ``arm_common.mk`` file to pull the |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 903 | sources. |
| 904 | |
| 905 | The cryptographic library |
| 906 | ~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 907 | |
| 908 | The cryptographic module relies on a library to perform the required operations, |
Dan Handley | 610e7e1 | 2018-03-01 18:44:00 +0000 | [diff] [blame] | 909 | i.e. verify a hash or a digital signature. Arm platforms will use a library |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 910 | based on mbed TLS, which can be found in |
| 911 | ``drivers/auth/mbedtls/mbedtls_crypto.c``. This library is registered in the |
| 912 | authentication framework using the macro ``REGISTER_CRYPTO_LIB()`` and exports |
| 913 | three functions: |
| 914 | |
| 915 | .. code:: c |
| 916 | |
| 917 | void init(void); |
| 918 | int verify_signature(void *data_ptr, unsigned int data_len, |
| 919 | void *sig_ptr, unsigned int sig_len, |
| 920 | void *sig_alg, unsigned int sig_alg_len, |
| 921 | void *pk_ptr, unsigned int pk_len); |
| 922 | int verify_hash(void *data_ptr, unsigned int data_len, |
| 923 | void *digest_info_ptr, unsigned int digest_info_len); |
| 924 | |
Qixiang Xu | aa05eea | 2017-08-24 15:26:39 +0800 | [diff] [blame] | 925 | The mbedTLS library algorithm support is configured by the |
| 926 | ``TF_MBEDTLS_KEY_ALG`` variable which can take in 3 values: `rsa`, `ecdsa` or |
| 927 | `rsa+ecdsa`. This variable allows the Makefile to include the corresponding |
| 928 | sources in the build for the various algorthms. Setting the variable to |
| 929 | `rsa+ecdsa` enables support for both rsa and ecdsa algorithms in the mbedTLS |
| 930 | library. |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 931 | |
| 932 | Note: If code size is a concern, the build option ``MBEDTLS_SHA256_SMALLER`` can |
| 933 | be defined in the platform Makefile. It will make mbed TLS use an implementation |
| 934 | of SHA-256 with smaller memory footprint (~1.5 KB less) but slower (~30%). |
| 935 | |
| 936 | -------------- |
| 937 | |
Dan Handley | 610e7e1 | 2018-03-01 18:44:00 +0000 | [diff] [blame] | 938 | *Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.* |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 939 | |
| 940 | .. _Trusted Board Boot: ./trusted-board-boot.rst |
| 941 | .. _Platform Porting Guide: ./porting-guide.rst |