void cps2_decrypt(const u32 *master_key) { u16 *rom = (u16 *)memory_region_cpu1; int length = memory_length_cpu1; u16 *dec = (u16 *)memory_region_user1; int upper_limit = memory_length_user1; int i; u32 key1[4]; // expand master key to 1st FN 96-bit key expand_1st_key(key1, master_key); // add extra bits for s-boxes with less than 6 inputs key1[0] ^= BIT(key1[0], 1) << 4; key1[0] ^= BIT(key1[0], 2) << 5; key1[0] ^= BIT(key1[0], 8) << 11; key1[1] ^= BIT(key1[1], 0) << 5; key1[1] ^= BIT(key1[1], 8) << 11; key1[2] ^= BIT(key1[2], 1) << 5; key1[2] ^= BIT(key1[2], 8) << 11; for (i = 0; i < 0x10000; ++i) { int a; u16 seed; u32 subkey[2]; u32 key2[4]; if ((i & 0x1fff) == 0) { msg_printf("Decrypting... %d%%\n", i*100/0x10000); } // pass the address through FN1 seed = feistel(i, fn1_groupA, fn1_groupB, fn1_r1_boxes, fn1_r2_boxes, fn1_r3_boxes, fn1_r4_boxes, key1[0], key1[1], key1[2], key1[3]); // expand the result to 64-bit expand_subkey(subkey, seed); // XOR with the master key subkey[0] ^= master_key[0]; subkey[1] ^= master_key[1]; // expand key to 2nd FN 96-bit key expand_2nd_key(key2, subkey); // add extra bits for s-boxes with less than 6 inputs key2[0] ^= BIT(key2[0], 0) << 5; key2[0] ^= BIT(key2[0], 6) << 11; key2[1] ^= BIT(key2[1], 0) << 5; key2[1] ^= BIT(key2[1], 1) << 4; key2[2] ^= BIT(key2[2], 2) << 5; key2[2] ^= BIT(key2[2], 3) << 4; key2[2] ^= BIT(key2[2], 7) << 11; key2[3] ^= BIT(key2[3], 1) << 5; // decrypt the opcodes for (a = i; a < length/2 && a < upper_limit/2; a += 0x10000) { dec[a] = feistel(rom[a], fn2_groupA, fn2_groupB, fn2_r1_boxes, fn2_r2_boxes, fn2_r3_boxes, fn2_r4_boxes, key2[0], key2[1], key2[2], key2[3]); } // copy the unencrypted part (not really needed) /* while (a < length/2) { dec[a] = rom[a]; a += 0x10000; } */ } msg_printf("Decrypting... Complete\n"); //m68000_set_encrypted_range(0x000000, length - 1, dec); }
static void cps2_decrypt(const UINT32 *master_key, unsigned int upper_limit) { UINT16 *rom = (UINT16 *)memory_region(REGION_CPU1); int length = memory_region_length(REGION_CPU1); UINT16 *dec = auto_malloc(length); int i; UINT32 key1[4]; // expand master key to 1st FN 96-bit key expand_1st_key(key1, master_key); // add extra bits for s-boxes with less than 6 inputs key1[0] ^= BIT(key1[0], 1) << 4; key1[0] ^= BIT(key1[0], 2) << 5; key1[0] ^= BIT(key1[0], 8) << 11; key1[1] ^= BIT(key1[1], 0) << 5; key1[1] ^= BIT(key1[1], 8) << 11; key1[2] ^= BIT(key1[2], 1) << 5; key1[2] ^= BIT(key1[2], 8) << 11; for (i = 0; i < 0x10000; ++i) { int a; UINT16 seed; UINT32 subkey[2]; UINT32 key2[4]; if ((i & 0xff) == 0) { char loadingMessage[256]; // for displaying with UI sprintf(loadingMessage, "Decrypting %d%%", i*100/0x10000); ui_set_startup_text(loadingMessage,FALSE); } // pass the address through FN1 seed = feistel(i, fn1_groupA, fn1_groupB, fn1_r1_boxes, fn1_r2_boxes, fn1_r3_boxes, fn1_r4_boxes, key1[0], key1[1], key1[2], key1[3]); // expand the result to 64-bit expand_subkey(subkey, seed); // XOR with the master key subkey[0] ^= master_key[0]; subkey[1] ^= master_key[1]; // expand key to 2nd FN 96-bit key expand_2nd_key(key2, subkey); // add extra bits for s-boxes with less than 6 inputs key2[0] ^= BIT(key2[0], 0) << 5; key2[0] ^= BIT(key2[0], 6) << 11; key2[1] ^= BIT(key2[1], 0) << 5; key2[1] ^= BIT(key2[1], 1) << 4; key2[2] ^= BIT(key2[2], 2) << 5; key2[2] ^= BIT(key2[2], 3) << 4; key2[2] ^= BIT(key2[2], 7) << 11; key2[3] ^= BIT(key2[3], 1) << 5; // decrypt the opcodes for (a = i; a < length/2 && a < upper_limit/2; a += 0x10000) { dec[a] = feistel(rom[a], fn2_groupA, fn2_groupB, fn2_r1_boxes, fn2_r2_boxes, fn2_r3_boxes, fn2_r4_boxes, key2[0], key2[1], key2[2], key2[3]); } // copy the unencrypted part (not really needed) while (a < length/2) { dec[a] = rom[a]; a += 0x10000; } } memory_set_decrypted_region(0, 0x000000, length - 1, dec); m68k_set_encrypted_opcode_range(0,0,length); #if 0 { FILE *f; f = fopen("d:/s.rom","wb"); fwrite(rom,1,0x100000,f); fclose(f); f = fopen("d:/s.dec","wb"); fwrite(dec,1,0x100000,f); fclose(f); } #endif }