Skip to content

Commit

Permalink
[nrfconnect] Factory data script fixes (#25795)
Browse files Browse the repository at this point in the history
* [nrf fromlist] [nrfconnect] Import spake2p.py as a module

In the factory data generation script, import spake2p.py
as a module instead of starting a new process. Also, update
the requirements.

* [nrfconnect] Fix factory data script after certificate renaming

The development certificate names now include the vendor ID
component.

Also, fix a syntax error due to using "is not" for literals.
  • Loading branch information
Damian-Nordic authored and pull[bot] committed Nov 13, 2023
1 parent 75c96d6 commit b3e4b39
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 35 deletions.
17 changes: 8 additions & 9 deletions config/nrfconnect/chip-module/generate_factory_data.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,19 @@ endif()

# for development purpose user can use default certs instead of generating or providing them
if(CONFIG_CHIP_FACTORY_DATA_USE_DEFAULT_CERTS)
# 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)
# all certs are located in ${CHIP_ROOT}/credentials/development/attestation
# it can be used during development without need to generate new certifications
string(APPEND script_args "--dac_cert \"${CHIP_ROOT}/credentials/development/attestation/Matter-Development-DAC-${raw_pid_upper}-Cert.der\"\n")
string(APPEND script_args "--dac_key \"${CHIP_ROOT}/credentials/development/attestation/Matter-Development-DAC-${raw_pid_upper}-Key.der\"\n")
string(APPEND script_args "--pai_cert \"${CHIP_ROOT}/credentials/development/attestation/Matter-Development-PAI-noPID-Cert.der\"\n")
string(APPEND script_args "--dac_cert \"${CHIP_ROOT}/credentials/development/attestation/Matter-Development-DAC-${raw_vid_upper}-${raw_pid_upper}-Cert.der\"\n")
string(APPEND script_args "--dac_key \"${CHIP_ROOT}/credentials/development/attestation/Matter-Development-DAC-${raw_vid_upper}-${raw_pid_upper}-Key.der\"\n")
string(APPEND script_args "--pai_cert \"${CHIP_ROOT}/credentials/development/attestation/Matter-Development-PAI-${raw_vid_upper}-noPID-Cert.der\"\n")
elseif(CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_USER)
string(APPEND script_args "--dac_cert \"${CONFIG_CHIP_FACTORY_DATA_USER_CERTS_DAC_CERT}\"\n")
string(APPEND script_args "--dac_key \"${CONFIG_CHIP_FACTORY_DATA_USER_CERTS_DAC_KEY}\"\n")
Expand All @@ -88,12 +92,7 @@ string(APPEND script_args "--include_passcode\n")
string(APPEND script_args "--overwrite\n")

# check if spake2 verifier should be generated using script
if(CONFIG_CHIP_FACTORY_DATA_GENERATE_SPAKE2_VERIFIER)
# request script to generate a new spake2_verifier
# by adding an argument to script_args
find_program(spake_exe NAMES spake2p REQUIRED)
string(APPEND script_args "--spake2p_path ${spake_exe}\n")
else()
if(NOT CONFIG_CHIP_FACTORY_DATA_GENERATE_SPAKE2_VERIFIER)
# Spake2 verifier should be provided using kConfig
string(APPEND script_args "--spake2_verifier \"${CONFIG_CHIP_DEVICE_SPAKE2_TEST_VERIFIER}\"\n")
endif()
Expand Down
6 changes: 3 additions & 3 deletions docs/guides/nrfconnect_factory_data_configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,9 +304,9 @@ $ python scripts/tools/nrfconnect/generate_nrfconnect_chip_factory_data.py \
--date "2022-02-02" \
--hw_ver 1 \
--hw_ver_str "prerelase" \
--dac_cert "credentials/development/attestation/Matter-Development-DAC-8006-Cert.der" \
--dac_key "credentials/development/attestation/Matter-Development-DAC-8006-Key.der" \
--pai_cert "credentials/development/attestation/Matter-Development-PAI-noPID-Cert.der" \
--dac_cert "credentials/development/attestation/Matter-Development-DAC-FFF1-8006-Cert.der" \
--dac_key "credentials/development/attestation/Matter-Development-DAC-FFF1-8006-Key.der" \
--pai_cert "credentials/development/attestation/Matter-Development-PAI-FFF1-noPID-Cert.der" \
--spake2_it 1000 \
--spake2_salt "U1BBS0UyUCBLZXkgU2FsdA==" \
--discriminator 0xF00 \
Expand Down
1 change: 1 addition & 0 deletions scripts/setup/requirements.nrfconnect.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
jsonschema>=4.4.0
cbor2>=5.4.3
ecdsa>=0.18.0
28 changes: 5 additions & 23 deletions scripts/tools/nrfconnect/generate_nrfconnect_chip_factory_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
INVALID_PASSCODES = [00000000, 11111111, 22222222, 33333333, 44444444,
55555555, 66666666, 77777777, 88888888, 99999999, 12345678, 87654321]

sys.path.insert(0, os.path.join(MATTER_ROOT, 'scripts', 'tools', 'spake2p'))
from spake2p import generate_verifier # noqa: E402 isort:skip


def get_raw_private_key_der(der_file: str, password: str):
""" Split given der file to get separated key pair consisting of public and private keys.
Expand Down Expand Up @@ -168,7 +171,7 @@ def gen_test_certs(chip_cert_exe: str,

# convert to .der files
for cert_k, cert_v in new_certificates.items():
action_type = "convert-cert" if cert_k.find("CERT") is not -1 else "convert-key"
action_type = "convert-cert" if cert_k.find("CERT") != -1 else "convert-key"
log.info(cert_v + ".der")
cmd = [chip_cert_exe, action_type,
cert_v + ".pem",
Expand All @@ -182,27 +185,6 @@ def gen_test_certs(chip_cert_exe: str,
new_certificates["PAI_CERT"] + ".der")


def gen_spake2p_verifier(passcode: int, it: int, salt: bytes) -> str:
""" Generate Spake2+ verifier using SPAKE2+ Python Tool
Args:
passcode (int): Pairing passcode using in Spake2+
it (int): Iteration counter for Spake2+ verifier generation
salt (str): Salt used to generate Spake2+ verifier
Returns:
verifier encoded in Base64
"""

cmd = [
os.path.join(MATTER_ROOT, 'scripts/tools/spake2p/spake2p.py'), 'gen-verifier',
'--passcode', str(passcode),
'--salt', base64.b64encode(salt).decode('ascii'),
'--iteration-count', str(it),
]
return subprocess.check_output(cmd)


class FactoryDataGenerator:
"""
Class to generate factory data from given arguments and generate a JSON file
Expand Down Expand Up @@ -355,7 +337,7 @@ def _add_entry(self, name: str, value: any):

def _generate_spake2_verifier(self):
""" If verifier has not been provided in arguments list it should be generated via external script """
return base64.b64decode(gen_spake2p_verifier(self._args.passcode, self._args.spake2_it, self._args.spake2_salt))
return generate_verifier(self._args.passcode, self._args.spake2_salt, self._args.spake2_it)

def _generate_rotating_device_uid(self):
""" If rotating device unique ID has not been provided it should be generated """
Expand Down

0 comments on commit b3e4b39

Please sign in to comment.