my research and reverse engineering notes/utilities relating to the Xbox 360 (Mirrored from https://github.com/InvoxiPlayGames/x360-research)

more system link

+81 -8
+81 -8
official-software/networking/system_link.md
··· 1 1 **Emma's Xbox 360 Research Notes - Networking** 2 2 3 - Updated 23rd October 2024. 3 + Updated 24th October 2024. 4 4 5 5 Stub page. 6 6 ··· 13 13 This article also applies to Games for Windows - LIVE, in sections discussing 14 14 cross-platform system link. 15 15 16 + Some information on this page was referenced from Xenia's partial 17 + [XNet Implementation](https://github.com/xenia-project/xenia/blob/systemlink/src/xenia/kernel/xnet.cc). 18 + 16 19 ## Encryption Key Initialisation 17 20 18 21 When a title initialises WinSock and XNet, `CXnIp::IpInit` initialises several 19 - encryption keys, likely for three different cryptography types, AES, 3DES and 20 - DES. *(TODO: Check)* Pseudocode for the derivation process is as follows: 22 + encryption keys, for HMAC validation, DES3 packet encryption, and a feed value 23 + for using DES3 in CBC mode. 24 + 25 + These keys are initialised by taking the LAN key from either the optional XEX 26 + header value 0x40404 (16 byte fixed-sized structure with ID 0x0404) on Xbox 360, 27 + or the `lankey` value from the .cfg XML next to the game executable on GfWL, 28 + and using that to build 3 keys forming a buffer of size 0x3C bytes. 29 + 30 + **Key Buffer:** 31 + 32 + When building the key buffer, numbers 0 through 2 are prefixed at the start of 33 + the LAN key and then hashed with either HMAC SHA-1 with the roamable obfuscation 34 + key (Xbox 360), or encrypted* and then a regular SHA-1 (GfWL / cross-platform) 35 + performed on it. 36 + 37 + *\* The LAN key is encrypted - the prefix byte remains unencrypted.* 38 + 39 + | Offset | Size | Description | 40 + | ------ | ------ | -------------------------------------- | 41 + | `0x00` | `0x14` | (HMAC) SHA-1 result for 0x00 + LAN key | 42 + | `0x14` | `0x14` | (HMAC) SHA-1 result for 0x01 + LAN key | 43 + | `0x28` | `0x14` | (HMAC) SHA-1 result for 0x02 + LAN key | 44 + 45 + This buffer is then sliced up into 3 final keys for the encryption process. 46 + 47 + | Offset | Size | Description | 48 + | ------ | ------ | ------------------------------------ | 49 + | `0x00` | `0x10` | HMAC SHA-1 key for packet validation | 50 + | `0x10` | `0x18` | 3DES encryption key for packet data | 51 + | `0x28` | `0x8` | Key for building the CBC feed | 52 + 53 + **Pseudocode:** 21 54 22 55 (Note that this is pseudocode of just key initialisation - it is not C that can 23 56 be compiled nor is it any specific CXnIp function) ··· 70 103 XeCryptSha(&config_buffer, 0x11, NULL, 0, NULL, 0, key_buffer.key3, 0x14); 71 104 } 72 105 73 - // use first 0x10 bytes of key1 for some 0x10 byte key, likely AES 74 - memcpy(this->lan_aes_key, key_buffer.key1, sizeof(this->lan_aes_key)); // 0x10 106 + // use first 0x10 bytes of key1 for a 0x10 byte HMAC-SHA1 key 107 + memcpy(this->lan_hmac_key, key_buffer.key1, sizeof(this->lan_hmac_key)); // 0x10 75 108 76 - // use the next 0x4 bytes of key1 and all of key2 for some 0x18 byte key, likely 3DES 109 + // use the next 0x4 bytes of key1 and all of key2 for a 0x18 byte 3DES key 77 110 memcpy(this->lan_3des_key, key_buffer + 0x10, sizeof(this->lan_3des_key)); // 0x18 78 111 XeCryptDesParity(this->lan_3des_key, sizeof(this->lan_3des_key), this->lan_3des_key); 79 112 80 - // use the first 0x8 bytes of key3 for some 0x8 byte key, likely DES 81 - memcpy(this->lan_des_key, key_buffer.key3, sizeof(this->lan_des_key)); 113 + // use the first 0x8 bytes of key3 for some 0x8 byte key for seeding CBC mode 114 + memcpy(this->lan_cbc_feed, key_buffer.key3, sizeof(this->lan_cbc_feed)); // 0x8 82 115 } 83 116 ``` 117 + 118 + ## Packet Structure 119 + 120 + *(TODO: This is for broadcast on 360 packets, but what about P2P/xplat? Check)* 121 + 122 + All values are in little endian. Why? 123 + 124 + **Xbox 360:** Broadcast messages are sent as IPv4 UDP packets over port 3074, 125 + with a source IP of 0.0.0.1 and a destination IP address of 255.255.255.255. 126 + The destination MAC address is FF:FF:FF:FF:FF:FF. 127 + 128 + **Cross-Platform:** TODO 129 + 130 + ### General Structure 131 + 132 + | Offset | Type / Size | Description | 133 + | -------- | ----------- | ----------------------------------- | 134 + | `0x0` | uint32 | Header flags *(TODO: Check?)* | 135 + | `0x4` | variable | Encrypted packet data | 136 + | variable | Footer | Metadata about the packet | 137 + 138 + Note that parts of the footer will be encrypted depending on the length of the 139 + packet data. 140 + 141 + ### Footer 142 + 143 + | Offset | Type / Size | Description | 144 + | ------ | ----------- | ----------------------------- | 145 + | `0x0` | uint16 | Source port | 146 + | `0x2` | uint16 | Destination port | 147 + | `0x4` | uint32 | Title ID | 148 + | `0x8` | uint32 | Title version | 149 + | `0xC` | uint32 | System kernel version | 150 + | `0x10` | uint8 | Bytes encrypted divided by 8 | 151 + | `0x11` | uint16 | Seed value for the CBC feed | 152 + | `0x13` | byte[0xA] | HMAC SHA-1 checksum | 153 + 154 + ### Encryption 155 + 156 + TODO