rijndael.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. /**************************************************************************
  2. * This code is based on Szymon Stefanek AES implementation: *
  3. * http://www.esat.kuleuven.ac.be/~rijmen/rijndael/rijndael-cpplib.tar.gz *
  4. * *
  5. * Dynamic tables generation is based on the Brian Gladman work: *
  6. * http://fp.gladman.plus.com/cryptography_technology/rijndael *
  7. **************************************************************************/
  8. #include "rar.hpp"
  9. const int uKeyLenInBytes=16, m_uRounds=10;
  10. static byte S[256],S5[256],rcon[30];
  11. static byte T1[256][4],T2[256][4],T3[256][4],T4[256][4];
  12. static byte T5[256][4],T6[256][4],T7[256][4],T8[256][4];
  13. static byte U1[256][4],U2[256][4],U3[256][4],U4[256][4];
  14. inline void Xor128(byte *dest,const byte *arg1,const byte *arg2)
  15. {
  16. #if defined(PRESENT_INT32) && defined(ALLOW_NOT_ALIGNED_INT)
  17. ((uint32*)dest)[0]=((uint32*)arg1)[0]^((uint32*)arg2)[0];
  18. ((uint32*)dest)[1]=((uint32*)arg1)[1]^((uint32*)arg2)[1];
  19. ((uint32*)dest)[2]=((uint32*)arg1)[2]^((uint32*)arg2)[2];
  20. ((uint32*)dest)[3]=((uint32*)arg1)[3]^((uint32*)arg2)[3];
  21. #else
  22. for (int I=0;I<16;I++)
  23. dest[I]=arg1[I]^arg2[I];
  24. #endif
  25. }
  26. inline void Xor128(byte *dest,const byte *arg1,const byte *arg2,
  27. const byte *arg3,const byte *arg4)
  28. {
  29. #if defined(PRESENT_INT32) && defined(ALLOW_NOT_ALIGNED_INT)
  30. (*(uint32*)dest)=(*(uint32*)arg1)^(*(uint32*)arg2)^(*(uint32*)arg3)^(*(uint32*)arg4);
  31. #else
  32. for (int I=0;I<4;I++)
  33. dest[I]=arg1[I]^arg2[I]^arg3[I]^arg4[I];
  34. #endif
  35. }
  36. inline void Copy128(byte *dest,const byte *src)
  37. {
  38. #if defined(PRESENT_INT32) && defined(ALLOW_NOT_ALIGNED_INT)
  39. ((uint32*)dest)[0]=((uint32*)src)[0];
  40. ((uint32*)dest)[1]=((uint32*)src)[1];
  41. ((uint32*)dest)[2]=((uint32*)src)[2];
  42. ((uint32*)dest)[3]=((uint32*)src)[3];
  43. #else
  44. for (int I=0;I<16;I++)
  45. dest[I]=src[I];
  46. #endif
  47. }
  48. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  49. // API
  50. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  51. Rijndael::Rijndael()
  52. {
  53. if (S[0]==0)
  54. GenerateTables();
  55. }
  56. void Rijndael::init(Direction dir,const byte * key,byte * initVector)
  57. {
  58. m_direction = dir;
  59. byte keyMatrix[_MAX_KEY_COLUMNS][4];
  60. for(uint i = 0;i < uKeyLenInBytes;i++)
  61. keyMatrix[i >> 2][i & 3] = key[i];
  62. for(int i = 0;i < MAX_IV_SIZE;i++)
  63. m_initVector[i] = initVector[i];
  64. keySched(keyMatrix);
  65. if(m_direction == Decrypt)
  66. keyEncToDec();
  67. }
  68. size_t Rijndael::blockDecrypt(const byte *input, size_t inputLen, byte *outBuffer)
  69. {
  70. if (input == 0 || inputLen <= 0)
  71. return 0;
  72. byte block[16], iv[4][4];
  73. memcpy(iv,m_initVector,16);
  74. size_t numBlocks=inputLen/16;
  75. for (size_t i = numBlocks; i > 0; i--)
  76. {
  77. decrypt(input, block);
  78. Xor128(block,block,(byte*)iv);
  79. #if STRICT_ALIGN
  80. memcpy(iv, input, 16);
  81. memcpy(outBuf, block, 16);
  82. #else
  83. Copy128((byte*)iv,input);
  84. Copy128(outBuffer,block);
  85. #endif
  86. input += 16;
  87. outBuffer += 16;
  88. }
  89. memcpy(m_initVector,iv,16);
  90. return 16*numBlocks;
  91. }
  92. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  93. // ALGORITHM
  94. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  95. void Rijndael::keySched(byte key[_MAX_KEY_COLUMNS][4])
  96. {
  97. int j,rconpointer = 0;
  98. // Calculate the necessary round keys
  99. // The number of calculations depends on keyBits and blockBits
  100. int uKeyColumns = m_uRounds - 6;
  101. byte tempKey[_MAX_KEY_COLUMNS][4];
  102. // Copy the input key to the temporary key matrix
  103. memcpy(tempKey,key,sizeof(tempKey));
  104. int r = 0;
  105. int t = 0;
  106. // copy values into round key array
  107. for(j = 0;(j < uKeyColumns) && (r <= m_uRounds); )
  108. {
  109. for(;(j < uKeyColumns) && (t < 4); j++, t++)
  110. for (int k=0;k<4;k++)
  111. m_expandedKey[r][t][k]=tempKey[j][k];
  112. if(t == 4)
  113. {
  114. r++;
  115. t = 0;
  116. }
  117. }
  118. while(r <= m_uRounds)
  119. {
  120. tempKey[0][0] ^= S[tempKey[uKeyColumns-1][1]];
  121. tempKey[0][1] ^= S[tempKey[uKeyColumns-1][2]];
  122. tempKey[0][2] ^= S[tempKey[uKeyColumns-1][3]];
  123. tempKey[0][3] ^= S[tempKey[uKeyColumns-1][0]];
  124. tempKey[0][0] ^= rcon[rconpointer++];
  125. if (uKeyColumns != 8)
  126. for(j = 1; j < uKeyColumns; j++)
  127. for (int k=0;k<4;k++)
  128. tempKey[j][k] ^= tempKey[j-1][k];
  129. else
  130. {
  131. for(j = 1; j < uKeyColumns/2; j++)
  132. for (int k=0;k<4;k++)
  133. tempKey[j][k] ^= tempKey[j-1][k];
  134. tempKey[uKeyColumns/2][0] ^= S[tempKey[uKeyColumns/2 - 1][0]];
  135. tempKey[uKeyColumns/2][1] ^= S[tempKey[uKeyColumns/2 - 1][1]];
  136. tempKey[uKeyColumns/2][2] ^= S[tempKey[uKeyColumns/2 - 1][2]];
  137. tempKey[uKeyColumns/2][3] ^= S[tempKey[uKeyColumns/2 - 1][3]];
  138. for(j = uKeyColumns/2 + 1; j < uKeyColumns; j++)
  139. for (int k=0;k<4;k++)
  140. tempKey[j][k] ^= tempKey[j-1][k];
  141. }
  142. for(j = 0; (j < uKeyColumns) && (r <= m_uRounds); )
  143. {
  144. for(; (j < uKeyColumns) && (t < 4); j++, t++)
  145. for (int k=0;k<4;k++)
  146. m_expandedKey[r][t][k] = tempKey[j][k];
  147. if(t == 4)
  148. {
  149. r++;
  150. t = 0;
  151. }
  152. }
  153. }
  154. }
  155. void Rijndael::keyEncToDec()
  156. {
  157. for(int r = 1; r < m_uRounds; r++)
  158. {
  159. byte n_expandedKey[4][4];
  160. for (int i=0;i<4;i++)
  161. for (int j=0;j<4;j++)
  162. {
  163. byte *w=m_expandedKey[r][j];
  164. n_expandedKey[j][i]=U1[w[0]][i]^U2[w[1]][i]^U3[w[2]][i]^U4[w[3]][i];
  165. }
  166. memcpy(m_expandedKey[r],n_expandedKey,sizeof(m_expandedKey[0]));
  167. }
  168. }
  169. void Rijndael::decrypt(const byte a[16], byte b[16])
  170. {
  171. int r;
  172. byte temp[4][4];
  173. Xor128((byte*)temp,(byte*)a,(byte*)m_expandedKey[m_uRounds]);
  174. Xor128(b, T5[temp[0][0]],T6[temp[3][1]],T7[temp[2][2]],T8[temp[1][3]]);
  175. Xor128(b+4, T5[temp[1][0]],T6[temp[0][1]],T7[temp[3][2]],T8[temp[2][3]]);
  176. Xor128(b+8, T5[temp[2][0]],T6[temp[1][1]],T7[temp[0][2]],T8[temp[3][3]]);
  177. Xor128(b+12,T5[temp[3][0]],T6[temp[2][1]],T7[temp[1][2]],T8[temp[0][3]]);
  178. for(r = m_uRounds-1; r > 1; r--)
  179. {
  180. Xor128((byte*)temp,(byte*)b,(byte*)m_expandedKey[r]);
  181. Xor128(b, T5[temp[0][0]],T6[temp[3][1]],T7[temp[2][2]],T8[temp[1][3]]);
  182. Xor128(b+4, T5[temp[1][0]],T6[temp[0][1]],T7[temp[3][2]],T8[temp[2][3]]);
  183. Xor128(b+8, T5[temp[2][0]],T6[temp[1][1]],T7[temp[0][2]],T8[temp[3][3]]);
  184. Xor128(b+12,T5[temp[3][0]],T6[temp[2][1]],T7[temp[1][2]],T8[temp[0][3]]);
  185. }
  186. Xor128((byte*)temp,(byte*)b,(byte*)m_expandedKey[1]);
  187. b[ 0] = S5[temp[0][0]];
  188. b[ 1] = S5[temp[3][1]];
  189. b[ 2] = S5[temp[2][2]];
  190. b[ 3] = S5[temp[1][3]];
  191. b[ 4] = S5[temp[1][0]];
  192. b[ 5] = S5[temp[0][1]];
  193. b[ 6] = S5[temp[3][2]];
  194. b[ 7] = S5[temp[2][3]];
  195. b[ 8] = S5[temp[2][0]];
  196. b[ 9] = S5[temp[1][1]];
  197. b[10] = S5[temp[0][2]];
  198. b[11] = S5[temp[3][3]];
  199. b[12] = S5[temp[3][0]];
  200. b[13] = S5[temp[2][1]];
  201. b[14] = S5[temp[1][2]];
  202. b[15] = S5[temp[0][3]];
  203. Xor128((byte*)b,(byte*)b,(byte*)m_expandedKey[0]);
  204. }
  205. #define ff_poly 0x011b
  206. #define ff_hi 0x80
  207. #define FFinv(x) ((x) ? pow[255 - log[x]]: 0)
  208. #define FFmul02(x) (x ? pow[log[x] + 0x19] : 0)
  209. #define FFmul03(x) (x ? pow[log[x] + 0x01] : 0)
  210. #define FFmul09(x) (x ? pow[log[x] + 0xc7] : 0)
  211. #define FFmul0b(x) (x ? pow[log[x] + 0x68] : 0)
  212. #define FFmul0d(x) (x ? pow[log[x] + 0xee] : 0)
  213. #define FFmul0e(x) (x ? pow[log[x] + 0xdf] : 0)
  214. #define fwd_affine(x) \
  215. (w = (uint)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), (byte)(0x63^(w^(w>>8))))
  216. #define inv_affine(x) \
  217. (w = (uint)x, w = (w<<1)^(w<<3)^(w<<6), (byte)(0x05^(w^(w>>8))))
  218. void Rijndael::GenerateTables()
  219. {
  220. unsigned char pow[512],log[256];
  221. int i = 0, w = 1;
  222. do
  223. {
  224. pow[i] = (byte)w;
  225. pow[i + 255] = (byte)w;
  226. log[w] = (byte)i++;
  227. w ^= (w << 1) ^ (w & ff_hi ? ff_poly : 0);
  228. } while (w != 1);
  229. for (int i = 0,w = 1; i < sizeof(rcon)/sizeof(rcon[0]); i++)
  230. {
  231. rcon[i] = w;
  232. w = (w << 1) ^ (w & ff_hi ? ff_poly : 0);
  233. }
  234. for(int i = 0; i < 256; ++i)
  235. {
  236. unsigned char b=S[i]=fwd_affine(FFinv((byte)i));
  237. T1[i][1]=T1[i][2]=T2[i][2]=T2[i][3]=T3[i][0]=T3[i][3]=T4[i][0]=T4[i][1]=b;
  238. T1[i][0]=T2[i][1]=T3[i][2]=T4[i][3]=FFmul02(b);
  239. T1[i][3]=T2[i][0]=T3[i][1]=T4[i][2]=FFmul03(b);
  240. S5[i] = b = FFinv(inv_affine((byte)i));
  241. U1[b][3]=U2[b][0]=U3[b][1]=U4[b][2]=T5[i][3]=T6[i][0]=T7[i][1]=T8[i][2]=FFmul0b(b);
  242. U1[b][1]=U2[b][2]=U3[b][3]=U4[b][0]=T5[i][1]=T6[i][2]=T7[i][3]=T8[i][0]=FFmul09(b);
  243. U1[b][2]=U2[b][3]=U3[b][0]=U4[b][1]=T5[i][2]=T6[i][3]=T7[i][0]=T8[i][1]=FFmul0d(b);
  244. U1[b][0]=U2[b][1]=U3[b][2]=U4[b][3]=T5[i][0]=T6[i][1]=T7[i][2]=T8[i][3]=FFmul0e(b);
  245. }
  246. }