eXecute-Only-Memory (XOM) is a firmware protection technique to help prevent 3rd parties from stealing or reverse engineering firmware, and at the same time allowing 3rd parties to add additional software to the chips and utilize the protected APIs in XOM. This technique is separated from chip-level, read-out-protection, which can block the read-back of the entire firmware.
To enable XOM, hardware system design arrangement is needed – it is impossible to implement XOM with just software. In a system with XOM, the bus system is designed so that a section of the program memory can be accessed only with instruction fetches. A transaction-filtering mechanism must be in place to enable this:
A data transfer to a XOM address range should be blocked, for example, by ignoring the transfer and return read data as 0. Instruction fetches are handled as normal. As a result, program stored in the XOM can be executed (the processor can fetch program code from XOM), but the program cannot be read back by debugger (debug accesses are marked as data transfers), or by other software running on the processor.
System designers must ensure that other bus masters in the systems (e.g. DMA controller) generate correct HPROT[0]/AxPROT[2] signal levels for the transfers.
Due to the nature of XOM, the program code placed in XOM cannot contain literal data. System designers must also make sure that exception vector tables are not placed inside XOM. To generate immediate data values in program sequences, the processor can use MOVW and MOVT instruction to generate 32-bit constants. Since Armv6-M architecture does not support MOVW and MOVT instructions, XOM is unsuitable for Cortex-M0 and Cortex-M0+ processors.
The XOM mechanism does not require Memory Protection Unit (MPU) – do not confuse XOM and XN (eXecute-Never) attribute in MPU. XN is a memory attribute to prevent a section of memory from being used as program memory. For example, a communication data buffer can contain code injected by attackers using communication interface, and therefore, designers can mark such memory with XN to help prevent execution of injected code.
XOM mechanism is independent from TrustZone Security Extension. It can be used on Armv7-M or Armv8-M processors, with or without the TrustZone feature. XOM can coexist with TrustZone to allow software developers to protect their Secure firmware asset, even if the Secure programming environment needs to be accessible by a third party. It can also be used for protecting firmware in the Non-secure world.
Since XOM program regions do not allow literal data accesses, compiler switches are implemented to handle XOM support.
In Arm Compiler 5, the “--execute_only” command line option is available.
In Arm Compiler 6, the “-mexecute-only” command line option is available.
gcc supports XOM in form of “-mpure-code” option and a PureCode attribute.
For users of Keil MDK (Microcontroller Development Kit), the eXecute-Only-Memory is support in project configuration GUI:
For users of IAR Embedded Workbench for Arm, eXecute-Only-Memory is also supported:
When XOM support option is used, in general, the performance of the applications could be reduced in some cases. For example, this can be caused by the restriction of not allowing table branches. However, in the cases where the memory system has wait states and cache systems are used, compiling code with XOM option can avoid cache misses in data cache and could help performance if cache miss rate in instruction cache is small.
Please note that the resulted code size could increase when using XOM options.
Although XOM can prevent program code from being read directly, data used by the application is not protected. For example, when a protected API is running, and the execution is halted, or interrupted by an interrupt handler, a software developer can observe the data in the register bank and SRAM (including stack contents).
It is also possible to use debug / frequent interrupts to try to ‘single step’ the protected firmware and guess the operations by observing the changes in register bank or memories. However, this requires significant effort, as the visibility is very limited. For example, a step that doesn’t have any register value change could be any of the following:
Nevertheless, such analysis can be automated, and therefore, chip designers should not rely on XOM on its own to protect critical software assets.
Great Article, It gives grate help to better understand XOM.
Many thanks