Cast6Engine.cs 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. using System;
  3. using Org.BouncyCastle.Crypto.Utilities;
  4. namespace Org.BouncyCastle.Crypto.Engines
  5. {
  6. /**
  7. * A class that provides CAST6 key encryption operations,
  8. * such as encoding data and generating keys.
  9. *
  10. * All the algorithms herein are from the Internet RFC
  11. *
  12. * RFC2612 - CAST6 (128bit block, 128-256bit key)
  13. *
  14. * and implement a simplified cryptography interface.
  15. */
  16. public sealed class Cast6Engine
  17. : Cast5Engine
  18. {
  19. //====================================
  20. // Useful constants
  21. //====================================
  22. private const int ROUNDS = 12;
  23. private const int BLOCK_SIZE = 16; // bytes = 128 bits
  24. /*
  25. * Put the round and mask keys into an array.
  26. * Kr0[i] => _Kr[i*4 + 0]
  27. */
  28. private int []_Kr = new int[ROUNDS*4]; // the rotating round key(s)
  29. private uint []_Km = new uint[ROUNDS*4]; // the masking round key(s)
  30. /*
  31. * Key setup
  32. */
  33. private int []_Tr = new int[24 * 8];
  34. private uint []_Tm = new uint[24 * 8];
  35. private uint[] _workingKey = new uint[8];
  36. public Cast6Engine()
  37. {
  38. }
  39. public override string AlgorithmName
  40. {
  41. get { return "CAST6"; }
  42. }
  43. public override void Reset()
  44. {
  45. }
  46. public override int GetBlockSize()
  47. {
  48. return BLOCK_SIZE;
  49. }
  50. //==================================
  51. // Private Implementation
  52. //==================================
  53. /*
  54. * Creates the subkeys using the same nomenclature
  55. * as described in RFC2612.
  56. *
  57. * See section 2.4
  58. */
  59. internal override void SetKey(
  60. byte[] key)
  61. {
  62. uint Cm = 0x5a827999;
  63. uint Mm = 0x6ed9eba1;
  64. int Cr = 19;
  65. int Mr = 17;
  66. /*
  67. * Determine the key size here, if required
  68. *
  69. * if keysize < 256 bytes, pad with 0
  70. *
  71. * Typical key sizes => 128, 160, 192, 224, 256
  72. */
  73. for (int i=0; i< 24; i++)
  74. {
  75. for (int j=0; j< 8; j++)
  76. {
  77. _Tm[i*8 + j] = Cm;
  78. Cm += Mm; //mod 2^32;
  79. _Tr[i*8 + j] = Cr;
  80. Cr = (Cr + Mr) & 0x1f; // mod 32
  81. }
  82. }
  83. byte[] tmpKey = new byte[64];
  84. key.CopyTo(tmpKey, 0);
  85. // now create ABCDEFGH
  86. for (int i = 0; i < 8; i++)
  87. {
  88. _workingKey[i] = Pack.BE_To_UInt32(tmpKey, i*4);
  89. }
  90. // Generate the key schedule
  91. for (int i = 0; i < 12; i++)
  92. {
  93. // KAPPA <- W2i(KAPPA)
  94. int i2 = i*2 *8;
  95. _workingKey[6] ^= F1(_workingKey[7], _Tm[i2], _Tr[i2]);
  96. _workingKey[5] ^= F2(_workingKey[6], _Tm[i2+1], _Tr[i2+1]);
  97. _workingKey[4] ^= F3(_workingKey[5], _Tm[i2+2], _Tr[i2+2]);
  98. _workingKey[3] ^= F1(_workingKey[4], _Tm[i2+3], _Tr[i2+3]);
  99. _workingKey[2] ^= F2(_workingKey[3], _Tm[i2+4], _Tr[i2+4]);
  100. _workingKey[1] ^= F3(_workingKey[2], _Tm[i2+5], _Tr[i2+5]);
  101. _workingKey[0] ^= F1(_workingKey[1], _Tm[i2+6], _Tr[i2+6]);
  102. _workingKey[7] ^= F2(_workingKey[0], _Tm[i2+7], _Tr[i2+7]);
  103. // KAPPA <- W2i+1(KAPPA)
  104. i2 = (i*2 + 1)*8;
  105. _workingKey[6] ^= F1(_workingKey[7], _Tm[i2], _Tr[i2]);
  106. _workingKey[5] ^= F2(_workingKey[6], _Tm[i2+1], _Tr[i2+1]);
  107. _workingKey[4] ^= F3(_workingKey[5], _Tm[i2+2], _Tr[i2+2]);
  108. _workingKey[3] ^= F1(_workingKey[4], _Tm[i2+3], _Tr[i2+3]);
  109. _workingKey[2] ^= F2(_workingKey[3], _Tm[i2+4], _Tr[i2+4]);
  110. _workingKey[1] ^= F3(_workingKey[2], _Tm[i2+5], _Tr[i2+5]);
  111. _workingKey[0] ^= F1(_workingKey[1], _Tm[i2+6], _Tr[i2+6]);
  112. _workingKey[7] ^= F2(_workingKey[0], _Tm[i2+7], _Tr[i2+7]);
  113. // Kr_(i) <- KAPPA
  114. _Kr[i*4] = (int)(_workingKey[0] & 0x1f);
  115. _Kr[i*4 + 1] = (int)(_workingKey[2] & 0x1f);
  116. _Kr[i*4 + 2] = (int)(_workingKey[4] & 0x1f);
  117. _Kr[i*4 + 3] = (int)(_workingKey[6] & 0x1f);
  118. // Km_(i) <- KAPPA
  119. _Km[i*4] = _workingKey[7];
  120. _Km[i*4 + 1] = _workingKey[5];
  121. _Km[i*4 + 2] = _workingKey[3];
  122. _Km[i*4 + 3] = _workingKey[1];
  123. }
  124. }
  125. /**
  126. * Encrypt the given input starting at the given offset and place
  127. * the result in the provided buffer starting at the given offset.
  128. *
  129. * @param src The plaintext buffer
  130. * @param srcIndex An offset into src
  131. * @param dst The ciphertext buffer
  132. * @param dstIndex An offset into dst
  133. */
  134. internal override int EncryptBlock(
  135. byte[] src,
  136. int srcIndex,
  137. byte[] dst,
  138. int dstIndex)
  139. {
  140. // process the input block
  141. // batch the units up into 4x32 bit chunks and go for it
  142. uint A = Pack.BE_To_UInt32(src, srcIndex);
  143. uint B = Pack.BE_To_UInt32(src, srcIndex + 4);
  144. uint C = Pack.BE_To_UInt32(src, srcIndex + 8);
  145. uint D = Pack.BE_To_UInt32(src, srcIndex + 12);
  146. uint[] result = new uint[4];
  147. CAST_Encipher(A, B, C, D, result);
  148. // now stuff them into the destination block
  149. Pack.UInt32_To_BE(result[0], dst, dstIndex);
  150. Pack.UInt32_To_BE(result[1], dst, dstIndex + 4);
  151. Pack.UInt32_To_BE(result[2], dst, dstIndex + 8);
  152. Pack.UInt32_To_BE(result[3], dst, dstIndex + 12);
  153. return BLOCK_SIZE;
  154. }
  155. /**
  156. * Decrypt the given input starting at the given offset and place
  157. * the result in the provided buffer starting at the given offset.
  158. *
  159. * @param src The plaintext buffer
  160. * @param srcIndex An offset into src
  161. * @param dst The ciphertext buffer
  162. * @param dstIndex An offset into dst
  163. */
  164. internal override int DecryptBlock(
  165. byte[] src,
  166. int srcIndex,
  167. byte[] dst,
  168. int dstIndex)
  169. {
  170. // process the input block
  171. // batch the units up into 4x32 bit chunks and go for it
  172. uint A = Pack.BE_To_UInt32(src, srcIndex);
  173. uint B = Pack.BE_To_UInt32(src, srcIndex + 4);
  174. uint C = Pack.BE_To_UInt32(src, srcIndex + 8);
  175. uint D = Pack.BE_To_UInt32(src, srcIndex + 12);
  176. uint[] result = new uint[4];
  177. CAST_Decipher(A, B, C, D, result);
  178. // now stuff them into the destination block
  179. Pack.UInt32_To_BE(result[0], dst, dstIndex);
  180. Pack.UInt32_To_BE(result[1], dst, dstIndex + 4);
  181. Pack.UInt32_To_BE(result[2], dst, dstIndex + 8);
  182. Pack.UInt32_To_BE(result[3], dst, dstIndex + 12);
  183. return BLOCK_SIZE;
  184. }
  185. /**
  186. * Does the 12 quad rounds rounds to encrypt the block.
  187. *
  188. * @param A the 00-31 bits of the plaintext block
  189. * @param B the 32-63 bits of the plaintext block
  190. * @param C the 64-95 bits of the plaintext block
  191. * @param D the 96-127 bits of the plaintext block
  192. * @param result the resulting ciphertext
  193. */
  194. private void CAST_Encipher(
  195. uint A,
  196. uint B,
  197. uint C,
  198. uint D,
  199. uint[] result)
  200. {
  201. for (int i = 0; i < 6; i++)
  202. {
  203. int x = i*4;
  204. // BETA <- Qi(BETA)
  205. C ^= F1(D, _Km[x], _Kr[x]);
  206. B ^= F2(C, _Km[x + 1], _Kr[x + 1]);
  207. A ^= F3(B, _Km[x + 2], _Kr[x + 2]);
  208. D ^= F1(A, _Km[x + 3], _Kr[x + 3]);
  209. }
  210. for (int i = 6; i < 12; i++)
  211. {
  212. int x = i*4;
  213. // BETA <- QBARi(BETA)
  214. D ^= F1(A, _Km[x + 3], _Kr[x + 3]);
  215. A ^= F3(B, _Km[x + 2], _Kr[x + 2]);
  216. B ^= F2(C, _Km[x + 1], _Kr[x + 1]);
  217. C ^= F1(D, _Km[x], _Kr[x]);
  218. }
  219. result[0] = A;
  220. result[1] = B;
  221. result[2] = C;
  222. result[3] = D;
  223. }
  224. /**
  225. * Does the 12 quad rounds rounds to decrypt the block.
  226. *
  227. * @param A the 00-31 bits of the ciphertext block
  228. * @param B the 32-63 bits of the ciphertext block
  229. * @param C the 64-95 bits of the ciphertext block
  230. * @param D the 96-127 bits of the ciphertext block
  231. * @param result the resulting plaintext
  232. */
  233. private void CAST_Decipher(
  234. uint A,
  235. uint B,
  236. uint C,
  237. uint D,
  238. uint[] result)
  239. {
  240. for (int i = 0; i < 6; i++)
  241. {
  242. int x = (11-i)*4;
  243. // BETA <- Qi(BETA)
  244. C ^= F1(D, _Km[x], _Kr[x]);
  245. B ^= F2(C, _Km[x + 1], _Kr[x + 1]);
  246. A ^= F3(B, _Km[x + 2], _Kr[x + 2]);
  247. D ^= F1(A, _Km[x + 3], _Kr[x + 3]);
  248. }
  249. for (int i=6; i<12; i++)
  250. {
  251. int x = (11-i)*4;
  252. // BETA <- QBARi(BETA)
  253. D ^= F1(A, _Km[x + 3], _Kr[x + 3]);
  254. A ^= F3(B, _Km[x + 2], _Kr[x + 2]);
  255. B ^= F2(C, _Km[x + 1], _Kr[x + 1]);
  256. C ^= F1(D, _Km[x], _Kr[x]);
  257. }
  258. result[0] = A;
  259. result[1] = B;
  260. result[2] = C;
  261. result[3] = D;
  262. }
  263. }
  264. }
  265. #endif