Debug authentication on RW612/RW610#

Introduction#

The fundamental principles of debugging, which require access to the system state and system information, conflict with the principles of security, which require the restriction of access to assets. Thus, many products disable debug access completely before deploying the product. To address these challenges, the chip offers a debug authentication protocol as a mechanism to authenticate the debugger (an external entity) has the credentials approved by the product manufacturer before granting debug access to the device. The debug authentication is a challenge-response scheme and assures that only the debugger in possession of the required debug credentials can successfully authenticate over the debug interface and access restricted parts of the device.

The protocol is divided into steps as described below:

  1. The debugger initiates the Debug Mailbox message exchange by setting the CSW[RESYNCH_REQ] bit and CSW[CHIP_RESET_REQ] bit of DM-AP.

  2. The debugger waits (minimum 30 ms) for the devices to restart and enter debug mailbox request handling loop.

  3. The debugger sends Debug Authentication Start command (command code 10h) to the device.

  4. The device responds back with Debug Authentication Challenge (DAC) packet based on the debug access rights preconfigured in CMPA fields, which are collectively referred as Device Credential Constraints Configuration (DCFG_CC). The response packet also contains a 32 bytes random challenge vector.

  5. The debugger responds to the challenge with a Debug Authentication Response (DAR) message by using an appropriate debug certificate, matching the device identifier in the DAC. The DAR packet contains the debug access permission certificate, also referred as Debug Credential (DC), and a cryptographic signature binding the DC and the challenge vector provided in the DAC.

  6. The device on receiving the DAR, validates the contents by verifying the cryptographic signature of the message using the debugger’s public key present in the embedded the Debug Credential (DC). On successful validation of DAR, the device enables access to the debug domains permitted in the DC

debug_authentication_flow

WARNING!#

This configuration is used only for demonstration purpose. For final security device configuration go through all configuration possibilities and define your own specific config/keys.

1. Prerequisites#

  • SPSDK is needed with examples extension. pip install spsdk[examples] (Please refer to the installation documentation.)

  • This example uses FRDM-RW612 board. This is example board configuration without external debugger. It is also possible to use configuration with external debugger such as JLink debug probe.

    frdm-rw612
  • Running signed MBI application (see Device preparation)

1.1 Let’s prepare the environment#

from spsdk.utils.jupyter_utils import YamlDiffWidget

# This env variable sets colored logger output to STDOUT
%env JUPYTER_SPSDK=1
# Set a magic for command execution and echo
%alias execute echo %l && %l
%alias_magic ! execute

WORKSPACE = "workspace/"  # change this to path to your workspace
KEYS = "../../_data/keys/ecc256/"  # change this to path to your keys
INPUTS = "inputs/"
DC_CONFIG = INPUTS + "dc_config.yaml"
SR_CONFIG = INPUTS + "sr_config.yaml"

# choose debug interface
INTERFACE = "pyocd"
# choose family
FAMILY = "rw612"
env: JUPYTER_SPSDK=1
Created `%!` as an alias for `%execute`.

2. Generate RoT + Debug auth keys#

First we need to generate Root of Trust Keys (RoTKs)/Super Root Keys (SRKs) and Debug Credential Key (DCK). Use nxpcrypto app to generate secp256r1 keys (see How-to-get-keys-using-nxpcrypto). We will need by default create 4 RoTKs and 1 DCK.

The notebook is using pre-generated keys just for that example purposes from folder _data/keys/ecc256 in root of all SPSDK examples.

3. Device preparation#

In chip MUST be loaded signed application to show capability of DAT in real application.. To achieve that we do those steps:

  • Go to ISP mode using nxpdebugmbox utility

  • Create signed MBI with matching keys used in example

  • Create Bootable image with generated example and FCB block

  • Load the created image into chip flash

# force device to ISP mode
%! nxpdebugmbox -f $FAMILY -i $INTERFACE cmd ispmode -m 1
# check if the device is connected and detected by PC
%! nxpdevscan
nxpdebugmbox -f rw612 -i pyocd cmd ispmode -m 1 
  #   Interface   Id           Description             
-------------------------------------------------------
  0   PyOCD       1069211762   Segger J-Link MCU-Link  
Entering into ISP mode succeeded
nxpdevscan 
-------- Connected NXP USB Devices --------

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

Port: COM119
Type: mboot device

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

-------- Connected NXP UUU Devices --------
# determine the interface connection based on the result from nxpdevscan
UART = "-p COM119"
# Create MBI
%! nxpimage mbi export -c inputs/mbi_xip_signed.yaml
# Merge MBI and FCB to bootable image
%! nxpimage bootable-image merge -c inputs/bootimg_rw61x_flexspi_nor.yaml -o workspace/bootable_image.bin
# Load it into flash
# Memory configuration
%! nxpmemcfg blhost-script -f $FAMILY -p flexspi_nor -m W25QxxxJV -i quad_spi --output workspace/script.txt --force
%! blhost $UART batch workspace/script.txt

# Erase memory
%! blhost $UART flash-erase-region 0x08000000 0x10000
# Write
%! blhost $UART write-memory 0x08000000 workspace/bootable_image.bin
nxpimage mbi export -c inputs/mbi_xip_signed.yaml 
RKTH: e2cca7cf09a45d2f1942969fda1c68ecaad78fad416d143292dad2f618291ddd
Success. (Master Boot Image: workspace/mbi.bin created.)
nxpimage bootable-image merge -c inputs/bootimg_rw61x_flexspi_nor.yaml -o workspace/bootable_image.bin 
Success. (Bootable Image: workspace/bootable_image.bin created) 
nxpmemcfg blhost-script -f rw612 -p flexspi_nor -m W25QxxxJV -i quad_spi --output workspace/script.txt --force 
Loaded option words: Opt0: 0xC0000007
Exported blhost script.
blhost -p COM119 batch workspace/script.txt 
Response status = 0 (0x0) Success.
Response status = 0 (0x0) Success.
blhost -p COM119 flash-erase-region 0x08000000 0x10000 
Response status = 0 (0x0) Success.
blhost -p COM119 write-memory 0x08000000 workspace/bootable_image.bin 
Writing memory
Response status = 0 (0x0) Success.
Response word 1 = 22772 (0x58f4)

4. Generate debug credential file including its configuration file#

First we need to prepare the configuration file for debug credential file export. Let’s begin by creating a template configuration file using the nxpdebugmbox dat dc get-template command. To simplify this example, we have already prepared that configuration, which can be found in the ./inputs/dc_config.yaml file. Below, we’ll compare the differences between the template and our customized example to highlight the additions we’ve made.

Note: As is mentioned in introduction, the DC file should be created by owner of RoT credentials.

Note: Example how to get UUID for one device: Connect debug probe into the connector and read the UUID by nxpdebugmbox -f rw612 tool get-uuid

NOTICE: Specify the chip revision precisely, because there is in SOCC value!

  • A1: socc = 0x4

  • A2: socc = 0xA

# Get difference of template and user YAML configuration
YamlDiffWidget("inputs/dc_config.diffc").html
nxpdebugmbox -f rw612 dat dc get-template -o workspace/dc_config.yaml --force 
The Debug Credentials template for rw612 has been saved into workspace/dc_config.yaml YAML file

Configuration Differences

Now we generate dc file based on yaml configuration.

DC_FILE_PATH = WORKSPACE + "debug_auth.dc"
%! nxpdebugmbox -f $FAMILY dat dc export -c $DC_CONFIG -o $DC_FILE_PATH --force
nxpdebugmbox -f rw612 dat dc export -c inputs/dc_config.yaml -o workspace/debug_auth.dc --force 
RKTH: e2cca7cf09a45d2f1942969fda1c68ecaad78fad416d143292dad2f618291ddd
Creating Debug credential file succeeded

5. Shadow registers configuration#

The following is an introduction to one of the variants of the shadow register configuration for DAT. The illustrative use case that is presented is based on disabling the debug access control registers.

  • The debug access control rights and security policies are configurable.

  • The configuration fields are referred to as device configuration for credential constraints (DCFG_CC).

  • Life Cycle (LC) state in shadow registers to be configured should be either Develop2 (0x0707) or In-Field (0x0F0F).

  • The RKTH value must be specified.

At the end of this chapter there is test of access to chip memory, that should ends without guaranteed access, because chip is running signed application and debug access is disabled.

# Get difference of template and user YAML configuration
YamlDiffWidget("inputs/sr_config.diffc").html
shadowregs -f rw612 get-template -o workspace/sr_config.yaml --force 
The Shadow registers template for rw612 has been saved into workspace/sr_config.yaml YAML file

Configuration Differences

5.1 Apply the Shadow register configuration#

The following commands loads prepared configuration for shadow registers (set RKTH, move life cycle to In-field state, enable secure boot). After load the MCU will be resets and to prove that settings are active the test-connection command is called and should returns that there is no debug connection to MCU.

# load modified shadowregs
%! shadowregs -i $INTERFACE -f $FAMILY loadconfig -c $SR_CONFIG --no-verify
# reset the device to load modified shadowregs
%! shadowregs -i $INTERFACE -f $FAMILY reset
# check the device is not accessible for debugging
%! nxpdebugmbox -f $FAMILY -i $INTERFACE mem-tool test-connection
shadowregs -i pyocd -f rw612 loadconfig -c inputs/sr_config.yaml --no-verify 
  #   Interface   Id           Description             
-------------------------------------------------------
  0   PyOCD       1069211762   Segger J-Link MCU-Link  
The Shadow registers has been loaded by configuration in C:\_DDM\GIT\PROVISIONING\spsdk2\examples\dat\rw612\inputs\sr_config.yaml YAML file
shadowregs -i pyocd -f rw612 reset 
  #   Interface   Id           Description             
-------------------------------------------------------
  0   PyOCD       1069211762   Segger J-Link MCU-Link  
The target has been reset.
nxpdebugmbox -f rw612 -i pyocd mem-tool test-connection 
  #   Interface   Id           Description             
-------------------------------------------------------
  0   PyOCD       1069211762   Segger J-Link MCU-Link  
The device is not-accessible for debugging.

6. Debug authentication challenge#

In the previous steps, we loaded a configuration with all the keys and enabled the debug authentication in the device. We have also created the DC certificate and private key for the debug authentication challenge. In addition, a protocol version and a beacon must be specified.

RW61x devices support two versions of ECDSA keys:

  • ECDSA P-256 signature verification RoT key(s)

  • ECDSA P-384 signature verification RoT key(s)

The debug authentication process can be extended with beacons. The authentication beacon defines the system-specific debug policy use case such as: restricting debug authentication to only certain devices having specific system product ID during manufacturing phase.

6.1 Generate debug authentication configuration file#

In advance we will prepare the configuration file for debug authentication procedure itself. Let’s begin again by creating a template configuration file using the nxpdebugmbox dat get-template command. To simplify this example, we have already prepared that configuration, which can be found in the ./inputs/dat_config.yaml file. Below, we’ll compare the differences between the template and our customized example to highlight the additions we’ve made. This tiny configuration file is needed that specify the data from in-field technician.

# Get difference of template and user YAML configuration
YamlDiffWidget("inputs/dat_config.diffc").html
nxpdebugmbox -f rw612 dat get-template -o workspace/dat_config.yaml --force 
Creating workspace/dat_config.yaml template file.

Configuration Differences

6.2 Perform Debug authentication#

The following command performs debug authentication challenge-response protocol itself. It should ends with unlocked device to debug.

DAT_CONFIG = INPUTS + "dat_config.yaml"
%! nxpdebugmbox -v -f $FAMILY -i $INTERFACE dat auth -c $DAT_CONFIG
nxpdebugmbox -v -f rw612 -i pyocd dat auth -c inputs/dat_config.yaml 
INFO:spsdk.apps.nxpdebugmbox:Starting Debug Authentication
  #   Interface   Id           Description             
-------------------------------------------------------
  0   PyOCD       1069211762   Segger J-Link MCU-Link  
INFO:spsdk.debuggers.debug_probe_pyocd:PyOCD connected via J-Link MCU-Link probe.
INFO:spsdk.apps.nxpdebugmbox:DAC: 
Version                : Version 2.0
SOCC                   : 0x0000000A
UUID                   : 254A3E01B4A243D8AEBDEC26C6534E83
CC_VU                  : 0
ROTID_rkh_revocation   : 5813F8FD
ROTID_rkth_hash        : f30f3c6947995c5885e72fdfc75b6b76cd8b7a5eee56246d51080d9be1fbb310
CC_soc_pinned          : 00000100
CC_soc_default         : 00000000
Challenge              : dbb9c42895a431460221bdd796e8e9bb88ee7bc1378f3b8e48c7b2c632079660

INFO:spsdk.apps.nxpdebugmbox:DAR:
DAC:
Version                : Version 2.0
SOCC                   : 0x0000000A
UUID                   : 254A3E01B4A243D8AEBDEC26C6534E83
CC_VU                  : 0
ROTID_rkh_revocation   : 5813F8FD
ROTID_rkth_hash        : f30f3c6947995c5885e72fdfc75b6b76cd8b7a5eee56246d51080d9be1fbb310
CC_soc_pinned          : 00000100
CC_soc_default         : 00000000
Challenge              : dbb9c42895a431460221bdd796e8e9bb88ee7bc1378f3b8e48c7b2c632079660

DC:
Version : Version 2.0
SOCC    : 0x0000000A
UUID    : 00000000000000000000000000000000
CC_SOCC : 0xfff
CC_VU   : 0x0
BEACON  : 0
Number of records in flags: 4
CRTK table has 4 entries
CTRK hash   : e2cca7cf09a45d2f1942969fda1c68ecaad78fad416d143292dad2f618291ddd

Authentication Beacon: 0

INFO:spsdk.debuggers.debug_probe_pyocd:PyOCD connected via J-Link MCU-Link probe.
Debug Authentication ends successfully.