trunk/src/mame/machine/315-5881_crypt.c
| r243078 | r243079 | |
| 130 | 130 | |
| 131 | 131 | The encryption is done by a stream cipher operating in counter mode, which use a 16-bits internal block cipher. |
| 132 | 132 | |
| 133 | | There are 2 "control bits" at the start of the decrypted stream which control the mode of operation: bit #1 set to 1 means |
| 134 | | that the stream needs to be decompressed after being decrypted. More on this later. |
| 133 | Every stream can be composed by several substreams; there are 18 header bits at the start of every substream, with |
| 134 | a 1+9+8 format; the highest bit control the mode of operation: set to 1 means that the substream needs to be decompressed |
| 135 | after being decrypted. The other two blocks (A||B) encode the length of the substream, as (A+1)*(B+1). When a |
| 136 | substream end, the header of the next one, if existing, follows inmediatly. |
| 135 | 137 | |
| 136 | 138 | The next 16-bits are part of the header (they don't belong to the plaintext), but his meaning is unclear. It has been |
| 137 | 139 | conjectured that it could stablish when to "reset" the process and start processing a new stream (based on some tests |
| r243078 | r243079 | |
| 144 | 146 | given plaintext word, and the remaining 2 to the next plaintext word. |
| 145 | 147 | |
| 146 | 148 | The underlying block cipher consists of two 4-round Feistel Networks (FN): the first one takes the counter (16 bits), |
| 147 | | the game-key (>=29 bits) and the sequence-key (16 bits) and output a middle result (16 bits) which will act as another key |
| 148 | | for the second one. The second FN will take the encrypted word (16 bits), the game-key, the sequence-key and the result |
| 149 | | from the first FN and will output the decrypted word (16 bits). |
| 149 | the game-key (>=29 bits; probably 64) and the sequence-key (16 bits) and output a middle result (16 bits) which will act |
| 150 | as another key for the second one. The second FN will take the encrypted word (16 bits), the game-key, the sequence-key |
| 151 | and the result from the first FN and will output the decrypted word (16 bits). |
| 150 | 152 | |
| 151 | 153 | Each round of the Feistel Networks use four substitution sboxes, each having 6 inputs and 2 outputs. The input is the |
| 152 | 154 | XOR of at most one bit from the previous round and at most one bit from the different keys. |
| 153 | 155 | |
| 154 | 156 | The underlying block cipher has the same structure than the one used by the CPS-2 (Capcom Play System 2) and, |
| 155 | 157 | indeed, some of the used sboxes are exactly the same and appear in the same FN/round in both systems (this is not evident, |
| 156 | | as you need to apply a bitswapping and some XORs to the input & output of the sboxes to get the same values due). However, |
| 157 | | 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 |
| 158 | | key bit. |
| 158 | as you need to apply a bitswapping and some XORs to the input & output of the sboxes to get the same values due). |
| 159 | 159 | |
| 160 | | Due to the small key-length, no sophisticated attacks are needed to recover the keys; a brute-force attack knowing just |
| 161 | | some (encrypted word-decrypted word) pairs suffice. However, due to the weak key scheduling, it should be noted that some |
| 162 | | related keys can produce the same output bytes for some (short) input sequences. |
| 163 | | |
| 164 | 160 | Note that this implementation considers that the counter initialization for ram decryption is 0 simply because the ram is |
| 165 | 161 | mapped to multiples of 128K. |
| 166 | 162 | |
| r243078 | r243079 | |
| 173 | 169 | as of january/2015 show small randomness and big correlations, making possible that some unseen bits could make the |
| 174 | 170 | decryption need those incomplete parts. |
| 175 | 171 | |
| 172 | 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 |
| 173 | is given by the following function: |
| 174 | |
| 175 | void key2label(uint32_t key) |
| 176 | { |
| 177 | int bcd0 = ((BIT(key,17)<<3)|(BIT(key,7)<<2)|(BIT(key,14)<<1)|BIT(key,19))^9; |
| 178 | int bcd1 = ((BIT(key,20)<<3)|(BIT(key,1)<<2)|(BIT(key,4)<<1)|BIT(key,13))^5; |
| 179 | int bcd2 = (BIT(key,9)<<1)|BIT(key,22); |
| 180 | int bcd3 = ((BIT(key,9)<<2)|BIT(key,9))^5; |
| 181 | |
| 182 | char chiplabel[13]; |
| 183 | sprintf(chiplabel, "317-%d%d%d%d-%s", bcd3, bcd2, bcd1, bcd0, (BIT(key,5)?"JPN":"COM")); |
| 184 | |
| 185 | printf("%s", chiplabel); |
| 186 | } |
| 187 | |
| 188 | Given the use of the BCD-encoded security module labels, it's expected that at least other 6 additional bits be present in the |
| 189 | real keys but undetected in the current implementation (due to them being set to fixed values on all the known 315-5881 chip labels). |
| 190 | That would rise the bit count at least to 35. |
| 191 | |
| 192 | Other key bits not directly related to the 315-5881 label still show low entropies, making possible that |
| 193 | they be derived from other non-random sources. |
| 194 | |
| 195 | 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 |
| 196 | that bit really represent various bits in the real key; see comments on the use of the labels above). Given that, it seems probable |
| 197 | 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 |
| 198 | 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 |
| 199 | Feistel Network, as only 80 bits are available, some bits would be used twice (as can be partially seen in the current implementation). |
| 200 | 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 |
| 201 | low-entropy sources. |
| 202 | |
| 176 | 203 | ****************************************************************************************/ |
| 177 | 204 | |
| 178 | 205 | const sega_315_5881_crypt_device::sbox sega_315_5881_crypt_device::fn1_sboxes[4][4] = { |
trunk/src/mame/machine/315-5881_helper.c
| r243078 | r243079 | |
| 39 | 39 | { "elandore", 0x05226d41 }, // 1998 317-5043-COM ST-V |
| 40 | 40 | { "ffreveng", 0x0524ac01 }, // 1998 317-5049-COM ST-V |
| 41 | 41 | |
| 42 | | { "gundmct", 0x000e8010 }, // 841-0017 2001 ??? Naomi |
| 43 | | { "puyoda", 0x000acd40 }, // 841-0006 1999 ??? Naomi |
| 44 | | { "smlg99", 0x08048a01 }, // 840-0012 1999 ??? Naomi |
| 45 | | { "vf4cart", 0x0eef2f96 }, // 840-0080 2002 ??? Naomi 2 |
| 46 | | { "vonot", 0x08010715 }, // 840-0028 2000 ??? Naomi |
| 47 | | { "marstv", 0x080b8ef5 }, // 840-0025 1999 317-0074-JPN Naomi |
| 48 | 42 | { "dybbnao", 0x080e6ae1 }, // 840-0001 1998 317-0246-JPN Naomi |
| 49 | 43 | { "crzytaxi", 0x080d2f45 }, // 840-0002 1999 317-0248-COM Naomi |
| 50 | 44 | { "zombrvn", 0x08012b41 }, // 840-0003 1999 317-0249-COM Naomi |
| r243078 | r243079 | |
| 56 | 50 | { "tduno", 0x08028ea5 }, // 840-0008 1999 317-0255-JPN Naomi |
| 57 | 51 | { "toyfight", 0x0802ca85 }, // 840-0011 1999 317-0257-COM Naomi |
| 58 | 52 | { "vs2_2k", 0x08088b08 }, // 840-0010 1999 317-0258-COM Naomi |
| 53 | { "smlg99", 0x08048a01 }, // 840-0012 1999 317-0259-COM Naomi |
| 59 | 54 | { "derbyoc", 0x080fee35 }, // 840-0016 1999 317-0262-JPN Naomi |
| 60 | 55 | { "vtennis", 0x0803eb15 }, // 840-0015 1999 317-0263-COM Naomi |
| 61 | 56 | { "jambo", 0x080fab95 }, // 840-0013 1999 317-0264-COM Naomi |
| r243078 | r243079 | |
| 72 | 67 | { "18wheelr", 0x0807cf54 }, // 840-0023 2000 317-0273-COM Naomi |
| 73 | 68 | { "18wheels", 0x0807cf54 }, // 840-0036 2000 317-0273-COM Naomi |
| 74 | 69 | { "18wheelu", 0x0807cf54 }, // 840-0037 2000 317-0273-COM Naomi |
| 70 | { "marstv", 0x080b8ef5 }, // 840-0025 1999 317-0274-JPN Naomi |
| 71 | { "vonot", 0x08010715 }, // 840-0028 2000 317-0279-COM Naomi |
| 75 | 72 | { "sstrkfgt", 0x08132303 }, // 840-0035 2000 317-0281-COM Naomi |
| 76 | 73 | { "sstrkfgta", 0x08132303 }, // 840-0035 2000 317-0281-COM Naomi |
| 77 | 74 | { "wwfroyal", 0x081627c3 }, // 840-0040 2000 317-0285-COM Naomi |
| r243078 | r243079 | |
| 91 | 88 | { "clubkrtd", 0x0ce7d742 }, // 840-0062 2001 317-0313-COM Naomi 2 |
| 92 | 89 | { "clubkrte", 0x0ce7d742 }, // 840-0062 2001 317-0313-COM Naomi 2 |
| 93 | 90 | { "inunoos", 0x094bc3e3 }, // 840-0073 2001 317-0316-JPN Naomi |
| 91 | { "vf4cart", 0x0eef2f96 }, // 840-0080 2002 317-0324-COM Naomi 2 |
| 94 | 92 | { "toukon4", 0x052e2901 }, // 25349801 2000 317-5040-COM Naomi |
| 95 | 93 | { "wldkicks", 0x052e2901 }, // 25209801 2000 317-5040-COM Naomi |
| 96 | 94 | { "wldkicksa", 0x052e2901 }, // 25209801 2000 317-5040-COM Naomi |
| r243078 | r243079 | |
| 101 | 99 | { "doa2m", 0x0008ad01 }, // 841-0003 1999 317-5048-COM Naomi |
| 102 | 100 | { "shangril", -1 }, // 841-0004 1999 317-5050-JPN Naomi seems not used by game |
| 103 | 101 | { "spawn", 0x00078d01 }, // 841-0005 1999 317-5051-COM Naomi |
| 102 | { "puyoda", 0x000acd40 }, // 841-0006 1999 317-5052-COM Naomi |
| 104 | 103 | { "pstone2", 0x000b8dc0 }, // 841-0008 2000 317-5054-COM Naomi |
| 105 | 104 | { "capsnk", 0x00000000 }, // 841-0011 2000 317-5059-COM Naomi |
| 106 | 105 | { "capsnka", 0x00000000 }, // 841-0011 2000 317-5059-COM Naomi |
| r243078 | r243079 | |
| 114 | 113 | { "ninjaslt1", 0x000ca510 }, // 25469801 2000 317-5068-COM Naomi |
| 115 | 114 | { "ninjaslt2", 0x000ca510 }, // 25469801 2000 317-5068-COM Naomi |
| 116 | 115 | { "ninjaslt4", 0x000ca510 }, // 25469801 2000 317-5068-COM Naomi |
| 116 | { "gundmct", 0x000e8010 }, // 841-0017 2001 317-5070-COM Naomi |
| 117 | 117 | { "hmgeo", 0x00038510 }, // HMG016007 2001 317-5071-COM Naomi |
| 118 | 118 | { "zerogu2", 0x0007c010 }, // 841-0020 2001 317-5073-COM Naomi |
| 119 | 119 | { "gunsur2", 0x000680d0 }, // 25709801 2001 317-5075-COM Naomi |
| r243078 | r243079 | |
| 135 | 135 | { "pltkids", -1 }, // 1998 317-5044-COM Model 2 |
| 136 | 136 | { "pltkidsa", -1 }, // 1998 317-5044-COM Model 2 |
| 137 | 137 | |
| 138 | | { "magtruck", 0x09266e45 }, // ???? ? Model 3 |
| 139 | 138 | { "von2", 0x092a0e97 }, // ???? 317-0234-COM Model 3 |
| 140 | 139 | { "von254g", 0x092a0e97 }, // ???? 317-0234-COM Model 3 |
| 141 | 140 | { "fvipers2", -1 }, // ???? 317-0235-COM Model 3 |
| r243078 | r243079 | |
| 148 | 147 | { "swtrilgy", 0x11272a01 }, // ???? 317-0241-COM Model 3 |
| 149 | 148 | { "swtrilgya", 0x11272a01 }, // ???? 317-0241-COM Model 3 |
| 150 | 149 | { "oceanhun", 0x092b6a01 }, // ???? 317-0242-COM Model 3 |
| 150 | { "magtruck", 0x09266e45 }, // ???? 317-0243-COM Model 3 |
| 151 | 151 | { "lamachin", 0x092a2bc5 }, // ???? 317-0244-COM Model 3 |
| 152 | 152 | { "vs299", 0x09222ac8 }, // ???? 317-0245-COM Model 3 |
| 153 | 153 | { "vs2v991", 0x09222ac8 }, // ???? 317-0245-COM Model 3 |