// // Encrypt a packed cartridge into a crypted cartridge // private void Encrypt() { _decrypted.CopyTo(_encrypted, 0); // // Content // byte[] content = new byte[0x40]; Buffer.BlockCopy(_decrypted, 0, content, 0, 0x40); // Checksum content Buffer.BlockCopy(Crc16_Checksum.Checksum(content), 0, _encrypted, 0x40, 2); // Encrypt content byte[] contentEncrypted = Desx_Crypto.Encrypt(_key, content); Buffer.BlockCopy(contentEncrypted, 0, _encrypted, 0, 0x40); // Checksum crypted content Buffer.BlockCopy(Crc16_Checksum.Checksum(contentEncrypted), 0, _encrypted, 0x46, 2); // // Current Material Quantity // byte[] currentMaterialQuantity = new byte[8]; Buffer.BlockCopy(_decrypted, 0x58, currentMaterialQuantity, 0, 8); // Checksum current material quantity Buffer.BlockCopy(Crc16_Checksum.Checksum(currentMaterialQuantity), 0, _encrypted, 0x62, 2); // Encrypt current material quantity byte[] currentMaterialQuantityEncrypted = Desx_Crypto.Encrypt(_key, currentMaterialQuantity); Buffer.BlockCopy(currentMaterialQuantityEncrypted, 0, _encrypted, 0x58, 8); // Checksum crypted current material quantity Buffer.BlockCopy(Crc16_Checksum.Checksum(currentMaterialQuantityEncrypted), 0, _encrypted, 0x60, 2); }
// // Decrypt a crypted cartridge into a packed cartridge // private void Decrypt() { _encrypted.CopyTo(_decrypted, 0); // // Content // byte[] contentEncrypted = new byte[0x40]; Buffer.BlockCopy(_encrypted, 0, contentEncrypted, 0, 0x40); // Validate crypted content checksum if (!Crc16_Checksum.Checksum(contentEncrypted).SequenceEqual(_cryptedContentCRC)) { throw new Exception("invalid crypted content checksum"); } // Decrypt content byte[] content = Desx_Crypto.Decrypt(_key, contentEncrypted); Buffer.BlockCopy(content, 0, _decrypted, 0, 0x40); // Validating plaintext checksum if (!Crc16_Checksum.Checksum(content).SequenceEqual(_plainContentCRC)) { throw new Exception( "invalid content checksum: should have " + _plainContentCRC.HexString() + " but have " + Crc16_Checksum.Checksum(content).HexString()); } // // Current Material Quantity // byte[] currentMaterialQuantityEncrypted = new byte[8]; Buffer.BlockCopy(_encrypted, 0x58, currentMaterialQuantityEncrypted, 0, 8); // Validate crypted current material quantity checksum if (!Crc16_Checksum.Checksum(currentMaterialQuantityEncrypted).SequenceEqual(_currentMaterialQuantityCryptedCRC)) { throw new Exception("invalid current material quantity checksum"); } // Decrypt current material quantity byte[] currentMaterialQuantityDecrypted = Desx_Crypto.Decrypt(_key, currentMaterialQuantityEncrypted); Buffer.BlockCopy(currentMaterialQuantityDecrypted, 0, _decrypted, 0x58, 8); // Validating current material quantity checksum if (!Crc16_Checksum.Checksum(currentMaterialQuantityDecrypted).SequenceEqual(_currentMaterialQuantityCRC)) { throw new Exception("invalid current material quantity checksum"); } }
// // Build a key used to encrypt/decrypt a cartridge // private void BuildKey() { Buffer.BlockCopy(_encrypted, 0x17, _keyFragment, 0, 8); if (!Crc16_Checksum.Checksum(_keyFragment, 0x14d0).SequenceEqual(_keyFragmentCRC)) { throw new Exception("invalid keyfragment checksum: should have " + _keyFragmentCRC.HexString() + " but have " + Crc16_Checksum.Checksum(_keyFragment).HexString()); } _keyFragment = shuffle_key_fragment(_keyFragment); byte[] machine_number = _machine.Number; _key[0] = (byte)(~_eepromUID[3] & 0xff); _key[1] = (byte)(~machine_number[3] & 0xff); _key[2] = (byte)(~machine_number[1] & 0xff); _key[3] = (byte)(~_keyFragment[0] & 0xff); _key[4] = (byte)(~_keyFragment[1] & 0xff); _key[5] = (byte)(~_keyFragment[2] & 0xff); _key[6] = (byte)(~_eepromUID[5] & 0xff); _key[7] = (byte)(~_keyFragment[3] & 0xff); _key[8] = (byte)(~machine_number[7] & 0xff); _key[9] = (byte)(~machine_number[5] & 0xff); _key[10] = (byte)(~machine_number[2] & 0xff); _key[11] = (byte)(~_eepromUID[1] & 0xff); _key[12] = (byte)(~_eepromUID[4] & 0xff); _key[13] = (byte)(~_keyFragment[4] & 0xff); _key[14] = (byte)(~_keyFragment[5] & 0xff); _key[15] = (byte)(~_eepromUID[6] & 0xff); _key[16] = (byte)(~_keyFragment[6] & 0xff); _key[17] = (byte)(~machine_number[0] & 0xff); _key[18] = (byte)(~machine_number[6] & 0xff); _key[19] = (byte)(~_eepromUID[0] & 0xff); _key[20] = (byte)(~machine_number[4] & 0xff); _key[21] = (byte)(~_keyFragment[7] & 0xff); _key[22] = (byte)(~_eepromUID[2] & 0xff); machine_number = null; }