2
0

mvAesAlg.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. /* rijndael-alg-ref.c v2.0 August '99
  2. * Reference ANSI C code
  3. * authors: Paulo Barreto
  4. * Vincent Rijmen, K.U.Leuven
  5. *
  6. * This code is placed in the public domain.
  7. */
  8. #include "mvOs.h"
  9. #include "mvAesAlg.h"
  10. #include "mvAesBoxes.dat"
  11. MV_U8 mul1(MV_U8 aa, MV_U8 bb);
  12. void KeyAddition(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC], MV_U8 BC);
  13. void ShiftRow128Enc(MV_U8 a[4][MAXBC]);
  14. void ShiftRow128Dec(MV_U8 a[4][MAXBC]);
  15. void Substitution(MV_U8 a[4][MAXBC], MV_U8 box[256]);
  16. void MixColumn(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC]);
  17. void InvMixColumn(MV_U8 a[4][MAXBC]);
  18. #define mul(aa, bb) (mask[bb] & Alogtable[aa + Logtable[bb]])
  19. MV_U8 mul1(MV_U8 aa, MV_U8 bb)
  20. {
  21. return mask[bb] & Alogtable[aa + Logtable[bb]];
  22. }
  23. void KeyAddition(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC], MV_U8 BC)
  24. {
  25. /* Exor corresponding text input and round key input bytes
  26. */
  27. ((MV_U32*)(&(a[0][0])))[0] ^= ((MV_U32*)(&(rk[0][0])))[0];
  28. ((MV_U32*)(&(a[1][0])))[0] ^= ((MV_U32*)(&(rk[1][0])))[0];
  29. ((MV_U32*)(&(a[2][0])))[0] ^= ((MV_U32*)(&(rk[2][0])))[0];
  30. ((MV_U32*)(&(a[3][0])))[0] ^= ((MV_U32*)(&(rk[3][0])))[0];
  31. }
  32. void ShiftRow128Enc(MV_U8 a[4][MAXBC]) {
  33. /* Row 0 remains unchanged
  34. * The other three rows are shifted a variable amount
  35. */
  36. MV_U8 tmp[MAXBC];
  37. tmp[0] = a[1][1];
  38. tmp[1] = a[1][2];
  39. tmp[2] = a[1][3];
  40. tmp[3] = a[1][0];
  41. ((MV_U32*)(&(a[1][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  42. /*
  43. a[1][0] = tmp[0];
  44. a[1][1] = tmp[1];
  45. a[1][2] = tmp[2];
  46. a[1][3] = tmp[3];
  47. */
  48. tmp[0] = a[2][2];
  49. tmp[1] = a[2][3];
  50. tmp[2] = a[2][0];
  51. tmp[3] = a[2][1];
  52. ((MV_U32*)(&(a[2][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  53. /*
  54. a[2][0] = tmp[0];
  55. a[2][1] = tmp[1];
  56. a[2][2] = tmp[2];
  57. a[2][3] = tmp[3];
  58. */
  59. tmp[0] = a[3][3];
  60. tmp[1] = a[3][0];
  61. tmp[2] = a[3][1];
  62. tmp[3] = a[3][2];
  63. ((MV_U32*)(&(a[3][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  64. /*
  65. a[3][0] = tmp[0];
  66. a[3][1] = tmp[1];
  67. a[3][2] = tmp[2];
  68. a[3][3] = tmp[3];
  69. */
  70. }
  71. void ShiftRow128Dec(MV_U8 a[4][MAXBC]) {
  72. /* Row 0 remains unchanged
  73. * The other three rows are shifted a variable amount
  74. */
  75. MV_U8 tmp[MAXBC];
  76. tmp[0] = a[1][3];
  77. tmp[1] = a[1][0];
  78. tmp[2] = a[1][1];
  79. tmp[3] = a[1][2];
  80. ((MV_U32*)(&(a[1][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  81. /*
  82. a[1][0] = tmp[0];
  83. a[1][1] = tmp[1];
  84. a[1][2] = tmp[2];
  85. a[1][3] = tmp[3];
  86. */
  87. tmp[0] = a[2][2];
  88. tmp[1] = a[2][3];
  89. tmp[2] = a[2][0];
  90. tmp[3] = a[2][1];
  91. ((MV_U32*)(&(a[2][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  92. /*
  93. a[2][0] = tmp[0];
  94. a[2][1] = tmp[1];
  95. a[2][2] = tmp[2];
  96. a[2][3] = tmp[3];
  97. */
  98. tmp[0] = a[3][1];
  99. tmp[1] = a[3][2];
  100. tmp[2] = a[3][3];
  101. tmp[3] = a[3][0];
  102. ((MV_U32*)(&(a[3][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  103. /*
  104. a[3][0] = tmp[0];
  105. a[3][1] = tmp[1];
  106. a[3][2] = tmp[2];
  107. a[3][3] = tmp[3];
  108. */
  109. }
  110. void Substitution(MV_U8 a[4][MAXBC], MV_U8 box[256]) {
  111. /* Replace every byte of the input by the byte at that place
  112. * in the nonlinear S-box
  113. */
  114. int i, j;
  115. for(i = 0; i < 4; i++)
  116. for(j = 0; j < 4; j++) a[i][j] = box[a[i][j]] ;
  117. }
  118. void MixColumn(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC]) {
  119. /* Mix the four bytes of every column in a linear way
  120. */
  121. MV_U8 b[4][MAXBC];
  122. int i, j;
  123. for(j = 0; j < 4; j++){
  124. b[0][j] = mul(25,a[0][j]) ^ mul(1,a[1][j]) ^ a[2][j] ^ a[3][j];
  125. b[1][j] = mul(25,a[1][j]) ^ mul(1,a[2][j]) ^ a[3][j] ^ a[0][j];
  126. b[2][j] = mul(25,a[2][j]) ^ mul(1,a[3][j]) ^ a[0][j] ^ a[1][j];
  127. b[3][j] = mul(25,a[3][j]) ^ mul(1,a[0][j]) ^ a[1][j] ^ a[2][j];
  128. }
  129. for(i = 0; i < 4; i++)
  130. /*for(j = 0; j < BC; j++) a[i][j] = b[i][j];*/
  131. ((MV_U32*)(&(a[i][0])))[0] = ((MV_U32*)(&(b[i][0])))[0] ^ ((MV_U32*)(&(rk[i][0])))[0];;
  132. }
  133. void InvMixColumn(MV_U8 a[4][MAXBC]) {
  134. /* Mix the four bytes of every column in a linear way
  135. * This is the opposite operation of Mixcolumn
  136. */
  137. MV_U8 b[4][MAXBC];
  138. int i, j;
  139. for(j = 0; j < 4; j++){
  140. b[0][j] = mul(223,a[0][j]) ^ mul(104,a[1][j]) ^ mul(238,a[2][j]) ^ mul(199,a[3][j]);
  141. b[1][j] = mul(223,a[1][j]) ^ mul(104,a[2][j]) ^ mul(238,a[3][j]) ^ mul(199,a[0][j]);
  142. b[2][j] = mul(223,a[2][j]) ^ mul(104,a[3][j]) ^ mul(238,a[0][j]) ^ mul(199,a[1][j]);
  143. b[3][j] = mul(223,a[3][j]) ^ mul(104,a[0][j]) ^ mul(238,a[1][j]) ^ mul(199,a[2][j]);
  144. }
  145. for(i = 0; i < 4; i++)
  146. /*for(j = 0; j < BC; j++) a[i][j] = b[i][j];*/
  147. ((MV_U32*)(&(a[i][0])))[0] = ((MV_U32*)(&(b[i][0])))[0];
  148. }
  149. int rijndaelKeySched (MV_U8 k[4][MAXKC], int keyBits, int blockBits, MV_U8 W[MAXROUNDS+1][4][MAXBC])
  150. {
  151. /* Calculate the necessary round keys
  152. * The number of calculations depends on keyBits and blockBits
  153. */
  154. int KC, BC, ROUNDS;
  155. int i, j, t, rconpointer = 0;
  156. MV_U8 tk[4][MAXKC];
  157. switch (keyBits) {
  158. case 128: KC = 4; break;
  159. case 192: KC = 6; break;
  160. case 256: KC = 8; break;
  161. default : return (-1);
  162. }
  163. switch (blockBits) {
  164. case 128: BC = 4; break;
  165. case 192: BC = 6; break;
  166. case 256: BC = 8; break;
  167. default : return (-2);
  168. }
  169. switch (keyBits >= blockBits ? keyBits : blockBits) {
  170. case 128: ROUNDS = 10; break;
  171. case 192: ROUNDS = 12; break;
  172. case 256: ROUNDS = 14; break;
  173. default : return (-3); /* this cannot happen */
  174. }
  175. for(j = 0; j < KC; j++)
  176. for(i = 0; i < 4; i++)
  177. tk[i][j] = k[i][j];
  178. t = 0;
  179. /* copy values into round key array */
  180. for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)
  181. for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j];
  182. while (t < (ROUNDS+1)*BC) { /* while not enough round key material calculated */
  183. /* calculate new values */
  184. for(i = 0; i < 4; i++)
  185. tk[i][0] ^= S[tk[(i+1)%4][KC-1]];
  186. tk[0][0] ^= rcon[rconpointer++];
  187. if (KC != 8)
  188. for(j = 1; j < KC; j++)
  189. for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
  190. else {
  191. for(j = 1; j < KC/2; j++)
  192. for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
  193. for(i = 0; i < 4; i++) tk[i][KC/2] ^= S[tk[i][KC/2 - 1]];
  194. for(j = KC/2 + 1; j < KC; j++)
  195. for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
  196. }
  197. /* copy values into round key array */
  198. for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)
  199. for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j];
  200. }
  201. return 0;
  202. }
  203. int rijndaelEncrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds)
  204. {
  205. /* Encryption of one block.
  206. */
  207. int r, BC, ROUNDS;
  208. BC = 4;
  209. ROUNDS = rounds;
  210. /* begin with a key addition
  211. */
  212. KeyAddition(a,rk[0],BC);
  213. /* ROUNDS-1 ordinary rounds
  214. */
  215. for(r = 1; r < ROUNDS; r++) {
  216. Substitution(a,S);
  217. ShiftRow128Enc(a);
  218. MixColumn(a, rk[r]);
  219. /*KeyAddition(a,rk[r],BC);*/
  220. }
  221. /* Last round is special: there is no MixColumn
  222. */
  223. Substitution(a,S);
  224. ShiftRow128Enc(a);
  225. KeyAddition(a,rk[ROUNDS],BC);
  226. return 0;
  227. }
  228. int rijndaelDecrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds)
  229. {
  230. int r, BC, ROUNDS;
  231. BC = 4;
  232. ROUNDS = rounds;
  233. /* To decrypt: apply the inverse operations of the encrypt routine,
  234. * in opposite order
  235. *
  236. * (KeyAddition is an involution: it 's equal to its inverse)
  237. * (the inverse of Substitution with table S is Substitution with the inverse table of S)
  238. * (the inverse of Shiftrow is Shiftrow over a suitable distance)
  239. */
  240. /* First the special round:
  241. * without InvMixColumn
  242. * with extra KeyAddition
  243. */
  244. KeyAddition(a,rk[ROUNDS],BC);
  245. ShiftRow128Dec(a);
  246. Substitution(a,Si);
  247. /* ROUNDS-1 ordinary rounds
  248. */
  249. for(r = ROUNDS-1; r > 0; r--) {
  250. KeyAddition(a,rk[r],BC);
  251. InvMixColumn(a);
  252. ShiftRow128Dec(a);
  253. Substitution(a,Si);
  254. }
  255. /* End with the extra key addition
  256. */
  257. KeyAddition(a,rk[0],BC);
  258. return 0;
  259. }