Difference between revisions of "Ernie Firmware"

From Vita Development Wiki
Jump to navigation Jump to search
 
(6 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
= References =
 
= References =
 +
 +
== Manuals ==
  
 
* [[File:78K0R_User_Manual.pdf|78K0R/KH3 Reference Manual]]
 
* [[File:78K0R_User_Manual.pdf|78K0R/KH3 Reference Manual]]
 
* [[File:RL78_ISA_Manual.pdf|RL78 ISA Manual]]
 
* [[File:RL78_ISA_Manual.pdf|RL78 ISA Manual]]
* [https://github.com/fail0verflow/rl78-ida-proc IDA Proc module]
+
* [[File:RL78_G13_User_Manual_Hardware.pdf|RL78 G13 User Manual Hardware]]
 +
 
 +
== Tools ==
 +
 
 +
* [https://github.com/fail0verflow/rl78-ida-proc IDA PRO RL78 Processor module]
 +
* [https://github.com/astrelsky/RL78_sleigh Ghidra RL78 disassembler and decompiler]
 +
 
 +
== Unofficial documentation ==
 +
 
 +
* [https://fail0verflow.com/blog/2018/ps4-syscon/ fail0verflow PS4 Syscon (RL78 G13) hack and RE writeup]
  
 
= Architecture =
 
= Architecture =
Line 39: Line 50:
 
== Startup ==
 
== Startup ==
  
Reset vector sets up environment and calls into the Worker Loop
+
Reset vector sets up environment and calls into the Worker Loop.
  
 
== Worker Loop ==
 
== Worker Loop ==
Line 53: Line 64:
 
== Main Function ==
 
== Main Function ==
  
The Main Function is the starting point for most of the Syscon's tasks. It looks at the current state (a global variable) and the target state (its only argument) to determine what to do. If the task is successful, the target state will be written to the current state variable and the function call returns to the Worker Loop.
+
The Main Function is the starting point for most of Syscon's tasks. It looks at the current state (a global variable) and the target state (its only argument) to determine what to do. If the task is successful, the target state will be written to the current state variable and the function call returns to the Worker Loop.
  
 
== Command Handler ==
 
== Command Handler ==
Line 61: Line 72:
 
== Asynchronous Handler ==
 
== Asynchronous Handler ==
  
A timer (<code>TMR00</code>) is set up at the start of the Worker Loop to count in <code>0x7D00</code> cycle intervals. Oddly, the timer interrupt is not configured but <code>INTCSI01</code> is configured. Possibly the reference manual is not correct w.r.t Ernie because the interrupt handler for <code>INTCSI01</code> does not appear to reference the serial interface at all. We will assume this interrupt is the timer's interrupt.
+
A timer (<code>TMR00</code>) is set up at the start of the Worker Loop to count in <code>0x7D00</code> cycle intervals. Oddly, the timer interrupt is not configured but <code>INTCSI01</code> is configured. Possibly the reference manual is not correct with reference to Ernie because the interrupt handler for <code>INTCSI01</code> does not appear to reference the serial interface at all. We will assume this interrupt is the timer's interrupt.
  
 
A table of software handlers are initialized to 0 at the start of the Worker Loop. Functions can register handlers in this table. Functions can also flag a handler to run at the next timer interrupt. During each timer interrupt, (with interrupt disabled) the firmware will iterate through the handlers and run any function that is flagged (and unflag it).
 
A table of software handlers are initialized to 0 at the start of the Worker Loop. Functions can register handlers in this table. Functions can also flag a handler to run at the next timer interrupt. During each timer interrupt, (with interrupt disabled) the firmware will iterate through the handlers and run any function that is flagged (and unflag it).
Line 69: Line 80:
 
When [[Ernie_Firmware#JIG_Enable|JIG is enabled]], commands can be sent through an UART interface by an external agent. An UART RX interrupt will flag asynchronous handler <code>0xB</code>. This handler is registered at the start of the Worker Loop to set flag <code>0x32</code> and return. In the Worker Loop, flag <code>0x32</code> can be handled by states 1, 3, 8, 9. In any of these states, the JIG Handler is called.
 
When [[Ernie_Firmware#JIG_Enable|JIG is enabled]], commands can be sent through an UART interface by an external agent. An UART RX interrupt will flag asynchronous handler <code>0xB</code>. This handler is registered at the start of the Worker Loop to set flag <code>0x32</code> and return. In the Worker Loop, flag <code>0x32</code> can be handled by states 1, 3, 8, 9. In any of these states, the JIG Handler is called.
  
JIG packets are ASCII encoded hex (each raw byte is 2 ASCII bytes) and end in \r\n. Once decoded into raw bytes, the packet is 2 byte command id, 1 byte unknown, 2 byte length*2 (equal to raw packet length - 7), a payload, and 2 byte checksum.
+
JIG packets are ASCII encoded hex (each raw byte is 2 ASCII bytes) and end in <code>"\r\n"</code>. Once decoded into raw bytes, the packet is 2 byte command id, 1 byte unknown, 2 byte length*2 (equal to raw packet length - 7), a payload, and 2 byte checksum.
  
 
= Kermit Bootrom JIG Mode =
 
= Kermit Bootrom JIG Mode =
  
Similar to Pandora battery on the PSP, the Vita also has a hidden manufacturing/recovery mode in the boot ROM. By convention, we call this "JIG mode". Once a handshake with Kermit boot ROM passes, the Vita will boot from an SD card in the gamecard slot instead of from eMMC. The payload must be signed by Sony specifically for this mode. There is no vulnerability that allows you to bypass the signature check.
+
Similarly to the Jigkick battery on PSP, the PS Vita also has a hidden manufacturing/recovery mode in the boot ROM. By convention, we call this "JIG mode". Once a handshake with Kermit boot ROM passes, the PS Vita will boot from an SD card in the gamecard slot instead of from internal eMMC. The payload must be signed by Sony specifically for this mode. There is no vulnerability that allows to bypass the signature check.
  
To trigger JIG mode, we have to first enable JIG from the syscon and then do a handshake with Kermit.
+
To trigger JIG mode, we have to first enable JIG from Ernie and then do a handshake with Kermit.
  
 
See also: [[Enc#Secret_debug_mode]]
 
See also: [[Enc#Secret_debug_mode]]
Line 86: Line 97:
 
# Repeat 1-3 and if the id value did not change, then we set a global variable to that value and set flag <code>0x7A</code>.
 
# Repeat 1-3 and if the id value did not change, then we set a global variable to that value and set flag <code>0x7A</code>.
 
# In states 0, 1, 3, 8, or 9, flag <code>0x7A</code> is handled.
 
# In states 0, 1, 3, 8, or 9, flag <code>0x7A</code> is handled.
# If the id from #3 is 0 (P26 is held at 1.562V - 1.622V for at least 32000 clock cycles), then then UART serial controller is configured. If bit 3 is set in [[Sysroot#Hardware_Info]] then a hello packet is written: <code>0x55 0x55 0x55</code>.
+
# If the id from #3 is 4 (P26 is held at 1.017V - 1.140V for at least 32000 clock cycles), then UART serial controller is configured. If bit 3 is set in [[KBL Param#Hardware_Info]] then a hello packet is printed to UART: <code>0x55 0x55 0x55</code> ("UUU").
  
 
=== Voltage Table ===
 
=== Voltage Table ===
Line 149: Line 160:
 
== Entering Handshake ==
 
== Entering Handshake ==
  
Now that [[Ernie_Firmware#JIG_Handler]] is set up, you can perform the handshake with Kermit boot ROM.
+
Now that [[Ernie_Firmware#JIG_Handler]] is set up, you can use the UART interface to trigger the Kermit handshake.
  
 
# Send a JIG packet with Command ID 0x110. This is a packet whose payload is encrypted. TODO: document the packet format. Maybe similar to 0xD0/0xD2 on the normal interface?
 
# Send a JIG packet with Command ID 0x110. This is a packet whose payload is encrypted. TODO: document the packet format. Maybe similar to 0xD0/0xD2 on the normal interface?
Line 160: Line 171:
 
== Handshake ==
 
== Handshake ==
  
The pin references for Kermit is from [[GPIO Registers]]. The pin references for Ernie is from the reference manual. TODO: figure out the physical mapping of the pins.
+
The pin references for Kermit are from [[GPIO Registers]]. The pin references for Ernie are from the reference manual. TODO: figure out the physical mapping of the pins.
  
# Ernie set P15
+
# Ernie sets P15
# Ernie set P97
+
# Ernie sets P97
# Kermit poll for GPIO Port 4 high
+
# Kermit polls for GPIO Port 4 high
 
# Kermit does some magic register writes (possibly switching SPI pins to JIG handshake interface)
 
# Kermit does some magic register writes (possibly switching SPI pins to JIG handshake interface)
# Kermit writes 8 bytes challenge to a F00D only register
+
# Kermit writes 8 bytes challenge to a cMeP only register
 
# Kermit sets GPIO Port 3 high
 
# Kermit sets GPIO Port 3 high
# Ernie poll for P16 high
+
# Ernie polls for P16 high
 
# Ernie clears P90
 
# Ernie clears P90
 
# Ernie receives a packet <code>84 00 88 XX XX XX XX</code> where XX is 4 bytes of the challenge.
 
# Ernie receives a packet <code>84 00 88 XX XX XX XX</code> where XX is 4 bytes of the challenge.
Line 185: Line 196:
 
# Ernie sends a packet <code>85 00 84 XX XX XX XX</code> where XX is 4 bytes of the response.
 
# Ernie sends a packet <code>85 00 84 XX XX XX XX</code> where XX is 4 bytes of the response.
 
# Ernie sets P90
 
# Ernie sets P90
# Kermit magically gets 8 bytes in a F00D only register
+
# Kermit magically gets 8 bytes in a cMeP only register
 
# Kermit sets GPIO Port 3 low
 
# Kermit sets GPIO Port 3 low
 
# Kermit AES encrypts the challenge with its own shared key and does a timing-safe memcmp with the response.
 
# Kermit AES encrypts the challenge with its own shared key and does a timing-safe memcmp with the response.
Line 192: Line 203:
 
== Hardware ==
 
== Hardware ==
  
In theory there needs to be 2 digital pins (UART) and 1 analog pin (JIG enable sense) accessible to the factory agent in order for JIG to work. On the Slim units, it is currently unknown where these pins might be. One theory is that there may be a USB serial hardware inside the TI charging chip. There is only weak evidence for this: the TI chip communicates with Syscon through an I2C interface and we see from pictures of the PCB that the USB data lanes go into and out of the TI chip on the Slim. This is different from the [[SN99057]] on the phat units which routes the USB data lanes in parallel (for charge sensing).
+
In theory there needs to be 2 digital pins (UART) and 1 analog pin (JIG enable sense) accessible to the factory agent in order for JIG to work. On the Slim PS Vita units, it is currently unknown where these pins might be. One theory is that there may be a USB serial hardware inside the Texas Instruments charging chip. There is only weak evidence for this: the Texas Instruments chip communicates with Syscon through an I2C interface and we see from pictures of the PCB that the USB data lanes go into and out of the Texas Instruments chip on the Slim PS Vita. This is different from the [[SN99057]] on the Fat PS Vita units which routes the USB data lanes in parallel (for charge sensing).
 +
 
 +
On the Fat PS Vita units, the [[UDC|multiconnector]] port has UART exposed on pin 6 and 7. Additionally there are pins 11, 12, and 13 that are routed directly to Ernie (seen through PCB delayering). They each have a 100K pull-up resistor to 1.8V.
 +
 
 +
[[File:Multiconnector testpoints.png|thumb|Yellow = UDC pin 12, Cyan = UDC pin 11, Green = UDC pin 6 (Ernie UART RX), Magenta = UDC pin 7 (Ernie UART TX)]]
  
On the phat units, the [[UDC|multiconnector]] port has UART exposed on pin 6 and 7. Additionally there are pins 11, 12, and 13 that are routed directly to Ernie (seen through PCB delayering).
+
Since the test points for UDC pins 11 and 12 are close to the test points for Ernie UART, one (or both) of these pins could be used for [[Ernie_Firmware#Voltage_Table|voltage sensing]]. Below is an untested theory of what a JIG enable circuit could look like.
  
[[File:Multiconnector testpoints.png|thumb|Yellow = UDC pin 12, Cyan = UDC pin 11, Green = UDC pin 6 (RX), Magenta = UDC pin 7 (TX)]]
+
[[File:Potential jig circuit.png|thumb|Possible JIG enable circuit with a 160K voltage divider.]]
  
We observe that without anything attached, the resistance between pin 11 and 12 is exactly 200Kohm. When the DevKit USB ethernet adapter is plugged in, the resistance between pin 11 and 12 is non-linear. One theory is that there is some sort of accessory sense based on these pins and the [[Ernie_Firmware#Voltage_Table]].
 
  
 
[[Category:Syscon]]
 
[[Category:Syscon]]
 
[[Category:Devices]]
 
[[Category:Devices]]

Latest revision as of 22:07, 30 August 2021

References

Manuals

Tools

Unofficial documentation

Architecture

Read the reference manual for full information. Below are the most important facts.

Memory Space

The memory is laid out into 0x800 sized blocks. The bottom X blocks are flash memory that can be programmed. Some blocks are not programmable on Ernie. Most keys reside on the non-programmable blocks.

Registers and Devices

Registers are 8-bits and adjacent registers can be addressed as 16-bits (example: register AX can be addressed as A (top 8 bits) and X (bottom 8 bits)).

Additional registers are located near the top of the memory map. They are addressed like any other memory. Ernie uses 0xFFED4-0xFFEDF as extra scratch registers.

Device registers (documented in the reference manual) are located at 0xFFF00-0xFFFFF (SFR) and 0xF0000-0xF07FF (SFR2).

The UART serial controller used by Ernie is not documented in the reference manual but the register definitions are the same as the serial controllers that are documented. There appears to be a few other registers and interrupt vectors that differ from the documentation.

Memory access is done through segmented addressing on a 20-bit address space. CS contains the top 4 bits for code access. ES contains the top 4 bits for data access.

Calling Convention

Functions with one argument: AX

Functions with one pointer argument: AX = pointer, C = segment

Functions with multiple arguments: first argument same as above, then rest are in stack using PUSH instruction. Stack pointer moves downwards.

Often, at the start of a function, the AX and BC registers are PUSH onto the stack before the frame pointer is allocated. Then the arguments are referenced by addressing the bottom of the frame pointer.

Firmware Basics

Startup

Reset vector sets up environment and calls into the Worker Loop.

Worker Loop

The Worker Loop is a FSM with 10 states (0-9). In each state, the Main function is called with the current state and the target state depending on flags that are set.

The starting state is either 0 or 7 depending on a global value derived earlier.

Flags are global variables in memory set by various sources: asynchronous interrupts, synchronous work in the current state, command handlers, etc. Not all states will handle all flags. Some flags can be handled in all states and some flags can be handled in only some states. Each flag is cleared after it is read. When multiple flags are set, the Main function will be called multiple times synchronously in a set order (certain flags have higher priority).

In states 3 and 4, after the Main Function is called (potentially multiple times depending on the flags set), the Command Handler is called.

Main Function

The Main Function is the starting point for most of Syscon's tasks. It looks at the current state (a global variable) and the target state (its only argument) to determine what to do. If the task is successful, the target state will be written to the current state variable and the function call returns to the Worker Loop.

Command Handler

Two bytes are read from SDR00. This is the command header. If the header & 0x80 == 0, then there is no data payload in the command and the command handler is invoked. One more byte is read. If there is no payload, this is the checksum. If there is a payload, the rest of the packet is read and handled in a different command table. Finally, the checksum is checked.

Asynchronous Handler

A timer (TMR00) is set up at the start of the Worker Loop to count in 0x7D00 cycle intervals. Oddly, the timer interrupt is not configured but INTCSI01 is configured. Possibly the reference manual is not correct with reference to Ernie because the interrupt handler for INTCSI01 does not appear to reference the serial interface at all. We will assume this interrupt is the timer's interrupt.

A table of software handlers are initialized to 0 at the start of the Worker Loop. Functions can register handlers in this table. Functions can also flag a handler to run at the next timer interrupt. During each timer interrupt, (with interrupt disabled) the firmware will iterate through the handlers and run any function that is flagged (and unflag it).

JIG Handler

When JIG is enabled, commands can be sent through an UART interface by an external agent. An UART RX interrupt will flag asynchronous handler 0xB. This handler is registered at the start of the Worker Loop to set flag 0x32 and return. In the Worker Loop, flag 0x32 can be handled by states 1, 3, 8, 9. In any of these states, the JIG Handler is called.

JIG packets are ASCII encoded hex (each raw byte is 2 ASCII bytes) and end in "\r\n". Once decoded into raw bytes, the packet is 2 byte command id, 1 byte unknown, 2 byte length*2 (equal to raw packet length - 7), a payload, and 2 byte checksum.

Kermit Bootrom JIG Mode

Similarly to the Jigkick battery on PSP, the PS Vita also has a hidden manufacturing/recovery mode in the boot ROM. By convention, we call this "JIG mode". Once a handshake with Kermit boot ROM passes, the PS Vita will boot from an SD card in the gamecard slot instead of from internal eMMC. The payload must be signed by Sony specifically for this mode. There is no vulnerability that allows to bypass the signature check.

To trigger JIG mode, we have to first enable JIG from Ernie and then do a handshake with Kermit.

See also: Enc#Secret_debug_mode

JIG Enable

  1. At startup, the timer for the Ernie_Firmware#Asynchronous_Handler is set up. When the interrupt is triggered at least 8 times, every time it is triggered, flag 0x79 is set.
  2. In states 0, 1, 3, 8, or 9, flag 0x79 is handled.
  3. The ADC is called on channel ANI6 (port P26). The voltage is passed to a lookup table that converts different voltage ranges to different ids. For example 1.562V - 1.622V corresponds to id 0.
  4. Repeat 1-3 and if the id value did not change, then we set a global variable to that value and set flag 0x7A.
  5. In states 0, 1, 3, 8, or 9, flag 0x7A is handled.
  6. If the id from #3 is 4 (P26 is held at 1.017V - 1.140V for at least 32000 clock cycles), then UART serial controller is configured. If bit 3 is set in KBL Param#Hardware_Info then a hello packet is printed to UART: 0x55 0x55 0x55 ("UUU").

Voltage Table

The conversion is done using the equation on 11.4.2 of the manual with Vref=1.8V.

ID ADC Value Min Voltage
0 59072 1.622
1 56896 1.562
255 52608 1.444
2 50240 1.379
3 46656 1.281
255 41536 1.140
4 37056 1.017
255 34752 0.954
5 31488 0.864
255 1408 0.038
6 320 0.008
7 0 0

Entering Handshake

Now that Ernie_Firmware#JIG_Handler is set up, you can use the UART interface to trigger the Kermit handshake.

  1. Send a JIG packet with Command ID 0x110. This is a packet whose payload is encrypted. TODO: document the packet format. Maybe similar to 0xD0/0xD2 on the normal interface?
  2. In the decrypted packet, the data triggers some command handler which sets flag 0x18
  3. Only state 1 handles flag 0x18.
  4. Main Function in state 1 is called with target state 9. It does some unknown tasks (maybe power on device?) and sets flag 0x15. State is set to 9.
  5. Main Function in state 9 is called with target state 3 (due to flag 0x15).
  6. Ernie is ready to perform the handshake.

Handshake

The pin references for Kermit are from GPIO Registers. The pin references for Ernie are from the reference manual. TODO: figure out the physical mapping of the pins.

  1. Ernie sets P15
  2. Ernie sets P97
  3. Kermit polls for GPIO Port 4 high
  4. Kermit does some magic register writes (possibly switching SPI pins to JIG handshake interface)
  5. Kermit writes 8 bytes challenge to a cMeP only register
  6. Kermit sets GPIO Port 3 high
  7. Ernie polls for P16 high
  8. Ernie clears P90
  9. Ernie receives a packet 84 00 88 XX XX XX XX where XX is 4 bytes of the challenge.
  10. Ernie sets P90
  11. Ernie clears P90
  12. Ernie receives a packet 84 00 8C XX XX XX XX where XX is 4 bytes of the challenge.
  13. Ernie sets P90
  14. Ernie does some endian swapping with the data.
  15. Ernie AES encrypts the challenge with the shared key with Kermit boot ROM.
  16. Ernie does some endian swapping with the data.
  17. Kermit polls for GPIO Port 4 high
  18. Ernie clears P90
  19. Ernie sends a packet 85 00 80 XX XX XX XX where XX is 4 bytes of the response.
  20. Ernie sets P90
  21. Ernie clears P90
  22. Ernie sends a packet 85 00 84 XX XX XX XX where XX is 4 bytes of the response.
  23. Ernie sets P90
  24. Kermit magically gets 8 bytes in a cMeP only register
  25. Kermit sets GPIO Port 3 low
  26. Kermit AES encrypts the challenge with its own shared key and does a timing-safe memcmp with the response.
  27. Kermit makes sure to wipe the key and all relevant registers.

Hardware

In theory there needs to be 2 digital pins (UART) and 1 analog pin (JIG enable sense) accessible to the factory agent in order for JIG to work. On the Slim PS Vita units, it is currently unknown where these pins might be. One theory is that there may be a USB serial hardware inside the Texas Instruments charging chip. There is only weak evidence for this: the Texas Instruments chip communicates with Syscon through an I2C interface and we see from pictures of the PCB that the USB data lanes go into and out of the Texas Instruments chip on the Slim PS Vita. This is different from the SN99057 on the Fat PS Vita units which routes the USB data lanes in parallel (for charge sensing).

On the Fat PS Vita units, the multiconnector port has UART exposed on pin 6 and 7. Additionally there are pins 11, 12, and 13 that are routed directly to Ernie (seen through PCB delayering). They each have a 100K pull-up resistor to 1.8V.

Yellow = UDC pin 12, Cyan = UDC pin 11, Green = UDC pin 6 (Ernie UART RX), Magenta = UDC pin 7 (Ernie UART TX)

Since the test points for UDC pins 11 and 12 are close to the test points for Ernie UART, one (or both) of these pins could be used for voltage sensing. Below is an untested theory of what a JIG enable circuit could look like.

Possible JIG enable circuit with a 160K voltage divider.