Source code of Windows XP (NT5)
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.

1148 lines
28 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. #ifndef SIG_VERIFY_ONLY
  34. BYTE abLKPPrivateKey0[] =
  35. {
  36. 0x64, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0xff, 0xab,
  37. 0xa9, 0xba, 0xae, 0xdf, 0x30, 0x01, 0xb7, 0x1e, 0x79, 0x64,
  38. 0x46, 0x00, 0x00, 0x00, 0x50, 0x6d, 0x54, 0x36, 0x05, 0x00,
  39. 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x3d, 0xcb, 0x68, 0x79,
  40. 0x23, 0x52, 0x2c, 0x98, 0x24, 0x00, 0x00, 0x00, 0x83, 0x1c,
  41. 0x65, 0x18, 0x2b, 0xd6, 0x7b, 0x6f, 0x05, 0x00, 0x00, 0x00,
  42. 0x29, 0xe8, 0xe0, 0x1e, 0x71, 0xa0, 0x80, 0x40, 0x36, 0x26,
  43. 0x23, 0xe3, 0xab, 0x55, 0xa2, 0x7b, 0xac, 0xda, 0xf3, 0x29,
  44. 0x4d, 0xe1, 0x1a, 0xfa, 0x54, 0x41, 0xb7, 0xd3, 0x28, 0x27,
  45. 0x02, 0x7e, 0x9b, 0x2b, 0xc6, 0xf7, 0x6e, 0x82, 0x2c, 0xe4
  46. };
  47. BYTE abLSIDPrivateKey0[] =
  48. {
  49. 0x64, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x79, 0x6d,
  50. 0x1a, 0x6c, 0xae, 0xdf, 0x30, 0x01, 0x83, 0xa1, 0xc9, 0xb1,
  51. 0x46, 0x00, 0x00, 0x00, 0x1d, 0x6e, 0x56, 0x37, 0x05, 0x00,
  52. 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x49, 0x17, 0x6c, 0x21,
  53. 0x8e, 0x1d, 0x01, 0x1a, 0x22, 0x00, 0x00, 0x00, 0xa8, 0x60,
  54. 0x22, 0xb7, 0x36, 0xe3, 0x43, 0x57, 0x08, 0x00, 0x00, 0x00,
  55. 0x4b, 0x18, 0x12, 0x54, 0x39, 0x8f, 0x7c, 0x85, 0x88, 0xc4,
  56. 0x61, 0x16, 0x39, 0x17, 0x29, 0x67, 0xe2, 0xe0, 0x20, 0x2c,
  57. 0xcb, 0xeb, 0x5b, 0xd7, 0x75, 0xf0, 0xb8, 0xf3, 0x87, 0x48,
  58. 0x6d, 0x49, 0xce, 0x9a, 0xb3, 0x12, 0x82, 0x05, 0x51, 0xb5
  59. };
  60. #endif
  61. BYTE abLKPPublicKey0[] =
  62. {
  63. 0x6c, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xb7, 0x1e,
  64. 0x79, 0x64, 0xae, 0xdf, 0x30, 0x01, 0x0c, 0x00, 0x00, 0x00,
  65. 0x23, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0xf1, 0x89,
  66. 0x3e, 0xb9, 0x7f, 0x5e, 0xc9, 0x40, 0x4f, 0x0d, 0x64, 0x2c,
  67. 0x9e, 0x1c, 0x5b, 0xd7, 0x43, 0xb3, 0x51, 0x59, 0x27, 0x81,
  68. 0xfb, 0x16, 0x86, 0xa7, 0xb5, 0x9d, 0x89, 0xdb, 0x52, 0xf6,
  69. 0x3e, 0x95, 0xc9, 0x4c, 0x7b, 0x34, 0x54, 0x01, 0xab, 0x3c,
  70. 0x10, 0xb9, 0x35, 0x40, 0x64, 0xba, 0x01, 0x00, 0x00, 0x00,
  71. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  72. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  73. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  74. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  75. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  76. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  77. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  78. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  79. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  80. 0x00, 0x00, 0x39, 0x4d, 0x13, 0xde, 0xe2, 0xc9, 0x68, 0xb5,
  81. 0xef, 0x45, 0x67, 0x94, 0xde, 0x01, 0xdd, 0x35, 0x56, 0x30,
  82. 0x7b, 0xcd, 0xbc, 0xd5, 0x88, 0x77, 0xee, 0xf9, 0x5d, 0xa1,
  83. 0xaf, 0xab, 0xc2, 0xdf, 0xf8, 0x6c, 0x8c, 0x3d, 0xce, 0x4d,
  84. 0xab, 0x27, 0x6b, 0xcc, 0x64, 0x77, 0x8b, 0xbd, 0x71, 0x7b,
  85. 0xdd, 0x93, 0x05, 0xe5, 0xeb, 0xf1, 0xe0, 0x7c, 0xe8, 0x35,
  86. 0x0d, 0x4e, 0x31, 0x22, 0x23, 0x42, 0xaf, 0x33, 0x9f, 0x72,
  87. 0xda, 0xc9, 0x77, 0xa6, 0xe9, 0xcf, 0xac, 0x26, 0xe0, 0xb7,
  88. 0x6e, 0x50, 0xbb, 0x32, 0x71, 0x35, 0x32, 0xc2, 0x41, 0xdf,
  89. 0x76, 0x24, 0xbe, 0xdf, 0x4a, 0x90, 0xff, 0x2e, 0xdc, 0x16,
  90. 0x02, 0x6c, 0xd0, 0x85, 0xf5, 0xdd, 0xf0, 0x0d, 0xe6, 0x01,
  91. 0x75, 0x05, 0x75, 0x87, 0x3b, 0xb6, 0xc8, 0x51, 0x7f, 0x66,
  92. 0xcd, 0x2b, 0x52, 0x0b, 0x09, 0xec, 0xa5, 0x4a, 0xdf, 0x2b,
  93. 0xf0, 0xbd, 0x0e, 0x83, 0x2f, 0xa9, 0xbb, 0xde, 0x43, 0x6e,
  94. 0x4f, 0x38, 0x13, 0xa3, 0x70, 0x2e, 0x5e, 0x7f, 0xf2, 0x84,
  95. 0xaa, 0xfe, 0x12, 0x7d, 0x4e, 0x17, 0xad, 0x7a, 0x3c, 0x05,
  96. 0x40, 0x92, 0xf8, 0x34, 0x97, 0x43, 0x88, 0x93, 0xf1, 0x78,
  97. 0xe4, 0xe9, 0xe6, 0x4c, 0x2d, 0xf9, 0xcf, 0xf8, 0xb5, 0x34,
  98. 0x8c, 0x98, 0x56, 0x8d, 0x89, 0x9d, 0x34, 0xf5, 0xfa, 0xb6,
  99. 0x78, 0xfa, 0x5a, 0x85
  100. };
  101. BYTE abLSIDPublicKey0[] =
  102. {
  103. 0x6c, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x83, 0xa1,
  104. 0xc9, 0xb1, 0xae, 0xdf, 0x30, 0x01, 0x0c, 0x00, 0x00, 0x00,
  105. 0x23, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x31, 0x07,
  106. 0xcb, 0x01, 0x1e, 0x92, 0x74, 0x0b, 0x1e, 0x2b, 0x2d, 0x07,
  107. 0x68, 0xc5, 0xff, 0x21, 0xc5, 0x5c, 0x32, 0xb6, 0x44, 0xdb,
  108. 0x02, 0x09, 0xde, 0x2e, 0xc6, 0x6d, 0xb5, 0xc4, 0xd4, 0x44,
  109. 0x6f, 0xc7, 0x0d, 0xba, 0x4e, 0xe5, 0x0b, 0x0f, 0x92, 0xb1,
  110. 0x22, 0x25, 0xab, 0xdd, 0x86, 0x8d, 0x01, 0x00, 0x00, 0x00,
  111. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  112. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  113. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  114. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  115. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  116. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  117. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  118. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  119. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  120. 0x00, 0x00, 0xdb, 0x86, 0x67, 0xfb, 0x5c, 0x8c, 0x53, 0x72,
  121. 0x0e, 0x49, 0x94, 0x97, 0x94, 0x15, 0xfc, 0x25, 0x0d, 0xdd,
  122. 0xa1, 0xe4, 0xa0, 0xf0, 0xc3, 0x17, 0xf6, 0x98, 0xce, 0x9c,
  123. 0x07, 0x31, 0x10, 0xb7, 0x73, 0x16, 0x4f, 0x91, 0xbb, 0xfa,
  124. 0x01, 0xde, 0x9e, 0x79, 0xf2, 0x66, 0x58, 0xf5, 0x77, 0x45,
  125. 0x55, 0xf0, 0xa8, 0xb8, 0x0c, 0x2c, 0x0f, 0x15, 0xc7, 0x28,
  126. 0xce, 0x81, 0x69, 0x4e, 0x55, 0xd5, 0xf3, 0x89, 0xdc, 0x11,
  127. 0x34, 0x09, 0x40, 0x94, 0x5c, 0xaa, 0xd0, 0x6a, 0x5a, 0x06,
  128. 0x8e, 0x62, 0x6e, 0x5f, 0x7e, 0x35, 0x44, 0x5f, 0x06, 0xb2,
  129. 0xa5, 0xe8, 0x3c, 0x1b, 0x4d, 0xb8, 0xc6, 0x5e, 0xe0, 0xe4,
  130. 0xa6, 0xac, 0x80, 0xef, 0x8c, 0x99, 0x23, 0x06, 0x70, 0xd6,
  131. 0x6c, 0x62, 0x01, 0xb6, 0xde, 0x3b, 0x0c, 0x5e, 0x2a, 0x96,
  132. 0x9e, 0x63, 0x58, 0x9f, 0xdf, 0xf1, 0xaf, 0x5d, 0x02, 0xb6,
  133. 0x84, 0xc1, 0x52, 0x1f, 0xbc, 0xb8, 0x0c, 0x72, 0x3c, 0x1b,
  134. 0xb4, 0x58, 0x51, 0xab, 0x73, 0x19, 0x65, 0xbb, 0xc6, 0xb4,
  135. 0xb2, 0x53, 0xeb, 0x17, 0x4c, 0x42, 0xc9, 0xc2, 0xcd, 0x7f,
  136. 0x88, 0x0f, 0xb8, 0xaa, 0xc4, 0xca, 0xaa, 0xe0, 0xa0, 0xe1,
  137. 0x5f, 0xdb, 0x6e, 0xb8, 0x26, 0xf9, 0x8d, 0x4a, 0xe7, 0xdb,
  138. 0x1e, 0xdc, 0xc7, 0xdf, 0xf0, 0x35, 0x88, 0xec, 0x1d, 0xbe,
  139. 0xab, 0xa4, 0x8d, 0x39
  140. };
  141. //SPK functions
  142. //SPK Format
  143. //Total length = 160 bits
  144. //SPK = 58 bits
  145. //Signature = 120 bits
  146. //SPK break down :
  147. // Bits 1 ..18 - Unique Id max value = 262144
  148. // Bit 19 - SPK Type = 0 = BASIC 1 = SELECT
  149. // Bits 20..56 = SPK Id extracted from PID.
  150. // PID is in this format 12345-123-1234567-12345
  151. // we are using chars 11-16 and 19 thru' end of PID and converting it to a
  152. // number.
  153. // Bits 57 .. end = signature for the first 56 bits
  154. //
  155. #ifndef SIG_VERIFY_ONLY
  156. DWORD LKPLiteGenSPK (
  157. LPTSTR pszPID, //PID for the product. Should include the installation number
  158. DWORD dwUniqueId, //unique Id to be put in the SPK
  159. short nSPKType, //Can be 1 for select or 0 for BASIC
  160. LPTSTR * ppszSPK
  161. )
  162. {
  163. DWORD dwRetCode = ERROR_SUCCESS;
  164. BYTE bSPK[LKPLITE_SPK_LEN] = {0xFF};
  165. __int64 n64SPK = 0;
  166. __int64 n64UniqueId = dwUniqueId;
  167. __int64 n64PID =0;
  168. //validate incomming parametetrs
  169. if ( NULL == pszPID || NULL == pszPID ||
  170. (LKPLITE_SPK_SELECT != nSPKType && LKPLITE_SPK_BASIC != nSPKType ) ||
  171. 0 ==dwUniqueId )
  172. {
  173. dwRetCode = ERROR_INVALID_PARAMETER;
  174. goto done;
  175. }
  176. //validate syntax of PID
  177. if ( ( dwRetCode = ValidatePID ( pszPID ) ) != ERROR_SUCCESS )
  178. {
  179. goto done;
  180. }
  181. //ALL OK so generate the SPK now
  182. n64SPK = dwUniqueId;
  183. n64SPK <<= 46; //left shift this by 46 bits
  184. //Or the bit mask for select/basic cert types.
  185. if ( nSPKType == LKPLITE_SPK_SELECT )
  186. {
  187. n64SPK |= LKPLITE_SPK_SELECT_MASK;
  188. }
  189. else if ( nSPKType == LKPLITE_SPK_BASIC )
  190. {
  191. n64SPK |= LKPLITE_SPK_BASIC_MASK;
  192. }
  193. //extract the PID stuff and move it into the stuff
  194. n64PID = GetSPKIDFromPID ( pszPID );
  195. //move the pid left by 8 bits and or it with the main stuff
  196. n64PID <<= 8;
  197. //set the last 8 bits of this PID to 1's
  198. n64PID |= LKPLITE_SPK_BITSTUFF;
  199. //or the PID with SPK
  200. n64SPK |= n64PID;
  201. memcpy ( bSPK, ((BYTE *) (&n64SPK)) + 1, sizeof(n64SPK)-1);
  202. //get the signature and then
  203. //assign the pointer
  204. /*
  205. dwRetCode = CryptSignBatch(0, NULL, 7, bSPK, sizeof(abPrivateKey0),abPrivateKey0,
  206. sizeof(abPublicKey0), abPublicKey0, SIGNATURE_LEN,
  207. bSPK+7,1);
  208. */
  209. dwRetCode = CryptSign(0, NULL, 7, bSPK, sizeof(abLSIDPrivateKey0), abLSIDPrivateKey0,
  210. sizeof(abLSIDPublicKey0), abLSIDPublicKey0, SIGNATURE_LEN,
  211. bSPK+7);
  212. if (dwRetCode != SS_OK)
  213. {
  214. goto done;
  215. }
  216. //encrypt it with the pid passed in
  217. dwRetCode = LKPLiteEncryptUsingPID(pszPID,
  218. bSPK,
  219. LKPLITE_RAWDATALEN);
  220. if (dwRetCode != ERROR_SUCCESS)
  221. {
  222. goto done;
  223. }
  224. dwRetCode = B24EncodeMSID((PBYTE)bSPK, ppszSPK);
  225. done:
  226. return dwRetCode;
  227. }
  228. #endif
  229. DWORD LKPLiteVerifySPK (
  230. LPTSTR pszPID, //PID to validate against
  231. LPTSTR pszSPK,
  232. DWORD * pdwVerifyResult
  233. )
  234. {
  235. DWORD dwRetCode = ERROR_SUCCESS;
  236. PBYTE pbDecodedSPK = NULL;
  237. __int64 n64SPK = 0;
  238. __int64 n64SPKPID =0;
  239. __int64 n64SPKVerifyPID =0;
  240. //common validations
  241. if ( NULL == pszPID || NULL == pszSPK ||
  242. NULL == pdwVerifyResult )
  243. {
  244. dwRetCode = ERROR_INVALID_PARAMETER;
  245. goto done;
  246. }
  247. if ((dwRetCode = ValidatePID ( pszPID ))!= ERROR_SUCCESS)
  248. {
  249. goto done;
  250. }
  251. //now decode the stuff comming in
  252. //base24 expects a string so we need to do this conversion
  253. dwRetCode = B24DecodeMSID(pszSPK , &pbDecodedSPK);
  254. if ( ERROR_SUCCESS != dwRetCode )
  255. {
  256. goto done;
  257. }
  258. dwRetCode = LKPLiteDecryptUsingPID(pszPID,
  259. pbDecodedSPK,
  260. LKPLITE_RAWDATALEN);
  261. if (dwRetCode != ERROR_SUCCESS)
  262. {
  263. goto done;
  264. }
  265. //Call function to verify signature on SPK
  266. dwRetCode = CryptVerifySig(7, pbDecodedSPK, sizeof(abLSIDPublicKey0),
  267. abLSIDPublicKey0, SIGNATURE_LEN, pbDecodedSPK+7);
  268. if (dwRetCode != SS_OK)
  269. {
  270. *pdwVerifyResult = LKPLITE_SPK_INVALID;
  271. goto done;
  272. }
  273. memcpy ( ((BYTE *) &n64SPK) + 1, pbDecodedSPK, sizeof(n64SPK) -1 );
  274. //now get the contents of SPK and then see if it matches with
  275. //the PID passed in
  276. //extract bits 20 - 56 and then move them right 8 bits
  277. n64SPKPID = n64SPK & LKPLITE_SPK_PID_MASK;
  278. n64SPKPID >>= 8;
  279. n64SPKVerifyPID = GetSPKIDFromPID ( pszPID );
  280. if ( n64SPKVerifyPID != n64SPKPID )
  281. {
  282. *pdwVerifyResult = LKPLITE_SPK_INVALID;
  283. }
  284. else
  285. {
  286. *pdwVerifyResult = LKPLITE_SPK_VALID;
  287. }
  288. done:
  289. if ( pbDecodedSPK )
  290. HeapFree (GetProcessHeap(),0,pbDecodedSPK );
  291. return dwRetCode;
  292. }
  293. DWORD LKPLiteCrackSPK (
  294. LPTSTR pszPID,
  295. LPTSTR pszSPK, //Pointer to SPK
  296. LPTSTR pszPIDPart, //PID Part of SPK
  297. DWORD * pdwUniqueId, //uniqueId part of SPK
  298. short * pnSPKType //Type of SPK - Select/Basic
  299. )
  300. {
  301. DWORD dwRetCode = ERROR_SUCCESS;
  302. PBYTE pbDecodedSPK = NULL;
  303. __int64 n64SPK =0;
  304. __int64 n64PIDPart =0;
  305. __int64 n64UniqueId =0;
  306. LPTSTR lpszEncodedSPK = NULL;
  307. //Validate the parameters
  308. if ( NULL == pszSPK || NULL == pszPIDPart ||
  309. NULL == pdwUniqueId || NULL == pnSPKType
  310. )
  311. {
  312. dwRetCode = ERROR_INVALID_PARAMETER;
  313. goto done;
  314. }
  315. //decode the SPK here
  316. dwRetCode = B24DecodeMSID(pszSPK, &pbDecodedSPK);
  317. if ( ERROR_SUCCESS != dwRetCode )
  318. {
  319. goto done;
  320. }
  321. dwRetCode = LKPLiteDecryptUsingPID(pszPID,
  322. pbDecodedSPK,
  323. LKPLITE_RAWDATALEN);
  324. if (dwRetCode != ERROR_SUCCESS)
  325. {
  326. goto done;
  327. }
  328. //get the SPK portion of it
  329. memcpy ( ((BYTE *) &n64SPK) + 1, pbDecodedSPK, sizeof(n64SPK) - 1);
  330. //get the first 20 bits into
  331. n64UniqueId = n64SPK & LKPLITE_SPK_UNIQUEID_MASK;
  332. n64UniqueId >>= 46;
  333. *pdwUniqueId = (DWORD)n64UniqueId;
  334. //check to see select / basic mask
  335. if ( n64SPK & LKPLITE_SPK_SELECT_MASK )
  336. {
  337. *pnSPKType = LKPLITE_SPK_SELECT;
  338. }
  339. else
  340. {
  341. *pnSPKType = LKPLITE_SPK_BASIC;
  342. }
  343. //get the PID part
  344. n64PIDPart = n64SPK & LKPLITE_SPK_PID_MASK;
  345. n64PIDPart >>= 6;
  346. pszPIDPart = _i64tot (n64PIDPart, pszPIDPart, 10);
  347. done:
  348. if ( pbDecodedSPK )
  349. HeapFree (GetProcessHeap(), 0, pbDecodedSPK );
  350. return dwRetCode;
  351. }
  352. //LKP functions
  353. //LKP Format
  354. // Bits 1..10 - Product Code It is 256 for not which is NT 5.0 product code
  355. // Bits 11..24 - Quantity Max 9999
  356. // Bits 25..36 - Serial num Max 4K
  357. // Bits 37..38 - Program Type 0-SELECT,1-MOLP, 2-RETAIL
  358. // Bits 39..46 - Dt Of expiration in months from today
  359. // Bits 47..53 - Version 1-99
  360. // Bits 54..56 - Upgrade / Full flag
  361. // Bits 57 .. end - Signature
  362. //
  363. #ifndef SIG_VERIFY_ONLY
  364. DWORD LKPLiteGenLKP (
  365. LPTSTR lpszPID, //used for encrypting the LKPLite structure
  366. LPTSTR lpszProductCode, //Product Code
  367. DWORD dwQuantity, //quantity
  368. DWORD dwSerialNum, //serail number of SPK
  369. DWORD dwExpirationMos, //expiration in number of months from today
  370. DWORD dwVersion, //version number can be upto 99
  371. DWORD dwUpgrade, //upgrade or full license
  372. DWORD dwProgramType, //SELECT,MOLP or RETAIL
  373. LPTSTR * ppszLKPLite
  374. )
  375. {
  376. DWORD dwRetCode = ERROR_SUCCESS;
  377. __int64 n64LKPLite = _ttoi(lpszProductCode);
  378. __int64 n64Qty = dwQuantity;
  379. __int64 n64SerialNo = dwSerialNum;
  380. __int64 n64dtOfExp = dwExpirationMos;
  381. __int64 n64Version = dwVersion;
  382. __int64 n64Upgrade = dwUpgrade;
  383. __int64 n64Program = dwProgramType;
  384. BYTE bLKP[LKPLITE_LKP_LEN] = {0};
  385. //validate params
  386. if ( NULL == lpszPID || NULL == lpszProductCode ||
  387. ( dwQuantity <= 0 || dwQuantity > 9999) ||
  388. ( dwSerialNum <= 0 || dwSerialNum >= 0xFFF ) ||
  389. ( dwExpirationMos <= 0 || dwExpirationMos >= 255) ||
  390. ( dwVersion <= 0 || dwVersion >= 99) ||
  391. ( dwUpgrade != 1 && dwUpgrade != 0 ) ||
  392. ( dwProgramType != LKPLITE_PROGRAM_SELECT && dwProgramType != LKPLITE_PROGRAM_MOLP &&
  393. dwProgramType != LKPLITE_PROGRAM_RETAIL)
  394. )
  395. {
  396. dwRetCode = ERROR_INVALID_PARAMETER;
  397. goto done;
  398. }
  399. //move the product code to extreme left
  400. n64LKPLite <<= 54;
  401. //move the quantity to position
  402. n64Qty <<= 40;
  403. n64LKPLite |= n64Qty;
  404. //move Serial number into position
  405. n64SerialNo <<= 28;
  406. n64LKPLite |= n64SerialNo;
  407. //move Program Type into position
  408. n64Program <<= 26;
  409. n64LKPLite |= n64Program;
  410. //move dt of expitration into position
  411. n64dtOfExp <<= 18;
  412. n64LKPLite |= n64dtOfExp;
  413. //move Version into place
  414. n64Version <<= 11;
  415. n64LKPLite |= n64Version;
  416. //move upgrade in place
  417. n64Upgrade <<= 8;
  418. n64LKPLite |= n64Upgrade;
  419. //set the last 8 bits of this PID to 1's
  420. n64LKPLite |= LKPLITE_SPK_BITSTUFF;
  421. memcpy ( bLKP, ((BYTE *) &n64LKPLite) + 1, sizeof(n64LKPLite ) - 1);
  422. /*
  423. dwRetCode = CryptSignBatch(0, NULL, 7, bLKP, sizeof(abPrivateKey0),abPrivateKey0,
  424. sizeof(abPublicKey0), abPublicKey0, SIGNATURE_LEN,
  425. bLKP+7,1);
  426. */
  427. //sign the lkp here
  428. dwRetCode = CryptSign(0, NULL, 7, bLKP, sizeof(abLKPPrivateKey0), abLKPPrivateKey0,
  429. sizeof(abLKPPublicKey0), abLKPPublicKey0, SIGNATURE_LEN,
  430. bLKP+7);
  431. if (dwRetCode != SS_OK)
  432. {
  433. goto done;
  434. }
  435. //encrypt it with the pid passed in
  436. dwRetCode = LKPLiteEncryptUsingPID(lpszPID,
  437. bLKP,
  438. LKPLITE_RAWDATALEN);
  439. if (dwRetCode != ERROR_SUCCESS)
  440. {
  441. goto done;
  442. }
  443. // memset ( bLKP, 0xFF, sizeof(bLKP));
  444. //now encode the spk
  445. dwRetCode = B24EncodeMSID((PBYTE)bLKP, ppszLKPLite);
  446. done:
  447. return dwRetCode;
  448. }
  449. #endif
  450. //This function has to verify the LKP by decrypting it
  451. //and matching the signature
  452. DWORD LKPLiteVerifyLKP (
  453. LPTSTR lpszPID, //PID for verifying the LKP lite blob
  454. LPTSTR pszLKPLite, //B24 encoded LKP
  455. DWORD * pdwVerifyResult
  456. )
  457. {
  458. DWORD dwRetCode = ERROR_SUCCESS;
  459. PBYTE pbDecodedLKP = NULL;
  460. *pdwVerifyResult = LKPLITE_LKP_VALID;
  461. //decode the SPK here
  462. dwRetCode = B24DecodeMSID(pszLKPLite, &pbDecodedLKP);
  463. if ( ERROR_SUCCESS != dwRetCode )
  464. {
  465. goto done;
  466. }
  467. dwRetCode = LKPLiteDecryptUsingPID(lpszPID,
  468. pbDecodedLKP,
  469. LKPLITE_RAWDATALEN);
  470. if (dwRetCode != ERROR_SUCCESS)
  471. {
  472. goto done;
  473. }
  474. //Call function to verify signature on SPK
  475. dwRetCode = CryptVerifySig(7, pbDecodedLKP, sizeof(abLKPPublicKey0),
  476. abLKPPublicKey0, SIGNATURE_LEN, pbDecodedLKP+7);
  477. if (dwRetCode != SS_OK)
  478. {
  479. *pdwVerifyResult = LKPLITE_SPK_INVALID;
  480. }
  481. done:
  482. if (pbDecodedLKP != NULL)
  483. {
  484. HeapFree(GetProcessHeap(), 0, pbDecodedLKP);
  485. }
  486. return dwRetCode;
  487. }
  488. DWORD LKPLiteCrackLKP (
  489. LPTSTR lpszPID,
  490. LPTSTR pszLKPLite,
  491. LPTSTR lpszProductCode,
  492. DWORD * pdwQuantity,
  493. DWORD * pdwSerialNum,
  494. DWORD * pdwExpirationMos,
  495. DWORD * pdwVersion,
  496. DWORD * pdwUpgrade,
  497. DWORD * pdwProgramType
  498. )
  499. {
  500. DWORD dwRetCode = ERROR_SUCCESS;
  501. PBYTE pbDecodedLKP = NULL;
  502. __int64 n64LKPLite = 0;
  503. __int64 n64ProductCode = 0;
  504. __int64 n64Qty = 0;
  505. __int64 n64SerialNo = 0;
  506. __int64 n64dtOfExp = 0;
  507. __int64 n64Version = 0;
  508. __int64 n64Upgrade = 0;
  509. __int64 n64Program = 0;
  510. if ( NULL == lpszPID || NULL == pszLKPLite ||
  511. NULL == lpszProductCode || NULL == pdwQuantity ||
  512. NULL == pdwSerialNum || NULL == pdwExpirationMos ||
  513. NULL == pdwVersion || NULL == pdwUpgrade ||
  514. NULL == pdwProgramType || NULL == pdwProgramType
  515. )
  516. {
  517. dwRetCode = ERROR_INVALID_PARAMETER;
  518. goto done;
  519. }
  520. //decode and decrypt the lkp here
  521. dwRetCode = B24DecodeMSID(pszLKPLite, &pbDecodedLKP);
  522. if ( ERROR_SUCCESS != dwRetCode )
  523. {
  524. goto done;
  525. }
  526. dwRetCode = LKPLiteDecryptUsingPID(lpszPID,
  527. pbDecodedLKP,
  528. LKPLITE_RAWDATALEN);
  529. if (dwRetCode != ERROR_SUCCESS)
  530. {
  531. goto done;
  532. }
  533. //copy all the stuff into int64 type
  534. memcpy ( ((BYTE *) &n64LKPLite) + 1, pbDecodedLKP, sizeof(n64LKPLite ) - 1 );
  535. // Decrypt it using the PID
  536. n64ProductCode = n64LKPLite & LKPLITE_LKP_PRODUCT_MASK;
  537. n64ProductCode >>= 54;
  538. //move the quantity to position
  539. n64Qty = n64LKPLite & LKPLITE_LKP_QUANTITY_MASK;
  540. n64Qty >>= 40;
  541. //move Serial number into position
  542. n64SerialNo = n64LKPLite & LKPLITE_LKP_SERAIL_NO_MASK;
  543. n64SerialNo >>= 28;
  544. //move Program Type into position
  545. n64Program = n64LKPLite & LKPLITE_LKP_PROGRAM_MASK;
  546. n64Program >>= 26;
  547. //move dt of expitration into position
  548. n64dtOfExp = n64LKPLite & LKPLITE_LKP_EXP_DATE_MASK;
  549. n64dtOfExp >>= 18;
  550. //move Version into place
  551. n64Version = n64LKPLite & LKPLITE_LKP_VERSION_MASK;
  552. n64Version >>= 11;
  553. //move upgrade in place
  554. n64Upgrade = n64LKPLite & LKPLITE_LKP_UPG_FULL_MASK;
  555. n64Upgrade >>= 8;
  556. done:
  557. if ( ERROR_SUCCESS == dwRetCode )
  558. {
  559. _stprintf(lpszProductCode, _T("%03d"), n64ProductCode);
  560. // _i64tot ( n64ProductCode, lpszProductCode, 10 );
  561. *pdwQuantity = (DWORD)n64Qty;
  562. *pdwSerialNum = (DWORD)n64SerialNo;
  563. *pdwExpirationMos = (DWORD)n64dtOfExp;
  564. *pdwVersion = (DWORD)n64Version;
  565. *pdwUpgrade = (DWORD)n64Upgrade;
  566. *pdwProgramType = (DWORD)n64Program;
  567. }
  568. if ( pbDecodedLKP )
  569. HeapFree ( GetProcessHeap(),0, pbDecodedLKP );
  570. return dwRetCode;
  571. }
  572. //internal functions
  573. DWORD ValidatePID ( LPTSTR lpszPID )
  574. {
  575. DWORD dwRetCode = ERROR_SUCCESS;
  576. DWORD dwPIDLen = _tcslen( lpszPID );
  577. DWORD dwCounter =0;
  578. if ( dwPIDLen != LKPLITE_PID_LEN )
  579. {
  580. dwRetCode = ERROR_INVALID_PARAMETER;
  581. }
  582. else
  583. {
  584. //check for syntax
  585. for ( dwCounter = 0; dwCounter < dwPIDLen; dwCounter ++ )
  586. {
  587. if ( !_istdigit ( *(lpszPID + dwCounter ) ) )
  588. {
  589. switch(dwCounter)
  590. {
  591. case 5:
  592. if (*(lpszPID + dwCounter ) != _T('-') )
  593. dwRetCode = ERROR_INVALID_PARAMETER;
  594. break;
  595. case 6:
  596. if (*(lpszPID + dwCounter ) != _T('O') && *(lpszPID + dwCounter ) != _T('o') )
  597. dwRetCode = ERROR_INVALID_PARAMETER;
  598. break;
  599. case 7:
  600. if (*(lpszPID + dwCounter ) != _T('E') && *(lpszPID + dwCounter ) != _T('e') )
  601. dwRetCode = ERROR_INVALID_PARAMETER;
  602. break;
  603. case 8:
  604. if (*(lpszPID + dwCounter ) != _T('M') && *(lpszPID + dwCounter ) != _T('m') )
  605. dwRetCode = ERROR_INVALID_PARAMETER;
  606. break;
  607. case 9:
  608. if (*(lpszPID + dwCounter ) != _T('-') )
  609. dwRetCode = ERROR_INVALID_PARAMETER;
  610. break;
  611. case 17:
  612. if (*(lpszPID + dwCounter ) != _T('-') )
  613. dwRetCode = ERROR_INVALID_PARAMETER;
  614. break;
  615. default:
  616. dwRetCode = ERROR_INVALID_PARAMETER;
  617. }
  618. }
  619. else
  620. {
  621. switch(dwCounter)
  622. {
  623. case 5:
  624. case 9:
  625. case 17:
  626. dwRetCode = ERROR_INVALID_PARAMETER;
  627. break;
  628. }
  629. }
  630. }
  631. }
  632. //can check here for mod 7 thing too but for now assume its OK.
  633. return dwRetCode;
  634. }
  635. //Assume that the PID comming in has aleady been validated
  636. __int64 GetSPKIDFromPID ( LPTSTR lpszPID )
  637. {
  638. __int64 n64PID;
  639. TCHAR szPID[12] = {0};
  640. memcpy ( szPID, lpszPID + 10, 6 * sizeof(TCHAR));
  641. memcpy ( szPID + 6, lpszPID+ 18, 5 * sizeof(TCHAR));
  642. n64PID = _ttoi64(szPID);
  643. return n64PID;
  644. }
  645. DWORD LKPLiteGenConfNumber(LPTSTR lpszLSID,
  646. LPTSTR lpszPID,
  647. LPTSTR *lpszConfirmation)
  648. {
  649. BYTE * pbDecodedData = NULL;
  650. DWORD dwRetCode = ERROR_SUCCESS;
  651. DWORD dwConfirmation;
  652. // lpszLSID is base 24 encoded, so decode it first
  653. dwRetCode = B24DecodeMSID(lpszLSID, &pbDecodedData);
  654. if (dwRetCode != ERROR_SUCCESS)
  655. {
  656. goto done;
  657. }
  658. // Decoded Data is available. Copy the leading 4 bytes for generating the confirmation
  659. // Number
  660. memcpy(&dwConfirmation, pbDecodedData, sizeof(DWORD));
  661. // Encrypt this number using the PID
  662. dwRetCode = LKPLiteEncryptUsingPID(lpszPID, (BYTE *) &dwConfirmation, sizeof(DWORD));
  663. if (dwRetCode != ERROR_SUCCESS)
  664. {
  665. goto done;
  666. }
  667. // Now Encode the Encrypted stream
  668. dwRetCode = B24EncodeCNumber((BYTE *) &dwConfirmation, lpszConfirmation);
  669. if (dwRetCode != ERROR_SUCCESS)
  670. {
  671. goto done;
  672. }
  673. done:
  674. if (pbDecodedData)
  675. {
  676. HeapFree(GetProcessHeap(), 0, pbDecodedData);
  677. }
  678. return dwRetCode;
  679. }
  680. DWORD LKPLiteValConfNumber(LPTSTR lpszLSID,
  681. LPTSTR lpszPID,
  682. LPTSTR lpszConfirmation)
  683. {
  684. BYTE * pbDecodedLSID = NULL;
  685. BYTE * pbDecodedConf = NULL;
  686. DWORD dwRetCode = ERROR_SUCCESS;
  687. // lpszLSID is base 24 encoded, so decode it first
  688. dwRetCode = B24DecodeMSID(lpszLSID, &pbDecodedLSID);
  689. if (dwRetCode != ERROR_SUCCESS)
  690. {
  691. goto done;
  692. }
  693. // Decode Confirmation Number
  694. dwRetCode = B24DecodeCNumber(lpszConfirmation, &pbDecodedConf);
  695. if (dwRetCode != ERROR_SUCCESS)
  696. {
  697. goto done;
  698. }
  699. // Decrypt the leading 4 bytes
  700. dwRetCode = LKPLiteDecryptUsingPID(lpszPID, pbDecodedConf, sizeof(DWORD));
  701. if (dwRetCode != ERROR_SUCCESS)
  702. {
  703. goto done;
  704. }
  705. if (memcmp(pbDecodedLSID, pbDecodedConf, sizeof(DWORD)) != 0)
  706. {
  707. // does not match
  708. dwRetCode = LKPLITE_INVALID_CONFNUM;
  709. }
  710. done:
  711. if (pbDecodedLSID)
  712. {
  713. HeapFree(GetProcessHeap(), 0, pbDecodedLSID);
  714. }
  715. if (pbDecodedConf)
  716. {
  717. HeapFree(GetProcessHeap(), 0, pbDecodedConf);
  718. }
  719. return dwRetCode;
  720. }
  721. /////////////////////////////////////////////////////////
  722. DWORD WINAPI
  723. EncryptDecryptData(
  724. IN PBYTE pbParm,
  725. IN DWORD cbParm,
  726. IN OUT PBYTE pbData,
  727. IN DWORD cbData
  728. )
  729. /*++
  730. Abstract:
  731. Internal routine to encrypt/decrypt a blob of data
  732. Parameter:
  733. pbParm : binary blob to generate encrypt/decrypt key.
  734. cbParm : size of binary blob.
  735. pbData : data to be encrypt/decrypt.
  736. cbData : size of data to be encrypt/decrypt.
  737. Returns:
  738. ERROR_SUCCESS or error code.
  739. Remark:
  740. --*/
  741. {
  742. DWORD dwRetCode = ERROR_SUCCESS;
  743. MD5_CTX md5Ctx;
  744. RC4_KEYSTRUCT rc4KS;
  745. BYTE key[16];
  746. int i;
  747. if(NULL == pbParm || 0 == cbParm)
  748. {
  749. SetLastError(dwRetCode = ERROR_INVALID_PARAMETER);
  750. return dwRetCode;
  751. }
  752. MD5Init(&md5Ctx);
  753. MD5Update(
  754. &md5Ctx,
  755. pbParm,
  756. cbParm
  757. );
  758. MD5Final(&md5Ctx);
  759. memset(key, 0, sizeof(key));
  760. for(i=0; i < 5; i++)
  761. {
  762. key[i] = md5Ctx.digest[i];
  763. }
  764. //
  765. // Call RC4 to encrypt/decrypt data
  766. //
  767. rc4_key(
  768. &rc4KS,
  769. sizeof(key),
  770. key
  771. );
  772. rc4(&rc4KS, cbData, pbData);
  773. return dwRetCode;
  774. }
  775. DWORD LKPLiteEncryptUsingPID(LPTSTR lpszPID,
  776. BYTE * pbBufferToEncrypt,
  777. DWORD dwLength)
  778. {
  779. DWORD dwRetCode = ERROR_SUCCESS;
  780. #if 1
  781. dwRetCode = EncryptDecryptData(
  782. (PBYTE) lpszPID,
  783. lstrlen(lpszPID)*sizeof(TCHAR),
  784. pbBufferToEncrypt,
  785. dwLength
  786. );
  787. #else
  788. BOOL bRet;
  789. HCRYPTPROV hProv = NULL;
  790. HCRYPTKEY hCKey = NULL;
  791. HCRYPTHASH hHash = NULL;
  792. bRet = CryptAcquireContext(&hProv,
  793. NULL,
  794. NULL,
  795. PROV_RSA_FULL,
  796. CRYPT_VERIFYCONTEXT);
  797. if (!bRet)
  798. {
  799. dwRetCode = GetLastError();
  800. goto done;
  801. }
  802. bRet = CryptCreateHash(hProv,
  803. CALG_MD5,
  804. 0,
  805. 0,
  806. &hHash);
  807. if (!bRet)
  808. {
  809. dwRetCode = GetLastError();
  810. goto done;
  811. }
  812. bRet = CryptHashData(hHash,
  813. (BYTE *) lpszPID,
  814. lstrlen(lpszPID)*sizeof(TCHAR),
  815. 0);
  816. if (!bRet)
  817. {
  818. dwRetCode = GetLastError();
  819. goto done;
  820. }
  821. bRet = CryptDeriveKey(hProv,
  822. CALG_RC4,
  823. hHash,
  824. 0,
  825. &hCKey);
  826. if (!bRet)
  827. {
  828. dwRetCode = GetLastError();
  829. goto done;
  830. }
  831. bRet = CryptEncrypt(hCKey,
  832. 0,
  833. TRUE,
  834. 0,
  835. pbBufferToEncrypt,
  836. &dwLength,
  837. dwLength);
  838. if (!bRet)
  839. {
  840. dwRetCode = GetLastError();
  841. goto done;
  842. }
  843. done:
  844. if (hCKey != NULL)
  845. {
  846. bRet = CryptDestroyKey(hCKey);
  847. if (!bRet)
  848. {
  849. dwRetCode = GetLastError();
  850. }
  851. }
  852. if (hHash != NULL)
  853. {
  854. bRet = CryptDestroyHash(hHash);
  855. if (!bRet)
  856. {
  857. dwRetCode = GetLastError();
  858. }
  859. }
  860. if (hProv != NULL)
  861. {
  862. bRet = CryptReleaseContext( hProv, 0 );
  863. if (!bRet)
  864. {
  865. dwRetCode = GetLastError();
  866. }
  867. }
  868. #endif
  869. return dwRetCode;
  870. }
  871. DWORD LKPLiteDecryptUsingPID(LPTSTR lpszPID,
  872. BYTE * pbBufferToDecrypt,
  873. DWORD dwLength)
  874. {
  875. DWORD dwRetCode = ERROR_SUCCESS;
  876. #if 1
  877. dwRetCode = EncryptDecryptData(
  878. (PBYTE) lpszPID,
  879. lstrlen(lpszPID)*sizeof(TCHAR),
  880. pbBufferToDecrypt,
  881. dwLength
  882. );
  883. #else
  884. BOOL bRet;
  885. HCRYPTPROV hProv = NULL;
  886. HCRYPTKEY hCKey = NULL;
  887. HCRYPTHASH hHash = NULL;
  888. bRet = CryptAcquireContext(&hProv,
  889. NULL,
  890. NULL,
  891. PROV_RSA_FULL,
  892. CRYPT_VERIFYCONTEXT);
  893. if (!bRet)
  894. {
  895. dwRetCode = GetLastError();
  896. goto done;
  897. }
  898. bRet = CryptCreateHash(hProv,
  899. CALG_MD5,
  900. 0,
  901. 0,
  902. &hHash);
  903. if (!bRet)
  904. {
  905. dwRetCode = GetLastError();
  906. goto done;
  907. }
  908. bRet = CryptHashData(hHash,
  909. (BYTE *) lpszPID,
  910. lstrlen(lpszPID)*sizeof(TCHAR),
  911. 0);
  912. if (!bRet)
  913. {
  914. dwRetCode = GetLastError();
  915. goto done;
  916. }
  917. bRet = CryptDeriveKey(hProv,
  918. CALG_RC4,
  919. hHash,
  920. 0,
  921. &hCKey);
  922. if (!bRet)
  923. {
  924. dwRetCode = GetLastError();
  925. goto done;
  926. }
  927. bRet = CryptDecrypt(hCKey,
  928. 0,
  929. TRUE,
  930. 0,
  931. (BYTE *) pbBufferToDecrypt,
  932. &dwLength);
  933. if (!bRet)
  934. {
  935. dwRetCode = GetLastError();
  936. goto done;
  937. }
  938. done:
  939. if (hCKey != NULL)
  940. {
  941. bRet = CryptDestroyKey(hCKey);
  942. if (!bRet)
  943. {
  944. dwRetCode = GetLastError();
  945. }
  946. }
  947. if (hHash != NULL)
  948. {
  949. bRet = CryptDestroyHash(hHash);
  950. if (!bRet)
  951. {
  952. dwRetCode = GetLastError();
  953. }
  954. }
  955. if (hProv != NULL)
  956. {
  957. bRet = CryptReleaseContext( hProv, 0 );
  958. if (!bRet)
  959. {
  960. dwRetCode = GetLastError();
  961. }
  962. }
  963. #endif
  964. return dwRetCode;
  965. }