blob: ea1e35a797ab78386c092ff498c3a15d4f57d28f [file] [log] [blame]
#
# Copyright (c) 2024 Project CHIP Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Generate certificates based on factory data given via Kconfigs.
#
# This function creates a list of arguments for external script and then run it to generate certificates.
#
# During generation process a some file will be created in zephyr's build directory:
# - Chip-PAI-NXP-<VID>-<PID>-Cert.der
# - Chip-PAI-NXP-<VID>-<PID>-Key.der
# - Chip-DAC-NXP-<VID>-<PID>-Cert.der
# - Chip-DAC-NXP-<VID>-<PID>-Key.der
#
# [Args]:
# script_path - a path to script that generates the certificates.
# output_path - a path to output directory, where generated certificates will be stored.
function(nxp_generate_certs script_path output_path)
if(NOT EXISTS ${CHIP_ROOT}/out/chip-cert)
message(FATAL_ERROR "Couldn't find chip-cert in ${CHIP_ROOT}/out folder.
Run following command from ${CHIP_ROOT} to build it:
gn gen out
ninja -C out chip-cert")
endif()
# generate all script arguments
set(script_args)
string(APPEND script_args "--gen_cd\n")
string(APPEND script_args "--cd_type \"1\"\n")
string(APPEND script_args "--chip_cert_path ${CHIP_ROOT}/out/chip-cert\n")
string(APPEND script_args "--vendor_id ${CONFIG_CHIP_DEVICE_VENDOR_ID}\n")
string(APPEND script_args "--product_id ${CONFIG_CHIP_DEVICE_PRODUCT_ID}\n")
string(APPEND script_args "--vendor_name \"${CONFIG_CHIP_DEVICE_VENDOR_NAME}\"\n")
string(APPEND script_args "--product_name \"${CONFIG_CHIP_DEVICE_PRODUCT_NAME}\"\n")
string(APPEND script_args "--device_type \"${CONFIG_CHIP_DEVICE_TYPE}\"\n")
string(APPEND script_args "--output \"${output_path}\"\n")
# convert decimal VID to its hexadecimal representation to find out certification files in repository
math(EXPR LOCAL_VID "${CONFIG_CHIP_DEVICE_VENDOR_ID}" OUTPUT_FORMAT HEXADECIMAL)
string(SUBSTRING ${LOCAL_VID} 2 -1 raw_vid)
string(TOUPPER ${raw_vid} raw_vid_upper)
# convert decimal PID to its hexadecimal representation to find out certification files in repository
math(EXPR LOCAL_PID "${CONFIG_CHIP_DEVICE_PRODUCT_ID}" OUTPUT_FORMAT HEXADECIMAL)
string(SUBSTRING ${LOCAL_PID} 2 -1 raw_pid)
string(TOUPPER ${raw_pid} raw_pid_upper)
# execute the script which can generate the certificates
separate_arguments(separated_script_args NATIVE_COMMAND ${script_args})
add_custom_command(
OUTPUT
${output_path}/Chip-PAI-NXP-${raw_vid_upper}-${raw_pid_upper}-Cert.pem
${output_path}/Chip-PAI-NXP-${raw_vid_upper}-${raw_pid_upper}-Key.pem
${output_path}/Chip-DAC-NXP-${raw_vid_upper}-${raw_pid_upper}-Cert.pem
${output_path}/Chip-DAC-NXP-${raw_vid_upper}-${raw_pid_upper}-Key.pem
${output_path}/Chip-PAI-NXP-${raw_vid_upper}-${raw_pid_upper}-Cert.der
${output_path}/Chip-PAI-NXP-${raw_vid_upper}-${raw_pid_upper}-Key.der
${output_path}/Chip-DAC-NXP-${raw_vid_upper}-${raw_pid_upper}-Cert.der
${output_path}/Chip-DAC-NXP-${raw_vid_upper}-${raw_pid_upper}-Key.der
DEPENDS ${script_path}
COMMAND ${Python3_EXECUTABLE} ${script_path} ${separated_script_args}
COMMENT "Generating new certificates..."
)
add_custom_target(chip-certificates ALL
DEPENDS
${output_path}/Chip-PAI-NXP-${raw_vid_upper}-${raw_pid_upper}-Cert.pem
${output_path}/Chip-PAI-NXP-${raw_vid_upper}-${raw_pid_upper}-Key.pem
${output_path}/Chip-DAC-NXP-${raw_vid_upper}-${raw_pid_upper}-Cert.pem
${output_path}/Chip-DAC-NXP-${raw_vid_upper}-${raw_pid_upper}-Key.pem
${output_path}/Chip-PAI-NXP-${raw_vid_upper}-${raw_pid_upper}-Cert.der
${output_path}/Chip-PAI-NXP-${raw_vid_upper}-${raw_pid_upper}-Key.der
${output_path}/Chip-DAC-NXP-${raw_vid_upper}-${raw_pid_upper}-Cert.der
${output_path}/Chip-DAC-NXP-${raw_vid_upper}-${raw_pid_upper}-Key.der
)
endfunction()
# Create a .bin file with factory data in KLV format.
#
# This function creates a .bin file from given Kconfig.
#
# During generation process, following files will be created in zephyr's build directory:
# - <factory_data_target>.bin a binary file containing all raw factory data in KLV format.
#
# [Args]:
# script_path - a path to script that makes a factory data .bin file from given arguments.
# output_path - a path to output directory, where created bin file will be stored.
function(nxp_generate_factory_data_bin script_path output_path)
if(NOT EXISTS ${CHIP_ROOT}/out/spake2p)
message(FATAL_ERROR "Couldn't find spake2p in ${CHIP_ROOT}/out folder.
Run following command from ${CHIP_ROOT} to build it:
gn gen out
ninja -C out spake2p")
endif()
# convert decimal VID to its hexadecimal representation to find out certification files in repository
math(EXPR LOCAL_VID "${CONFIG_CHIP_DEVICE_VENDOR_ID}" OUTPUT_FORMAT HEXADECIMAL)
string(SUBSTRING ${LOCAL_VID} 2 -1 raw_vid)
string(TOUPPER ${raw_vid} raw_vid_upper)
# convert decimal PID to its hexadecimal representation to find out certification files in repository
math(EXPR LOCAL_PID "${CONFIG_CHIP_DEVICE_PRODUCT_ID}" OUTPUT_FORMAT HEXADECIMAL)
string(SUBSTRING ${LOCAL_PID} 2 -1 raw_pid)
string(TOUPPER ${raw_pid} raw_pid_upper)
# generate all script arguments
set(script_args)
string(APPEND script_args "--it \"${CONFIG_CHIP_DEVICE_SPAKE2_IT}\"\n")
string(APPEND script_args "--salt \"${CONFIG_CHIP_DEVICE_SPAKE2_SALT}\"\n")
string(APPEND script_args "--discriminator ${CONFIG_CHIP_DEVICE_DISCRIMINATOR}\n")
string(APPEND script_args "--passcode ${CONFIG_CHIP_DEVICE_SPAKE2_PASSCODE}\n")
string(APPEND script_args "--vid ${CONFIG_CHIP_DEVICE_VENDOR_ID}\n")
string(APPEND script_args "--pid ${CONFIG_CHIP_DEVICE_PRODUCT_ID}\n")
string(APPEND script_args "--vendor_name \"${CONFIG_CHIP_DEVICE_VENDOR_NAME}\"\n")
string(APPEND script_args "--product_name \"${CONFIG_CHIP_DEVICE_PRODUCT_NAME}\"\n")
string(APPEND script_args "--hw_version ${CONFIG_CHIP_DEVICE_HARDWARE_VERSION}\n")
string(APPEND script_args "--hw_version_str \"${CONFIG_CHIP_DEVICE_HARDWARE_VERSION_STRING}\"\n")
string(APPEND script_args "--spake2p_path \"${CHIP_ROOT}/out/spake2p\"\n")
string(APPEND script_args "--serial_num \"${CONFIG_CHIP_DEVICE_SERIAL_NUMBER}\"\n")
string(APPEND script_args "--date \"${CONFIG_CHIP_DEVICE_MANUFACTURING_DATE}\"\n")
string(APPEND script_args "--unique_id \"${CONFIG_CHIP_DEVICE_ROTATING_DEVICE_UID}\"\n")
string(APPEND script_args "--product_finish ${CONFIG_CHIP_DEVICE_PRODUCT_FINISH}\n")
string(APPEND script_args "--product_url ${CONFIG_CHIP_DEVICE_PRODUCT_URL}\n")
string(APPEND script_args "--product_label ${CONFIG_CHIP_DEVICE_PRODUCT_LABEL}\n")
string(APPEND script_args "--part_number ${CONFIG_CHIP_DEVICE_PART_NUMBER}\n")
string(APPEND script_args "--out \"${output_path}/factory_data.bin\"\n")
# for development purpose user can use default certs instead of generating or providing them
if(CONFIG_CHIP_FACTORY_DATA_USE_DEFAULT_CERTS)
# all certs are located in ${CHIP_ROOT}/credentials/development/attestation
# it can be used during development without need to generate new certifications
set(cd_cert ${CHIP_ROOT}/credentials/development/cd-certs/Chip-Test-CD-Cert.der)
set(dac_cert ${CHIP_ROOT}/credentials/development/attestation/Matter-Development-DAC-${raw_vid_upper}-${raw_pid_upper}-Cert.der)
set(dac_key ${CHIP_ROOT}/credentials/development/attestation/Matter-Development-DAC-${raw_vid_upper}-${raw_pid_upper}-Key.der)
set(pai_cert ${CHIP_ROOT}/credentials/development/attestation/Matter-Development-PAI-${raw_vid_upper}-noPID-Cert.der)
elseif(CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_USER)
set(cd_cert ${CONFIG_CHIP_FACTORY_DATA_USER_CERTS_CD_CERT})
set(dac_cert ${CONFIG_CHIP_FACTORY_DATA_USER_CERTS_DAC_CERT})
set(dac_key ${CONFIG_CHIP_FACTORY_DATA_USER_CERTS_DAC_KEY})
set(pai_cert ${CONFIG_CHIP_FACTORY_DATA_USER_CERTS_PAI_CERT})
elseif(CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_GENERATED)
set(cd_cert ${output_path}/Chip-Test-CD-${raw_vid_upper}-${raw_pid_upper}.der)
set(dac_cert ${output_path}/Chip-DAC-NXP-${raw_vid_upper}-${raw_pid_upper}-Cert.der)
set(dac_key ${output_path}/Chip-DAC-NXP-${raw_vid_upper}-${raw_pid_upper}-Key.der)
set(pai_cert ${output_path}/Chip-PAI-NXP-${raw_vid_upper}-${raw_pid_upper}-Cert.der)
else()
message(FATAL_ERROR "Either CONFIG_CHIP_FACTORY_DATA_USE_DEFAULT_CERTS or CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_USER
or CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_GENERATED must be defined.
See ${CHIP_ROOT}/config/nxp/chip-module/Kconfig for details.")
endif()
string(APPEND script_args "--cert_declaration \"${cd_cert}\"\n")
string(APPEND script_args "--dac_cert \"${dac_cert}\"\n")
string(APPEND script_args "--dac_key \"${dac_key}\"\n")
string(APPEND script_args "--pai_cert \"${pai_cert}\"\n")
# check if spake2 verifier should be generated using script
if(NOT CONFIG_CHIP_FACTORY_DATA_GENERATE_SPAKE2_VERIFIER)
# Spake2 verifier should be provided using Kconfig
string(APPEND script_args "--spake2p_verifier \"${CONFIG_CHIP_DEVICE_SPAKE2_TEST_VERIFIER}\"\n")
endif()
if(CONFIG_CHIP_ENCRYPTED_FACTORY_DATA)
if(NOT CONFIG_CHIP_ENCRYPTED_FACTORY_DATA_AES128_KEY)
message(FATAL_ERROR "CONFIG_CHIP_ENCRYPTED_FACTORY_DATA_AES128_KEY is required when using CONFIG_CHIP_ENCRYPTED_FACTORY_DATA !")
endif()
string(APPEND script_args "--aes128_key \"${CONFIG_CHIP_ENCRYPTED_FACTORY_DATA_AES128_KEY}\"\n")
endif()
if(CONFIG_CHIP_DEVICE_PRODUCT_COLOR)
string(APPEND script_args "--product_primary_color ${CONFIG_CHIP_DEVICE_PRODUCT_COLOR}\n")
endif()
# execute the script which can generate the factory_data.bin file
separate_arguments(separated_script_args NATIVE_COMMAND ${script_args})
add_custom_command(
OUTPUT ${output_path}/factory_data.bin
DEPENDS ${script_path}
COMMAND ${Python3_EXECUTABLE} ${script_path} ${separated_script_args}
COMMENT "Generating new Factory Data..."
)
add_custom_target(factory_data ALL
DEPENDS ${output_path}/factory_data.bin
)
if(CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_GENERATED)
# Make sure certificates are generated before trying to generate factory data
add_dependencies(factory_data chip-certificates)
endif()
endfunction()
# Generate factory data partition using given args
#
# During generation process a some file will be created in zephyr's build directory:
# - factory_data.bin: a raw binary file containing the factory data partition
# - CD, PAI, DEC certificates if CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_GENERATED is set
#
function(nxp_generate_factory_data)
find_package(Python REQUIRED)
# CHIP_ROOT must be provided as a reference set all localization of scripts
if(NOT CHIP_ROOT)
message(FATAL_ERROR "CHIP_ROOT variable is not set, please add it to CMakeLists.txt file")
endif()
# Localize all scripts needed to generate factory data partition
set(GENERATE_CERTS_SCRIPT_PATH ${CHIP_ROOT}/scripts/tools/nxp/generate_certs.py)
set(GENERATE_FDATA_SCRIPT_PATH ${CHIP_ROOT}/scripts/tools/nxp/factory_data_generator/generate.py)
set(OUTPUT_FILE_PATH ${APPLICATION_BINARY_DIR}/zephyr)
if(CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_GENERATED)
# Generate certificates
nxp_generate_certs(${GENERATE_CERTS_SCRIPT_PATH} ${OUTPUT_FILE_PATH})
endif()
nxp_generate_factory_data_bin(${GENERATE_FDATA_SCRIPT_PATH} ${OUTPUT_FILE_PATH})
endfunction()