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.

1102 lines
33 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. // FILE : manage.c //
  3. // DESCRIPTION : Misc list/memory management routines. //
  4. // AUTHOR : //
  5. // HISTORY : //
  6. // Jan 25 1995 larrys Changed from Nametag //
  7. // Feb 23 1995 larrys Changed NTag_SetLastError to SetLastError //
  8. // Apr 19 1995 larrys Cleanup //
  9. // Sep 11 1995 Jeffspel/ramas Merge STT into default CSP //
  10. // Oct 27 1995 rajeshk RandSeed Stuff added hUID to PKCS2Encrypt //
  11. // Nov 3 1995 larrys Merge for NT checkin //
  12. // Nov 13 1995 larrys Fixed memory leak //
  13. // Dec 11 1995 larrys Added WIN95 password cache //
  14. // Dec 13 1995 larrys Remove MTS stuff //
  15. // May 15 1996 larrys Remove old cert stuff //
  16. // May 28 1996 larrys Added Win95 registry install stuff //
  17. // Jun 12 1996 larrys Encrypted public keys //
  18. // Jun 26 1996 larrys Put rsabase.sig into a resource for regsrv32 //
  19. // Sep 16 1996 mattt Added Strong provider type in #define //
  20. // Oct 14 1996 jeffspel Changed GenRandom to NewGenRandom //
  21. // May 23 1997 jeffspel Added provider type checking //
  22. // //
  23. // Copyright (C) 1993 Microsoft Corporation All Rights Reserved //
  24. /////////////////////////////////////////////////////////////////////////////
  25. #include "precomp.h"
  26. #include "resource.h"
  27. #include "nt_rsa.h"
  28. #include "randlib.h"
  29. #include "protstor.h"
  30. #include "ole2.h"
  31. #include "swnt_pk.h"
  32. #include "sgccheck.h"
  33. #include "swnt_pk.h"
  34. #include <delayimp.h>
  35. #define MAXITER 0xFFFF
  36. #define RSAFULL_TYPE_STRING "Type 001"
  37. #define RSA_SCH_TYPE_STRING "Type 012"
  38. #define RSAAES_TYPE_STRING "Type 024"
  39. #define MS_RSA_TYPE "RSA Full (Signature and Key Exchange)"
  40. #define MS_RSA_SCH_TYPE "RSA SChannel"
  41. #define MS_RSAAES_TYPE "RSA Full and AES"
  42. #define PROVPATH "SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider\\"
  43. #define PROVPATH_LEN sizeof(PROVPATH)
  44. #define TYPEPATH "SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider Types\\"
  45. #define TYPEPATH_LEN sizeof(TYPEPATH)
  46. HINSTANCE g_hInstance;
  47. extern DWORD SelfMACCheck(IN LPSTR pszImage);
  48. static CHAR l_szImagePath[MAX_PATH];
  49. #define KEYSIZE1024 0x88
  50. #if 0
  51. struct _mskey
  52. {
  53. BSAFE_PUB_KEY PUB;
  54. unsigned char pubmodulus[KEYSIZE1024];
  55. } MSKEY = {
  56. {
  57. 0x2bad85ae,
  58. 0x883adacc,
  59. 0xb32ebd68,
  60. 0xa7ec8b06,
  61. 0x58dbeb81,
  62. },
  63. {
  64. 0x42, 0x34, 0xb7, 0xab, 0x45, 0x0f, 0x60, 0xcd,
  65. 0x8f, 0x77, 0xb5, 0xd1, 0x79, 0x18, 0x34, 0xbe,
  66. 0x66, 0xcb, 0x5c, 0x66, 0x4a, 0x9f, 0x03, 0x18,
  67. 0x13, 0x36, 0x8e, 0x88, 0x21, 0x78, 0xb1, 0x94,
  68. 0xa1, 0xd5, 0x8f, 0x8c, 0xa5, 0xd3, 0x9f, 0x86,
  69. 0x43, 0x89, 0x05, 0xa0, 0xe3, 0xee, 0xe2, 0xd0,
  70. 0xe5, 0x1d, 0x5f, 0xaf, 0xff, 0x85, 0x71, 0x7a,
  71. 0x0a, 0xdb, 0x2e, 0xd8, 0xc3, 0x5f, 0x2f, 0xb1,
  72. 0xf0, 0x53, 0x98, 0x3b, 0x44, 0xee, 0x7f, 0xc9,
  73. 0x54, 0x26, 0xdb, 0xdd, 0xfe, 0x1f, 0xd0, 0xda,
  74. 0x96, 0x89, 0xc8, 0x9e, 0x2b, 0x5d, 0x96, 0xd1,
  75. 0xf7, 0x52, 0x14, 0x04, 0xfb, 0xf8, 0xee, 0x4d,
  76. 0x92, 0xd1, 0xb6, 0x37, 0x6a, 0xe0, 0xaf, 0xde,
  77. 0xc7, 0x41, 0x06, 0x7a, 0xe5, 0x6e, 0xb1, 0x8c,
  78. 0x8f, 0x17, 0xf0, 0x63, 0x8d, 0xaf, 0x63, 0xfd,
  79. 0x22, 0xc5, 0xad, 0x1a, 0xb1, 0xe4, 0x7a, 0x6b,
  80. 0x1e, 0x0e, 0xea, 0x60, 0x56, 0xbd, 0x49, 0xd0,
  81. }
  82. };
  83. struct _key
  84. {
  85. BSAFE_PUB_KEY PUB;
  86. unsigned char pubmodulus[KEYSIZE1024];
  87. } KEY = {
  88. {
  89. 0x3fcbf1a9,
  90. 0x08f597db,
  91. 0xe4aecab4,
  92. 0x75360f90,
  93. 0x9d6c0f00,
  94. },
  95. {
  96. 0x85, 0xdd, 0x9b, 0xf4, 0x4d, 0x0b, 0xc4, 0x96,
  97. 0x3e, 0x79, 0x86, 0x30, 0x6d, 0x27, 0x31, 0xee,
  98. 0x4a, 0x85, 0xf5, 0xff, 0xbb, 0xa9, 0xbd, 0x81,
  99. 0x86, 0xf2, 0x4f, 0x87, 0x6c, 0x57, 0x55, 0x19,
  100. 0xe4, 0xf4, 0x49, 0xa3, 0x19, 0x27, 0x08, 0x82,
  101. 0x9e, 0xf9, 0x8a, 0x8e, 0x41, 0xd6, 0x91, 0x71,
  102. 0x47, 0x48, 0xee, 0xd6, 0x24, 0x2d, 0xdd, 0x22,
  103. 0x72, 0x08, 0xc6, 0xa7, 0x34, 0x6f, 0x93, 0xd2,
  104. 0xe7, 0x72, 0x57, 0x78, 0x7a, 0x96, 0xc1, 0xe1,
  105. 0x47, 0x38, 0x78, 0x43, 0x53, 0xea, 0xf3, 0x88,
  106. 0x82, 0x66, 0x41, 0x43, 0xd4, 0x62, 0x44, 0x01,
  107. 0x7d, 0xb2, 0x16, 0xb3, 0x50, 0x89, 0xdb, 0x0a,
  108. 0x93, 0x17, 0x02, 0x02, 0x46, 0x49, 0x79, 0x76,
  109. 0x59, 0xb6, 0xb1, 0x2b, 0xfc, 0xb0, 0x9a, 0x21,
  110. 0xe6, 0xfa, 0x2d, 0x56, 0x07, 0x36, 0xbc, 0x13,
  111. 0x7f, 0x1c, 0xde, 0x55, 0xfb, 0x0d, 0x67, 0x0f,
  112. 0xc2, 0x17, 0x45, 0x8a, 0x14, 0x2b, 0xba, 0x55,
  113. }
  114. };
  115. #endif
  116. #if 0
  117. NTVersion(
  118. void)
  119. {
  120. static BOOL dwVersion = 0;
  121. OSVERSIONINFO osVer;
  122. memset(&osVer, 0, sizeof(OSVERSIONINFO));
  123. osVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  124. if(!GetVersionEx(&osVer) )
  125. goto ErrorExit;
  126. dwVersion = osVer.dwMajorVersion;
  127. ErrorExit:
  128. return dwVersion;
  129. }
  130. #endif
  131. /*static*/ DWORD
  132. SetCSPInfo(
  133. LPSTR pszProvider,
  134. LPSTR pszImagePath,
  135. BYTE *pbSig,
  136. DWORD cbSig,
  137. DWORD dwProvType,
  138. LPSTR pszType,
  139. LPSTR pszTypeName,
  140. BOOL fSigInFile,
  141. BOOL fMakeDefault)
  142. {
  143. DWORD dwReturn = ERROR_INTERNAL_ERROR;
  144. DWORD dwIgn;
  145. HKEY hKey = 0;
  146. HKEY hTypeKey = 0;
  147. DWORD cbProv;
  148. BYTE *pszProv = NULL;
  149. DWORD cbTypePath;
  150. BYTE *pszTypePath = NULL;
  151. DWORD dwVal = 0;
  152. DWORD dwSts;
  153. cbProv = PROVPATH_LEN + strlen(pszProvider);
  154. pszProv = _nt_malloc(cbProv);
  155. if (NULL == pszProv)
  156. {
  157. dwReturn = ERROR_NOT_ENOUGH_MEMORY;
  158. goto ErrorExit;
  159. }
  160. strcpy((LPSTR)pszProv, PROVPATH);
  161. strcat((LPSTR)pszProv, pszProvider);
  162. //
  163. // Create or open in local machine for provider:
  164. //
  165. dwSts = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  166. (const char *)pszProv,
  167. 0L, "", REG_OPTION_NON_VOLATILE,
  168. KEY_ALL_ACCESS, NULL, &hKey,
  169. &dwIgn);
  170. if (ERROR_SUCCESS != dwSts)
  171. {
  172. dwReturn = dwSts;
  173. goto ErrorExit;
  174. }
  175. //
  176. // Set Image path to: scp.dll
  177. //
  178. dwSts = RegSetValueEx(hKey, "Image Path", 0L, REG_SZ,
  179. (LPBYTE)pszImagePath,
  180. strlen(pszImagePath) + 1);
  181. if (ERROR_SUCCESS != dwSts)
  182. {
  183. dwReturn = dwSts;
  184. goto ErrorExit;
  185. }
  186. //
  187. // Set Type to: Type 003
  188. //
  189. dwSts = RegSetValueEx(hKey, "Type", 0L, REG_DWORD,
  190. (LPBYTE)&dwProvType,
  191. sizeof(DWORD));
  192. if (ERROR_SUCCESS != dwSts)
  193. {
  194. dwReturn = dwSts;
  195. goto ErrorExit;
  196. }
  197. if (fSigInFile)
  198. {
  199. //
  200. // Place signature in file value
  201. //
  202. dwSts = RegSetValueEx(hKey, "SigInFile", 0L,
  203. REG_DWORD, (LPBYTE)&dwVal,
  204. sizeof(DWORD));
  205. if (ERROR_SUCCESS != dwSts)
  206. {
  207. dwReturn = dwSts;
  208. goto ErrorExit;
  209. }
  210. }
  211. else
  212. {
  213. //
  214. // Place signature
  215. //
  216. dwSts = RegSetValueEx(hKey, "Signature", 0L,
  217. REG_BINARY, pbSig, cbSig);
  218. if (ERROR_SUCCESS != dwSts)
  219. {
  220. dwReturn = dwSts;
  221. goto ErrorExit;
  222. }
  223. }
  224. //
  225. // Create or open in local machine for provider type:
  226. //
  227. cbTypePath = TYPEPATH_LEN + strlen(pszType) + 1;
  228. pszTypePath = _nt_malloc(cbTypePath);
  229. if (NULL == pszTypePath)
  230. {
  231. dwReturn = ERROR_NOT_ENOUGH_MEMORY;
  232. goto ErrorExit;
  233. }
  234. strcpy((LPSTR)pszTypePath, TYPEPATH);
  235. strcat((LPSTR)pszTypePath, pszType);
  236. dwSts = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  237. (LPSTR)pszTypePath,
  238. 0L, "", REG_OPTION_NON_VOLATILE,
  239. KEY_ALL_ACCESS, NULL, &hTypeKey,
  240. &dwIgn);
  241. if (ERROR_SUCCESS != dwSts)
  242. {
  243. dwReturn = dwSts;
  244. goto ErrorExit;
  245. }
  246. if ((REG_CREATED_NEW_KEY == dwIgn) || fMakeDefault)
  247. {
  248. dwSts = RegSetValueEx(hTypeKey, "Name", 0L,
  249. REG_SZ, (LPBYTE)pszProvider,
  250. strlen(pszProvider) + 1);
  251. if (ERROR_SUCCESS != dwSts)
  252. {
  253. dwReturn = dwSts;
  254. goto ErrorExit;
  255. }
  256. dwSts = RegSetValueEx(hTypeKey, "TypeName", 0L,
  257. REG_SZ, (LPBYTE)pszTypeName,
  258. strlen(pszTypeName) + 1);
  259. if (ERROR_SUCCESS != dwSts)
  260. {
  261. dwReturn = dwSts;
  262. goto ErrorExit;
  263. }
  264. }
  265. dwReturn = ERROR_SUCCESS;
  266. ErrorExit:
  267. if (hKey)
  268. RegCloseKey(hKey);
  269. if (hTypeKey)
  270. RegCloseKey(hTypeKey);
  271. if (pszProv)
  272. _nt_free(pszProv, 0);
  273. if (pszTypePath)
  274. _nt_free(pszTypePath, 0);
  275. return dwReturn;
  276. }
  277. // See if a handle of the given type is in the list.
  278. // If it is, return the data that the item holds.
  279. void *
  280. NTLCheckList(
  281. HNTAG hThisThing,
  282. BYTE bTypeValue)
  283. {
  284. HTABLE *pTable;
  285. pTable = (HTABLE*)(hThisThing ^ HANDLE_MASK);
  286. if ((BYTE)pTable->dwType != bTypeValue)
  287. return NULL;
  288. return (void*)pTable->pItem;
  289. }
  290. // Find & validate the passed list item against the user and type.
  291. DWORD
  292. NTLValidate(
  293. HNTAG hItem,
  294. HCRYPTPROV hUID,
  295. BYTE bTypeValue,
  296. LPVOID *ppvRet)
  297. {
  298. DWORD dwReturn = ERROR_INTERNAL_ERROR;
  299. void *pTmpVal;
  300. // check to see if the key is in the key list
  301. pTmpVal = NTLCheckList(hItem, bTypeValue);
  302. if (pTmpVal == NULL)
  303. {
  304. dwReturn = (DWORD)NTE_FAIL; // converted by caller
  305. goto ErrorExit;
  306. }
  307. // check to make sure there is a key value
  308. if ((bTypeValue == KEY_HANDLE) &&
  309. (((PNTAGKeyList)pTmpVal)->pKeyValue == NULL))
  310. {
  311. ASSERT(((PNTAGKeyList)pTmpVal)->cbKeyLen == 0);
  312. dwReturn = (DWORD)NTE_BAD_KEY;
  313. goto ErrorExit;
  314. }
  315. // make sure the UIDs are the same
  316. if (((PNTAGKeyList)pTmpVal)->hUID != hUID)
  317. {
  318. dwReturn = (DWORD)NTE_BAD_UID;
  319. goto ErrorExit;
  320. }
  321. *ppvRet = pTmpVal;
  322. dwReturn = ERROR_SUCCESS;
  323. ErrorExit:
  324. return dwReturn;
  325. }
  326. // Make a new list item of the given type, and assign the data to it.
  327. DWORD
  328. NTLMakeItem(
  329. HNTAG *phItem,
  330. BYTE bTypeValue,
  331. void *NewData)
  332. {
  333. DWORD dwReturn = ERROR_INTERNAL_ERROR;
  334. HTABLE *NewMember;
  335. NewMember = (HTABLE *)_nt_malloc(sizeof(HTABLE));
  336. if (NULL == NewMember)
  337. {
  338. dwReturn = ERROR_NOT_ENOUGH_MEMORY;
  339. goto ErrorExit;
  340. }
  341. NewMember->pItem = NewData;
  342. NewMember->dwType = bTypeValue;
  343. *phItem = (HNTAG)((HNTAG)NewMember ^ HANDLE_MASK);
  344. dwReturn = ERROR_SUCCESS;
  345. ErrorExit:
  346. return dwReturn;
  347. }
  348. // Remove the handle. Assumes that any memory used by the handle data has
  349. // been freed.
  350. void
  351. NTLDelete(
  352. HNTAG hItem)
  353. {
  354. HTABLE *pTable;
  355. pTable = (HTABLE*)(hItem ^ HANDLE_MASK);
  356. _nt_free(pTable, sizeof(HTABLE));
  357. }
  358. /****************************************************************/
  359. /* FreeUserRec frees the dynamically allocated memory for the */
  360. /* appropriate fields of the UserRec structure. */
  361. /* */
  362. /* MTS: we assume that pUser has only one reference (no */
  363. /* MTS: multiple logon's for the same user name). */
  364. /****************************************************************/
  365. void
  366. FreeUserRec(
  367. PNTAGUserList pUser)
  368. {
  369. if (pUser != NULL)
  370. {
  371. // No need to zero lengths, since entire struct is going away
  372. if (pUser->pExchPrivKey)
  373. {
  374. memnuke(pUser->pExchPrivKey, pUser->ExchPrivLen);
  375. _nt_free (pUser->pExchPrivKey, 0);
  376. }
  377. if (pUser->pSigPrivKey)
  378. {
  379. memnuke(pUser->pSigPrivKey, pUser->SigPrivLen);
  380. _nt_free (pUser->pSigPrivKey, 0);
  381. }
  382. if (pUser->pUser)
  383. {
  384. _nt_free(pUser->pUser, 0);
  385. }
  386. if (NULL != pUser->szProviderName)
  387. {
  388. _nt_free(pUser->szProviderName, 0);
  389. }
  390. if (pUser->pCachePW)
  391. {
  392. memnuke(pUser->pCachePW, STORAGE_RC4_KEYLEN);
  393. _nt_free(pUser->pCachePW, 0);
  394. }
  395. if (pUser->pPStore)
  396. {
  397. FreePSInfo(pUser->pPStore);
  398. }
  399. #ifdef USE_SGC
  400. // free the SGC key info
  401. SGCDeletePubKeyValues(&pUser->pbSGCKeyMod,
  402. &pUser->cbSGCKeyMod,
  403. &pUser->dwSGCKeyExpo);
  404. #endif
  405. FreeContainerInfo(&pUser->ContInfo);
  406. FreeOffloadInfo(pUser->pOffloadInfo);
  407. DeleteCriticalSection(&pUser->CritSec);
  408. ZeroMemory(pUser, sizeof(NTAGUserList));
  409. _nt_free (pUser, 0);
  410. }
  411. }
  412. // RSA private key in PRIVATEKEYBLOB format
  413. static BYTE l_rgbRSAPriv[] =
  414. {
  415. 0x52, 0x53, 0x41, 0x32, 0x48, 0x00, 0x00, 0x00,
  416. 0x00, 0x02, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00,
  417. 0x01, 0x00, 0x01, 0x00, 0xEF, 0x4C, 0x0D, 0x34,
  418. 0xCF, 0x44, 0x0F, 0xB1, 0x73, 0xAC, 0xD4, 0x9B,
  419. 0xBE, 0xCC, 0x2D, 0x11, 0x2A, 0x2B, 0xBD, 0x21,
  420. 0x04, 0x8E, 0xAC, 0xAD, 0xD5, 0xFC, 0xD2, 0x50,
  421. 0x14, 0x35, 0x1B, 0x43, 0x15, 0x62, 0x67, 0x8F,
  422. 0x5E, 0x00, 0xB9, 0x25, 0x1B, 0xE2, 0x4F, 0xBE,
  423. 0xA1, 0x50, 0xA1, 0x44, 0x3B, 0x17, 0xD8, 0x91,
  424. 0xF5, 0x28, 0xF9, 0xFA, 0xAE, 0xE7, 0xC0, 0xFD,
  425. 0xB9, 0xCD, 0x76, 0x4F, 0x00, 0x00, 0x00, 0x00,
  426. 0x00, 0x00, 0x00, 0x00, 0xE9, 0xBB, 0x38, 0x52,
  427. 0xD9, 0x0D, 0x56, 0xD7, 0x36, 0xBA, 0xDC, 0xE8,
  428. 0xB5, 0x57, 0x56, 0x13, 0x1A, 0x3A, 0x43, 0x30,
  429. 0xDE, 0x7D, 0x76, 0x6F, 0xBB, 0x71, 0x3B, 0x0A,
  430. 0x92, 0xBA, 0x60, 0x94, 0x00, 0x00, 0x00, 0x00,
  431. 0x17, 0x33, 0x3D, 0xB5, 0xEF, 0xD8, 0x2B, 0xDE,
  432. 0xCD, 0xA6, 0x6A, 0x94, 0x17, 0xC3, 0x57, 0xE9,
  433. 0x2E, 0x1C, 0x9F, 0x35, 0xDA, 0xA4, 0xBD, 0x02,
  434. 0x5B, 0x9D, 0xD1, 0x38, 0x4C, 0xF2, 0x19, 0x89,
  435. 0x00, 0x00, 0x00, 0x00, 0x89, 0x21, 0xCB, 0x3F,
  436. 0x0C, 0xA7, 0x71, 0xBC, 0xF6, 0xA1, 0x87, 0xDF,
  437. 0x00, 0x2D, 0x27, 0x64, 0x4A, 0xD4, 0x93, 0x9F,
  438. 0x58, 0x93, 0x4B, 0x83, 0x1E, 0xAB, 0xD8, 0x5D,
  439. 0xBC, 0x0E, 0x58, 0x03, 0x00, 0x00, 0x00, 0x00,
  440. 0xAB, 0x09, 0xD7, 0x21, 0xBA, 0x6F, 0x55, 0x08,
  441. 0x12, 0xEE, 0x5B, 0x47, 0x6B, 0x9F, 0x3F, 0xD3,
  442. 0xFC, 0xEA, 0xB5, 0x25, 0x19, 0xB7, 0x9E, 0xBD,
  443. 0xDF, 0x6F, 0x7F, 0x96, 0x00, 0x88, 0xC6, 0x7B,
  444. 0x00, 0x00, 0x00, 0x00, 0x95, 0x0B, 0x23, 0xC5,
  445. 0x72, 0x98, 0x9D, 0x49, 0x7A, 0x46, 0x4E, 0xE1,
  446. 0xE6, 0x2F, 0xC6, 0x63, 0x21, 0x8F, 0x66, 0xDC,
  447. 0x9B, 0xCC, 0xE2, 0x27, 0x03, 0x27, 0x85, 0xF0,
  448. 0x3A, 0x02, 0xFB, 0x40, 0x00, 0x00, 0x00, 0x00,
  449. 0x51, 0x74, 0xF6, 0xF2, 0x23, 0xEC, 0xA1, 0x76,
  450. 0x55, 0x58, 0x07, 0x71, 0xBF, 0x7F, 0x0A, 0x1E,
  451. 0x6B, 0x48, 0x48, 0xBB, 0x92, 0xB6, 0x2A, 0xB1,
  452. 0x07, 0xA4, 0x21, 0xD1, 0xC6, 0xCB, 0x5F, 0x40,
  453. 0xCE, 0xDD, 0xBA, 0xDB, 0xFC, 0x17, 0xFB, 0xA7,
  454. 0xBD, 0xE1, 0xF4, 0x63, 0xD8, 0x9E, 0x89, 0xE2,
  455. 0xDD, 0x7A, 0xEC, 0x11, 0xD6, 0xA9, 0x9C, 0xBA,
  456. 0xC7, 0x5E, 0x35, 0x96, 0xA6, 0x6F, 0x7F, 0x2C,
  457. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  458. };
  459. // RSA private key in PUBLICKEYBLOB format
  460. static BYTE l_rgbRSAPub[] =
  461. {
  462. 0x52, 0x53, 0x41, 0x31, 0x48, 0x00, 0x00, 0x00,
  463. 0x00, 0x02, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00,
  464. 0x01, 0x00, 0x01, 0x00, 0xEF, 0x4C, 0x0D, 0x34,
  465. 0xCF, 0x44, 0x0F, 0xB1, 0x73, 0xAC, 0xD4, 0x9B,
  466. 0xBE, 0xCC, 0x2D, 0x11, 0x2A, 0x2B, 0xBD, 0x21,
  467. 0x04, 0x8E, 0xAC, 0xAD, 0xD5, 0xFC, 0xD2, 0x50,
  468. 0x14, 0x35, 0x1B, 0x43, 0x15, 0x62, 0x67, 0x8F,
  469. 0x5E, 0x00, 0xB9, 0x25, 0x1B, 0xE2, 0x4F, 0xBE,
  470. 0xA1, 0x50, 0xA1, 0x44, 0x3B, 0x17, 0xD8, 0x91,
  471. 0xF5, 0x28, 0xF9, 0xFA, 0xAE, 0xE7, 0xC0, 0xFD,
  472. 0xB9, 0xCD, 0x76, 0x4F, 0x00, 0x00, 0x00, 0x00,
  473. 0x00, 0x00, 0x00, 0x00
  474. };
  475. // known result of an MD5 hash on the above buffer
  476. static BYTE l_rgbKnownMD5[] =
  477. {
  478. 0xb8, 0x2f, 0x6b, 0x11, 0x31, 0xc8, 0xec, 0xf4,
  479. 0xfe, 0x0b, 0xf0, 0x6d, 0x2a, 0xda, 0x3f, 0xc3
  480. };
  481. // known result of an SHA-1 hash on the above buffer
  482. static BYTE l_rgbKnownSHA1[] =
  483. {
  484. 0xe8, 0x96, 0x82, 0x85, 0xeb, 0xae, 0x01, 0x14,
  485. 0x73, 0xf9, 0x08, 0x45, 0xc0, 0x6a, 0x6d, 0x3e,
  486. 0x69, 0x80, 0x6a, 0x0c
  487. };
  488. // known key, plaintext, and ciphertext for RC4
  489. static BYTE l_rgbRC4Key[] = {0x61, 0x8a, 0x63, 0xd2, 0xfb};
  490. static BYTE l_rgbRC4KnownPlaintext[] = {0xDC, 0xEE, 0x4C, 0xF9, 0x2C};
  491. static BYTE l_rgbRC4KnownCiphertext[] = {0xF1, 0x38, 0x29, 0xC9, 0xDE};
  492. // IV for all block ciphers
  493. BYTE l_rgbIV[] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF};
  494. // known key, plaintext, and ciphertext for RC2
  495. BYTE l_rgbRC2Key[] = {0x59, 0x45, 0x9a, 0xf9, 0x27, 0x84, 0x74, 0xCA};
  496. BYTE l_rgbRC2KnownPlaintext[] = {0xD5, 0x58, 0x75, 0x12, 0xCE, 0xEF, 0x77, 0x93};
  497. BYTE l_rgbRC2KnownCiphertext[] = {0x7b, 0x98, 0xdf, 0x9d, 0xa2, 0xdc, 0x7b, 0x7a};
  498. BYTE l_rgbRC2CBCCiphertext[] = {0x9d, 0x93, 0x8e, 0xf6, 0x7c, 0x01, 0x5e, 0xeb};
  499. // known key, plaintext, and ciphertext for DES40 (CALG_CYLINK_MEK)
  500. BYTE l_rgbDES40Key[] = {0x01, 0x23, 0x04, 0x67, 0x08, 0xab, 0x0d, 0xef};
  501. BYTE l_rgbDES40KnownPlaintext[] = {0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74};
  502. BYTE l_rgbDES40KnownCiphertext[] = {0xac, 0x97, 0x4d, 0xd9, 0x02, 0x13, 0x88, 0x2c};
  503. BYTE l_rgbDES40CBCCiphertext[] = {0x47, 0xdc, 0xf0, 0x13, 0x7f, 0xa5, 0xd6, 0x32};
  504. // known key, plaintext, and ciphertext for DES
  505. BYTE l_rgbDESKey[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
  506. BYTE l_rgbDESKnownPlaintext[] = {0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74};
  507. BYTE l_rgbDESKnownCiphertext[] = {0x3F, 0xA4, 0x0E, 0x8A, 0x98, 0x4D, 0x48, 0x15};
  508. BYTE l_rgbDESCBCCiphertext[] = {0xE5, 0xC7, 0xCD, 0xDE, 0x87, 0x2B, 0xF2, 0x7C};
  509. // known key, plaintext, and ciphertext for 3 key 3DES
  510. BYTE l_rgb3DESKey[] =
  511. {
  512. 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
  513. 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
  514. 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23
  515. };
  516. BYTE l_rgb3DESKnownPlaintext[] = {0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74};
  517. BYTE l_rgb3DESKnownCiphertext[] = {0x31, 0x4F, 0x83, 0x27, 0xFA, 0x7A, 0x09, 0xA8};
  518. BYTE l_rgb3DESCBCCiphertext[] = {0xf3, 0xc0, 0xff, 0x02, 0x6c, 0x02, 0x30, 0x89};
  519. // known key, plaintext, and ciphertext for 2 key 3DES
  520. BYTE l_rgb3DES112Key[] =
  521. {
  522. 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
  523. 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01
  524. };
  525. BYTE l_rgb3DES112KnownPlaintext[] = {0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74};
  526. BYTE l_rgb3DES112KnownCiphertext[] = {0xb7, 0x83, 0x57, 0x79, 0xee, 0x26, 0xac, 0xb7};
  527. BYTE l_rgb3DES112CBCCiphertext[] = {0x13, 0x4b, 0x98, 0xf8, 0xee, 0xb3, 0xf6, 0x07};
  528. //
  529. // AES vectors are from NIST web site
  530. //
  531. // known key, plaintext, and ciphertext for 128 bit AES
  532. BYTE l_rgbAES128Key[] =
  533. {
  534. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  535. 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
  536. };
  537. BYTE l_rgbAES128KnownPlaintext[] =
  538. {
  539. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  540. 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
  541. };
  542. BYTE l_rgbAES128KnownCiphertext[] =
  543. {
  544. 0x0A, 0x94, 0x0B, 0xB5, 0x41, 0x6E, 0xF0, 0x45,
  545. 0xF1, 0xC3, 0x94, 0x58, 0xC6, 0x53, 0xEA, 0x5A
  546. };
  547. // known key, plaintext, and ciphertext for 192 bit AES
  548. BYTE l_rgbAES192Key[] =
  549. {
  550. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  551. 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
  552. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17
  553. };
  554. BYTE l_rgbAES192KnownPlaintext[] =
  555. {
  556. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  557. 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
  558. };
  559. BYTE l_rgbAES192KnownCiphertext[] =
  560. {
  561. 0x00, 0x60, 0xBF, 0xFE, 0x46, 0x83, 0x4B, 0xB8,
  562. 0xDA, 0x5C, 0xF9, 0xA6, 0x1F, 0xF2, 0x20, 0xAE
  563. };
  564. // known key, plaintext, and ciphertext for 256 bit AES
  565. BYTE l_rgbAES256Key[] =
  566. {
  567. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  568. 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
  569. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  570. 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
  571. };
  572. BYTE l_rgbAES256KnownPlaintext[] =
  573. {
  574. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  575. 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
  576. };
  577. BYTE l_rgbAES256KnownCiphertext[] =
  578. {
  579. 0x5A, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
  580. 0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92
  581. };
  582. // **********************************************************************
  583. // AlgorithmCheck performs known answer tests using the algorithms
  584. // supported by the provider.
  585. // **********************************************************************
  586. /*static*/ DWORD
  587. AlgorithmCheck(
  588. void)
  589. {
  590. DWORD dwReturn = ERROR_INTERNAL_ERROR;
  591. BYTE rgbMD5[MD5DIGESTLEN];
  592. BYTE rgbSHA1[A_SHA_DIGEST_LEN];
  593. DWORD dwSts;
  594. memset(rgbMD5, 0, sizeof(rgbMD5));
  595. memset(rgbSHA1, 0, sizeof(rgbSHA1));
  596. // check if RSA is working properly
  597. dwSts = EncryptAndDecryptWithRSAKey(l_rgbRSAPub, l_rgbRSAPriv, TRUE, TRUE);
  598. if (ERROR_SUCCESS != dwSts)
  599. {
  600. dwReturn = dwSts;
  601. goto ErrorExit;
  602. }
  603. // check if RSA is working properly
  604. dwSts = EncryptAndDecryptWithRSAKey(l_rgbRSAPub, l_rgbRSAPriv, FALSE, TRUE);
  605. if (ERROR_SUCCESS != dwSts)
  606. {
  607. dwReturn = dwSts;
  608. goto ErrorExit;
  609. }
  610. #ifdef CSP_USE_MD5
  611. // known answer test with MD5 (this function is found in hash.c)
  612. if (!TestMD5((LPBYTE)"HashThis", 8, rgbMD5))
  613. {
  614. dwReturn = (DWORD)NTE_FAIL;
  615. goto ErrorExit;
  616. }
  617. if (memcmp(rgbMD5, l_rgbKnownMD5, sizeof(rgbMD5)))
  618. {
  619. dwReturn = (DWORD)NTE_FAIL;
  620. goto ErrorExit;
  621. }
  622. #endif // CSP_USE_MD5
  623. #ifdef CSP_USE_SHA1
  624. // known answer test with SHA-1 (this function is found in hash.c)
  625. if (!TestSHA1((LPBYTE)"HashThis", 8, rgbSHA1))
  626. {
  627. dwReturn = (DWORD)NTE_FAIL;
  628. goto ErrorExit;
  629. }
  630. if (memcmp(rgbSHA1, l_rgbKnownSHA1, sizeof(rgbSHA1)))
  631. {
  632. dwReturn = (DWORD)NTE_FAIL;
  633. goto ErrorExit;
  634. }
  635. #endif // CSP_USE_SHA1
  636. #ifdef CSP_USE_RC4
  637. // known answer test with RC4
  638. dwSts = TestSymmetricAlgorithm(CALG_RC4,
  639. l_rgbRC4Key,
  640. sizeof(l_rgbRC4Key),
  641. l_rgbRC4KnownPlaintext,
  642. sizeof(l_rgbRC4KnownPlaintext),
  643. l_rgbRC4KnownCiphertext, NULL);
  644. if (ERROR_SUCCESS != dwSts)
  645. {
  646. dwReturn = dwSts;
  647. goto ErrorExit;
  648. }
  649. #endif // CSP_USE_RC4
  650. #ifdef CSP_USE_RC2
  651. // known answer test with RC2 - ECB
  652. dwSts = TestSymmetricAlgorithm(CALG_RC2,
  653. l_rgbRC2Key,
  654. sizeof(l_rgbRC2Key),
  655. l_rgbRC2KnownPlaintext,
  656. sizeof(l_rgbRC2KnownPlaintext),
  657. l_rgbRC2KnownCiphertext,
  658. NULL);
  659. if (ERROR_SUCCESS != dwSts)
  660. {
  661. dwReturn = dwSts;
  662. goto ErrorExit;
  663. }
  664. // known answer test with RC2 - CBC
  665. dwSts = TestSymmetricAlgorithm(CALG_RC2,
  666. l_rgbRC2Key,
  667. sizeof(l_rgbRC2Key),
  668. l_rgbRC2KnownPlaintext,
  669. sizeof(l_rgbRC2KnownPlaintext),
  670. l_rgbRC2CBCCiphertext,
  671. l_rgbIV);
  672. if (ERROR_SUCCESS != dwSts)
  673. {
  674. dwReturn = dwSts;
  675. goto ErrorExit;
  676. }
  677. #endif // CSP_USE_RC2
  678. #ifdef CSP_USE_DES
  679. // known answer test with DES - ECB
  680. dwSts = TestSymmetricAlgorithm(CALG_DES,
  681. l_rgbDESKey,
  682. sizeof(l_rgbDESKey),
  683. l_rgbDESKnownPlaintext,
  684. sizeof(l_rgbDESKnownPlaintext),
  685. l_rgbDESKnownCiphertext,
  686. NULL);
  687. if (ERROR_SUCCESS != dwSts)
  688. {
  689. dwReturn = dwSts;
  690. goto ErrorExit;
  691. }
  692. // known answer test with DES - CBC
  693. dwSts = TestSymmetricAlgorithm(CALG_DES,
  694. l_rgbDESKey,
  695. sizeof(l_rgbDESKey),
  696. l_rgbDESKnownPlaintext,
  697. sizeof(l_rgbDESKnownPlaintext),
  698. l_rgbDESCBCCiphertext,
  699. l_rgbIV);
  700. if (ERROR_SUCCESS != dwSts)
  701. {
  702. dwReturn = dwSts;
  703. goto ErrorExit;
  704. }
  705. #endif // CSP_USE_DES
  706. #ifdef CSP_USE_3DES
  707. // known answer test with 3DES - ECB
  708. dwSts = TestSymmetricAlgorithm(CALG_3DES,
  709. l_rgb3DESKey,
  710. sizeof(l_rgb3DESKey),
  711. l_rgb3DESKnownPlaintext,
  712. sizeof(l_rgb3DESKnownPlaintext),
  713. l_rgb3DESKnownCiphertext,
  714. NULL);
  715. if (ERROR_SUCCESS != dwSts)
  716. {
  717. dwReturn = dwSts;
  718. goto ErrorExit;
  719. }
  720. // known answer test with 3DES - CBC
  721. dwSts = TestSymmetricAlgorithm(CALG_3DES,
  722. l_rgb3DESKey,
  723. sizeof(l_rgb3DESKey),
  724. l_rgb3DESKnownPlaintext,
  725. sizeof(l_rgb3DESKnownPlaintext),
  726. l_rgb3DESCBCCiphertext,
  727. l_rgbIV);
  728. if (ERROR_SUCCESS != dwSts)
  729. {
  730. dwReturn = dwSts;
  731. goto ErrorExit;
  732. }
  733. // known answer test with 3DES 112 - ECB
  734. dwSts = TestSymmetricAlgorithm(CALG_3DES_112,
  735. l_rgb3DES112Key,
  736. sizeof(l_rgb3DES112Key),
  737. l_rgb3DES112KnownPlaintext,
  738. sizeof(l_rgb3DES112KnownPlaintext),
  739. l_rgb3DES112KnownCiphertext,
  740. NULL);
  741. if (ERROR_SUCCESS != dwSts)
  742. {
  743. dwReturn = dwSts;
  744. goto ErrorExit;
  745. }
  746. dwSts = TestSymmetricAlgorithm(CALG_3DES_112,
  747. l_rgb3DES112Key,
  748. sizeof(l_rgb3DES112Key),
  749. l_rgb3DES112KnownPlaintext,
  750. sizeof(l_rgb3DES112KnownPlaintext),
  751. l_rgb3DES112CBCCiphertext,
  752. l_rgbIV);
  753. if (ERROR_SUCCESS != dwSts)
  754. {
  755. dwReturn = dwSts;
  756. goto ErrorExit;
  757. }
  758. #endif // CSP_USE_3DES
  759. #ifdef CSP_USE_AES
  760. // known answer test with AES 128 - ECB
  761. dwSts = TestSymmetricAlgorithm(CALG_AES_128,
  762. l_rgbAES128Key,
  763. sizeof(l_rgbAES128Key),
  764. l_rgbAES128KnownPlaintext,
  765. sizeof(l_rgbAES128KnownPlaintext),
  766. l_rgbAES128KnownCiphertext,
  767. NULL);
  768. if (ERROR_SUCCESS != dwSts)
  769. {
  770. dwReturn = dwSts;
  771. goto ErrorExit;
  772. }
  773. // known answer test with AES 192 - ECB
  774. dwSts = TestSymmetricAlgorithm(CALG_AES_192,
  775. l_rgbAES192Key,
  776. sizeof(l_rgbAES192Key),
  777. l_rgbAES192KnownPlaintext,
  778. sizeof(l_rgbAES192KnownPlaintext),
  779. l_rgbAES192KnownCiphertext,
  780. NULL);
  781. if (ERROR_SUCCESS != dwSts)
  782. {
  783. dwReturn = dwSts;
  784. goto ErrorExit;
  785. }
  786. // known answer test with AES 256 - ECB
  787. dwSts = TestSymmetricAlgorithm(CALG_AES_256,
  788. l_rgbAES256Key,
  789. sizeof(l_rgbAES256Key),
  790. l_rgbAES256KnownPlaintext,
  791. sizeof(l_rgbAES256KnownPlaintext),
  792. l_rgbAES256KnownCiphertext,
  793. NULL);
  794. if (ERROR_SUCCESS != dwSts)
  795. {
  796. dwReturn = dwSts;
  797. goto ErrorExit;
  798. }
  799. #endif
  800. dwReturn = ERROR_SUCCESS;
  801. ErrorExit:
  802. return dwReturn;
  803. }
  804. BOOL WINAPI
  805. DllInitialize(
  806. IN PVOID hmod,
  807. IN ULONG Reason,
  808. IN PCONTEXT Context) // Unused parameter
  809. {
  810. g_hInstance = (HINSTANCE) hmod;
  811. if (Reason == DLL_PROCESS_ATTACH)
  812. {
  813. DWORD dwLen;
  814. DisableThreadLibraryCalls(hmod);
  815. // Get our image name.
  816. dwLen = GetModuleFileName(hmod, l_szImagePath,
  817. sizeof(l_szImagePath) / sizeof(CHAR));
  818. if (0 == dwLen)
  819. return FALSE;
  820. // load strings from csprc.dll
  821. if (ERROR_SUCCESS != LoadStrings())
  822. return FALSE;
  823. // Verify this image hasn't been modified.
  824. if (ERROR_SUCCESS != SelfMACCheck(l_szImagePath))
  825. return FALSE;
  826. // do a start up check on all supported algorithms to make sure they
  827. // are working correctly
  828. if (ERROR_SUCCESS != AlgorithmCheck())
  829. return FALSE;
  830. }
  831. else if (Reason == DLL_PROCESS_DETACH)
  832. {
  833. // free the strings loaded from csprc.dll
  834. UnloadStrings();
  835. }
  836. return TRUE;
  837. }
  838. STDAPI
  839. DllRegisterServer(
  840. void)
  841. {
  842. return ERROR_SUCCESS;
  843. }
  844. STDAPI
  845. DllUnregisterServer(
  846. void)
  847. {
  848. return S_OK;
  849. }
  850. //
  851. // Delayload stubs
  852. //
  853. BOOL RsaenhGetProfileTypeStub(
  854. DWORD dwFlags)
  855. {
  856. return FALSE;
  857. }
  858. HRESULT RsaenhSHGetFolderPathWStub(
  859. HWND hwndOwner,
  860. int nFolder,
  861. HANDLE hToken,
  862. DWORD dwFlags,
  863. LPWSTR pwszPath)
  864. {
  865. return E_FAIL;
  866. }
  867. void RsaenhCoTaskMemFreeStub(
  868. void *pv)
  869. {
  870. return;
  871. }
  872. BOOL WINAPI RsaenhCryptUnprotectDataStub(
  873. DATA_BLOB *pDataIn,
  874. LPWSTR *ppszDataDescr,
  875. DATA_BLOB *pOptionalEntropy,
  876. PVOID pvReserved,
  877. CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct,
  878. DWORD dwFlags,
  879. DATA_BLOB *pDataOut)
  880. {
  881. return FALSE;
  882. }
  883. BOOL WINAPI RsaenhCryptProtectDataStub(
  884. DATA_BLOB *pDataIn,
  885. LPCWSTR szDataDescr,
  886. DATA_BLOB *pOptionalEntropy,
  887. PVOID pvReserved,
  888. CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct,
  889. DWORD dwFlags,
  890. DATA_BLOB *pDataOut)
  891. {
  892. return FALSE;
  893. }
  894. RPC_STATUS RPC_ENTRY RsaenhUuidCreateStub(
  895. UUID *Uuid)
  896. {
  897. return E_FAIL;
  898. }
  899. RPC_STATUS RPC_ENTRY RsaenhUuidToStringAStub(
  900. UUID *Uuid,
  901. unsigned char **StringUuid)
  902. {
  903. return E_FAIL;
  904. }
  905. RPC_STATUS RPC_ENTRY RsaenhRpcStringFreeAStub(
  906. unsigned char **String)
  907. {
  908. return E_FAIL;
  909. }
  910. HRESULT __stdcall RsaenhPStoreCreateInstance(
  911. IPStore __RPC_FAR *__RPC_FAR *ppProvider,
  912. PST_PROVIDERID __RPC_FAR *pProviderID,
  913. void __RPC_FAR *pReserved,
  914. DWORD dwFlags)
  915. {
  916. return E_FAIL;
  917. }
  918. //
  919. // Delayload failure and notification hook
  920. //
  921. BOOL RsaenhLookupModule(LPCSTR pszDll)
  922. {
  923. unsigned u;
  924. for (u = 0; u < g_cRsaenhDelayLoadStubs; u++) {
  925. if (0 == _stricmp(pszDll, g_RsaenhDelayLoadStubs[u].pszDll))
  926. return TRUE;
  927. }
  928. return FALSE;
  929. }
  930. FARPROC RsaenhLookupExport(DelayLoadProc *pdlp)
  931. {
  932. unsigned u;
  933. FARPROC fpResult = NULL;
  934. if (! pdlp->fImportByName)
  935. goto Return;
  936. // could alphabetize and use binary search instead
  937. for (u = 0; u < g_cRsaenhDelayLoadStubs; u++) {
  938. if (0 == _stricmp(pdlp->szProcName, g_RsaenhDelayLoadStubs[u].pszExport)) {
  939. fpResult = g_RsaenhDelayLoadStubs[u].fpStub;
  940. goto Return;
  941. }
  942. }
  943. Return:
  944. return fpResult;
  945. }
  946. FARPROC WINAPI RsaenhDelayLoadHook(unsigned uReason, PDelayLoadInfo pdli)
  947. {
  948. FARPROC fpResult = NULL;
  949. switch (uReason) {
  950. case dliFailLoadLib:
  951. if (RsaenhLookupModule(pdli->szDll))
  952. fpResult = (FARPROC) -1;
  953. break;
  954. case dliNotePreGetProcAddress:
  955. if ((HINSTANCE) -1 == pdli->hmodCur) {
  956. SetLastError(ERROR_MOD_NOT_FOUND);
  957. fpResult = RsaenhLookupExport(&pdli->dlp);
  958. }
  959. break;
  960. case dliFailGetProc:
  961. if ((HINSTANCE) -1 == pdli->hmodCur) {
  962. SetLastError(ERROR_PROC_NOT_FOUND);
  963. fpResult = RsaenhLookupExport(&pdli->dlp);
  964. }
  965. break;
  966. }
  967. return fpResult;
  968. }
  969. PfnDliHook __pfnDliFailureHook2 = RsaenhDelayLoadHook;
  970. PfnDliHook __pfnDliNotifyHook = RsaenhDelayLoadHook;