AT88SC104 加密认证过程

论坛 期权论坛 脚本     
匿名技术用户   2020-12-22 08:10   11   0

AT88SCXX有三种模式:普通读写,密码验证,身份认证,加密认证;
身份认证:主机读取设备的Cryptogram C 和Secret Seed G 。主机生成随机数与Cryptogram C 和Secret Seed G
相结合生成一个挑战码。挑战码生成(由DES(F1,F2)算法计算出);再将主机生成的八字节随机数和八字节的挑战码发送给设备。最后重新读取Cryptogram ,将读取的Cryptogram 与主机自己生成的Cryptogram(由DES(F1,F2)算法产生)比较。相同则成功。

加密认证:身份认证后进行加密认证。过程与身份认证类似,将身份认证中的Secret Seed替换成Session Encryption Key(由身份认证时(DES(F1,F2)算法产生))。


假设用户区0:使用加密认证,步骤:(1)主机读取设备的Cryptogram C 和Secret Seed G 。主机生成随机数与设备Cryptogram C 和Secret Seed G相结合生成一个挑战码。挑战码生成(由DES(F1,F2)算法计算出);再将主机生成的八字节随机数和八字节的挑战码发送给设备。最后重新读取Cryptogram ,将读取的Cryptogram 与主机自己生成的Cryptogram(由DES(F1,F2)算法产生)比较。相同则成功,重复(1)过程,只要将(1)过程中的Secret Seed替换成Session Encryption Key。
注意:在身份认证成功后需要将Cryptogram 加入到F1,F2算法中。


DES算法(F1,)头文件

#define RA       (ucGpaRegisters[0])
#define RB       (ucGpaRegisters[1])
#define RC       (ucGpaRegisters[2])
#define RD       (ucGpaRegisters[3])
#define RE       (ucGpaRegisters[4])
#define RF       (ucGpaRegisters[5])
#define RG       (ucGpaRegisters[6])
#define TA       (ucGpaRegisters[7])
#define TB       (ucGpaRegisters[8])
#define TC       (ucGpaRegisters[9])
#define TD       (ucGpaRegisters[10])
#define TE       (ucGpaRegisters[11])
#define SA       (ucGpaRegisters[12])
#define SB       (ucGpaRegisters[13])
#define SC       (ucGpaRegisters[14])
#define SD       (ucGpaRegisters[15])
#define SE       (ucGpaRegisters[16])
#define SF       (ucGpaRegisters[17])
#define SG       (ucGpaRegisters[18])
#define Gpa_byte (ucGpaRegisters[19])
#define Gpa_Regs (20)
 
 
// Defines for constants used
#define CM_MOD_R (0x1F)
#define CM_MOD_T (0x1F)
#define CM_MOD_S (0x7F)
 
// Macros for common operations
#define cm_Mod(x,y,m) ((x+y)>m?(x+y-m):(x+y))
#define cm_RotT(x)    (((x<<1)&0x1e)|((x>>4)&0x01))
#define cm_RotR(x)    (((x<<1)&0x1e)|((x>>4)&0x01))
#define cm_RotS(x)    (((x<<1)&0x7e)|((x>>6)&0x01))
 
// Externals
extern uint8_t ucGpaRegisters[Gpa_Regs];

DES算法(F1,F2)源代码

返回值即为产生的一个字节挑战码(这里将返回值设置成全局)
// Generate next value
uint8_t cm_GPAGen(uint8_t Datain)
{   
  uint8_t Din_gpa;
  uint8_t Ri, Si, Ti;
  uint8_t R_sum, S_sum, T_sum;
   
  // Input Character
  Din_gpa = Datain^Gpa_byte;
  Ri = Din_gpa&0x1f;                   //Ri[4:0] = Din_gpa[4:0]
  Si = ((Din_gpa<<3)&0x78)|((Din_gpa>>5)&0x07);   //Si[6:0] = {
  //Din_gpa[3:0], Din_gpa[7:5]
  //}
  Ti = (Din_gpa>>3)&0x1f;                  //Ti[4:0] = Din_gpa[7:3];
      
  //R polynomial
  R_sum = cm_Mod(RD, cm_RotR(RG), CM_MOD_R);
  RG = RF;
  RF = RE;
  RE = RD;
  RD = RC^Ri;
  RC = RB;
  RB = RA;
  RA = R_sum;   
  //S ploynomial
  S_sum = cm_Mod(SF, cm_RotS(SG), CM_MOD_S);
  SG = SF;
  SF = SE^Si;
  SE = SD;
  SD = SC;
  SC = SB;
  SB = SA;
  SA = S_sum;
  //T polynomial
  T_sum = cm_Mod(TE,TC,CM_MOD_T);
  TE = TD;
  TD = TC;
  TC = TB^Ti;
  TB = TA;
  TA = T_sum;
  // Output Stage
  Gpa_byte =(Gpa_byte<<4)&0xF0;                                  // shift gpa_byte left by 4
  Gpa_byte |= ((((RA^RE)&0x1F)&(~SA))|(((TA^TD)&0x1F)&SA))&0x0F; // concat 4 prev bits and 4 new bits
 
 return Gpa_byte;
}

主机产生挑战码和Ci,sk,

//此函数功能:主机产生自身的Cyptogram和Session Encryption Key ,产生设备需要的挑战码。
  /* function Do authenticate/encrypt challenge
  * pQ: host generate random number
  * 
  * pCi: read at88sc Cyptogram and generate host Cyptogram
  * pCh : cryptogram and secret seed to generate a 64-bit challenge for the devic
  * pSK : Secret Seed
  */
void KM_AuthenticationCal(uint8_t *pCi,uint8_t *pSK,uint8_t*pQ ,uint8_t *pCh)
{
 int i = 0,j = 0;
 cm_ResetCrypto();
 // Setup the cyptographic registers
 for(j = 0; j < 4 ;j++)//总执行四次。不能更改次数
 {
   for(i = 0; i<3; i++) cm_GPAGen(pCi[2*j]);
   for(i = 0; i<3; i++) cm_GPAGen(pCi[2*j+1]);
   cm_GPAGen(pQ[j]); 
 }
  for(j = 0; j<4; j++ ) //总执行四次。不能更改次数
 { 
  for(i = 0; i<3; i++) cm_GPAGen(pSK[2*j]);
  for(i = 0; i<3; i++) cm_GPAGen(pSK[2*j+1]);
  cm_GPAGen(pQ[j+4]);     
 } 
 cm_GPAGenN(6);                    // 6 0x00s
 pCh[0] = Gpa_byte;
  for (j = 1; j<8; j++) //总执行8次。不能更改次数
 {
  cm_GPAGenN(7);                // 7 0x00s
  pCh[j] = Gpa_byte;     
 }
 pCi[0] = 0xFF;//new ci
 for(j = 1; j < 8; j++)//总执行8次。不能更改次数
 {
  cm_GPAGenN(2);                // 2 0x00s
  pCi[j] = Gpa_byte; 
 }
 for(j = 0; j < 8; j++)//总执行8次。不能更改次数
 {
   cm_GPAGenN(2);                // new sk
    pSK[j] = Gpa_byte; 
 }
 cm_GPAGenN(3); 
}

//例子:加密认证
int main()
{
AuthenEncypt();
setUser(0xB4,0x03,zone,0x00);
read(0xB2,0x00,0x00,0x08,缓存的BUFF,大小)//读取用户区

}

bool AuthenEncypt(void)
{
char * Cyptogram[0x08],SecretSeed[0x08],RandomNumber[0x08],Changlleng[0x08];
char *wAT88[0x10];
1.读取设备 Cyptogram,Secret Seed 。
read(指令,高地址,低地址,读取到的八个字节,读取的大小(0x08));//读取
2.主机生成随机数(可自定义八个)
for()
{
RandomNumber[i] = rand()%255+1;
}
3.将读取出来的Cyptogram,Secret Seed,和random 三个相结合。调用函数
void KM_AuthenticationCal(uint8_t *pCi,uint8_t *pSK,uint8_t*pQ ,uint8_t *pCh);

KM_AuthenticationCal(Cyptogram,SecretSeed,RandomNumber,Changlleng);

4.将随机数RandomNumber和挑战码Changlleng合并成一个16字节
for()
{
wAT88[i] = RandomNumber[i];
}
for()
{
wAT88[i+8] = Changlleng[i];
}
5.发送到AT88SC
write(0xB8,0x0X(X=key set 0-3),0x00,0x10);
6.读AT88SC配置区中Cryptogram(G0-G3)所对应的八字节
read(0xB6,0x00,0x50(例如选择G0),0x08,存放Cryptogram缓冲区wAT88);

7.比较读到的Cryptogram和主机产生的Cryptogram。
for(i = 0; i < 8; i++)
{
if(Cyptogram[i] != wAT88[i])//Cyptogram在调用KM_AuthenticationCal时候产生的,wAT88c执行完第五步后产生的。
{
//错误提示,身份认证失败
}

}
8.执行完成第七部后如果成功,就执行第八步:注意第八步的第三小步:
1.读取设备 Cyptogram,Secret Seed 。
read(指令,高地址,低地址,读取到的八个字节,读取的大小(0x08));//读取
2.主机生成随机数(可自定义八个)
for()
{
RandomNumber[i] = rand()%255+1;
}
3.重新读取设备Cyptogram。在上面的第三大步中产生了一个Session Encryption Key 在变量SecretSeed[0x08]八个字节
void KM_AuthenticationCal(uint8_t *pCi,uint8_t *pSK,uint8_t*pQ ,uint8_t *pCh);

KM_AuthenticationCal(Cyptogram,SecretSeed,RandomNumber,Changlleng);

4.将随机数RandomNumber和挑战码Changlleng合并成一个16字节
for()
{
wAT88[i] = RandomNumber[i];
}
for()
{
wAT88[i+8] = Changlleng[i];
}
5.发送到AT88SC
write(0xB8,0x1X(X=key set 0-3),0x00,0x10);
6.读AT88SC配置区中Cryptogram(G0-G3)所对应的八字节
7.比较读到的Cryptogram和主机产生的Cryptogram。
for(i = 0; i < 8; i++)
{
if(Cyptogram[i] != wAT88[i])//Cyptogram在调用KM_AuthenticationCal时候产生的,wAT88c 执行完第五步后产生的。
{
//错误提示,加密认证失败
}

}
9.到这里说明加密认证成功。最后要读写,需要如下:

for(int i = 0; i < 5; i++){
cm_GPAGen(0x00);//执行五次
}

cm_GPAGen(DataIn);//DataIn:在第八步骤中第6小步读出的Cyptogram所在的地址数据。


for(i = 0; i < 8; i++)
{
cm_GPAGen(ucCM_Ci2[i]);//ucCM_Ci2[i] 读出的Cyptogram八个字节。
for(int i = 0; i < 5; i++){
cm_GPAGen(0x00);//执行五次
}
}
}

}

void setUser(0xB4,0x03,zone,0x00);
{

cm_GPAGen(zone);//将第几用户区加入到DES算法中
//发送 0xB4,0x03,zone,0x00这条指令到at88sc

}

void read(0xB2,0x00,0x00,缓存的BUFF,大小len)//读取用户区
{
for(i < 5;)
{
cm_GPAGen(0x00);//需要 for 循环五次
}
cm_GPAGen(0x00);//0x00:要读的区域高地址一般时0x00;注意执行一次
for(i < 5;)
{
cm_GPAGen(0x00);//需要 for 循环五次
}
cm_GPAGen(len);//len:要读取的大小;注意执行一次

发送0xB2,0x00,要读取的地址,要读取的大小len,接收的数据,接收的大小。这条指令到AT88SC
// 最后对读取的数据进行解密:

for(i = 0; i < len(读取的大小);i++)
{


if(加密的话执行if语句里)//加入时读取AT88SC中的配置区,那么这个判断语句必须是一个大 于从密码区的起始地址例如AT88SC104那么这个必须大于 0xB0
{
缓冲区buff[i] = read[i]^Gpa_byte //read[i] 读取到的数据抑或上Gpa_byte :此函数中返 回值的全变量cm_GPAGen();
}
cm_GPAGen(buff[i]);
for(j<5){//单独执行cm_GPAGen(0x00);五次
cm_GPAGen(0x00);
}
}
}


void write()//加密写入用户区
{


for(i < 5;)
{
cm_GPAGen(0x00);//需要 for 循环五次
}
cm_GPAGen(0x00);//0x00:要写入的区域高地址一般时0x00;注意执行一次
for(i < 5;)
{
cm_GPAGen(0x00);// 循环五次
}
cm_GPAGen(len);//len:要写入的大小;注意执行一次


for(i = 0; i < len(读取的大小);i++)
{
temp = write[i]//read[i] 写入到的数据

for(j<5){//单独执行cm_GPAGen(0x00);五次
cm_GPAGen(0x00);
}

if(加密的话执行if语句里)//加入时写入AT88SC中的配置区,那么这个判断语句必须是一个大 于从密码区的起始地址例如AT88SC104那么这个必须大于 0xB0
{
缓冲区buff[i] = read[i]^Gpa_byte //read[i] 读取到的数据抑或上Gpa_byte :此函数中返 回值的全变量cm_GPAGen();
}
cm_GPAGen(temp);
}

}


分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP