AES-CMAC代码的C++实现
- 本人使用的codeblock,来编写代码,以及代码的仿真和调试的,感觉挺好用,
- 代码实现主要分为三部分,start,mid,end。类似CRC校验的实现方式,
- /加密算法 plaintext 明文,ciphertext 密文 key 秘钥*/
void EncryPtion(uint8_t plaintext[16], uint8_t key[16], uint8_t ciphertext[16])
{
int i,j;
uint8_t state[4][4];
for(i=0;i<4;i++)
for(j=0;j<4;j++)
state[j][i]=plaintext[4i+j];
key_Expansion(key); //秘钥扩展
Roundkey(state,0);
for(i=1;i<10;i++)
Round_4(state,i);
Round_3(state);
for(i=0;i<4;i++)
for(j=0;j<4;j++)
ciphertext[4i+j]=state[j][i];
}
/k1_k2_test*/
}*/
}
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"); }
}
- main函数
/主函数/
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;
}
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/231168.html原文链接:https://javaforall.net
