Secure Modules

A Secure Module, abbreviated as SM, is a module running in the Secure Block of the PS Vita. A SM is a SELF targetting the CMeP processor. By convention, a finalized SM filename ends with "_sm.self". A SM is usually unloadable and is only loaded when one of its exported functions is called by the Second Loader, the Kernel Boot Loader or the ARM Kernel, and unloaded after the call.

= Secure Modules List =


 * kprx_auth_sm.self, SceSblKprxAuthSm
 * applier_sm.self, SceSblApplierSm
 * aimgr_sm.self, SceSblAimgrSm
 * update_service_sm.self, SceSblUpdateServiceSm
 * act_sm.self, SceSblActSm
 * encdec_w_portability_sm.self, SceSblEncdecWPortabilitySm
 * gcauthmgr_sm.self, SceSblGcAuthMgrSm
 * pm_sm.self, SceSblPmSm
 * qaf_sm.self, SceSblQafSm (or SceSblQafmgrSm according to ss_mgr symbols)
 * utoken_sm.self, SceSblUtokenSm
 * rmauth_sm.self, SceSblRmauthSm
 * mgkm_sm.self, SceSblMgKeyMgrSm
 * compat_sm.self, SceSblCompatSm
 * spkg_verifier_sm_w_key_2.self, SceSblSpkgVerifierSmWKey2

See also Secure Modules Functions.

= Secure Modules Common Code =

Secure Modules are loaded to physical address 0x80B000, then code from that address is executed.

There is a lot of common code shared between Secure Modules: entry, command handler, command setup, etc.

Entry
This is the first code executed in a Secure Module. It is located at phyical address 0x80B000. It does the following:
 * Get random value (stack cookie?)
 * call_ctors
 * sm_main
 * call_dtors
 * syscall 1: Unload
 * while(1) sleep

call_ctors/call_dtors
These just call function pointers, basically libc_init_array.

sm_main
It has a memory pool allocated on stack. It is filled with structures for command handlers. Then, it calls main_loop.

main_loop
This uses syscall 4 (RegisterIrqHandler) to register a common handler for incoming commands (cmd_handler). Then it loops while sm is "active". Then it sets handler for commands = null pointer.

cmd_handler
This is the common handler for all incoming commands. It reads physical address from 0xE0000014 and ANDs it with 1 to check validity. It checks that size is valid (>= 0x40 and < 0x1000), copies command buffer into private CMeP memory and executes an appropriate command handler.

is_addr_range_arm_NS(addr, size)
This is used by cmd_handler to check if the input address of command buffer is safe. The allowed address ranges are:
 * Non-secure DRAM (starting at 0x40200000). Note: this is weird because if configuration (word at physical address 0xE0062260) results in overflow, it does some crazy stuff.
 * ScePowerScratchPad32KiB
 * SceVeneziaSpram