SC Communication: Difference between revisions
Jump to navigation
Jump to search
m (Yes, NVS) |
|||
Line 50: | Line 50: | ||
| 0x13 || Power Service - Controls system power and related info. (Power Up/Power Button Mode, Wake Source, RTC too.) | | 0x13 || Power Service - Controls system power and related info. (Power Up/Power Button Mode, Wake Source, RTC too.) | ||
|- | |- | ||
| 0x14 || NVS Service - Used for eeprom read/write. | | 0x14 || NVS Service - Used for eeprom read/write. | ||
|- | |- | ||
| 0x16 || LED / Buzzer Service - Controls the lights on the console and the ring buzzer. | | 0x16 || LED / Buzzer Service - Controls the lights on the console and the ring buzzer. |
Revision as of 18:37, 20 July 2014
Introduction
- The following information was reverse engineered from lv0ldr, lv0, lv1.self, and Iso module sc_iso.self.
- Big thanks to graf_chokolo for a large part of the basis of this page, and to Jestero for Syscon Authentication info!
Overview of Syscon Communication
- Syscon lives at the mmio space of 0x24000080000.
- Communication occurs through mmio read/writes.
List of known offsets in Syscon:
Offset (from start of address space) | Size | Description |
---|---|---|
0xC000 | 0xFF0 | Syscon packet send area |
0xCFF0 | 0x4 | Syscon sent packet counter |
0xCFF4 | 0x4 | Syscon sent packet acknowledge counter |
0xD000 | 0xFF0 | Syscon packet receive area |
0xDFF0 | 0x4 | Syscon received packet counter |
0xDFF4 | 0x4 | Syscon received packet acknowledge counter |
0xE100 | 0x4 | Tells syscon there is a packet to be received |
Quick explanation of the packet counters:
- There are two counters that are incremented by each side (Cell / Syscon).
- 0xCFF0 and 0xDFF0 are incremented by the sending side (Syscon for 0xCFF0, Cell for 0xDFF0)
- 0xCFF4 and 0xDFF4 are incremented by the receiving side (Cell for 0xCFF4, Syscon for 0xDFF4)
Syscon Services
- To be completed...
Service ID | Description |
---|---|
0x10 | PS2 PCI Bus Power On/Off |
0x11 | Time Zone Presence, Temperature, Thermal Alert Mode, |
0x12 | Configuration? (BE Count, Error Log....) |
0x13 | Power Service - Controls system power and related info. (Power Up/Power Button Mode, Wake Source, RTC too.) |
0x14 | NVS Service - Used for eeprom read/write. |
0x16 | LED / Buzzer Service - Controls the lights on the console and the ring buzzer. |
0x18 | Livelock(?) Service - Checks for permission to use other services. (and SC Type/Major-,Minor Version) |
0x20 | Syscon Debug Output(?) - Used to send a string to syscon. |
0x2D | (used when getting Patch/ROM Version in EPROM) |
0x30 | A/V Service. |
0x1F | Authenticated Services. |
0xFF | Syscon Init (Seen in lv0ldr init sequence to syscon: http://www.ps3devwiki.com/wiki/User_talk:JuanNadie) |
Syscon Packet Headers
- Some useful packet headers...
- If the header is shorter than 0x10, you must add your own size.
- If greater than 0x10, it's a full packet ;)
What? | Description | Data | Notes |
---|---|---|---|
AUTH1 | AUTH1 Header | 0x1F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30 |
|
AUTH2 | AUTH2 Header | 0x1F, 0x01, 0x00, 0x01, 0x00, 0x00, 0x80, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30 |
|
Debug Output | Sends string to Syscon TTY | 0x20, 0x01, 0x00, 0x07, 0x00, 0x00, 0x80, 0x28, 0x00, 0x00, 0x00, 0x00 |
Start message with 0x00. Will print as much as packet length. |
Triple Beep | 0x16, 0x01, 0x16, 0x20, 0x00, 0x00, 0x80, 0x4D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x08, 0x20, 0x29, 0x0A, 0x00, 0x00, 0x00, 0x01, 0xB6 |
||
Shutdown | 0x13, 0x01, 0x00, 0x0D, 0x00, 0x00, 0x80, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x11, 0x00, 0x00, 0x00 |
Will not gracefully shut down HD. | |
Soft Restart | 0x13, 0x01, 0x00, 0x0D, 0x00, 0x00, 0x80, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x11, 0x00, 0x00, 0x01 |
Restarts, but doesn't kill power between boots. | |
Hard Restart | 0x13, 0x01, 0x00, 0x0D, 0x00, 0x00, 0x80, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x11, 0x00, 0x00, 0x02 |
Restarts, but kills power between boots. | |
Panic | 0x13, 0x01, 0x00, 0x0D, 0x00, 0x00, 0x80, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x11, 0x00, 0x00, 0x03 |
Shuts down, beeps, and kills power LED until power button pressed, or power removed. |
Syscon Authentication
- An IV of 0x00 is used for most AES steps.
Step 1 - Generate Individual Seeds
Encrypt sc_iso metadata seeds w/ eid root key / iv.
aes256cbc_enc(eid_root_erk, eid_root_riv, sc_module_seeds, 0x40, sc_module_seeds);
Step 2 - Generate SC_ISO encrypted keys
Encrypt the sc_key_seeds.
indiv_key = sc_module_seeds + 0x20; for (int i = 0; i < 0x100; i += 0x10) aes256cbc_enc(indiv_key, zero_iv, key_seeds + i, 0x10, enc_key_seeds + i);
Step 3 - Authenticate with Syscon
Pick a session_id. Must be <= 7.
Step 3a - Secure Packet Header
struct secure_payload_header { u8 session_id; u8 seq_service_id; //service_ID (Unsecure uses 0xFF, AUTH1 = 0x02, AUTH2 = 0x03, READ/WRITE = 0x04) u8 packet_type; //0xFF for BE->SC, 0x00 for SC->BE (if success) u8 magic[0x2]; //0xAD1A u8 prng_random[0xB] //Random shit for padding };
Step 3b - AUTH 1 to SC
uint8_t random_shit[0x10]; auth_key_1_0x01 = enc_key_seeds + (session_id * (0x10*2)); auth_key_2_0x01 = enc_key_seeds + (session_id * (0x10*2) + 0x10); //generating random payload for auth1 rnd_gen(random_shit, 0x10); //create auth1 random data aes128cbc_enc(auth_key_1_0x01, zero_iv, random_shit, 0x10, secure_payload_buf + 0x10); //length = 0x20 //Create secure header/footer // create header: 5 bytes + random stuff (0xb) payload_header->session_id = session_id; payload_header->seq_service_id = seq_service_id++; // starts at 0 payload_header->packet_type = 0xFF; payload_header->magic[0] = 0xAD; payload_header->magic[1] = 0x1A; rnd_gen((u8*) &payload_header->prng_random, 0x0B); //encrypt payload aes128cbc_enc(be2sc_key, zero_iv, secure_payload_buf, length, secure_payload_buf); // create footer: omac1 of the whole packet aesOmac1Mode(secure_payload_buf + length, secure_payload_buf, length, be2sc_key, sizeof(be2sc_key)*8); //Set regular header memcpy(sc_packet, auth1_pkt_header, 0x10); //Send packet. 0x40 Bytes
Step 3c - Validate AUTH1
First, check the header/footer.
- Calculate AES OMAC over the packet length and compare to OMAC from syscon. Use sc2be key.
- Decrypt internal packet with sc2be key. Use AES128CBC
- Compare returned session_id and seq_service_id.
- Check secure_payload_buf[0x2] == 0.
Then check the AUTH1 response
// decrypt secure_payload for (i = 0x0; i < 0x20; i += 0x10) aes128cbc(auth_key_2_0x01, zero_iv, secure_payload_buf + 0x10 + i, 0x10, secure_payload_buf + 0x10 + i); // check if challange returned from syscon is correct res = memcmp(secure_payload_buf + 0x10, random_shit, 0x10); if (res != 0) return -1; // save the new challange needed for AUTH2 memcpy(auth_challenge, secure_payload_buf + 0x20, 0x10);
Step 3d - AUTH2 to SC
//AUTH2 Challenge Payload aes128cbc_enc(auth_key_1_0x01, zero_iv, auth_challenge, 0x10, secure_payload_buf + 0x10); //length = 0x20 //Create secure header/footer // create header: 5 bytes + random stuff (0xb) payload_header->session_id = session_id; payload_header->seq_service_id = seq_service_id++; // starts at 0 payload_header->packet_type = 0xFF; payload_header->magic[0] = 0xAD; payload_header->magic[1] = 0x1A; rnd_gen((u8*) &payload_header->prng_random, 0x0B); //encrypt payload aes128cbc_enc(be2sc_key, zero_iv, secure_payload_buf, length, secure_payload_buf); // create footer: omac1 of the whole packet aesOmac1Mode(secure_payload_buf + length, secure_payload_buf, length, be2sc_key, sizeof(be2sc_key)*8); //Set regular header memcpy(sc_packet, auth2_pkt_header, 0x10); //Put packet - 0x40 packet length
Step 3e - Validate AUTH2
Again, check the header/footer.
- Calculate AES OMAC over the packet length and compare to OMAC from syscon. Use sc2be key.
- Decrypt internal packet with sc2be key. Use AES128-CBC
- Compare returned session_id and seq_service_id.
- Check secure_payload_buf[0x2] == 0.
// encrypt random_shit using auth_challenge (returned from AUTH1 reply) as key and 0 IV aes128cbc_enc(auth_challenge, zero_iv, random_shit, 0x10, session_key); // encrypt result in place with session_key_create[0x10 * sess_id] and IV 0 (result will be the session_key) aes128cbc_enc(session_key_create + (session_id * 0x10), zero_iv, session_key, 0x10, session_key); // use the session_key to decrypt auth2_payload in place (0x10) aes128cbc(session_key, zero_iv, secure_payload_buf + 0x10, 0x10, secure_payload_buf + 0x10); // compare the result with a 0x10 zero string res = memcmp(secure_payload_buf + 0x10, zero_iv, 0x10); //res == 0x0 is good.
Step 4 - Profit?
You are now authenticated with syscon, and can use privileged commands. Just use the session_key calculated from the AUTH2 reply to encrypt/decrypt responses.