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 | } |