CIC stuff
This commit is contained in:
parent
fbcefccbb1
commit
b6cc40e290
6
cic/d411-seeds.txt
Normal file
6
cic/d411-seeds.txt
Normal file
@ -0,0 +1,6 @@
|
||||
key seed: b14f4b57fd61e98
|
||||
110101111101010
|
||||
|
||||
lck seed: _9a185f11e10dec
|
||||
_10101111010100
|
||||
|
||||
230
cic/d411.pseudo
Normal file
230
cic/d411.pseudo
Normal file
@ -0,0 +1,230 @@
|
||||
map:
|
||||
|
||||
RAM:0x01~0x0f Seed 1 (own key seed)?
|
||||
RAM:0x10 send/receive buffer?
|
||||
RAM:0x11 Stream ID received from LOCK
|
||||
RAM:0x12~0x1f Seed 2 (Stream ID part of lock seed)?
|
||||
|
||||
main:
|
||||
goto initstream;
|
||||
|
||||
mainloop:
|
||||
a=0x1;
|
||||
mainloop2:
|
||||
x=a;
|
||||
for(x=a; x<16; x++) {
|
||||
main_inner1:
|
||||
bm=0x0;
|
||||
call 34b(0x00+x) // prepare next stream bit (send)
|
||||
bm=0x1;
|
||||
call 34b(0x10+x) // prepare next stream bit (recv)
|
||||
call 131 // bm=1; bl=0; a=P0
|
||||
a=P0;
|
||||
if(P0.0) die; // WTF? P0.0 is an output!
|
||||
if(P0.1) die;
|
||||
|
||||
a=0x0;
|
||||
a<->RAM[0x10]; // load A with next output stream bit (nibble)
|
||||
P0=a; // LSB -> Key output
|
||||
nop; // wait
|
||||
a=P0; // read from lock
|
||||
P0=0; // clear output port
|
||||
RAM[0x10]=a; // store next input stream bit in RAM
|
||||
bl=3; a=P3 // P3.0, which is usually UNCONNECTED,
|
||||
// somehow determines how to deal with
|
||||
// the input stream. This is SNES CIC specific.
|
||||
// NOTE: For commonly used key operation / pin mapping we must assume
|
||||
// that P3.0 is HIGH (1). (otherwise the key would die immediately)
|
||||
bl=0
|
||||
if(P3.0){
|
||||
if(RAM[0x10].1) { // input stream bit set?
|
||||
call 159 // bm=0; bl=0; a=P0 // switch "bank"
|
||||
if(RAM[0x00].0) { // matches calculated bit?
|
||||
goto 13d // then go on
|
||||
} else goto 157 // DIE // else gtfo
|
||||
} else goto input_stream_bit_clear // input stream bit clear, check
|
||||
} else goto 175
|
||||
|
||||
input_stream_bit_clear: // input stream bit cleared
|
||||
call 159 // bm=0; bl=0; a=P0 // switch "bank"
|
||||
if(RAM[0x00].0) { // calculated bit doesn't match?
|
||||
goto 157 // DIE // then die
|
||||
} else goto 17a // nop; goto 13d // else go on
|
||||
|
||||
175:
|
||||
if(RAM[0x10].0) { // this is essentially the same
|
||||
call 159 // bm=0; bl=0; a=P0 // as above but
|
||||
if(RAM[0x00].1) { // input stream bit is set in
|
||||
goto 13d; // RAM[0x10].0 instead of .1 and
|
||||
} else goto 157 // DIE // calculated from RAM[0x00].1
|
||||
} else { // instead of .0, if P3.0 is 0.
|
||||
call 159 // bm=0; bl=0; a=P0
|
||||
if(RAM[0x00].1) {
|
||||
goto 157 // DIE
|
||||
} else goto 17a // nop; goto 13d
|
||||
}
|
||||
|
||||
13d: // continue
|
||||
a=x;
|
||||
a++; // loop to next of 15 stream
|
||||
if(!overflow) { // bits, afterwards:
|
||||
x=a;
|
||||
goto main_inner1;
|
||||
}
|
||||
} // for x=1 to 15
|
||||
(x=0) //
|
||||
call 04a // set Resets (dummy for key mode) // output reset levels
|
||||
call 370 // "MANGLE BOTH" // calculate new seeds
|
||||
call 370 // "MANGLE BOTH" // for both sides
|
||||
call 370 // "MANGLE BOTH" // (lock+key) to exchange
|
||||
// this is "SNES security": MANGLE is called THREE TIMES!
|
||||
// as opposed to only once on the NES CICs.
|
||||
a=RAM[0x13];
|
||||
RAM[0x13]=RAM[0x17];
|
||||
// set P3.0 to LSB of RAM[0x13]
|
||||
P3 = (P3 & 0xe) | (RAM[0x13] & 0x1);
|
||||
if(a.0==1) {
|
||||
goto mainloop (seed offset=0x1)
|
||||
} else goto mainloop2 (seed offset=a)
|
||||
|
||||
|
||||
04a: // "RUN HOST"
|
||||
call 37a // "skip if lock"
|
||||
a=0x0;
|
||||
P1=a;
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
P1=a;
|
||||
return
|
||||
|
||||
mangle_both:
|
||||
call mangle(bm=0);
|
||||
goto mangle(bm=1);
|
||||
|
||||
mangle:
|
||||
bl=0xf;
|
||||
a=RAM[bm:0xf];
|
||||
x=a;
|
||||
carry=1;
|
||||
bl=0x1;
|
||||
a+=RAM[bm:0x1]+1;
|
||||
RAM[bm:0x1]=a;
|
||||
==> RAM[bm:0x1]+=RAM[bm:0xf]+1;
|
||||
a=RAM[bm:0x1]; bl++;
|
||||
a+=RAM[bm:0x2]+1;
|
||||
a=~a;
|
||||
RAM[bm:0x2]=a; bl++;
|
||||
a+=RAM[bm:0x3]+1;
|
||||
if(!overflow) {
|
||||
RAM[bm:0x3]=a; bl++;
|
||||
}
|
||||
a+=RAM[bm:0x4];
|
||||
RAM[bm:0x4]=a;
|
||||
a=RAM[bm:0x4]; bl++;
|
||||
carry=0;
|
||||
a+=RAM[bm:0x5]+0;
|
||||
RAM[bm:0x5]=a; bl++;
|
||||
a+=8;
|
||||
a+=RAM[bm:0x6]+0;
|
||||
RAM[bm:0x6]=a; bl++;
|
||||
mangle_inner1:
|
||||
a++;
|
||||
nop
|
||||
a+=RAM[bm:0x7..0xf]+0;
|
||||
RAM[bm:0x7..0xf]=a;
|
||||
a=RAM[bm:0x7..0xf]; bl++;
|
||||
if(!overflow) goto mangle_inner1
|
||||
a<->x;
|
||||
a+=0xf;
|
||||
if(!overflow) return;
|
||||
goto mangle
|
||||
|
||||
131:
|
||||
bm=0x0;
|
||||
call 37a
|
||||
(if(!lock)bm=1);
|
||||
return;
|
||||
|
||||
37a:
|
||||
|
||||
34b: input x='bl'
|
||||
// take a nibble out of the seed (indexed by bm:x)
|
||||
// and set [bm:0], i.e. RAM[0x00] or RAM[0x10] like this:
|
||||
// if(seednibble&1) {
|
||||
// result=0b0000;
|
||||
// } else {
|
||||
// if(P3.0) {
|
||||
// result=0b0101;
|
||||
// } else {
|
||||
// result=0b0010;
|
||||
// }
|
||||
// }
|
||||
bl=x;
|
||||
a=RAM[bm:x];
|
||||
RAM[bm:0] = RAM[bm:x].0 ? 0x7 : 0x0;
|
||||
|
||||
a=P3; // WTF is P3????
|
||||
bl=0;
|
||||
if (P3.0==1) {
|
||||
RAM[bm:0] &= 0b1101;
|
||||
} else {
|
||||
RAM[bm:0] &= 0b1010;
|
||||
}
|
||||
return
|
||||
|
||||
initstream:
|
||||
if(P0.3==0) {
|
||||
if(P0.3==0) {
|
||||
A=RAM[0x11]; RAM[0x11]=0xf
|
||||
input_stream_id_bit;
|
||||
if !(A.1) RAM[0x11]&=0b0111
|
||||
input_stream_id_bit;
|
||||
if !(A.1) RAM[0x11]&=0b1110
|
||||
input_stream_id_bit;
|
||||
if !(A.1) RAM[0x11]&=0b1101
|
||||
input_stream_id_bit;
|
||||
if !(A.1) RAM[0x11]&=0b1011
|
||||
nop
|
||||
|
||||
RAM[0x01]=0xb;
|
||||
RAM[0x02]=0x1;
|
||||
RAM[0x03]=0x4;
|
||||
RAM[0x04]=0xf;
|
||||
RAM[0x05]=0x4;
|
||||
RAM[0x06]=0xb; // 0x6????
|
||||
RAM[0x07]=0x5;
|
||||
RAM[0x08]=0x7; // 0x8????
|
||||
RAM[0x09]=0xf;
|
||||
RAM[0x0a]=0xd; // 0xa????
|
||||
RAM[0x0b]=0x6;
|
||||
RAM[0x0c]=0x1; // 0xc????
|
||||
RAM[0x0d]=0xe;
|
||||
RAM[0x0e]=0x9;
|
||||
RAM[0x0f]=0x8;
|
||||
|
||||
RAM[0x12]=0x9;
|
||||
RAM[0x13]=0xa;
|
||||
RAM[0x14]=0x1;
|
||||
RAM[0x15]=0x8;
|
||||
RAM[0x16]=0x5;
|
||||
RAM[0x17]=0xf; // 0x7????
|
||||
RAM[0x18]=0x1;
|
||||
RAM[0x19]=0x1; // 0x9????
|
||||
RAM[0x1a]=0xe;
|
||||
RAM[0x1b]=0x1; // 0xb????
|
||||
RAM[0x1c]=0x0;
|
||||
RAM[0x1d]=0xd;
|
||||
RAM[0x1e]=0xe;
|
||||
RAM[0x1f]=0xc;
|
||||
|
||||
mainloop;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
input_stream_id_bit:
|
||||
wait 6 cycles
|
||||
A=P0
|
||||
ret
|
||||
103
cic/mangle.c
Normal file
103
cic/mangle.c
Normal file
@ -0,0 +1,103 @@
|
||||
#include <stdio.h>
|
||||
|
||||
void printseed(unsigned char* data) {
|
||||
int i;
|
||||
for(i=1;i<16;i++) {
|
||||
printf("%x ", data[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void printstream(unsigned char* data, int restart) {
|
||||
int i;
|
||||
for(i=restart;i<16;i++) {
|
||||
printf("%d ", data[i]&1);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#define CARRY if(a>0x0f) {\
|
||||
a &= 0xf;\
|
||||
carry=1;\
|
||||
} else carry=0;
|
||||
|
||||
void mangle(unsigned char* data) {
|
||||
unsigned char a,x,temp,i,offset,carry=0;
|
||||
a=data[0xf];
|
||||
do {
|
||||
x=a;
|
||||
offset=1;
|
||||
carry=1;
|
||||
a+=data[offset]+carry;
|
||||
data[offset]=a&0xf;
|
||||
a=data[offset++];
|
||||
a+=data[offset]+carry;
|
||||
a=(~a)&0xf;
|
||||
temp=a; a=data[offset]; data[offset++]=temp&0xf;
|
||||
a+=data[offset]+carry;
|
||||
if(a<0x10) {
|
||||
temp=a; a=data[offset]; data[offset++]=temp&0xf;
|
||||
}
|
||||
a+=data[offset];
|
||||
data[offset]=a&0xf;
|
||||
a=data[offset++];
|
||||
carry=0;
|
||||
a+=data[offset]+carry;
|
||||
temp=a; a=data[offset]; data[offset++]=temp&0xf;
|
||||
a+=8;
|
||||
if(a<0x10) {
|
||||
a+=data[offset]+carry;
|
||||
}
|
||||
temp=a; a=data[offset]; data[offset++]=temp&0xf;
|
||||
|
||||
while(offset<0x10) {
|
||||
a++;
|
||||
a+=data[offset]+carry;
|
||||
data[offset]=a&0xf;
|
||||
a=data[offset++];
|
||||
}
|
||||
offset &= 0xf;
|
||||
a=x;
|
||||
a+=0xf;
|
||||
CARRY
|
||||
} while(carry);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
unsigned char restart=1;
|
||||
unsigned char keyseed_orig[16]= {0x0, // dummy
|
||||
0xb,0x1,0x4,0xf,
|
||||
0x4,0xb,0x5,0x7,
|
||||
0xf,0xd,0x6,0x1,
|
||||
0xe,0x9,0x8};
|
||||
unsigned char lockseed_orig[16]={0x0, // dummy
|
||||
0x0,0x9,0xa,0x1,
|
||||
0x8,0x5,0xf,0x1,
|
||||
0x1,0xe,0x1,0x0,
|
||||
0xd,0xe,0xc};
|
||||
|
||||
unsigned char keyseed[16];
|
||||
unsigned char lockseed[16];
|
||||
|
||||
printseed(keyseed);
|
||||
printseed(lockseed);
|
||||
printf("\n");
|
||||
|
||||
while(1) {
|
||||
printf("\n");
|
||||
printstream(keyseed, restart);
|
||||
mangle(keyseed);
|
||||
mangle(keyseed);
|
||||
mangle(keyseed);
|
||||
mangle(lockseed);
|
||||
mangle(lockseed);
|
||||
mangle(lockseed);
|
||||
|
||||
// printseed(keyseed);
|
||||
// printseed(lockseed);
|
||||
restart=lockseed[3];
|
||||
lockseed[3]=lockseed[7];
|
||||
if(!restart)restart=1;
|
||||
// printf("send %d-15\n", restart);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
70
cic/scramble.txt
Normal file
70
cic/scramble.txt
Normal file
@ -0,0 +1,70 @@
|
||||
start:
|
||||
b14f4b57fd61e98
|
||||
4953771997e11b4
|
||||
BL=f
|
||||
A=[f]=8
|
||||
X=A
|
||||
C=1
|
||||
BL=1
|
||||
A+=[1]+1 = 8+b+1 = 4 C=1
|
||||
store [1]=4
|
||||
A=[1]=4 BL=2
|
||||
A+=[2]+1 = 4+1+1 = 6 C=0
|
||||
A=~A = 9
|
||||
A=[2] = 1
|
||||
store [2]=9 BL=3
|
||||
A+=[3]+0 = 4+1+0 = 5 C=0; no skip
|
||||
A=[3] = 4
|
||||
store [3]=5 BL=4
|
||||
A+=[4] = 4+f = 3 C=1
|
||||
store [4]=3
|
||||
A=[4] = 3 BL=5
|
||||
C=0
|
||||
A+=[5]+1 = 3+4+0 = 7 C=0
|
||||
A=[5] = 4
|
||||
store [5]=7 BL=6
|
||||
A+=8 = 4+8 = c C=0
|
||||
A+=[6]+0 = b+c+0 = 7 C=1
|
||||
A=[6] = b
|
||||
store [6]=7 BL=7
|
||||
|
||||
A+=1 = b+1 = c C=0
|
||||
A+=[7]+0 = c+5+0 = 1 C=1
|
||||
store [7] = 1
|
||||
A=[7] = 1 BL=8
|
||||
A+=1 = 1+1 = 2 C=0
|
||||
A+=[8]+0 = 2+7+0 = 9 C=0
|
||||
store [8] = 9
|
||||
A=[8] = 9 BL=9
|
||||
A+=1 = 9+1 = a C=0
|
||||
A+=[9]+0 = a+f+0 = 9 C=1
|
||||
store [9] = 9
|
||||
A=[9] = 9 BL=a
|
||||
A+=1 = 9+1 = a C=0
|
||||
A+=[a]+0 = a+d+0 = 7 C=1
|
||||
store [a] = 7
|
||||
A=[a] = 7 BL=b
|
||||
A+=1 = 7+1 = 8 C=0
|
||||
A+=[b]+0 = 8+6+0 = e C=0
|
||||
store [b] = e
|
||||
A=[b] = e BL=c
|
||||
A+=1 = e+1 = f C=0
|
||||
A+=[c]+0 = f+1+0 = 0 C=1
|
||||
store [c] = 0
|
||||
A=[c] = 0 BL=d
|
||||
A+=1 = 0+1 = 1 C=0
|
||||
A+=[d]+0 = 1+e+0 = f C=0
|
||||
store [d] = f
|
||||
A=[d] = f BL=e
|
||||
A+=1 = f+1 = 0 C=1
|
||||
A+=[e]+1 = 0+9+1 = a C=0
|
||||
store [e] = a
|
||||
A=[e] = a BL=f
|
||||
A+=1 = a+1 = b C=0
|
||||
A+=[f]+0 = b+8+0 = 3 C=1
|
||||
store [f] = 3
|
||||
A=[f] = 3 BL=0; skip
|
||||
A=X=8
|
||||
A+=f = 8+f = 7 C=1; skip
|
||||
noooo, all the shit again
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user