12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022 |
- Authentication Framework & Chain of Trust
- =========================================
- The aim of this document is to describe the authentication framework
- implemented in Trusted Firmware-A (TF-A). This framework fulfills the
- following requirements:
- #. It should be possible for a platform port to specify the Chain of Trust in
- terms of certificate hierarchy and the mechanisms used to verify a
- particular image/certificate.
- #. The framework should distinguish between:
- - The mechanism used to encode and transport information, e.g. DER encoded
- X.509v3 certificates to ferry Subject Public Keys, hashes and non-volatile
- counters.
- - The mechanism used to verify the transported information i.e. the
- cryptographic libraries.
- The framework has been designed following a modular approach illustrated in the
- next diagram:
- ::
- +---------------+---------------+------------+
- | Trusted | Trusted | Trusted |
- | Firmware | Firmware | Firmware |
- | Generic | IO Framework | Platform |
- | Code i.e. | (IO) | Port |
- | BL1/BL2 (GEN) | | (PP) |
- +---------------+---------------+------------+
- ^ ^ ^
- | | |
- v v v
- +-----------+ +-----------+ +-----------+
- | | | | | Image |
- | Crypto | | Auth | | Parser |
- | Module |<->| Module |<->| Module |
- | (CM) | | (AM) | | (IPM) |
- | | | | | |
- +-----------+ +-----------+ +-----------+
- ^ ^
- | |
- v v
- +----------------+ +-----------------+
- | Cryptographic | | Image Parser |
- | Libraries (CL) | | Libraries (IPL) |
- +----------------+ +-----------------+
- | |
- | |
- | |
- v v
- +-----------------+
- | Misc. Libs e.g. |
- | ASN.1 decoder |
- | |
- +-----------------+
- DIAGRAM 1.
- This document describes the inner details of the authentication framework and
- the abstraction mechanisms available to specify a Chain of Trust.
- Framework design
- ----------------
- This section describes some aspects of the framework design and the rationale
- behind them. These aspects are key to verify a Chain of Trust.
- Chain of Trust
- ~~~~~~~~~~~~~~
- A CoT is basically a sequence of authentication images which usually starts with
- a root of trust and culminates in a single data image. The following diagram
- illustrates how this maps to a CoT for the BL31 image described in the
- `TBBR-Client specification`_.
- ::
- +------------------+ +-------------------+
- | ROTPK/ROTPK Hash |------>| Trusted Key |
- +------------------+ | Certificate |
- | (Auth Image) |
- /+-------------------+
- / |
- / |
- / |
- / |
- L v
- +------------------+ +-------------------+
- | Trusted World |------>| BL31 Key |
- | Public Key | | Certificate |
- +------------------+ | (Auth Image) |
- +-------------------+
- / |
- / |
- / |
- / |
- / v
- +------------------+ L +-------------------+
- | BL31 Content |------>| BL31 Content |
- | Certificate PK | | Certificate |
- +------------------+ | (Auth Image) |
- +-------------------+
- / |
- / |
- / |
- / |
- / v
- +------------------+ L +-------------------+
- | BL31 Hash |------>| BL31 Image |
- | | | (Data Image) |
- +------------------+ | |
- +-------------------+
- DIAGRAM 2.
- The root of trust is usually a public key (ROTPK) that has been burnt in the
- platform and cannot be modified.
- Image types
- ~~~~~~~~~~~
- Images in a CoT are categorised as authentication and data images. An
- authentication image contains information to authenticate a data image or
- another authentication image. A data image is usually a boot loader binary, but
- it could be any other data that requires authentication.
- Component responsibilities
- ~~~~~~~~~~~~~~~~~~~~~~~~~~
- For every image in a Chain of Trust, the following high level operations are
- performed to verify it:
- #. Allocate memory for the image either statically or at runtime.
- #. Identify the image and load it in the allocated memory.
- #. Check the integrity of the image as per its type.
- #. Authenticate the image as per the cryptographic algorithms used.
- #. If the image is an authentication image, extract the information that will
- be used to authenticate the next image in the CoT.
- In Diagram 1, each component is responsible for one or more of these operations.
- The responsibilities are briefly described below.
- TF-A Generic code and IO framework (GEN/IO)
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- These components are responsible for initiating the authentication process for a
- particular image in BL1 or BL2. For each BL image that requires authentication,
- the Generic code asks recursively the Authentication module what is the parent
- image until either an authenticated image or the ROT is reached. Then the
- Generic code calls the IO framework to load the image and calls the
- Authentication module to authenticate it, following the CoT from ROT to Image.
- TF-A Platform Port (PP)
- ^^^^^^^^^^^^^^^^^^^^^^^
- The platform is responsible for:
- #. Specifying the CoT for each image that needs to be authenticated. Details of
- how a CoT can be specified by the platform are explained later. The platform
- also specifies the authentication methods and the parsing method used for
- each image.
- #. Statically allocating memory for each parameter in each image which is
- used for verifying the CoT, e.g. memory for public keys, hashes etc.
- #. Providing the ROTPK or a hash of it.
- #. Providing additional information to the IPM to enable it to identify and
- extract authentication parameters contained in an image, e.g. if the
- parameters are stored as X509v3 extensions, the corresponding OID must be
- provided.
- #. Fulfill any other memory requirements of the IPM and the CM (not currently
- described in this document).
- #. Export functions to verify an image which uses an authentication method that
- cannot be interpreted by the CM, e.g. if an image has to be verified using a
- NV counter, then the value of the counter to compare with can only be
- provided by the platform.
- #. Export a custom IPM if a proprietary image format is being used (described
- later).
- Authentication Module (AM)
- ^^^^^^^^^^^^^^^^^^^^^^^^^^
- It is responsible for:
- #. Providing the necessary abstraction mechanisms to describe a CoT. Amongst
- other things, the authentication and image parsing methods must be specified
- by the PP in the CoT.
- #. Verifying the CoT passed by GEN by utilising functionality exported by the
- PP, IPM and CM.
- #. Tracking which images have been verified. In case an image is a part of
- multiple CoTs then it should be verified only once e.g. the Trusted World
- Key Certificate in the TBBR-Client spec. contains information to verify
- SCP_BL2, BL31, BL32 each of which have a separate CoT. (This
- responsibility has not been described in this document but should be
- trivial to implement).
- #. Reusing memory meant for a data image to verify authentication images e.g.
- in the CoT described in Diagram 2, each certificate can be loaded and
- verified in the memory reserved by the platform for the BL31 image. By the
- time BL31 (the data image) is loaded, all information to authenticate it
- will have been extracted from the parent image i.e. BL31 content
- certificate. It is assumed that the size of an authentication image will
- never exceed the size of a data image. It should be possible to verify this
- at build time using asserts.
- Cryptographic Module (CM)
- ^^^^^^^^^^^^^^^^^^^^^^^^^
- The CM is responsible for providing an API to:
- #. Verify a digital signature.
- #. Verify a hash.
- The CM does not include any cryptography related code, but it relies on an
- external library to perform the cryptographic operations. A Crypto-Library (CL)
- linking the CM and the external library must be implemented. The following
- functions must be provided by the CL:
- .. code:: c
- void (*init)(void);
- int (*verify_signature)(void *data_ptr, unsigned int data_len,
- void *sig_ptr, unsigned int sig_len,
- void *sig_alg, unsigned int sig_alg_len,
- void *pk_ptr, unsigned int pk_len);
- int (*calc_hash)(enum crypto_md_algo alg, void *data_ptr,
- unsigned int data_len,
- unsigned char output[CRYPTO_MD_MAX_SIZE])
- int (*verify_hash)(void *data_ptr, unsigned int data_len,
- void *digest_info_ptr, unsigned int digest_info_len);
- int (*auth_decrypt)(enum crypto_dec_algo dec_algo, void *data_ptr,
- size_t len, const void *key, unsigned int key_len,
- unsigned int key_flags, const void *iv,
- unsigned int iv_len, const void *tag,
- unsigned int tag_len);
- These functions are registered in the CM using the macro:
- .. code:: c
- REGISTER_CRYPTO_LIB(_name,
- _init,
- _verify_signature,
- _verify_hash,
- _calc_hash,
- _auth_decrypt,
- _convert_pk);
- ``_name`` must be a string containing the name of the CL. This name is used for
- debugging purposes.
- Crypto module provides a function ``_calc_hash`` to calculate and
- return the hash of the given data using the provided hash algorithm.
- This function is mainly used in the ``MEASURED_BOOT`` and ``DRTM_SUPPORT``
- features to calculate the hashes of various images/data.
- Optionally, a platform function can be provided to convert public key
- (_convert_pk). It is only used if the platform saves a hash of the ROTPK.
- Most platforms save the hash of the ROTPK, but some may save slightly different
- information - e.g the hash of the ROTPK plus some related information.
- Defining this function allows to transform the ROTPK used to verify
- the signature to the buffer (a platform specific public key) which
- hash is saved in OTP.
- .. code:: c
- int (*convert_pk)(void *full_pk_ptr, unsigned int full_pk_len,
- void **hashed_pk_ptr, unsigned int *hashed_pk_len);
- - ``full_pk_ptr``: Pointer to Distinguished Encoding Rules (DER) ROTPK.
- - ``full_pk_len``: DER ROTPK size.
- - ``hashed_pk_ptr``: to return a pointer to a buffer, which hash should be the one saved in OTP.
- - ``hashed_pk_len``: previous buffer size
- Image Parser Module (IPM)
- ^^^^^^^^^^^^^^^^^^^^^^^^^
- The IPM is responsible for:
- #. Checking the integrity of each image loaded by the IO framework.
- #. Extracting parameters used for authenticating an image based upon a
- description provided by the platform in the CoT descriptor.
- Images may have different formats (for example, authentication images could be
- x509v3 certificates, signed ELF files or any other platform specific format).
- The IPM allows to register an Image Parser Library (IPL) for every image format
- used in the CoT. This library must implement the specific methods to parse the
- image. The IPM obtains the image format from the CoT and calls the right IPL to
- check the image integrity and extract the authentication parameters.
- See Section "Describing the image parsing methods" for more details about the
- mechanism the IPM provides to define and register IPLs.
- Authentication methods
- ~~~~~~~~~~~~~~~~~~~~~~
- The AM supports the following authentication methods:
- #. Hash
- #. Digital signature
- The platform may specify these methods in the CoT in case it decides to define
- a custom CoT instead of reusing a predefined one.
- If a data image uses multiple methods, then all the methods must be a part of
- the same CoT. The number and type of parameters are method specific. These
- parameters should be obtained from the parent image using the IPM.
- #. Hash
- Parameters:
- #. A pointer to data to hash
- #. Length of the data
- #. A pointer to the hash
- #. Length of the hash
- The hash will be represented by the DER encoding of the following ASN.1
- type:
- ::
- DigestInfo ::= SEQUENCE {
- digestAlgorithm DigestAlgorithmIdentifier,
- digest Digest
- }
- This ASN.1 structure makes it possible to remove any assumption about the
- type of hash algorithm used as this information accompanies the hash. This
- should allow the Cryptography Library (CL) to support multiple hash
- algorithm implementations.
- #. Digital Signature
- Parameters:
- #. A pointer to data to sign
- #. Length of the data
- #. Public Key Algorithm
- #. Public Key value
- #. Digital Signature Algorithm
- #. Digital Signature value
- The Public Key parameters will be represented by the DER encoding of the
- following ASN.1 type:
- ::
- SubjectPublicKeyInfo ::= SEQUENCE {
- algorithm AlgorithmIdentifier{PUBLIC-KEY,{PublicKeyAlgorithms}},
- subjectPublicKey BIT STRING }
- The Digital Signature Algorithm will be represented by the DER encoding of
- the following ASN.1 types.
- ::
- AlgorithmIdentifier {ALGORITHM:IOSet } ::= SEQUENCE {
- algorithm ALGORITHM.&id({IOSet}),
- parameters ALGORITHM.&Type({IOSet}{@algorithm}) OPTIONAL
- }
- The digital signature will be represented by:
- ::
- signature ::= BIT STRING
- The authentication framework will use the image descriptor to extract all the
- information related to authentication.
- Specifying a Chain of Trust
- ---------------------------
- A CoT can be described as a set of image descriptors linked together in a
- particular order. The order dictates the sequence in which they must be
- verified. Each image has a set of properties which allow the AM to verify it.
- These properties are described below.
- The PP is responsible for defining a single or multiple CoTs for a data image.
- Unless otherwise specified, the data structures described in the following
- sections are populated by the PP statically.
- Describing the image parsing methods
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The parsing method refers to the format of a particular image. For example, an
- authentication image that represents a certificate could be in the X.509v3
- format. A data image that represents a boot loader stage could be in raw binary
- or ELF format. The IPM supports three parsing methods. An image has to use one
- of the three methods described below. An IPL is responsible for interpreting a
- single parsing method. There has to be one IPL for every method used by the
- platform.
- #. Raw format: This format is effectively a nop as an image using this method
- is treated as being in raw binary format e.g. boot loader images used by
- TF-A. This method should only be used by data images.
- #. X509V3 method: This method uses industry standards like X.509 to represent
- PKI certificates (authentication images). It is expected that open source
- libraries will be available which can be used to parse an image represented
- by this method. Such libraries can be used to write the corresponding IPL
- e.g. the X.509 parsing library code in mbed TLS.
- #. Platform defined method: This method caters for platform specific
- proprietary standards to represent authentication or data images. For
- example, The signature of a data image could be appended to the data image
- raw binary. A header could be prepended to the combined blob to specify the
- extents of each component. The platform will have to implement the
- corresponding IPL to interpret such a format.
- The following enum can be used to define these three methods.
- .. code:: c
- typedef enum img_type_enum {
- IMG_RAW, /* Binary image */
- IMG_PLAT, /* Platform specific format */
- IMG_CERT, /* X509v3 certificate */
- IMG_MAX_TYPES,
- } img_type_t;
- An IPL must provide functions with the following prototypes:
- .. code:: c
- void init(void);
- int check_integrity(void *img, unsigned int img_len);
- int get_auth_param(const auth_param_type_desc_t *type_desc,
- void *img, unsigned int img_len,
- void **param, unsigned int *param_len);
- An IPL for each type must be registered using the following macro:
- .. code:: c
- REGISTER_IMG_PARSER_LIB(_type, _name, _init, _check_int, _get_param)
- - ``_type``: one of the types described above.
- - ``_name``: a string containing the IPL name for debugging purposes.
- - ``_init``: initialization function pointer.
- - ``_check_int``: check image integrity function pointer.
- - ``_get_param``: extract authentication parameter function pointer.
- The ``init()`` function will be used to initialize the IPL.
- The ``check_integrity()`` function is passed a pointer to the memory where the
- image has been loaded by the IO framework and the image length. It should ensure
- that the image is in the format corresponding to the parsing method and has not
- been tampered with. For example, RFC-2459 describes a validation sequence for an
- X.509 certificate.
- The ``get_auth_param()`` function is passed a parameter descriptor containing
- information about the parameter (``type_desc`` and ``cookie``) to identify and
- extract the data corresponding to that parameter from an image. This data will
- be used to verify either the current or the next image in the CoT sequence.
- Each image in the CoT will specify the parsing method it uses. This information
- will be used by the IPM to find the right parser descriptor for the image.
- Describing the authentication method(s)
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- As part of the CoT, each image has to specify one or more authentication methods
- which will be used to verify it. As described in the Section "Authentication
- methods", there are three methods supported by the AM.
- .. code:: c
- typedef enum {
- AUTH_METHOD_NONE,
- AUTH_METHOD_HASH,
- AUTH_METHOD_SIG,
- AUTH_METHOD_NUM
- } auth_method_type_t;
- The AM defines the type of each parameter used by an authentication method. It
- uses this information to:
- #. Specify to the ``get_auth_param()`` function exported by the IPM, which
- parameter should be extracted from an image.
- #. Correctly marshall the parameters while calling the verification function
- exported by the CM and PP.
- #. Extract authentication parameters from a parent image in order to verify a
- child image e.g. to verify the certificate image, the public key has to be
- obtained from the parent image.
- .. code:: c
- typedef enum {
- AUTH_PARAM_NONE,
- AUTH_PARAM_RAW_DATA, /* Raw image data */
- AUTH_PARAM_SIG, /* The image signature */
- AUTH_PARAM_SIG_ALG, /* The image signature algorithm */
- AUTH_PARAM_HASH, /* A hash (including the algorithm) */
- AUTH_PARAM_PUB_KEY, /* A public key */
- AUTH_PARAM_NV_CTR, /* A non-volatile counter */
- } auth_param_type_t;
- The AM defines the following structure to identify an authentication parameter
- required to verify an image.
- .. code:: c
- typedef struct auth_param_type_desc_s {
- auth_param_type_t type;
- void *cookie;
- } auth_param_type_desc_t;
- ``cookie`` is used by the platform to specify additional information to the IPM
- which enables it to uniquely identify the parameter that should be extracted
- from an image. For example, the hash of a BL3x image in its corresponding
- content certificate is stored in an X509v3 custom extension field. An extension
- field can only be identified using an OID. In this case, the ``cookie`` could
- contain the pointer to the OID defined by the platform for the hash extension
- field while the ``type`` field could be set to ``AUTH_PARAM_HASH``. A value of 0 for
- the ``cookie`` field means that it is not used.
- For each method, the AM defines a structure with the parameters required to
- verify the image.
- .. code:: c
- /*
- * Parameters for authentication by hash matching
- */
- typedef struct auth_method_param_hash_s {
- auth_param_type_desc_t *data; /* Data to hash */
- auth_param_type_desc_t *hash; /* Hash to match with */
- } auth_method_param_hash_t;
- /*
- * Parameters for authentication by signature
- */
- typedef struct auth_method_param_sig_s {
- auth_param_type_desc_t *pk; /* Public key */
- auth_param_type_desc_t *sig; /* Signature to check */
- auth_param_type_desc_t *alg; /* Signature algorithm */
- auth_param_type_desc_t *tbs; /* Data signed */
- } auth_method_param_sig_t;
- The AM defines the following structure to describe an authentication method for
- verifying an image
- .. code:: c
- /*
- * Authentication method descriptor
- */
- typedef struct auth_method_desc_s {
- auth_method_type_t type;
- union {
- auth_method_param_hash_t hash;
- auth_method_param_sig_t sig;
- } param;
- } auth_method_desc_t;
- Using the method type specified in the ``type`` field, the AM finds out what field
- needs to access within the ``param`` union.
- Storing Authentication parameters
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- A parameter described by ``auth_param_type_desc_t`` to verify an image could be
- obtained from either the image itself or its parent image. The memory allocated
- for loading the parent image will be reused for loading the child image. Hence
- parameters which are obtained from the parent for verifying a child image need
- to have memory allocated for them separately where they can be stored. This
- memory must be statically allocated by the platform port.
- The AM defines the following structure to store the data corresponding to an
- authentication parameter.
- .. code:: c
- typedef struct auth_param_data_desc_s {
- void *auth_param_ptr;
- unsigned int auth_param_len;
- } auth_param_data_desc_t;
- The ``auth_param_ptr`` field is initialized by the platform. The ``auth_param_len``
- field is used to specify the length of the data in the memory.
- For parameters that can be obtained from the child image itself, the IPM is
- responsible for populating the ``auth_param_ptr`` and ``auth_param_len`` fields
- while executing the ``img_get_auth_param()`` function.
- The AM defines the following structure to enable an image to describe the
- parameters that should be extracted from it and used to verify the next image
- (child) in a CoT.
- .. code:: c
- typedef struct auth_param_desc_s {
- auth_param_type_desc_t type_desc;
- auth_param_data_desc_t data;
- } auth_param_desc_t;
- Describing an image in a CoT
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- An image in a CoT is a consolidation of the following aspects of a CoT described
- above.
- #. A unique identifier specified by the platform which allows the IO framework
- to locate the image in a FIP and load it in the memory reserved for the data
- image in the CoT.
- #. A parsing method which is used by the AM to find the appropriate IPM.
- #. Authentication methods and their parameters as described in the previous
- section. These are used to verify the current image.
- #. Parameters which are used to verify the next image in the current CoT. These
- parameters are specified only by authentication images and can be extracted
- from the current image once it has been verified.
- The following data structure describes an image in a CoT.
- .. code:: c
- typedef struct auth_img_desc_s {
- unsigned int img_id;
- const struct auth_img_desc_s *parent;
- img_type_t img_type;
- const auth_method_desc_t *const img_auth_methods;
- const auth_param_desc_t *const authenticated_data;
- } auth_img_desc_t;
- A CoT is defined as an array of pointers to ``auth_image_desc_t`` structures
- linked together by the ``parent`` field. Those nodes with no parent must be
- authenticated using the ROTPK stored in the platform.
- Implementation example
- ----------------------
- This section is a detailed guide explaining a trusted boot implementation using
- the authentication framework. This example corresponds to the Applicative
- Functional Mode (AFM) as specified in the TBBR-Client document. It is
- recommended to read this guide along with the source code.
- The TBBR CoT
- ~~~~~~~~~~~~
- CoT specific to BL1 and BL2 can be found in ``drivers/auth/tbbr/tbbr_cot_bl1.c``
- and ``drivers/auth/tbbr/tbbr_cot_bl2.c`` respectively. The common CoT used across
- BL1 and BL2 can be found in ``drivers/auth/tbbr/tbbr_cot_common.c``.
- This CoT consists of an array of pointers to image descriptors and it is
- registered in the framework using the macro ``REGISTER_COT(cot_desc)``, where
- ``cot_desc`` must be the name of the array (passing a pointer or any other
- type of indirection will cause the registration process to fail).
- The number of images participating in the boot process depends on the CoT.
- There is, however, a minimum set of images that are mandatory in TF-A and thus
- all CoTs must present:
- - ``BL2``
- - ``SCP_BL2`` (platform specific)
- - ``BL31``
- - ``BL32`` (optional)
- - ``BL33``
- The TBBR specifies the additional certificates that must accompany these images
- for a proper authentication. Details about the TBBR CoT may be found in the
- :ref:`Trusted Board Boot` document.
- Following the :ref:`Porting Guide`, a platform must provide unique
- identifiers for all the images and certificates that will be loaded during the
- boot process. If a platform is using the TBBR as a reference for trusted boot,
- these identifiers can be obtained from ``include/common/tbbr/tbbr_img_def.h``.
- Arm platforms include this file in ``include/plat/arm/common/arm_def.h``. Other
- platforms may also include this file or provide their own identifiers.
- **Important**: the authentication module uses these identifiers to index the
- CoT array, so the descriptors location in the array must match the identifiers.
- Each image descriptor must specify:
- - ``img_id``: the corresponding image unique identifier defined by the platform.
- - ``img_type``: the image parser module uses the image type to call the proper
- parsing library to check the image integrity and extract the required
- authentication parameters. Three types of images are currently supported:
- - ``IMG_RAW``: image is a raw binary. No parsing functions are available,
- other than reading the whole image.
- - ``IMG_PLAT``: image format is platform specific. The platform may use this
- type for custom images not directly supported by the authentication
- framework.
- - ``IMG_CERT``: image is an x509v3 certificate.
- - ``parent``: pointer to the parent image descriptor. The parent will contain
- the information required to authenticate the current image. If the parent
- is NULL, the authentication parameters will be obtained from the platform
- (i.e. the BL2 and Trusted Key certificates are signed with the ROT private
- key, whose public part is stored in the platform).
- - ``img_auth_methods``: this points to an array which defines the
- authentication methods that must be checked to consider an image
- authenticated. Each method consists of a type and a list of parameter
- descriptors. A parameter descriptor consists of a type and a cookie which
- will point to specific information required to extract that parameter from
- the image (i.e. if the parameter is stored in an x509v3 extension, the
- cookie will point to the extension OID). Depending on the method type, a
- different number of parameters must be specified. This pointer should not be
- NULL.
- Supported methods are:
- - ``AUTH_METHOD_HASH``: the hash of the image must match the hash extracted
- from the parent image. The following parameter descriptors must be
- specified:
- - ``data``: data to be hashed (obtained from current image)
- - ``hash``: reference hash (obtained from parent image)
- - ``AUTH_METHOD_SIG``: the image (usually a certificate) must be signed with
- the private key whose public part is extracted from the parent image (or
- the platform if the parent is NULL). The following parameter descriptors
- must be specified:
- - ``pk``: the public key (obtained from parent image)
- - ``sig``: the digital signature (obtained from current image)
- - ``alg``: the signature algorithm used (obtained from current image)
- - ``data``: the data to be signed (obtained from current image)
- - ``authenticated_data``: this array pointer indicates what authentication
- parameters must be extracted from an image once it has been authenticated.
- Each parameter consists of a parameter descriptor and the buffer
- address/size to store the parameter. The CoT is responsible for allocating
- the required memory to store the parameters. This pointer may be NULL.
- In the ``tbbr_cot*.c`` file, a set of buffers are allocated to store the parameters
- extracted from the certificates. In the case of the TBBR CoT, these parameters
- are hashes and public keys. In DER format, an RSA-4096 public key requires 550
- bytes, and a hash requires 51 bytes. Depending on the CoT and the authentication
- process, some of the buffers may be reused at different stages during the boot.
- Next in that file, the parameter descriptors are defined. These descriptors will
- be used to extract the parameter data from the corresponding image.
- Example: the BL31 Chain of Trust
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Four image descriptors form the BL31 Chain of Trust:
- .. code:: c
- static const auth_img_desc_t trusted_key_cert = {
- .img_id = TRUSTED_KEY_CERT_ID,
- .img_type = IMG_CERT,
- .parent = NULL,
- .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
- [0] = {
- .type = AUTH_METHOD_SIG,
- .param.sig = {
- .pk = &subject_pk,
- .sig = &sig,
- .alg = &sig_alg,
- .data = &raw_data
- }
- },
- [1] = {
- .type = AUTH_METHOD_NV_CTR,
- .param.nv_ctr = {
- .cert_nv_ctr = &trusted_nv_ctr,
- .plat_nv_ctr = &trusted_nv_ctr
- }
- }
- },
- .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
- [0] = {
- .type_desc = &trusted_world_pk,
- .data = {
- .ptr = (void *)trusted_world_pk_buf,
- .len = (unsigned int)PK_DER_LEN
- }
- },
- [1] = {
- .type_desc = &non_trusted_world_pk,
- .data = {
- .ptr = (void *)non_trusted_world_pk_buf,
- .len = (unsigned int)PK_DER_LEN
- }
- }
- }
- };
- static const auth_img_desc_t soc_fw_key_cert = {
- .img_id = SOC_FW_KEY_CERT_ID,
- .img_type = IMG_CERT,
- .parent = &trusted_key_cert,
- .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
- [0] = {
- .type = AUTH_METHOD_SIG,
- .param.sig = {
- .pk = &trusted_world_pk,
- .sig = &sig,
- .alg = &sig_alg,
- .data = &raw_data
- }
- },
- [1] = {
- .type = AUTH_METHOD_NV_CTR,
- .param.nv_ctr = {
- .cert_nv_ctr = &trusted_nv_ctr,
- .plat_nv_ctr = &trusted_nv_ctr
- }
- }
- },
- .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
- [0] = {
- .type_desc = &soc_fw_content_pk,
- .data = {
- .ptr = (void *)content_pk_buf,
- .len = (unsigned int)PK_DER_LEN
- }
- }
- }
- };
- static const auth_img_desc_t soc_fw_content_cert = {
- .img_id = SOC_FW_CONTENT_CERT_ID,
- .img_type = IMG_CERT,
- .parent = &soc_fw_key_cert,
- .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
- [0] = {
- .type = AUTH_METHOD_SIG,
- .param.sig = {
- .pk = &soc_fw_content_pk,
- .sig = &sig,
- .alg = &sig_alg,
- .data = &raw_data
- }
- },
- [1] = {
- .type = AUTH_METHOD_NV_CTR,
- .param.nv_ctr = {
- .cert_nv_ctr = &trusted_nv_ctr,
- .plat_nv_ctr = &trusted_nv_ctr
- }
- }
- },
- .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
- [0] = {
- .type_desc = &soc_fw_hash,
- .data = {
- .ptr = (void *)soc_fw_hash_buf,
- .len = (unsigned int)HASH_DER_LEN
- }
- },
- [1] = {
- .type_desc = &soc_fw_config_hash,
- .data = {
- .ptr = (void *)soc_fw_config_hash_buf,
- .len = (unsigned int)HASH_DER_LEN
- }
- }
- }
- };
- static const auth_img_desc_t bl31_image = {
- .img_id = BL31_IMAGE_ID,
- .img_type = IMG_RAW,
- .parent = &soc_fw_content_cert,
- .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
- [0] = {
- .type = AUTH_METHOD_HASH,
- .param.hash = {
- .data = &raw_data,
- .hash = &soc_fw_hash
- }
- }
- }
- };
- The **Trusted Key certificate** is signed with the ROT private key and contains
- the Trusted World public key and the Non-Trusted World public key as x509v3
- extensions. This must be specified in the image descriptor using the
- ``img_auth_methods`` and ``authenticated_data`` arrays, respectively.
- The Trusted Key certificate is authenticated by checking its digital signature
- using the ROTPK. Four parameters are required to check a signature: the public
- key, the algorithm, the signature and the data that has been signed. Therefore,
- four parameter descriptors must be specified with the authentication method:
- - ``subject_pk``: parameter descriptor of type ``AUTH_PARAM_PUB_KEY``. This type
- is used to extract a public key from the parent image. If the cookie is an
- OID, the key is extracted from the corresponding x509v3 extension. If the
- cookie is NULL, the subject public key is retrieved. In this case, because
- the parent image is NULL, the public key is obtained from the platform
- (this key will be the ROTPK).
- - ``sig``: parameter descriptor of type ``AUTH_PARAM_SIG``. It is used to extract
- the signature from the certificate.
- - ``sig_alg``: parameter descriptor of type ``AUTH_PARAM_SIG``. It is used to
- extract the signature algorithm from the certificate.
- - ``raw_data``: parameter descriptor of type ``AUTH_PARAM_RAW_DATA``. It is used
- to extract the data to be signed from the certificate.
- Once the signature has been checked and the certificate authenticated, the
- Trusted World public key needs to be extracted from the certificate. A new entry
- is created in the ``authenticated_data`` array for that purpose. In that entry,
- the corresponding parameter descriptor must be specified along with the buffer
- address to store the parameter value. In this case, the ``trusted_world_pk``
- descriptor is used to extract the public key from an x509v3 extension with OID
- ``TRUSTED_WORLD_PK_OID``. The BL31 key certificate will use this descriptor as
- parameter in the signature authentication method. The key is stored in the
- ``trusted_world_pk_buf`` buffer.
- The **BL31 Key certificate** is authenticated by checking its digital signature
- using the Trusted World public key obtained previously from the Trusted Key
- certificate. In the image descriptor, we specify a single authentication method
- by signature whose public key is the ``trusted_world_pk``. Once this certificate
- has been authenticated, we have to extract the BL31 public key, stored in the
- extension specified by ``soc_fw_content_pk``. This key will be copied to the
- ``content_pk_buf`` buffer.
- The **BL31 certificate** is authenticated by checking its digital signature
- using the BL31 public key obtained previously from the BL31 Key certificate.
- We specify the authentication method using ``soc_fw_content_pk`` as public key.
- After authentication, we need to extract the BL31 hash, stored in the extension
- specified by ``soc_fw_hash``. This hash will be copied to the
- ``soc_fw_hash_buf`` buffer.
- The **BL31 image** is authenticated by calculating its hash and matching it
- with the hash obtained from the BL31 certificate. The image descriptor contains
- a single authentication method by hash. The parameters to the hash method are
- the reference hash, ``soc_fw_hash``, and the data to be hashed. In this case,
- it is the whole image, so we specify ``raw_data``.
- The image parser library
- ~~~~~~~~~~~~~~~~~~~~~~~~
- The image parser module relies on libraries to check the image integrity and
- extract the authentication parameters. The number and type of parser libraries
- depend on the images used in the CoT. Raw images do not need a library, so
- only an x509v3 library is required for the TBBR CoT.
- Arm platforms will use an x509v3 library based on mbed TLS. This library may be
- found in ``drivers/auth/mbedtls/mbedtls_x509_parser.c``. It exports three
- functions:
- .. code:: c
- void init(void);
- int check_integrity(void *img, unsigned int img_len);
- int get_auth_param(const auth_param_type_desc_t *type_desc,
- void *img, unsigned int img_len,
- void **param, unsigned int *param_len);
- The library is registered in the framework using the macro
- ``REGISTER_IMG_PARSER_LIB()``. Each time the image parser module needs to access
- an image of type ``IMG_CERT``, it will call the corresponding function exported
- in this file.
- The build system must be updated to include the corresponding library and
- mbed TLS sources. Arm platforms use the ``arm_common.mk`` file to pull the
- sources.
- The cryptographic library
- ~~~~~~~~~~~~~~~~~~~~~~~~~
- The cryptographic module relies on a library to perform the required operations,
- i.e. verify a hash or a digital signature. Arm platforms will use a library
- based on mbed TLS, which can be found in
- ``drivers/auth/mbedtls/mbedtls_crypto.c``. This library is registered in the
- authentication framework using the macro ``REGISTER_CRYPTO_LIB()`` and exports
- below functions:
- .. code:: c
- void init(void);
- int verify_signature(void *data_ptr, unsigned int data_len,
- void *sig_ptr, unsigned int sig_len,
- void *sig_alg, unsigned int sig_alg_len,
- void *pk_ptr, unsigned int pk_len);
- int crypto_mod_calc_hash(enum crypto_md_algo alg, void *data_ptr,
- unsigned int data_len,
- unsigned char output[CRYPTO_MD_MAX_SIZE])
- int verify_hash(void *data_ptr, unsigned int data_len,
- void *digest_info_ptr, unsigned int digest_info_len);
- int auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr,
- size_t len, const void *key, unsigned int key_len,
- unsigned int key_flags, const void *iv,
- unsigned int iv_len, const void *tag,
- unsigned int tag_len)
- The mbedTLS library algorithm support is configured by both the
- ``TF_MBEDTLS_KEY_ALG`` and ``TF_MBEDTLS_KEY_SIZE`` variables.
- - ``TF_MBEDTLS_KEY_ALG`` can take in 3 values: `rsa`, `ecdsa` or `rsa+ecdsa`.
- This variable allows the Makefile to include the corresponding sources in
- the build for the various algorithms. Setting the variable to `rsa+ecdsa`
- enables support for both rsa and ecdsa algorithms in the mbedTLS library.
- - ``TF_MBEDTLS_KEY_SIZE`` sets the supported RSA key size for TFA. Valid values
- include 1024, 2048, 3072 and 4096.
- - ``TF_MBEDTLS_USE_AES_GCM`` enables the authenticated decryption support based
- on AES-GCM algorithm. Valid values are 0 and 1.
- .. note::
- If code size is a concern, the build option ``MBEDTLS_SHA256_SMALLER`` can
- be defined in the platform Makefile. It will make mbed TLS use an
- implementation of SHA-256 with smaller memory footprint (~1.5 KB less) but
- slower (~30%).
- --------------
- *Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.*
- .. _TBBR-Client specification: https://developer.arm.com/docs/den0006/latest
|