-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
device-provisioning: Add process documentation
Signed-off-by: Ahmed Ismail <[email protected]>
- Loading branch information
1 parent
0f95b71
commit 148e59d
Showing
4 changed files
with
73 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
device-provisioning: Add process documentation. |