Ernie Secure

SNVS
The syscon provides raw storage. Kermit partitions some of this storage for encrypted data. The keys to encrypt/decrypt this data is from slots 0x502-0x504. They are derived by second_loader by encrypting a constant buffer with key slot 0x216 using AES-256-CBC, which is console unique. Consoles with factory firmware < 0.996 use a set of static keys found in second_loader. Factory firmware comes from idstorage.

Syscon four part key exchange
The  here appears to be a class id. Only  and   has been seen but only   seems to be supported by the update sm using the command 0xD0002 (with different sequence number for each part).

Part 1: Ernie challenges Kermit

 * 1) Generate an empty buffer   and send it to Syscon.
 * 2) Syscon returns header   + 8 byte challenge.

Part 2: Kermit responds and challenges Ernie

 * 1) F00D composes a data buffer that is 8 bytes of RNG value, 8 bytes copied from challenge in part 1.2, and 16 bytes of Shared Data A.
 * 2) This data is encrypted using AES-128-CBC with all zero IV and Shared Key A as the key.
 * 3) A header is prepended   to the data and sent to Syscon

Part 3: Session Key Establishment

 * 1) Gets a 0x28 byte response from Syscon with a header   and 0x20 buffer.
 * 2) Decrypt with AES-128-CBC with all zero IV and the key Shared Key B.
 * 3) Check that first 8 byte matches the challenge from part 1.2 and next 8 byte matches the F00D nonce generated in part 2.1. The remaining 16 bytes are zero.
 * 4) Encrypt the same buffer back using Shared Key C for 16 bytes. The IV will be the last 16 bytes from the encrypted input buffer.
 * 5) This is now the session key!

Part 4: Verification
This part is only seen used with command 0xD0 and not 0xA0.
 * 1) Using the session key, encrypt a known value, Shared Data B.
 * 2) Append the header   and send to Syscon
 * 3) Get a response back from Syscon (header  ), decrypt the buffer with the session, and check that it matches the known value. Both the plaintext and ciphertext should match.

Channel Protocol
Packets sent/received with command 0xD2 are encrypted with the session key and IV = 0. There is a 4 byte command field, 4 byte counter (from keyslot 0x512) that increments per send, 6 bytes of zeros, optional data, and a 2 byte checksum. The checksum is the sum of all previous bytes and then negated.

Syscon 0xA0
This command uses class 0xB and is only seen in secure_loader. No data transfer is seen. The session key derived here is actually not used. The hypothesis is that this handshake serves as a checkpoint for the Syscon to know that F00D has successfully decrypted IDPS and OpenPSID since in between the handshake each decryption happens. The decryption does not use any data from this handshake.

Syscon 0xD0
Establishes a secure channel for class 0xF used by updater 0xD0002 as well as second_loader.

After handshake:

Keyslot 0x511 is programmed with the session key.

Keyslot 0x512 is programmed with a 32 bit random number from Bigmac.

Syscon 0xD2
Data transfer for class 0xF.

Seen at boot
First transaction

F00D => Syscon:

F00D <= Syscon:

Data decrypted using a slot in 0x502-0x504 and result is written to slot 0x50B (8 bytes).

Second transaction

F00D => Syscon:

F00D <= Syscon:

Decrypted is a list of versions, two are read using some information from the MBR. On a default 3.60 retail system, the two offsets used are at 0x4 and 0x8. Those are both checked to be 0x03600000 on 3.60 (hard coded). If they are 0xDEADBEEF, the check is skipped. Additionally, in the decrypted buffer from the previous command (written to slot 0x50B), if bit 1 at byte offset 0x4 is set, then the version check is skipped. Then, if boot is not resume the version from kernel_boot_loader.self is also checked. Finally slot 0x50E and 0x518 are written with these two version codes.