TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
CascDecrypt.cpp File Reference
#include "CascLib.h"
#include "CascCommon.h"
+ Include dependency graph for CascDecrypt.cpp:

Classes

struct  _CASC_ENCRYPTION_KEY
 
struct  _CASC_SALSA20
 

Macros

#define __CASCLIB_SELF__
 

Typedefs

typedef struct _CASC_ENCRYPTION_KEY CASC_ENCRYPTION_KEY
 
typedef struct
_CASC_ENCRYPTION_KEY
PCASC_ENCRYPTION_KEY
 
typedef struct _CASC_SALSA20 CASC_SALSA20
 
typedef struct _CASC_SALSA20PCASC_SALSA20
 

Functions

static DWORD Rol32 (DWORD dwValue, DWORD dwRolCount)
 
static LPBYTE FindCascKey (ULONGLONG KeyName)
 
static void Initialize (PCASC_SALSA20 pState, LPBYTE pbKey, DWORD cbKeyLength, LPBYTE pbVector)
 
static int Decrypt (PCASC_SALSA20 pState, LPBYTE pbOutBuffer, LPBYTE pbInBuffer, size_t cbInBuffer)
 
static int Decrypt_Salsa20 (LPBYTE pbOutBuffer, LPBYTE pbInBuffer, size_t cbInBuffer, LPBYTE pbKey, DWORD cbKeySize, LPBYTE pbVector)
 
int CascDecrypt (LPBYTE pbOutBuffer, PDWORD pcbOutBuffer, LPBYTE pbInBuffer, DWORD cbInBuffer, DWORD dwFrameIndex)
 
int CascDirectCopy (LPBYTE pbOutBuffer, PDWORD pcbOutBuffer, LPBYTE pbInBuffer, DWORD cbInBuffer)
 

Variables

static CASC_ENCRYPTION_KEY CascKeys []
 
static const char * szKeyConstant16 = "expand 16-byte k"
 
static const char * szKeyConstant32 = "expand 32-byte k"
 

Macro Definition Documentation

#define __CASCLIB_SELF__

Typedef Documentation

typedef struct _CASC_SALSA20 CASC_SALSA20
typedef struct _CASC_SALSA20 * PCASC_SALSA20

Function Documentation

int CascDecrypt ( LPBYTE  pbOutBuffer,
PDWORD  pcbOutBuffer,
LPBYTE  pbInBuffer,
DWORD  cbInBuffer,
DWORD  dwFrameIndex 
)
206 {
207  ULONGLONG KeyName = 0;
208  LPBYTE pbBufferEnd = pbInBuffer + cbInBuffer;
209  LPBYTE pbKey;
210  DWORD KeyNameSize;
211  DWORD dwShift = 0;
212  DWORD IVSize;
213  BYTE Vector[0x08];
214  BYTE EncryptionType;
215  int nError;
216 
217  // Verify and retrieve the key name size
218  if(pbInBuffer >= pbBufferEnd)
219  return ERROR_FILE_CORRUPT;
220  if(pbInBuffer[0] != 0 && pbInBuffer[0] != 8)
221  return ERROR_NOT_SUPPORTED;
222  KeyNameSize = *pbInBuffer++;
223 
224  // Copy the key name
225  if((pbInBuffer + KeyNameSize) >= pbBufferEnd)
226  return ERROR_FILE_CORRUPT;
227  memcpy(&KeyName, pbInBuffer, KeyNameSize);
228  pbInBuffer += KeyNameSize;
229 
230  // Verify and retrieve the Vector size
231  if(pbInBuffer >= pbBufferEnd)
232  return ERROR_FILE_CORRUPT;
233  if(pbInBuffer[0] != 4 && pbInBuffer[0] != 8)
234  return ERROR_NOT_SUPPORTED;
235  IVSize = *pbInBuffer++;
236 
237  // Copy the initialization vector
238  if((pbInBuffer + IVSize) >= pbBufferEnd)
239  return ERROR_FILE_CORRUPT;
240  memset(Vector, 0, sizeof(Vector));
241  memcpy(Vector, pbInBuffer, IVSize);
242  pbInBuffer += IVSize;
243 
244  // Verify and retrieve the encryption type
245  if(pbInBuffer >= pbBufferEnd)
246  return ERROR_FILE_CORRUPT;
247  if(pbInBuffer[0] != 'S' && pbInBuffer[0] != 'A')
248  return ERROR_NOT_SUPPORTED;
249  EncryptionType = *pbInBuffer++;
250 
251  // Do we have enough space in the output buffer?
252  if((DWORD)(pbBufferEnd - pbInBuffer) > pcbOutBuffer[0])
254 
255  // Check if we know the key
256  pbKey = FindCascKey(KeyName);
257  if(pbKey == NULL)
258  return ERROR_UNKNOWN_FILE_KEY;
259 
260  // Shuffle the Vector with the block index
261  // Note that there's no point to go beyond 32 bits, unless the file has
262  // more than 0xFFFFFFFF frames.
263  for(int i = 0; i < sizeof(dwFrameIndex); i++)
264  {
265  Vector[i] = Vector[i] ^ (BYTE)((dwFrameIndex >> dwShift) & 0xFF);
266  dwShift += 8;
267  }
268 
269  // Perform the decryption-specific action
270  switch(EncryptionType)
271  {
272  case 'S': // Salsa20
273  nError = Decrypt_Salsa20(pbOutBuffer, pbInBuffer, (pbBufferEnd - pbInBuffer), pbKey, 0x10, Vector);
274  if(nError != ERROR_SUCCESS)
275  return nError;
276 
277  // Supply the size of the output buffer
278  pcbOutBuffer[0] = (DWORD)(pbBufferEnd - pbInBuffer);
279  return ERROR_SUCCESS;
280 
281 // case 'A':
282 // return ERROR_NOT_SUPPORTED;
283  }
284 
285  assert(false);
286  return ERROR_NOT_SUPPORTED;
287 }
unsigned long long ULONGLONG
Definition: CascPort.h:144
#define ERROR_UNKNOWN_FILE_KEY
Definition: CascLib.h:35
#define ERROR_INSUFFICIENT_BUFFER
Definition: CascPort.h:213
#define ERROR_FILE_CORRUPT
Definition: CascPort.h:218
arena_t NULL
Definition: jemalloc_internal.h:624
BYTE * LPBYTE
Definition: CascPort.h:152
static LPBYTE FindCascKey(ULONGLONG KeyName)
Definition: CascDecrypt.cpp:68
unsigned int DWORD
Definition: CascPort.h:139
static int Decrypt_Salsa20(LPBYTE pbOutBuffer, LPBYTE pbInBuffer, size_t cbInBuffer, LPBYTE pbKey, DWORD cbKeySize, LPBYTE pbVector)
Definition: CascDecrypt.cpp:194
#define ERROR_NOT_SUPPORTED
Definition: CascPort.h:209
unsigned char BYTE
Definition: CascPort.h:136
#define ERROR_SUCCESS
Definition: CascPort.h:204

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int CascDirectCopy ( LPBYTE  pbOutBuffer,
PDWORD  pcbOutBuffer,
LPBYTE  pbInBuffer,
DWORD  cbInBuffer 
)
290 {
291  // Check the buffer size
292  if((cbInBuffer - 1) > pcbOutBuffer[0])
294 
295  // Copy the data
296  memcpy(pbOutBuffer, pbInBuffer, cbInBuffer);
297  pcbOutBuffer[0] = cbInBuffer;
298  return ERROR_SUCCESS;
299 }
#define ERROR_INSUFFICIENT_BUFFER
Definition: CascPort.h:213
#define ERROR_SUCCESS
Definition: CascPort.h:204

+ Here is the caller graph for this function:

static int Decrypt ( PCASC_SALSA20  pState,
LPBYTE  pbOutBuffer,
LPBYTE  pbInBuffer,
size_t  cbInBuffer 
)
static
108 {
109  LPBYTE pbXorValue;
110  DWORD KeyMirror[0x10];
111  DWORD XorValue[0x10];
112  DWORD BlockSize;
113  DWORD i;
114 
115  // Repeat until we have data to read
116  while(cbInBuffer > 0)
117  {
118  // Create the copy of the key
119  memcpy(KeyMirror, pState->Key, sizeof(KeyMirror));
120 
121  // Shuffle the key
122  for(i = 0; i < pState->dwRounds; i += 2)
123  {
124  KeyMirror[0x04] ^= Rol32((KeyMirror[0x00] + KeyMirror[0x0C]), 0x07);
125  KeyMirror[0x08] ^= Rol32((KeyMirror[0x04] + KeyMirror[0x00]), 0x09);
126  KeyMirror[0x0C] ^= Rol32((KeyMirror[0x08] + KeyMirror[0x04]), 0x0D);
127  KeyMirror[0x00] ^= Rol32((KeyMirror[0x0C] + KeyMirror[0x08]), 0x12);
128 
129  KeyMirror[0x09] ^= Rol32((KeyMirror[0x05] + KeyMirror[0x01]), 0x07);
130  KeyMirror[0x0D] ^= Rol32((KeyMirror[0x09] + KeyMirror[0x05]), 0x09);
131  KeyMirror[0x01] ^= Rol32((KeyMirror[0x0D] + KeyMirror[0x09]), 0x0D);
132  KeyMirror[0x05] ^= Rol32((KeyMirror[0x01] + KeyMirror[0x0D]), 0x12);
133 
134  KeyMirror[0x0E] ^= Rol32((KeyMirror[0x0A] + KeyMirror[0x06]), 0x07);
135  KeyMirror[0x02] ^= Rol32((KeyMirror[0x0E] + KeyMirror[0x0A]), 0x09);
136  KeyMirror[0x06] ^= Rol32((KeyMirror[0x02] + KeyMirror[0x0E]), 0x0D);
137  KeyMirror[0x0A] ^= Rol32((KeyMirror[0x06] + KeyMirror[0x02]), 0x12);
138 
139  KeyMirror[0x03] ^= Rol32((KeyMirror[0x0F] + KeyMirror[0x0B]), 0x07);
140  KeyMirror[0x07] ^= Rol32((KeyMirror[0x03] + KeyMirror[0x0F]), 0x09);
141  KeyMirror[0x0B] ^= Rol32((KeyMirror[0x07] + KeyMirror[0x03]), 0x0D);
142  KeyMirror[0x0F] ^= Rol32((KeyMirror[0x0B] + KeyMirror[0x07]), 0x12);
143 
144  KeyMirror[0x01] ^= Rol32((KeyMirror[0x00] + KeyMirror[0x03]), 0x07);
145  KeyMirror[0x02] ^= Rol32((KeyMirror[0x01] + KeyMirror[0x00]), 0x09);
146  KeyMirror[0x03] ^= Rol32((KeyMirror[0x02] + KeyMirror[0x01]), 0x0D);
147  KeyMirror[0x00] ^= Rol32((KeyMirror[0x03] + KeyMirror[0x02]), 0x12);
148 
149  KeyMirror[0x06] ^= Rol32((KeyMirror[0x05] + KeyMirror[0x04]), 0x07);
150  KeyMirror[0x07] ^= Rol32((KeyMirror[0x06] + KeyMirror[0x05]), 0x09);
151  KeyMirror[0x04] ^= Rol32((KeyMirror[0x07] + KeyMirror[0x06]), 0x0D);
152  KeyMirror[0x05] ^= Rol32((KeyMirror[0x04] + KeyMirror[0x07]), 0x12);
153 
154  KeyMirror[0x0B] ^= Rol32((KeyMirror[0x0A] + KeyMirror[0x09]), 0x07);
155  KeyMirror[0x08] ^= Rol32((KeyMirror[0x0B] + KeyMirror[0x0A]), 0x09);
156  KeyMirror[0x09] ^= Rol32((KeyMirror[0x08] + KeyMirror[0x0B]), 0x0D);
157  KeyMirror[0x0A] ^= Rol32((KeyMirror[0x09] + KeyMirror[0x08]), 0x12);
158 
159  KeyMirror[0x0C] ^= Rol32((KeyMirror[0x0F] + KeyMirror[0x0E]), 0x07);
160  KeyMirror[0x0D] ^= Rol32((KeyMirror[0x0C] + KeyMirror[0x0F]), 0x09);
161  KeyMirror[0x0E] ^= Rol32((KeyMirror[0x0D] + KeyMirror[0x0C]), 0x0D);
162  KeyMirror[0x0F] ^= Rol32((KeyMirror[0x0E] + KeyMirror[0x0D]), 0x12);
163  }
164 
165  // Set the number of remaining bytes
166  pbXorValue = (LPBYTE)XorValue;
167  BlockSize = (DWORD)CASCLIB_MIN(cbInBuffer, 0x40);
168 
169  // Prepare the XOR constants
170  for(i = 0; i < 16; i++)
171  {
172  XorValue[i] = KeyMirror[i] + pState->Key[i];
173  }
174 
175  // Decrypt the block
176  for(i = 0; i < BlockSize; i++)
177  {
178  pbOutBuffer[i] = pbInBuffer[i] ^ pbXorValue[i];
179  }
180 
181  pState->Key[8] = pState->Key[8] + 1;
182  if(pState->Key[8] == 0)
183  pState->Key[9] = pState->Key[9] + 1;
184 
185  // Adjust buffers
186  pbOutBuffer += BlockSize;
187  pbInBuffer += BlockSize;
188  cbInBuffer -= BlockSize;
189  }
190 
191  return ERROR_SUCCESS;
192 }
BYTE * LPBYTE
Definition: CascPort.h:152
#define CASCLIB_MIN(a, b)
Definition: CascCommon.h:73
unsigned int DWORD
Definition: CascPort.h:139
static DWORD Rol32(DWORD dwValue, DWORD dwRolCount)
Definition: CascDecrypt.cpp:63
DWORD dwRounds
Definition: CascDecrypt.cpp:27
DWORD Key[0x10]
Definition: CascDecrypt.cpp:26
#define ERROR_SUCCESS
Definition: CascPort.h:204

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int Decrypt_Salsa20 ( LPBYTE  pbOutBuffer,
LPBYTE  pbInBuffer,
size_t  cbInBuffer,
LPBYTE  pbKey,
DWORD  cbKeySize,
LPBYTE  pbVector 
)
static
195 {
196  CASC_SALSA20 SalsaState;
197 
198  Initialize(&SalsaState, pbKey, cbKeySize, pbVector);
199  return Decrypt(&SalsaState, pbOutBuffer, pbInBuffer, cbInBuffer);
200 }
static int Decrypt(PCASC_SALSA20 pState, LPBYTE pbOutBuffer, LPBYTE pbInBuffer, size_t cbInBuffer)
Definition: CascDecrypt.cpp:107
Definition: CascDecrypt.cpp:24
static void Initialize(PCASC_SALSA20 pState, LPBYTE pbKey, DWORD cbKeyLength, LPBYTE pbVector)
Definition: CascDecrypt.cpp:81

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static LPBYTE FindCascKey ( ULONGLONG  KeyName)
static
69 {
70  // Search the known keys
71  for(size_t i = 0; CascKeys[i].KeyName != 0; i++)
72  {
73  if(CascKeys[i].KeyName == KeyName)
74  return CascKeys[i].Key;
75  }
76 
77  // Key not found
78  return NULL;
79 }
arena_t NULL
Definition: jemalloc_internal.h:624
static CASC_ENCRYPTION_KEY CascKeys[]
Definition: CascDecrypt.cpp:43
BYTE Key[0x10]
Definition: CascDecrypt.cpp:21
ULONGLONG KeyName
Definition: CascDecrypt.cpp:20

+ Here is the caller graph for this function:

static void Initialize ( PCASC_SALSA20  pState,
LPBYTE  pbKey,
DWORD  cbKeyLength,
LPBYTE  pbVector 
)
static
82 {
83  const char * szConstants = (cbKeyLength == 32) ? szKeyConstant32 : szKeyConstant16;
84  DWORD KeyIndex = cbKeyLength - 0x10;
85 
86  memset(pState, 0, sizeof(CASC_SALSA20));
87  pState->Key[0] = *(PDWORD)(szConstants + 0x00);
88  pState->Key[1] = *(PDWORD)(pbKey + 0x00);
89  pState->Key[2] = *(PDWORD)(pbKey + 0x04);
90  pState->Key[3] = *(PDWORD)(pbKey + 0x08);
91  pState->Key[4] = *(PDWORD)(pbKey + 0x0C);
92  pState->Key[5] = *(PDWORD)(szConstants + 0x04);
93  pState->Key[6] = *(PDWORD)(pbVector + 0x00);
94  pState->Key[7] = *(PDWORD)(pbVector + 0x04);
95  pState->Key[8] = 0;
96  pState->Key[9] = 0;
97  pState->Key[10] = *(PDWORD)(szConstants + 0x08);
98  pState->Key[11] = *(PDWORD)(pbKey + KeyIndex + 0x00);
99  pState->Key[12] = *(PDWORD)(pbKey + KeyIndex + 0x04);
100  pState->Key[13] = *(PDWORD)(pbKey + KeyIndex + 0x08);
101  pState->Key[14] = *(PDWORD)(pbKey + KeyIndex + 0x0C);
102  pState->Key[15] = *(PDWORD)(szConstants + 0x0C);
103 
104  pState->dwRounds = 20;
105 }
static const char * szKeyConstant16
Definition: CascDecrypt.cpp:57
DWORD * PDWORD
Definition: CascPort.h:151
Definition: CascDecrypt.cpp:24
static const char * szKeyConstant32
Definition: CascDecrypt.cpp:58
unsigned int DWORD
Definition: CascPort.h:139
DWORD dwRounds
Definition: CascDecrypt.cpp:27
DWORD Key[0x10]
Definition: CascDecrypt.cpp:26

+ Here is the caller graph for this function:

static DWORD Rol32 ( DWORD  dwValue,
DWORD  dwRolCount 
)
static
64 {
65  return (dwValue << dwRolCount) | (dwValue >> (32 - dwRolCount));
66 }

+ Here is the caller graph for this function:

Variable Documentation

CASC_ENCRYPTION_KEY CascKeys[]
static
Initial value:
=
{
{0xFB680CB6A8BF81F3ULL, {0x62, 0xD9, 0x0E, 0xFA, 0x7F, 0x36, 0xD7, 0x1C, 0x39, 0x8A, 0xE2, 0xF1, 0xFE, 0x37, 0xBD, 0xB9}},
{0x402CD9D8D6BFED98ULL, {0xAE, 0xB0, 0xEA, 0xDE, 0xA4, 0x76, 0x12, 0xFE, 0x6C, 0x04, 0x1A, 0x03, 0x95, 0x8D, 0xF2, 0x41}},
{0x87AEBBC9C4E6B601ULL, {0x68, 0x5E, 0x86, 0xC6, 0x06, 0x3D, 0xFD, 0xA6, 0xC9, 0xE8, 0x52, 0x98, 0x07, 0x6B, 0x3D, 0x42}},
{0xA19C4F859F6EFA54ULL, {0x01, 0x96, 0xCB, 0x6F, 0x5E, 0xCB, 0xAD, 0x7C, 0xB5, 0x28, 0x38, 0x91, 0xB9, 0x71, 0x2B, 0x4B}},
{0x11A9203C9881710AULL, {0x2E, 0x2C, 0xB8, 0xC3, 0x97, 0xC2, 0xF2, 0x4E, 0xD0, 0xB5, 0xE4, 0x52, 0xF1, 0x8D, 0xC2, 0x67}},
{0xDBD3371554F60306ULL, {0x34, 0xE3, 0x97, 0xAC, 0xE6, 0xDD, 0x30, 0xEE, 0xFD, 0xC9, 0x8A, 0x2A, 0xB0, 0x93, 0xCD, 0x3C}},
{0xDEE3A0521EFF6F03ULL, {0xAD, 0x74, 0x0C, 0xE3, 0xFF, 0xFF, 0x92, 0x31, 0x46, 0x81, 0x26, 0x98, 0x57, 0x08, 0xE1, 0xB9}},
{0x8C9106108AA84F07ULL, {0x53, 0xD8, 0x59, 0xDD, 0xA2, 0x63, 0x5A, 0x38, 0xDC, 0x32, 0xE7, 0x2B, 0x11, 0xB3, 0x2F, 0x29}},
{0x49166D358A34D815ULL, {0x66, 0x78, 0x68, 0xCD, 0x94, 0xEA, 0x01, 0x35, 0xB9, 0xB1, 0x6C, 0x93, 0xB1, 0x12, 0x4A, 0xBA}},
{0, {0}}
}
const char* szKeyConstant16 = "expand 16-byte k"
static
const char* szKeyConstant32 = "expand 32-byte k"
static