当前位置:   article > 正文

C语言实现AES-128 CMAC算法_c语言实现cmac加密

c语言实现cmac加密

MessageAuthentication CodeMAC)是一种保障信息完整性和认证的密码学方法,其中CMAC的全称是Cypher-Based Message Authentication Code,基于AES等对称加密方式实现消息认证。通信双方需要共享一个对称密钥,由发送方生成一个MAC值,附在消息后面,接收方计算收到消息的MAC,如果和收到的MAC一致,则说明没有被篡改,并且能确认发送方一定拥有相同的密钥,即认证身份。

        美国国家标准与技术研究院NIST推荐了一种CMAC计算方式,可以避免CBC-MAC带来的缺点,编号为800-3B,文档可以从其官网上下载。该算法通过MAC密钥生成k1k2两个子密钥,并规定了数据位填充的规则,可以通过AES-128AES-192AES-256三种模式进行MAC计算,支持所有整数字节的数据以及长度为0的输入。下图为MAC算法处理不需要位填充和需要位填充的两种情况。本文介绍AES-128生成的CMAC实现。





    本C代码外部依赖项是mbedTLS的密码学库,下载及使用见《C语言实现AES加密解密》。


1外部调用列表


     本CMAC算法包括的内部函数如下。


2本代码中设计的函数


    本CMAC算法包括的全局变量如下。


3本代码中的全局变量



CMAC实现部分代码如下:

  1. #include<stdio.h>
  2. #include "mbedtls/aes.h"
  3. #include "mbedtls/compat-1.3.h"
  4. uint8_t MAC[16];
  5. uint8_t MACkey[16];
  6. uint8_t k1[16];
  7. uint8_t k2[16];
  8. mbedtls_aes_context aes;
  9. void leftshift(int len, uint8_t* add, uint8_t*des)
  10. {
  11. int i;
  12. for (i = 0; i < len - 1; i++)
  13. {
  14. des[i] = (add[i] << 1) + (add[i + 1] >= 0x80?1:0);
  15. }
  16. des[len - 1] = add[len - 1] << 1;
  17. }
  18. void ArrayXor(int len, uint8_t*a1, uint8_t*a2, uint8_t*des)
  19. {
  20. int i;
  21. for (i = 0; i < len; i++)
  22. {
  23. des[i] = a1[i] ^ a2[i];
  24. }
  25. }
  26. void LoadMacKey(uint8_t *key)
  27. {
  28. int i;
  29. uint8_t plain[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  30. uint8_t Rb[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 };
  31. uint8_t c0[16];
  32. for (i = 0; i < 16; i++)
  33. {
  34. MACkey[i] = key[i]; // set MAC key
  35. }
  36. mbedtls_aes_setkey_enc(&aes, MACkey, 128);
  37. mbedtls_aes_crypt_ecb(&aes, AES_ENCRYPT, plain, c0);
  38. if (c0[0]<0x80) //generate k1
  39. {
  40. leftshift(16, c0, k1);
  41. }
  42. else
  43. {
  44. leftshift(16, c0, k1);
  45. ArrayXor(16, k1, Rb, k1);
  46. }
  47. if (k1[0] < 0x80) //generate k2
  48. {
  49. leftshift(16, k1, k2);
  50. }
  51. else
  52. {
  53. leftshift(16, k1, k2);
  54. ArrayXor(16, k2, Rb, k2);
  55. }
  56. }
  57. void GenerateMAC(int len, uint8_t *add, uint8_t *macvalue)
  58. {
  59. int i,block;
  60. uint8_t IVtemp[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  61. uint8_t Blocktemp[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  62. if (len % 16 == 0 && len!=0)
  63. {
  64. mbedtls_aes_setkey_enc(&aes, MACkey, 128);// load mac key
  65. block = len / 16;
  66. for (i = 0; i < block-1; i++)
  67. {
  68. ArrayXor(16, &add[i * 16], IVtemp, Blocktemp);
  69. mbedtls_aes_crypt_ecb(&aes, AES_ENCRYPT, Blocktemp, IVtemp);
  70. }
  71. ArrayXor(16, &add[(block-1)*16], IVtemp, Blocktemp);
  72. ArrayXor(16, Blocktemp, k1, Blocktemp);
  73. mbedtls_aes_crypt_ecb(&aes, AES_ENCRYPT, Blocktemp, macvalue);
  74. }
  75. else
  76. {
  77. if (len==0)
  78. {
  79. mbedtls_aes_setkey_enc(&aes, MACkey, 128);// load mac key
  80. block = 1;
  81. Blocktemp[0] = 0x80;//padding the first bit with 1
  82. ArrayXor(16, Blocktemp, k2, Blocktemp);
  83. mbedtls_aes_crypt_ecb(&aes, AES_ENCRYPT, Blocktemp, macvalue);
  84. }
  85. else
  86. {
  87. mbedtls_aes_setkey_enc(&aes, MACkey, 128);// load mac key
  88. uint8_t remain = len % 16;
  89. block = len / 16 + 1;
  90. for (i = 0; i < block - 1; i++)
  91. {
  92. ArrayXor(16, &add[i * 16], IVtemp, Blocktemp);
  93. mbedtls_aes_crypt_ecb(&aes, AES_ENCRYPT, Blocktemp, IVtemp);
  94. }
  95. // the last block padding
  96. for (i = 0; i < remain; i++)
  97. {
  98. Blocktemp[i] = add[(block - 1) * 16 + i];
  99. }
  100. Blocktemp[remain] = 0x80;
  101. for (i = remain + 1; i < 16; i++)
  102. {
  103. Blocktemp[i] = 0;
  104. }
  105. // end of the last block padding
  106. ArrayXor(16, Blocktemp, k2, Blocktemp);
  107. ArrayXor(16, Blocktemp, IVtemp, Blocktemp);
  108. mbedtls_aes_crypt_ecb(&aes, AES_ENCRYPT, Blocktemp, macvalue);
  109. }
  110. }
  111. }
  112. uint8_t VerifyMAC(int len, uint8_t *add, uint8_t *macvalue1)
  113. {
  114. int i, block;
  115. uint8_t IVtemp[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  116. uint8_t Blocktemp[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  117. uint8_t macvalue[16];
  118. uint8_t result=1;
  119. if (len % 16 == 0 && len != 0)
  120. {
  121. mbedtls_aes_setkey_enc(&aes, MACkey, 128);// load mac key
  122. block = len / 16;
  123. for (i = 0; i < block - 1; i++)
  124. {
  125. ArrayXor(16, &add[i * 16], IVtemp, Blocktemp);
  126. mbedtls_aes_crypt_ecb(&aes, AES_ENCRYPT, Blocktemp, IVtemp);
  127. }
  128. ArrayXor(16, &add[(block - 1) * 16], IVtemp, Blocktemp);
  129. ArrayXor(16, Blocktemp, k1, Blocktemp);
  130. mbedtls_aes_crypt_ecb(&aes, AES_ENCRYPT, Blocktemp, macvalue);
  131. }
  132. else
  133. {
  134. if (len == 0)
  135. {
  136. mbedtls_aes_setkey_enc(&aes, MACkey, 128);// load mac key
  137. block = 1;
  138. Blocktemp[0] = 0x80;//padding the first bit with 1
  139. ArrayXor(16, Blocktemp, k2, Blocktemp);
  140. mbedtls_aes_crypt_ecb(&aes, AES_ENCRYPT, Blocktemp, macvalue);
  141. }
  142. else
  143. {
  144. mbedtls_aes_setkey_enc(&aes, MACkey, 128);// load mac key
  145. uint8_t remain = len % 16;
  146. block = len / 16 + 1;
  147. for (i = 0; i < block - 1; i++)
  148. {
  149. ArrayXor(16, &add[i * 16], IVtemp, Blocktemp);
  150. mbedtls_aes_crypt_ecb(&aes, AES_ENCRYPT, Blocktemp, IVtemp);
  151. }
  152. // the last block padding
  153. for (i = 0; i < remain; i++)
  154. {
  155. Blocktemp[i] = add[(block - 1) * 16 + i];
  156. }
  157. Blocktemp[remain] = 0x80;
  158. for (i = remain + 1; i < 16; i++)
  159. {
  160. Blocktemp[i] = 0;
  161. }
  162. // end of the last block padding
  163. ArrayXor(16, Blocktemp, k2, Blocktemp);
  164. ArrayXor(16, Blocktemp, IVtemp, Blocktemp);
  165. mbedtls_aes_crypt_ecb(&aes, AES_ENCRYPT, Blocktemp, macvalue);
  166. }
  167. }
  168. result = 1;
  169. for (i = 0; i < 16; i++)
  170. {
  171. if (macvalue[i] != macvalue1[i])
  172. {
  173. return(result);
  174. }
  175. }
  176. result = 0;
  177. return(result);
  178. }

Main函数部分代码如下:

  1. <pre class="cpp" name="code">int main()
  2. {
  3. uint8_t data[64] = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
  4. 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
  5. 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
  6. 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 };
  7. uint8_t tf=2;
  8. uint8_t tk[16] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c };
  9. LoadMacKey(tk);//加载MAC key
  10. GenerateMAC(33, data, MAC);// 数据字节长度,数据地址,MAC地址
  11. tf=VerifyMAC(33, data, MAC); // 数据字节长度,数据地址,MAC地址
  12. }

 








本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号