Leaked source code of windows server 2003
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.

788 lines
19 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Copyright (c) 1997-2000 Microsoft Corporation
  4. //
  5. // File:
  6. //
  7. // Contents:
  8. //
  9. // History:
  10. //
  11. //---------------------------------------------------------------------------
  12. #ifndef _WIN32_WINNT
  13. #define _WIN32_WINNT 0x0400
  14. #endif
  15. #include <windows.h>
  16. #include <wincrypt.h>
  17. #include <stdio.h>
  18. #include <tchar.h>
  19. #include "Shortsig.h"
  20. #include "base24.h"
  21. #include "lkplite.h"
  22. #include "rc4.h"
  23. #include "md5.h"
  24. //internal functions
  25. #define LKPLITE_PID_LEN _tcslen(_TEXT("12345-123-1234567-12345"))
  26. #define SIGNATURE_LEN 104
  27. #define LKPLITE_PID_FIRSTCOPYOFFSET 10
  28. #define LKPLITE_PID_SECONDCOPYOFFSET 18
  29. #define LKPLITE_SPK_BITSTUFF 0x00000000000000FF
  30. #define LKPLITE_RAWDATALEN 20
  31. DWORD ValidatePID ( LPTSTR lpszPID );
  32. __int64 GetSPKIDFromPID ( LPTSTR lpszPID );
  33. BYTE abLKPPublicKey0[] =
  34. {
  35. 0x6c, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xb7, 0x1e,
  36. 0x79, 0x64, 0xae, 0xdf, 0x30, 0x01, 0x0c, 0x00, 0x00, 0x00,
  37. 0x23, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0xf1, 0x89,
  38. 0x3e, 0xb9, 0x7f, 0x5e, 0xc9, 0x40, 0x4f, 0x0d, 0x64, 0x2c,
  39. 0x9e, 0x1c, 0x5b, 0xd7, 0x43, 0xb3, 0x51, 0x59, 0x27, 0x81,
  40. 0xfb, 0x16, 0x86, 0xa7, 0xb5, 0x9d, 0x89, 0xdb, 0x52, 0xf6,
  41. 0x3e, 0x95, 0xc9, 0x4c, 0x7b, 0x34, 0x54, 0x01, 0xab, 0x3c,
  42. 0x10, 0xb9, 0x35, 0x40, 0x64, 0xba, 0x01, 0x00, 0x00, 0x00,
  43. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  44. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  45. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  46. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  47. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  48. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  49. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  50. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  51. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  52. 0x00, 0x00, 0x39, 0x4d, 0x13, 0xde, 0xe2, 0xc9, 0x68, 0xb5,
  53. 0xef, 0x45, 0x67, 0x94, 0xde, 0x01, 0xdd, 0x35, 0x56, 0x30,
  54. 0x7b, 0xcd, 0xbc, 0xd5, 0x88, 0x77, 0xee, 0xf9, 0x5d, 0xa1,
  55. 0xaf, 0xab, 0xc2, 0xdf, 0xf8, 0x6c, 0x8c, 0x3d, 0xce, 0x4d,
  56. 0xab, 0x27, 0x6b, 0xcc, 0x64, 0x77, 0x8b, 0xbd, 0x71, 0x7b,
  57. 0xdd, 0x93, 0x05, 0xe5, 0xeb, 0xf1, 0xe0, 0x7c, 0xe8, 0x35,
  58. 0x0d, 0x4e, 0x31, 0x22, 0x23, 0x42, 0xaf, 0x33, 0x9f, 0x72,
  59. 0xda, 0xc9, 0x77, 0xa6, 0xe9, 0xcf, 0xac, 0x26, 0xe0, 0xb7,
  60. 0x6e, 0x50, 0xbb, 0x32, 0x71, 0x35, 0x32, 0xc2, 0x41, 0xdf,
  61. 0x76, 0x24, 0xbe, 0xdf, 0x4a, 0x90, 0xff, 0x2e, 0xdc, 0x16,
  62. 0x02, 0x6c, 0xd0, 0x85, 0xf5, 0xdd, 0xf0, 0x0d, 0xe6, 0x01,
  63. 0x75, 0x05, 0x75, 0x87, 0x3b, 0xb6, 0xc8, 0x51, 0x7f, 0x66,
  64. 0xcd, 0x2b, 0x52, 0x0b, 0x09, 0xec, 0xa5, 0x4a, 0xdf, 0x2b,
  65. 0xf0, 0xbd, 0x0e, 0x83, 0x2f, 0xa9, 0xbb, 0xde, 0x43, 0x6e,
  66. 0x4f, 0x38, 0x13, 0xa3, 0x70, 0x2e, 0x5e, 0x7f, 0xf2, 0x84,
  67. 0xaa, 0xfe, 0x12, 0x7d, 0x4e, 0x17, 0xad, 0x7a, 0x3c, 0x05,
  68. 0x40, 0x92, 0xf8, 0x34, 0x97, 0x43, 0x88, 0x93, 0xf1, 0x78,
  69. 0xe4, 0xe9, 0xe6, 0x4c, 0x2d, 0xf9, 0xcf, 0xf8, 0xb5, 0x34,
  70. 0x8c, 0x98, 0x56, 0x8d, 0x89, 0x9d, 0x34, 0xf5, 0xfa, 0xb6,
  71. 0x78, 0xfa, 0x5a, 0x85
  72. };
  73. BYTE abLSIDPublicKey0[] =
  74. {
  75. 0x6c, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x83, 0xa1,
  76. 0xc9, 0xb1, 0xae, 0xdf, 0x30, 0x01, 0x0c, 0x00, 0x00, 0x00,
  77. 0x23, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x31, 0x07,
  78. 0xcb, 0x01, 0x1e, 0x92, 0x74, 0x0b, 0x1e, 0x2b, 0x2d, 0x07,
  79. 0x68, 0xc5, 0xff, 0x21, 0xc5, 0x5c, 0x32, 0xb6, 0x44, 0xdb,
  80. 0x02, 0x09, 0xde, 0x2e, 0xc6, 0x6d, 0xb5, 0xc4, 0xd4, 0x44,
  81. 0x6f, 0xc7, 0x0d, 0xba, 0x4e, 0xe5, 0x0b, 0x0f, 0x92, 0xb1,
  82. 0x22, 0x25, 0xab, 0xdd, 0x86, 0x8d, 0x01, 0x00, 0x00, 0x00,
  83. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  84. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  85. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  86. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  87. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  88. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  89. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  90. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  91. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  92. 0x00, 0x00, 0xdb, 0x86, 0x67, 0xfb, 0x5c, 0x8c, 0x53, 0x72,
  93. 0x0e, 0x49, 0x94, 0x97, 0x94, 0x15, 0xfc, 0x25, 0x0d, 0xdd,
  94. 0xa1, 0xe4, 0xa0, 0xf0, 0xc3, 0x17, 0xf6, 0x98, 0xce, 0x9c,
  95. 0x07, 0x31, 0x10, 0xb7, 0x73, 0x16, 0x4f, 0x91, 0xbb, 0xfa,
  96. 0x01, 0xde, 0x9e, 0x79, 0xf2, 0x66, 0x58, 0xf5, 0x77, 0x45,
  97. 0x55, 0xf0, 0xa8, 0xb8, 0x0c, 0x2c, 0x0f, 0x15, 0xc7, 0x28,
  98. 0xce, 0x81, 0x69, 0x4e, 0x55, 0xd5, 0xf3, 0x89, 0xdc, 0x11,
  99. 0x34, 0x09, 0x40, 0x94, 0x5c, 0xaa, 0xd0, 0x6a, 0x5a, 0x06,
  100. 0x8e, 0x62, 0x6e, 0x5f, 0x7e, 0x35, 0x44, 0x5f, 0x06, 0xb2,
  101. 0xa5, 0xe8, 0x3c, 0x1b, 0x4d, 0xb8, 0xc6, 0x5e, 0xe0, 0xe4,
  102. 0xa6, 0xac, 0x80, 0xef, 0x8c, 0x99, 0x23, 0x06, 0x70, 0xd6,
  103. 0x6c, 0x62, 0x01, 0xb6, 0xde, 0x3b, 0x0c, 0x5e, 0x2a, 0x96,
  104. 0x9e, 0x63, 0x58, 0x9f, 0xdf, 0xf1, 0xaf, 0x5d, 0x02, 0xb6,
  105. 0x84, 0xc1, 0x52, 0x1f, 0xbc, 0xb8, 0x0c, 0x72, 0x3c, 0x1b,
  106. 0xb4, 0x58, 0x51, 0xab, 0x73, 0x19, 0x65, 0xbb, 0xc6, 0xb4,
  107. 0xb2, 0x53, 0xeb, 0x17, 0x4c, 0x42, 0xc9, 0xc2, 0xcd, 0x7f,
  108. 0x88, 0x0f, 0xb8, 0xaa, 0xc4, 0xca, 0xaa, 0xe0, 0xa0, 0xe1,
  109. 0x5f, 0xdb, 0x6e, 0xb8, 0x26, 0xf9, 0x8d, 0x4a, 0xe7, 0xdb,
  110. 0x1e, 0xdc, 0xc7, 0xdf, 0xf0, 0x35, 0x88, 0xec, 0x1d, 0xbe,
  111. 0xab, 0xa4, 0x8d, 0x39
  112. };
  113. DWORD LKPLiteVerifySPK (
  114. LPTSTR pszPID, //PID to validate against
  115. LPTSTR pszSPK,
  116. DWORD * pdwVerifyResult
  117. )
  118. {
  119. DWORD dwRetCode = ERROR_SUCCESS;
  120. PBYTE pbDecodedSPK = NULL;
  121. __int64 n64SPK = 0;
  122. __int64 n64SPKPID =0;
  123. __int64 n64SPKVerifyPID =0;
  124. //common validations
  125. if ( NULL == pszPID || NULL == pszSPK ||
  126. NULL == pdwVerifyResult )
  127. {
  128. dwRetCode = ERROR_INVALID_PARAMETER;
  129. goto done;
  130. }
  131. if ((dwRetCode = ValidatePID ( pszPID ))!= ERROR_SUCCESS)
  132. {
  133. goto done;
  134. }
  135. //now decode the stuff comming in
  136. //base24 expects a string so we need to do this conversion
  137. dwRetCode = B24DecodeMSID(pszSPK , &pbDecodedSPK);
  138. if ( ERROR_SUCCESS != dwRetCode )
  139. {
  140. goto done;
  141. }
  142. dwRetCode = LKPLiteDecryptUsingPID(pszPID,
  143. pbDecodedSPK,
  144. LKPLITE_RAWDATALEN);
  145. if (dwRetCode != ERROR_SUCCESS)
  146. {
  147. goto done;
  148. }
  149. //Call function to verify signature on SPK
  150. dwRetCode = CryptVerifySig(7, pbDecodedSPK, sizeof(abLSIDPublicKey0),
  151. abLSIDPublicKey0, SIGNATURE_LEN, pbDecodedSPK+7);
  152. if (dwRetCode != SS_OK)
  153. {
  154. *pdwVerifyResult = LKPLITE_SPK_INVALID;
  155. goto done;
  156. }
  157. memcpy ( ((BYTE *) &n64SPK) + 1, pbDecodedSPK, sizeof(n64SPK) -1 );
  158. //now get the contents of SPK and then see if it matches with
  159. //the PID passed in
  160. //extract bits 20 - 56 and then move them right 8 bits
  161. n64SPKPID = n64SPK & LKPLITE_SPK_PID_MASK;
  162. n64SPKPID >>= 8;
  163. n64SPKVerifyPID = GetSPKIDFromPID ( pszPID );
  164. if ( n64SPKVerifyPID != n64SPKPID )
  165. {
  166. *pdwVerifyResult = LKPLITE_SPK_INVALID;
  167. }
  168. else
  169. {
  170. *pdwVerifyResult = LKPLITE_SPK_VALID;
  171. }
  172. done:
  173. if ( pbDecodedSPK )
  174. HeapFree (GetProcessHeap(),0,pbDecodedSPK );
  175. return dwRetCode;
  176. }
  177. //This function has to verify the LKP by decrypting it
  178. //and matching the signature
  179. DWORD LKPLiteVerifyLKP (
  180. LPTSTR lpszPID, //PID for verifying the LKP lite blob
  181. LPTSTR pszLKPLite, //B24 encoded LKP
  182. DWORD * pdwVerifyResult
  183. )
  184. {
  185. DWORD dwRetCode = ERROR_SUCCESS;
  186. PBYTE pbDecodedLKP = NULL;
  187. *pdwVerifyResult = LKPLITE_LKP_VALID;
  188. //decode the SPK here
  189. dwRetCode = B24DecodeMSID(pszLKPLite, &pbDecodedLKP);
  190. if ( ERROR_SUCCESS != dwRetCode )
  191. {
  192. goto done;
  193. }
  194. dwRetCode = LKPLiteDecryptUsingPID(lpszPID,
  195. pbDecodedLKP,
  196. LKPLITE_RAWDATALEN);
  197. if (dwRetCode != ERROR_SUCCESS)
  198. {
  199. goto done;
  200. }
  201. //Call function to verify signature on SPK
  202. dwRetCode = CryptVerifySig(7, pbDecodedLKP, sizeof(abLKPPublicKey0),
  203. abLKPPublicKey0, SIGNATURE_LEN, pbDecodedLKP+7);
  204. if (dwRetCode != SS_OK)
  205. {
  206. *pdwVerifyResult = LKPLITE_SPK_INVALID;
  207. }
  208. done:
  209. if (pbDecodedLKP != NULL)
  210. {
  211. HeapFree(GetProcessHeap(), 0, pbDecodedLKP);
  212. }
  213. return dwRetCode;
  214. }
  215. DWORD LKPLiteCrackLKP (
  216. LPTSTR lpszPID,
  217. LPTSTR pszLKPLite,
  218. LPTSTR lpszProductCode,
  219. DWORD * pdwQuantity,
  220. DWORD * pdwSerialNum,
  221. DWORD * pdwExpirationMos,
  222. DWORD * pdwVersion,
  223. DWORD * pdwUpgrade,
  224. DWORD * pdwProgramType
  225. )
  226. {
  227. DWORD dwRetCode = ERROR_SUCCESS;
  228. PBYTE pbDecodedLKP = NULL;
  229. __int64 n64LKPLite = 0;
  230. __int64 n64ProductCode = 0;
  231. __int64 n64Qty = 0;
  232. __int64 n64SerialNo = 0;
  233. __int64 n64dtOfExp = 0;
  234. __int64 n64Version = 0;
  235. __int64 n64Upgrade = 0;
  236. __int64 n64Program = 0;
  237. if ( NULL == lpszPID || NULL == pszLKPLite ||
  238. NULL == lpszProductCode || NULL == pdwQuantity ||
  239. NULL == pdwSerialNum || NULL == pdwExpirationMos ||
  240. NULL == pdwVersion || NULL == pdwUpgrade ||
  241. NULL == pdwProgramType || NULL == pdwProgramType
  242. )
  243. {
  244. dwRetCode = ERROR_INVALID_PARAMETER;
  245. goto done;
  246. }
  247. //decode and decrypt the lkp here
  248. dwRetCode = B24DecodeMSID(pszLKPLite, &pbDecodedLKP);
  249. if ( ERROR_SUCCESS != dwRetCode )
  250. {
  251. goto done;
  252. }
  253. dwRetCode = LKPLiteDecryptUsingPID(lpszPID,
  254. pbDecodedLKP,
  255. LKPLITE_RAWDATALEN);
  256. if (dwRetCode != ERROR_SUCCESS)
  257. {
  258. goto done;
  259. }
  260. //copy all the stuff into int64 type
  261. memcpy ( ((BYTE *) &n64LKPLite) + 1, pbDecodedLKP, sizeof(n64LKPLite ) - 1 );
  262. // Decrypt it using the PID
  263. n64ProductCode = n64LKPLite & LKPLITE_LKP_PRODUCT_MASK;
  264. n64ProductCode >>= 54;
  265. //move the quantity to position
  266. n64Qty = n64LKPLite & LKPLITE_LKP_QUANTITY_MASK;
  267. n64Qty >>= 40;
  268. //move Serial number into position
  269. n64SerialNo = n64LKPLite & LKPLITE_LKP_SERAIL_NO_MASK;
  270. n64SerialNo >>= 28;
  271. //move Program Type into position
  272. n64Program = n64LKPLite & LKPLITE_LKP_PROGRAM_MASK;
  273. n64Program >>= 26;
  274. //move dt of expitration into position
  275. n64dtOfExp = n64LKPLite & LKPLITE_LKP_EXP_DATE_MASK;
  276. n64dtOfExp >>= 18;
  277. //move Version into place
  278. n64Version = n64LKPLite & LKPLITE_LKP_VERSION_MASK;
  279. n64Version >>= 11;
  280. //move upgrade in place
  281. n64Upgrade = n64LKPLite & LKPLITE_LKP_UPG_FULL_MASK;
  282. n64Upgrade >>= 8;
  283. done:
  284. if ( ERROR_SUCCESS == dwRetCode )
  285. {
  286. _stprintf(lpszProductCode, _T("%03d"), n64ProductCode);
  287. // _i64tot ( n64ProductCode, lpszProductCode, 10 );
  288. *pdwQuantity = (DWORD)n64Qty;
  289. *pdwSerialNum = (DWORD)n64SerialNo;
  290. *pdwExpirationMos = (DWORD)n64dtOfExp;
  291. *pdwVersion = (DWORD)n64Version;
  292. *pdwUpgrade = (DWORD)n64Upgrade;
  293. *pdwProgramType = (DWORD)n64Program;
  294. }
  295. if ( pbDecodedLKP )
  296. HeapFree ( GetProcessHeap(),0, pbDecodedLKP );
  297. return dwRetCode;
  298. }
  299. //internal functions
  300. DWORD ValidatePID ( LPTSTR lpszPID )
  301. {
  302. DWORD dwRetCode = ERROR_SUCCESS;
  303. DWORD dwPIDLen = _tcslen( lpszPID );
  304. DWORD dwCounter =0;
  305. if ( dwPIDLen != LKPLITE_PID_LEN )
  306. {
  307. dwRetCode = ERROR_INVALID_PARAMETER;
  308. }
  309. else
  310. {
  311. //check for syntax
  312. for ( dwCounter = 0; dwCounter < dwPIDLen; dwCounter ++ )
  313. {
  314. if ( !_istdigit ( *(lpszPID + dwCounter ) ) )
  315. {
  316. switch(dwCounter)
  317. {
  318. case 5:
  319. if (*(lpszPID + dwCounter ) != _T('-') )
  320. dwRetCode = ERROR_INVALID_PARAMETER;
  321. break;
  322. case 6:
  323. if (*(lpszPID + dwCounter ) != _T('O') && *(lpszPID + dwCounter ) != _T('o') )
  324. dwRetCode = ERROR_INVALID_PARAMETER;
  325. break;
  326. case 7:
  327. if (*(lpszPID + dwCounter ) != _T('E') && *(lpszPID + dwCounter ) != _T('e') )
  328. dwRetCode = ERROR_INVALID_PARAMETER;
  329. break;
  330. case 8:
  331. if (*(lpszPID + dwCounter ) != _T('M') && *(lpszPID + dwCounter ) != _T('m') )
  332. dwRetCode = ERROR_INVALID_PARAMETER;
  333. break;
  334. case 9:
  335. if (*(lpszPID + dwCounter ) != _T('-') )
  336. dwRetCode = ERROR_INVALID_PARAMETER;
  337. break;
  338. case 17:
  339. if (*(lpszPID + dwCounter ) != _T('-') )
  340. dwRetCode = ERROR_INVALID_PARAMETER;
  341. break;
  342. default:
  343. dwRetCode = ERROR_INVALID_PARAMETER;
  344. }
  345. }
  346. else
  347. {
  348. switch(dwCounter)
  349. {
  350. case 5:
  351. case 9:
  352. case 17:
  353. dwRetCode = ERROR_INVALID_PARAMETER;
  354. break;
  355. }
  356. }
  357. }
  358. }
  359. //can check here for mod 7 thing too but for now assume its OK.
  360. return dwRetCode;
  361. }
  362. //Assume that the PID comming in has aleady been validated
  363. __int64 GetSPKIDFromPID ( LPTSTR lpszPID )
  364. {
  365. __int64 n64PID;
  366. TCHAR szPID[12] = {0};
  367. memcpy ( szPID, lpszPID + 10, 6 * sizeof(TCHAR));
  368. memcpy ( szPID + 6, lpszPID+ 18, 5 * sizeof(TCHAR));
  369. n64PID = _ttoi64(szPID);
  370. return n64PID;
  371. }
  372. DWORD LKPLiteValConfNumber(LPTSTR lpszLSID,
  373. LPTSTR lpszPID,
  374. LPTSTR lpszConfirmation)
  375. {
  376. BYTE * pbDecodedLSID = NULL;
  377. BYTE * pbDecodedConf = NULL;
  378. DWORD dwRetCode = ERROR_SUCCESS;
  379. // lpszLSID is base 24 encoded, so decode it first
  380. dwRetCode = B24DecodeMSID(lpszLSID, &pbDecodedLSID);
  381. if (dwRetCode != ERROR_SUCCESS)
  382. {
  383. goto done;
  384. }
  385. // Decode Confirmation Number
  386. dwRetCode = B24DecodeCNumber(lpszConfirmation, &pbDecodedConf);
  387. if (dwRetCode != ERROR_SUCCESS)
  388. {
  389. goto done;
  390. }
  391. // Decrypt the leading 4 bytes
  392. dwRetCode = LKPLiteDecryptUsingPID(lpszPID, pbDecodedConf, sizeof(DWORD));
  393. if (dwRetCode != ERROR_SUCCESS)
  394. {
  395. goto done;
  396. }
  397. if (memcmp(pbDecodedLSID, pbDecodedConf, sizeof(DWORD)) != 0)
  398. {
  399. // does not match
  400. dwRetCode = LKPLITE_INVALID_CONFNUM;
  401. }
  402. done:
  403. if (pbDecodedLSID)
  404. {
  405. HeapFree(GetProcessHeap(), 0, pbDecodedLSID);
  406. }
  407. if (pbDecodedConf)
  408. {
  409. HeapFree(GetProcessHeap(), 0, pbDecodedConf);
  410. }
  411. return dwRetCode;
  412. }
  413. /////////////////////////////////////////////////////////
  414. DWORD WINAPI
  415. EncryptDecryptData(
  416. IN PBYTE pbParm,
  417. IN DWORD cbParm,
  418. IN OUT PBYTE pbData,
  419. IN DWORD cbData
  420. )
  421. /*++
  422. Abstract:
  423. Internal routine to encrypt/decrypt a blob of data
  424. Parameter:
  425. pbParm : binary blob to generate encrypt/decrypt key.
  426. cbParm : size of binary blob.
  427. pbData : data to be encrypt/decrypt.
  428. cbData : size of data to be encrypt/decrypt.
  429. Returns:
  430. ERROR_SUCCESS or error code.
  431. Remark:
  432. --*/
  433. {
  434. DWORD dwRetCode = ERROR_SUCCESS;
  435. MD5_CTX md5Ctx;
  436. RC4_KEYSTRUCT rc4KS;
  437. BYTE key[16];
  438. int i;
  439. if(NULL == pbParm || 0 == cbParm)
  440. {
  441. SetLastError(dwRetCode = ERROR_INVALID_PARAMETER);
  442. return dwRetCode;
  443. }
  444. MD5Init(&md5Ctx);
  445. MD5Update(
  446. &md5Ctx,
  447. pbParm,
  448. cbParm
  449. );
  450. MD5Final(&md5Ctx);
  451. memset(key, 0, sizeof(key));
  452. for(i=0; i < 5; i++)
  453. {
  454. key[i] = md5Ctx.digest[i];
  455. }
  456. //
  457. // Call RC4 to encrypt/decrypt data
  458. //
  459. rc4_key(
  460. &rc4KS,
  461. sizeof(key),
  462. key
  463. );
  464. rc4(&rc4KS, cbData, pbData);
  465. return dwRetCode;
  466. }
  467. DWORD LKPLiteEncryptUsingPID(LPTSTR lpszPID,
  468. BYTE * pbBufferToEncrypt,
  469. DWORD dwLength)
  470. {
  471. DWORD dwRetCode = ERROR_SUCCESS;
  472. #if 1
  473. dwRetCode = EncryptDecryptData(
  474. (PBYTE) lpszPID,
  475. lstrlen(lpszPID)*sizeof(TCHAR),
  476. pbBufferToEncrypt,
  477. dwLength
  478. );
  479. #else
  480. BOOL bRet;
  481. HCRYPTPROV hProv = NULL;
  482. HCRYPTKEY hCKey = NULL;
  483. HCRYPTHASH hHash = NULL;
  484. bRet = CryptAcquireContext(&hProv,
  485. NULL,
  486. NULL,
  487. PROV_RSA_FULL,
  488. CRYPT_VERIFYCONTEXT);
  489. if (!bRet)
  490. {
  491. dwRetCode = GetLastError();
  492. goto done;
  493. }
  494. bRet = CryptCreateHash(hProv,
  495. CALG_MD5,
  496. 0,
  497. 0,
  498. &hHash);
  499. if (!bRet)
  500. {
  501. dwRetCode = GetLastError();
  502. goto done;
  503. }
  504. bRet = CryptHashData(hHash,
  505. (BYTE *) lpszPID,
  506. lstrlen(lpszPID)*sizeof(TCHAR),
  507. 0);
  508. if (!bRet)
  509. {
  510. dwRetCode = GetLastError();
  511. goto done;
  512. }
  513. bRet = CryptDeriveKey(hProv,
  514. CALG_RC4,
  515. hHash,
  516. 0,
  517. &hCKey);
  518. if (!bRet)
  519. {
  520. dwRetCode = GetLastError();
  521. goto done;
  522. }
  523. bRet = CryptEncrypt(hCKey,
  524. 0,
  525. TRUE,
  526. 0,
  527. pbBufferToEncrypt,
  528. &dwLength,
  529. dwLength);
  530. if (!bRet)
  531. {
  532. dwRetCode = GetLastError();
  533. goto done;
  534. }
  535. done:
  536. if (hCKey != NULL)
  537. {
  538. bRet = CryptDestroyKey(hCKey);
  539. if (!bRet)
  540. {
  541. dwRetCode = GetLastError();
  542. }
  543. }
  544. if (hHash != NULL)
  545. {
  546. bRet = CryptDestroyHash(hHash);
  547. if (!bRet)
  548. {
  549. dwRetCode = GetLastError();
  550. }
  551. }
  552. if (hProv != NULL)
  553. {
  554. bRet = CryptReleaseContext( hProv, 0 );
  555. if (!bRet)
  556. {
  557. dwRetCode = GetLastError();
  558. }
  559. }
  560. #endif
  561. return dwRetCode;
  562. }
  563. DWORD LKPLiteDecryptUsingPID(LPTSTR lpszPID,
  564. BYTE * pbBufferToDecrypt,
  565. DWORD dwLength)
  566. {
  567. DWORD dwRetCode = ERROR_SUCCESS;
  568. #if 1
  569. dwRetCode = EncryptDecryptData(
  570. (PBYTE) lpszPID,
  571. lstrlen(lpszPID)*sizeof(TCHAR),
  572. pbBufferToDecrypt,
  573. dwLength
  574. );
  575. #else
  576. BOOL bRet;
  577. HCRYPTPROV hProv = NULL;
  578. HCRYPTKEY hCKey = NULL;
  579. HCRYPTHASH hHash = NULL;
  580. bRet = CryptAcquireContext(&hProv,
  581. NULL,
  582. NULL,
  583. PROV_RSA_FULL,
  584. CRYPT_VERIFYCONTEXT);
  585. if (!bRet)
  586. {
  587. dwRetCode = GetLastError();
  588. goto done;
  589. }
  590. bRet = CryptCreateHash(hProv,
  591. CALG_MD5,
  592. 0,
  593. 0,
  594. &hHash);
  595. if (!bRet)
  596. {
  597. dwRetCode = GetLastError();
  598. goto done;
  599. }
  600. bRet = CryptHashData(hHash,
  601. (BYTE *) lpszPID,
  602. lstrlen(lpszPID)*sizeof(TCHAR),
  603. 0);
  604. if (!bRet)
  605. {
  606. dwRetCode = GetLastError();
  607. goto done;
  608. }
  609. bRet = CryptDeriveKey(hProv,
  610. CALG_RC4,
  611. hHash,
  612. 0,
  613. &hCKey);
  614. if (!bRet)
  615. {
  616. dwRetCode = GetLastError();
  617. goto done;
  618. }
  619. bRet = CryptDecrypt(hCKey,
  620. 0,
  621. TRUE,
  622. 0,
  623. (BYTE *) pbBufferToDecrypt,
  624. &dwLength);
  625. if (!bRet)
  626. {
  627. dwRetCode = GetLastError();
  628. goto done;
  629. }
  630. done:
  631. if (hCKey != NULL)
  632. {
  633. bRet = CryptDestroyKey(hCKey);
  634. if (!bRet)
  635. {
  636. dwRetCode = GetLastError();
  637. }
  638. }
  639. if (hHash != NULL)
  640. {
  641. bRet = CryptDestroyHash(hHash);
  642. if (!bRet)
  643. {
  644. dwRetCode = GetLastError();
  645. }
  646. }
  647. if (hProv != NULL)
  648. {
  649. bRet = CryptReleaseContext( hProv, 0 );
  650. if (!bRet)
  651. {
  652. dwRetCode = GetLastError();
  653. }
  654. }
  655. #endif
  656. return dwRetCode;
  657. }