From 6ab3db690589cfd13740af23fe716cf9115e856a Mon Sep 17 00:00:00 2001 From: "R. Belmont" Date: Sun, 28 Feb 2010 01:32:36 +0000 Subject: [PATCH] naomi: Fixed decrypt method 2, added many more game keys [Deunan Knute, R. Belmont] --- src/mame/drivers/naomi.c | 21 ------- src/mame/machine/naomibd.c | 119 +++++++++++++++++-------------------- 2 files changed, 55 insertions(+), 85 deletions(-) diff --git a/src/mame/drivers/naomi.c b/src/mame/drivers/naomi.c index 2b950318e32..8e16d2e27a8 100644 --- a/src/mame/drivers/naomi.c +++ b/src/mame/drivers/naomi.c @@ -3183,27 +3183,6 @@ ROM_START( gwing2 ) ROM_LOAD("mpr-22273.ic3", 0x2800000, 0x1000000, CRC(cd633dcf) SHA1(f044d93802a4ba29d0e70c597d3fbe65da591335) ) ROM_LOAD("mpr-22274.ic4", 0x3800000, 0x1000000, CRC(f8daaaf3) SHA1(8854d3f8e3d55715ede33ee918b641e251f752b4) ) ROM_LOAD("mpr-22275.ic5", 0x4800000, 0x1000000, CRC(61aa1521) SHA1(7d9f5790e72a9151d128ac7887e236526fdf72a0) ) - - // trojaned protection data (filename is address read from) - ROM_REGION( 0x200000, "naomibd_prot", ROMREGION_ERASE00 ) - ROM_LOAD( "a085ddc0.bin", 0x000000, 0x00c960, CRC(77303f1c) SHA1(5dc8799b9ec102540c6e7647eccb69dfc5e6ecfb) ) - ROM_LOAD( "a080c6c0.bin", 0x010000, 0x020000, CRC(168e551a) SHA1(03bb8ce4bb233db75a0e07a8b5ad28149b5f126e) ) - ROM_LOAD( "a082c6c4.bin", 0x030000, 0x020000, CRC(bd2fcd3a) SHA1(2eefa22472d7caf30a3467c1f7ed8dc72f1665c1) ) - ROM_LOAD( "a084c6c8.bin", 0x050000, 0x020000, CRC(c1d28ba0) SHA1(5e497758c3756fe993b481ab2009402a105fbc63) ) - ROM_LOAD( "a08c67e0.bin", 0x070000, 0x020000, CRC(ceabcb70) SHA1(bbc97218f32913eefe52b1bb1606bad60d7c2894) ) - ROM_LOAD( "a08e67e4.bin", 0x090000, 0x020000, CRC(4bc98e7b) SHA1(5f506d05a05a129bf500f0112e39b722872f1220) ) - ROM_LOAD( "a09067e8.bin", 0x0b0000, 0x020000, CRC(4cd8a958) SHA1(d3a96287986ab851acced420c4ff9f4d2035188a) ) - ROM_LOAD( "a09267ec.bin", 0x0d0000, 0x020000, CRC(17c1df0d) SHA1(62964224f27c54651518a8622756c253d777629a) ) - ROM_LOAD( "a09467f0.bin", 0x0f0000, 0x020000, CRC(99c78505) SHA1(bbb95757bc0be76c680255a0e72d2eacc4ca525e) ) - ROM_LOAD( "a09667f4.bin", 0x110000, 0x016360, CRC(bec1fd2f) SHA1(e2e9d47d6d5d35bfa9a432c7f47f95c780b17551) ) - ROM_LOAD( "a088acc0.bin", 0x130000, 0x020000, CRC(abb1e0d9) SHA1(a1d5d484faaa806b365069755660ec14c1cecada) ) - ROM_LOAD( "a08aacc4.bin", 0x150000, 0x01bb00, CRC(2acc08c8) SHA1(c04276ec940a73e4b8fe140ef9f4bec8c629ecc9) ) - ROM_LOAD( "a086a740.bin", 0x170000, 0x020000, CRC(5d90c88c) SHA1(7af4107e1930292d3c64b80cb29d31aae8a565b6) ) - ROM_LOAD( "a088a744.bin", 0x190000, 0x000560, CRC(79c8eb0f) SHA1(0216fa128d9851b96f3864446ef71e0ed6f4ccd0) ) - ROM_LOAD( "a097cb60.bin", 0x1a0000, 0x010820, CRC(371e88d9) SHA1(04f0167000e96d556227e8abf6e06e0698e61e9f) ) - ROM_LOAD( "a0807fa0.bin", 0x1c0000, 0x004700, CRC(4eed5ff3) SHA1(26425baa06959d612b3b7e9f367fbb97258f544e) ) - ROM_LOAD( "a0800000.bin", 0x1d0000, 0x006040, CRC(17651005) SHA1(500806ba917133ae604817c6ee2913d10762e290) ) - ROM_LOAD( "a0806060.bin", 0x1e0000, 0x001f20, CRC(ff25a8fe) SHA1(e8c0ddf63802e3d35478e1a491dc7162283b2474) ) ROM_END /* diff --git a/src/mame/machine/naomibd.c b/src/mame/machine/naomibd.c index c0e59850fe2..02eeb6f566c 100644 --- a/src/mame/machine/naomibd.c +++ b/src/mame/machine/naomibd.c @@ -224,7 +224,7 @@ struct _naomibd_state // live decrypt vars UINT32 dc_gamekey, dc_seqkey, dc_seed; UINT8 dc_cart_ram[128*1024]; // internal cartridge RAM - INT32 dc_m3_ptr, dc_is_m3, dc_m2_ptr, dc_readback; + INT32 dc_m3_ptr, dc_m2_ptr, dc_readback; #if NAOMIBD_PRINTF_PROTECTION int prot_pio_count; @@ -236,22 +236,39 @@ struct _naomibd_state // if key is not -1, it's used for the match instead of the address written. static const naomibd_config_table naomibd_translate_tbl[] = { - // capsnk/capsnka use a game key of 0. Seriously. + // games where on-the-fly decryption works (many of these are fully playable in MAME, just slow) + { "18wheelr", 0, 0x7cf54, { 0x1502, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, + { "alpilota", 0, 0x70e41, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, + { "alpiltdx", 0, 0x70e41, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "capsnk", 0, 0, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "capsnka", 0, 0, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, - { "wwfroyal",0, 0x627c3, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "crzytaxi", 0, 0xd2f45, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, - { "jambo", 0, 0xfab95, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "csmash", 1, 0x03347, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "csmasho", 1, 0x03347, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, - { "toyfight", 0, 0x2ca85, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, - { "suchie3", 0, 0x368e1, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, - - { "vtennis", 0, 0x3eb15, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, -// { "vs2_2k", 0, 0x88b08, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, // uses compression + { "cspike", 0, 0xe2010, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, + { "deathcox", 0, 0xb64d0, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "dybb99", 0, 0x48a01, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, + { "f355twin", 0, 0x6efd4, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, + { "f355twn2", 0, 0x666c6, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, + { "ggram2", 0, 0x74a61, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, + { "gwing2", 0, 0xb25d0, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, + { "hmgeo", 0, 0x38510, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, + { "jambo", 0, 0xfab95, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, + { "otrigger", 0, 0xfea94, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, + { "pjustic", 0, 0x725d0, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, + { "pstone", 0, 0xe69c1, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, + { "pstone2", 0, 0xb8dc0, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, + { "samba", 0, 0xa8b5d, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, + { "slasho", 0, 0xa66ca, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, + { "smlg99", 0, 0x48a01, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, + { "spawn", 0, 0x78d01, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, + { "suchie3", 0, 0x368e1, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, + { "toyfight", 0, 0x2ca85, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, + { "vtennis", 0, 0x3eb15, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, + { "wwfroyal",0, 0x627c3, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "zombrvn", 0, 0x12b41, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, + // games where the encryption is stacked with the ASIC's compression { "doa2", 0, -1, { -1, 0x500, 0, -1, 0x20504, 0x20000, -1, 0x40508, 0x40000, -1, 0x6050c, 0x60000, -1, 0x80510, 0x80000, // 0x8ad01, has compression -1, 0xa0514, 0xa0000, -1, 0xc0518, 0xc0000, -1, 0xe051c, 0xe0000, -1, 0x100520,0x100000, -1, 0x118a3a, 0x120000, -1, 0x12c0d8, 0x140000, -1, 0x147e22, 0x160000, -1, 0x1645ce, 0x180000, -1, 0x17c6b2, 0x1a0000, @@ -260,27 +277,20 @@ static const naomibd_config_table naomibd_translate_tbl[] = -1, 0xa0514, 0xa0000, -1, 0xc0518, 0xc0000, -1, 0xe051c, 0xe0000, -1, 0x100520,0x100000, -1, 0x11a5b4, 0x120000, -1, 0x12e7c4, 0x140000, -1, 0x1471f6, 0x160000, -1, 0x1640c4, 0x180000, -1, 0x1806ca, 0x1a0000, -1, 0x199df4, 0x1c0000, -1, 0x1b5d0a, 0x1e0000, 0xffffffff, 0xffffffff } }, - { "hmgeo", 0, 0x38510, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, - { "gwing2", 0, -1, { -1, 0x85ddc0, 0, 0xd567, 0, 0x10000, 0xe329, 0, 0x30000, 0xc112, 0, 0x50000, // 0xb25d0, uses compression - 0xabcd, 0, 0x70000, 0xef01, 0, 0x90000, 0x1234, 0, 0xb0000, 0x5678, 0, 0xd0000, - 0x5555, 0, 0xf0000, 0x6666, 0, 0x110000, 0xa901, 0, 0x130000, 0xa802, 0, 0x150000, - 0x3232, 0, 0x170000, 0x8989, 0, 0x190000, 0x6655, 0, 0x1a0000, - 0x3944, 0, 0x1c0000, 0x655a, 0, 0x1d0000, 0xf513, 0, 0x1e0000, - 0xb957, 0, 0, 0x37ca, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, - { "pjustic", 0, 0x725d0, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, - { "pstone2", 0, 0xb8dc0, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "ggx", 0, -1, { -1, 0x200000, 0x100000, -1, 0x210004, 0x110000, -1, 0x220008, 0x120000, -1, 0x228000, 0x130000, // 0x76110, uses compression 0x3af9, 0, 0x000000, 0x2288, 0, 0x010000, 0xe5e6, 0, 0x020000, 0xebb0, 0, 0x030000, 0x0228, 0, 0x040000, 0x872c, 0, 0x050000, 0xbba0, 0, 0x060000, 0x772f, 0, 0x070000, 0x2924, 0, 0x080000, 0x3222, 0, 0x090000, 0x7954, 0, 0x0a0000, 0x5acd, 0, 0x0b0000, 0xdd19, 0, 0x0c0000, 0x2428, 0, 0x0d0000, 0x3329, 0, 0x0e0000, 0x2142, 0, 0x0f0000, 0xffffffff, 0xffffffff, 0xffffffff } }, - { "18wheelr", 0, -1, { 0x1502, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, // 0x7cf54, uses compression { "sgtetris", 0, -1, { 0x1234, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, // 0x8ae51, uses compression +// { "virnbao", 0, 0x68b58, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, // note: "virnba" set doesn't have protection +// { "vs2_2k", 0, 0x88b08, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, }; // forward declaration for decrypt function static void stream_decrypt(UINT32 game_key, UINT32 sequence_key, UINT16 seed, UINT8* ciphertext, UINT8* plaintext, int length); +static UINT16 block_decrypt(UINT32 game_key, UINT16 sequence_key, UINT16 counter, UINT16 data); /*************************************************************************** INLINE FUNCTIONS @@ -404,31 +414,8 @@ READ64_DEVICE_HANDLER( naomibd_r ) // can we live-decrypt this game? if (v->dc_gamekey != -1) { - if (v->dc_is_m3) - { - ret = (UINT64)(v->dc_cart_ram[v->dc_readback+1] | (v->dc_cart_ram[v->dc_readback]<<8)); - v->dc_readback += 2; - } - else - { - UINT8 plain[2], crypt[2]; - - crypt[0] = ROM[(v->prot_offset*2)+v->dc_seed+1]; - crypt[1] = ROM[(v->prot_offset*2)+v->dc_seed]; - - // decrypt -// stream_decrypt(v->dc_gamekey, v->dc_seqkey, v->dc_seed>>1, &ROM[(v->prot_offset*2)+v->dc_seed], plain, 2); - stream_decrypt(v->dc_gamekey, v->dc_seqkey, v->dc_seed>>1, crypt, plain, 2); - - ret = (UINT64)(plain[0] | (plain[1]<<8)); - - #if NAOMIBD_PRINTF_PROTECTION - printf("M2 decrypt: gamekey %x seqkey %x offset %x seed %x src %02x %02x = %02x %02x\n", v->dc_gamekey, v->dc_seqkey, v->prot_offset*2, v->dc_seed>>1, ROM[(v->prot_offset*2)+v->dc_seed], ROM[(v->prot_offset*2)+v->dc_seed+1], plain[0], plain[1]); - #endif - - // bump readback pointer - v->dc_seed += 2; - } + ret = (UINT64)(v->dc_cart_ram[v->dc_readback+1] | (v->dc_cart_ram[v->dc_readback]<<8)); + v->dc_readback += 2; } else { @@ -694,34 +681,38 @@ WRITE64_DEVICE_HANDLER( naomibd_w ) // if dc_gamekey isn't -1, we can live-decrypt this one if (v->dc_gamekey != -1) { + UINT8 temp_ram[128*1024]; + UINT8 *ROM = (UINT8 *)v->memory; + v->dc_seed = 0; - v->dc_is_m3 = 0; v->dc_readback = 0; v->dc_seqkey = v->prot_key; - if (v->prot_offset == 0x2000000/2) // M3 readback, must decrypt now + #if NAOMIBD_PRINTF_PROTECTION + printf("M2/M3 decrypt: gamekey %x seqkey %x seed %x length %x\n", v->dc_gamekey, v->dc_seqkey, v->dc_seed, v->dc_m3_ptr); + #endif + + // M2: just decrypt up to the size limit since we don't know the size in advance + if (v->prot_offset != 0x2000000/2) + { + // decrypt to temp buffer + stream_decrypt(v->dc_gamekey, v->dc_seqkey, v->prot_offset&0xffff, &ROM[v->prot_offset*2], temp_ram, 128*1024); + } + else { - UINT8 temp_ram[128*1024]; - - #if NAOMIBD_PRINTF_PROTECTION - printf("M3 decrypt: gamekey %x seqkey %x seed %x length %x\n", v->dc_gamekey, v->dc_seqkey, v->dc_seed, v->dc_m3_ptr); - #endif - // decrypt cart ram to temp buffer stream_decrypt(v->dc_gamekey, v->dc_seqkey, v->dc_seed, v->dc_cart_ram, temp_ram, v->dc_m3_ptr); - - #if NAOMIBD_PRINTF_PROTECTION - printf("result: %02x %02x %02x %02x %02x %02x %02x %02x\n", - temp_ram[0], temp_ram[1], temp_ram[2], temp_ram[3], - temp_ram[4], temp_ram[5], temp_ram[6], temp_ram[7]); - #endif - - // copy results to cart ram for readback - memcpy(v->dc_cart_ram, temp_ram, 128*1024); - - v->dc_is_m3 = 1; } + #if NAOMIBD_PRINTF_PROTECTION + printf("result: %02x %02x %02x %02x %02x %02x %02x %02x\n", + temp_ram[0], temp_ram[1], temp_ram[2], temp_ram[3], + temp_ram[4], temp_ram[5], temp_ram[6], temp_ram[7]); + #endif + + // copy results to cart ram for readback + memcpy(v->dc_cart_ram, temp_ram, 128*1024); + v->dc_m3_ptr = 0; v->prot_sum = 0; } @@ -1049,7 +1040,7 @@ static void load_rom_gdrom(running_machine* machine, naomibd_state *v) /*************************************************************************** DECRYPTION EMULATION -By convention, we label the tree known cart protection methods this way (using Deunan Knute's wording): +By convention, we label the three known cart protection methods this way (using Deunan Knute's wording): M1: DMA read of protected ROM area M2: special read of ROM area which supplies decryption key first M3: normal read followed by write to cart's decryption buffer (up to 64kB), followed by M2 but from buffer area