📄 at88scxx.c
字号:
GPA[1]=GPA[2];
GPA[2]=GPA[3];
GPA[3]=GPA[4];
GPA[4]=GPA[5]^Ri;
GPA[5]=GPA[6];
GPA[6]=GPA[7];
GPA[7]=R_Sum;
//s元素
if ((GPA[9]+((GPA[8]&0x3f)<<1)+((GPA[8]&0x40)>>6) )>127)
{S_Sum=( (GPA[9]) + ((GPA[8]&0x3f)<<1)+((GPA[8]&0x40)>>6) )-127;}
else
{S_Sum= (GPA[9]) + ((GPA[8]&0x3f)<<1)+((GPA[8]&0x40)>>6) ;}
GPA[8]=GPA[9];
GPA[9]=Si^GPA[10];
GPA[10]=GPA[11];
GPA[11]=GPA[12];
GPA[12]=GPA[13];
GPA[13]=GPA[14];
GPA[14]=S_Sum;
//t元素
if ((GPA[15]+GPA[17])> 31)
{T_Sum=GPA[15]+GPA[17]-31;}
else
{T_Sum=GPA[15]+GPA[17];}
GPA[15]=GPA[16];
GPA[16]=GPA[17];
GPA[17]=GPA[18]^Ti;
GPA[18]=GPA[19];
GPA[19]=T_Sum;
///Output
if((GPA[14]&0x01)==0)
{d=((GPA[7]^GPA[3])&0x01);}
else
{d=((GPA[19]^GPA[16])&0x01);}
if((GPA[14]&0x02)==0)
{d=d+((GPA[7]^GPA[3])&0x02);}
else
{d=d+((GPA[19]^GPA[16])&0x02);}
if((GPA[14]&0x04)==0)
{d=d+((GPA[7]^GPA[3])&0x04);}
else
{d=d+((GPA[19]^GPA[16])&0x04);}
if((GPA[14]&0x08)==0)
{d=d+((GPA[7]^GPA[3])&0x08);}
else
{d=d+((GPA[19]^GPA[16])&0x08);}
GPA[0]= ( (((GPA[0])&0x0f)<<4) +d); //GPA出口
}
}
//***********************read*************************
//功能:对at88scxx读操作函数
//本程序中以read(rwdata)调用;
//入口:rwdata数组
//出口:rwdata数组
//rd数组长度可改
//cmd_send_counter发送命令次数,超出8次,本函数退出,并认为I2C线路上无器件
//*****************************************************************
void read(rd)//
unsigned char rd[0x20];
{
unsigned char bitcounter;
unsigned char temp;
unsigned char cmd_send_counter;
unsigned char bytecounter;
temp=rd[0];
bytecounter=0;
cmd_send_counter=0;
SMSTART();
do{
for(bitcounter=0;bitcounter<8;bitcounter++)
{
if ((temp&0x80)==0x80)
{SDA=1;}
else
{SDA=0;}
_Nop();_Nop();
SCL=1;_Nop();_Nop();
SCL=0;temp=temp<<1;
}
SDA=1;_Nop();_Nop();_Nop();
SCL=1;_Nop();_Nop();_Nop();
if(SDA==0)
{SCL=0;bytecounter++;temp=rd[bytecounter];}
else
{SCL=0;SMSTART();temp=rd[0];bytecounter=0;cmd_send_counter++;}
if(cmd_send_counter>8)
{bytecounter=4;}
}while(bytecounter<4);
//rev byte
SDA=1;
for(bytecounter=0;bytecounter<rd[3];bytecounter++)
{
for(bitcounter=0;bitcounter<8;bitcounter++)
{
SCL=1;_Nop();_Nop();
if (SDA==1)
{temp=temp|0x01;}
else
{temp=(temp&0xfe);}
if(bitcounter<7)
{temp=temp<<1;}
else
{_Nop();}
SCL=0;_Nop();_Nop();
}
SDA=0;_Nop();_Nop();
SCL=1;_Nop();_Nop();
SCL=0;_Nop();_Nop();
SDA=1;_Nop();
rd[bytecounter+4]=temp;
}
SMSTOP();
}
//************************write***************************************
//功能:对at88scxx写操作函数
//本程序中以write(rwdata)调用;
//入口:rwdata数组
//出口:rwdata数组
//rd数组长度可改
//cmd_send_counter发送命令次数,超出8次,本函数退出,并认为I2C线路上无器件
//*****************************************************************
void write(SDATA)
unsigned char SDATA[0X14];
{
unsigned char bitcounter;
unsigned char temp;
unsigned char bytecounter;
unsigned char cmd_send_counter;
temp=SDATA[0];
bytecounter=0;
cmd_send_counter=0;
SMSTART();
do{
for(bitcounter=0;bitcounter<8;bitcounter++)
{
if ((temp&0x80)==0x80)
{SDA=1;}
else
{SDA=0;}
_Nop();_Nop();_Nop();
SCL=1;_Nop();_Nop();
SCL=0;_Nop();_Nop();
temp=temp<<1;
}
SDA=1;_Nop();_Nop();
SCL=1;_Nop();_Nop();
if(SDA==0)
{SCL=0;bytecounter++;temp=SDATA[bytecounter];}
else
{SCL=0;SMSTART();temp=SDATA[0];bytecounter=0;cmd_send_counter++;}
if(cmd_send_counter>8)
{bytecounter=SDATA[3]+4;}
}while(bytecounter<SDATA[3]+4);
SMSTOP();
}
//*****************************AUTHENTICATION*****************************
//双向认证函数
//入口:GC_select:选择密钥套数
//出口:AAC: 认证结果
//过程:
//1.从器件读出CIx,产生随机数Q0,计算密钥;计算出Q1,将Q0、Q1发送给器件,计算出新的CIx,SKx
//2.用读回的CIx与计算出的CIx比较
//3.用计算出的SKx替代GCx,重复1过程
//AAC:认证错误计数器.AAC!=0xff表示双向认证未通过或无器件
//需产生随机数则应在程序里修改
//************************************************************************
unsigned char AUTHENTICATION(unsigned char GC_select)
{
unsigned char SK[8]; //会话密钥
unsigned char Q_CH[0x14];//发送14H字节载体
unsigned char j;
for(j=0;j<=19;j++)
{GPA[j]=0x00;}//初始化GPA单元
Q_CH[0]=0xb6;
Q_CH[1]=0x00;
Q_CH[2]=GC_select<<4;
Q_CH[2]=Q_CH[2]+0x50;
Q_CH[3]=0x08;
read(Q_CH);
for(j=0;j<8;j++)
{Q_CH[j+12]=Q_CH[j+4];}//CI
for(j=0;j<8;j++)
{Q_CH[j+4]=0xAA;} //此处可改随机数
for(j=0;j<4;j++)
{
GPA_CLOCK(Q_CH[12+2*j],0x03);
GPA_CLOCK(Q_CH[12+2*j+1],0x03);
GPA_CLOCK(Q_CH[4+j],0x01);
}
if ((GC_select&0x0f)==0x00)
for(j=0;j<8;j++)
{Q_CH[12+j]=GC0[j];}
else if ((GC_select&0x0f)==0x01)
for(j=0;j<8;j++)
{Q_CH[12+j]=GC1[j];}
else if ((GC_select&0x0f)==0x02)
for(j=0;j<8;j++)
{Q_CH[12+j]=GC2[j];}
else
for(j=0;j<8;j++)
{Q_CH[12+j]=GC3[j];}
for(j=0;j<4;j++)
{
GPA_CLOCK(Q_CH[12+2*j],0x03);
GPA_CLOCK(Q_CH[12+2*j+1],0x03);
GPA_CLOCK(Q_CH[8+j],0x01);
}
GPA_CLOCK(0x00,0x06);
Q_CH[12]=GPA[0];
for(j=1;j<8;j++)
{
GPA_CLOCK(0x00,0x07);
Q_CH[12+j]=GPA[0];
}
Q_CH[0]=0xb8;//send ch
Q_CH[2]=0x00;
Q_CH[3]=0x10;
Q_CH[1]=GC_select;
write(Q_CH);
Wait_For_AckPolling();
//new ci
Q_CH[12]=0xFF;
for(j=1;j<8;j++)
{
GPA_CLOCK(0x00,0x02);
Q_CH[12+j]=GPA[0];
}
//new sk
for(j=0;j<8;j++)
{
GPA_CLOCK(0x00,0x02);
SK[j]=GPA[0];
}
GPA_CLOCK(0x00,0x03);
//比较CI值是否一致
Q_CH[0]=0XB6;
Q_CH[1]=0X00;
Q_CH[2]=GC_select<<4;
Q_CH[2]=Q_CH[2]+0x50;
Q_CH[3]=0x08;
read(Q_CH);
Wait_For_AckPolling();
if (Q_CH[4]!=0xff)
{goto Aut_Report;}
for(j=0;j<8;j++)
{
if(Q_CH[4+j]!= Q_CH[12+j])
{goto Aut_Report;}
}
GPA_CLOCK(0x00,0x05);
GPA_CLOCK(Q_CH[2],0x01);
GPA_CLOCK(0x00,0x05);
GPA_CLOCK(0x08,0x01);
for(j=0;j<8;j++)
{
GPA_CLOCK(Q_CH[4+j],0x01);
GPA_CLOCK(0x00,0x05);
}
//******************crypto_Authentication*************************
//以会话密钥再认证一次
//*****************************************************************
for(j=0;j<=19;j++)
{GPA[j]=0x00;}
for(j=0;j<8;j++)
{Q_CH[j+4]=0xAA;} //此处可改随机数
for(j=0;j<4;j++)
{
GPA_CLOCK(Q_CH[12+2*j],0x03);
GPA_CLOCK(Q_CH[12+2*j+1],0x03);
GPA_CLOCK(Q_CH[4+j],0x01);
}
for(j=0;j<4;j++)
{
GPA_CLOCK(SK[2*j],0x03);
GPA_CLOCK(SK[2*j+1],0x03);
GPA_CLOCK(Q_CH[8+j],0x01);
}
GPA_CLOCK(0x00,0x06);
Q_CH[12]=GPA[0];
for(j=1;j<8;j++)
{
GPA_CLOCK(0x00,0x07);
Q_CH[12+j]=GPA[0];
}
Q_CH[0]=0xb8;
Q_CH[1]=GC_select+0x10;
Q_CH[2]=0x00;
Q_CH[3]=0x10;
write(Q_CH);
Wait_For_AckPolling();
//new ci
Q_CH[12]=0xFF;
for(j=1;j<8;j++)
{
GPA_CLOCK(0x00,0x02);
Q_CH[12+j]=GPA[0];
}
//new sk
for(j=0;j<8;j++)
{
GPA_CLOCK(0x00,0x02);
SK[j]=GPA[0];
}
GPA_CLOCK(0x00,0x03);
//比较CI值是否一致
Q_CH[0]=0XB6;
Q_CH[1]=0X00;
Q_CH[2]=GC_select<<4;
Q_CH[2]=Q_CH[2]+0x50;
Q_CH[3]=0x08;
read(Q_CH);
Wait_For_AckPolling();
if (Q_CH[4]!=0xff)
{goto Aut_Report;}
for(j=0;j<8;j++)
{
if(Q_CH[4+j]!= Q_CH[12+j])
{goto Aut_Report;}
}
GPA_CLOCK(0x00,0x05);
GPA_CLOCK(Q_CH[2],0x01);
GPA_CLOCK(0x00,0x05);
GPA_CLOCK(0x08,0x01);
for(j=0;j<8;j++)
{
GPA_CLOCK(Q_CH[4+j],0x01);
GPA_CLOCK(0x00,0x05);
}
Aut_Report:
return Q_CH[4];
}
//******************verify_wr_pw********************************
//校验写密码组主函数,正确校验了写密码后开放读写
//pw_select:密码套数选择
//PAC:密码校验错误计数器.PAC!=0xff表示认证未通过或无器件
//****************************************************************
unsigned char verify_write_password(unsigned char pw_select)
{
unsigned char j;
unsigned char pw[7];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -