MSPM0L1117: Clarification on Debug Password – 128-bit in J-link Script vs 256-bit SHA in SysConfig Utility (Factory Reset + Mass Erase Protection)

Part Number: MSPM0L1117
Other Parts Discussed in Thread: SEGGER, , SHA-256, SYSCONFIG

Tool/software:

Hello TI Experts,

I'm working with the MSPM0L1117 and using the SEGGER J-Link debugger with a custom J-Link script to enable debug access with password protection.

Objective:
I want to configure the device with full security:

  • Protect debug access (SW-DP)

  • Protect factory reset

  • Protect mass erase
    All using a password authentication scheme by custom J-link script.

  • Primary Questions:

    1. What format is expected by the MSPM0 device in the SEGGER J-Link script:

      • Is it expecting a raw 128-bit password (as 8 x 32-bit words)?

      • Or is it expecting a 256-bit SHA-256 digest of that 128-bit password?

    2. In TI SysConfig (see attached screenshots), I see that passwords must be given as a 256-bit SHA-256 hash (8 x 32-bit).

      • How does this correlate with what I must provide in the SEGGER script?

      • Should the script send the raw password (pre-hash)?

      • Or does the script also require the final SHA-256 hash (post-hash)?

        Reference Screenshots & script:

        • Image 1: TI SysConfig settings showing password fields and SHA-256 hash requirement.

           Script snippet used with SEGGER J-Link.

          Log output from J-Link showing password being accepted but failure to connect to the core.

          What I need from TI:

          1. Clarification on password formats:

            • What format is expected in the SEGGER script?

            • What format is required in TI SysConfig?

          2. A working example of:

            • A known 128-bit password (for example: 0xCAFECAFE12345678A5A5C3C30000FFFF)

            • The corresponding 256-bit SHA-256 hash

            • A valid SEGGER J-Link script snippet for MSPM0L111x that unlocks debug access using that password (covering Debug + Mass Erase + Factory Reset protection).

              Setup Summary:

              • Target: MSPM0L1117 (LQFP-48)

              • Tool: SEGGER J-Link with InitTarget() script

              • Protection mode: Security Level 1 – Custom Restrictions

              • Debug Access: Enabled with Password Match

              • J-Flash V 8.50

                Current Script:- __constant U32 _DAP_ACC_32BIT_AUTO_INC        = (1 << 29) | (1 << 25) | (1 << 24) | (1 << 4) | (2 << 0);  // HMASTER = DEBUG, Private access, Auto-increment, Access size: word;
                __constant U32 _DAP_ACC_8BIT_NO_AUTO_INC      = (1 << 29) | (1 << 25) | (1 << 24) | (0 << 4) | (0 << 0);  // HMASTER = DEBUG, Private access, no Auto-increment, Access size: byte;
                __constant U32 _DAP_ACC_16BIT_NO_AUTO_INC     = (1 << 29) | (1 << 25) | (1 << 24) | (0 << 4) | (1 << 0);  // HMASTER = DEBUG, Private access, no Auto-increment, Access size: half word;
                __constant U32 _DAP_ACC_32BIT_NO_AUTO_INC     = (1 << 29) | (1 << 25) | (1 << 24) | (0 << 4) | (2 << 0);  // HMASTER = DEBUG, Private access, no Auto-increment, Access size: word;
                __constant U32 _DAP_MASS_ERASE                = (0x020C);   
                __constant U32 _DAP_FACTORY_RESET             = (0x020A);
                __constant U32 __DAP_DEBUG_AUTH               = (0x030E);
                __constant U32 _DAP_DATA_EXCHANGE             = (0x00EE);
                __constant U32 _DAP_PWR_AP_DPREC_LPM            = (0x9 << 16) | (1 << 20) | (1 << 3);
                __constant U32 _PASSWORD_1                    = (0x0000FFFF); 
                __constant U32 _PASSWORD_2                    = (0xA5A5C3C3);
                __constant U32 _PASSWORD_3                    = (0x12345678);
                __constant U32 _PASSWORD_4                    = (0xCAFECAFE);
                __constant U32 _FACTORY_RESET_PROCESSED       = (0x0000000A);

                int phase                                     = (0);
                /*********************************************************************
                *
                *       Static code
                *
                **********************************************************************
                */

                /*********************************************************************
                *
                *       InitTarget()
                *
                *  Function description
                *    If present, called right before performing generic connect sequence.
                *    Usually used for targets which need a special connect sequence.
                *    E.g.: TI devices with ICEPick TAP on them where core TAP needs to be enabled via specific ICEPick sequences first
                *
                *  Return value
                *    >= 0:  O.K.
                *     < 0:  Error
                *
                *  Notes
                *    (1) Must not use high-level API functions like JLINK_MEM_ etc.
                *    (2) For target interface JTAG, this device has to setup the JTAG chain + JTAG TAP Ids.
                *    (3) This function is called before J-Link performed any communication with the device
                */

                int InitTarget(void) {
                  U32 AccessPoint;
                  U32 Bank;
                  U32 Data;
                  U32 DestAddr;
                  U32 secap_rxctl_read;
                  U32 secap_txctl_read;
                  U32 secap_rxdata_read;
                  U32 cmd;
                  U32 counter;
                  U32 secap_ctl_mask;
                  U32 secap_txctl_transmit_full_mask;
                  U32 accessPoint_response;
                  U32 accessPoint_cmd;
                  U32 secap_cmdMask;
                  U32 dssm_cmd_received;
                  U32 empty_buffer;
                  U32 command_passed;

                  cmd = __DAP_DEBUG_AUTH; //command we wish to use
                  dssm_cmd_received = 0x00000100;
                  secap_cmdMask = 0x000000FE;
                  secap_txctl_transmit_full_mask = 0x00000001;
                  secap_ctl_mask = 0x0000FFFF;
                  empty_buffer = 0x00000000;
                  counter = 0;
                  AccessPoint = 2;       // Device specific AP
                  Bank = 0;

                  if(phase == 0){
                    JLINK_SYS_Report("phase 0");
                  }else{
                    JLINK_SYS_Report("phase 1");
                  }
                  
                  counter = 0;
                  
                  do{
                    JLINK_SYS_Sleep(500);
                    JLINK_SYS_Report1("iteration count: ", counter);
                    JLINK_TIF_ActivateTargetReset();                                                            //Pulling nRST line low
                    JLINK_SYS_Sleep(150);                                                                       //Giving JLink some time to pull the nRST line low
                    JLINK_CORESIGHT_WriteDP(JLINK_CORESIGHT_DP_REG_SELECT, (AccessPoint << 24) | (Bank << 0));  //Switching the access point to SEC-AP
                    JLINK_CORESIGHT_WriteAP(0, 0x00);                                                           //Clearing out the mailbox
                    JLINK_CORESIGHT_WriteAP(1, cmd);                                             //Setting the command to factory reset 
                    JLINK_SYS_Sleep(150);                                                                       //Giving some time to make sure the command enters the mailbox
                    JLINK_TIF_ReleaseTargetReset();     
                    secap_rxctl_read = JLINK_CORESIGHT_ReadAP(3);
                    secap_rxctl_read = secap_rxctl_read & secap_ctl_mask;
                    if((secap_rxctl_read & secap_txctl_transmit_full_mask) == secap_txctl_transmit_full_mask){
                      JLINK_SYS_Report("Command successfully sent");
                      command_passed = 1;
                      counter=10;
                    }else{
                      JLINK_SYS_Report("Command failed to send");
                      counter=counter+1;
                    }
                  }while((counter != 10));

                  if (command_passed == 1) //command obviously failed don't bother 
                  {
                    accessPoint_cmd = (secap_rxctl_read & secap_cmdMask);
                    accessPoint_response = JLINK_CORESIGHT_ReadAP(2);

                    if ((accessPoint_cmd != (cmd & secap_cmdMask)) ||
                        ((accessPoint_response >> 8) != dssm_cmd_received))
                        {
                          JLINK_SYS_Report("Command was not succesfully processed, re-run the script");
                          JLINK_SYS_Report1("Command = ", accessPoint_cmd);
                          JLINK_SYS_Report1("Response = ", accessPoint_response);
                        } 
                        else 
                        {
                          JLINK_SYS_Report("Command successfully processed");
                          JLINK_SYS_Report("Now sending password");
                          counter = 0;
                        }
                      JLINK_SYS_Sleep(100); 
                  }

                  phase = 1;
                  AccessPoint = 4;                                                                            
                  JLINK_CORESIGHT_WriteDP(JLINK_CORESIGHT_DP_REG_SELECT, (AccessPoint << 24) | (Bank << 0));  //switching to pwr-ap
                  JLINK_CORESIGHT_WriteAP(0x00, _DAP_PWR_AP_DPREC_LPM);                                       //enable low-power mode handling

                  return 0;
                }
        Log:- Connecting ...
         - Connecting via USB to probe/ programmer device 0
         - Probe/ Programmer firmware: J-Link V10 compiled Jan 30 2023 11:28:07
         - Probe/ Programmer S/N: 600102529
         - Device "MSPM0L1117" selected.
         - Target interface speed: 4000 kHz (Fixed)
         - VTarget = 3.499V
         - InitTarget() start
         - DAP initialized successfully.
         - No PWR-AP detected.
         - InitTarget() end - Took 5.49ms
         - Found SW-DP with ID 0x6BA02477
         - DPIDR: 0x6BA02477
         - CoreSight SoC-400 or earlier
         - Scanning AP map to find all available APs
         - AP[0]: Stopped AP scan as end of AP map has been reached
         - Iterating through AP map to find AHB-AP to use
         - Attach to CPU failed. Executing connect under reset.
         - DPIDR: 0x6BA02477
         - CoreSight SoC-400 or earlier
         - Scanning AP map to find all available APs
         - AP[0]: Stopped AP scan as end of AP map has been reached
         - Iterating through AP map to find AHB-AP to use
         - Could not find core in Coresight setup
         - InitTarget() start
         - DAP initialized successfully.
         - No PWR-AP detected.
         - InitTarget() end - Took 5.46ms
         - Found SW-DP with ID 0x6BA02477
         - DPIDR: 0x6BA02477
         - CoreSight SoC-400 or earlier
         - Scanning AP map to find all available APs
         - AP[0]: Stopped AP scan as end of AP map has been reached
         - Iterating through AP map to find AHB-AP to use
         - Attach to CPU failed. Executing connect under reset.
         - DPIDR: 0x6BA02477
         - CoreSight SoC-400 or earlier
         - Scanning AP map to find all available APs
         - AP[0]: Stopped AP scan as end of AP map has been reached
         - Iterating through AP map to find AHB-AP to use
         - Could not find core in Coresight setup
         - ERROR: Error while evaluating J-Link script file: Error while compiling. Line 20, column 19:
          U32 AccessPoint = 2;   // SEC-AP for command/password
                          ^
        Expected a ';'
        Failed prepare script file
         - ERROR: Failed to connect.
        Could not establish a connection to target.
        General troubleshooting guide: kb.segger.com/J-Link_Troubleshooting 
        Device specific guide: kb.segger.com/TI_MSPM0L
         - ERROR: Connect failed

  • Hi,

    The basic theory is that the actual password can not be directly written into flash memory. If someone have the access to your flash memory, they still can not get your password directly. 

    So, according to this theory, the data you have written into the NONMAIN is 256-bit SHA-256 digest data which has been encrypted at this stage. And it is expected a raw 128-bit password to be written in the script. 

    Best regards,

    Cash Hao

  • Hi Cash,

    Thank you for clarifying the theory around 128-bit password and 256-bit SHA hash.

    However, I still need help with the following:

    1. Can you please provide a working SEGGER J-Link script that:

      • Sends a 128-bit password correctly

      • Supports password-protected Debug Access

      • Also protects Factory Reset and Mass Erase

      • Works with Security Level 1 set via TI SysConfig

    2. Can you confirm if the existing SEGGER example supports all these protections or if additional command/AP switch logic is required?

    3. I'm currently getting the following issue even after correct password entry:

      Could not find core in Coresight setup
      Attach to CPU failed.          

    Could this be due to missing steps in my script or mismatched AP settings?

    Any complete working example would be greatly appreciated, especially with:

    • A sample 128-bit password

    • Its 256-bit SHA hash (for SysConfig)

    • J-Link script steps required to unlock and connect to the device securely

    Thank you!