private CASCHandler(CASCConfig config) : base(config) { using (var fs = OpenEncodingFile(this)) EncodingHandler = new EncodingHandler(fs); if ((CASCConfig.LoadFlags & LoadFlags.Download) != 0) { using var fs = OpenDownloadFile(EncodingHandler, this); DownloadHandler = new DownloadHandler(fs); } KeyService.LoadKeys(); using (var fs = OpenRootFile(EncodingHandler, this)) RootHandler = new WowRootHandler(fs); if ((CASCConfig.LoadFlags & LoadFlags.Install) != 0) { using var fs = OpenInstallFile(EncodingHandler, this); InstallHandler = new InstallHandler(fs); } }
private static byte[] Decrypt(byte[] data, int index) { byte keyNameSize = data[1]; if (keyNameSize == 0 || keyNameSize != 8) { throw new BLTEDecoderException(2, "keyNameSize == 0 || keyNameSize != 8"); } byte[] keyNameBytes = new byte[keyNameSize]; Array.Copy(data, 2, keyNameBytes, 0, keyNameSize); ulong keyName = BitConverter.ToUInt64(keyNameBytes, 0); byte IVSize = data[keyNameSize + 2]; if (IVSize != 4 || IVSize > 0x10) { throw new BLTEDecoderException(2, "IVSize != 4 || IVSize > 0x10"); } byte[] IVpart = new byte[IVSize]; Array.Copy(data, keyNameSize + 3, IVpart, 0, IVSize); if (data.Length < IVSize + keyNameSize + 4) { throw new BLTEDecoderException(2, "data.Length < IVSize + keyNameSize + 4"); } int dataOffset = keyNameSize + IVSize + 3; byte encType = data[dataOffset]; if (encType != ENCRYPTION_SALSA20 && encType != ENCRYPTION_ARC4) // 'S' or 'A' { throw new BLTEDecoderException(2, "encType != ENCRYPTION_SALSA20 && encType != ENCRYPTION_ARC4"); } dataOffset++; // expand to 8 bytes byte[] IV = new byte[8]; Array.Copy(IVpart, IV, IVpart.Length); // magic for (int shift = 0, i = 0; i < sizeof(int); shift += 8, i++) { IV[i] ^= (byte)((index >> shift) & 0xFF); } byte[] key = KeyService.GetKey(keyName); if (key == null) { throw new BLTEDecoderException(3, "unknown keyname {0:X16}", keyName); } if (encType == ENCRYPTION_SALSA20) { ICryptoTransform decryptor = KeyService.SalsaInstance.CreateDecryptor(key, IV); return(decryptor.TransformFinalBlock(data, dataOffset, data.Length - dataOffset)); } else { // ARC4 ? throw new BLTEDecoderException(2, "encType ENCRYPTION_ARC4 not implemented"); } }