LPC55Sxx Secure Firmware Update

This notebook describes how to create secure container for firmware update on LPC55Sxx devices using the SPSDK command line utilities, it is based on the application note https://www.nxp.com/docs/en/application-note/AN12283.pdf.

Secure Boot Setup

We need to setup secure boot first. This is better described in “lpc55sx_secure_boot.ipynb” notebook. So, let’s execute it first.

[74]:
%run ./lpc55sxx_secure_boot.ipynb
Created `%!` as an alias for `%execute`.
nxpimage -v utils binary-image convert -i lpcxpresso55s69_led_blinky.axf -f BIN workspace/lpcxpresso55s69_led_blinky.bin
WARNING:spsdk.utils.images:Elf file support is experimental. Take that with care.
INFO:spsdk.apps.nxpimage:
+--0x0000_0000--lpcxpresso55s69_led_blinky.axf--+
|                 Size: 8.8 kB                  |
|The image loaded from: /Users/macbook-m1/spsdk_|
|test/spsdk/examples/jupyter_examples/lpc55sxx_s|
|  ecure_boot/lpcxpresso55s69_led_blinky.axf .  |
|+--0x0000_0000--Segment 0---------------------+|
||                Size: 8.8 kB                 ||
|+--0x0000_2273--------------------------------+|
+--0x0000_2273----------------------------------+

Success. (Converted file: workspace/lpcxpresso55s69_led_blinky.bin created.)
nxpimage -v mbi get-templates -f lpc55s6x workspace/templates
Skip creating workspace/templates/lpc55s6x_int_xip_plain.yml, this file already exists.
Skip creating workspace/templates/lpc55s6x_int_xip_crc.yml, this file already exists.
Skip creating workspace/templates/lpc55s6x_int_xip_signed.yml, this file already exists.
Skip creating workspace/templates/lpc55s6x_ram_crc.yml, this file already exists.
Skip creating workspace/templates/lpc55s6x_ram_signed.yml, this file already exists.
nxpcrypto -v key generate -k rsa2048 workspace/rsa2048_key.pem --force
INFO:spsdk.apps.nxpkeygen:Generating RSA private key...
INFO:spsdk.apps.nxpkeygen:Generating RSA corresponding public key...
INFO:spsdk.apps.nxpkeygen:Saving RSA key pair...
nxpcrypto -v cert get-template workspace/root_cert_template.yml --force
INFO:spsdk.apps.nxpcertgen:Creating Certificate template...
The configuration template file has been created: /Users/macbook-m1/spsdk_test/spsdk/examples/jupyter_examples/lpc55sxx_secure_boot/workspace/root_cert_template.yml
nxpcrypto -v cert get-template workspace/chain_cert_template.yml --force
INFO:spsdk.apps.nxpcertgen:Creating Certificate template...
The configuration template file has been created: /Users/macbook-m1/spsdk_test/spsdk/examples/jupyter_examples/lpc55sxx_secure_boot/workspace/chain_cert_template.yml
Root Certificate config:
{   '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': {   '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'},
    'issuer_private_key': 'workspace/rsa2048_key.pem',
    'subject_public_key': 'workspace/rsa2048_key.pub',
    'serial_number': 12346578,
    'duration': 3650,
    'extensions': {'BASIC_CONSTRAINTS': {'ca': True, 'path_length': 0}}}
Chain certificate config:
{   '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': {   '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'},
    'issuer_private_key': 'workspace/rsa2048_key.pem',
    'subject_public_key': 'workspace/rsa2048_key.pub',
    'serial_number': 12346578,
    'duration': 3650,
    'extensions': {'BASIC_CONSTRAINTS': {'ca': False, 'path_length': 0}}}
nxpcrypto -v cert generate -c workspace/root_cert_template.yml -e DER -o workspace/ROT1_sha256_2048_65537_v3_ca_crt.der --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: /Users/macbook-m1/spsdk_test/spsdk/examples/jupyter_examples/lpc55sxx_secure_boot/workspace/ROT1_sha256_2048_65537_v3_ca_crt.der
nxpcrypto -v cert generate -c workspace/chain_cert_template.yml -e DER -o workspace/IMG1_1_sha256_2048_65537_v3_usr_key.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: /Users/macbook-m1/spsdk_test/spsdk/examples/jupyter_examples/lpc55sxx_secure_boot/workspace/IMG1_1_sha256_2048_65537_v3_usr_key.pem
nxpimage -v mbi export workspace/mbi_config_lpc55s6x.yml
Success. (Master Boot Image: /Users/macbook-m1/spsdk_test/spsdk/examples/jupyter_examples/lpc55sxx_secure_boot/workspace/lpc55s6x_mbi.bin created.)
pfr get-template -t cmpa -d lpc55s6x -o workspace/cmpa_lpc55s6x.yml
WARNING:spsdk.pfr.pfr:The silicon revision is not specified, the latest: '1b' has been used.
pfr get-template -t cfpa -d lpc55s6x -o workspace/cfpa_lpc55s6x.yml
WARNING:spsdk.pfr.pfr:The silicon revision is not specified, the latest: '1b' has been used.
CMPA config:
{   'description': {   'device': 'lpc55s6x',
                       'revision': '1b',
                       'type': 'CMPA',
                       'version': '1.7.1',
                       'author': 'NXP',
                       'release': 'alpha'},
    'settings': {   'BOOT_CFG': {   'bitfields': {   'DEFAULT_ISP_MODE': 'BOOT_CFG_DEFAULT_ISP_MODE_AUTO_ISP',
                                                     'BOOT_SPEED': 'BOOT_CFG_BOOT_SPEED_SYSTEM_SPEED_CODE',
                                                     'USB_SPEED': 'BOOT_CFG_USB_SPEED_USB_SPEED_0',
                                                     'BOOT_FAILURE_PIN': 0}},
                    'SPI_FLASH_CFG': {'bitfields': {'SPI_RECOVERY_BOOT_EN': 0}},
                    'USB_ID': {   'bitfields': {   'USB_VENDOR_ID': 0,
                                                   'USB_PRODUCT_ID': 0}},
                    'SDIO_CFG': {'value': '0x00000000'},
                    'DCFG_CC_SOCU_PIN': {   'bitfields': {   'NIDEN': 'DCFG_CC_SOCU_PIN_NIDEN_USE_DAP',
                                                             'DBGEN': 'DCFG_CC_SOCU_PIN_DBGEN_USE_DAP',
                                                             'SPNIDEN': 'DCFG_CC_SOCU_PIN_SPNIDEN_USE_DAP',
                                                             'SPIDEN': 'DCFG_CC_SOCU_PIN_SPIDEN_USE_DAP',
                                                             'TAPEN': 'DCFG_CC_SOCU_PIN_TAPEN_USE_DAP',
                                                             'MCM33_DBGEN': 'DCFG_CC_SOCU_PIN_MCM33_DBGEN_USE_DAP',
                                                             'ISP_CMD_EN': 'DCFG_CC_SOCU_PIN_ISP_CMD_EN_USE_DAP',
                                                             'FA_ME_CMD_EN': 'DCFG_CC_SOCU_PIN_FA_ME_CMD_EN_USE_DAP',
                                                             'MCM33_NIDEN': 'DCFG_CC_SOCU_PIN_MCM33_NIDEN_USE_DAP',
                                                             'UUID_CHECK': 0}},
                    'DCFG_CC_SOCU_DFLT': {   'bitfields': {   'NIDEN': 'DCFG_CC_SOCU_DFLT_NIDEN_DISABLED',
                                                              'DBGEN': 'DCFG_CC_SOCU_DFLT_DBGEN_DISABLED',
                                                              'SPNIDEN': 'DCFG_CC_SOCU_DFLT_SPNIDEN_DISABLED',
                                                              'SPIDEN': 'DCFG_CC_SOCU_DFLT_SPIDEN_DISABLED',
                                                              'TAPEN': 'DCFG_CC_SOCU_DFLT_TAPEN_DISABLED',
                                                              'MCM33_DBGEN': 'DCFG_CC_SOCU_DFLT_MCM33_DBGEN_DISABLED',
                                                              'ISP_CMD_EN': 'DCFG_CC_SOCU_DFLT_ISP_CMD_EN_DISABLED',
                                                              'FA_ME_CMD_EN': 'DCFG_CC_SOCU_DFLT_FA_ME_CMD_EN_DISABLED',
                                                              'MCM33_NIDEN': 'DCFG_CC_SOCU_DFLT_MCM33_NIDEN_DISABLED'}},
                    'VENDOR_USAGE': {'bitfields': {'VENDOR_USAGE': 0}},
                    'SECURE_BOOT_CFG': {   'bitfields': {   'RSA4K': 'SECURE_BOOT_CFG_RSA4K_RSA2048',
                                                            'DICE_INC_NXP_CFG': 'SECURE_BOOT_CFG_DICE_INC_NXP_CFG_NOT_INCLUDE',
                                                            'DICE_CUST_CFG': 'SECURE_BOOT_CFG_DICE_CUST_CFG_NOT_INCLUDE',
                                                            'SKIP_DICE': 'SECURE_BOOT_CFG_SKIP_DICE_DISABLE_0',
                                                            'TZM_IMAGE_TYPE': 'SECURE_BOOT_CFG_TZM_IMAGE_TYPE_HEADER',
                                                            'BLOCK_SET_KEY': 'SECURE_BOOT_CFG_BLOCK_SET_KEY_ALLOW',
                                                            'BLOCK_ENROLL': 'SECURE_BOOT_CFG_BLOCK_ENROLL_ALLOW',
                                                            'DICE_INC_SEC_EPOCH': 0,
                                                            'SEC_BOOT_EN': 'SECURE_BOOT_CFG_SEC_BOOT_EN_ENABLE_0'}},
                    'PRINCE_BASE_ADDR': {   'bitfields': {   'ADDR0_PRG': 0,
                                                             'ADDR1_PRG': 0,
                                                             'ADDR2_PRG': 0,
                                                             'LOCK_REG0': 'PRINCE_BASE_ADDR_LOCK_REG0_UNLOCK',
                                                             'LOCK_REG1': 'PRINCE_BASE_ADDR_LOCK_REG1_UNLOCK',
                                                             'REG0_ERASE_CHECK_EN': 'PRINCE_BASE_ADDR_REG0_ERASE_CHECK_EN_DISABLE',
                                                             'REG1_ERASE_CHECK_EN': 'PRINCE_BASE_ADDR_REG1_ERASE_CHECK_EN_DISABLE',
                                                             'REG2_ERASE_CHECK_EN': 'PRINCE_BASE_ADDR_REG2_ERASE_CHECK_EN_DISABLE'}},
                    'PRINCE_SR_0': {'value': '0x00000000'},
                    'PRINCE_SR_1': {'value': '0x00000000'},
                    'PRINCE_SR_2': {'value': '0x00000000'},
                    'XTAL_32KHZ_CAPABANK_TRIM': {   'bitfields': {   'TRIM_VALID': 'XTAL_32KHZ_CAPABANK_TRIM_TRIM_VALID_NOT_TRIM',
                                                                     'XTAL_LOAD_CAP_IEC_PF_X100': 0,
                                                                     'PCB_XIN_PARA_CAP_PF_X100': 0,
                                                                     'PCB_XOUT_PARA_CAP_PF_X100': 0}},
                    'XTAL_16MHZ_CAPABANK_TRIM': {   'bitfields': {   'TRIM_VALID': 'XTAL_16MHZ_CAPABANK_TRIM_TRIM_VALID_NOT_TRIM',
                                                                     'XTAL_LOAD_CAP_IEC_PF_X100': 0,
                                                                     'PCB_XIN_PARA_CAP_PF_X100': 0,
                                                                     'PCB_XOUT_PARA_CAP_PF_X100': 0}},
                    'ROTKH': {   'value': '0000000000000000000000000000000000000000000000000000000000000000'},
                    'CUSTOMER_DEFINED0': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED1': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED2': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED3': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED4': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED5': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED6': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED7': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED8': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED9': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED10': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED11': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED12': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED13': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED14': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED15': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED16': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED17': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED18': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED19': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED20': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED21': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED22': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED23': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED24': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED25': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED26': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED27': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED28': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED29': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED30': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED31': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED32': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED33': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED34': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED35': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED36': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED37': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED38': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED39': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED40': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED41': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED42': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED43': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED44': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED45': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED46': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED47': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED48': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED49': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED50': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED51': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED52': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED53': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED54': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED55': {'value': '0x00000000'}}}
pfr -v generate-binary -c workspace/cmpa_lpc55s6x.yml -o workspace/cmpa.bin -e workspace/mbi_config_lpc55s6x.yml
INFO:spsdk.utils.crypto.rkht:ROTKH: afe32dd22b37766ec1b38aff03224bcaee70700a4f796841857587c38596cb84
nxpdevscan
-------- Connected NXP USB Devices --------

USB COMPOSITE DEVICE - NXP SEMICONDUCTOR INC.
Vendor ID: 0x1fc9
Product ID: 0x0021
Path: DevSrvsID:4295541984
Name: LPC55, RT6xx
Serial number:

-------- Connected NXP UART Devices --------

-------- Connected NXP SIO Devices --------

blhost -u lpc55 get-property current-version
Response status = 0 (0x0) Success.
Response word 1 = 1258487808 (0x4b030000)
Current Version = K3.0.0
blhost -u lpc55 set-property 29 1
Response status = 0 (0x0) Success.
blhost -u lpc55 write-memory 0x9E600 zero_1536.bin
Writing memory  [####################################]  100%
Response status = 0 (0x0) Success.
Response word 1 = 1536 (0x600)
blhost -u lpc55 set-property 29 0
Response status = 0 (0x0) Success.
pfr read -d lpc55s6x -u lpc55 -t cfpa -o workspace/cfpa.bin -y workspace/cfpa_parsed.yaml --show-diff
CFPA page address on lpc55s6x is 0x9de00
CFPA data stored to workspace/cfpa.bin
Parsed config stored to workspace/cfpa_parsed.yaml
Parsed CFPA from the processor
{   'description': {   'device': 'lpc55s6x',
                       'revision': '1b',
                       'type': 'CFPA',
                       'version': '1.7.1',
                       'author': 'NXP',
                       'release': 'alpha'},
    'settings': {   'VERSION': {'value': '0x000007aa'},
                    'ROTKH_REVOKE': {   'bitfields': {   'RoTK0_EN': 'ROTKH_REVOKE_RoTK0_EN_ENABLED'}},
                    'CMPA_PROG_IN_PROGRESS': {'value': '0x5cc55aa5'}}}
CFPA config:
{   'description': {   'device': 'lpc55s6x',
                       'revision': '1b',
                       'type': 'CFPA',
                       'version': '1.7.1',
                       'author': 'NXP',
                       'release': 'alpha'},
    'settings': {   'HEADER': {'value': '0x00000000'},
                    'VERSION': {'value': '0x7ab'},
                    'S_FW_Version': {'value': '0x00000000'},
                    'NS_FW_Version': {'value': '0x00000000'},
                    'IMAGE_KEY_REVOKE': {'value': '0x00000000'},
                    'ROTKH_REVOKE': {   'bitfields': {   'RoTK0_EN': 'ROTKH_REVOKE_RoTK0_EN_ENABLED',
                                                         'RoTK1_EN': 'ROTKH_REVOKE_RoTK1_EN_INVALID',
                                                         'RoTK2_EN': 'ROTKH_REVOKE_RoTK2_EN_INVALID',
                                                         'RoTK3_EN': 'ROTKH_REVOKE_RoTK3_EN_INVALID'}},
                    'VENDOR_USAGE': {'bitfields': {'DBG_VENDOR_USAGE': 0}},
                    'DCFG_CC_SOCU_NS_PIN': {   'bitfields': {   'NIDEN': 'DCFG_CC_SOCU_NS_PIN_NIDEN_USE_DAP',
                                                                'DBGEN': 'DCFG_CC_SOCU_NS_PIN_DBGEN_USE_DAP',
                                                                'SPNIDEN': 'DCFG_CC_SOCU_NS_PIN_SPNIDEN_USE_DAP',
                                                                'SPIDEN': 'DCFG_CC_SOCU_NS_PIN_SPIDEN_USE_DAP',
                                                                'TAPEN': 'DCFG_CC_SOCU_NS_PIN_TAPEN_USE_DAP',
                                                                'MCM33_DBGEN': 'DCFG_CC_SOCU_NS_PIN_MCM33_DBGEN_USE_DAP',
                                                                'ISP_CMD_EN': 'DCFG_CC_SOCU_NS_PIN_ISP_CMD_EN_USE_DAP',
                                                                'FA_ME_CMD_EN': 'DCFG_CC_SOCU_NS_PIN_FA_ME_CMD_EN_USE_DAP',
                                                                'MCM33_NIDEN': 'DCFG_CC_SOCU_NS_PIN_MCM33_NIDEN_USE_DAP',
                                                                'UUID_CHECK': 0}},
                    'DCFG_CC_SOCU_NS_DFLT': {   'bitfields': {   'NIDEN': 'DCFG_CC_SOCU_NS_DFLT_NIDEN_DISABLED',
                                                                 'DBGEN': 'DCFG_CC_SOCU_NS_DFLT_DBGEN_DISABLED',
                                                                 'SPNIDEN': 'DCFG_CC_SOCU_NS_DFLT_SPNIDEN_DISABLED',
                                                                 'SPIDEN': 'DCFG_CC_SOCU_NS_DFLT_SPIDEN_DISABLED',
                                                                 'TAPEN': 'DCFG_CC_SOCU_NS_DFLT_TAPEN_DISABLED',
                                                                 'MCM33_DBGEN': 'DCFG_CC_SOCU_NS_DFLT_MCM33_DBGEN_DISABLED',
                                                                 'ISP_CMD_EN': 'DCFG_CC_SOCU_NS_DFLT_ISP_CMD_EN_DISABLED',
                                                                 'FA_ME_CMD_EN': 'DCFG_CC_SOCU_NS_DFLT_FA_ME_CMD_EN_DISABLED',
                                                                 'MCM33_NIDEN': 'DCFG_CC_SOCU_NS_DFLT_MCM33_NIDEN_DISABLED'}},
                    'ENABLE_FA_MODE': {'value': '0x00000000'},
                    'CMPA_PROG_IN_PROGRESS': {'value': '0x00000000'},
                    'PRINCE_REGION0_IV_HEADER0': {'value': '0x00000000'},
                    'PRINCE_REGION0_IV_HEADER1': {   'bitfields': {   'TYPE': 0,
                                                                      'INDEX': 0,
                                                                      'SIZE': 0}},
                    'PRINCE_REGION0_IV_BODY0': {'value': '0x00000000'},
                    'PRINCE_REGION0_IV_BODY1': {'value': '0x00000000'},
                    'PRINCE_REGION0_IV_BODY2': {'value': '0x00000000'},
                    'PRINCE_REGION0_IV_BODY3': {'value': '0x00000000'},
                    'PRINCE_REGION0_IV_BODY4': {'value': '0x00000000'},
                    'PRINCE_REGION0_IV_BODY5': {'value': '0x00000000'},
                    'PRINCE_REGION0_IV_BODY6': {'value': '0x00000000'},
                    'PRINCE_REGION0_IV_BODY7': {'value': '0x00000000'},
                    'PRINCE_REGION0_IV_BODY8': {'value': '0x00000000'},
                    'PRINCE_REGION0_IV_BODY9': {'value': '0x00000000'},
                    'PRINCE_REGION0_IV_BODY10': {'value': '0x00000000'},
                    'PRINCE_REGION0_IV_BODY11': {'value': '0x00000000'},
                    'PRINCE_REGION1_IV_HEADER0': {'value': '0x00000000'},
                    'PRINCE_REGION1_IV_HEADER1': {   'bitfields': {   'TYPE': 0,
                                                                      'INDEX': 0,
                                                                      'SIZE': 0}},
                    'PRINCE_REGION1_IV_BODY0': {'value': '0x00000000'},
                    'PRINCE_REGION1_IV_BODY1': {'value': '0x00000000'},
                    'PRINCE_REGION1_IV_BODY2': {'value': '0x00000000'},
                    'PRINCE_REGION1_IV_BODY3': {'value': '0x00000000'},
                    'PRINCE_REGION1_IV_BODY4': {'value': '0x00000000'},
                    'PRINCE_REGION1_IV_BODY5': {'value': '0x00000000'},
                    'PRINCE_REGION1_IV_BODY6': {'value': '0x00000000'},
                    'PRINCE_REGION1_IV_BODY7': {'value': '0x00000000'},
                    'PRINCE_REGION1_IV_BODY8': {'value': '0x00000000'},
                    'PRINCE_REGION1_IV_BODY9': {'value': '0x00000000'},
                    'PRINCE_REGION1_IV_BODY10': {'value': '0x00000000'},
                    'PRINCE_REGION1_IV_BODY11': {'value': '0x00000000'},
                    'PRINCE_REGION2_IV_HEADER0': {'value': '0x00000000'},
                    'PRINCE_REGION2_IV_HEADER1': {   'bitfields': {   'TYPE': 0,
                                                                      'INDEX': 0,
                                                                      'SIZE': 0}},
                    'PRINCE_REGION2_IV_BODY0': {'value': '0x00000000'},
                    'PRINCE_REGION2_IV_BODY1': {'value': '0x00000000'},
                    'PRINCE_REGION2_IV_BODY2': {'value': '0x00000000'},
                    'PRINCE_REGION2_IV_BODY3': {'value': '0x00000000'},
                    'PRINCE_REGION2_IV_BODY4': {'value': '0x00000000'},
                    'PRINCE_REGION2_IV_BODY5': {'value': '0x00000000'},
                    'PRINCE_REGION2_IV_BODY6': {'value': '0x00000000'},
                    'PRINCE_REGION2_IV_BODY7': {'value': '0x00000000'},
                    'PRINCE_REGION2_IV_BODY8': {'value': '0x00000000'},
                    'PRINCE_REGION2_IV_BODY9': {'value': '0x00000000'},
                    'PRINCE_REGION2_IV_BODY10': {'value': '0x00000000'},
                    'PRINCE_REGION2_IV_BODY11': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED0': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED1': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED2': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED3': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED4': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED5': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED6': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED7': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED8': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED9': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED10': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED11': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED12': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED13': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED14': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED15': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED16': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED17': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED18': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED19': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED20': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED21': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED22': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED23': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED24': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED25': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED26': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED27': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED28': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED29': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED30': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED31': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED32': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED33': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED34': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED35': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED36': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED37': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED38': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED39': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED40': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED41': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED42': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED43': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED44': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED45': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED46': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED47': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED48': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED49': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED50': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED51': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED52': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED53': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED54': {'value': '0x00000000'},
                    'CUSTOMER_DEFINED55': {'value': '0x00000000'}}}
pfr -v generate-binary -c workspace/cfpa_lpc55s6x.yml -o workspace/cfpa.bin
pfr write -u lpc55 -t cfpa -d lpc55s6x -b workspace/cfpa.bin
CFPA page address on lpc55s6x is 0x9de00
CFPA data written to device.
pfr write -u lpc55 -t cmpa -d lpc55s6x -b workspace/cmpa.bin
CMPA page address on lpc55s6x is 0x9e400
CMPA data written to device.
blhost -u lpc55 flash-erase-region 0 0x10000
Response status = 0 (0x0) Success.
blhost -u lpc55 write-memory 0 workspace/lpc55s6x_mbi.bin
Writing memory  [####################################]  100%
Response status = 0 (0x0) Success.
Response word 1 = 11064 (0x2b38)

SBKEK generation

SBKEK is key (AES-256) used for encryption of the Secure Binary. We have to prepare it in plaint text and in binary form. We can use nxpimage sb21 get-sbkek tool for key generation.

[75]:
WORKSPACE = "workspace/"

# we can specify key with -k option. If the key is not specified, random one will be generated.
%! nxpimage sb21 get-sbkek -o $WORKSPACE

SBKEK_PATH = WORKSPACE + "sbkek.txt"
SBKEK_BIN = WORKSPACE + "sbkek.bin"

nxpimage sb21 get-sbkek -o workspace/
SBKEK: 05401b7e5c003b75c69df91999e0fd1eeb3a8cf46686ba9974fdb3c94bc2083d
SBKEK has been stored to: workspace/

Secure Binary preparation

Secure Binary (SB) is a container in case of LPC55xx in version 2.1. It’s symmetrically encrypted using AES-256 and decrypted during boot and digitally signed. The SB configuration file contains the configuration commands that are processed after the SB2 file is loaded in the device. The image location is stated in the “sources” section of the .bd file. The SB key in the text file is used for encryption with the nxpimage command line tool.

In the example below we have prepared simple BD file with one section with two commands - erase and load.

[76]:
import os


BD_FILE_PATH = WORKSPACE + "signed.bd"
SB2_PATH = WORKSPACE + "output.sb2"


bd = """options {
 flags = 0x8; // for sb2.1 use only 0x8 encrypted + signed
 buildNumber = 0x1;
 productVersion = "1.00.00";
 componentVersion = "1.00.00";
 secureBinaryVersion = "2.1";
}
sources
{
 inputFile = extern(0);
}
section (0)
{
 erase 0..0x00010000;
 load inputFile > 0x0;
}"""

# write configuration to file
with open(BD_FILE_PATH, "w+") as bd_file:
    bd_file.write(bd)

assert os.path.exists(SBKEK_PATH)
assert os.path.exists(SBKEK_BIN)

%! nxpimage $VERBOSITY sb21 export -k $SBKEK_PATH -c $BD_FILE_PATH -o $SB2_PATH -s $PRIVATE_KEY_PATH -S $ROOT_0_CERT_PATH -S $CHAIN_CERT_0 -R $ROOT_0_CERT_PATH $BIN_OUTPUT_PATH
assert _exit_code == 0

assert os.path.exists(SB2_PATH)

nxpimage -v sb21 export -k workspace/sbkek.txt -c workspace/signed.bd -o workspace/output.sb2 -s workspace/rsa2048_key.pem -S workspace/ROT1_sha256_2048_65537_v3_ca_crt.der -S workspace/IMG1_1_sha256_2048_65537_v3_usr_key.pem -R workspace/ROT1_sha256_2048_65537_v3_ca_crt.der workspace/lpc55s6x_mbi.bin
Success. (Secure binary 2.1: workspace/output.sb2 created.)

Device preparation

Now it’s time to prepare the device (enroll keys, load pfr…). In this example we will use LPCXpresso55S69 Evaluation kit.

First step is to enter ISP mode, this could be achieved by either shorting J10 or by simultaneously pressing ISP button and reset button.

LPCXpresso55S69 supports UART and USB-HID interface for the ISP programming. In the picture below we used UART, if you want to use USB, connect the cable to high speed USB port.

lpc55s69

We could use app nxpdevscan to check if the device is connected to the PC in ISP mode.

[77]:
# check if the device is connected and detected by PC
%! nxpdevscan
nxpdevscan
-------- Connected NXP USB Devices --------

USB COMPOSITE DEVICE - NXP SEMICONDUCTOR INC.
Vendor ID: 0x1fc9
Product ID: 0x0021
Path: DevSrvsID:4295541984
Name: LPC55, RT6xx
Serial number:

-------- Connected NXP UART Devices --------

-------- Connected NXP SIO Devices --------

[78]:
USB_CONNECTION = "-u lpc55"
# choose com port or /dev
UART_CONNECTION = "-p com6"

# comment if you want to use UART
CONNECTION = USB_CONNECTION
# CONNECTION = UART_CONNECTION

%! blhost $CONNECTION get-property current-version
assert _exit_code == 0
blhost -u lpc55 get-property current-version
Response status = 0 (0x0) Success.
Response word 1 = 1258487808 (0x4b030000)
Current Version = K3.0.0

Key enrollment

Key enrollment should be done only once in the device life cycle. We have to write KEK key that will be used for SB decryption and we will generate PUF keys for PRINCE encryption.

To detect if key provisioning was enrolled issue blhost command read-memory 0x0009E600 4. If the output is “95 95 95 95” it means that the key store is already enrolled.

[79]:
## Check if the keystore is enrolled
%! blhost $CONNECTION read-memory 0x0009E600 4

## Key provisioning enroll uncomment in case it's not enrolled ###
%! blhost $CONNECTION key-provisioning enroll
assert _exit_code == 0

### Write KEK for SB
%! blhost $CONNECTION key-provisioning set_user_key 3 $SBKEK_BIN
assert _exit_code == 0

### Generate random key for PRINCE region 0 ###
%! blhost $CONNECTION key-provisioning set_key 7 16
assert _exit_code == 0

### Generate random key for PRINCE region 1 ###
%! blhost $CONNECTION key-provisioning set_key 8 16
assert _exit_code == 0

### Generate random key for PRINCE region 2 ###
%! blhost $CONNECTION key-provisioning set_key 9 16
assert _exit_code == 0

### In case the key store has been enrolled comment if enrolling
# read keystore from internal flash
# %! blhost $CONNECTION key-provisioning read_key_nonvolatile 0

# # Write KEK for SB
# %! blhost $CONNECTION key-provisioning set_user_key 3 $SBKEK_BIN

# ### Now write the keystore to internal flash
%! blhost $CONNECTION key-provisioning write_key_nonvolatile 0
assert _exit_code == 0

blhost -u lpc55 read-memory 0x0009E600 4
Reading memory  [####################################]  100%
00 00 00 00
Response status = 0 (0x0) Success.
Response word 1 = 4 (0x4)
Read 4 of 4 bytes.
blhost -u lpc55 key-provisioning enroll
Response status = 0 (0x0) Success.
blhost -u lpc55 key-provisioning set_user_key 3 workspace/sbkek.bin
Response status = 0 (0x0) Success.
blhost -u lpc55 key-provisioning set_key 7 16
Response status = 0 (0x0) Success.
blhost -u lpc55 key-provisioning set_key 8 16
Response status = 0 (0x0) Success.
blhost -u lpc55 key-provisioning set_key 9 16
Response status = 0 (0x0) Success.
blhost -u lpc55 key-provisioning write_key_nonvolatile 0
Response status = 0 (0x0) Success.

Receive SB file

Last step is to receive SB and then reset the chip to boot the image. Do not forget to remove the ISP jumper.

[80]:
%! blhost $CONNECTION receive-sb-file $SB2_PATH
assert _exit_code == 0

# reset target
%! blhost $CONNECTION reset
assert _exit_code == 0
blhost -u lpc55 receive-sb-file workspace/output.sb2
Sending SB file  [####################################]  100%
Response status = 0 (0x0) Success.
blhost -u lpc55 reset
Response status = 0 (0x0) Success.