Atmosic OTP Tool
Building with Secure Debug
Secure Debug is a collection of hardware and software features to limit access to the debug port for devices in production. It is not intended to be used in development because once security measures are enabled many steps in the normal development flow will no longer function.
Managing the OTP bits
At a hardware level, the debug security state at power-on is defined by two OTP bits (ATM_OTP_MASK_SEC_DBG_DEBUG_SECURED and ATM_OTP_MASK_SEC_DBG_DEBUG_DISABLED).
Hardware applies the debug security state prior to the CPU booting. No intervention is required by software to enforce the security state. When secure debug is either SECURED or DISABLED, access through SWD is disallowed even if benign boot is enabled. When the port is SECURED (rather than DISABLED), the state can be cleared by software after a software challenge to prove the identity of the debug access requester. The authenticator is implemented in the MCUboot image that monitors a UART console port.
To check the state of the OTP bits, users can use the atmotp west extension by issuing the following command:
west atmotp get --board <BOARD> --device <DEVICE_ID> --otp SEC_DBG_CONFIG.DEBUG_DISABLED
or:
west atmotp get --board <BOARD> --device <DEVICE_ID> --otp SEC_DBG_CONFIG.DEBUG_SECURED
To completely disable secure debug, users can issue the following command (this is irreversible):
west atmotp burn --board <BOARD> --device <DEVICE_ID> --otp SEC_DBG_CONFIG.DEBUG_DISABLED
To enable secure debug, users can issue the following command:
west atmotp burn --board <BOARD> --device <DEVICE_ID> --otp SEC_DBG_CONFIG.DEBUG_SECURED
The authenticator software component runs during the boot sequence of MCUboot. Secure debug is not accessible in Non-MCUboot builds. If no authentication occurs, the software will sticky lock the debug port until reset. A Python script is provided to demonstrate communications with the MCUboot authenticator to unlock the debug port. The challenge/authentication process must be performed on each boot. The challenge consists of a unique hash of per-device data stored in the secure journal. This is computed by the MCUboot image and provided as a base64 encoded text output on the UART console port. The hash will be unique for each manufactured device. The challenge must be signed with the private ECDSA key and the resulting signature provided back to the authenticator to verify it using its local public ECDSA key. The signature is unique for the device and can be used for every challenge response.
Compiling MCUboot with Secure Debug
To build with secure debug, add the following additional flags:
-DCONFIG_ATM_MCUBOOT_SECURE_DEBUG=y -DDTS_EXTRA_CPPFLAGS="-DUSE_ATM_SECURE_DEBUG"
The DTS option -DUSE_ATM_SECURE_DEBUG will enable UART0 as a bi-directional console port for authentication use.
The MCUboot extension for secure debug will use a default private ECC-P256 key to generate the public ECC-P256 key stored in the image. This is a widely distributed key and should not be used in production.
At this time the authenticator implements a 500ms default timeout through CONFIG_ATM_MCUBOOT_UART_DEBUG_AUTH_TIMEOUT_MS while monitoring the console port for characters. You can adjust as needed -DCONFIG_ATM_MCUBOOT_UART_DEBUG_AUTH_TIMEOUT_MS=<milliseconds> to extend the timeout. A future update will support monitoring the UART RX pin for a logic high state to detect the presence of a host UART connection.
Using the Debug Unlock Script
A debug unlock Python script is provided in openair/tools/scripts/sec_debug_unlock.py. This tool requires PySerial.
python sec_debug_unlock.py -v -k <private ECC-P256 key in .pem format> -p <console port>
To unlock using the default private key in openair/lib/atm_debug_auth/
python sec_debug_unlock.py -v -k openair/lib/atm_debug_auth/root-debug-ec-p256.pem -p <console port>
The unlocking script using the -v option will verbosely output:
Sending: b'DBG REQUEST\n'
Received: b'Static Challenge: o9H3wvgqOfAi/mvTV/qvvdNjBqzGILIai3G4OBURjhE=\n'
Unlock Static Challenge
Sending: b'DBG STATIC_RESPONSE sMdx+QFewpAt3Dnqy9BrjSLNxgtObtu3IKhSvpuvbG7J9IClpt/zJL4XRlo9rt7KCCw6orjUIyBdaWWM657aRw==\n'
Received: b'Debug unlocked\n'
The SWD port will be unlocked and MCUboot will remain in a benign state with the processor halted at a WFI instruction (Wait For Interrupt). The developer can freely attach a debugger such as GDB and inspect the target (read memory, set breakpoints). If the debugger allows the CPU to continue then MCUboot will continue its boot from the point at which WFI was entered.