Counter Strike : Global Offensive Source Code
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.

429 lines
8.0 KiB

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