Changes

Jump to navigation Jump to search
2,486 bytes removed ,  06:50, 23 September 2021
Line 1: Line 1:  
== Entrypoint ==
 
== Entrypoint ==
 +
 
The entrypoint of secure_kernel is +0x100.
 
The entrypoint of secure_kernel is +0x100.
First thing it does is disable irq.
  −
Then it zeroes the bss segment 8 bytes at a time.
     −
It sets up $sp to 0x808FF0, and $gp to 0x80F8A8.
+
First thing it does is disable irq. Then it zeroes the .bss segment 8 bytes at a time.
Then it sets dbg::TraceEnableFlag to *0xE005003C.
+
 
 +
It sets up $sp to 0x808FF0, and $gp to 0x80F8A8. Then it sets dbg::TraceEnableFlag to *0xE005003C.
    
In the dump trace was enabled, and buf_ptr was 0x4002C160.
 
In the dump trace was enabled, and buf_ptr was 0x4002C160.
Line 15: Line 15:  
Then it copies a jmp instruction to the reset-vector, unsure why.
 
Then it copies a jmp instruction to the reset-vector, unsure why.
   −
Then it calls a function that sets up icache:
+
Then it calls a function that sets up icache. If icache size is 0, function just returns without doing anything. It also bails if icache line width is < 2 or >= 5 (reserved values).
If icache size is 0, function just returns without doing anything.
  −
It also bails if icache line width is < 2 or >= 5 (reserved values).
      
Then it calls a function at 0x400B0, which is an uncached code that does:
 
Then it calls a function at 0x400B0, which is an uncached code that does:
*     Enable icache.
+
* Enable icache.
*     ORs 0x400 into CFG (this is "reserved" according to datasheet!).
+
* ORs 0x400 into CFG (this is "reserved" according to datasheet!).
   −
Then it calls a function that just iterates through an empty table of function pointers.
+
Then it calls a function that just iterates through an empty table of function pointers. C++ object initialization?
C++ object initialization?
      
Then it calls main().
 
Then it calls main().
   −
Then it calls a function that just iterates through an empty table of function pointers, again.
+
Then it calls a function that just iterates through an empty table of function pointers, again. C++ object dtors.
C++ object dtors.
      
Finally goes into death-mode:
 
Finally goes into death-mode:
   −
Writes a jump instruction to inf-loop to the reset-vector.
+
Writes a jump instruction to inf-loop to the reset-vector. This works because jmp instruction encoding contains an abs address.
This works because jmp instruction encoding contains an abs address.
      
Sets $lp = inf_sleep_loop.
 
Sets $lp = inf_sleep_loop.
   −
Then it sets up args and jumps to a small stub at 0x008000E0.
+
Then it sets up args and jumps to a small stub at 0x008000E0. This small stub clears everything in cMeP memory in the region 0x00800100-0x8080FF0. Unknown why last 0x10 bytes are not cleared.
This small stub clears everything in f00d-mem in the region 0x00800100-0x8080FF0.
  −
Unknown why last 0x10 bytes are not cleared.
  −
 
      
== Teardown ==
 
== Teardown ==
   −
eep::Teardown sets full protection on 0-0x7F, 0x100-0x17F, 0x200-0x217, 0x300-0x3FF.
+
eep::Teardown sets full protection on keyslots 0-0x7F, 0x100-0x17F, 0x200-0x217, 0x300-0x3FF.
 
  −
Then it zero-programs and protects the following ranges 0x400-0x47F, 0x500-0x57F, 0x600-0x607, 0x700-0x7FF.
  −
 
  −
 
  −
 
  −
== F00D messages ==
  −
These are sent to ARM using the lower 16-bits at 0xE0000000.
  −
When ARM has read it, it is set to 0.
     −
ARM can write a 32-bit response to 0xE0000010.
+
Then it zero-programs and protects keyslots 0x400-0x47F, 0x500-0x57F, 0x600-0x607, 0x700-0x7FF.
For ARM->F00D, bit0 is used to indictate the message was written by ARM.
     −
<pre>
+
== Cmep states ==
    1 = Request succeded
  −
    4 = Debug string
  −
0x101 = Main init started
  −
0x102 = Sm can be loaded/resumed
  −
0x103 = Sm resumed successfully
  −
0x104 = Sm was shut down
  −
0x106 = Main shutting down
  −
0x107 = Suspend beginning
  −
0x108 = Ready for suspending, when using the async version.
  −
0x8016 = Error: Invalid address range
  −
0x802F = Error: Failed to init E003, E006.
  −
</pre>
     −
== Food states ==
   
<pre>
 
<pre>
 
  1 = Secure kernel boot value?
 
  1 = Secure kernel boot value?
  2 = Secure kernel inited
+
  2 = Secure kernel initiated
 
  3 = Secure kernel ready to load
 
  3 = Secure kernel ready to load
 
  4 = SM loading
 
  4 = SM loading
Line 82: Line 52:  
  7 = SM suspended
 
  7 = SM suspended
 
  8 = Soft rebooting. Set by syscall 1.
 
  8 = Soft rebooting. Set by syscall 1.
  9 = Shutdown requested. Triggered by ARM command 0x101.
+
  9 = Shutdown requested. Triggered by ARM ?command? 0x101.
 
10 = Shutting down.
 
10 = Shutting down.
 
</pre>
 
</pre>
    +
== Debug prints ==
   −
  −
== Debug prints ==
   
secure_kernel supports tracing to a buffer.
 
secure_kernel supports tracing to a buffer.
   −
Enabled by -7FF8h($gp) being non-zero.
+
It is enabled by -7FF8h($gp) being non-zero. Out-buf address is stored in -7FF4($gp). It writes in a loop, 16 bytes at a time, inserting a null-terminator at buf[15] each "line".
Out-buf address is stored in -7FF4($gp).
  −
It writes in a loop, 16 bytes at a time, inserting a null-terminator at buf[15] each "line".
     −
After out-buf is written, writes 0x20000 to 0xE0000000.
+
After out-buf is written, it writes 0x20000 to 0xE0000000. This will either signal ARM or disable ARM communications. Then infinite loop. This is a panic function.
This will either signal ARM or disable ARM communications.
  −
Then inf-loop, this is a panic function.
      
=== Print types ===
 
=== Print types ===
Addresses are xored with a stack cookie that's fixed for all functions.
+
 
 +
Addresses are xored with a stack cookie that is fixed for all functions.
    
<pre>
 
<pre>
Line 107: Line 73:  
SWI 1 UnreachableCode:                        00000006
 
SWI 1 UnreachableCode:                        00000006
 
SWI 7 UnreachableCode:                        00000007
 
SWI 7 UnreachableCode:                        00000007
Addrcheck IntegerOverflow Food:                0000000B
+
Addrcheck IntegerOverflow Cmep:                0000000B
 
Addrcheck IntegerOverflow Kernel:              0000000B
 
Addrcheck IntegerOverflow Kernel:              0000000B
 
Addrcheck IntegerOverflow Module:              0000000C
 
Addrcheck IntegerOverflow Module:              0000000C
IRQ register func w irq enabled:               0000000E
+
IRQ register func with irq enabled:           0000000E
Force exit dmac w irq enabled:                 0000000F
+
Force exit dmac with irq enabled:             0000000F
 
Crypto irq enabled:                            00000010
 
Crypto irq enabled:                            00000010
Resuming suspendbuf w irq enabled:             00000012
+
Resuming suspendbuf with irq enabled:         00000012
Creating suspendbuf w irq enabled:             00000013
+
Creating suspendbuf with irq enabled:         00000013
 
Reset:                                        00000014 <xored-exception-lr> <xored-exception-pc> <exception-lr>
 
Reset:                                        00000014 <xored-exception-lr> <xored-exception-pc> <exception-lr>
 
RI:                                            00000015 <xored-exception-pc>
 
RI:                                            00000015 <xored-exception-pc>
Line 135: Line 101:     
=== SWI ===
 
=== SWI ===
 +
 
When swi-handler is entered stack is set to 0x00807CC0.
 
When swi-handler is entered stack is set to 0x00807CC0.
 
It stores context (all regs) on this stack.
 
It stores context (all regs) on this stack.
Line 145: Line 112:  
Syscall numbers >= 8 are ignored by the handler and returns error 0x800F032C.
 
Syscall numbers >= 8 are ignored by the handler and returns error 0x800F032C.
    +
=== IRQ ===
   −
=== IRQ ===
   
When irq-handler is entered stack is set to 0x00807B40.
 
When irq-handler is entered stack is set to 0x00807B40.
 
Then it reads irq number from control bus space using the ldcb instruction.
 
Then it reads irq number from control bus space using the ldcb instruction.
Line 166: Line 133:     
=== IRQ8 ===
 
=== IRQ8 ===
 +
 
IRQ8 is the 8th interrupt.
 
IRQ8 is the 8th interrupt.
This is the one triggered when ARM sends a request to F00D using 0xE0000010.
+
This is the one triggered when ARM sends a request to cMeP using 0xE0000010.
 
And secure_kernel has a handler for this one.
 
And secure_kernel has a handler for this one.
   Line 174: Line 142:  
This interrupt is sent when ARM writes to sm cmd registers (0xE0000014 and maybe more?). It's handled inside every sm module.
 
This interrupt is sent when ARM writes to sm cmd registers (0xE0000014 and maybe more?). It's handled inside every sm module.
    +
== Secure Kernel Commands ==
   −
  −
== Secure Kernel Commands ==
   
Handler starts with a switch statement that handles reset commands.
 
Handler starts with a switch statement that handles reset commands.
   −
For a command 0x100401 0x10 is size of shared buffer that's used by f00d handler, 0x4 is command ID, 0x1 is validity flag(?).
+
For a command 0x100401 0x10 is size of shared buffer that is used by cMeP handler, 0x4 is command ID, 0x1 is validity flag(?).
   −
None of the following 5 commands are enabled/disabled depending on f00d-state.
+
None of the following 5 commands are enabled/disabled depending on cmep-state. These are all unconditional.
These are all unconditional.
      
=== 0xB01 ===
 
=== 0xB01 ===
 +
 
   Reset ScePervasiveResetReg +0x190 to enable re-writing the mask for the protected memory (keyring)
 
   Reset ScePervasiveResetReg +0x190 to enable re-writing the mask for the protected memory (keyring)
 
   Set mask to 0x10 for slots 0x20E and 0x20F (set in 0xE0070008)and trigger reset with 0 and 1 to device control 0xE0070000
 
   Set mask to 0x10 for slots 0x20E and 0x20F (set in 0xE0070008)and trigger reset with 0 and 1 to device control 0xE0070000
    
=== 0xC01 ===
 
=== 0xC01 ===
 +
 
   Reads protected mem/keyring slot 0x50C.
 
   Reads protected mem/keyring slot 0x50C.
 
   If lower 4 bits are nonzero:
 
   If lower 4 bits are nonzero:
Line 195: Line 163:     
=== 0xD01 ===
 
=== 0xD01 ===
 +
 
   Reads protected mem/keyring slot 0x50C.
 
   Reads protected mem/keyring slot 0x50C.
   If lower 4 bits are nonzero:
+
   If lower 4 bits are nonzero (external boot mode):
 
     Does same thing as 0xB01.
 
     Does same thing as 0xB01.
    
=== 0xE01 ===
 
=== 0xE01 ===
 +
 
   Does same thing as 0xB01.
 
   Does same thing as 0xB01.
 
   Then reads 3 times from ScePervasiveMisc (0xE3100000).
 
   Then reads 3 times from ScePervasiveMisc (0xE3100000).
Line 210: Line 180:  
Temp name was GetEncryptedInfoBlk.
 
Temp name was GetEncryptedInfoBlk.
   −
This command setups an encrypted SKSO then copies it to paddr 0x4001FF00.
+
This command setups an encrypted SKSO then copies it to physical address 0x4001FF00.
    
<source lang="C">
 
<source lang="C">
Line 251: Line 221:  
* It appends a AES256CMAC hash of header+data using keyslot 0x514 as key.
 
* It appends a AES256CMAC hash of header+data using keyslot 0x514 as key.
 
* It AES-128-CBC encrypts a block of size 0xA0 with key coming from keyslot 0x515, and hardcoded IV from .data.
 
* It AES-128-CBC encrypts a block of size 0xA0 with key coming from keyslot 0x515, and hardcoded IV from .data.
* It memcpys the encrypted SKSO to paddr 0x4001FF00.
+
* It memcpys the encrypted SKSO to physical address 0x4001FF00.
 
* It writes (u32)1, followed by zeroes, to Bigmac keyslot 0x516. That's a sort of status.
 
* It writes (u32)1, followed by zeroes, to Bigmac keyslot 0x516. That's a sort of status.
   −
 
+
After processing, -1 is written to physical address 0xE0000010.
 
  −
After processing, -1 is written to 0xE0000010.
   
Then comes the real switch.
 
Then comes the real switch.
 
This one gives different func-ptrs.
 
This one gives different func-ptrs.
But before func-ptr is called there's a check in a table-lookup based on f00d-state.
+
But before func-ptr is called there's a check in a table-lookup based on cmep-state.
 
So not all cmds are allowed in all states. If not allowed error 0x8029 is sent.
 
So not all cmds are allowed in all states. If not allowed error 0x8029 is sent.
   −
Then it reads lower u16 of f00d mailbox.
+
Then it reads lower u16 of cMeP mailbox.
 
If all zeroes then it returns 0x802D.
 
If all zeroes then it returns 0x802D.
 
Then it reads lower u16 and now wants it to be 0, if not it returns 0x802D.
 
Then it reads lower u16 and now wants it to be 0, if not it returns 0x802D.
Line 288: Line 256:     
=== 0x101: ArmPanic ===
 
=== 0x101: ArmPanic ===
   Sets food-state to 9.
+
 
 +
   Sets cmep-state to 9.
 
   This will later cause main() to return, triggering memclr + infloop.
 
   This will later cause main() to return, triggering memclr + infloop.
   Line 297: Line 266:     
=== 0x500201: LoadModule ===
 
=== 0x500201: LoadModule ===
 +
 
   Reads 0x50 bytes from ArmBuffer into buf.
 
   Reads 0x50 bytes from ArmBuffer into buf.
 
   If *(buf+4) and *(buf+8) are not aligned to 4 it fails.
 
   If *(buf+4) and *(buf+8) are not aligned to 4 it fails.
Line 303: Line 273:  
   If any of these 3 checks fail, return code is 0x8016 or panic.
 
   If any of these 3 checks fail, return code is 0x8016 or panic.
   −
   Then it sets food-state to 4.
+
   Then it sets cmep-state to 4.
    
   memcpy(sp+0x68, buf+0x30, 0x20);
 
   memcpy(sp+0x68, buf+0x30, 0x20);
Line 323: Line 293:     
=== 0x100301: RestoreModule ===
 
=== 0x100301: RestoreModule ===
 +
 
   Reads 0x10 bytes from shared buf.
 
   Reads 0x10 bytes from shared buf.
 
   Checks alignment on stuff also.
 
   Checks alignment on stuff also.
Line 335: Line 306:  
<hr>
 
<hr>
   −
It checks the suspendbuf-state already in f00d-memory.
+
It checks the suspendbuf-state already in cMeP memory.
 
Checks magic, version, and size. On fail 0x800F0324.
 
Checks magic, version, and size. On fail 0x800F0324.
 
Then it uses the easter value to get the key into keyslot 0x22 and 0x33 somehow.
 
Then it uses the easter value to get the key into keyslot 0x22 and 0x33 somehow.
 
Called function does this.
 
Called function does this.
   −
Then it calculates CMAC of the header that's already in f00d-memory into a buf on stack.
+
Then it calculates CMAC of the header that is already in cMeP memory into a buffer on stack.
    
Then it calls a corrupted function that probably is this:
 
Then it calls a corrupted function that probably is this:
Line 352: Line 323:  
         dst=module_base, size=module_size+0x1C0, skip=0x180, shared_buf, sp0=4, sp4=&some_stack_buf)
 
         dst=module_base, size=module_size+0x1C0, skip=0x180, shared_buf, sp0=4, sp4=&some_stack_buf)
   −
Note that size here is read by the f00d header before the ARM one is copied in.
+
Note that size here is read by the cMeP header before the ARM one is copied in.
 
So we can't modify it in this call unfortunately.
 
So we can't modify it in this call unfortunately.
    
Then it continues the CMAC calculation on the module just read.
 
Then it continues the CMAC calculation on the module just read.
   −
Then it calls the update keyslot 0x22 and 0x23 function.
+
Then it calls the update keyslots 0x22 and 0x23 function.
 
This is to prevent next suspendbuf from having the same key?
 
This is to prevent next suspendbuf from having the same key?
   Line 365: Line 336:  
If hash checks out, it memcopies the contexts to whereever they were saved from.
 
If hash checks out, it memcopies the contexts to whereever they were saved from.
 
It loads all func-ptrs for IRQ listeners that were saved.
 
It loads all func-ptrs for IRQ listeners that were saved.
It resets the F00D io-state that was saved.
+
It resets the cMeP io-state that was saved.
It sets MeP irq mask, but it makes sure to first mask away non-allowed ones.
+
It sets cMeP irq mask, but it makes sure to first mask away non-allowed ones.
    
Then it calls a function that calls the easteregg function.
 
Then it calls a function that calls the easteregg function.
Line 372: Line 343:     
=== 0x100401: RequestModuleSuspend ===
 
=== 0x100401: RequestModuleSuspend ===
 +
 
   Reads 0x10 bytes from shared buf.
 
   Reads 0x10 bytes from shared buf.
 
   Verifies alignment on *(buf+4), *(buf+8), *(buf+12).
 
   Verifies alignment on *(buf+4), *(buf+8), *(buf+12).
Line 380: Line 352:  
   If bad it returns 8016.
 
   If bad it returns 8016.
   −
   Sets f00d-state to 6.
+
   Sets cMeP-state to 6.
   If sm is not ready for suspend, it saves the buf in bss.
+
   If sm is not ready for suspend, it saves the buf in .bss.
 
   Also sets the flag that suspend has been requested then returns.
 
   Also sets the flag that suspend has been requested then returns.
   Line 405: Line 377:     
==== CreateSuspendBuf ====
 
==== CreateSuspendBuf ====
 +
 
Input:
 
Input:
 
   r1: shared_buf_contents
 
   r1: shared_buf_contents
Line 417: Line 390:     
Then it writes the following to a struct in .data:
 
Then it writes the following to a struct in .data:
     +0 = 0x534D4300 (Magic)
+
     +0 = 0x534D4300 "SMC." (Magic)
 
     +4 = 1          (Version?)
 
     +4 = 1          (Version?)
 
     +8 = <return-of-easteregg-function>
 
     +8 = <return-of-easteregg-function>
Line 428: Line 401:  
     +0xA0
 
     +0xA0
   −
Then it writes the uer irq handlers to suspend-buf:
+
Then it writes the user irq handlers to suspend-buf:
 
     +0x100 = irq_1_func
 
     +0x100 = irq_1_func
 
     +0x104 = irq_2_func
 
     +0x104 = irq_2_func
Line 439: Line 412:  
     +0x120 = irq_11_func
 
     +0x120 = irq_11_func
   −
Then it writes (f00d io state):
+
Then it writes (cMeP io state):
 
     +0x124 = *0xE0000004
 
     +0x124 = *0xE0000004
 
     +0x128 = *0xE0000008
 
     +0x128 = *0xE0000008
Line 493: Line 466:  
         src=suspend_buf+0x180, size=0x40, skip=module_size+0x180, shared_buf, sp0=3, sp4=&some_stack_buf)
 
         src=suspend_buf+0x180, size=0x40, skip=module_size+0x180, shared_buf, sp0=3, sp4=&some_stack_buf)
   −
Encryption is done using DMAC channel 0, and CMAC is using channel 1
+
Encryption is done using DMAC channel 0, and CMAC is using channel 1.
    
Then it uses an Dmac feature to overwrite the keyslots 0x22 and 0x23 with output from itself.
 
Then it uses an Dmac feature to overwrite the keyslots 0x22 and 0x23 with output from itself.
Line 499: Line 472:     
==== SuspendBufWritePalist ====
 
==== SuspendBufWritePalist ====
 +
 
r1=src
 
r1=src
 
r2=size
 
r2=size
Line 570: Line 544:     
=== 0x501: SubscribeSuspendAsyncEvent ===
 
=== 0x501: SubscribeSuspendAsyncEvent ===
   Sets f00d-state to 6.
+
 
 +
   Sets cmep-state to 6.
 
   If sm is ready to be suspended, sends 0x108 and move into state 7.
 
   If sm is ready to be suspended, sends 0x108 and move into state 7.
    
=== 0x601: ForceExitModule ===
 
=== 0x601: ForceExitModule ===
   Sets f00d state to 6.
+
 
 +
   Sets cmep-state to 6.
 
   Then it calls a function that:
 
   Then it calls a function that:
 
     * Calls a function that appears to stop DMAC.
 
     * Calls a function that appears to stop DMAC.
Line 583: Line 559:     
=== 0x80901: SetTraceBuffer ===
 
=== 0x80901: SetTraceBuffer ===
 +
 
   Shared buf:
 
   Shared buf:
 
     +0: Addr
 
     +0: Addr
Line 592: Line 569:     
=== 0x80A01: SetRevocationList ===
 
=== 0x80A01: SetRevocationList ===
 +
 
   Reads 8 bytes from "shared buf".
 
   Reads 8 bytes from "shared buf".
 
   Calls the function to set the revocation list.
 
   Calls the function to set the revocation list.
 
   If that function returns error x, the error that gets sent back is x&0xFF.
 
   If that function returns error x, the error that gets sent back is x&0xFF.
 
   On success, 1 is sent back.
 
   On success, 1 is sent back.
  −
== Debug prints ==
  −
secure_kernel supports tracing to a buffer.
  −
  −
Enabled by -7FF8h($gp) being non-zero.
  −
Out-buf address is stored in -7FF4($gp).
  −
It writes in a loop, 16 bytes at a time, inserting a null-terminator at buf[15] each "line".
  −
  −
After out-buf is written, writes 0x20000 to 0xE0000000.
  −
This will either signal ARM or disable ARM communications.
  −
Then inf-loop, this is a panic function.
  −
  −
=== Print types ===
  −
Addresses are xored with a stack cookie that's fixed for all functions.
  −
  −
<pre>
  −
SuspendEncrypt BadAddr:                        00000003
  −
SWI 1 BadAddr:                                00000004
  −
SWI 1 UnreachableCode:                        00000006
  −
SWI 7 UnreachableCode:                        00000007
  −
Addrcheck IntegerOverflow Food:                0000000B
  −
Addrcheck IntegerOverflow Kernel:              0000000B
  −
Addrcheck IntegerOverflow Module:              0000000C
  −
IRQ register func w irq enabled:              0000000E
  −
Force exit dmac w irq enabled:                0000000F
  −
Crypto irq enabled:                            00000010
  −
Resuming suspendbuf w irq enabled:            00000012
  −
Creating suspendbuf w irq enabled:            00000013
  −
Reset:                                        00000014 <xored-exception-lr> <xored-exception-pc> <exception-lr>
  −
RI:                                            00000015 <xored-exception-pc>
  −
ZDIV:                                          00000016 <xored-exception-pc>
  −
Trace:                                        00000017 <func-addr>
  −
SWI 7:                                        00000018 <xored-r1>
  −
DMAC when updating suspendbuf key:            00000019 <ret-val>
  −
DMAC cmac bad enum:                            0000001A <enum-value>
  −
Bad enum to suspend AES-CBC function:          0000001B <enum-value>
  −
Generating new suspendbuf key failed:          0000001C
  −
Creating suspendbuf w irq8 module-registered:  0000001D
  −
Addrcheck IntegerOverflow Tz:                  0000001E
  −
Addrcheck IntegerOverflow Tz2:                0000001F
  −
Bad ptr to suspend AES-CBC function:          00000020
  −
IRQ register func w bad irq number:            00000022
  −
Recieved unknown IRQ:                          00000023
  −
</pre>
      
== Syscalls ==
 
== Syscalls ==
   −
[[Private:Sm_modules]] use these via SWI.
+
[[Sm modules]] use these syscalls via SWI.
    
=== 1: Unload ===
 
=== 1: Unload ===
   Sets f00d-state to 8.
+
 
 +
   Sets cmep-state to 8.
 
   Writes r1 to "the shared2-buf".
 
   Writes r1 to "the shared2-buf".
 
   Sends msg 1 to ARM.
 
   Sends msg 1 to ARM.
    
   Then it uses dmac with operation 0xC to memset entire module region to 0,
 
   Then it uses dmac with operation 0xC to memset entire module region to 0,
   Finally it jumps to secure_kernel entrypoint, triggering a softreboot.
+
   Finally it jumps to secure_kernel entrypoint, triggering a soft reboot.
    
=== 2: ReadyToSuspend ===
 
=== 2: ReadyToSuspend ===
 +
 
   This just writes 1 to a state-field and returns 1,
 
   This just writes 1 to a state-field and returns 1,
   or returns 0x800F0329 if it's already non-zero.
+
   or returns 0x800F0329 if it is already non-zero.
   −
   This flag tells kernel whether or not module ready to be suspended.
+
   This flag tells kernel whether or not module is ready to be suspended.
    
=== 3: SuspendSelfIfRequested ===
 
=== 3: SuspendSelfIfRequested ===
 +
 
   Returns 0x800F0329 if SuspendReady wasn't called prior to this.
 
   Returns 0x800F0329 if SuspendReady wasn't called prior to this.
 
   It checks a flag if 0x501 cmd has subscribed to the event.
 
   It checks a flag if 0x501 cmd has subscribed to the event.
   Then it will send msg 0x108 to ARM and goes into f00d-state 7.
+
   Then it will send msg 0x108 to ARM and goes into cmep-state 7.
    
   Regardless of that flag it also checks whether or not ARM has requested suspend.
 
   Regardless of that flag it also checks whether or not ARM has requested suspend.
Line 669: Line 606:     
=== 4: RegisterIrqHandler ===
 
=== 4: RegisterIrqHandler ===
 +
 
   r1 = irq-number
 
   r1 = irq-number
 
   r2 = func-ptr (or NULL to deregister)
 
   r2 = func-ptr (or NULL to deregister)
Line 693: Line 631:     
=== 5: TracePrintf ===
 
=== 5: TracePrintf ===
 +
 
   This just printfs with "%s" to the emit buffer, and returns 1.
 
   This just printfs with "%s" to the emit buffer, and returns 1.
    
=== 6: CheckRvkList ===
 
=== 6: CheckRvkList ===
 +
 
   If r1 or r2 is 0 it returns 0x800F0B16.
 
   If r1 or r2 is 0 it returns 0x800F0B16.
 
   Then it checks that r1 size 0x130 is in module region.
 
   Then it checks that r1 size 0x130 is in module region.
 
   And that r2 size 0x80 also, same error.
 
   And that r2 size 0x80 also, same error.
   −
   It returns 0x800F0326 if no rvk list has been inited.
+
   It returns 0x800F0326 if no rvk list has been initialized.
 
   After that it returns result of the revocation checking function
 
   After that it returns result of the revocation checking function
 
   (same as used for sm normally).
 
   (same as used for sm normally).
    
=== 7: UnloadPanic ===
 
=== 7: UnloadPanic ===
 +
 
   This one trace-printfs.
 
   This one trace-printfs.
   Then it sets f00d-state to 8.
+
   Then it sets cmep-state to 8.
 
   Then it writes 0x800F033B to the "0x40 buffer".
 
   Then it writes 0x800F033B to the "0x40 buffer".
 
   Then corrupted insn?
 
   Then corrupted insn?
 
   Then it zeroes the module region and soft-reboots.
 
   Then it zeroes the module region and soft-reboots.
   −
=== 8: ReadEepromFlag ===
+
=== 8: IsDevelopmentMode ===
   This reads a bool from eeprom block 0x510 byte16 bit31.
+
 
 +
   Reads DIPSW from Bigmac keyslot 0x510 and returns true if the Development Mode flag is on.
    
== Misc func doc ==
 
== Misc func doc ==
    
=== SuspendModule ===
 
=== SuspendModule ===
 +
 
Sends arm message 0x107.
 
Sends arm message 0x107.
   Line 726: Line 669:     
=== LoadModule ===
 
=== LoadModule ===
 +
 
If either num_paddrs and paddr_list is NULL, return error 0x8016.
 
If either num_paddrs and paddr_list is NULL, return error 0x8016.
 
Then it copies rsa pubkey + exponent to stack bufs.
 
Then it copies rsa pubkey + exponent to stack bufs.
Line 733: Line 677:  
     *0xE0050104 = 3;
 
     *0xE0050104 = 3;
 
</pre>
 
</pre>
 +
...
   −
...
   
Ends up calling SceDecrypt.
 
Ends up calling SceDecrypt.
    +
=== SceDecrypt ===
   −
=== SceDecrypt ===
   
<pre>
 
<pre>
 
r1=out, ptr to {buffer = module end region - 0x800, size = 0x800}
 
r1=out, ptr to {buffer = module end region - 0x800, size = 0x800}
Line 849: Line 793:     
=== main() ===
 
=== main() ===
 +
 
Interrupts are disabled when this is called.
 
Interrupts are disabled when this is called.
 
First thing it writes 0x2000F to 0xE0020000. Probably sets up the device.
 
First thing it writes 0x2000F to 0xE0020000. Probably sets up the device.
   −
It checks the f00d-state, and if it's 1 (cold boot?), it writes:
+
It checks the cmep-state, and if it's 1 (cold boot?), it writes:
 
   * Writes 0xFFFFFFFF to 0xE0000010.
 
   * Writes 0xFFFFFFFF to 0xE0000010.
 
   * Calls a big function that initializes 0xE0030000.
 
   * Calls a big function that initializes 0xE0030000.
 
   * Sends ARM-message 0x101.
 
   * Sends ARM-message 0x101.
   * Sets f00d-state to 2.
+
   * Sets cmep-state to 2.
 
   * Waits for ARM to send address for shared buffer and writes it to a state.
 
   * Waits for ARM to send address for shared buffer and writes it to a state.
 
   * Writes 0xFFFFFFFF to the ARM mailbox.
 
   * Writes 0xFFFFFFFF to the ARM mailbox.
Line 862: Line 807:  
     Sends msg 0x802F to ARM
 
     Sends msg 0x802F to ARM
 
     Calls a function that deinitializes 0xE0030000.
 
     Calls a function that deinitializes 0xE0030000.
     Returns from main(), triggering F00D memclear + hang.
+
     Returns from main(), triggering cMeP memclear + hang.
    
Then it calls the following function regardless of state:
 
Then it calls the following function regardless of state:
Line 870: Line 815:     
   This function detects downgrades!
 
   This function detects downgrades!
   if 0x1692000 != eeprom_read_fw_version(): return 0x800F0337;
+
   if 0x1692000 != read_fw_version(): return 0x800F0337;
 
   return 1;
 
   return 1;
   Line 878: Line 823:  
Then it calls a function that enables "software interrupt 3", dafuk is this.
 
Then it calls a function that enables "software interrupt 3", dafuk is this.
   −
Then it sets f00d state to 3.
+
Then it sets cmep-state to 3.
 
Then it sends msg 0x102 to ARM.
 
Then it sends msg 0x102 to ARM.
   Line 912: Line 857:     
=== Range checks ===
 
=== Range checks ===
 +
 
<pre>
 
<pre>
 
   ArmTz:  if (x >= 0x40000000 || x < 0x40300000) return 1;
 
   ArmTz:  if (x >= 0x40000000 || x < 0x40300000) return 1;
Line 929: Line 875:  
           if (addr < 0x0080A000) return 0;
 
           if (addr < 0x0080A000) return 0;
 
           return addr < (0x0080A000+0x00016000)
 
           return addr < (0x0080A000+0x00016000)
   Food:
+
   Cmep:
 
           if (addr < 0x00800000) return 0;
 
           if (addr < 0x00800000) return 0;
 
           return addr < 0x00820000
 
           return addr < 0x00820000
 
</pre>
 
</pre>
 +
 +
=== self_header_auth ===
 +
 +
{| class="wikitable"
 +
! Firmware !! Address
 +
|-
 +
| 3.60 || 0x803586
 +
|}
    
== Changelog ==
 
== Changelog ==
   −
Base is 1.692.
+
Base FW in this section is 1.692.
 +
 
 +
=== Diff vs. FW 1.05 ===
   −
=== Diff vs. 105 ===
   
<pre>
 
<pre>
Stack cookies weren't enabled.
+
Stack cookies were not enabled.
    
Debug vector was initially a "reti" instruction, was later replaced with infloop.
 
Debug vector was initially a "reti" instruction, was later replaced with infloop.
Line 959: Line 914:  
   Did not disable interrupts.
 
   Did not disable interrupts.
   −
eeprom::Init
+
keyslots::Init
 
   Changed a lot. todo: Investigate later.
 
   Changed a lot. todo: Investigate later.
   Line 967: Line 922:  
Cmd 0xF01 did not exist.
 
Cmd 0xF01 did not exist.
   −
All f00d cmds that read from the shared region uses a buf in .bss instead of stack.
+
All cMeP commands that read from the shared region uses a buf in .bss instead of stack.
   This allowed a race condition where you could request a suspend using cmd 0x401.
+
   This allowed a race condition where you could request a suspend using command 0x401.
   Then just before the sm calls syscall 3 you send another F00D cmd to overwrite the sharedbuf.
+
   Then just before the sm calls syscall 3 you send another cMeP command to overwrite the sharedbuf.
 
   This will call sm::Suspend on a buffer that's not properly checked.
 
   This will call sm::Suspend on a buffer that's not properly checked.
   Line 978: Line 933:  
   Code was added to prevent it for ending up in an infinite recursion if stack cookie gets corrupted.
 
   Code was added to prevent it for ending up in an infinite recursion if stack cookie gets corrupted.
   −
The foodcmd::AllowedCmdInStateTable was unchanged.
+
The cmep_cmd::AllowedCmdInStateTable was unchanged.
 
</pre>
 
</pre>
   −
=== Diff vs. 160 ===
+
=== Diff vs. FW 1.60 ===
 +
 
 
<pre>
 
<pre>
 
.bss size grew from 0x478 bytes to 0x480.
 
.bss size grew from 0x478 bytes to 0x480.
Line 988: Line 944:  
Rev changed from 5209->5679
 
Rev changed from 5209->5679
   −
foodcmd::Parse changed:
+
cmep_cmd::Parse changed:
 
   Stackframe grew 0x20 bytes.
 
   Stackframe grew 0x20 bytes.
 
   The function that that changed appears to be 0x501.
 
   The function that that changed appears to be 0x501.
Line 994: Line 950:  
GetFirmwareVersion returns 0x16920000 instead of 0x16000000 (duh!).
 
GetFirmwareVersion returns 0x16920000 instead of 0x16000000 (duh!).
   −
eeprom::Init changed:
+
keyslots::Init changed:
   Some bitmask in was chanaged from 0x3FFFDF to 0xFFFFDF.
+
   Some bitmask in was changed from 0x3FFFDF to 0xFFFFDF.
   Branch was removed here that programmed Eeprom blk 0x516 to all zeroes.
+
   Branch was removed here that used to set Bigmac keyslot 0x516 to all zeroes.
 
   The function was also extended a lot.
 
   The function was also extended a lot.
   −
   Idea: Does this possibly protect additional EEPROM stuff?
+
   Idea: Does this possibly protect additional keyslots stuff?
 
   However otp::Teardown looks identical.
 
   However otp::Teardown looks identical.
  

Navigation menu