aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/user_guides/services/tfm_attestation_integration_guide.md422
1 files changed, 337 insertions, 85 deletions
diff --git a/docs/user_guides/services/tfm_attestation_integration_guide.md b/docs/user_guides/services/tfm_attestation_integration_guide.md
index 2e4809bcba..d6085f4665 100644
--- a/docs/user_guides/services/tfm_attestation_integration_guide.md
+++ b/docs/user_guides/services/tfm_attestation_integration_guide.md
@@ -13,98 +13,331 @@ key provisioning is out of scope for the attestation service and is expected to
take part during manufacturing of the device.
## Current service limitations
-
-**CBOR encoding** - The final data encoding of initial attestation token
-is going to follow the Concise Binary Object Representation, aka.
-[CBOR](http://cbor.io/).
-Currently TLV (Type-Length-Value) encoding is used.
-
-**Signing of token** - In the current implementation the token is not signed.
-Claims are concatenated in raw format and there is no signature applied. The
-final implementation is going to use signed token. Signatures are going to be
-generated according to the [COSE](https://datatracker.ietf.org/doc/rfc8152/)
-format.
+- **Signing of token** - In the current implementation the token is not properly
+signed. Signature is generated according to the
+[COSE](https://datatracker.ietf.org/doc/rfc8152/) format. But its actual value
+is not a correct ECDSA P256 signature, due to the lack of support of the ECDSA
+algorithm in the current implementation of the TF-M Crypto service. A fake
+signature is created, which is the concatenation of the token's hash value
+twice.
## Claims in the initial attestation token
-The initial attestation token is formed of claims. A claim is a data entry,
+The initial attestation token is formed of claims. A claim is a data item,
which is represented in a key - value structure. The following fixed set of
claims are included in the token:
- - **Challenge** - Input object from caller. It can be a nonce value from a
- server, or a hash value of attested data.
- - **Client ID** - The ID of that secure partition or non-secure thread who
- called the Initial Attestation Service.
- - **Boot status** - Measurements(hash) of firmware components by secure
- bootloader.
- - **Boot seed** - Random number, which is non-volatile during the same boot
- cycle.
- - **Device ID** - Universally and globally unique ID of the device.
-
-## Claims encoding
-Currently claims are encoded in TLV format. The definition of TLV structure is
-described in `bl2\include\tfm_boot_status.h`. The Initial Attestation Service
-related type identifiers are described in
-`secure_fw\services\initial_attestation\attestation.h`
-
-Claim structure:
-```
----------------------------------------------------------------
-| Major_type(uint8_t) | Minor_type(uint8_t) | Length(uit16_t) |
----------------------------------------------------------------
-| Raw data |
----------------------------------------------------------------
-```
+- **Challenge**: Input object from caller. Can be a single nonce from server or
+hash of nonce and attested data. It is intended to provide freshness to reports
+and the caller has responsibility to arrange this. Allowed length: 32, 48,
+64 bytes. The claim is modeled to be eventually represented by the EAT standard
+claim nonce. Until such a time as that standard exists, the claim will be
+represented by a custom claim. Value is encoded as byte string.
+
+- **Instance ID**: It represents the unique identifier of the instance. In the
+PSA definition it is a hash of the public attestation key of the instance. The
+claim is modeled to be eventually represented by the EAT standard claim UEID of
+type GUID. Until such a time as that standard exists, the claim will be
+represented by a custom claim Value is encoded as byte string.
+
+- **Verification service indicator**: Optional, recommended claim. It is used by
+a Relying Party to locate a validation service for the token. The value is a
+text string that can be used to locate the service or a URL specifying the
+address of the service. The claim is modeled to be eventually represented by
+the EAT standard claim origination. Until such a time as that standard exists,
+the claim will be represented by a custom claim. Value is encoded as text
+string.
+
+- **Profile definition**: Optional, recommended claim. It contains the name of a
+document that describes the 'profile' of the token, being a full description of
+the claims, their usage, verification and token signing. The document name may
+include versioning. Custom claim with a value encoded as text string.
+
+- **Implementation ID**: It represents the original implementation signer of the
+attestation key and identifies the contract between the report and verification.
+A verification service will use this claim to locate the details of the
+verification process. Custom claim with a value encoded as byte string.
+
+- **Security lifecycle**: It represents the current lifecycle state of the
+instance. Custom claim with a value encoded as an integer.
+
+- **Client ID**: The partition ID of that secure partition or non-secure thread
+who called the initial attestation API. Custom claim with a value encoded as a
+`signed` integer. Negative number represents non-secure caller, positive numbers
+represents secure callers, zero is invalid.
+
+- **HW version**: Optional claim. Globally unique number in EAN-13 format
+identifying the GDSII that went to fabrication, HW and ROM. It can be used to
+reference the security level of the PSA-ROT via a certification website. Custom
+claim with a value is encoded as text string.
+
+- **Boot seed**: It represents a random value created at system boot time that
+will allow differentiation of reports from different system sessions. The size
+is 32 bytes. Custom claim with a value is encoded as byte string.
+
+- **Software components**: Optional, recommended claim. It represents the
+software state of the system. The value of the claim is an array of CBOR map
+entries, with one entry per software component within the device. Each map
+contains multiple claims that describe evidence about the details of the
+software component.
+
+ - **Measurement type**: Optional claim. It represents the role of the software
+ component. Value is encoded as short(!) text string.
+
+ - **Measurement value**: It represents a hash of the invariant software
+ component in memory at start-up time. The value must be a cryptographic hash
+ of 256 bits or stronger. Value is encoded as byte string.
+
+ - **Security epoch**: Optional claim. It represents the security control point
+ of the software component. Value is encoded as unsigned integer.
+
+ - **Version**: Optional claim. It represents the issued software version. Value
+ is encoded as text string.
+
+ - **Signer ID**: It represents the hash of a signing authority public key.
+ Value is encoded as byte string.
+
+ - **Measurement description**: Optional claim. It represents the way in which
+ the measurement value of the software component is computed. Value is encoded
+ as text string containing an abbreviated description (name) of the measurement
+ method.
+
+- **No software measurements**: In the event that the implementation does not
+contain any software measurements then the software components claim above can
+be omitted but instead it is mandatory to include this claim to indicate this is
+a deliberate state. Custom claim a value is encoded as an unsigned integer set
+to 1.
+
+## Initial attestation token (IAT) data encoding
+The initial attestation token is planned to be aligned with future version of
+[Entity Attestation Token](https://tools.ietf.org/html/draft-mandyam-eat-01)
+format. The token is encoded according to the
+[CBOR](https://tools.ietf.org/html/rfc7049) format and signed according to
+[COSE](https://tools.ietf.org/html/rfc8152) standard.
## Code structure
The PSA interface for the Initial Attestation Service is located in
-`interface\include`.
+`interface/include`.
The only header to be included by applications that want to use functions from
the PSA API is `psa_initial_attestation.h`.
The TF-M Initial Attestation Service source files are located in
-`secure_fw\services\initial_attestation`.
+`secure_fw/services/initial_attestation`.
+The CBOR library is located in `lib/ext/qcbor` folder.
-### PSA interface
+### Service source files
+- CBOR library:
+ - `lib/ext/qcbor`: This library is used to create a proper CBOR token. It can
+ be used on 32-bit and 64-bit machines. It was designed to suite constrained
+ devices with low memory usage and without dynamic memory allocation. It is a
+ fork of this external
+ [QCBOR library](https://github.com/laurencelundblade/QCBOR).
+ - `lib/ext/qcbor/inc/qcbor.h`: Public API documentation of CBOR library.
+- COSE library:
+ - `lib/t_cose`: This library is used to sign a CBOR token and create the COSE
+ header and signature around the initial attestation token. Only a subset of the
+ [COSE](https://tools.ietf.org/html/rfc8152) standard is implemented. Only the
+ cose_sign1 signature schema is supported.
+ - `lib/t_cose/src/t_cose_crypto.h`: Expose an API to bind `t_cose` library with
+ available crypto library in the device.
+ - `lib/t_cose/src/t_cose_psa_crypto.c`: Implements the exposed API and ports
+ `t_cose` to psa_crypto library.
+- Initial Attestation Service:
+ - `attestation_core.c` : Implements core functionalities such as implementation
+ of APIs, retrieval of claims and token creation.
+ - `attest_token.c`: Implements the token creation function such as start and
+ finish token creation and adding claims to the token.
+ - `attestation_crypto_stub.c`: Temporary file, it implements the missing
+ psa_crypto APIs.
+ - `attestation_key.c`: Get the attestation key from platform layer and register
+ it to psa_crypto service for further usage.
+ - `tfm_attestation.c`: Implements the SPM abstraction layer, and bind the
+ attestation service to the SPM implementation in TF-M project.
+ - `tfm_attestation_secure_api.c`: Implements the secure API layer to allow
+ other services in the secure domain to request functionalities from the
+ attestation service using the PSA API interface.
-The TF-M Initial Attestation Service exposes the following PSA interface:
+### Service interface definitions
+- **Boot loader interface**: The attestation service might include data in the
+token about the distinct software components in the device. This data is
+provided by the boot loader and must be encoded in the TLV format, definition
+is described below in the boot loader interface paragraph. Possible claims in
+the boot status are describe above in the software components paragraph.
+- **Hardware abstraction layer**:
+ - Headers are located in `platform/include` folder.
+ - `tfm_attest_hal.h`: Expose an API to get the following claims: security
+ lifecycle, verification service indicator, profile definition.
+ - `tfm_plat_boot_seed.h`: Expose an API to get the boot seed claim.
+ - `tfm_plat_device_id.h`: Expose an API to get the following claims:
+ implementation ID, hardware version, instance ID.
+- **SPM interface**:
+ - `attestation.h`: Expose an API to bind attestation service to an SPM
+ implementation.
+- **PSA interface**:
+ - `psa_initial_attestation.h`: Public API definition of initial attestation
+ service.
+- **Crypto interface**:
+ - `t_cose_crypto.h`: Expose an API to bind the `t_cose` implementation to any
+ cryptographic library.
+ - `tfm_plat_crypto_keys.h`: Expose an API to get the attestation key from
+ platform layer.
+### PSA interface
+The TF-M Initial Attestation Service exposes the following PSA interface:
``` c
enum psa_attest_err_t
psa_initial_attest_get_token(const uint8_t *challenge_obj,
uint32_t challenge_size,
uint8_t *token,
uint32_t *token_size);
+
+enum psa_attest_err_t
+psa_initial_attest_get_token_size(uint32_t challenge_size,
+ uint32_t *token_size);
```
+The caller must allocate a large enough buffer, where the token is going to be
+created by Initial Attestation Service. The size of the created token is highly
+dependent on the number of software components in the system and the provided
+attributes of these.
+The `psa_initial_attest_get_token_size()` function can be called to get the
+exact size of the created token.
-### Service source files
+System integrators might need to port these interfaces to a custom secure
+partition manager implementation (SPM). Implementation in TF-M project can be
+found here:
+- `interface/src/tfm_initial_attestation_api.c`: non-secure interface
+implementation
+- `secure_fw/services/initial_attestation/tfm_attestation_secure_api.c`: secure
+interface implementation
+
+### Secure Partition Manager (SPM) interface
+The Initial Attestation Service defines the following interface towards the
+secure partition manager (SPM). System integrators **must** port this
+interface according to their SPM implementation.
+```c
+enum psa_attest_err_t
+attest_get_boot_data(uint8_t major_type, void *ptr, uint32_t len);
+
+enum psa_attest_err_t
+attest_get_caller_client_id(int32_t *caller_id);
+
+enum psa_attest_err_t
+attest_check_memory_access(void *addr,
+ uint32_t size,
+ enum attest_memory_access access);
+```
+- `attest_get_boot_data()`: Service can retrieve the relevant data from shared
+memory area between boot loader and runtime software. It might be the case that
+only SPM has direct access to the shared memory area, therefore this function
+can be used to copy the service related data from shared memory to a local
+memory buffer. In TF-M implementation this function must be called during
+service initialization phase, because the shared memory region is deliberately
+overlapping with secure main stack to spare some memory and reuse this area
+during execution. If boot loader is not available in the system to provide
+attributes of software components then this function must be implemented in a
+way that just initialize service's memory buffer to:
+ ```c
+ struct shared_data_tlv_header *tlv_header =
+ (struct shared_data_tlv_header *)ptr;
+ tlv_header->tlv_magic = 2016;
+ tlv_header->tlv_tot_len = sizeof(struct shared_data_tlv_header *tlv_header);
+ ```
+
+- `attest_get_caller_client_id()`: Retrieves the ID of the caller thread.
+- `attest_check_memory_access()`: Validates the availability and access rights
+of memory regions received as input data: challenge object, token buffer, etc.
+- `tfm_client.h`: Service relies on the following external definitions, which
+must be present or included in this header file:
+
+ ```c
+ typedef struct psa_invec {
+ const void *base;
+ size_t len;
+ } psa_invec;
+
+ typedef struct psa_outvec {
+ void *base;
+ size_t len;
+ } psa_outvec;
+ ```
+
+### Hardware abstraction layer:
+The following API definitions are intended to retrieve the platform specific
+claims. System integrators **must** implement these interface according to their
+SoC and software design. Detailed definition of the claims are above in the
+claims in the initial attestation token paragraph.
+- `tfm_attest_hal_get_security_lifecycle()`: Get the security lifecycle of the
+device.
+- `tfm_attest_hal_get_verification_service()`: Get the verification service
+indicator for initial attestation.
+- `tfm_attest_hal_get_profile_definition()`: Get the name of the profile
+definition document for initial attestation.
+- `tfm_plat_get_boot_seed()`: Get the boot seed, which is a constant random
+number during a boot cycle.
+- `tfm_plat_get_instance_id()`: Get the UEID of the device.
+- `tfm_plat_get_implementation_id`: Get the implementation ID of the device.
+- `tfm_plat_get_hw_version`: Get the hardware version of the device.
+
+### Boot loader interface
+It is **recommended** to have a secure boot loader in the boot chain, which is
+capable of measuring the runtime firmware components (calculates the hash value
+of firmware images) and provide other attributes of these (version, type, etc).
+
+The shared data between boot loader and runtime software is TLV encoded. The
+definition of TLV structure is described in `bl2/include/tfm_boot_status.h`.
+The shared data is stored in a well known location in secure internal memory
+and this is a contract between boot loader and runtime SW.
+
+The structure of shared data must be the following:
+ - At the beginning there must be a header: `struct shared_data_tlv_header`
+ This contains a magic number and a size field which covers the entire
+ size of the shared data area including this header.
+ ```c
+ struct shared_data_tlv_header {
+ uint16_t tlv_magic;
+ uint16_t tlv_tot_len;
+ };
+ ```
+ - After the header there come the entries which are composed from an entry
+ header structure: `struct shared_data_tlv_entry` and the data. In the entry
+ header is a type field `tlv_type` which identify the consumer of the entry
+ in the runtime software and specify the subtype of that data item. There is
+ a size field `tlv_len` which covers the size of the entry header and the
+ data. After this structure comes the actual data.
+ ```c
+ struct shared_data_tlv_entry {
+ uint16_t tlv_type;
+ uint16_t tlv_len;
+ };
+ ```
+ - Arbitrary number and size of data entry can be in the shared memory area.
+
+The table below gives of overview about the `tlv_type` field in the entry
+header. The `tlv_type` always composed from a major and minor number. Major
+number identifies the addressee in runtime software, which the data entry is
+sent to. Minor number used to encode more info about the data entry. The actual
+definition of minor number could change per major number. In case of boot
+status data, which is going to be processed by initial attestation service
+the minor number is split further to two part: `sw_module` and `claim`. The
+`sw_module` identifies the SW component in the system which the data item
+belongs to and the `claim` part identifies the exact type of the data.
+
+`tlv_type` description:
+```
+|------------------------------------------------ |
+| tlv_type (16 bits) |
+|-------------------------------------------------|
+| tlv_major(4 bits) | tlv_minor(12 bits) |
+|-------------------------------------------------|
+| MAJOR_IAS | sw_module(6 bits) | claim(6 bits) |
+|-------------------------------------------------|
+| MAJOR_CORE | TBD |
+|-------------------------------------------------|
+```
- - `attestation_core.c` : This file implements core functionalities such as
- retrieval of claims and token creation.
-
-### SPM interface
-The Secure Partition Manager provides an interface to retrieve data from secure
-bootloader which is relevant to runtime services. The attestation token must
-contain the measurements of firmware components. These measurements are done by
-the bootloader and stored in a shared data region for runtime firmware. Only SPM
-has direct access to the shared data region. Services can retrieve relevant data
-with the following interface:
- - `int32_t tfm_core_get_boot_data(uint8_t major_type, void *ptr,
- uint32_t len)`
-
-This function must be called during service initialization phase, because the
-shared data region is deliberately overlapping with secure main stack to spare
-some memory and reuse this area during execution. After calling the function SPM
-copies the service relevant data, identified by `major_type`, to service's
-memory space.
-
-### Shared data structure
-The format of shared data is TLV encoded. The definition of TLV structure is
-described in `bl2\include\tfm_boot_status.h`.
-
-Structure of shared data:
+Overall structure of shared data:
```
---------------------------------------------------------------
| Magic number(uint16_t) | Shared data total length(uint16_t) |
---------------------------------------------------------------
-| Major_type(uint8_t) | Minor_type(uint8_t) | Length(uit16_t) |
+| Major_type(4 bits) | Minor_type(12 bits) | Length(uint16_t) |
---------------------------------------------------------------
| Raw data |
---------------------------------------------------------------
@@ -112,33 +345,52 @@ Structure of shared data:
| . |
| . |
---------------------------------------------------------------
-| Major_type(uint8_t) | Minor_type(uint8_t) | Length(uit16_t) |
+| Major_type(4 bits) | Minor_type(12 bits) | Length(uint16_t) |
---------------------------------------------------------------
| Raw data |
---------------------------------------------------------------
```
-Structure of TLV entry's header:
- - **Major_type** - Identifies the secure service which the data is sent to.
- - **Minor_type** - Identifies the type of the data.
- - **Length** - The length of one TLV entry including the header.
+### Crypto interface
+Device **must** contain an asymmetric key pair. The private part of it is used
+to sign the initial attestation token. Current implementation supports only the
+ECDSA P256 signature over SHA256. The public part of the key pair is used to
+create the key identifier (kid) in the unprotected part of the COSE header. The
+kid is used by verification entity to look up the corresponding public key to
+verify the signature in the token. The `t_cose` part of the initial attestation
+service implements the signature generation and kid creation. But the actual
+calculation of token's hash and signature is done by the Crypto service in the
+device. System integrators might need to re-implement the following functions
+if they want to use initial attestation service with a different cryptographic
+library than Crypto service:
+- `t_cose_crypto_pub_key_sign()`: Calculates the signature over a hash value.
+- `t_cose_crypto_get_ec_pub_key()`: Get the public key to create the key
+identifier.
+- `t_cose_crypto_hash_start()`: Start a multipart hash operation.
+- `t_cose_crypto_hash_update()`: Add a message fragment to a multipart hash
+operation.
+- `t_cose_crypto_hash_finish()`:Finish the calculation of the hash of a message.
-## Initial Attestation Service integration guide
-In order to interact with Initial Attestation Service and retrieve attestation
-token, the described PSA interface in `psa_initial_attestation.h` must be
-called. It can be called from secure and non-secure context as well.
+Interface needed by verification code:
+- `t_cose_crypto_pub_key_verify()`: Verify the signature over a hash value.
-The caller must allocate a big enough buffer, where the token is going to be
-created by Initial Attestation Service. Detailed description of the interface
-can be found in the above mentioned header file.
+#### Key handling
+The provisioning of the initial attestation key is out of scope of the service
+and this document. It is assumed that device maker provisions the unique
+asymmetric key pair during the manufacturing process. The following API is
+defined to retrieve the attestation key pair from platform layer. Software
+integrators **must** port this interface according to their SoC design and make
+sure that key pair is available by Crypto service:
+- `tfm_plat_get_initial_attest_key()`: Retrieve the initial attestation key pair
+from platform layer.
-### Measured boot
-It **must** have a secure bootloader in the boot chain, which is capable to
-measure the runtime firmware components (calculates hash value of theirs).
-The data must be stored in the above described TLV format in a shared data
-region in secure internal RAM. The address and format of shared data region is
-a contract between the bootloader and the secure firmware.
+In TF-M project the attestation key is retrieved by initial attestation service.
+The key is registered and unregistered to the Crypto service by attestation
+service with `psa_import_key()` and `psa_destroy_key()` API calls for further
+usage. See in `attestation_key.c`. In other implementation if the attestation
+key is directly retrieved by the Crypto service then this key handling is not
+necessary.
--------------
-*Copyright (c) 2018, Arm Limited. All rights reserved.*
+*Copyright (c) 2018-2019, Arm Limited. All rights reserved.*