mirror of
https://github.com/holub/mame
synced 2025-04-25 17:56:43 +03:00
Partial reverse enginnering of the use of security PIC labels within 315-5881 keys [Andreas Naive]
This commit is contained in:
parent
ea0ec6567b
commit
33dc76bf99
@ -328,7 +328,7 @@ House of the Dead 2 (original) 834-13636 21385 20 (64Mb)
|
||||
House of the Dead 2 834-13636-01 21585 20 (64Mb) not present 315-6213 not present
|
||||
Idol Janshi Suchie-Pai 3 841-0002C 21979 14 (64Mb) ? 315-6213 317-5047-JPN requires mahjong panel
|
||||
Jambo! Safari (Rev A) 840-0013C 22826A 8 (64Mb) ? 315-6213 317-0264-COM
|
||||
Mars TV 840-0025C 22993 15 (64Mb) present 315-6213 317-0074-JPN
|
||||
Mars TV 840-0025C 22993 15 (64Mb) present 315-6213 317-0274-JPN
|
||||
OutTrigger 840-0017C 22163 19 (64Mb) ? 315-6213 317-0266-COM requires regular 837-13551 and 837-13938 rotary JVS boards, and special panel
|
||||
Power Stone 841-0001C 21597 8 (64Mb) present 315-6213 317-5046-COM joystick + 3 buttons
|
||||
Power Stone 2 841-0008C 23127 9 (64Mb) present 315-6213 317-5054-COM joystick + 3 buttons
|
||||
|
@ -130,8 +130,10 @@ Notes below refer to M2 & M3.
|
||||
|
||||
The encryption is done by a stream cipher operating in counter mode, which use a 16-bits internal block cipher.
|
||||
|
||||
There are 2 "control bits" at the start of the decrypted stream which control the mode of operation: bit #1 set to 1 means
|
||||
that the stream needs to be decompressed after being decrypted. More on this later.
|
||||
Every stream can be composed by several substreams; there are 18 header bits at the start of every substream, with
|
||||
a 1+9+8 format; the highest bit control the mode of operation: set to 1 means that the substream needs to be decompressed
|
||||
after being decrypted. The other two blocks (A||B) encode the length of the substream, as (A+1)*(B+1). When a
|
||||
substream end, the header of the next one, if existing, follows inmediatly.
|
||||
|
||||
The next 16-bits are part of the header (they don't belong to the plaintext), but his meaning is unclear. It has been
|
||||
conjectured that it could stablish when to "reset" the process and start processing a new stream (based on some tests
|
||||
@ -144,22 +146,16 @@ internal block-cipher. So, at a given step, the internal block cipher will outpu
|
||||
given plaintext word, and the remaining 2 to the next plaintext word.
|
||||
|
||||
The underlying block cipher consists of two 4-round Feistel Networks (FN): the first one takes the counter (16 bits),
|
||||
the game-key (>=29 bits) and the sequence-key (16 bits) and output a middle result (16 bits) which will act as another key
|
||||
for the second one. The second FN will take the encrypted word (16 bits), the game-key, the sequence-key and the result
|
||||
from the first FN and will output the decrypted word (16 bits).
|
||||
the game-key (>=29 bits; probably 64) and the sequence-key (16 bits) and output a middle result (16 bits) which will act
|
||||
as another key for the second one. The second FN will take the encrypted word (16 bits), the game-key, the sequence-key
|
||||
and the result from the first FN and will output the decrypted word (16 bits).
|
||||
|
||||
Each round of the Feistel Networks use four substitution sboxes, each having 6 inputs and 2 outputs. The input is the
|
||||
XOR of at most one bit from the previous round and at most one bit from the different keys.
|
||||
|
||||
The underlying block cipher has the same structure than the one used by the CPS-2 (Capcom Play System 2) and,
|
||||
indeed, some of the used sboxes are exactly the same and appear in the same FN/round in both systems (this is not evident,
|
||||
as you need to apply a bitswapping and some XORs to the input & output of the sboxes to get the same values due). However,
|
||||
the key scheduling used by this implementation is much weaker than the CPS-2's one. Many s-boxes inputs aren't XORed with any
|
||||
key bit.
|
||||
|
||||
Due to the small key-length, no sophisticated attacks are needed to recover the keys; a brute-force attack knowing just
|
||||
some (encrypted word-decrypted word) pairs suffice. However, due to the weak key scheduling, it should be noted that some
|
||||
related keys can produce the same output bytes for some (short) input sequences.
|
||||
as you need to apply a bitswapping and some XORs to the input & output of the sboxes to get the same values due).
|
||||
|
||||
Note that this implementation considers that the counter initialization for ram decryption is 0 simply because the ram is
|
||||
mapped to multiples of 128K.
|
||||
@ -173,6 +169,37 @@ It can be observed that a couple of sboxes have incomplete tables (a 255 value i
|
||||
as of january/2015 show small randomness and big correlations, making possible that some unseen bits could make the
|
||||
decryption need those incomplete parts.
|
||||
|
||||
SEGA apparently used his security part label (317-xxxx-yyy) as part of the key; the mapping of the current keys to the chip label
|
||||
is given by the following function:
|
||||
|
||||
void key2label(uint32_t key)
|
||||
{
|
||||
int bcd0 = ((BIT(key,17)<<3)|(BIT(key,7)<<2)|(BIT(key,14)<<1)|BIT(key,19))^9;
|
||||
int bcd1 = ((BIT(key,20)<<3)|(BIT(key,1)<<2)|(BIT(key,4)<<1)|BIT(key,13))^5;
|
||||
int bcd2 = (BIT(key,9)<<1)|BIT(key,22);
|
||||
int bcd3 = ((BIT(key,9)<<2)|BIT(key,9))^5;
|
||||
|
||||
char chiplabel[13];
|
||||
sprintf(chiplabel, "317-%d%d%d%d-%s", bcd3, bcd2, bcd1, bcd0, (BIT(key,5)?"JPN":"COM"));
|
||||
|
||||
printf("%s", chiplabel);
|
||||
}
|
||||
|
||||
Given the use of the BCD-encoded security module labels, it's expected that at least other 6 additional bits be present in the
|
||||
real keys but undetected in the current implementation (due to them being set to fixed values on all the known 315-5881 chip labels).
|
||||
That would rise the bit count at least to 35.
|
||||
|
||||
Other key bits not directly related to the 315-5881 label still show low entropies, making possible that
|
||||
they be derived from other non-random sources.
|
||||
|
||||
In the second Feistel Network, every key bit seem to be used at most once (the various uses of current bit #9 are fictitious, as
|
||||
that bit really represent various bits in the real key; see comments on the use of the labels above). Given that, it seems probable
|
||||
that the real key is 64 bits long, exactly as in the related CPS-2 scheme, and the designers tried to cover all 96 input bits with
|
||||
the bits provening from the game key, the sequence key and the result from the first feistel network (64+16+16=96). In the first
|
||||
Feistel Network, as only 80 bits are available, some bits would be used twice (as can be partially seen in the current implementation).
|
||||
The fact that only 29 bits out of the expected 64 have been observed till now would be due to the generation of the key by composing
|
||||
low-entropy sources.
|
||||
|
||||
****************************************************************************************/
|
||||
|
||||
const sega_315_5881_crypt_device::sbox sega_315_5881_crypt_device::fn1_sboxes[4][4] = {
|
||||
|
@ -39,12 +39,6 @@ static const struct game_keys keys_table[] =
|
||||
{ "elandore", 0x05226d41 }, // 1998 317-5043-COM ST-V
|
||||
{ "ffreveng", 0x0524ac01 }, // 1998 317-5049-COM ST-V
|
||||
|
||||
{ "gundmct", 0x000e8010 }, // 841-0017 2001 ??? Naomi
|
||||
{ "puyoda", 0x000acd40 }, // 841-0006 1999 ??? Naomi
|
||||
{ "smlg99", 0x08048a01 }, // 840-0012 1999 ??? Naomi
|
||||
{ "vf4cart", 0x0eef2f96 }, // 840-0080 2002 ??? Naomi 2
|
||||
{ "vonot", 0x08010715 }, // 840-0028 2000 ??? Naomi
|
||||
{ "marstv", 0x080b8ef5 }, // 840-0025 1999 317-0074-JPN Naomi
|
||||
{ "dybbnao", 0x080e6ae1 }, // 840-0001 1998 317-0246-JPN Naomi
|
||||
{ "crzytaxi", 0x080d2f45 }, // 840-0002 1999 317-0248-COM Naomi
|
||||
{ "zombrvn", 0x08012b41 }, // 840-0003 1999 317-0249-COM Naomi
|
||||
@ -56,6 +50,7 @@ static const struct game_keys keys_table[] =
|
||||
{ "tduno", 0x08028ea5 }, // 840-0008 1999 317-0255-JPN Naomi
|
||||
{ "toyfight", 0x0802ca85 }, // 840-0011 1999 317-0257-COM Naomi
|
||||
{ "vs2_2k", 0x08088b08 }, // 840-0010 1999 317-0258-COM Naomi
|
||||
{ "smlg99", 0x08048a01 }, // 840-0012 1999 317-0259-COM Naomi
|
||||
{ "derbyoc", 0x080fee35 }, // 840-0016 1999 317-0262-JPN Naomi
|
||||
{ "vtennis", 0x0803eb15 }, // 840-0015 1999 317-0263-COM Naomi
|
||||
{ "jambo", 0x080fab95 }, // 840-0013 1999 317-0264-COM Naomi
|
||||
@ -72,6 +67,8 @@ static const struct game_keys keys_table[] =
|
||||
{ "18wheelr", 0x0807cf54 }, // 840-0023 2000 317-0273-COM Naomi
|
||||
{ "18wheels", 0x0807cf54 }, // 840-0036 2000 317-0273-COM Naomi
|
||||
{ "18wheelu", 0x0807cf54 }, // 840-0037 2000 317-0273-COM Naomi
|
||||
{ "marstv", 0x080b8ef5 }, // 840-0025 1999 317-0274-JPN Naomi
|
||||
{ "vonot", 0x08010715 }, // 840-0028 2000 317-0279-COM Naomi
|
||||
{ "sstrkfgt", 0x08132303 }, // 840-0035 2000 317-0281-COM Naomi
|
||||
{ "sstrkfgta", 0x08132303 }, // 840-0035 2000 317-0281-COM Naomi
|
||||
{ "wwfroyal", 0x081627c3 }, // 840-0040 2000 317-0285-COM Naomi
|
||||
@ -91,6 +88,7 @@ static const struct game_keys keys_table[] =
|
||||
{ "clubkrtd", 0x0ce7d742 }, // 840-0062 2001 317-0313-COM Naomi 2
|
||||
{ "clubkrte", 0x0ce7d742 }, // 840-0062 2001 317-0313-COM Naomi 2
|
||||
{ "inunoos", 0x094bc3e3 }, // 840-0073 2001 317-0316-JPN Naomi
|
||||
{ "vf4cart", 0x0eef2f96 }, // 840-0080 2002 317-0324-COM Naomi 2
|
||||
{ "toukon4", 0x052e2901 }, // 25349801 2000 317-5040-COM Naomi
|
||||
{ "wldkicks", 0x052e2901 }, // 25209801 2000 317-5040-COM Naomi
|
||||
{ "wldkicksa", 0x052e2901 }, // 25209801 2000 317-5040-COM Naomi
|
||||
@ -101,6 +99,7 @@ static const struct game_keys keys_table[] =
|
||||
{ "doa2m", 0x0008ad01 }, // 841-0003 1999 317-5048-COM Naomi
|
||||
{ "shangril", -1 }, // 841-0004 1999 317-5050-JPN Naomi seems not used by game
|
||||
{ "spawn", 0x00078d01 }, // 841-0005 1999 317-5051-COM Naomi
|
||||
{ "puyoda", 0x000acd40 }, // 841-0006 1999 317-5052-COM Naomi
|
||||
{ "pstone2", 0x000b8dc0 }, // 841-0008 2000 317-5054-COM Naomi
|
||||
{ "capsnk", 0x00000000 }, // 841-0011 2000 317-5059-COM Naomi
|
||||
{ "capsnka", 0x00000000 }, // 841-0011 2000 317-5059-COM Naomi
|
||||
@ -114,6 +113,7 @@ static const struct game_keys keys_table[] =
|
||||
{ "ninjaslt1", 0x000ca510 }, // 25469801 2000 317-5068-COM Naomi
|
||||
{ "ninjaslt2", 0x000ca510 }, // 25469801 2000 317-5068-COM Naomi
|
||||
{ "ninjaslt4", 0x000ca510 }, // 25469801 2000 317-5068-COM Naomi
|
||||
{ "gundmct", 0x000e8010 }, // 841-0017 2001 317-5070-COM Naomi
|
||||
{ "hmgeo", 0x00038510 }, // HMG016007 2001 317-5071-COM Naomi
|
||||
{ "zerogu2", 0x0007c010 }, // 841-0020 2001 317-5073-COM Naomi
|
||||
{ "gunsur2", 0x000680d0 }, // 25709801 2001 317-5075-COM Naomi
|
||||
@ -135,7 +135,6 @@ static const struct game_keys keys_table[] =
|
||||
{ "pltkids", -1 }, // 1998 317-5044-COM Model 2
|
||||
{ "pltkidsa", -1 }, // 1998 317-5044-COM Model 2
|
||||
|
||||
{ "magtruck", 0x09266e45 }, // ???? ? Model 3
|
||||
{ "von2", 0x092a0e97 }, // ???? 317-0234-COM Model 3
|
||||
{ "von254g", 0x092a0e97 }, // ???? 317-0234-COM Model 3
|
||||
{ "fvipers2", -1 }, // ???? 317-0235-COM Model 3
|
||||
@ -148,6 +147,7 @@ static const struct game_keys keys_table[] =
|
||||
{ "swtrilgy", 0x11272a01 }, // ???? 317-0241-COM Model 3
|
||||
{ "swtrilgya", 0x11272a01 }, // ???? 317-0241-COM Model 3
|
||||
{ "oceanhun", 0x092b6a01 }, // ???? 317-0242-COM Model 3
|
||||
{ "magtruck", 0x09266e45 }, // ???? 317-0243-COM Model 3
|
||||
{ "lamachin", 0x092a2bc5 }, // ???? 317-0244-COM Model 3
|
||||
{ "vs299", 0x09222ac8 }, // ???? 317-0245-COM Model 3
|
||||
{ "vs2v991", 0x09222ac8 }, // ???? 317-0245-COM Model 3
|
||||
|
Loading…
Reference in New Issue
Block a user