Debug authentication on MCXC151#

The MCXC151 device implements a controlled, password-based mechanism for enabling debug access. This mechanism ensures that only entities possessing the correct password - defined and stored in the device’s CMPA configuration - can activate the debug interface. A software-based authentication step in the bootloader validates the password written through the Debug Mailbox registers, and debug access is granted only when the submitted value matches the CMPA-configured reference and the device is in an appropriate lifecycle state. SPSDK supports this lightweight authentication flow by writing the required 128-bit password into the designated Debug Mailbox registers, following the sequence defined by the bootloader. The device compares the received password with the value stored in CMPA, and - if valid and permitted by the current lifecycle state - temporarily enables the debug port. From SPSDK’s perspective, the process includes:

  • Preparing the 128-bit password from user configuration.

  • Writing the password sequentially into the Debug Mailbox registers.

  • Polling for the device’s response to confirm whether access is granted.

  • Proceeding with standard debug operations once authentication succeeds.

This ensures SPSDK remains aligned with the MCXC151 security model while providing a streamlined workflow for devices protected by password-based debug control.

WARNING!#

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

1. Prerequisites#

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

  • This example uses MCXC151 board.

The password-authentication flow for MCXC151 consists of programming the CMPA with a password, switching the device lifecycle to IN_FIELD1, attempting a J-Link connection (which is correctly blocked), performing the password-based debug authentication, and then successfully connecting with J-Link once the password is validated.

1.1 Let’s prepare the environment#

# Import required modules
import os

# 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

# Setup workspace
WORKSPACE = "workspace/"
DATA_DIR = "inputs/"
VERBOSITY = "-v"

# Create output directory
os.makedirs(WORKSPACE, exist_ok=True)

# Device configuration
FAMILY = "mcxc151"
INTERFACE = "jlink"
PASSWORD = "00000010010000000000000110000000"
CMPA_PSWD_CONFIG = os.path.join(DATA_DIR, "mcxc151_cmpa_pswd.yaml")
CMPA_LC_CONFIG = os.path.join(DATA_DIR, "mcxc151_cmpa_lc.yaml")
env: JUPYTER_SPSDK=1
Created `%!` as an alias for `%execute`.

1.2 Let’s prepare the device#

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 $VERBOSITY
nxpdevscan -v 
Scanning USB devices...  Nothing found
Scanning UART devices...INFO:spsdk.sdp.sdp:TX-CMD: ReadStatus
INFO:spsdk.sdp.sdp:RX-CMD: Timeout Error
INFO:spsdk.sdp.sdp:TX-CMD: ReadStatus
INFO:spsdk.sdp.sdp:RX-CMD: Timeout Error
INFO:spsdk.sdp.sdp:TX-CMD: ReadStatus
INFO:spsdk.sdp.sdp:RX-CMD: Timeout Error
INFO:spsdk.sdp.sdp:TX-CMD: ReadStatus
INFO:spsdk.sdp.sdp:RX-CMD: Timeout Error
INFO:spsdk.sdp.sdp:TX-CMD: ReadStatus
INFO:spsdk.sdp.sdp:RX-CMD: Timeout Error

╔════════════════════════════════════════════╗
║   Connected NXP UART Devices  (1 device)   ║
╠════════════════════════════════════════════╣
║  Port : COM8                               ║
║  Type : mboot device                       ║
╚════════════════════════════════════════════╝

Scanning LPCUSBSIO devices...  Nothing found
Scanning UUU devices...  Nothing found
# choose USB or UART interface based on the result of nxpdevscan
UART = "-p COM8"

# check if the board responds in ISP mode
%! blhost $VERBOSITY $UART get-property 1
blhost -v -p COM8 get-property 1 
INFO:spsdk.mboot.mcuboot:Connect: identifier='uart', device=COM8
INFO:spsdk.mboot.mcuboot:Connect: identifier='uart', device=COM8
INFO:spsdk.mboot.mcuboot:CMD: GetProperty(CurrentVersion, index=0)
INFO:spsdk.mboot.mcuboot:CMD: GetProperty(CurrentVersion, index=0)
INFO:spsdk.mboot.mcuboot:CMD: Status: 0 (0x0) Success.
INFO:spsdk.mboot.mcuboot:CMD: Status: 0 (0x0) Success.
Response status = 0 (0x0) Success.
Response word 1 = 1258356736 (0x4b010000)
Current Version = K1.0.0
INFO:spsdk.mboot.mcuboot:Closing: identifier='uart', device=COM8
INFO:spsdk.mboot.mcuboot:Closing: identifier='uart', device=COM8

Step 1: Erase Flash#

First, we need to erase the flash memory while the device is still in the open/development lifecycle state (before transitioning to IN_FIELD1).

%! blhost $UART flash-erase-all
blhost -p COM8 flash-erase-all 
Response status = 0 (0x0) Success.

Step 2: Write Password CMPA#

Write the Customer Manufacturing Programming Area (CMPA) with password configuration.

%! pfr write $UART -t cmpa_pswd -f $FAMILY -c $CMPA_PSWD_CONFIG
pfr write -p COM8 -t cmpa_pswd -f mcxc151 -c inputs/mcxc151_cmpa_pswd.yaml 
CMPA_PSWD data written to device.

Step 3: Move Lifecycle to IN_FIELD1#

Transition the device lifecycle state to IN_FIELD1 (In-field application state for end customer use (debug authentication required)).

%! pfr write $UART -t cmpa_lc -f $FAMILY -c $CMPA_LC_CONFIG
pfr write -p COM8 -t cmpa_lc -f mcxc151 -c inputs/mcxc151_cmpa_lc.yaml 
CMPA_LC data written to device.

Step 4: Check Device Properties#

Verify the device properties after lifecycle transition.

%! blhost $UART get-property 7
blhost -p COM8 get-property 7 
Response status = 0 (0x0) Success.
Response word 1 = 3153 (0xc51)
Available Commands = ['FlashEraseAll', 'FillMemory', 'GetProperty', 'Reset', 'SetProperty']

Step 5: Start Debug Mailbox#

Initialize the debug mailbox communication.

%! nxpdebugmbox -i $INTERFACE cmd --family $FAMILY start
nxpdebugmbox -i jlink cmd --family mcxc151 start 
  #   Interface   Id          Description                 
----------------------------------------------------------
  0   Jlink       852002625   Segger J-Link Compact PLUS  
Start Debug Mailbox succeeded

Step 6: Authenticate with Password#

Perform password authentication to gain debug access.

%! nxpdebugmbox -i $INTERFACE cmd -f $FAMILY password-auth --password $PASSWORD
nxpdebugmbox -i jlink cmd -f mcxc151 password-auth --password 00000010010000000000000110000000 
  #   Interface   Id          Description                 
----------------------------------------------------------
  0   Jlink       852002625   Segger J-Link Compact PLUS  
Password authentication succeeded

Step 7: Start Debug Session#

Establish the debug session after successful authentication.

%! nxpdebugmbox -i $INTERFACE cmd --family $FAMILY start-debug-session
nxpdebugmbox -i jlink cmd --family mcxc151 start-debug-session 
  #   Interface   Id          Description                 
----------------------------------------------------------
  0   Jlink       852002625   Segger J-Link Compact PLUS  
Start debug session succeeded

Step 8: Test Connection#

Verify that the debug connection is working properly.

Expected Result: The test connection should end successfully.

%! nxpdebugmbox -i $INTERFACE mem-tool test-connection -f $FAMILY
nxpdebugmbox -i jlink mem-tool test-connection -f mcxc151 
  #   Interface   Id          Description                 
----------------------------------------------------------
  0   Jlink       852002625   Segger J-Link Compact PLUS  
The test connection ends successfully.

Summary#

This notebook demonstrated the complete flow for password-protected debug authentication on MCXC151 devices:

  1. ✓ Flash erased in IN-FIELD1

  2. ✓ Password CMPA written

  3. ✓ Lifecycle moved to ROP1

  4. ✓ Device properties verified

  5. ✓ Debug mailbox started

  6. ✓ Password authentication completed

  7. ✓ Debug session established

  8. ✓ Connection tested successfully

The device is now in a password-protected debug state and authenticated for debugging.