summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/machine/naomim4.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/machine/naomim4.c')
-rw-r--r--src/mame/machine/naomim4.c34
1 files changed, 19 insertions, 15 deletions
diff --git a/src/mame/machine/naomim4.c b/src/mame/machine/naomim4.c
index effe3a4c55c..e7f29c01759 100644
--- a/src/mame/machine/naomim4.c
+++ b/src/mame/machine/naomim4.c
@@ -16,17 +16,16 @@
// phase is indeed a nibble-based linear combination.
// With that block cipher, a stream cipher is constructed by feeding the output result of the 1st round
// of a certain 16-bits block as a whitening value for the next block. The cart dependent data used by
-// the algorithm is comprised by a 16-bits "key" and a 16-bits IV (initialization vector) --though they
-// will be merged in a only 32-bits number in the code--. The hardware auto-reset the feed value
+// the algorithm is a 32-bits key stored in the PIC16C621A. The hardware auto-reset the feed value
// to the cart-based IV every 16 blocks (32 bytes); that reset is not address-based, but index-based.
const device_type NAOMI_M4_BOARD = &device_creator<naomi_m4_board>;
const UINT8 naomi_m4_board::k_sboxes[4][16] = {
- {13,14,1,11,7,9,10,0,15,6,4,5,8,2,12,3},
- {12,3,14,6,7,15,2,13,1,4,11,0,9,10,8,5},
- {6,12,0,10,1,5,14,9,7,2,15,13,4,11,3,8},
- {9,12,8,7,10,4,0,15,1,11,14,2,13,5,6,3}
+ {9,8,2,11,1,14,5,15,12,6,0,3,7,13,10,4},
+ {2,10,0,15,14,1,11,3,7,12,13,8,4,9,5,6},
+ {4,11,3,8,7,2,15,13,1,5,14,9,6,12,0,10},
+ {1,13,8,2,0,5,6,14,4,11,15,10,12,3,7,9}
};
// from S29GL512N datasheet
@@ -67,8 +66,8 @@ void naomi_m4_board::device_start()
key = tempkey & 0xffff;
#else
const UINT8 *key_data = memregion(key_tag)->base();
- key = (key_data[2] << 8) | key_data[3];
- iv = (key_data[0] << 8) | key_data[1];
+ subkey1 = (key_data[17] << 8) | key_data[16];
+ subkey2 = (key_data[19] << 8) | key_data[18];
#endif
buffer = auto_alloc_array(machine(), UINT8, BUFFER_SIZE);
enc_init();
@@ -117,7 +116,7 @@ void naomi_m4_board::device_reset()
encryption = false;
cfi_mode = false;
counter = 0;
- cur_iv = 0;
+ iv = 0;
}
void naomi_m4_board::board_setup_address(UINT32 address, bool is_dma)
@@ -176,19 +175,24 @@ void naomi_m4_board::board_advance(UINT32 size)
void naomi_m4_board::enc_reset()
{
buffer_actual_size = 0;
- cur_iv = iv;
+ iv = 0;
counter = 0;
}
+UINT16 naomi_m4_board::decrypt_one_round(UINT16 word, UINT16 subkey)
+{
+ return one_round[word ^ subkey] ^ subkey ;
+}
+
void naomi_m4_board::enc_fill()
{
const UINT8 *base = m_region->base() + rom_cur_address;
while(buffer_actual_size < BUFFER_SIZE) {
UINT16 enc = base[0] | (base[1] << 8);
- UINT16 output_whitening = key ^ cur_iv;
- cur_iv = one_round[enc ^ cur_iv];
- UINT16 dec = one_round[key ^ cur_iv] ^ output_whitening;
-
+ UINT16 dec = iv;
+ iv = decrypt_one_round(enc ^ iv, subkey1);
+ dec ^= decrypt_one_round(iv, subkey2);
+
buffer[buffer_actual_size++] = dec;
buffer[buffer_actual_size++] = dec >> 8;
@@ -198,7 +202,7 @@ void naomi_m4_board::enc_fill()
counter++;
if(counter == 16) {
counter = 0;
- cur_iv = iv;
+ iv = 0;
}
}
}