AT88SC104 加密认证过程

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);
    }

}

 

 


 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值