CIC stuff

This commit is contained in:
ikari 2010-03-10 13:49:02 +01:00
parent fbcefccbb1
commit b6cc40e290
4 changed files with 409 additions and 0 deletions

6
cic/d411-seeds.txt Normal file
View File

@ -0,0 +1,6 @@
key seed: b14f4b57fd61e98
110101111101010
lck seed: _9a185f11e10dec
_10101111010100

230
cic/d411.pseudo Normal file
View 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
View 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
View 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