KW45xx and K32W1xx Load NBU image#
This notebook describes how to load NBU image to KW45xx/K32W1xx device.
Keys preparation#
First we need to generate Root of Trust Keys (RoTKs)/Super Root Keys (SRKs) and optionally Image Signing Key (ISK). In this example, we will use nxpcrypto app to generate secp384r1 keys (see How-to-get-keys-using-nxpcrypto). Script by default load 4 RoTKs and 1 ISK. Feel free to modify it according your needs. At least one RoTK is mandatory.
See the script’s comments and modify the script according to the application security requirements.
Based on loaded keys, ROTK value is calculated and loaded in the device fuses so that’s why keys cannot be changed anymore for the device.
%run ../init_notebook.ipynb
import os
import pprint
import yaml
pp = pprint.PrettyPrinter(indent=4)
WORKSPACE = "workspace/" # change this to path to your workspace
KEYS = "../_data/keys/ecc384/" # change this to path to your keys
INPUTS = "inputs/"
VERBOSITY = (
"-v" # verbosity of commands, might be -v or -vv for debug or blank for no additional info
)
# choose family (kw45xx or k32w1xx)
FAMILY = "kw45xx"
env: JUPYTER_SPSDK=1
Created `%!` as an alias for `%execute`.
# load generated key pair for ROTK0
ROTK0_PRIVATE_KEY_PATH = KEYS + "srk0_ecc384.pem"
ROTK0_PUBLIC_KEY_PATH = KEYS + "srk0_ecc384.pub"
# verify that keys were loaded
assert os.path.exists(ROTK0_PRIVATE_KEY_PATH)
assert os.path.exists(ROTK0_PUBLIC_KEY_PATH)
# load generated key pair for ROTK1
ROTK1_PRIVATE_KEY_PATH = KEYS + "srk1_ecc384.pem"
ROTK1_PUBLIC_KEY_PATH = KEYS + "srk1_ecc384.pub"
# verify that keys were loaded
assert os.path.exists(ROTK1_PRIVATE_KEY_PATH)
assert os.path.exists(ROTK1_PUBLIC_KEY_PATH)
# load generated key pair for ROTK2
ROTK2_PRIVATE_KEY_PATH = KEYS + "srk2_ecc384.pem"
ROTK2_PUBLIC_KEY_PATH = KEYS + "srk2_ecc384.pub"
# verify that keys were loaded
assert os.path.exists(ROTK2_PRIVATE_KEY_PATH)
assert os.path.exists(ROTK2_PUBLIC_KEY_PATH)
# load generated key pair for ROTK3
ROTK3_PRIVATE_KEY_PATH = KEYS + "srk3_ecc384.pem"
ROTK3_PUBLIC_KEY_PATH = KEYS + "srk3_ecc384.pub"
# verify that keys were loaded
assert os.path.exists(ROTK3_PRIVATE_KEY_PATH)
assert os.path.exists(ROTK3_PUBLIC_KEY_PATH)
# load generated key pair for ISK
ISK_PRIVATE_KEY_PATH = KEYS + "imgkey_ecc384.pem"
ISK_PUBLIC_KEY_PATH = KEYS + "imgkey_ecc384.pub"
# verify that keys were loaded
assert os.path.exists(ISK_PRIVATE_KEY_PATH)
assert os.path.exists(ISK_PUBLIC_KEY_PATH)
Certificates preparation#
Generate self-signed x509 certificate(s) containing public key for private key generated in previous step (ROTKX). Application nxpcrypto will be used. First step is to get a template.
# obtain a template for root cert ROTK0
ROOT0_CERT_CONFIG_PATH = WORKSPACE + "cert0_template.yml"
%! nxpcrypto $VERBOSITY cert get-template -o $ROOT0_CERT_CONFIG_PATH --force
# obtain a template for root cert ROTK1
ROOT1_CERT_CONFIG_PATH = WORKSPACE + "cert1_template.yml"
%! nxpcrypto $VERBOSITY cert get-template -o $ROOT1_CERT_CONFIG_PATH --force
# obtain a template for root cert ROTK2
ROOT2_CERT_CONFIG_PATH = WORKSPACE + "cert2_template.yml"
%! nxpcrypto $VERBOSITY cert get-template -o $ROOT2_CERT_CONFIG_PATH --force
# obtain a template for root cert ROTK3
ROOT3_CERT_CONFIG_PATH = WORKSPACE + "cert3_template.yml"
%! nxpcrypto $VERBOSITY cert get-template -o $ROOT3_CERT_CONFIG_PATH --force
# obtain a template for root cert ISK
ISK_CERT_CONFIG_PATH = WORKSPACE + "sign_cert_template.yml"
%! nxpcrypto $VERBOSITY cert get-template -o $ISK_CERT_CONFIG_PATH --force
nxpcrypto -v cert get-template -o workspace/cert0_template.yml --force
INFO:spsdk.apps.nxpcertgen:Creating Certificate template...
The configuration template file has been created: workspace/cert0_template.yml
nxpcrypto -v cert get-template -o workspace/cert1_template.yml --force
INFO:spsdk.apps.nxpcertgen:Creating Certificate template...
The configuration template file has been created: workspace/cert1_template.yml
nxpcrypto -v cert get-template -o workspace/cert2_template.yml --force
INFO:spsdk.apps.nxpcertgen:Creating Certificate template...
The configuration template file has been created: workspace/cert2_template.yml
nxpcrypto -v cert get-template -o workspace/cert3_template.yml --force
INFO:spsdk.apps.nxpcertgen:Creating Certificate template...
The configuration template file has been created: workspace/cert3_template.yml
nxpcrypto -v cert get-template -o workspace/sign_cert_template.yml --force
INFO:spsdk.apps.nxpcertgen:Creating Certificate template...
The configuration template file has been created: workspace/sign_cert_template.yml
Configuration template for certificates should look like this:
# This is template for configuration file used for generating certificates
# ==============================================
# Issuer identification fields
# ==============================================
# All available option can be found within class NameOID in
# cryptography/src/cryptography/x509/oid.py at https://github.com/pyca/cryptography
issuer:
COMMON_NAME: NXP
COUNTRY_NAME: CZ
LOCALITY_NAME: Roznov pod Radhostem
STATE_OR_PROVINCE_NAME: Morava
STREET_ADDRESS: 1.maje 1009
ORGANIZATION_NAME: SPSDK Team
# ==============================================
# Subject identification fields
# ==============================================
# All available option can be found within class NameOID in
# cryptography/src/cryptography/x509/oid.py at https://github.com/pyca/cryptography
subject:
COMMON_NAME: NXP - SPSDK
COUNTRY_NAME: CZ
LOCALITY_NAME: Roznov pod Radhostem
STATE_OR_PROVINCE_NAME: Morava
STREET_ADDRESS: 1.maje 1009
ORGANIZATION_NAME: SPSDK Team
POSTAL_CODE: 756 61
# ==============================================
# The certificate settings
# ==============================================
# Path, where issuer private key is stored
issuer_private_key: issuer_key.pem
# Path, where subject public key is stored
subject_public_key: subject_key.pub
# Serial number of certificate
serial_number: 12346578
# Validity duration in days
duration: 3650
# ==============================================
# Certificate basic extensions
# ==============================================
extensions:
BASIC_CONSTRAINTS:
# Delegate certificate as a signing authority to create an intermediate certificates.
ca: false # Valid values true|false
# Integer length of the path of certificate signature from a given certificate, back to the root certificate
path_length: 0
Certificates are in x.509 format and should be DER encoded.
ROOT_0_CERT_PATH = WORKSPACE + "ec_secp384r1_cert0.pem"
ROOT_1_CERT_PATH = WORKSPACE + "ec_secp384r1_cert1.pem"
ROOT_2_CERT_PATH = WORKSPACE + "ec_secp384r1_cert2.pem"
ROOT_3_CERT_PATH = WORKSPACE + "ec_secp384r1_cert3.pem"
ISK_CERT_PATH = WORKSPACE + "ec_secp384r1_sign_cert.pem"
# Fill the configuration file accordingly
assert os.path.exists(ROOT0_CERT_CONFIG_PATH)
assert os.path.exists(ROOT1_CERT_CONFIG_PATH)
assert os.path.exists(ROOT2_CERT_CONFIG_PATH)
assert os.path.exists(ROOT3_CERT_CONFIG_PATH)
# Create configuration for root certificate 0
with open(ROOT0_CERT_CONFIG_PATH) as cert_config:
# load yaml configuration to dictionary
cert = yaml.safe_load(cert_config)
# change path to private and public keys
cert["issuer_private_key"] = ROTK0_PRIVATE_KEY_PATH
cert["subject_public_key"] = ROTK0_PUBLIC_KEY_PATH
with open(ROOT0_CERT_CONFIG_PATH, "w+") as cert_config:
print("Root Certificate config:")
pp.pprint(cert)
# dump the dictionary back to YAML
yaml.dump(cert, cert_config)
# Create configuration for root certificate 1
with open(ROOT1_CERT_CONFIG_PATH) as cert_config:
# load yaml configuration to dictionary
cert = yaml.safe_load(cert_config)
# change path to private and public keys
cert["issuer_private_key"] = ROTK1_PRIVATE_KEY_PATH
cert["subject_public_key"] = ROTK1_PUBLIC_KEY_PATH
with open(ROOT1_CERT_CONFIG_PATH, "w+") as cert_config:
print("Root Certificate config:")
pp.pprint(cert)
# dump the dictionary back to YAML
yaml.dump(cert, cert_config)
# Create configuration for root certificate 2
with open(ROOT2_CERT_CONFIG_PATH) as cert_config:
# load yaml configuration to dictionary
cert = yaml.safe_load(cert_config)
# change path to private and public keys
cert["issuer_private_key"] = ROTK2_PRIVATE_KEY_PATH
cert["subject_public_key"] = ROTK2_PUBLIC_KEY_PATH
with open(ROOT2_CERT_CONFIG_PATH, "w+") as cert_config:
print("Root Certificate config:")
pp.pprint(cert)
# dump the dictionary back to YAML
yaml.dump(cert, cert_config)
# Create configuration for root certificate 3
with open(ROOT3_CERT_CONFIG_PATH) as cert_config:
# load yaml configuration to dictionary
cert = yaml.safe_load(cert_config)
# change path to private and public keys
cert["issuer_private_key"] = ROTK3_PRIVATE_KEY_PATH
cert["subject_public_key"] = ROTK3_PUBLIC_KEY_PATH
with open(ROOT3_CERT_CONFIG_PATH, "w+") as cert_config:
print("Root Certificate config:")
pp.pprint(cert)
# dump the dictionary back to YAML
yaml.dump(cert, cert_config)
# Create configuration for ISK certificate
with open(ISK_CERT_CONFIG_PATH) as cert_config:
# load yaml configuration to dictionary
cert = yaml.safe_load(cert_config)
# change path to private and public keys
cert["issuer_private_key"] = ISK_PRIVATE_KEY_PATH
cert["subject_public_key"] = ISK_PUBLIC_KEY_PATH
with open(ISK_CERT_CONFIG_PATH, "w+") as cert_config:
print("Root Certificate config:")
pp.pprint(cert)
# dump the dictionary back to YAML
yaml.dump(cert, cert_config)
# Generate root certificates 0
%! nxpcrypto $VERBOSITY cert generate -c $ROOT0_CERT_CONFIG_PATH -o $ROOT_0_CERT_PATH --force
# Generate root certificates 1
%! nxpcrypto $VERBOSITY cert generate -c $ROOT1_CERT_CONFIG_PATH -o $ROOT_1_CERT_PATH --force
# Generate root certificates 2
%! nxpcrypto $VERBOSITY cert generate -c $ROOT2_CERT_CONFIG_PATH -o $ROOT_2_CERT_PATH --force
# Generate root certificates 3
%! nxpcrypto $VERBOSITY cert generate -c $ROOT3_CERT_CONFIG_PATH -o $ROOT_3_CERT_PATH --force
# Generate ISK certificate
%! nxpcrypto $VERBOSITY cert generate -c $ISK_CERT_CONFIG_PATH -o $ISK_CERT_PATH --force
# verify that certificates were generated
assert os.path.exists(ROOT_0_CERT_PATH)
assert os.path.exists(ROOT_1_CERT_PATH)
assert os.path.exists(ROOT_2_CERT_PATH)
assert os.path.exists(ROOT_3_CERT_PATH)
assert os.path.exists(ISK_CERT_PATH)
Root Certificate config:
{ 'duration': 3650,
'extensions': {'BASIC_CONSTRAINTS': {'ca': False, 'path_length': None}},
'issuer': { 'COMMON_NAME': 'NXP',
'COUNTRY_NAME': 'CZ',
'LOCALITY_NAME': 'Roznov pod Radhostem',
'ORGANIZATION_NAME': 'SPSDK Team',
'STATE_OR_PROVINCE_NAME': 'Morava',
'STREET_ADDRESS': '1.maje 1009'},
'issuer_private_key': 'workspace/_data/keys/ecc384/srk0_ecc384.pem',
'serial_number': 12346578,
'subject': { 'COMMON_NAME': 'NXP - SPSDK',
'COUNTRY_NAME': 'CZ',
'LOCALITY_NAME': 'Roznov pod Radhostem',
'ORGANIZATION_NAME': 'SPSDK Team',
'POSTAL_CODE': '756 61',
'STATE_OR_PROVINCE_NAME': 'Morava',
'STREET_ADDRESS': '1.maje 1009'},
'subject_public_key': 'workspace/_data/keys/ecc384/srk0_ecc384.pub'}
Root Certificate config:
{ 'duration': 3650,
'extensions': {'BASIC_CONSTRAINTS': {'ca': False, 'path_length': None}},
'issuer': { 'COMMON_NAME': 'NXP',
'COUNTRY_NAME': 'CZ',
'LOCALITY_NAME': 'Roznov pod Radhostem',
'ORGANIZATION_NAME': 'SPSDK Team',
'STATE_OR_PROVINCE_NAME': 'Morava',
'STREET_ADDRESS': '1.maje 1009'},
'issuer_private_key': 'workspace/_data/keys/ecc384/srk1_ecc384.pem',
'serial_number': 12346578,
'subject': { 'COMMON_NAME': 'NXP - SPSDK',
'COUNTRY_NAME': 'CZ',
'LOCALITY_NAME': 'Roznov pod Radhostem',
'ORGANIZATION_NAME': 'SPSDK Team',
'POSTAL_CODE': '756 61',
'STATE_OR_PROVINCE_NAME': 'Morava',
'STREET_ADDRESS': '1.maje 1009'},
'subject_public_key': 'workspace/_data/keys/ecc384/srk1_ecc384.pub'}
Root Certificate config:
{ 'duration': 3650,
'extensions': {'BASIC_CONSTRAINTS': {'ca': False, 'path_length': None}},
'issuer': { 'COMMON_NAME': 'NXP',
'COUNTRY_NAME': 'CZ',
'LOCALITY_NAME': 'Roznov pod Radhostem',
'ORGANIZATION_NAME': 'SPSDK Team',
'STATE_OR_PROVINCE_NAME': 'Morava',
'STREET_ADDRESS': '1.maje 1009'},
'issuer_private_key': 'workspace/_data/keys/ecc384/srk2_ecc384.pem',
'serial_number': 12346578,
'subject': { 'COMMON_NAME': 'NXP - SPSDK',
'COUNTRY_NAME': 'CZ',
'LOCALITY_NAME': 'Roznov pod Radhostem',
'ORGANIZATION_NAME': 'SPSDK Team',
'POSTAL_CODE': '756 61',
'STATE_OR_PROVINCE_NAME': 'Morava',
'STREET_ADDRESS': '1.maje 1009'},
'subject_public_key': 'workspace/_data/keys/ecc384/srk2_ecc384.pub'}
Root Certificate config:
{ 'duration': 3650,
'extensions': {'BASIC_CONSTRAINTS': {'ca': False, 'path_length': None}},
'issuer': { 'COMMON_NAME': 'NXP',
'COUNTRY_NAME': 'CZ',
'LOCALITY_NAME': 'Roznov pod Radhostem',
'ORGANIZATION_NAME': 'SPSDK Team',
'STATE_OR_PROVINCE_NAME': 'Morava',
'STREET_ADDRESS': '1.maje 1009'},
'issuer_private_key': 'workspace/_data/keys/ecc384/srk3_ecc384.pem',
'serial_number': 12346578,
'subject': { 'COMMON_NAME': 'NXP - SPSDK',
'COUNTRY_NAME': 'CZ',
'LOCALITY_NAME': 'Roznov pod Radhostem',
'ORGANIZATION_NAME': 'SPSDK Team',
'POSTAL_CODE': '756 61',
'STATE_OR_PROVINCE_NAME': 'Morava',
'STREET_ADDRESS': '1.maje 1009'},
'subject_public_key': 'workspace/_data/keys/ecc384/srk3_ecc384.pub'}
Root Certificate config:
{ 'duration': 3650,
'extensions': {'BASIC_CONSTRAINTS': {'ca': False, 'path_length': None}},
'issuer': { 'COMMON_NAME': 'NXP',
'COUNTRY_NAME': 'CZ',
'LOCALITY_NAME': 'Roznov pod Radhostem',
'ORGANIZATION_NAME': 'SPSDK Team',
'STATE_OR_PROVINCE_NAME': 'Morava',
'STREET_ADDRESS': '1.maje 1009'},
'issuer_private_key': 'workspace/_data/keys/ecc384/imgkey_ecc384.pem',
'serial_number': 12346578,
'subject': { 'COMMON_NAME': 'NXP - SPSDK',
'COUNTRY_NAME': 'CZ',
'LOCALITY_NAME': 'Roznov pod Radhostem',
'ORGANIZATION_NAME': 'SPSDK Team',
'POSTAL_CODE': '756 61',
'STATE_OR_PROVINCE_NAME': 'Morava',
'STREET_ADDRESS': '1.maje 1009'},
'subject_public_key': 'workspace/_data/keys/ecc384/imgkey_ecc384.pub'}
nxpcrypto -v cert generate -c workspace/cert0_template.yml -o workspace/ec_secp384r1_cert0.pem --force
INFO:spsdk.apps.nxpcertgen:Generating Certificate...
INFO:spsdk.apps.nxpcertgen:Loading configuration from yml file...
INFO:spsdk.apps.nxpcertgen:Saving the generated certificate to the specified path...
INFO:spsdk.apps.nxpcertgen:Certificate generated successfully...
The certificate file has been created: workspace/ec_secp384r1_cert0.pem
nxpcrypto -v cert generate -c workspace/cert1_template.yml -o workspace/ec_secp384r1_cert1.pem --force
INFO:spsdk.apps.nxpcertgen:Generating Certificate...
INFO:spsdk.apps.nxpcertgen:Loading configuration from yml file...
INFO:spsdk.apps.nxpcertgen:Saving the generated certificate to the specified path...
INFO:spsdk.apps.nxpcertgen:Certificate generated successfully...
The certificate file has been created: workspace/ec_secp384r1_cert1.pem
nxpcrypto -v cert generate -c workspace/cert2_template.yml -o workspace/ec_secp384r1_cert2.pem --force
INFO:spsdk.apps.nxpcertgen:Generating Certificate...
INFO:spsdk.apps.nxpcertgen:Loading configuration from yml file...
INFO:spsdk.apps.nxpcertgen:Saving the generated certificate to the specified path...
INFO:spsdk.apps.nxpcertgen:Certificate generated successfully...
The certificate file has been created: workspace/ec_secp384r1_cert2.pem
nxpcrypto -v cert generate -c workspace/cert3_template.yml -o workspace/ec_secp384r1_cert3.pem --force
INFO:spsdk.apps.nxpcertgen:Generating Certificate...
INFO:spsdk.apps.nxpcertgen:Loading configuration from yml file...
INFO:spsdk.apps.nxpcertgen:Saving the generated certificate to the specified path...
INFO:spsdk.apps.nxpcertgen:Certificate generated successfully...
The certificate file has been created: workspace/ec_secp384r1_cert3.pem
nxpcrypto -v cert generate -c workspace/sign_cert_template.yml -o workspace/ec_secp384r1_sign_cert.pem --force
INFO:spsdk.apps.nxpcertgen:Generating Certificate...
INFO:spsdk.apps.nxpcertgen:Loading configuration from yml file...
INFO:spsdk.apps.nxpcertgen:Saving the generated certificate to the specified path...
INFO:spsdk.apps.nxpcertgen:Certificate generated successfully...
The certificate file has been created: workspace/ec_secp384r1_sign_cert.pem
Generate SB3KDK#
To generate SB3KDK use the below script. Key generation can be done only once on the beginning, then is SB3KDK key loaded in device fuses and key cannot be changed anymore for device.
import binascii
SB3KDK_KEY_PATH = WORKSPACE + "sb3kdk.txt"
with open(SB3KDK_KEY_PATH, "wb") as f:
f.write(binascii.b2a_hex(os.urandom(32)))
assert os.path.exists(SB3KDK_KEY_PATH)
Prepare SB3.1 configuration file#
In order to generate SB3.1 file, npximage tool is used. The nxpimage tool generates the SB3.1 file according to the configuration file. Let’s create a template for SB3.1. Modify examples according your needs.
SB31_TEMPLATE_DEFAULT_PATH = WORKSPACE + "sb31_config_default.yml"
%! nxpimage $VERBOSITY sb31 get-template -f $FAMILY -o $SB31_TEMPLATE_DEFAULT_PATH --force
# For K32W1XX device:
# %! nxpimage $VERBOSITY sb31 get-template -f $FAMILY -o $SB31_TEMPLATE_DEFAULT_PATH --force
assert os.path.exists(SB31_TEMPLATE_DEFAULT_PATH)
nxpimage -v sb31 get-template -f kw45xx -o workspace/sb31_config_default.yml --force
Creating workspace/sb31_config_default.yml template file.
For signed container scenario, we need to create a certificate blok separately. In order to do this, use nxpimage cert-block get-template command as described below.
CERT_BLOCK_TEMPLATE_DEFAULT = WORKSPACE + "cert_block_default_kw45.yaml"
%! nxpimage $VERBOSITY cert-block get-template -f $FAMILY -o $CERT_BLOCK_TEMPLATE_DEFAULT --force
nxpimage -v cert-block get-template -f kw45xx -o workspace/cert_block_default_kw45.yaml --force
Creating workspace/cert_block_default_kw45.yaml template file.
In our case, we modified these items in the certification block configuration template:
CERT_BLOCK_TEMPLATE = INPUTS + "cert_block_kw45.yaml"
assert os.path.exists(CERT_BLOCK_TEMPLATE)
Choose whether you want to use ISK. If so, define the path to the ISK public key.

Define paths to keys and choose index of main certification key.


Define output path where certification block will be saved.

Our case does not require the definition of the following items, but it would be appropriate to consider their use for the given case.

In our case, we modified these items in the SB3.1 configuration template:
SB31_TEMPLATE_PATH = INPUTS + "sb31_config.yml"
assert os.path.exists(SB31_TEMPLATE_PATH)
Define output path where final sb31 file will be saved.

Define path to the main certificate private key or signature provider.

Define path to the certificate block.

Specify path to the SB3KDK that was generated in the previous steps.

Value of KDK is used as key properties for key derivation process.

We used the commands erase to erase specified size of flash and load to load the file to the defined memory address.

SB3.1 generation#
We have created certificates and keys required for the creation of SB3.1 file. Let’s create a SB3.1.
SB31_FILE_PATH = WORKSPACE + "sb3.sb3"
%! nxpimage sb31 export -c $SB31_TEMPLATE_PATH
assert os.path.exists(SB31_FILE_PATH)
nxpimage sb31 export -c inputs/sb31_config.yml
RKTH: 89e4983eb79bed26fc25cf6ba9b89ddb6727c80ed7c786a6f3c77c09bba0e832b468895926a6568031c0f955a614434e
Success. (Secure binary 3.1: workspace/sb3.sb3 created.)
Device preparation#
Now it’s time to prepare the device. In this example we will use KW45xx-EVK/K32W1xx board.
First step is to enter ISP mode, this could be achieved by:
1 ) Put JP25 to (1-2)
2 ) Reset the board with SW4 pressed


Use app nxpdevscan to check if the device is connected to the PC in ISP mode.
# check if the device is connected and detected by PC
%! nxpdevscan
nxpdevscan
-------- Connected NXP SDIO Devices --------
-------- Connected NXP USB Devices --------
-------- Connected NXP UART Devices --------
Port: COM10
Type: mboot device
-------- Connected NXP SIO Devices --------
# choose com port
UART_CONNECTION = "-p com10"
%! blhost $UART_CONNECTION get-property current-version
blhost -p com10 get-property current-version
Response status = 0 (0x0) Success.
Response word 1 = 1258488064 (0x4b030100)
Current Version = K3.1.0
Program device fuses with keys/RKTH generated in previous steps#
To program fuses blhost tool is used. Device needs to be in ISP mode, where it can communicate with blhost and process blhost commands. To serve the purpose of this document, ISP communication only over UART peripheral is considered for scripts. Also, accurate COMx port must be used.
WARNING!!! This step is destructive operation (burning fuses), be sure that you set values of SB3KDK and RoTKH correctly in script as printed in output from nxpimage
# Increase voltage for fuse burning
blhost $UART_CONNECTION set-property 0x16 1
# Program SB3KDK (CUST_PROD_OEMFW_ENC_SK)
# Put value SB3KDK generated by nxpimage
blhost $UART_CONNECTION fuse-program 0x20 [[c2d3eafa44cedc1edf237a7655acf18a1f41e85ea605dcc3bf473e4618b7882f]]
# Program RKTH (CUST_PROD_OEMFW_AUTH_PUK)
# Put value RKTH generated by nxpimage
blhost $UART_CONNECTION fuse-program 0x1F [[89e4983eb79bed26fc25cf6ba9b89ddb6727c80ed7c786a6f3c77c09bba0e832b468895926a6568031c0f955a614434e]]
# Set voltage to normal value
blhost $UART_CONNECTION set-property 0x16 0
Send SB3.1 file to device#
Last step is to uploads SB3.1 file with NBU image to device.
# uploads SB3.1
%! blhost $UART_CONNECTION receive-sb-file $SB31_FILE_PATH
blhost -p com10 receive-sb-file workspace/sb3.sb3
Sending SB file
Response status = 0 (0x0) Success.