summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author andreasnaive <andreasnaive@gmail.com>2015-01-23 20:39:57 +0100
committer andreasnaive <andreasnaive@gmail.com>2015-01-23 20:40:37 +0100
commit33dc76bf9914ca268f45b5455ca316f9a789e6be (patch)
treef00ba6f3726966d1b3697ac04427047962442591
parentea0ec6567b6eaa0e27311c66d9e8128a15b1d8e1 (diff)
Partial reverse enginnering of the use of security PIC labels within 315-5881 keys [Andreas Naive]
-rw-r--r--src/mame/drivers/naomi.c2
-rw-r--r--src/mame/machine/315-5881_crypt.c51
-rw-r--r--src/mame/machine/315-5881_helper.c14
3 files changed, 47 insertions, 20 deletions
diff --git a/src/mame/drivers/naomi.c b/src/mame/drivers/naomi.c
index a10d5c26e33..35b35a046a9 100644
--- a/src/mame/drivers/naomi.c
+++ b/src/mame/drivers/naomi.c
@@ -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
diff --git a/src/mame/machine/315-5881_crypt.c b/src/mame/machine/315-5881_crypt.c
index 6431303016b..db2b2311be9 100644
--- a/src/mame/machine/315-5881_crypt.c
+++ b/src/mame/machine/315-5881_crypt.c
@@ -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] = {
diff --git a/src/mame/machine/315-5881_helper.c b/src/mame/machine/315-5881_helper.c
index 858dd71d06c..6291d788f3c 100644
--- a/src/mame/machine/315-5881_helper.c
+++ b/src/mame/machine/315-5881_helper.c
@@ -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