Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

392 lines
7.3 KiB

  1. //========= Public Domain Code ================================================
  2. //
  3. // Purpose: C++ implementation of the ICE encryption algorithm.
  4. // Taken from public domain code, as written by Matthew Kwan - July 1996
  5. // http://www.darkside.com.au/ice/
  6. //=============================================================================
  7. #include "IceKey.H"
  8. #pragma warning(disable: 4244)
  9. /* Structure of a single round subkey */
  10. class IceSubkey {
  11. public:
  12. unsigned long val[3];
  13. };
  14. /* The S-boxes */
  15. static unsigned long ice_sbox[4][1024];
  16. static int ice_sboxes_initialised = 0;
  17. /* Modulo values for the S-boxes */
  18. static const int ice_smod[4][4] = {
  19. {333, 313, 505, 369},
  20. {379, 375, 319, 391},
  21. {361, 445, 451, 397},
  22. {397, 425, 395, 505}};
  23. /* XOR values for the S-boxes */
  24. static const int ice_sxor[4][4] = {
  25. {0x83, 0x85, 0x9b, 0xcd},
  26. {0xcc, 0xa7, 0xad, 0x41},
  27. {0x4b, 0x2e, 0xd4, 0x33},
  28. {0xea, 0xcb, 0x2e, 0x04}};
  29. /* Permutation values for the P-box */
  30. static const unsigned long ice_pbox[32] = {
  31. 0x00000001, 0x00000080, 0x00000400, 0x00002000,
  32. 0x00080000, 0x00200000, 0x01000000, 0x40000000,
  33. 0x00000008, 0x00000020, 0x00000100, 0x00004000,
  34. 0x00010000, 0x00800000, 0x04000000, 0x20000000,
  35. 0x00000004, 0x00000010, 0x00000200, 0x00008000,
  36. 0x00020000, 0x00400000, 0x08000000, 0x10000000,
  37. 0x00000002, 0x00000040, 0x00000800, 0x00001000,
  38. 0x00040000, 0x00100000, 0x02000000, 0x80000000};
  39. /* The key rotation schedule */
  40. static const int ice_keyrot[16] = {
  41. 0, 1, 2, 3, 2, 1, 3, 0,
  42. 1, 3, 2, 0, 3, 1, 0, 2};
  43. /*
  44. * 8-bit Galois Field multiplication of a by b, modulo m.
  45. * Just like arithmetic multiplication, except that additions and
  46. * subtractions are replaced by XOR.
  47. */
  48. static unsigned int
  49. gf_mult (
  50. register unsigned int a,
  51. register unsigned int b,
  52. register unsigned int m
  53. ) {
  54. register unsigned int res = 0;
  55. while (b) {
  56. if (b & 1)
  57. res ^= a;
  58. a <<= 1;
  59. b >>= 1;
  60. if (a >= 256)
  61. a ^= m;
  62. }
  63. return (res);
  64. }
  65. /*
  66. * Galois Field exponentiation.
  67. * Raise the base to the power of 7, modulo m.
  68. */
  69. static unsigned long
  70. gf_exp7 (
  71. register unsigned int b,
  72. unsigned int m
  73. ) {
  74. register unsigned int x;
  75. if (b == 0)
  76. return (0);
  77. x = gf_mult (b, b, m);
  78. x = gf_mult (b, x, m);
  79. x = gf_mult (x, x, m);
  80. return (gf_mult (b, x, m));
  81. }
  82. /*
  83. * Carry out the ICE 32-bit P-box permutation.
  84. */
  85. static unsigned long
  86. ice_perm32 (
  87. register unsigned long x
  88. ) {
  89. register unsigned long res = 0;
  90. register const unsigned long *pbox = ice_pbox;
  91. while (x) {
  92. if (x & 1)
  93. res |= *pbox;
  94. pbox++;
  95. x >>= 1;
  96. }
  97. return (res);
  98. }
  99. /*
  100. * Initialise the ICE S-boxes.
  101. * This only has to be done once.
  102. */
  103. static void
  104. ice_sboxes_init (void)
  105. {
  106. register int i;
  107. for (i=0; i<1024; i++) {
  108. int col = (i >> 1) & 0xff;
  109. int row = (i & 0x1) | ((i & 0x200) >> 8);
  110. unsigned long x;
  111. x = gf_exp7 (col ^ ice_sxor[0][row], ice_smod[0][row]) << 24;
  112. ice_sbox[0][i] = ice_perm32 (x);
  113. x = gf_exp7 (col ^ ice_sxor[1][row], ice_smod[1][row]) << 16;
  114. ice_sbox[1][i] = ice_perm32 (x);
  115. x = gf_exp7 (col ^ ice_sxor[2][row], ice_smod[2][row]) << 8;
  116. ice_sbox[2][i] = ice_perm32 (x);
  117. x = gf_exp7 (col ^ ice_sxor[3][row], ice_smod[3][row]);
  118. ice_sbox[3][i] = ice_perm32 (x);
  119. }
  120. }
  121. /*
  122. * Create a new ICE key.
  123. */
  124. IceKey::IceKey (int n)
  125. {
  126. if (!ice_sboxes_initialised) {
  127. ice_sboxes_init ();
  128. ice_sboxes_initialised = 1;
  129. }
  130. if (n < 1) {
  131. _size = 1;
  132. _rounds = 8;
  133. } else {
  134. _size = n;
  135. _rounds = n * 16;
  136. }
  137. _keysched = new IceSubkey[_rounds];
  138. }
  139. /*
  140. * Destroy an ICE key.
  141. */
  142. IceKey::~IceKey ()
  143. {
  144. int i, j;
  145. for (i=0; i<_rounds; i++)
  146. for (j=0; j<3; j++)
  147. _keysched[i].val[j] = 0;
  148. _rounds = _size = 0;
  149. delete[] _keysched;
  150. }
  151. /*
  152. * The single round ICE f function.
  153. */
  154. static unsigned long
  155. ice_f (
  156. register unsigned long p,
  157. const IceSubkey *sk
  158. ) {
  159. unsigned long tl, tr; /* Expanded 40-bit values */
  160. unsigned long al, ar; /* Salted expanded 40-bit values */
  161. /* Left half expansion */
  162. tl = ((p >> 16) & 0x3ff) | (((p >> 14) | (p << 18)) & 0xffc00);
  163. /* Right half expansion */
  164. tr = (p & 0x3ff) | ((p << 2) & 0xffc00);
  165. /* Perform the salt permutation */
  166. // al = (tr & sk->val[2]) | (tl & ~sk->val[2]);
  167. // ar = (tl & sk->val[2]) | (tr & ~sk->val[2]);
  168. al = sk->val[2] & (tl ^ tr);
  169. ar = al ^ tr;
  170. al ^= tl;
  171. al ^= sk->val[0]; /* XOR with the subkey */
  172. ar ^= sk->val[1];
  173. /* S-box lookup and permutation */
  174. return (ice_sbox[0][al >> 10] | ice_sbox[1][al & 0x3ff]
  175. | ice_sbox[2][ar >> 10] | ice_sbox[3][ar & 0x3ff]);
  176. }
  177. /*
  178. * Encrypt a block of 8 bytes of data with the given ICE key.
  179. */
  180. void
  181. IceKey::encrypt (
  182. const unsigned char *ptext,
  183. unsigned char *ctext
  184. ) const
  185. {
  186. register int i;
  187. register unsigned long l, r;
  188. l = (((unsigned long) ptext[0]) << 24)
  189. | (((unsigned long) ptext[1]) << 16)
  190. | (((unsigned long) ptext[2]) << 8) | ptext[3];
  191. r = (((unsigned long) ptext[4]) << 24)
  192. | (((unsigned long) ptext[5]) << 16)
  193. | (((unsigned long) ptext[6]) << 8) | ptext[7];
  194. for (i = 0; i < _rounds; i += 2) {
  195. l ^= ice_f (r, &_keysched[i]);
  196. r ^= ice_f (l, &_keysched[i + 1]);
  197. }
  198. for (i = 0; i < 4; i++) {
  199. ctext[3 - i] = r & 0xff;
  200. ctext[7 - i] = l & 0xff;
  201. r >>= 8;
  202. l >>= 8;
  203. }
  204. }
  205. /*
  206. * Decrypt a block of 8 bytes of data with the given ICE key.
  207. */
  208. void
  209. IceKey::decrypt (
  210. const unsigned char *ctext,
  211. unsigned char *ptext
  212. ) const
  213. {
  214. register int i;
  215. register unsigned long l, r;
  216. l = (((unsigned long) ctext[0]) << 24)
  217. | (((unsigned long) ctext[1]) << 16)
  218. | (((unsigned long) ctext[2]) << 8) | ctext[3];
  219. r = (((unsigned long) ctext[4]) << 24)
  220. | (((unsigned long) ctext[5]) << 16)
  221. | (((unsigned long) ctext[6]) << 8) | ctext[7];
  222. for (i = _rounds - 1; i > 0; i -= 2) {
  223. l ^= ice_f (r, &_keysched[i]);
  224. r ^= ice_f (l, &_keysched[i - 1]);
  225. }
  226. for (i = 0; i < 4; i++) {
  227. ptext[3 - i] = r & 0xff;
  228. ptext[7 - i] = l & 0xff;
  229. r >>= 8;
  230. l >>= 8;
  231. }
  232. }
  233. /*
  234. * Set 8 rounds [n, n+7] of the key schedule of an ICE key.
  235. */
  236. void
  237. IceKey::scheduleBuild (
  238. unsigned short *kb,
  239. int n,
  240. const int *keyrot
  241. ) {
  242. int i;
  243. for (i=0; i<8; i++) {
  244. register int j;
  245. register int kr = keyrot[i];
  246. IceSubkey *isk = &_keysched[n + i];
  247. for (j=0; j<3; j++)
  248. isk->val[j] = 0;
  249. for (j=0; j<15; j++) {
  250. register int k;
  251. unsigned long *curr_sk = &isk->val[j % 3];
  252. for (k=0; k<4; k++) {
  253. unsigned short *curr_kb = &kb[(kr + k) & 3];
  254. register int bit = *curr_kb & 1;
  255. *curr_sk = (*curr_sk << 1) | bit;
  256. *curr_kb = (*curr_kb >> 1) | ((bit ^ 1) << 15);
  257. }
  258. }
  259. }
  260. }
  261. /*
  262. * Set the key schedule of an ICE key.
  263. */
  264. void
  265. IceKey::set (
  266. const unsigned char *key
  267. ) {
  268. int i;
  269. if (_rounds == 8) {
  270. unsigned short kb[4];
  271. for (i=0; i<4; i++)
  272. kb[3 - i] = (key[i*2] << 8) | key[i*2 + 1];
  273. scheduleBuild (kb, 0, ice_keyrot);
  274. return;
  275. }
  276. for (i=0; i<_size; i++) {
  277. int j;
  278. unsigned short kb[4];
  279. for (j=0; j<4; j++)
  280. kb[3 - j] = (key[i*8 + j*2] << 8) | key[i*8 + j*2 + 1];
  281. scheduleBuild (kb, i*8, ice_keyrot);
  282. scheduleBuild (kb, _rounds - 8 - i*8, &ice_keyrot[8]);
  283. }
  284. }
  285. /*
  286. * Return the key size, in bytes.
  287. */
  288. int
  289. IceKey::keySize () const
  290. {
  291. return (_size * 8);
  292. }
  293. /*
  294. * Return the block size, in bytes.
  295. */
  296. int
  297. IceKey::blockSize () const
  298. {
  299. return (8);
  300. }