Matter device factory data provisioning

1. Introduction

Factory data are parameters stored in the device during the manufacturing process in a factory. These data do not change during the lifetime of the device. For this purpose, ST provides a tool with X-CUBE-MATTER that can be used to store data in the flash memory and manage them in general. ST have also partners providing infrastructure for Device Attestation Certificate (DAC) and Product Attestation Intermediate (PAI) certificates provisioning. Factory data provisioning is enabled by defining and setting to 1 CONFIG_STM32_FACTORY_DATA_ENABLE flag in the header file app_conf.h located in X-CUBE-MATTER\Projects\STM32WB5MM-DK\Applications\Matter\<XXX-App>\Core\Inc folder. If CONFIG_STM32_FACTORY_DATA_ENABLE flag is not set, Matter test VID/PID & certificates will be used at commissioning time. Development DAC/PAI certificates are available in X-CUBE-MATTER\Middlewares\Third_Party\connectedhomeip\src\credentials\examples\ExampleDACs.cpp/ExamplePAI.cpp. User can select the VID and PID in CHIPProjectConfig.h using CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID and CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID.

1.1. Provisioning overview

In a Matter Ecosystem, each device is identified through a set of credentials. This allows to securely identify each device joining a Matter Fabric (illustrated by the figure below) and the SW running on the device. Trusted software are referenced on CSA Distributed Compliance Ledger (DCL) server.

Connectivity Matter fabric.png

1.2. Matter factory data

Each device must have a consistent set of credentials to complete Matter commissioning. These credentials are stored on Matter device during provisioning. Following information is stored in Factory data:

  • Product Information:
- VID/PID, HW version, Serial Number, Firmware Information
  • Matter Certificates:
- PAI, DAC, DAC public key, DAC private key, Certification Declaration (CD)
  • Other Security credentials:
- Setup Discriminator, Spake2+ parameters

1.3. Matter commissioning

Connectivity Matter commissioning.png

During Matter Commissioning:

  • The Commissioner extracts the DAC certificate and the PAI certificate from the Commissionee at Validate Attestation step.
  • The Authenticity & Integrity of the DAC is checked by Commissioner sending a challenge request to Commissionee. The challenge request is signed by Commissionee using DAC private key.
  • The answer to the CSR request is also signed using DAC private key.

1.4. Device attestation PKI hierarchy

Connectivity Matter device attestation PKI hierarchy.png

Each Matter device is identified by its own DAC certificate. DAC certificates are derived from a single root of Trust involving PAA & PAI. Each DAC is provided with a public/private key pair. DAC private key length is 256 bits.

2. ST Provisioning architecture

2.1. Device provisioning overall system architecture

Connectivity Matter provisioning architecture.png

The Matter provisioning data model promoted by ST is open. ST end customer may contact whatever PKI provider to get PAI & DAC for his Matter End Device. Factory FW is flashed on M4 and final DCM Wireless Stack is flashed on M0. Factory used by end customer shall meet minimum Security requirements so that key assets cannot be stolen.

Architecture requirements:

  • DAC & PAI certificates are retrieved from PKI provider server, using a secure connection (PKCS#10, …)
  • DAC private key is generated in the device and shall be securely stored to prevent device cloning. Application SW should not be able to read or modify it.
  • Embedded SW with 3rd party Middleware is used to customize the interaction with Provisioning infrastructure.

Data structure and format:

Matter Factory data are stored in TLV format as represented in figures below:

Connectivity Matter factory data TLV format 1.png
Connectivity Matter factory data TLV format 2.png

2.2. Device provisioning HW environment

Connectivity Provisioning HW environment.png

2.3. Secure provisioning services deliveries

ST Delivers tools as part of X-CUBE-MATTER package to support device “data Factory setting” during Manufacturing. The tools are integrated/customized by “PKI provider company” as required by actual Customer Manufacturing process. ST provides supports to integrate the tools. The tools comprise:

  • Python script (genFactoryData.py) running on a Programming PC connected to the device to be programmed via ST Link
- It uses STM32CubeProgrammer CLI to communicate with the STM32 Device
- It writes firmware and data factory (non-sensitive) into the device flash memory, and can also set sensitive data (DAC/PAI certificates DAC public/private keys in reconfigure mode
- It is provided in X-CUBE-MATTER within the Utilities\DataFactory folder
- It launches a provisioning function on the programming PC to manage the provisioning process. ST deliver a Provisioning process manager script (STM32_provisioning.py) for provisioning demonstration. Third-Party must provide its own application to be used in provisioning mode on the programming PC
  • Embedded FW (STM_Provisioning project), delivered in source code, runs on the Device (STM32) to perform “secure provisioning” of sensitive data (DAC’s private key)
- It uses a customizable interface to interact with the Programming PC. This interface allows to receive DAC and PAI certificates from the Programming PC
- It writes/stores the DAC private key, DAC certificate and PAI certificate to the target storage area. DAC private key is stored in flash memory for Test mode and in secure storage (e.g. Customer Key Storage (CKS) in WB55 platform) for Production mode
- It is provided in X-CUBE-MATTER within the Project\<STM32 platform>\Applications\Matter folder

2.3.1. genFactoryData python script description

  • Features
- Read JSON or binary files containing device configuration data, compute a binary DataFactory output file and flash it to a specified address
- Program firmware to a specified address (or specified addresses for dual-core STM32 such as STM32WB55 with M0 and M4 cores)
- Use a script (STM32_provisioning.py) that monitors the provisioning process, to be replaced by Third-Party FW in provisioning mode
- List and check availability of serial ports
- Handle multiple devices concurrently using threading (instances of STM32_provisioning.py in reconfigure mode, or Third-Party FW in provisioning mode)
  • Requirements
Installation of:
- Python 3.x
- STM32CubeProgrammer (default path: `c:\Program Files\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin`)
- Required Python packages: serial, concurrent.futures, argparse, json, struct, subprocess, tempfile, os, re, ssl, enum, threading, datetime
  • Command Line options and parameters
The script accepts the following command line arguments to control its behavior:
- Platform independent command line arguments
  • --provisioning: mandatory argument set to 0 for reconfigure mode or 1 for provisioning mode. The reconfigure mode applies during development phase to a device already configured with application firmware and on which the ST tool is used to reconfigure the factory data.
  • --json: to indicate the path to an input JSON file containing device configuration data (mutually exclusive with --binary). The json file includes or does not include DAC/PAI certificate and DAC public/private key if provisioning is set to 0 or 1 respectively
  • --binary: to indicate the path to a binary file containing device configuration data (mutually exclusive with --json). The binary file includes or does not include DAC/PAI certificates and DAC public/private key if provisioning is set to 0 or 1 respectively
  • --provisioning_script': to indicate the path to the provisioning script STM32_provisioning.py in reconfigure mode or Third-Party FW in provisioning mode (required if --provisioning is set to 1)
  • -flashAddr or -fa: to indicate the address where the DataFactory binary output file will be programmed (if this option is not set, the binary output file will not be programmed)
  • -programmerPath or -pp: to indicate the path to STM32CubeProgrammer and the executable file name (if not set, the default path defined in programmer will be used)
  • -externalLoader or -el: to indicate the external loader driver to use for external flash and the driver name (if not set, the external loader defined in external_loader will be used by default)
- Command line arguments specific to STM32WB55 platform
  • --m0: to indicate the path to the M0 firmware file for a dual-core STM32 (required if `--provisioning` is `1`). The file is programmed at the address indicated by option -M0Addr
  • --m4_provisioning: to indicate the path to the M4 firmware provisioning file for a dual-core STM32 (required if --provisioning is set to 1). The file is programmed at the address indicated by option -M4Addr
  • --m4_matter: to indicate the path to the M4 Matter operational firmware file (required if `--provisioning` is 1). The file is programmed at the address indicated by option -M4Addr
  • -M0Addr or -0a: to indicate the address where the M0 firmware will be programmed (if not set, value in M0_address must be used as default value)
  • -M4Addr or -4a: to indicate the address where the M4 firmware will be programmed (if not set, value in M4_address must be used as default value)
  • Usage examples
- STM32WB55 based device
python genFactoryData.py --provisioning 1 --json config.json --m0 m0_firmware.bin --m4_provisioning m4_provisioning_firmware.bin --provisioning_script provisioning_script.py --m4_matter m4_matter_firmware.bin
In the above example the default values will be applied for arguments not present in the command line
  • -flashAddr or -fa: value in Data_address variable (e.g. 0x901C0000) will be used
  • -M0Addr or -0a: value in M0_address variable (e.g. 0x08094000) will be used
  • -M4Addr or -4a: value in M4_address variable (e.g. 0x08000000) will be used
  • -programmerPath or -pp: value in programmer structure will be used (e.g. programmer = {'path' : "c:\\Program Files\\STMicroelectronics\\STM32Cube\\STM32CubeProgrammer\\bin", 'prg' : "STM32_Programmer_CLI.exe"})
  • -externalLoader or -el: (e.g. external_loader = {'path' : programmer['path'] + "\\" + "ExternalLoader", 'drv' : "S25FL128S_STM32WB5MM-DK"})
The provisioning process manager (provisioning_script.py) is either the script provided by ST for demonstration (STM32_provisioning.py) or the Third-Party FW used in provisioning mode.

2.3.2. Embedded FW for device provisioning demonstration

Connectivity Embedded FW for device provisioning demo.png

For test and demonstration purpose ST provide within X-CUBE-MATTER a device provisioning FW to be flashed by the programming PC using the Python script. This programming FW programs a predefined certificates (DAC, PAI) and DAC keys (Public, Private), then send the result of this operation to the programming PC over the UART interface.

The STM_provisioning embedded FW allows to choose the provisioning mode which is either TEST mode in which the DAC private key is written in flash memory, or PRODUCTION mode in which the DAC private key is written in secure storage (e.g. CKS for STM32WB55 based platform).

An instance of the provisioning process manager application is used for uart port on which a device is connected to manage. The STM32_provisioning.py will simply monitor the provisioning process: display start message, read the uart port to get the result, and display end status.

2.3.3. Embedded FW for device provisioning during manufacturing

Connectivity Embedded FW for device provisioning during manufacturing.png

In provisioning mode a customized (by Third-Party) STM_Provisioning embedded FW, not including hardcoded certificates and keys, will be used. This embedded FW relies on Third-Party middleware to compute the DAC keypair, send CSR to and obtain certificates from the programming PC, then write certificates on flash memory and the private key on secure storage.

In provisioning mode, the provisioning process manager is provided by Third-Party and will play the proxy role between the device to be programmed and the PKI server.

Note: The current version of X-CUBE-MATTER does not include Third-Party FW. Customer could contact ST Partners referenced in section ST provisioning services integration with ST partners secure provisioning frameworks

3. Provisioning procedure

A typical provisioning sequence in provisioning mode would be the following:

  • The ST Python script genFactoryData
- enumerates/selects STLINK and COM Ports
- writes all parameters except the DAC/PAI certificate and DAC public/private key into the Device Flash Memory, using JTAG interface
- Program the device with the Provisioning SW through the JTAG interface. Upon installed, this FW generates the DAC keypair, prepares and sends the CSR to the programming PC using UART interface
- launches an instance of the provisioning process manager on the programming PC for each selected COM Port
- Program the device with the Operational SW through the JTAG interface at the end of the provisioning
  • The provisioning process manager (Third-Party SW) on the programming PC
- forwards the CSR request to the PKI server
- gets the DAC and PAI certificates from the PKI server and send them to the Embedded FW on the device through the UART interface
- ends and returns to the script
  • Upon receipt of the CSR response, the provisioning Embedded FW writes DAC/PAI certificates and DAC PublicKey on device's flash memory, and the DAC PrivateKey on flash memory in test mode or on secure storage in production mode, then signals the successful completion of the provisioning to the provisioning process manager (Third-Party SW in the programing PC) which will in its turn signal it to the ST python script


Connectivity Provisiong sequence.png

4. Factory data implementation

4.1. STM32WB55 factory data implementation

Connectivity STM32WB55 factory data implementation.png

Note: Provisional SW and Operational SW in the above figure are not present at the same time. Provisional SW is loaded for provisioning and is replaced by Operational SW at the end of the provisioning.

In STM32WB55 Matter platform, the secure storage of the DAC private key is the CKS storage. The CKS usage is enabled by USE_STM32WBXX_DAC_CRYPTO compilation flag defined and set to 1 in X-CUBE-MATTER\Projects\STM32WB5MM-DK\Applications\Matter\<App>\System\Inc\app_conf.h.

The following API can be used to store DAC private key in CKS:

otError otCksDacInitialize(const uint8_t *DAC_private_key);

With:

  • DAC_private_key: pointer to DAC private key in raw format.

DAC private key stored in CKS area can be used to sign Matter challenge using below API.

otError otCksDacSignature(const uint8_t *message_to_sign, const size_t msg_length, const uint8_t *DAC_public_key, uint8_t *out_signature);

With:

  • message_to_sign: pointer to message to be signed
  • msg_length: length of message to be signed
  • DAC_public_key: pointer to DAC public_key in raw format. Shall be consistent with DAC private key stored in CKS area. DAC_public_key length is 65 bytes
  • Out_signature: pointer to output signature. Signature size is 64 bytes (kP256_ECDSA_Signature_Length_Raw)

To use DAC private key stored in CKS area for Matter challenge signing, the key is loaded from CKS and signature is performed on M0 side in a fully isolated environment. ECDSA signature is computed calling MbedTLS crypto functions.

5. ST provisioning services integration with ST partners secure provisioning frameworks

ST has partners to securely provision the device with CSA Matter DAC and PAI certificates.

For STM32WB55 based Matter device provisioning, available pre-integrated frameworks with ST partners and related details can be found in ST partner portal.

6. Acronyms and definitions

Term Definition
CKS Customer Key Storage
CSR Certificate Signing Request
DAC Device Attestation Certificate
ECDSA Elliptic Curve Digital Signature Algorithm
PAI Product Attestation Intermediate