Previous 199869 Revisions Next

r34509 Tuesday 20th January, 2015 at 16:53:09 UTC by David Haywood
some changes to the 315-5881 to allow basic multiple stream support, astrass needs this - we were ignoring a size value in the header, when the 'size' is reached the stream ends, and a new header needs to be read.

I need to review the changes w/regards the naomi code later (don't have the material to test here) also this will need looking at w/regards compressed streams, as they can be mixed.

the data decrypted from astrass is now a 100% match for the data that was extracted from the saturn version.
[src/mame/machine]315-5881_crypt.c 315-5881_crypt.h

trunk/src/mame/machine/315-5881_crypt.c
r243020r243021
529529UINT16 sega_315_5881_crypt_device::block_decrypt(UINT32 game_key, UINT16 sequence_key, UINT16 counter, UINT16 data)
530530{
531531   int j;
532   int aux,aux2;
533   int A,B;
532   int aux, aux2;
533   int A, B;
534534   int middle_result;
535535   UINT32 fn1_subkeys[4];
536536   UINT32 fn2_subkeys[4];
537537
538538   /* Game-key scheduling; this could be done just once per game at initialization time */
539   memset(fn1_subkeys,0,sizeof(UINT32)*4);
540   memset(fn2_subkeys,0,sizeof(UINT32)*4);
539   memset(fn1_subkeys, 0, sizeof(UINT32) * 4);
540   memset(fn2_subkeys, 0, sizeof(UINT32) * 4);
541541
542   for (j=0; j<38; ++j) {
543      if (BIT(game_key, fn1_game_key_scheduling[j][0])!=0) {
544         aux = fn1_game_key_scheduling[j][1]%24;
545         aux2 = fn1_game_key_scheduling[j][1]/24;
546         fn1_subkeys[aux2] ^= (1<<aux);
542   for (j = 0; j < 38; ++j) {
543      if (BIT(game_key, fn1_game_key_scheduling[j][0]) != 0) {
544         aux = fn1_game_key_scheduling[j][1] % 24;
545         aux2 = fn1_game_key_scheduling[j][1] / 24;
546         fn1_subkeys[aux2] ^= (1 << aux);
547547      }
548548   }
549549
550   for (j=0; j<34; ++j) {
551      if (BIT(game_key, fn2_game_key_scheduling[j][0])!=0) {
552         aux = fn2_game_key_scheduling[j][1]%24;
553         aux2 = fn2_game_key_scheduling[j][1]/24;
554         fn2_subkeys[aux2] ^= (1<<aux);
550   for (j = 0; j < 34; ++j) {
551      if (BIT(game_key, fn2_game_key_scheduling[j][0]) != 0) {
552         aux = fn2_game_key_scheduling[j][1] % 24;
553         aux2 = fn2_game_key_scheduling[j][1] / 24;
554         fn2_subkeys[aux2] ^= (1 << aux);
555555      }
556556   }
557557   /********************************************************/
558558
559559   /* Sequence-key scheduling; this could be done just once per decryption run */
560   for (j=0; j<20; ++j) {
561      if (BIT(sequence_key,fn1_sequence_key_scheduling[j][0])!=0) {
562         aux = fn1_sequence_key_scheduling[j][1]%24;
563         aux2 = fn1_sequence_key_scheduling[j][1]/24;
564         fn1_subkeys[aux2] ^= (1<<aux);
560   for (j = 0; j < 20; ++j) {
561      if (BIT(sequence_key, fn1_sequence_key_scheduling[j][0]) != 0) {
562         aux = fn1_sequence_key_scheduling[j][1] % 24;
563         aux2 = fn1_sequence_key_scheduling[j][1] / 24;
564         fn1_subkeys[aux2] ^= (1 << aux);
565565      }
566566   }
567567
568   for (j=0; j<16; ++j) {
569      if (BIT(sequence_key,j)!=0) {
570         aux = fn2_sequence_key_scheduling[j]%24;
571         aux2 = fn2_sequence_key_scheduling[j]/24;
572         fn2_subkeys[aux2] ^= (1<<aux);
568   for (j = 0; j < 16; ++j) {
569      if (BIT(sequence_key, j) != 0) {
570         aux = fn2_sequence_key_scheduling[j] % 24;
571         aux2 = fn2_sequence_key_scheduling[j] / 24;
572         fn2_subkeys[aux2] ^= (1 << aux);
573573      }
574574   }
575575
576576   // subkeys bits 10 & 41
577   fn2_subkeys[0] ^= (BIT(sequence_key,2)<<10);
578   fn2_subkeys[1] ^= (BIT(sequence_key,4)<<17);
577   fn2_subkeys[0] ^= (BIT(sequence_key, 2) << 10);
578   fn2_subkeys[1] ^= (BIT(sequence_key, 4) << 17);
579579   /**************************************************************/
580580
581581   // First Feistel Network
582582
583   aux = BITSWAP16(counter,5,12,14,13,9,3,6,4,    8,1,15,11,0,7,10,2);
583   aux = BITSWAP16(counter, 5, 12, 14, 13, 9, 3, 6, 4, 8, 1, 15, 11, 0, 7, 10, 2);
584584
585585   // 1st round
586586   B = aux >> 8;
587   A = (aux & 0xff) ^ feistel_function(B,fn1_sboxes[0],fn1_subkeys[0]);
587   A = (aux & 0xff) ^ feistel_function(B, fn1_sboxes[0], fn1_subkeys[0]);
588588
589589   // 2nd round
590   B = B ^ feistel_function(A,fn1_sboxes[1],fn1_subkeys[1]);
590   B = B ^ feistel_function(A, fn1_sboxes[1], fn1_subkeys[1]);
591591
592592   // 3rd round
593   A = A ^ feistel_function(B,fn1_sboxes[2],fn1_subkeys[2]);
593   A = A ^ feistel_function(B, fn1_sboxes[2], fn1_subkeys[2]);
594594
595595   // 4th round
596   B = B ^ feistel_function(A,fn1_sboxes[3],fn1_subkeys[3]);
596   B = B ^ feistel_function(A, fn1_sboxes[3], fn1_subkeys[3]);
597597
598   middle_result = (B<<8)|A;
598   middle_result = (B << 8) | A;
599599
600600
601601   /* Middle-result-key sheduling */
602   for (j=0; j<16; ++j) {
603      if (BIT(middle_result,j)!=0) {
604         aux = fn2_middle_result_scheduling[j]%24;
605         aux2 = fn2_middle_result_scheduling[j]/24;
606         fn2_subkeys[aux2] ^= (1<<aux);
602   for (j = 0; j < 16; ++j) {
603      if (BIT(middle_result, j) != 0) {
604         aux = fn2_middle_result_scheduling[j] % 24;
605         aux2 = fn2_middle_result_scheduling[j] / 24;
606         fn2_subkeys[aux2] ^= (1 << aux);
607607      }
608608   }
609609   /*********************/
610610
611611   // Second Feistel Network
612612
613   aux = BITSWAP16(data,14,3,8,12,13,7,15,4,    6,2,9,5,11,0,1,10);
613   aux = BITSWAP16(data, 14, 3, 8, 12, 13, 7, 15, 4, 6, 2, 9, 5, 11, 0, 1, 10);
614614
615615   // 1st round
616616   B = aux >> 8;
617   A = (aux & 0xff) ^ feistel_function(B,fn2_sboxes[0],fn2_subkeys[0]);
617   A = (aux & 0xff) ^ feistel_function(B, fn2_sboxes[0], fn2_subkeys[0]);
618618
619619   // 2nd round
620   B = B ^ feistel_function(A,fn2_sboxes[1],fn2_subkeys[1]);
620   B = B ^ feistel_function(A, fn2_sboxes[1], fn2_subkeys[1]);
621621
622622   // 3rd round
623   A = A ^ feistel_function(B,fn2_sboxes[2],fn2_subkeys[2]);
623   A = A ^ feistel_function(B, fn2_sboxes[2], fn2_subkeys[2]);
624624
625625   // 4th round
626   B = B ^ feistel_function(A,fn2_sboxes[3],fn2_subkeys[3]);
626   B = B ^ feistel_function(A, fn2_sboxes[3], fn2_subkeys[3]);
627627
628   aux = (B<<8)|A;
628   aux = (B << 8) | A;
629629
630   aux = BITSWAP16(aux,15,7,6,14,13,12,5,4,    3,2,11,10,9,1,0,8);
630   aux = BITSWAP16(aux, 15, 7, 6, 14, 13, 12, 5, 4, 3, 2, 11, 10, 9, 1, 0, 8);
631631
632632   return aux;
633633}
634634
635
635636UINT16 sega_315_5881_crypt_device::get_decrypted_16()
636637{
637638   UINT16 enc;
r243020r243021
643644   dec_hist = dec;
644645
645646   prot_cur_address ++;
647
646648   return res;
647649}
648650
651
649652void sega_315_5881_crypt_device::enc_start()
650653{
654   dec_hist = 0; // seems to be needed by astrass at least otherwise any call after the first one will be influenced by the one before it.
655   block_pos = 0;
651656   buffer_pos = BUFFER_SIZE;
652657   dec_header = get_decrypted_16() << 16;
653658   dec_header |= get_decrypted_16();
654659
660   // the lower header bits are 2 values that multiply together to get the current stream length
661   // in astrass the first block is 0xffff (for a 0x10000 block) followed by 0x3f3f (for a 0x1000 block)
662   // etc. after each block a new header must be read, it looks like compressed and uncompressed blocks
663   // can be mixed like this, I don't know if the length is src length of decompressed length.
664   int blockx = ((dec_header & 0x00ff) >> 0) + 1;
665   int blocky = ((dec_header & 0xff00) >> 8) + 1;
666   block_size = blockx * blocky;
667
655668   if(dec_header & FLAG_COMPRESSED) {
656669      line_buffer_size = dec_header & FLAG_LINE_SIZE_512 ? 512 : 256;
657670      line_buffer_pos = line_buffer_size;
658671      buffer_bit = 7;
659672   }
673
674//   printf("header %08x\n", dec_header);
660675   enc_ready = true;
661676}
662677
r243020r243021
667682      UINT16 val = get_decrypted_16();
668683      buffer[i] = val;
669684      buffer[i+1] = val >> 8;
685      block_pos+=2;
686      if (block_pos == block_size)
687      {
688         // if we reach the size specified we need to read a new header
689         // todo: how should this work with compressed blocks??
690
691         enc_start();
692      }
670693   }
671694   buffer_pos = 0;
672695}
trunk/src/mame/machine/315-5881_crypt.h
r243020r243021
4040private:
4141
4242   enum {
43      BUFFER_SIZE = 32768, LINE_SIZE = 512,
43      BUFFER_SIZE = 32768*8, LINE_SIZE = 512*8,
4444      FLAG_COMPRESSED = 0x10000, FLAG_LINE_SIZE_512 = 0x20000
4545   };
4646
r243020r243021
5454   bool enc_ready;
5555
5656   int buffer_pos, line_buffer_pos, line_buffer_size, buffer_bit;
57   int block_size;
58   int block_pos;
5759
5860   struct sbox {
5961      UINT8 table[64];


Previous 199869 Revisions Next


© 1997-2024 The MAME Team