SC Communication: Difference between revisions

From PS3 Developer wiki
Jump to navigation Jump to search
m (AUTH1 to SC)
 
(61 intermediate revisions by 9 users not shown)
Line 1: Line 1:
[[Category:Software]]
=Introduction=
=Introduction=


* The following information was reverse engineered from lv0ldr, lv0, lv1, and sc_iso.self.
* The following information was reverse engineered from [[lv0ldr]], [[lv0]], [[Hypervisor_Reverse_Engineering#System_Controller_.28SC_or_SYSCON.29|lv1]].[[SC_Manager|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!
* Big thanks to graf_chokolo for a large part of the basis of this page, and to Jestero for Syscon Authentication info!


Line 16: Line 15:
! Offset (from start of address space) !! Size !! Description
! Offset (from start of address space) !! Size !! Description
|-
|-
|0xC000 || 0xFF0 || Syscon packet send area
|0xC000 || 0xFF0 || Syscon packet send area (Cell reads from here)
|-
|-
|0xCFF0 || 0x4  || Syscon sent packet counter
|0xCFF0 || 0x4  || Syscon packet TX counter
|-
|-
|0xCFF4 || 0x4  || Syscon sent packet acknowledge counter
|0xCFF4 || 0x4  || Syscon packet RX counter
|-
|-
|0xD000 || 0xFF0 || Syscon packet receive area
|0xD000 || 0xFF0 || Cell packet send area
|-
|-
|0xDFF0 || 0x4  || Syscon received packet counter
|0xDFF0 || 0x4  || Cell packet TX counter
|-
|-
|0xDFF4 || 0x4  || Syscon received packet acknowledge counter
|0xDFF4 || 0x4  || Cell packet RX counter
|-
|-
|0xE100 || 0x4  || Tells syscon there is a packet to be received
|0xE100 || 0x4  || Tells syscon there is a packet to be received
Line 37: Line 36:


=Syscon Services=
=Syscon Services=
* To be completed...
* To be completed... (see {{talk}} page for examples)
 
<pre>
03 SERV_SDA        (not available on Sherwood)
10 SERV_DEVPM
11 SERV_THERM
12 SERV_SETCFG
13 SERV_SYSPM
14 SERV_NVS
15 SERV_SIRCS      (not available on Sherwood)
16 SERV_NOTIF
17 SERV_INTR_NOTIF  (not available on Sherwood)
18 SERV_VERS
1B SERV_LIVELOCK
1C SERV_OSWDT
1E SERV_DIAG        (not available on Sherwood)
1F SERV_SECU
20 SERV_CONSOLE
2D SERV_PATCH
30 SERV_HDMI
40 SERV_LS
50 SERV_STORAGE    (not available on Sherwood)
 
F1 CC_CGMS_191F8
F2 SERV_LS_DATA_23EBC
</pre>


{| class="wikitable FCK__ShowTableBorders"
{| class="wikitable FCK__ShowTableBorders"
Line 43: Line 67:
! Service ID !! Description
! Service ID !! Description
|-
|-
| 0x14 || NVS Service - Used for eeprom read/write (Non-Volatile Storage?)
| 0x03 || Device Access Service - Used for eeprom read/write.
|-
|-
| 0x18 || Livelock(?) Service - Checks for permission to use other services
| 0x10 || Device Power Service (PS2 PCI Bus Power On/Off)
|-
|-
| 0x1F || Authenticated Services
| 0x11 || Time Zone Presence, Temperature, Thermal Alert Mode,
|-
| 0x12 || Config Info Service (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. See: [[SC Manager#0x900B - SC Read EPROM]]
|-
| 0x15 || Serial Infrared Remote Control System
|-
| 0x16 || Notification / (LED / Buzzer) Service - Controls the lights on the console and the ring buzzer.
|-
| 0x17 || Interrupt Notification Service
|-
| 0x18 || Version Service - Versioning related (SC Type/Major-,Minor Version)
|-
| 0x1B || Livelock(?) Service - Checks for permission to use other services.
|-
| 0x1C || Operating System Watch Dog Timer
|-
| 0x1E || Diag Service
|-
| 0x20 || Syscon Console Output - Used to send a string to syscon.
|-
| 0x2D || Syscon Patch Service
|-
| 0x30 || A/V Service / HDMI Service
|-
| 0x40 || LabStation (Fun Stuff)
|-
| 0x50 || Storage Service
|-
| 0x1F || Secure Services. (sc_secure_service)
|-
| 0xF1 || Copy Generation Management System Configuration
|-
| 0xF2 || LabStation Data (More FunStuff)
|-
| 0xFF || Syscon Init (Seen in lv0ldr init sequence to syscon: [[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 ;)
 
{| class="wikitable FCK__ShowTableBorders"
|-
! What? !! Description || Data || Notes
|-
| AUTH1 || AUTH1 Header || 0x1F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00,<br>0x00, 0x30, 0x00, 0x30 || On AUTH1 UART SC Packets it's instead 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|-
| AUTH2 || AUTH2 Header || 0x1F, 0x01, 0x00, 0x01, 0x00, 0x00, 0x80, 0x21, 0x00, 0x00, 0x00, 0x00,<br>0x00, 0x30, 0x00, 0x30 || On AUTH2 UART SC Packets it's instead 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|-
| Debug Output || Sends string to Syscon TTY || 0x20, 0x01, 0x00, 0x07, 0x00, 0x00, 0x80, 0x28, 0x00, 0x00, 0x00, 0x00<br>|| 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,<br>0x00, 0x08, 0x00, 0x08,<br>0x20, 0x29, 0x0A, 0x00, 0x00, 0x00, 0x01, 0xB6||
|-
| Shutdown || || 0x13, 0x01, 0x00, 0x0D, 0x00, 0x00, 0x80, 0x21, 0x00, 0x00, 0x00, 0x00,<br>0x00, 0x04, 0x00, 0x04,<br>0x11, 0x00, 0x00, 0x00|| Will not gracefully shut down HD.
|-
| Soft Restart || || 0x13, 0x01, 0x00, 0x0D, 0x00, 0x00, 0x80, 0x21, 0x00, 0x00, 0x00, 0x00,<br>0x00, 0x04, 0x00, 0x04,<br>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,<br>0x00, 0x04, 0x00, 0x04,<br>0x11, 0x00, 0x00, 0x02|| Restarts, but kills power between boots.
|-
| Panic || || 0x13, 0x01, 0x00, 0x0D, 0x00, 0x00, 0x80, 0x21, 0x00, 0x00, 0x00, 0x00,<br>0x00, 0x04, 0x00, 0x04,<br>0x11, 0x00, 0x00, 0x03|| Shuts down, beeps, and kills power LED until power button pressed, or power removed.
|-
| Set Wake Up Source to Restart after Shutdown (Patch) || || 0x13, 0x01, 0x13, 0x12, 0x00, 0x00, 0x80, 0x39, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x08, 0x12, 0x00, 0x00, 0x00, 0x80, 0x00, 0x02, 0x74 || Sets Wake Up Source to Wake Up after Shutdown
|-
| Shutdown Some Syscon Services Responsible for Patch  || || 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x11, 0x00, 0x00, 0x09 || Shutdown Some Syscon Services Responsible for Patch
|-
|-
| 0xFF || Syscon Init (Seen in lv0ldr init sequence to syscon: http://www.ps3devwiki.com/wiki/User_talk:JuanNadie)
|}
|}


Line 76: Line 167:
struct secure_payload_header {
struct secure_payload_header {
     u8 session_id;
     u8 session_id;
     u8 seq_service_id;  //service_ID (Unsecure uses 0xFF, AUTH1 = 0x02, AUTH2 = 0x03, READ/WRITE = 0x04)
     u8 seq_service_id;  //service_ID (Unsecure uses 0xFF, AUTH1 = 0x02, AUTH2 = 0x03, READ_DATA = 0x04, WRITE_DATA = 0x05)
     u8 packet_type;    //0xFF for BE->SC, 0x00 for SC->BE (if success)
     u8 packet_type;    //0xFF for BE->SC, 0x00 for SC->BE (if success)
     u8 magic[0x2];      //0xAD1A
     u8 magic[0x2];      //0xAD1A
Line 85: Line 176:
=== Step 3b - AUTH 1 to SC ===
=== Step 3b - AUTH 1 to SC ===
<pre>
<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];
uint8_t random_shit[0x10];
auth_key_1_0x01 = enc_key_seeds + (session_id * (0x10*2));
auth_key_1_0x01 = enc_key_seeds + (session_id * (0x10*2));
Line 96: Line 186:
aes128cbc_enc(auth_key_1_0x01, zero_iv, random_shit, 0x10, secure_payload_buf + 0x10);
aes128cbc_enc(auth_key_1_0x01, zero_iv, random_shit, 0x10, secure_payload_buf + 0x10);


//length = 0x20
//Create secure header/footer
//Create secure header/footer
// create header: 5 bytes + random stuff (0xb)
// create header: 5 bytes + random stuff (0xb)
Line 114: Line 205:
memcpy(sc_packet, auth1_pkt_header, 0x10);
memcpy(sc_packet, auth1_pkt_header, 0x10);


//Send packet.
//Send packet. 0x40 Bytes
</pre>
</pre>
=== Step 3c - Validate AUTH1 ===
First, check the header/footer.
* Calculate AES [http://en.wikipedia.org/wiki/One-key_MAC OMAC] over the packet length and compare to [http://en.wikipedia.org/wiki/One-key_MAC 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
<pre>
// 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);
</pre>
=== Step 3d - AUTH2 to SC ===
<pre>
//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
</pre>
=== Step 3e - Validate AUTH2 ===
Again, check the header/footer.
* Calculate AES [http://en.wikipedia.org/wiki/One-key_MAC OMAC] over the packet length and compare to [http://en.wikipedia.org/wiki/One-key_MAC 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.
<pre>
// 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.
</pre>
== 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.
= Some Samples from DYN-001 Syscon SPI SC Comms =
* https://mega.nz/#!2w00VAjK!u10PD2b0G-MqwUZTBD4Nv_by36QNn8P-jVIUxq0pLDM (dead link)
<pre>
00 70 0B 93 FF DC CF 43 97 68 49 06 71 32 27 C1
E8 9F D1 73 DA 4D FA A2 7C 6F 24 F7 BD 95 37 EC
F9 17 5B BB DB 32 E8 82 55 3F 51 23 F1 71 E6 88
</pre>
{{Reverse engineering}}<noinclude>[[Category:Main]]</noinclude>

Latest revision as of 01:10, 10 November 2021

Introduction[edit | edit source]

  • 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[edit | edit source]

  • 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 (Cell reads from here)
0xCFF0 0x4 Syscon packet TX counter
0xCFF4 0x4 Syscon packet RX counter
0xD000 0xFF0 Cell packet send area
0xDFF0 0x4 Cell packet TX counter
0xDFF4 0x4 Cell packet RX 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[edit | edit source]

  • To be completed... (see Discussion page for examples)
03 SERV_SDA         (not available on Sherwood)
10 SERV_DEVPM
11 SERV_THERM
12 SERV_SETCFG
13 SERV_SYSPM
14 SERV_NVS
15 SERV_SIRCS       (not available on Sherwood)
16 SERV_NOTIF
17 SERV_INTR_NOTIF  (not available on Sherwood)
18 SERV_VERS
1B SERV_LIVELOCK
1C SERV_OSWDT
1E SERV_DIAG        (not available on Sherwood)
1F SERV_SECU
20 SERV_CONSOLE
2D SERV_PATCH
30 SERV_HDMI
40 SERV_LS
50 SERV_STORAGE     (not available on Sherwood)

F1 CC_CGMS_191F8
F2 SERV_LS_DATA_23EBC
Service ID Description
0x03 Device Access Service - Used for eeprom read/write.
0x10 Device Power Service (PS2 PCI Bus Power On/Off)
0x11 Time Zone Presence, Temperature, Thermal Alert Mode,
0x12 Config Info Service (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. See: SC Manager#0x900B - SC Read EPROM
0x15 Serial Infrared Remote Control System
0x16 Notification / (LED / Buzzer) Service - Controls the lights on the console and the ring buzzer.
0x17 Interrupt Notification Service
0x18 Version Service - Versioning related (SC Type/Major-,Minor Version)
0x1B Livelock(?) Service - Checks for permission to use other services.
0x1C Operating System Watch Dog Timer
0x1E Diag Service
0x20 Syscon Console Output - Used to send a string to syscon.
0x2D Syscon Patch Service
0x30 A/V Service / HDMI Service
0x40 LabStation (Fun Stuff)
0x50 Storage Service
0x1F Secure Services. (sc_secure_service)
0xF1 Copy Generation Management System Configuration
0xF2 LabStation Data (More FunStuff)
0xFF Syscon Init (Seen in lv0ldr init sequence to syscon: User_talk:JuanNadie)

Syscon Packet Headers[edit | edit source]

  • 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
On AUTH1 UART SC Packets it's instead 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
AUTH2 AUTH2 Header 0x1F, 0x01, 0x00, 0x01, 0x00, 0x00, 0x80, 0x21, 0x00, 0x00, 0x00, 0x00,
0x00, 0x30, 0x00, 0x30
On AUTH2 UART SC Packets it's instead 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
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.
Set Wake Up Source to Restart after Shutdown (Patch) 0x13, 0x01, 0x13, 0x12, 0x00, 0x00, 0x80, 0x39, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x08, 0x12, 0x00, 0x00, 0x00, 0x80, 0x00, 0x02, 0x74 Sets Wake Up Source to Wake Up after Shutdown
Shutdown Some Syscon Services Responsible for Patch 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x11, 0x00, 0x00, 0x09 Shutdown Some Syscon Services Responsible for Patch

Syscon Authentication[edit | edit source]

- An IV of 0x00 is used for most AES steps.

Step 1 - Generate Individual Seeds[edit | edit source]

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[edit | edit source]

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[edit | edit source]

Pick a session_id. Must be <= 7.

Step 3a - Secure Packet Header[edit | edit source]

struct secure_payload_header {
    u8 session_id;
    u8 seq_service_id;  //service_ID (Unsecure uses 0xFF, AUTH1 = 0x02, AUTH2 = 0x03, READ_DATA = 0x04, WRITE_DATA = 0x05)
    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[edit | edit source]

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[edit | edit source]

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[edit | edit source]

//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[edit | edit source]

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?[edit | edit source]

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.


Some Samples from DYN-001 Syscon SPI SC Comms[edit | edit source]

00 70 0B 93 FF DC CF 43 97 68 49 06 71 32 27 C1 
E8 9F D1 73 DA 4D FA A2 7C 6F 24 F7 BD 95 37 EC 
F9 17 5B BB DB 32 E8 82 55 3F 51 23 F1 71 E6 88