MechaCon: Difference between revisions

From PS2 Developer wiki
Jump to navigation Jump to search
Line 28: Line 28:


== Firmware revisions ==
== Firmware revisions ==
Firmware comes in an OTP or mask ROM inside MechaCon, except in CXR706F080, which has a reprogrammable flash ROM.


== EEPROM layout ==
== EEPROM layout ==

Revision as of 17:23, 14 October 2021

MechaCon is short for Mechanics Controller. This chip is the security ic of the PlayStation 2 that implements game disk security, Magic Gate and KELF file decryption.

There are two known main variants of it.

The earlier one is based on SPC 9700 and used till GH-022. Chip name starts with "CXP10". Older versions come in a QFP package, newer versions in a BGA package.

The newer one is ARM based, codenamed "Dragon", and used from GH-023 (SCPH-5000X) onwards. Chip name starts with "CXR7". All versions come in a BGA package. Besides this, "Dragon" also includes the functions that were fulfilled by the separate SysCon chip on earlier boards up to GH-022, as well as the RTC+EEPROM chip, that was separate on earlier boards (or dedicated EEPROM and RTC chips on even earlier boards).

The chip contains (Dragon) or is connected to (on earlier boards) an 512 word eeprom. The content is different between the two main revisions.

SPC

Hardware revisions

  • CXP101064 (only used on early GH-001 boards)
  • CXP102064
  • CXP103049 (BGA case, used in F and G-chassis)

Firmware revisions

Firmware comes in a OTP or mask ROM inside MechaCon.

TODO

Dragon

Hardware revisions

  • CXR706F080 (has a flash ROM for firmware; used for engineering, not used in retail consoles)
  • CXR706080
  • CXR716080
  • CXR726080

Firmware revisions

Firmware comes in an OTP or mask ROM inside MechaCon, except in CXR706F080, which has a reprogrammable flash ROM.

EEPROM layout

Start (word) End (word) Size (byte) Offset in file Description
0 48 96 0x0
48 90 84 0x60
96 128 64 0xC0
128 150 44 0x100
160 190 60 0x140
192 198 12 0x180 Region params (only slim)
204 208 8 0x198 MAC address
211 216 10 0x1A6 wake up time
216 225 18 0x1B0 model number
227 232 10 0x1C6 Region code key seed
232 237 10 0x1D0 Region code ciphertext
240 245 10 0x1E0 iLink id
245 248 6 0x1EA (used by scmd 3, subcmd 48 and 49)
248 253 10 0x1F0 Console id
253 256 6 0x1FA (used by scmd 3, subcmd 48 and 49)
256 312 112 0x200 config 2
312 344 64 0x270 config 0
344 400 112 0x2B0 config 1
400 512 224 0x320 Rom patches ciphertext

Region code

Decryption

int getRegionFlags()
{
	// read kek
	uint8_t key508[8];
	ksGetKey(key508, 508);
	
	// read saved seed from eeprom
	uint8_t keyseed[10];
	eepromRead(227, sizeof(keyseed), keyseed);
	
	// read encrypted region from eeprom
	uint8_t ciphertext[10];
	eepromRead(232, sizeof(ciphertext), ciphertext);
	
	// generate key
	uint8_t key[8];
	desEncrypt(key508, keyseed, key);
	
	// decrypt ciphertext
	uint8_t plaintext[8];
	desDecrypt(key, ciphertext, plaintext);
	
	uint16_t crc = *(uint16_t *) plaintext;
	crc += *(uint16_t *) &plaintext[2];
	crc += *(uint16_t *) &plaintext[4];
	
	// check checksum
	if (crc  == *(uint16_t *) &plaintext[6])
		return *(uint32_t *) plaintext;
	
	retrun 0;
}

Bits

Bit Description
0 Japan
1 USA
2 Europe
3 Oceania
4 Asia
5 Russia
6 China
7 Mexico
16 Development (changes MagicGate keys)
17 Retail MagicGate keys on Development, bypass BootCertify
18 Arcade (changes MagicGate keys)
19 Prototype? (changes MagicGate keys)
20 ? (dvd related)

Rom patch

Decryption

bool readAndDecryptRomPatch()
{
	// read the patch's first half
	uint8_t patches[0xDE];
	eepromRead(400, 0x70, patches);
	
	// check if the -1th byte is 0 (sum is not checked)
	if (patches[0x6E])
		return false;

	// read the patch's second half
	eepromRead(456, 0x70, &patches[0x6E]);
	
	// check if the -1th byte is 0 (sum is not checked)
	if (patches[0xDC])
		return false;

	// read encryption key
	uint8_t key504[8];
	ksGetKey(key504, 504);
	
	// decrypt the patch using DES-ECB
	for (int i = 0; i < 0xD8; i += 8)
		desDecrypt(key504, &patches[i], &patches[i]);

	// check sum
	uint32_t sum = *(uint32_t *)patches;
	sum += *(uint32_t *)&patches[4];
	sum += *(uint32_t *)&patches[8];
	sum += *(uint32_t *)&patches[12];

	if (*(uint32_t *) &patches[0xD8] == ~sum)
		return false;
		
	return true;
}

Content

The patch can contain up to 4 patches.

addressX = The address where to apply the patch

valueX = The data that's written there

svc_addressX = The address where SVC X instruction jumps to.

payload = Arbitrary, could be code or data as well.

Offset Size Name
0x00 0x04 address0
0x04 0x04 address1
0x08 0x04 address2
0x0C 0x04 address3
0x10 0x04 value0
0x14 0x04 value1
0x18 0x04 value2
0x1C 0x04 value3
0x20 0x04 svc_address0
0x24 0x04 svc_address1
0x28 0x04 svc_address2
0x2C 0x04 svc_address3
0x30 0xA8 payload
0xD8 0x04 crc