rc4.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /*
  2. ** Command & Conquer Generals Zero Hour(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. //
  19. // rc4.cpp
  20. // RC4 encryption / decryption
  21. //
  22. #include "rc4.h"
  23. #include <memory.h>
  24. #include <stdio.h>
  25. static unsigned char RC4_Temp_Byte;
  26. #define RC4_SWAP_BYTE(a,b) RC4_Temp_Byte=a; a=b; b=RC4_Temp_Byte
  27. //
  28. // Used to init the key state vector in key setup
  29. //
  30. static unsigned char RC4_Table_Init[]={
  31. 0, 1, 2, 3, 4,
  32. 5, 6, 7, 8, 9,
  33. 10, 11, 12, 13, 14,
  34. 15, 16, 17, 18, 19,
  35. 20, 21, 22, 23, 24,
  36. 25, 26, 27, 28, 29,
  37. 30, 31, 32, 33, 34,
  38. 35, 36, 37, 38, 39,
  39. 40, 41, 42, 43, 44,
  40. 45, 46, 47, 48, 49,
  41. 50, 51, 52, 53, 54,
  42. 55, 56, 57, 58, 59,
  43. 60, 61, 62, 63, 64,
  44. 65, 66, 67, 68, 69,
  45. 70, 71, 72, 73, 74,
  46. 75, 76, 77, 78, 79,
  47. 80, 81, 82, 83, 84,
  48. 85, 86, 87, 88, 89,
  49. 90, 91, 92, 93, 94,
  50. 95, 96, 97, 98, 99,
  51. 100, 101, 102, 103, 104,
  52. 105, 106, 107, 108, 109,
  53. 110, 111, 112, 113, 114,
  54. 115, 116, 117, 118, 119,
  55. 120, 121, 122, 123, 124,
  56. 125, 126, 127, 128, 129,
  57. 130, 131, 132, 133, 134,
  58. 135, 136, 137, 138, 139,
  59. 140, 141, 142, 143, 144,
  60. 145, 146, 147, 148, 149,
  61. 150, 151, 152, 153, 154,
  62. 155, 156, 157, 158, 159,
  63. 160, 161, 162, 163, 164,
  64. 165, 166, 167, 168, 169,
  65. 170, 171, 172, 173, 174,
  66. 175, 176, 177, 178, 179,
  67. 180, 181, 182, 183, 184,
  68. 185, 186, 187, 188, 189,
  69. 190, 191, 192, 193, 194,
  70. 195, 196, 197, 198, 199,
  71. 200, 201, 202, 203, 204,
  72. 205, 206, 207, 208, 209,
  73. 210, 211, 212, 213, 214,
  74. 215, 216, 217, 218, 219,
  75. 220, 221, 222, 223, 224,
  76. 225, 226, 227, 228, 229,
  77. 230, 231, 232, 233, 234,
  78. 235, 236, 237, 238, 239,
  79. 240, 241, 242, 243, 244,
  80. 245, 246, 247, 248, 249,
  81. 250, 251, 252, 253, 254,
  82. 255
  83. };
  84. //
  85. // Don't rely on this to zero the key
  86. //
  87. RC4Class::RC4Class()
  88. {
  89. memset(Key.State, 0, 256);
  90. Key.X=0;
  91. Key.Y=0;
  92. }
  93. //
  94. // Setup the encryption key. This must be called before you encrypt/decrypt!
  95. //
  96. void RC4Class::Prepare_Key(const unsigned char *key_data_ptr, int key_data_len)
  97. {
  98. switch(key_data_len) {
  99. case 8:
  100. Prepare_Key_8bytes(key_data_ptr);
  101. break;
  102. case 16:
  103. Prepare_Key_16bytes(key_data_ptr);
  104. break;
  105. default:
  106. {
  107. unsigned char index1;
  108. unsigned char index2;
  109. unsigned char *state;
  110. unsigned short counter;
  111. state = &Key.State[0];
  112. memcpy(state, RC4_Table_Init, 256);
  113. Key.X = 0;
  114. Key.Y = 0;
  115. index1 = 0;
  116. index2 = 0;
  117. for (counter = 0; counter < 256; counter++) {
  118. index2 = (key_data_ptr[index1] + state[counter] + index2);
  119. RC4_SWAP_BYTE(state[counter], state[index2]);
  120. index1 = (unsigned char)((index1 + 1) % key_data_len);
  121. }
  122. }
  123. } // switch
  124. }
  125. void RC4Class::Print_State(void) {
  126. unsigned char *state;
  127. state = &Key.State[0];
  128. for (int i=0; i<256; i+=5) {
  129. printf(" %3d %3d %3d %3d %3d\n",state[i], state[i+1], state[i+2], state[i+3], state[i+4]);
  130. }
  131. printf("X = %d Y = %d\n\n",Key.X,Key.Y);
  132. }
  133. //
  134. // RC4 in standard mode.
  135. //
  136. // This will XOR the buffer with the RC4 stream (like a one time pad).
  137. //
  138. void RC4Class::RC4(unsigned char *buffer_ptr, int buffer_len)
  139. {
  140. unsigned char x;
  141. unsigned char y;
  142. unsigned char *state;
  143. unsigned char *buffer_end=buffer_ptr+buffer_len;
  144. unsigned char *buffer_cur=buffer_ptr;
  145. x = Key.X;
  146. y = Key.Y;
  147. state = &Key.State[0];
  148. while(buffer_cur != buffer_end) {
  149. x++;
  150. y = (unsigned char)(y + state[x]);
  151. RC4_SWAP_BYTE(state[x], state[y]);
  152. *buffer_cur ^= state[(state[x] + state[y]) & 255];
  153. ++buffer_cur;
  154. }
  155. Key.X = x;
  156. Key.Y = y;
  157. }
  158. //
  159. // Copy state & key
  160. //
  161. RC4Class &RC4Class::operator=(const RC4Class &other) {
  162. if (this == &other)
  163. return(*this);
  164. Key.X=other.Key.X;
  165. Key.Y=other.Key.Y;
  166. memcpy(Key.State, other.Key.State, 256);
  167. return(*this);
  168. }
  169. //////////////////////////// private methods ////////////////////////////
  170. //
  171. // Setup the encryption key. This must be called before you encrypt/decrypt!
  172. // This version assumes the key len is 8 bytes (64 bits).
  173. //
  174. void RC4Class::Prepare_Key_8bytes(const unsigned char *key_data_ptr)
  175. {
  176. unsigned char index1;
  177. unsigned char index2;
  178. unsigned char *state;
  179. unsigned short counter;
  180. state = &Key.State[0];
  181. memcpy(state, RC4_Table_Init, 256);
  182. Key.X = 0;
  183. Key.Y = 0;
  184. index1 = 0;
  185. index2 = 0;
  186. for (counter = 0; counter < 256; counter++) {
  187. index2 = (unsigned char)(key_data_ptr[index1] + state[counter] + index2);
  188. RC4_SWAP_BYTE(state[counter], state[index2]);
  189. ++index1;
  190. index1 &= 0x07;
  191. }
  192. }
  193. //
  194. // Setup the encryption key. This must be called before you encrypt/decrypt!
  195. // This version assumes the key len is 16 bytes (128 bits).
  196. //
  197. void RC4Class::Prepare_Key_16bytes(const unsigned char *key_data_ptr)
  198. {
  199. unsigned char index1;
  200. unsigned char index2;
  201. unsigned char *state;
  202. unsigned short counter;
  203. state = &Key.State[0];
  204. memcpy(state, RC4_Table_Init, 256);
  205. Key.X = 0;
  206. Key.Y = 0;
  207. index1 = 0;
  208. index2 = 0;
  209. for (counter = 0; counter < 256; counter++) {
  210. index2 = (unsigned char)(key_data_ptr[index1] + state[counter] + index2);
  211. RC4_SWAP_BYTE(state[counter], state[index2]);
  212. ++index1;
  213. index1 &= 0x0F;
  214. }
  215. }