From 83bde098ff2bccc56535ecaea3e665797a7cd6da Mon Sep 17 00:00:00 2001 From: andreasnaive Date: Tue, 20 Jan 2015 23:30:53 +0100 Subject: Two new key bits for SEGA's 315-5881 encryption --- src/mame/machine/315-5881_crypt.c | 42 +++++++++++++++++++-------------------- src/mame/machine/315-5881_crypt.h | 6 ++++-- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/mame/machine/315-5881_crypt.c b/src/mame/machine/315-5881_crypt.c index 0d9ee7cfc60..6a21bb261b6 100644 --- a/src/mame/machine/315-5881_crypt.c +++ b/src/mame/machine/315-5881_crypt.c @@ -134,7 +134,7 @@ 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 (>=27 bits) and the sequence-key (16 bits) and output a middle result (16 bits) which will act as another key +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). @@ -470,20 +470,20 @@ const sega_315_5881_crypt_device::sbox sega_315_5881_crypt_device::fn2_sboxes[4] }, }; -const int sega_315_5881_crypt_device::fn1_game_key_scheduling[38][2] = { - {1,29}, {1,71}, {2,4}, {2,54}, {3,8}, {4,56}, {4,73}, {5,11}, - {6,51}, {7,92}, {8,89}, {9,9}, {9,10}, {9,39}, {9,41}, {9,58}, - {9,59}, {9,86}, {10,90}, {11,6}, {12,64}, {13,49}, {14,44}, {15,40}, - {16,69}, {17,15}, {18,23}, {18,43}, {19,82}, {20,81}, {21,32}, {22,5}, - {23,66}, {24,13}, {24,45}, {25,12}, {25,35}, {26,61}, +const int sega_315_5881_crypt_device::fn1_game_key_scheduling[FN1GK][2] = { + {1,29}, {1,71}, {2,4}, {2,54}, {3,8}, {4,56}, {4,73}, {5,11}, + {6,51}, {7,92}, {8,89}, {9,9}, {9,39}, {9,41}, {9,58}, {9,86}, + {10,90}, {11,6}, {12,64}, {13,49}, {14,44}, {15,40}, {16,69}, {17,15}, + {18,23}, {18,43}, {19,82}, {20,81}, {21,32}, {22,5}, {23,66}, {24,13}, + {24,45}, {25,12}, {25,35}, {26,61}, {27,10}, {27,59}, {28,25} }; -const int sega_315_5881_crypt_device::fn2_game_key_scheduling[34][2] = { - {0,0}, {1,3}, {2,11}, {3,20}, {4,22}, {5,23}, {6,29}, {7,38}, - {8,39}, {9,47}, {9,55}, {9,86}, {9,87}, {9,90}, {10,50}, {10,53}, - {11,57}, {12,59}, {13,61}, {13,64}, {14,63}, {15,67}, {16,72}, {17,83}, - {18,88}, {19,94}, {20,35}, {21,17}, {22,6}, {22,11}, {23,85}, {24,16}, - {25,25}, {26,92} +const int sega_315_5881_crypt_device::fn2_game_key_scheduling[FN2GK][2] = { + {0,0}, {1,3}, {2,11}, {3,20}, {4,22}, {5,23}, {6,29}, {7,38}, + {8,39}, {9,55}, {9,86}, {9,87}, {9,90}, {10,50}, {10,53}, {11,57}, + {12,59}, {13,61}, {13,64}, {14,63}, {15,67}, {16,72}, {17,83}, {18,88}, + {19,94}, {20,35}, {21,17}, {22,6}, {22,11}, {23,85}, {24,16}, {25,25}, + {26,92}, {27,47}, {28,28} }; const int sega_315_5881_crypt_device::fn1_sequence_key_scheduling[20][2] = { @@ -539,7 +539,7 @@ UINT16 sega_315_5881_crypt_device::block_decrypt(UINT32 game_key, UINT16 sequenc memset(fn1_subkeys, 0, sizeof(UINT32) * 4); memset(fn2_subkeys, 0, sizeof(UINT32) * 4); - for (j = 0; j < 38; ++j) { + for (j = 0; j < FN1GK; ++j) { if (BIT(game_key, fn1_game_key_scheduling[j][0]) != 0) { aux = fn1_game_key_scheduling[j][1] % 24; aux2 = fn1_game_key_scheduling[j][1] / 24; @@ -547,7 +547,7 @@ UINT16 sega_315_5881_crypt_device::block_decrypt(UINT32 game_key, UINT16 sequenc } } - for (j = 0; j < 34; ++j) { + for (j = 0; j < FN2GK; ++j) { if (BIT(game_key, fn2_game_key_scheduling[j][0]) != 0) { aux = fn2_game_key_scheduling[j][1] % 24; aux2 = fn2_game_key_scheduling[j][1] / 24; @@ -587,13 +587,13 @@ UINT16 sega_315_5881_crypt_device::block_decrypt(UINT32 game_key, UINT16 sequenc A = (aux & 0xff) ^ feistel_function(B, fn1_sboxes[0], fn1_subkeys[0]); // 2nd round - B = B ^ feistel_function(A, fn1_sboxes[1], fn1_subkeys[1]); + B ^= feistel_function(A, fn1_sboxes[1], fn1_subkeys[1]); // 3rd round - A = A ^ feistel_function(B, fn1_sboxes[2], fn1_subkeys[2]); + A ^= feistel_function(B, fn1_sboxes[2], fn1_subkeys[2]); // 4th round - B = B ^ feistel_function(A, fn1_sboxes[3], fn1_subkeys[3]); + B ^= feistel_function(A, fn1_sboxes[3], fn1_subkeys[3]); middle_result = (B << 8) | A; @@ -617,13 +617,13 @@ UINT16 sega_315_5881_crypt_device::block_decrypt(UINT32 game_key, UINT16 sequenc A = (aux & 0xff) ^ feistel_function(B, fn2_sboxes[0], fn2_subkeys[0]); // 2nd round - B = B ^ feistel_function(A, fn2_sboxes[1], fn2_subkeys[1]); + B ^= feistel_function(A, fn2_sboxes[1], fn2_subkeys[1]); // 3rd round - A = A ^ feistel_function(B, fn2_sboxes[2], fn2_subkeys[2]); + A ^= feistel_function(B, fn2_sboxes[2], fn2_subkeys[2]); // 4th round - B = B ^ feistel_function(A, fn2_sboxes[3], fn2_subkeys[3]); + B ^= feistel_function(A, fn2_sboxes[3], fn2_subkeys[3]); aux = (B << 8) | A; diff --git a/src/mame/machine/315-5881_crypt.h b/src/mame/machine/315-5881_crypt.h index 155bc27a13e..288af4eb2f3 100644 --- a/src/mame/machine/315-5881_crypt.h +++ b/src/mame/machine/315-5881_crypt.h @@ -66,8 +66,10 @@ private: static const sbox fn1_sboxes[4][4]; static const sbox fn2_sboxes[4][4]; - static const int fn1_game_key_scheduling[38][2]; - static const int fn2_game_key_scheduling[34][2]; + static const int FN1GK = 39; + static const int FN2GK = 35; + static const int fn1_game_key_scheduling[FN1GK][2]; + static const int fn2_game_key_scheduling[FN2GK][2]; static const int fn1_sequence_key_scheduling[20][2]; static const int fn2_sequence_key_scheduling[16]; static const int fn2_middle_result_scheduling[16]; -- cgit v1.2.3