encrypt.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2016 RWS Inc, All Rights Reserved
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of version 2 of the GNU General Public License as published by
  7. // the Free Software Foundation
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License along
  15. // with this program; if not, write to the Free Software Foundation, Inc.,
  16. // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. //
  18. // Module Name: Encrypt.cpp
  19. //
  20. // Description: This is the encryption module of Syndicated Game Shell.
  21. //
  22. // History:
  23. //
  24. // 03/25/96 AJM Created.
  25. //
  26. // 07/10/97 BRH Commented out #include AppMain.h so that
  27. // it will work with Postal. It doesn't seem to
  28. // need that file.
  29. //
  30. // 07/10/97 BRH Branched this version of encrypt to use
  31. // Postal's GetRandom() rather than rand();
  32. //
  33. // 07/11/97 BRH Changed Encrypt to return the length of
  34. // the buffer that needs to be stored, and
  35. // changed Decrypt to subtract 2 from that
  36. // length to use as the number of bytes to
  37. // decrypt.
  38. //
  39. //////////////////////////////////////////////////////////////////////////////////////
  40. //////////////////////////////////////////////////////////////////////////////////////
  41. // Windows Headers.
  42. //////////////////////////////////////////////////////////////////////////////////////
  43. //////////////////////////////////////////////////////////////////////////////////////
  44. // C Headers.
  45. //////////////////////////////////////////////////////////////////////////////////////
  46. #include <stdlib.h>
  47. #include <limits.h>
  48. #include "RSPiX.h"
  49. #include "game.h"
  50. //////////////////////////////////////////////////////////////////////////////////////
  51. // Local Headers.
  52. //////////////////////////////////////////////////////////////////////////////////////
  53. #include "encrypt.h"
  54. //////////////////////////////////////////////////////////////////////////////////////
  55. // Module specific macros.
  56. //////////////////////////////////////////////////////////////////////////////////////
  57. #define NUM_KEYS 10
  58. #define KEY_LENGTH 128
  59. #define MAX_STRING_LENGTH 256
  60. #define CRCPOLY 0xA001 /* ANSI CRC-16 */
  61. /* CCITT: 0x8408 */
  62. #define UPDATE_CRC(c) \
  63. ms_usCRC = ms_usCRCtable[(ms_usCRC ^ (c)) & 0xFF] ^ (ms_usCRC >> CHAR_BIT)
  64. //////////////////////////////////////////////////////////////////////////////////////
  65. // Module specific typedefs.
  66. //////////////////////////////////////////////////////////////////////////////////////
  67. //////////////////////////////////////////////////////////////////////////////////////
  68. // Module specific (static) globals.
  69. //////////////////////////////////////////////////////////////////////////////////////
  70. static char *ms_aszSeed[NUM_KEYS]= { "S3D5Lf6klfdsjiureLJKHLKmnblkjshgwieourLKHLKJHSDA0432175094SJAKLFK7348LSDLKJDHFOIUhjgdskgfeiurytowelxcmnvbdfhgeoriyfdslkhgfdgyuie",
  71. "KlkjILKJ879IHKJ8kj67kjh7IUKJHjkh98769872vYUTui6JHG87jhg78JHg787JHGUYuytuyjg876RHCVBnvbAIUT678787igJGFHGFTy67uhHJKJHUYTjhg6HGHG76",
  72. "4LKJH5Euhysdiouyfjlkw45879345kjshfdgcvxJSDHFR8734hdskmfv7y8KJLSDGFAVBMZXBV789kMNADFYUYjhkgkjhdsgfowe787243KJHGDSAGJKkjgdfuye3sd7",
  73. "l45kjhdfuihlIUYSLKHi87ylKJHYOIUmsagKJLHgY9802734KJHLKiuoymNJHTmnb4iU7687nkmbojyTD64654HJG765KHKJhg87jKHKJ76dcbnmbDBDSJFDHJ6IHGHJ",
  74. "fdlkhgljslfkdfhvcxzb 902374jklhfdgoIUOYLSKFDJH98798ysdlk9870OLHL987sdxmncosidHGKJ876kjhtdg786JHG87kj76Kjhgkjhi8K8HG98kgdnb mvzms",
  75. "lsdhflkasjhLKJHSLKHAFD987435LRKJHL34UY5L34J64MNB7IU4Yiuoyt87sdfjshg87ahjkjhgds87JHGKJHT8kjhgdfsvbmyt4eu678JHGkjyt6jKH78k0kjt02KJ",
  76. "lkjhUIYkljhlUYOI6yt9876HJMNBVuyt97JKHfMvhjytrfiyIUHGKVBMNBuyi9872548JKN76kj9fsd8KHG8JKg7872732jK8JgkjhKJHGKJHgkjhg7jkhgkjhgkjhgk",
  77. "dsdfLKJH;LKjKJFLdJGmhpi657oU6Y76fhgf5dyfh879346nmzmbvc56erter654gvcbmzwsdfdsmxcngfvRDFrEDfg76bDewdfvdfgwqsdfdgfcrRDfhgfderfdfteP",
  78. "lkhfdsRE546457djh6g65l67KJHLkhmnbvxcbDF09KLJliuyfdsgxcvbFDGERsdasdfgTEdhFDtYrt8765DFRrfgfhvhghretwRF67654DFhDGFDVctTRTtrytrRyiTY",
  79. "28734jsdfhg873jksgUIYTIUkhgiuT7YIGVBKjg8796KHG8o76HJG876tKJHG8976GFd6584H6G67RT987kJHG65978JKHG8JHGKJHGkhjgkjhgidsytf87439649283"};
  80. static unsigned short ms_usCRCtable[UCHAR_MAX + 1];
  81. static unsigned short ms_usCRC;
  82. //////////////////////////////////////////////////////////////////////////////////////
  83. // Modular functions.
  84. //////////////////////////////////////////////////////////////////////////////////////
  85. short Verify(char *szSource,short sLength,unsigned short usCRC);
  86. void MakeCRCTable();
  87. //////////////////////////////////////////////////////////////////////////////////////
  88. // Globally externable variables.
  89. //////////////////////////////////////////////////////////////////////////////////////
  90. //////////////////////////////////////////////////////////////////////////////////////
  91. // External Functions.
  92. //////////////////////////////////////////////////////////////////////////////////////
  93. //////////////////////////////////////////////////////////////////////////////////////
  94. //
  95. // Function Name: Encrypt
  96. //
  97. // Description: This is the string encryption function.
  98. //
  99. // Input: char*: string to be encrypted
  100. // char*: returned encrypted string
  101. //
  102. // Output: 0 on success
  103. //
  104. // History: 03/25/97, AJM, Created.
  105. //
  106. //////////////////////////////////////////////////////////////////////////////////////
  107. short Encrypt(char* szInputString,char* szOutputString,short sSourceLength)
  108. {
  109. short rc=0, // assume success
  110. sIndex=0,
  111. sStartIndex=GetRandom()%KEY_LENGTH,
  112. sCurrentKey=GetRandom()%NUM_KEYS,
  113. sSeedIndex=sStartIndex;
  114. //store start point in seed
  115. szOutputString[0]=(char)sCurrentKey;
  116. szOutputString[1]=(char)sStartIndex;
  117. //pass one xor against the seed
  118. while(1)
  119. {
  120. //base case time to break
  121. if(sIndex==sSourceLength)
  122. {
  123. szOutputString[sIndex+2]='\0';
  124. break;
  125. }
  126. szOutputString[sIndex+2]=szInputString[sIndex]^(~ms_aszSeed[sCurrentKey][sSeedIndex]);
  127. sIndex++;
  128. sSeedIndex++;
  129. //time to wrap?
  130. if(sSeedIndex==KEY_LENGTH)
  131. sSeedIndex=0;
  132. }
  133. sIndex=2;
  134. //pass two xor against previous char
  135. while(1)
  136. {
  137. //base case time to break
  138. if(sIndex==sSourceLength+1)
  139. {
  140. break;
  141. }
  142. //xor with previous char
  143. szOutputString[sIndex]^=szOutputString[sIndex-1];
  144. sIndex++;
  145. }
  146. return sIndex+1;
  147. }
  148. //////////////////////////////////////////////////////////////////////////////////////
  149. //
  150. // Function Name: Decrypt
  151. //
  152. // Description: This is the string decryption function.
  153. //
  154. // Input: char*: string to be decrypted
  155. // char*: returned decrypted string
  156. //
  157. // Output: 0 on success
  158. //
  159. // History: 03/25/97, AJM, Created.
  160. //
  161. //////////////////////////////////////////////////////////////////////////////////////
  162. short Decrypt(char* szInputString,char* szOutputString,short sSourceLength)
  163. {
  164. sSourceLength -= 2;
  165. short rc=0, // assume success
  166. sStartIndex=szInputString[1],
  167. sIndex=sSourceLength,
  168. sCurrentKey=szInputString[0],
  169. sSeedIndex=sStartIndex;
  170. if((sStartIndex<KEY_LENGTH)&&(sStartIndex>=0))
  171. {
  172. if((sCurrentKey<NUM_KEYS)&&(sCurrentKey>=0))
  173. {
  174. //pass one xor against previous char
  175. while(1)
  176. {
  177. //base case time to break
  178. if(sIndex==1)
  179. {
  180. break;
  181. }
  182. //xor with previous char
  183. szInputString[sIndex]^=szInputString[sIndex-1];
  184. sIndex--;
  185. }
  186. sIndex=2;
  187. //pass two xor against the seed
  188. while(1)
  189. {
  190. //base case time to break
  191. if(sIndex==sSourceLength+2)
  192. {
  193. szOutputString[sSourceLength+2]='\0';
  194. break;
  195. }
  196. szOutputString[sIndex-2]=szInputString[sIndex]^(~ms_aszSeed[sCurrentKey][sSeedIndex]);
  197. sIndex++;
  198. sSeedIndex++;
  199. //time to wrap?
  200. if(sSeedIndex==KEY_LENGTH)
  201. sSeedIndex=0;
  202. }
  203. }
  204. else
  205. {
  206. TRACE("ERROR: Invalid key.\n");
  207. rc=-1;
  208. }
  209. }
  210. else
  211. {
  212. TRACE("ERROR: Invalid start position.");
  213. rc=-2;
  214. }
  215. return rc;
  216. }
  217. //////////////////////////////////////////////////////////////////////////////////////
  218. //
  219. // Function Name: Encrypt
  220. //
  221. // Description: This is the file encryption function.
  222. //
  223. // Input: char*: name of file to encrypt to,
  224. // char*: NULL terminated plaintext to encrypt
  225. //
  226. // Output: 0 on success.
  227. //
  228. // History: 03/25/97, AJM, Created.
  229. //
  230. //////////////////////////////////////////////////////////////////////////////////////
  231. short Encrypt(char* szFileName,char* szInputString)
  232. {
  233. short rc=-1, //assume failure
  234. sLength=strlen(szInputString);
  235. RFile cnFile;
  236. char szEncrypted[MAX_STRING_LENGTH];
  237. ms_usCRC=0;
  238. if(cnFile.Open(szFileName,"wb",RFile::LittleEndian)==0)
  239. {
  240. if(Encrypt(szInputString,szEncrypted,sLength)==0)
  241. {
  242. MakeCRCTable();
  243. for (short i=0;i<sLength;i++)
  244. UPDATE_CRC(szEncrypted[i]);
  245. //grow 2 bytes for internal info
  246. cnFile.Write((S16*)&sLength);
  247. cnFile.Write((S8*) szEncrypted,sLength+2);
  248. cnFile.Write((U16*)&ms_usCRC);
  249. rc=0;
  250. }
  251. cnFile.Close();
  252. }
  253. return rc;
  254. }
  255. //////////////////////////////////////////////////////////////////////////////////////
  256. //
  257. // Function Name: Decrypt
  258. //
  259. // Description: This is the file decryption function.
  260. //
  261. // Input: char*: name of file to be decrypted
  262. // char*: text to decrypt into
  263. //
  264. // Output: 0 on success.
  265. //
  266. // History: 03/25/97, AJM, Created.
  267. //
  268. //////////////////////////////////////////////////////////////////////////////////////
  269. short Decrypt(char* szFileName,char* szOutputString)
  270. {
  271. short rc=-1, //assume failure
  272. sLength;
  273. RFile cnFile;
  274. char szDecrypted[MAX_STRING_LENGTH];
  275. unsigned short usCRC=0;
  276. if(cnFile.Open(szFileName,"rb",RFile::LittleEndian)==0)
  277. {
  278. MakeCRCTable();
  279. cnFile.Read((S16*)&sLength);
  280. cnFile.Read((S8*) szDecrypted,sLength+2);
  281. cnFile.Read((U16*)&usCRC);
  282. if(Verify(szDecrypted,sLength,usCRC)==0)
  283. rc=Decrypt(szDecrypted,szOutputString,sLength);
  284. cnFile.Close();
  285. }
  286. return rc;
  287. }
  288. //////////////////////////////////////////////////////////////////////////////////////
  289. //
  290. // Function Name: Verify
  291. //
  292. // Description: This verifys that the data in the encrypted string hasnt been corrupted
  293. //
  294. // Input: char*: string to insert checksums into
  295. // short: length of string
  296. //
  297. // Output: none
  298. //
  299. // History: 03/25/97, AJM, Created.
  300. //
  301. //////////////////////////////////////////////////////////////////////////////////////
  302. short Verify(char *szSource,short sLength,unsigned short usCRC)
  303. {
  304. short rc=0; //assume success
  305. ms_usCRC=0;
  306. for (short i=0;i<sLength;i++)
  307. UPDATE_CRC(szSource[i]);
  308. if(ms_usCRC!=usCRC)
  309. {
  310. TRACE("Error: CRC failure !!! Old CRC: %hu New CRC: %hu\n");
  311. rc=-1;
  312. }
  313. return rc;
  314. }
  315. void MakeCRCTable()
  316. {
  317. unsigned short i, j, r;
  318. for (i = 0; i <= UCHAR_MAX; i++)
  319. {
  320. r = i;
  321. for (j = 0; j < CHAR_BIT; j++)
  322. if (r & 1) r = (r >> 1) ^ CRCPOLY;
  323. else r >>= 1;
  324. ms_usCRCtable[i] = r;
  325. }
  326. return;
  327. }
  328. //////////////////////////////////////////////////////////////////////////////////////
  329. // EOF
  330. //////////////////////////////////////////////////////////////////////////////////////