SC Communication: Difference between revisions
Jump to navigation
Jump to search
m (→Step 2 - Generate SC_ISO encrypted keys: whoops...) |
m (AUTH1 to SC) |
||
Line 70: | Line 70: | ||
== Step 3 - Authenticate with Syscon == | == Step 3 - Authenticate with Syscon == | ||
Pick a session_id. Must be <= 7. | |||
=== Step 3a - Secure Packet Header === | |||
<pre> | |||
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 | |||
}; | |||
</pre> | |||
=== Step 3b - AUTH 1 to SC === | |||
<pre> | |||
u8 auth1_pkt_header[] = {0x1f,0x01,0x00,0x00,0x00,0x00,0x80,0x20,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x30}; | |||
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); | |||
//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. | |||
</pre> |
Revision as of 19:03, 26 January 2013
Introduction
- The following information was reverse engineered from lv0ldr, lv0, lv1, and 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 |
---|---|
0x14 | NVS Service - Used for eeprom read/write (Non-Volatile Storage?) |
0x18 | Livelock(?) Service - Checks for permission to use other services |
0x1F | Authenticated Services |
0xFF | Syscon Init (Seen in lv0ldr init sequence to syscon: http://www.ps3devwiki.com/wiki/User_talk:JuanNadie) |
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
u8 auth1_pkt_header[] = {0x1f,0x01,0x00,0x00,0x00,0x00,0x80,0x20,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x30}; 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); //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.