By default, the example application is configured to use generic test certificates and provisioning data embedded with the application code. It is possible for a final stage application to generate its own manufacturing data using the procedure described below.
Generate build files from Matter root folder by running:
gn gen out
Build chip-cert
tool:
ninja -C out chip-cert
Build spake2p
tool:
ninja -C out spake2p
To generate the different certificates, NXP provides a Python script scripts/tools/nxp/generate_certs.py
. This script will always generate the PAI and DAC certificates/keys. It can also generate the Certification Declaration and the PAA certificate/key depending on the parameters.
Parameter | Description | Type | Required |
---|---|---|---|
--chip_cert_path | Path to chip-cert executable | string | Yes |
--output | Output path to store certificates | string | Yes |
--vendor_id | Vendor Identification Number | integer or hex integer | Yes |
--product_id | Product Identification Number | integer or hex integer | Yes |
--vendor_name | Human-readable vendor name | string | Yes |
--product_name | Human-readable product name | string | Yes |
--gen_cd | Use this option to enable Certificate Declaration generation | boolean | No |
--cd_type | Type of generated Certification Declaration: 0 - development, 1 - provisional, 2 - official | integer | No |
--device_type | The primary device type implemented by the node | int | No |
--paa_cert | Path to the Product Attestation Authority (PAA) certificate. Will be generated if not provided. | string | No |
--paa_key | Path to the Product Attestation Authority (PAA) key. Will be generated if not provided. | string | No |
--valid_from | The start date for the certificate's validity period. | string | No |
--lifetime | The lifetime for the certificates, in whole days. | string | No |
You can also run the following command to get more details on the parameters and their default value (if applicable):
python scripts/tools/nxp/generate_certs.py --help
Example of a command that will generate CD, PAA, PAI and DAC certificates and keys in both .pem and .der formats:
python scripts/tools/nxp/generate_certs.py --gen_cd --cd_type 1 --chip_cert_path ./out/chip-cert --vendor_id 0x1037 --product_id 0xA220 --vendor_name "NXP Semiconductors" --product_name all-clusters-app --device_type 65535 --output .
Note: the commands provided in this guide are just for the example and shall be adapted to your use case accordingly
Generate new provisioning data and convert all the data to a binary (unencrypted data):
python3 ./scripts/tools/nxp/factory_data_generator/generate.py -i 10000 -s UXKLzwHdN3DZZLBaL2iVGhQi/OoQwIwJRQV4rpEalbA= -p 14014 -d 1000 --vid 0x1037 --pid 0xA220 --vendor_name "NXP Semiconductors" --product_name "Lighting app" --serial_num "12345678" --date "2023-01-01" --hw_version 1 --hw_version_str "1.0" --cert_declaration ./Chip-Test-CD-1037-A220.der --dac_cert ./Chip-DAC-NXP-1037-A220-Cert.der --dac_key ./Chip-DAC-NXP-1037-A220-Key.der --pai_cert ./Chip-PAI-NXP-1037-A220-Cert.der --spake2p_path ./out/spake2p --unique_id "00112233445566778899aabbccddeeff" --out ./factory_data.bin
Same example as above, but with an already generated verifier passed as input:
python3 ./scripts/tools/nxp/factory_data_generator/generate.py -i 10000 -s UXKLzwHdN3DZZLBaL2iVGhQi/OoQwIwJRQV4rpEalbA= -p 14014 -d 1000 --vid "0x1037" --pid "0xA220" --vendor_name "NXP Semiconductors" --product_name "Lighting app" --serial_num "12345678" --date "2023-01-01" --hw_version 1 --hw_version_str "1.0" --cert_declaration ./Chip-Test-CD-1037-A220.der --dac_cert ./Chip-DAC-NXP-1037-A220-Cert.der --dac_key ./Chip-DAC-NXP-1037-A220-Key.der --pai_cert ./Chip-PAI-NXP-1037-A220-Cert.der --spake2p_path ./out/spake2p --spake2p_verifier ivD5n3L2t5+zeFt6SjW7BhHRF30gFXWZVvvXgDxgCNcE+BGuTA5AUaVm3qDZBcMMKn1a6CakI4SxyPUnJr0CpJ4pwpr0DvpTlkQKqaRvkOQfAQ1XDyf55DuavM5KVGdDrg== --unique_id "00112233445566778899aabbccddeeff" --out ./factory_data.bin
Generate new provisioning data and convert all the data to a binary (encrypted data with the AES key). Add the following option to one of the above examples:
--aes128_key 2B7E151628AED2A6ABF7158809CF4F3C
Here is the interpretation of the required parameters:
-i -> SPAKE2+ iteration -s -> SPAKE2+ salt (passed as base64 encoded string) -p -> SPAKE2+ passcode -d -> discriminator --vid -> Vendor ID --pid -> Product ID --vendor_name -> Vendor Name --product_name -> Product Name --hw_version -> Hardware Version as number --hw_version_str -> Hardware Version as string --cert_declaration -> path to the Certification Declaration (der format) location --dac_cert -> path to the DAC (der format) location --dac_key -> path to the DAC key (der format) location --pai_cert -> path to the PAI (der format) location --spake2p_path -> path to the spake2p tool --out -> name of the binary that will be used for storing all the generated data
Here is the interpretation of the optional parameters:
--dac_key_password -> Password to decode DAC key --dac_key_use_sss_blob -> Used when --dac_key contains a path to an encrypted blob, instead of the actual DAC private key. The blob metadata size is 24, so the total length of the resulting value is private key length (32) + 24 = 56. False by default. --spake2p_verifier -> SPAKE2+ verifier (passed as base64 encoded string). If this option is set, all SPAKE2+ inputs will be encoded in the final binary. The spake2p tool will not be used to generate a new verifier on the fly. --aes128_key -> 128 bits AES key used to encrypt the whole dataset. Please make sure that the target application/board supports this feature: it has access to the private key and implements a mechanism which can be used to decrypt the factory data information. --date -> Manufacturing Date (YYYY-MM-DD format) --part_number -> Part number as string --product_url -> Product URL as string --product_label -> Product label as string --serial_num -> Serial Number --unique_id -> Unique id used for rotating device id generation
For the K32W0x1 variants, the binary needs to be written in the internal flash at location 0x9D600 using DK6Programmer.exe
:
DK6Programmer.exe -Y -V2 -s <COM_PORT> -P 1000000 -Y -p FLASH@0x9D600="factory_data.bin"
For K32W1 platform, the binary needs to be written in the internal flash at location given by __MATTER_FACTORY_DATA_START
, using JLink
:
loadfile factory_data.bin 0xf4000
where 0xf4000
is the value of __MATTER_FACTORY_DATA_START
in the corresponding .map file (can be different if using a custom linker script).
For the RT1060, RT1170 and RW61X platform, the binary needs to be written using MCUXpresso Flash Tool GUI
at the address value corresponding to __FACTORY_DATA_START
(the map file of the application should be checked to get the exact value).
Use chip_with_factory_data=1
when compiling to enable factory data usage.
Run chip-tool with a new PAA:
./chip-tool pairing ble-thread 2 hex: $hex_value 14014 1000 --paa-trust-store-path /home/ubuntu/certs/paa
Here is the interpretation of the parameters:
--paa-trust-store-path -> path to the generated PAA (der format)
paa-trust-store-path
must contain only the PAA certificate. Avoid placing other certificates in the same location as this may confuse chip-tool
.
PAA certificate can be copied to the chip-tool machine using SCP for example.
This is needed for testing self-generated DACs, but likely not required for “true production” with production PAI issued DACs.
Implementation of manufacturing data provisioning has been validated using test certificates generated by OpenSSL 1.1.1l
.
Also, demo DAC, PAI and PAA certificates needed in case chip_with_factory_data=1
is used can be found in ./scripts/tools/nxp/demo_generated_certs
.
Supported platforms:
src/plaftorm/nxp/k32w/k32w1/FactoryDataProviderImpl.h
For platforms that have a secure subsystem (SSS
), the DAC private key can be converted to an encrypted blob. This blob will overwrite the DAC private key in factory data and will be imported in the SSS
at initialization, by the factory data provider instance.
The conversion process shall happen at manufacturing time and should be run one time only:
chip_with_factory_data=1 chip_convert_dac_private_key=1
set.After the conversion process:
chip_with_factory_data=1
, but without chip_convert_dac_private_key
arg, since conversion already happened.If you are using Jlink, you can see a conversion script example in:
./scripts/tools/nxp/factory_data_generator/k32w1/example_convert_dac_private_key.jlink
Factory data should now contain a corresponding encrypted blob instead of the DAC private key.
If an encrypted blob of the DAC private key is already available (e.g. obtained previously, using other methods), then the conversion process shall be skipped. Instead, option --dac_key_use_sss_blob
can be used in the factory data generation command:
python3 ./scripts/tools/nxp/factory_data_generator/generate.py -i 10000 -s UXKLzwHdN3DZZLBaL2iVGhQi/OoQwIwJRQV4rpEalbA= -p 14014 -d 1000 --vid "0x1037" --pid "0xA221" --vendor_name "NXP Semiconductors" --product_name "Lighting app" --serial_num "12345678" --date "2023-01-01" --hw_version 1 --hw_version_str "1.0" --cert_declaration ./Chip-Test-CD-1037-A221.der --dac_cert ./Chip-DAC-NXP-1037-A221-Cert.der --dac_key ./Chip-DAC-NXP-1037-A221-Key-encrypted-blob.bin --pai_cert ./Chip-PAI-NXP-1037-A221-Cert.der --spake2p_path ./out/spake2p --unique_id "00112233445566778899aabbccddeeff" --dac_key_use_sss_blob --out ./factory_data_with_blob.bin
Please note that --dac_key
now points to a binary file that contains the encrypted blob.