SHOW:
|
|
- or go back to the newest paste.
1 | /* | |
2 | * SaveData En/Decrypter on PC (GPLv3+) | |
3 | * kirk-engine (C) draan / proxima | |
4 | * jpcsp (C) jpcsp team, especially CryptoEngine by hykem | |
5 | * ported by PopsDeco | |
6 | */ | |
7 | ||
8 | #include <stdio.h> | |
9 | #include <stdlib.h> | |
10 | #include <string.h> | |
11 | #include <sys/stat.h> | |
12 | #include "kirk_engine.h" | |
13 | ||
14 | #define arraycopy(src,srcPos,dest,destPos,len) memcpy((dest)+(destPos),(src)+(srcPos),(len)) | |
15 | ||
16 | typedef unsigned char byte; | |
17 | ||
18 | #if defined(WIN32) || (!defined(__GNUC__) && !defined(__clang__)) | |
19 | #define initstdio() setmode(fileno(stdin),O_BINARY),setmode(fileno(stdout),O_BINARY),setmode(fileno(stderr),O_BINARY); | |
20 | #else | |
21 | #define initstdio() | |
22 | int filelength(int fd){ //constant phrase | |
23 | struct stat st; | |
24 | fstat(fd,&st); | |
25 | return st.st_size; | |
26 | } | |
27 | #endif | |
28 | ||
29 | byte sdHashKey1[16] = {0x40, 0xE6, 0x53, 0x3F, 0x05, 0x11, 0x3A, 0x4E, 0xA1, 0x4B, 0xDA, 0xD6, 0x72, 0x7C, 0x53, 0x4C}; | |
30 | byte sdHashKey2[16] = {0xFA, 0xAA, 0x50, 0xEC, 0x2F, 0xDE, 0x54, 0x93, 0xAD, 0x14, 0xB2, 0xCE, 0xA5, 0x30, 0x05, 0xDF}; | |
31 | byte sdHashKey3[16] = {0x36, 0xA5, 0x3E, 0xAC, 0xC5, 0x26, 0x9E, 0xA3, 0x83, 0xD9, 0xEC, 0x25, 0x6C, 0x48, 0x48, 0x72}; | |
32 | byte sdHashKey4[16] = {0xD8, 0xC0, 0xB0, 0xF3, 0x3E, 0x6B, 0x76, 0x85, 0xFD, 0xFB, 0x4D, 0x7D, 0x45, 0x1E, 0x92, 0x03}; | |
33 | byte sdHashKey5[16] = {0xCB, 0x15, 0xF4, 0x07, 0xF9, 0x6A, 0x52, 0x3C, 0x04, 0xB9, 0xB2, 0xEE, 0x5C, 0x53, 0xFA, 0x86}; | |
34 | byte sdHashKey6[16] = {0x70, 0x44, 0xA3, 0xAE, 0xEF, 0x5D, 0xA5, 0xF2, 0x85, 0x7F, 0xF2, 0xD6, 0x94, 0xF5, 0x36, 0x3B}; | |
35 | byte sdHashKey7[16] = {0xEC, 0x6D, 0x29, 0x59, 0x26, 0x35, 0xA5, 0x7F, 0x97, 0x2A, 0x0D, 0xBC, 0xA3, 0x26, 0x33, 0x00}; | |
36 | ||
37 | typedef struct{ | |
38 | int mode; | |
39 | int unk; | |
40 | unsigned char buf[16]; | |
41 | } _SDCtx1, *SDCtx1; | |
42 | ||
43 | typedef struct{ | |
44 | int mode; | |
45 | unsigned char key[16]; | |
46 | unsigned char pad[16]; | |
47 | unsigned int padSize; | |
48 | } _SDCtx2, *SDCtx2; | |
49 | ||
50 | void ScrambleSD(byte *buf, int size, int seed, int cbc, int kirk) { | |
51 | // Set CBC mode. | |
52 | *(int*)(buf)=cbc; | |
53 | #if 0 | |
54 | buf[0] = 0; | |
55 | buf[1] = 0; | |
56 | buf[2] = 0; | |
57 | buf[3] = (byte) cbc; | |
58 | #endif | |
59 | // Set unkown parameters to 0. | |
60 | buf[4] = 0; | |
61 | buf[5] = 0; | |
62 | buf[6] = 0; | |
63 | buf[7] = 0; | |
64 | ||
65 | buf[8] = 0; | |
66 | buf[9] = 0; | |
67 | buf[10] = 0; | |
68 | buf[11] = 0; | |
69 | ||
70 | // Set the the key seed to seed. | |
71 | *(int*)(buf+12)=seed; | |
72 | #if 0 | |
73 | buf[12] = 0; | |
74 | buf[13] = 0; | |
75 | buf[14] = 0; | |
76 | buf[15] = (byte) seed; | |
77 | #endif | |
78 | // Set the the data size to size. | |
79 | buf[16] = (byte) ((size >> 24) & 0xFF); | |
80 | buf[17] = (byte) ((size >> 16) & 0xFF); | |
81 | buf[18] = (byte) ((size >> 8) & 0xFF); | |
82 | buf[19] = (byte) (size & 0xFF); | |
83 | ||
84 | sceUtilsBufferCopyWithRange(buf, size, buf, size, kirk); | |
85 | } | |
86 | ||
87 | int hleSdSetIndex(SDCtx2 ctx, int encMode) { | |
88 | // Set all parameters to 0 and assign the encMode. | |
89 | ctx->mode = encMode; | |
90 | return 0; | |
91 | } | |
92 | ||
93 | int hleSdCreateList(SDCtx1 ctx, int encMode, int genMode, byte *data, byte *key) { | |
94 | // If the key is not a 16-byte key, return an error. | |
95 | //if (key.length < 0x10) { | |
96 | // return -1; | |
97 | //} | |
98 | int i; | |
99 | ||
100 | // Set the mode and the unknown parameters. | |
101 | ctx->mode = encMode; | |
102 | ctx->unk = 0x1; | |
103 | ||
104 | // Key generator mode 0x1 (encryption): use an encrypted pseudo random number before XORing the data with the given key. | |
105 | if (genMode == 0x1) { | |
106 | unsigned char header[0x10 + 0x14]; | |
107 | byte random[0x14]; | |
108 | byte newKey[0x10]; | |
109 | ||
110 | sceUtilsBufferCopyWithRange(random, 0x14, NULL, 0, 0xE); | |
111 | ||
112 | for (i = 0xF; i >= 0; i--) { | |
113 | newKey[0xF - i] = random[i]; | |
114 | } | |
115 | arraycopy(newKey, 0, header, 0x14, 0x10); | |
116 | for (i = 0; i < 4; i++) { | |
117 | header[0x20 + i] = 0; | |
118 | } | |
119 | ||
120 | // Encryption mode 0x1: encrypt with KIRK CMD4 and XOR with the given key. | |
121 | if (ctx->mode == 0x1) { | |
122 | ScrambleSD(header, 0x10, 0x4, 0x4, 0x04); | |
123 | arraycopy(header, 0, ctx->buf, 0, 0x10); | |
124 | arraycopy(header, 0, data, 0, 0x10); | |
125 | // If the key is not NULL, XOR the hash with it. | |
126 | if (key != NULL) { | |
127 | for (i = 0; i < 16; i++) { | |
128 | ctx->buf[i] = (byte) (ctx->buf[i] ^ key[i]); | |
129 | } | |
130 | } | |
131 | return 0; | |
132 | } else if (ctx->mode == 0x2) { // Encryption mode 0x2: encrypt with KIRK CMD5 and XOR with the given key. | |
133 | ScrambleSD(header, 0x10, 0x100, 0x4, 0x05); | |
134 | arraycopy(header, 0, ctx->buf, 0, 0x10); | |
135 | arraycopy(header, 0, data, 0, 0x10); | |
136 | // If the key is not NULL, XOR the hash with it. | |
137 | if (key != NULL) { | |
138 | for (i = 0; i < 16; i++) { | |
139 | ctx->buf[i] = (byte) (ctx->buf[i] ^ key[i]); | |
140 | } | |
141 | } | |
142 | return 0; | |
143 | } else if (ctx->mode == 0x3) { // Encryption mode 0x3: XOR with SD keys, encrypt with KIRK CMD4 and XOR with the given key. | |
144 | for (i = 0; i < 0x10; i++) { | |
145 | header[0x14 + i] = (byte) (header[0x14 + i] ^ sdHashKey3[i]); | |
146 | } | |
147 | ScrambleSD(header, 0x10, 0xE, 0x4, 0x04); | |
148 | for (i = 0; i < 0x10; i++) { | |
149 | header[i] = (byte) (header[i] ^ sdHashKey4[i]); | |
150 | } | |
151 | arraycopy(header, 0, ctx->buf, 0, 0x10); | |
152 | arraycopy(header, 0, data, 0, 0x10); | |
153 | // If the key is not NULL, XOR the hash with it. | |
154 | if (key != NULL) { | |
155 | for (i = 0; i < 16; i++) { | |
156 | ctx->buf[i] = (byte) (ctx->buf[i] ^ key[i]); | |
157 | } | |
158 | } | |
159 | return 0; | |
160 | } else if (ctx->mode == 0x4) { // Encryption mode 0x4: XOR with SD keys, encrypt with KIRK CMD5 and XOR with the given key. | |
161 | for (i = 0; i < 0x10; i++) { | |
162 | header[0x14 + i] = (byte) (header[0x14 + i] ^ sdHashKey3[i]); | |
163 | } | |
164 | ScrambleSD(header, 0x10, 0x100, 0x4, 0x05); | |
165 | for (i = 0; i < 0x10; i++) { | |
166 | header[i] = (byte) (header[i] ^ sdHashKey4[i]); | |
167 | } | |
168 | arraycopy(header, 0, ctx->buf, 0, 0x10); | |
169 | arraycopy(header, 0, data, 0, 0x10); | |
170 | // If the key is not NULL, XOR the hash with it. | |
171 | if (key != NULL) { | |
172 | for (i = 0; i < 16; i++) { | |
173 | ctx->buf[i] = (byte) (ctx->buf[i] ^ key[i]); | |
174 | } | |
175 | } | |
176 | return 0; | |
177 | } else if (ctx->mode == 0x6) { // Encryption mode 0x6: XOR with new SD keys, encrypt with KIRK CMD5 and XOR with the given key. | |
178 | for (i = 0; i < 0x10; i++) { | |
179 | header[0x14 + i] = (byte) (header[0x14 + i] ^ sdHashKey3[i]); | |
180 | } | |
181 | ScrambleSD(header, 0x10, 0x100, 0x4, 0x05); | |
182 | for (i = 0; i < 0x10; i++) { | |
183 | header[i] = (byte) (header[i] ^ sdHashKey4[i]); | |
184 | } | |
185 | arraycopy(header, 0, ctx->buf, 0, 0x10); | |
186 | arraycopy(header, 0, data, 0, 0x10); | |
187 | // If the key is not NULL, XOR the hash with it. | |
188 | if (key != NULL) { | |
189 | for (i = 0; i < 16; i++) { | |
190 | ctx->buf[i] = (byte) (ctx->buf[i] ^ key[i]); | |
191 | } | |
192 | } | |
193 | return 0; | |
194 | } else { // Encryption mode 0x0: XOR with new SD keys, encrypt with KIRK CMD4 and XOR with the given key. | |
195 | for (i = 0; i < 0x10; i++) { | |
196 | header[0x14 + i] = (byte) (header[0x14 + i] ^ sdHashKey6[i]); | |
197 | } | |
198 | ScrambleSD(header, 0x10, 0x12, 0x4, 0x04); | |
199 | for (i = 0; i < 0x10; i++) { | |
200 | header[i] = (byte) (header[i] ^ sdHashKey7[i]); | |
201 | } | |
202 | arraycopy(header, 0, ctx->buf, 0, 0x10); | |
203 | arraycopy(header, 0, data, 0, 0x10); | |
204 | // If the key is not NULL, XOR the hash with it. | |
205 | if (key != NULL) { | |
206 | for (i = 0; i < 16; i++) { | |
207 | ctx->buf[i] = (byte) (ctx->buf[i] ^ key[i]); | |
208 | } | |
209 | } | |
210 | return 0; | |
211 | } | |
212 | } else if (genMode == 0x2) { // Key generator mode 0x02 (decryption): directly XOR the data with the given key. | |
213 | // Grab the data hash (first 16-bytes). | |
214 | arraycopy(data, 0, ctx->buf, 0, 0x10); | |
215 | // If the key is not NULL, XOR the hash with it. | |
216 | if (key != NULL) { | |
217 | for (i = 0; i < 16; i++) { | |
218 | ctx->buf[i] = (byte) (ctx->buf[i] ^ key[i]); | |
219 | } | |
220 | } | |
221 | return 0; | |
222 | } else { | |
223 | // Invalid mode. | |
224 | return -1; | |
225 | } | |
226 | } | |
227 | ||
228 | int hleSdRemoveValue(SDCtx2 ctx, byte *data, int length) { | |
229 | if (ctx->padSize > 0x10 || (length < 0)) { | |
230 | // Invalid key or length. | |
231 | return -1; | |
232 | } else if (((ctx->padSize + length) <= 0x10)) { | |
233 | // The key hasn't been set yet. | |
234 | // Extract the hash from the data and set it as the key. | |
235 | arraycopy(data, 0, ctx->pad, ctx->padSize, length); | |
236 | ctx->padSize += length; | |
237 | return 0; | |
238 | } else { | |
239 | // Calculate the seed. | |
240 | int seed = 0; | |
241 | switch (ctx->mode) { | |
242 | case 0x6: | |
243 | seed = 0x11; | |
244 | break; | |
245 | case 0x4: | |
246 | seed = 0xD; | |
247 | break; | |
248 | case 0x2: | |
249 | seed = 0x5; | |
250 | break; | |
251 | case 0x1: | |
252 | seed = 0x3; | |
253 | break; | |
254 | case 0x3: | |
255 | seed = 0xC; | |
256 | break; | |
257 | default: | |
258 | seed = 0x10; | |
259 | break; | |
260 | } | |
261 | ||
262 | // Setup the buffers. | |
263 | byte *scrambleBuf = malloc((length + ctx->padSize) + 0x14); | |
264 | ||
265 | // Copy the previous key to the buffer. | |
266 | arraycopy(ctx->pad, 0, scrambleBuf, 0x14, ctx->padSize); | |
267 | ||
268 | // Calculate new key length. | |
269 | int kLen = ctx->padSize; | |
270 | ||
271 | ctx->padSize += length; | |
272 | ctx->padSize &= 0x0F; | |
273 | if(ctx->padSize == 0) { | |
274 | ctx->padSize = 0x10; | |
275 | } | |
276 | ||
277 | // Calculate new data length. | |
278 | length -= ctx->padSize; | |
279 | ||
280 | // Copy data's footer to make a new key. | |
281 | arraycopy(data, length, ctx->pad, 0, ctx->padSize); | |
282 | ||
283 | // Process the encryption in 0x800 blocks. | |
284 | int blockSize = 0; | |
285 | int dataOffset = 0; | |
286 | ||
287 | while (length > 0) { | |
288 | blockSize = (length + kLen >= 0x0800) ? 0x0800 : length + kLen; | |
289 | ||
290 | arraycopy(data, dataOffset, scrambleBuf, 0x14 + kLen, blockSize - kLen); | |
291 | int i; | |
292 | // Encrypt with KIRK CMD 4 and XOR with result. | |
293 | for (i = 0; i < 0x10; i++) { | |
294 | scrambleBuf[0x14 + i] = (byte) (scrambleBuf[0x14 + i] ^ ctx->key[i]); | |
295 | } | |
296 | ScrambleSD(scrambleBuf, blockSize, seed, 0x4, 0x04); | |
297 | arraycopy(scrambleBuf, (blockSize + 0x4) - 0x14, ctx->key, 0, 0x10); | |
298 | ||
299 | // Adjust data length, data offset and reset any key length. | |
300 | length -= (blockSize - kLen); | |
301 | dataOffset += (blockSize - kLen); | |
302 | kLen = 0; | |
303 | } | |
304 | ||
305 | return 0; | |
306 | } | |
307 | } | |
308 | ||
309 | int hleSdGetLastIndex(SDCtx2 ctx, byte *hash, byte *key) { | |
310 | if (ctx->padSize > 0x10) { | |
311 | // Invalid key length. | |
312 | return -1; | |
313 | } | |
314 | ||
315 | // Setup the buffers. | |
316 | byte scrambleEmptyBuf[0x10 + 0x14]; | |
317 | byte keyBuf[0x10]; | |
318 | byte scrambleKeyBuf[0x10 + 0x14]; | |
319 | byte resultBuf[0x10]; | |
320 | byte scrambleResultBuf[0x10 + 0x14]; | |
321 | byte scrambleResultKeyBuf[0x10 + 0x14]; | |
322 | ||
323 | // Calculate the seed. | |
324 | int seed = 0; | |
325 | switch (ctx->mode) { | |
326 | case 0x6: | |
327 | seed = 0x11; | |
328 | break; | |
329 | case 0x4: | |
330 | seed = 0xD; | |
331 | break; | |
332 | case 0x2: | |
333 | seed = 0x5; | |
334 | break; | |
335 | case 0x1: | |
336 | seed = 0x3; | |
337 | break; | |
338 | case 0x3: | |
339 | seed = 0xC; | |
340 | break; | |
341 | default: | |
342 | seed = 0x10; | |
343 | break; | |
344 | } | |
345 | ||
346 | // Encrypt an empty buffer with KIRK CMD 4. | |
347 | ScrambleSD(scrambleEmptyBuf, 0x10, seed, 0x4, 0x04); | |
348 | arraycopy(scrambleEmptyBuf, 0, keyBuf, 0, 0x10); | |
349 | int i; | |
350 | // Apply custom padding management. | |
351 | byte b = ((keyBuf[0] & (byte) 0x80) != 0) ? (byte) 0x87 : 0; | |
352 | for(i = 0; i < 0xF; i++) { | |
353 | keyBuf[i] = (byte) ((keyBuf[i] << 1) | (keyBuf[i + 1] >> 7)); | |
354 | } | |
355 | keyBuf[0xF] = (byte) ((keyBuf[0xF] << 1) ^ b); | |
356 | ||
357 | if (ctx->padSize < 0x10) { | |
358 | byte bb = ((keyBuf[0] & (byte) 0x80) != 0) ? (byte) 0x87 : 0; | |
359 | for(i = 0; i < 0xF; i++) { | |
360 | keyBuf[i] = (byte) ((keyBuf[i] << 1) | (keyBuf[i + 1] >> 7)); | |
361 | } | |
362 | keyBuf[0xF] = (byte) ((keyBuf[0xF] << 1) ^ bb); | |
363 | ||
364 | ctx->pad[ctx->padSize] = (byte) 0x80; | |
365 | if ((ctx->padSize + 1) < 0x10) { | |
366 | for (i = 0; i < (0x10 - ctx->padSize - 1); i++) { | |
367 | ctx->pad[ctx->padSize + 1 + i] = 0; | |
368 | } | |
369 | } | |
370 | } | |
371 | ||
372 | // XOR previous key with new one. | |
373 | for (i = 0; i < 0x10; i++) { | |
374 | ctx->pad[i] = (byte) (ctx->pad[i] ^ keyBuf[i]); | |
375 | } | |
376 | ||
377 | arraycopy(ctx->pad, 0, scrambleKeyBuf, 0x14, 0x10); | |
378 | arraycopy(ctx->key, 0, resultBuf, 0, 0x10); | |
379 | ||
380 | // Encrypt with KIRK CMD 4 and XOR with result. | |
381 | for (i = 0; i < 0x10; i++) { | |
382 | scrambleKeyBuf[0x14 + i] = (byte) (scrambleKeyBuf[0x14 + i] ^ resultBuf[i]); | |
383 | } | |
384 | ScrambleSD(scrambleKeyBuf, 0x10, seed, 0x4, 0x04); | |
385 | arraycopy(scrambleKeyBuf, (0x10 + 0x4) - 0x14, resultBuf, 0, 0x10); | |
386 | ||
387 | // If ctx->mode is the new mode 0x6, XOR with the new hash key 5, else, XOR with hash key 2. | |
388 | if (ctx->mode == 0x6) { | |
389 | for (i = 0; i < 0x10; i++) { | |
390 | resultBuf[i] = (byte) (resultBuf[i] ^ sdHashKey5[i]); | |
391 | } | |
392 | } else { | |
393 | for (i = 0; i < 0x10; i++) { | |
394 | resultBuf[i] = (byte) (resultBuf[i] ^ sdHashKey2[i]); | |
395 | } | |
396 | } | |
397 | ||
398 | // If mode is 2, 4 or 6, encrypt again with KIRK CMD 5 and then KIRK CMD 4. | |
399 | if ((ctx->mode == 0x2) || (ctx->mode == 0x4) || (ctx->mode == 0x6)) { | |
400 | arraycopy(resultBuf, 0, scrambleResultBuf, 0x14, 0x10); | |
401 | ScrambleSD(scrambleResultBuf, 0x10, 0x100, 0x4, 0x05); | |
402 | ScrambleSD(scrambleResultBuf, 0x10, seed, 0x4, 0x04); | |
403 | arraycopy(scrambleResultBuf, 0, resultBuf, 0, 0x10); | |
404 | } | |
405 | ||
406 | // XOR with the supplied key and encrypt with KIRK CMD 4. | |
407 | if (key != NULL) { | |
408 | for (i = 0; i < 0x10; i++) { | |
409 | resultBuf[i] = (byte) (resultBuf[i] ^ key[i]); | |
410 | } | |
411 | arraycopy(resultBuf, 0, scrambleResultKeyBuf, 0x14, 0x10); | |
412 | ScrambleSD(scrambleResultKeyBuf, 0x10, seed, 0x4, 0x04); | |
413 | arraycopy(scrambleResultKeyBuf, 0, resultBuf, 0, 0x10); | |
414 | } | |
415 | ||
416 | // Copy back the generated hash. | |
417 | arraycopy(resultBuf, 0, hash, 0, 0x10); | |
418 | ||
419 | // Clear the context fields. | |
420 | ctx->mode = 0; | |
421 | ctx->padSize = 0; | |
422 | for (i = 0; i < 0x10; i++) { | |
423 | ctx->pad[i] = 0; | |
424 | } | |
425 | for (i = 0; i < 0x10; i++) { | |
426 | ctx->key[i] = 0; | |
427 | } | |
428 | ||
429 | return 0; | |
430 | } | |
431 | ||
432 | int hleSdSetMember(SDCtx1 ctx, byte *data, int length) { | |
433 | if (length <= 0) { | |
434 | return -1; | |
435 | } | |
436 | ||
437 | int finalSeed = 0; | |
438 | byte *dataBuf = calloc(length + 0x14,1); | |
439 | - | byte keyBuf[0x10 + 0x10]; |
439 | + | byte keyBuf[0x10 + 0x10];memset(keyBuf,0,0x20); |
440 | byte hashBuf[0x10]; | |
441 | ||
442 | // Copy the hash stored by hleSdCreateList. | |
443 | arraycopy(ctx->buf, 0, dataBuf, 0x14, 0x10); | |
444 | ||
445 | int i; | |
446 | if (ctx->mode == 0x1) { | |
447 | // Decryption mode 0x01: decrypt the hash directly with KIRK CMD7. | |
448 | ScrambleSD(dataBuf, 0x10, 0x4, 5, 0x07); | |
449 | finalSeed = 0x53; | |
450 | } else if (ctx->mode == 0x2) { | |
451 | // Decryption mode 0x02: decrypt the hash directly with KIRK CMD8. | |
452 | ScrambleSD(dataBuf, 0x10, 0x100, 5, 0x08); | |
453 | finalSeed = 0x53; | |
454 | } else if (ctx->mode == 0x3) { | |
455 | // Decryption mode 0x03: XOR the hash with SD keys and decrypt with KIRK CMD7. | |
456 | for (i = 0; i < 0x10; i++) { | |
457 | dataBuf[0x14 + i] = (byte) (dataBuf[0x14 + i] ^ sdHashKey3[i]); | |
458 | } | |
459 | ScrambleSD(dataBuf, 0x10, 0xE, 5, 0x07); | |
460 | for (i = 0; i < 0x10; i++) { | |
461 | dataBuf[i] = (byte) (dataBuf[i] ^ sdHashKey4[i]); | |
462 | } | |
463 | finalSeed = 0x57; | |
464 | } else if (ctx->mode == 0x4) { | |
465 | // Decryption mode 0x04: XOR the hash with SD keys and decrypt with KIRK CMD8. | |
466 | for (i = 0; i < 0x10; i++) { | |
467 | dataBuf[0x14 + i] = (byte) (dataBuf[0x14 + i] ^ sdHashKey3[i]); | |
468 | } | |
469 | ScrambleSD(dataBuf, 0x10, 0x100, 5, 0x08); | |
470 | for (i = 0; i < 0x10; i++) { | |
471 | dataBuf[i] = (byte) (dataBuf[i] ^ sdHashKey4[i]); | |
472 | } | |
473 | finalSeed = 0x57; | |
474 | } else if (ctx->mode == 0x6) { | |
475 | // Decryption mode 0x06: XOR the hash with new SD keys and decrypt with KIRK CMD8. | |
476 | for (i = 0; i < 0x10; i++) { | |
477 | dataBuf[0x14 + i] = (byte) (dataBuf[0x14 + i] ^ sdHashKey7[i]); | |
478 | } | |
479 | ScrambleSD(dataBuf, 0x10, 0x100, 5, 0x08); | |
480 | for (i = 0; i < 0x10; i++) { | |
481 | dataBuf[i] = (byte) (dataBuf[i] ^ sdHashKey6[i]); | |
482 | } | |
483 | finalSeed = 0x64; | |
484 | } else { | |
485 | // Decryption master mode: XOR the hash with new SD keys and decrypt with KIRK CMD7. | |
486 | for (i = 0; i < 0x10; i++) { | |
487 | dataBuf[0x14 + i] = (byte) (dataBuf[0x14 + i] ^ sdHashKey7[i]); | |
488 | } | |
489 | ScrambleSD(dataBuf, 0x10, 0x12, 5, 0x07); | |
490 | for (i = 0; i < 0x10; i++) { | |
491 | dataBuf[i] = (byte) (dataBuf[i] ^ sdHashKey6[i]); | |
492 | } | |
493 | finalSeed = 0x64; | |
494 | } | |
495 | ||
496 | // Store the calculated key. | |
497 | arraycopy(dataBuf, 0, keyBuf, 0x10, 0x10); | |
498 | ||
499 | if (ctx->unk != 0x1) { | |
500 | arraycopy(keyBuf, 0x10, keyBuf, 0, 0xC); | |
501 | keyBuf[0xC] = (byte) ((ctx->unk - 1) & 0xFF); | |
502 | keyBuf[0xD] = (byte) (((ctx->unk - 1) >> 8) & 0xFF); | |
503 | keyBuf[0xE] = (byte) (((ctx->unk - 1) >> 16) & 0xFF); | |
504 | keyBuf[0xF] = (byte) (((ctx->unk - 1) >> 24) & 0xFF); | |
505 | } | |
506 | ||
507 | // Copy the first 0xC bytes of the obtained key and replicate them | |
508 | // across a new list buffer. As a terminator, add the ctx->unk parameter's | |
509 | // 4 bytes (endian swapped) to achieve a full numbered list. | |
510 | for (i = 0x14; i < (length + 0x14); i += 0x10) { | |
511 | arraycopy(keyBuf, 0x10, dataBuf, i, 0xC); | |
512 | dataBuf[i + 0xC] = (byte) (ctx->unk & 0xFF); | |
513 | dataBuf[i + 0xD] = (byte) ((ctx->unk >> 8) & 0xFF); | |
514 | dataBuf[i + 0xE] = (byte) ((ctx->unk >> 16) & 0xFF); | |
515 | dataBuf[i + 0xF] = (byte) ((ctx->unk >> 24) & 0xFF); | |
516 | ctx->unk++; | |
517 | } | |
518 | ||
519 | arraycopy(dataBuf, length + 0x04, hashBuf, 0, 0x10); | |
520 | ||
521 | ScrambleSD(dataBuf, length, finalSeed, 5, 0x07); | |
522 | //memcpy(data,dataBuf,length);return 0; | |
523 | // XOR the first 16-bytes of data with the saved key to generate a new hash. | |
524 | for (i = 0; i < 0x10; i++) { | |
525 | dataBuf[i] = (byte) (dataBuf[i] ^ keyBuf[i]); | |
526 | } | |
527 | ||
528 | // Copy back the last hash from the list to the first half of keyBuf. | |
529 | arraycopy(hashBuf, 0, keyBuf, 0, 0x10); | |
530 | ||
531 | // Finally, XOR the full list with the given data. | |
532 | for (i = 0; i < length; i++) { | |
533 | data[i] = (byte) (data[i] ^ dataBuf[i]); | |
534 | } | |
535 | ||
536 | return 0; | |
537 | } | |
538 | ||
539 | int hleChnnlsv_21BE78B4(SDCtx1 ctx) { | |
540 | ctx->mode = 0; | |
541 | ctx->unk = 0; | |
542 | int i; | |
543 | for(i = 0; i < 0x10; i++) { | |
544 | ctx->buf[i] = 0; | |
545 | } | |
546 | return 0; | |
547 | } | |
548 | #if 0 | |
549 | DecryptSavedata(byte *inbuf, int size, byte *key, int mode) { | |
550 | // Setup the crypto and keygen modes and initialize both context structs. | |
551 | int sdEncMode = 0; | |
552 | int sdGenMode = 2; | |
553 | SDCtx1 ctx1 = new SDCtx1(); | |
554 | SDCtx2 ctx2 = new SDCtx2(); | |
555 | ||
556 | // Align the buffers to 16-bytes. | |
557 | int alignedSize = ((size + 0xF) >> 4) << 4; | |
558 | byte[] outbuf = new byte[alignedSize + 0x10]; | |
559 | byte[] dataBuf = new byte[alignedSize]; | |
560 | ||
561 | // Fully copy the contents of the encrypted file. | |
562 | arraycopy(inbuf, 0, dataBuf, 0, size); | |
563 | ||
564 | // Check the crypto modes. | |
565 | byte[] NULLKey = new byte[0x10]; | |
566 | if (key == NULLKey) { | |
567 | sdEncMode = 1; | |
568 | } else if ((mode == 1) || (mode == 2)) { // Old crypto mode (up to firmware 2.5.2). | |
569 | sdEncMode = 3; | |
570 | } | |
571 | ||
572 | // Call the SD functions. | |
573 | hleSdSetIndex(ctx2, sdEncMode); | |
574 | hleSdCreateList(ctx1, sdEncMode, sdGenMode, outbuf, key); | |
575 | hleSdRemoveValue(ctx2, outbuf, 0x10); | |
576 | hleSdRemoveValue(ctx2, dataBuf, alignedSize); | |
577 | hleSdSetMember(ctx1, dataBuf, alignedSize); | |
578 | arraycopy(dataBuf, 0, outbuf, 0x10, alignedSize); | |
579 | ||
580 | return outbuf; | |
581 | } | |
582 | #endif | |
583 | //byte* DecryptSavedata(byte *inbuf, int size, byte *key, int mode) { | |
584 | main(int argc, char **argv){ | |
585 | kirk_init(); | |
586 | initstdio(); | |
587 | FILE *f=fopen(argv[1],"rb"); | |
588 | int size=filelength(fileno(f)); | |
589 | char *inbuf=malloc(size); | |
590 | fread(inbuf,1,size,f); | |
591 | fclose(f); | |
592 | - | f=fopen(argv[2],"rb"); |
592 | + | byte key[16];memset(key,0,16); |
593 | - | byte key[16]; |
593 | + | if(strcasecmp(argv[2],"NULL")){ |
594 | - | fread(key,1,16,f); |
594 | + | f=fopen(argv[2],"rb"); |
595 | fread(key,1,16,f); | |
596 | fclose(f); | |
597 | } | |
598 | if(argc>3){ //enc. argv[3]=PARAM.SFO. | |
599 | int sdEncMode = 0; | |
600 | int sdGenMode = 1; | |
601 | _SDCtx1 ctx1; | |
602 | _SDCtx2 ctx2; | |
603 | ||
604 | // Align the buffers to 16-bytes. | |
605 | int alignedSize = ((size + 0xF) >> 4) << 4; | |
606 | byte *outbuf = malloc(alignedSize + 0x10); | |
607 | byte *dataBuf = malloc(alignedSize); | |
608 | ||
609 | // Fully copy the contents of the encrypted file. | |
610 | arraycopy(inbuf, 0, dataBuf, 0, size); | |
611 | ||
612 | int mode=0; | |
613 | // Check the crypto modes. | |
614 | byte nullKey[0x10]; | |
615 | memset(nullKey,0,0x10); | |
616 | if (!memcmp(key,nullKey,0x10)) { | |
617 | sdEncMode = 1; | |
618 | } else if ((mode == 1) || (mode == 2)) { // Old crypto mode (up to firmware 2.5.2). | |
619 | sdEncMode = 3; | |
620 | } | |
621 | ||
622 | // Call the SD functions. | |
623 | hleSdSetIndex(&ctx2, sdEncMode); | |
624 | hleSdCreateList(&ctx1, sdEncMode, sdGenMode, outbuf, key); | |
625 | hleSdRemoveValue(&ctx2, outbuf, 0x10); | |
626 | hleSdRemoveValue(&ctx2, dataBuf, alignedSize); | |
627 | hleSdSetMember(&ctx1, dataBuf, alignedSize); | |
628 | - | fwrite(outbuf,1,alignedSize,stdout); |
628 | + | |
629 | - | } |
629 | + | |
630 | fwrite(outbuf,1,alignedSize+0x10,stdout); | |
631 | }else{ | |
632 | //fprintf(stderr,"%s\n",key); | |
633 | // Setup the crypto and keygen modes and initialize both context structs. | |
634 | int sdEncMode = 0; | |
635 | int sdGenMode = 2; | |
636 | _SDCtx1 ctx1; | |
637 | _SDCtx2 ctx2; | |
638 | ||
639 | // Align the buffers to 16-bytes. | |
640 | int alignedSize = ((size + 0xF) >> 4) << 4; | |
641 | byte *outbuf = malloc(alignedSize - 0x10); | |
642 | byte *dataBuf = malloc(alignedSize); | |
643 | int mode=0; | |
644 | // Fully copy the contents of the encrypted file. | |
645 | arraycopy(inbuf, 0, dataBuf, 0, size); | |
646 | ||
647 | // Check the crypto modes. | |
648 | byte nullKey[0x10]; | |
649 | memset(nullKey,0,0x10); | |
650 | if (!memcmp(key,nullKey,0x10)) { | |
651 | sdEncMode = 1; | |
652 | } else if ((mode == 1) || (mode == 2)) { // Old crypto mode (up to firmware 2.5.2). | |
653 | sdEncMode = 3; | |
654 | } | |
655 | ||
656 | // Call the SD functions. | |
657 | hleSdSetIndex(&ctx2, sdEncMode); | |
658 | hleSdCreateList(&ctx1, sdEncMode, sdGenMode, dataBuf, key); | |
659 | hleSdRemoveValue(&ctx2, dataBuf, 0x10); | |
660 | arraycopy(dataBuf, 0x10, outbuf, 0, alignedSize - 0x10); | |
661 | hleSdRemoveValue(&ctx2, outbuf, alignedSize - 0x10); | |
662 | hleSdSetMember(&ctx1, outbuf, alignedSize - 0x10); | |
663 | fwrite(outbuf,1,alignedSize-0x10,stdout); | |
664 | } | |
665 | return 0; | |
666 | } |