Skip to content

Commit

Permalink
device-provisioning: Add process documentation
Browse files Browse the repository at this point in the history
Signed-off-by: Ahmed Ismail <[email protected]>
  • Loading branch information
AhmedIsmail02 authored and urutva committed Mar 1, 2024
1 parent 0f95b71 commit 148e59d
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 12 deletions.
70 changes: 70 additions & 0 deletions docs/device_provisioning.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Device Provisioning

## Introduction
Device provisioning is composed of sequential steps, The main idea is to provide a unique identity for each device along with storing the authenticated identity in a secure space to safeguard against potential attacks by adversaries. In the context of the AWS IoT Core, these take the form of an **AWS IoT client certificate** stored in the device's protected storage and a **private key** imported to PSA Crypto.

## How it works
The device provisioning binary (`provisioning_data.bin`) is built from a C source file that contains an instance of a provisioning bundle struct (`ProvisioningParamsBundle_t`) as shown below:

```c
const ProvisioningParamsBundle_t provisioningBundle =
{
.provisioningMagic1 = PROVISIONING_MAGIC,
.provisioningParams =
{
.pucJITPCertificate = keyJITR_DEVICE_CERTIFICATE_AUTHORITY_PEM,
.pucClientCertificate = keyCLIENT_CERTIFICATE_PEM,
.pucClientPrivateKey = keyCLIENT_PRIVATE_KEY_PEM
},
.codeSigningPublicKey = keyCODE_SIGNING_PUBLIC_KEY_PEM,
.provisioningMagic2 = PROVISIONING_MAGIC
};
```

* `PROVISIONING_MAGIC`: a configurable value that can be set in [provisioning_config.h](../applications/helpers/provisioning/provisioning_config.h) header file, the `PROVISIONING_MAGIC` value is checked at the beginning of the provisioning process to make sure that the provided bundle parameters are genuine.

* `keyJITR_DEVICE_CERTIFICATE_AUTHORITY_PEM`: contents of a *.pem file representing a Just-in-Time Registration of Device Certificate. This is not supported by the FRI as device certificates are generated prior to connecting to AWS IoT Core, hence this value is defined as an empty string.

* `keyCLIENT_CERTIFICATE_PEM`: contents of `<certificate-name>.pem` file passed as part of the build command (`--certificate_path <path-to-certificate-name.pem>`). This is needed as AWS IoT Core authenticates device connections with the help of X.509 certificates. For more information on how to generate a X.509 certificate, please check [setting_up_aws_connectivity.md](./setting_up_aws_connectivity.md) document.

* `keyCLIENT_PRIVATE_KEY_PEM`: contents of `<private-key-name>.pem` file passed as part of the build command (`--private_key_path <path-to-private-key-name.pem>`). This is used along with the certificate to validate the identity of the device.

* `keyCODE_SIGNING_PUBLIC_KEY_PEM`: contents of `image_ns_signing_public_key.pem` which is the public key component of the key pair generated by TF-M during the build process. This is needed to validate the authenticity of an OTA update image by verifying the associated signature.

* `keyJITR_DEVICE_CERTIFICATE_AUTHORITY_PEM`, `keyCLIENT_CERTIFICATE_PEM`, `keyCLIENT_PRIVATE_KEY_PEM`, and `keyCODE_SIGNING_PUBLIC_KEY_PEM` are used to generate the credentials header during the build process using [generate_credentials_header.py](../tools/scripts/generate_credentials_header.py) python script.
The credentials header can be generated manually using the following command from the project's top level directory:

```sh
python3 ./tools/scripts/generate_credentials_header.py \
"<build_path>/helpers/provisioning" \
--path-to-client-private-key-pem "<path-to-private-key-name.pem>" \
--path-to-client-certificate-pem "<path-to-certificate-name.pem>" \
--path-to-code-signing-public-key-pem "$TFM_KEYS_PATH/image_ns_signing_public_key.pem"
```

where `$TFM_KEYS_PATH` is the path TF-M keys are generated in (`$BUILD_PATH/iot_reference_arm_corstone3xx/components/security/trusted_firmware-m/integration/trusted_firmware-m-build-prefix/src/trusted_firmware-m-build-build/api_ns/image_signing/keys/`).

The provisioning binary `provisioning_data.bin` is built into `<build_path>/helpers/provisioning` subdirectory where the binary is used to provision the device with the client certificate, associated private and public key pair, and the optional Just-in-Time registration certificate. If the private or public key is unavailable in storage, a new key pair is generated.

The `provisioning_data.bin` binary has to be loaded to `NS_PROVISIONING_BUNDLE_LOAD_ADDRESS` (platform dependant address specified at `bsp/CMakeLists.txt`) so that when the application runs, it detects that the non-secure provisioning bundle is present and writes the credentials into the protected storage. This step is done automatically as part of merging the output application binaries which takes place during the the build process through `iot_reference_arm_corstone3xx_tf_m_merge_images` CMake function.

This step can also be done manually at run time by using the following command:

```sh
FVP_Corstone_SSE-310 -a cpu0*=$TFM_BUILD_PATH/bl2.axf \
--data "$TFM_BUILD_PATH/tfm_s_signed.bin"@<S_IMAGE_LOAD_ADDRESS> \
--data "$BUILD_PATH/<application-name>_signed.bin"@<NS_IMAGE_LOAD_ADDRESS> \
--data "$TFM_BUILD_PATH/encrypted_provisioning_bundle.bin"@<S_PROVISIONING_BUNDLE_LOAD_ADDRESS> \
--data "$BUILD_PATH/helpers/provisioning/provisioning_data.bin"@<NS_PROVISIONING_BUNDLE_LOAD_ADDRESS>
```

`$BUILD_PATH` is the path which is passed through `--path` option as part of the build command.

`$TFM_BUILD_PATH` is the path where TF-M binaries are generated (`$BUILD_PATH/iot_reference_arm_corstone3xx/components/security/trusted_firmware-m/integration/trusted_firmware-m-build-prefix/src/trusted_firmware-m-build-build/api_ns/bin`).

### Note:

If the contents of the certificate or private key `.pem` files used for building the application (passed with `--certificate_path` and `--private_key_path`) have changed, rebuild the non-secure provisioning binary using the following command:
```sh
cmake --build build -j -- provisioning_data
```
7 changes: 1 addition & 6 deletions docs/keyword_detection.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,7 @@ Or, run the command below to perform a clean build:


## Provisioning the device credentials into Protected Storage
During the build process a ```provisioning_data.bin``` is built into the ```build/applications/keyword_detection/provisioning_data``` directory.
This binary contains the device credentials (private key and certificate).

If the content of the .pem files that were used during the build process (passed with ```--certificate_path``` and ```--private_key_path```) changed, then ```cmake --build build -j -- provisioning_data``` rebuilds this provisioning binary.

The binary has to be loaded to the ```0x210FF000``` address so the ```keyword-detection``` can detect that a provisioning bundle is present and writes the credentials into the Protected Storage. (The run.sh script automatically does this.)
Check [Device Provisioning](./device_provisioning.md) for detailed information.

## Running the application

Expand Down
7 changes: 1 addition & 6 deletions docs/speech_recognition.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,7 @@ Or, run the command below to perform a clean build:
```

## Provisioning the device credentials into Protected Storage
During the build process a ```provisioning_data.bin``` is built into the ```build/applications/speech_recognition/provisioning_data``` directory.
This binary contains the device credentials (private key and certificate).

If the content of the .pem files that were used during the build process (passed with ```--certificate_path``` and ```--private_key_path```) changed, then ```cmake --build build -j -- provisioning_data``` rebuilds this provisioning binary.

The binary has to be loaded to the ```0x210FF000``` address so the ```speech-recognition``` can detect that a provisioning bundle is present and writes the credentials into the Protected Storage. (The run.sh script automatically does this.)
Check [Device Provisioning](./device_provisioning.md) for detailed information.

## Running the application

Expand Down
1 change: 1 addition & 0 deletions release_changes/202402261206.change
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
device-provisioning: Add process documentation.

0 comments on commit 148e59d

Please sign in to comment.