⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 at88scxx.c

📁 Atmel公司推出了最新的加密芯片AT88SC0104C~25616C系列
💻 C
📖 第 1 页 / 共 3 页
字号:

     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 + -