#include "aes.h"extern OL_APITABLE_T *AP_interface;typedef struct{ uint32_t eK[44], dK[44]; // encKey, decKey int Nr; // 10 rounds}AesKey;#d_//设定常量 const uint8_t ">
当前位置:   article > 正文

C语言 AES算法 加密解密_//设定常量 const uint8_t rcon[11]={0x01,0x02,0x04,0x08

//设定常量 const uint8_t rcon[11]={0x01,0x02,0x04,0x08,0x20,0x40,0x80,0x1b,0

C语言 实现 AES 128 位加密解密
1、调用函数

  1. #include "stdio.h"
  2. #include "stdlib.h"
  3. #include <string.h>
  4. #include "aes.h"
  5. extern OL_APITABLE_T *AP_interface;
  6. typedef struct{
  7. uint32_t eK[44], dK[44]; // encKey, decKey
  8. int Nr; // 10 rounds
  9. }AesKey;
  10. #define BLOCKSIZE 16 //AES-128分组长度为16字节
  11. // uint8_t y[4] -> uint32_t x
  12. #define LOAD32H(x, y) \
  13. do { (x) = ((uint32_t)((y)[0] & 0xff)<<24) | ((uint32_t)((y)[1] & 0xff)<<16) | \
  14. ((uint32_t)((y)[2] & 0xff)<<8) | ((uint32_t)((y)[3] & 0xff));} while(0)
  15. // uint32_t x -> uint8_t y[4]
  16. #define STORE32H(x, y) \
  17. do { (y)[0] = (uint8_t)(((x)>>24) & 0xff); (y)[1] = (uint8_t)(((x)>>16) & 0xff); \
  18. (y)[2] = (uint8_t)(((x)>>8) & 0xff); (y)[3] = (uint8_t)((x) & 0xff); } while(0)
  19. // 从uint32_t x中提取从低位开始的第n个字节
  20. #define BYTE(x, n) (((x) >> (8 * (n))) & 0xff)
  21. /* used for keyExpansion */
  22. // 字节替换然后循环左移1位
  23. #define MIX(x) (((S[BYTE(x, 2)] << 24) & 0xff000000) ^ ((S[BYTE(x, 1)] << 16) & 0xff0000) ^ \
  24. ((S[BYTE(x, 0)] << 8) & 0xff00) ^ (S[BYTE(x, 3)] & 0xff))
  25. // uint32_t x循环左移n位
  26. #define ROF32(x, n) (((x) << (n)) | ((x) >> (32-(n))))
  27. // uint32_t x循环右移n位
  28. #define ROR32(x, n) (((x) >> (n)) | ((x) << (32-(n))))
  29. /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
  30. // AES-128轮常量
  31. static const uint32_t rcon[10] = {
  32. 0x01000000UL, 0x02000000UL, 0x04000000UL, 0x08000000UL, 0x10000000UL,
  33. 0x20000000UL, 0x40000000UL, 0x80000000UL, 0x1B000000UL, 0x36000000UL
  34. };
  35. // S盒
  36. unsigned char S[256] = {
  37. 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
  38. 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
  39. 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
  40. 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
  41. 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
  42. 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
  43. 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
  44. 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
  45. 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
  46. 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
  47. 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
  48. 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
  49. 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
  50. 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
  51. 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
  52. 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
  53. };
  54. //逆S盒
  55. unsigned char inv_S[256] = {
  56. 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
  57. 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
  58. 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
  59. 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
  60. 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
  61. 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
  62. 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
  63. 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
  64. 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
  65. 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
  66. 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
  67. 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
  68. 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
  69. 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
  70. 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
  71. 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
  72. };
  73. /* copy in[16] to state[4][4] */
  74. int loadStateArray(uint8_t (*state)[4], const uint8_t *in) {
  75. int i=0,j=0;
  76. for (i = 0; i < 4; ++i) {
  77. for (j = 0; j < 4; ++j) {
  78. state[j][i] = *in++;
  79. }
  80. }
  81. return 0;
  82. }
  83. /* copy state[4][4] to out[16] */
  84. int storeStateArray(uint8_t (*state)[4], uint8_t *out) {
  85. int i=0,j=0;
  86. for (i = 0; i < 4; ++i) {
  87. for (j = 0; j < 4; ++j) {
  88. *out++ = state[j][i];
  89. }
  90. }
  91. return 0;
  92. }
  93. //秘钥扩展
  94. int keyExpansion(const uint8_t *key, uint32_t keyLen, AesKey *aesKey) {
  95. uint32_t *w = aesKey->eK; //加密秘钥
  96. uint32_t *v = aesKey->dK; //解密秘钥
  97. int i=0,j=0;
  98. if (NULL == key || NULL == aesKey){
  99. AP_interface->ol_print("keyExpansion param is NULL\n");
  100. return -1;
  101. }
  102. if (keyLen != 16){
  103. AP_interface->ol_print("keyExpansion keyLen = %d, Not support.\n", keyLen);
  104. return -1;
  105. }
  106. /* keyLen is 16 Bytes, generate uint32_t W[44]. */
  107. /* W[0-3] */
  108. for (i = 0; i < 4; ++i) {
  109. LOAD32H(w[i], key + 4*i);
  110. }
  111. /* W[4-43] */
  112. for (i = 0; i < 10; ++i) {
  113. w[4] = w[0] ^ MIX(w[3]) ^ rcon[i];
  114. w[5] = w[1] ^ w[4];
  115. w[6] = w[2] ^ w[5];
  116. w[7] = w[3] ^ w[6];
  117. w += 4;
  118. }
  119. w = aesKey->eK+44 - 4;
  120. //解密秘钥矩阵为加密秘钥矩阵的倒序,方便使用,把ek的11个矩阵倒序排列分配给dk作为解密秘钥
  121. //即dk[0-3]=ek[41-44], dk[4-7]=ek[37-40]... dk[41-44]=ek[0-3]
  122. for (j = 0; j < 11; ++j) {
  123. for (i = 0; i < 4; ++i) {
  124. v[i] = w[i];
  125. }
  126. w -= 4;
  127. v += 4;
  128. }
  129. return 0;
  130. }
  131. // 轮秘钥加
  132. int addRoundKey(uint8_t (*state)[4], const uint32_t *key) {
  133. uint8_t k[4][4];
  134. int i=0,j=0;
  135. /* i: row, j: col */
  136. for (i = 0; i < 4; ++i) {
  137. for (j = 0; j < 4; ++j) {
  138. k[i][j] = (uint8_t) BYTE(key[j], 3 - i); /* 把 uint32 key[4] 先转换为矩阵 uint8 k[4][4] */
  139. state[i][j] ^= k[i][j];
  140. }
  141. }
  142. return 0;
  143. }
  144. //字节替换
  145. int subBytes(uint8_t (*state)[4]) {
  146. /* i: row, j: col */
  147. int i=0,j=0;
  148. for (i = 0; i < 4; ++i) {
  149. for (j = 0; j < 4; ++j) {
  150. state[i][j] = S[state[i][j]]; //直接使用原始字节作为S盒数据下标
  151. }
  152. }
  153. return 0;
  154. }
  155. //逆字节替换
  156. int invSubBytes(uint8_t (*state)[4]) {
  157. /* i: row, j: col */
  158. int i=0,j=0;
  159. for (i = 0; i < 4; ++i) {
  160. for (j = 0; j < 4; ++j) {
  161. state[i][j] = inv_S[state[i][j]];
  162. }
  163. }
  164. return 0;
  165. }
  166. //行移位
  167. int shiftRows(uint8_t (*state)[4]) {
  168. uint32_t block[4] = {0};
  169. int i=0,j=0;
  170. /* i: row */
  171. for (i = 0; i < 4; ++i) {
  172. //便于行循环移位,先把一行4字节拼成uint_32结构,移位后再转成独立的4个字节uint8_t
  173. LOAD32H(block[i], state[i]);
  174. block[i] = ROF32(block[i], 8*i);
  175. STORE32H(block[i], state[i]);
  176. }
  177. return 0;
  178. }
  179. //逆行移位
  180. int invShiftRows(uint8_t (*state)[4]) {
  181. uint32_t block[4] = {0};
  182. int i=0,j=0;
  183. /* i: row */
  184. for (i = 0; i < 4; ++i) {
  185. LOAD32H(block[i], state[i]);
  186. block[i] = ROR32(block[i], 8*i);
  187. STORE32H(block[i], state[i]);
  188. }
  189. return 0;
  190. }
  191. /* Galois Field (256) Multiplication of two Bytes */
  192. // 两字节的伽罗华域乘法运算
  193. uint8_t GMul(uint8_t u, uint8_t v) {
  194. uint8_t p = 0;
  195. int i=0,j=0,flag = 0;
  196. for (i = 0; i < 8; ++i) {
  197. if (u & 0x01) { //
  198. p ^= v;
  199. }
  200. flag = (v & 0x80);
  201. v <<= 1;
  202. if (flag) {
  203. v ^= 0x1B; /* x^8 + x^4 + x^3 + x + 1 */
  204. }
  205. u >>= 1;
  206. }
  207. return p;
  208. }
  209. // 列混合
  210. int mixColumns(uint8_t (*state)[4]) {
  211. uint8_t tmp[4][4];
  212. uint8_t M[4][4] = {{0x02, 0x03, 0x01, 0x01},
  213. {0x01, 0x02, 0x03, 0x01},
  214. {0x01, 0x01, 0x02, 0x03},
  215. {0x03, 0x01, 0x01, 0x02}};
  216. int i=0,j=0;
  217. /* copy state[4][4] to tmp[4][4] */
  218. for (i = 0; i < 4; ++i) {
  219. for (j = 0; j < 4; ++j){
  220. tmp[i][j] = state[i][j];
  221. }
  222. }
  223. for (i = 0; i < 4; ++i) {
  224. for (j = 0; j < 4; ++j) { //伽罗华域加法和乘法
  225. state[i][j] = GMul(M[i][0], tmp[0][j]) ^ GMul(M[i][1], tmp[1][j])
  226. ^ GMul(M[i][2], tmp[2][j]) ^ GMul(M[i][3], tmp[3][j]);
  227. }
  228. }
  229. return 0;
  230. }
  231. // 逆列混合
  232. int invMixColumns(uint8_t (*state)[4]) {
  233. uint8_t tmp[4][4];
  234. uint8_t M[4][4] = {{0x0E, 0x0B, 0x0D, 0x09},
  235. {0x09, 0x0E, 0x0B, 0x0D},
  236. {0x0D, 0x09, 0x0E, 0x0B},
  237. {0x0B, 0x0D, 0x09, 0x0E}}; //使用列混合矩阵的逆矩阵
  238. int i=0,j=0;
  239. /* copy state[4][4] to tmp[4][4] */
  240. for (i = 0; i < 4; ++i) {
  241. for (j = 0; j < 4; ++j){
  242. tmp[i][j] = state[i][j];
  243. }
  244. }
  245. for (i = 0; i < 4; ++i) {
  246. for (j = 0; j < 4; ++j) {
  247. state[i][j] = GMul(M[i][0], tmp[0][j]) ^ GMul(M[i][1], tmp[1][j])
  248. ^ GMul(M[i][2], tmp[2][j]) ^ GMul(M[i][3], tmp[3][j]);
  249. }
  250. }
  251. return 0;
  252. }

2、加密方法

  1. // AES-128加密接口,输入key应为16字节长度,输入长度应该是16字节整倍数,
  2. // 这样输出长度与输入长度相同,函数调用外部为输出数据分配内存
  3. int aesEncrypt(const uint8_t *key, uint32_t keyLen, const uint8_t *pt, uint8_t *ct, uint32_t len) {
  4. AesKey aesKey;
  5. uint8_t *pos = ct;
  6. const uint32_t *rk = aesKey.eK; //解密秘钥指针
  7. uint8_t out[BLOCKSIZE] = {0};
  8. uint8_t actualKey[16] = {0};
  9. uint8_t state[4][4] = {0};
  10. int i=0,j=0;
  11. if (NULL == key || NULL == pt || NULL == ct){
  12. AP_interface->ol_print("param err.\n");
  13. return -1;
  14. }
  15. if (keyLen > 16){
  16. AP_interface->ol_print("keyLen must be 16.\n");
  17. return -1;
  18. }
  19. if (len % BLOCKSIZE){
  20. AP_interface->ol_print("inLen is invalid.\n");
  21. return -1;
  22. }
  23. memcpy(actualKey, key, keyLen);
  24. keyExpansion(actualKey, 16, &aesKey); // 秘钥扩展
  25. // 使用ECB模式循环加密多个分组长度的数据
  26. for (i = 0; i < len; i += BLOCKSIZE) {
  27. // 把16字节的明文转换为4x4状态矩阵来进行处理
  28. loadStateArray(state, pt);
  29. // 轮秘钥加
  30. addRoundKey(state, rk);
  31. for (j = 1; j < 10; ++j) {
  32. rk += 4;
  33. subBytes(state); // 字节替换
  34. shiftRows(state); // 行移位
  35. mixColumns(state); // 列混合
  36. addRoundKey(state, rk); // 轮秘钥加
  37. }
  38. subBytes(state); // 字节替换
  39. shiftRows(state); // 行移位
  40. // 此处不进行列混合
  41. addRoundKey(state, rk+4); // 轮秘钥加
  42. // 把4x4状态矩阵转换为uint8_t一维数组输出保存
  43. storeStateArray(state, pos);
  44. pos += BLOCKSIZE; // 加密数据内存指针移动到下一个分组
  45. pt += BLOCKSIZE; // 明文数据指针移动到下一个分组
  46. rk = aesKey.eK; // 恢复rk指针到秘钥初始位置
  47. }
  48. return 0;
  49. }


3、解密方法

  1. // AES128解密, 参数要求同加密
  2. int aesDecrypt(const uint8_t *key, uint32_t keyLen, const uint8_t *ct, uint8_t *pt, uint32_t len) {
  3. AesKey aesKey;
  4. uint8_t *pos = pt;
  5. const uint32_t *rk = aesKey.dK; //解密秘钥指针
  6. uint8_t out[BLOCKSIZE] = {0};
  7. uint8_t actualKey[16] = {0};
  8. uint8_t state[4][4] = {0};
  9. int i=0,j=0;
  10. if (NULL == key || NULL == ct || NULL == pt){
  11. AP_interface->ol_print("param err.\n");
  12. return -1;
  13. }
  14. if (keyLen > 16){
  15. AP_interface->ol_print("keyLen must be 16.\n");
  16. return -1;
  17. }
  18. if (len % BLOCKSIZE){
  19. AP_interface->ol_print("inLen is invalid.\n");
  20. return -1;
  21. }
  22. memcpy(actualKey, key, keyLen);
  23. keyExpansion(actualKey, 16, &aesKey); //秘钥扩展,同加密
  24. for (i = 0; i < len; i += BLOCKSIZE) {
  25. // 把16字节的密文转换为4x4状态矩阵来进行处理
  26. loadStateArray(state, ct);
  27. // 轮秘钥加,同加密
  28. addRoundKey(state, rk);
  29. for (j = 1; j < 10; ++j) {
  30. rk += 4;
  31. invShiftRows(state); // 逆行移位
  32. invSubBytes(state); // 逆字节替换,这两步顺序可以颠倒
  33. addRoundKey(state, rk); // 轮秘钥加,同加密
  34. invMixColumns(state); // 逆列混合
  35. }
  36. invSubBytes(state); // 逆字节替换
  37. invShiftRows(state); // 逆行移位
  38. // 此处没有逆列混合
  39. addRoundKey(state, rk+4); // 轮秘钥加,同加密
  40. storeStateArray(state, pos); // 保存明文数据
  41. pos += BLOCKSIZE; // 输出数据内存指针移位分组长度
  42. ct += BLOCKSIZE; // 输入数据内存指针移位分组长度
  43. rk = aesKey.dK; // 恢复rk指针到秘钥初始位置
  44. }
  45. return 0;
  46. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/51807
推荐阅读
相关标签
  

闽ICP备14008679号