赞
踩
//CMAC
void k1_k2(uint8_t key[16], uint8_t key_1[16], uint8_t key_2[16])
{
uint8_t L[16];
uint8_t Zero_n[16]={0X00};
int i;
EncryPtion(Zero_n,key,L);
if(L[0]>=0X80)
{
for(i=0;i<16;i++)
key_1[i]=L[i]<<1;
key_1[15]=key_1[15]^0X87;
}
else
{
for(i=0;i<16;i++)
key_1[i]=L[i]<<1;
}
if(key_1[0]>=0X80)
{
for(i=0;i<16;i++)
key_2[i]=key_1[i]<<1;
key_2[15]=key_2[15]^0X87;
}
else
{
for(i=0;i<16;i++)
key_2[i]=key_1[i]<<1;
}
}
/k1_k2_test*/
void k1_k2_test(uint8_t * key, Mac_Para_Out *mac_para_out)
{
uint8_t L[16];
uint8_t Zero_n[16]={0X00};
int i;
EncryPtion(Zero_n,key,L);
if(L[0]>=0X80)
{
for(i=0;i<16;i++)
mac_para_out->key_1[i]=L[i]<<1;
mac_para_out->key_1[15]=mac_para_out->key_1[15]^0X87;
}
else
{
for(i=0;i<16;i++)
mac_para_out->key_1[i]=L[i]<<1;
}
if(mac_para_out->key_1[0]>=0X80)
{
for(i=0;i<16;i++)
mac_para_out->key_2[i]=mac_para_out->key_1[i]<<1;
mac_para_out->key_2[15]=mac_para_out->key_2[15]^0X87;
}
else
{
for(i=0;i<16;i++)
mac_para_out->key_2[i]=mac_para_out->key_1[i]<<1;
}
/*printf(“将KEY_1 KEY_2的值打印出来”);
printf("\r\n");
for(i=0;i<16;i++)
{
printf("%x key1 “,mac_para_out->key_1[i]);
printf(”%x key2 “,mac_para_out->key_2[i]);
printf(”\r\n");
}*/
}
//对于消息不是密文分组的整数倍,
void fil(uint8_t *last_test, uint32_t length, uint8_t out_text[16])
{
int i;
for(i=0;i<16;i++)
{
if(i<length)
out_text[i]=last_test[i];
else if(i==length)
out_text[i]=0X80;
else
out_text[i]=0X00;
}
}
void AES_CMAC(uint8_t * MASS , uint8_t key, uint32_t length,uint8_t * mac)
{
int i,j,n,last_i;
int flag=0; //用于标记密文分组是否完整
uint8_t M_c1[16]={0x00}, M_c2[16],M_c_k[16]; //用于存放中间数据
uint8_t key_1[16],key_2[16]; //分组秘钥
uint8_t last[16],Cn[16];
n=(length+15)/16; //用于确定分几组
last_i=length%16;
k1_k2(key, key_1,key_2);
if(last_i0)
flag=1; //标明是分组长度b=128的整数倍
if(flag0)
fil(&MASS[16(n-1)], last_i,last);
//对前n-1轮
for(i=0;i<(n-1);i++)
{
for(j=0;j<16;j++)
M_c2[j]=M_c1[j]^MASS[16*i+j];
EncryPtion(M_c2,key,M_c1); // M_c1 is output
printf("\r\n");
printf(“AES_CMAC:将M_c1的结果输出来,也就是前N-1轮加密的结果”);
printf("\r\n");
for(j=0;j<16;j++)
printf("%x " , M_c1[j]);
printf("\r\n");
} printf("\r\n"); if(flag==1) { for(i=0;i<16;i++) M_c_k[i]=MASS[16*(n-1)+i]^M_c1[i]^key_1[i]; EncryPtion(M_c_k, key, Cn); printf("\r\n"); printf("将Cn的结果输出来,也就是第N次加密后的结果"); printf("\r\n"); for(i=0;i<16;i++) { printf("%x " ,Cn[i]); } printf("\r\n"); } else { for(i=0;i<16;i++) M_c_k[i]=last[i]^M_c1[i]^key_2[i]; EncryPtion(M_c_k, key,Cn); printf("\r\n"); printf("将最后不全的数值Cn的结果输出,也就是最后不全部分补全后输出"); printf("\r\n"); for(i=0;i<16;i++) { printf("%x " , Cn[i]); } printf("\r\n"); } for(i=0;i<16;i++) mac[i]=Cn[i];
}
/第一次开始计算**/
void CMAC_CalStart(uint8_t *data, uint8_t * key, uint32_t len, Mac_Para_Out *mac_para_out )
{
int j;
for(j=0;j<16;j++)
// mac_para_out->M_c2[j]=data[j]mac_para_out->M_c1[j]mac_para_out->key_1[j];
mac_para_out->M_c2[j]=mac_para_out->M_c1[j]^data[j];
EncryPtion(mac_para_out->M_c2,key,mac_para_out->M_c1);
printf("将第一次加密后的结果放到struct里,并将其输出出来");
printf("\r\n");
for( j = 0 ; j < 16 ;j++)
{
printf("%x ",mac_para_out->M_c1[ j ]);
}
printf("\r\n");
}
/中间部分计算***/
void CMAC_CalMid(uint8_t *data, uint8_t * key, uint32_t len, Mac_Para_Out mac_para_out)
{
int i,j,n;
n=(len+15)/16; //用于确定分几组
printf("\r\n");
printf(“将上一次加密后结果输出,,,,”);
printf("\r\n");
for( j = 0 ; j < 16 ;j++)
{
printf("%x ",mac_para_out->M_c1[ j ]);
}
for(i=0;i<(n);i++)
{
for(j=0;j<16;j++)
mac_para_out->M_c2[j]=mac_para_out->M_c1[j]^data[16i+j];
EncryPtion(mac_para_out->M_c2,key,mac_para_out->M_c1); // M_c1 is output
printf("\r\n");
printf("mid部分,将中间n次加密后的结果放到struct里,并将其输出出来");
printf("\r\n");
for( j = 0 ; j < 16 ;j++)
{
printf("%x ",mac_para_out->M_c1[ j ]);
}
printf("\r\n");
}
}
/最后不全的,需要补全计算/
void CMAC_CalEnd(uint8_t *data, uint8_t * key, uint32_t len, Mac_Para_Out *mac_para_out)
{
int i,j,n,last_i;
int flag=0; //用于标记密文分组是否完整
uint8_t last[16];
n=(len+15)/16; //用于确定分几组
last_i=len%16;
if(last_i0)
flag=1; //标明是分组长度b=128的整数倍
if(flag0)
printf("\r\n"); printf("end:将上一次加密后结果输出,,,,"); printf("\r\n"); for( j = 0 ; j < 16 ;j++) { printf("%x ",mac_para_out->M_c1[ j ]); } fil(&data[16*(n-1)], last_i,last); //对前n-1轮 for(i=0;i<n-1;i++) { for(j=0;j<16;j++) mac_para_out->M_c2[j]=mac_para_out->M_c1[j]^data[16*i+j]; EncryPtion(mac_para_out->M_c2,key,mac_para_out->M_c1); // M_c1 is output printf("\r\n"); printf("cal_end:将M_c1的结果输出来,也就是前N-1轮加密的结果"); printf("\r\n"); for(i=0;i<16;i++) printf("%x " , mac_para_out->M_c1[i]); printf("\r\n"); } printf("\r\n"); if(flag==1) { for(i=0;i<16;i++) mac_para_out->M_c_k[i]=data[16*(n-1)+i]^mac_para_out->M_c1[i]^mac_para_out->key_1[i]; EncryPtion(mac_para_out->M_c_k, key, mac_para_out->Cn); printf("\r\n"); printf("将Cn的结果输出来,也就是第N次加密后的结果"); printf("\r\n"); for(i=0;i<16;i++) { printf("%x " ,mac_para_out->Cn[i]); } printf("\r\n"); } else { for(i=0;i<16;i++) mac_para_out->M_c_k[i]=last[i]^mac_para_out->M_c1[i]^mac_para_out->key_2[i]; EncryPtion(mac_para_out->M_c_k, key,mac_para_out->Cn); printf("\r\n"); printf("将最后不全的数值Cn的结果输出,也就是最后不全部分补全后输出"); printf("\r\n"); for(i=0;i<16;i++) { printf("%x " ,mac_para_out->Cn[i]); } printf("\r\n"); }
}
int main()
{
uint8_t mac[16]={0};
uint8_t key[16]={22, 11, 15, 16, 28, 11, 20, 56, 11, 55, 15, 88, 34, 44, 44, 33};
uint8_t Mass[62]={ 12, 22, 22, 40, 45, 96, 65, 33, 77, 11, 73, 93, 17, 44, 55, 22,
88, 57, 12, 03, 33, 55, 66, 74, 77, 88, 45,56, 65, 51, 30, 34, 54, 46, 55, 66, 77, 11,
65, 55, 44, 19, 33, 22, 52, 11, 23, 32, 24, 45,
43, 45, 45, 17, 45, 54, 41, 65, 67, 76, 37, 10};
uint8_t Mass_start[16]={12, 22, 22, 40, 45, 96, 65, 33, 77, 11, 73, 93, 17, 44, 55, 22};
uint8_t Mass_mid[32]={88, 57, 12, 03, 33, 55, 66, 74, 77, 88, 45,56, 65, 51, 30, 34,
54, 46, 55, 66, 77, 11,65, 55, 44, 19, 33, 22, 52, 11, 23,32};
/uint8_t Mass_mid[48]={12, 22, 22, 40, 45, 96, 65, 33, 77, 11, 73, 93, 17, 44, 55, 22,
88, 57, 12, 03, 33, 55, 66, 74, 77, 88, 45,56, 65, 51, 30, 34,
54, 46, 55, 66, 77, 11,65, 55, 44, 19, 33, 22, 52, 11, 23,32};/
uint8_t Mass_last[14]={24, 45,43, 45, 45, 17, 45, 54, 41, 65, 67, 76, 37, 10};
Mac_Para_Out mac_para_out; printf("这个是对于62个都进行CMAC运算后的结果"); printf("\r\n"); AES_CMAC(Mass,key ,62,mac ); for(int i=0;i<16;i++) printf("%x ",mac[i]); printf("\r\n"); printf("这个是对于前16个都进行CMAC运算后的结果"); printf("\r\n"); k1_k2_test(key, &mac_para_out); CMAC_CalStart(Mass_start,key ,16,&mac_para_out); for(int i=0;i<16;i++) printf("%x ",mac_para_out.M_c1[i]); printf("\r\n"); printf("这个是对中间32个进行CMAC计算结果"); printf("\r\n"); CMAC_CalMid(Mass_mid,key,32,&mac_para_out ); for(int i=0;i<16;i++) printf("%x ",mac_para_out.M_c1[i]); printf("\r\n"); printf("这个是对于最后14个都进行CMAC运算后的结果"); printf("\r\n"); CMAC_CalEnd(Mass_last,key,14, &mac_para_out); for(int i=0;i<16;i++) printf("%x ",mac_para_out.Cn[i]); return 0;
}
5.关于CMAC算法的介绍,好多人都写过,我这里就不说了,就把结果发出来,记录一下,感兴趣的,可以看我 之前的文章,


Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。