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.

4651 lines
122 KiB

  1. // *****************************************************************************
  2. //
  3. // Purpose : Multithreaded stress test
  4. //
  5. // Created : arunm 03/20/96
  6. // Modified: dangriff 11/6/00
  7. //
  8. // *****************************************************************************
  9. #include <nt.h>
  10. #include <ntrtl.h>
  11. #include <nturtl.h>
  12. #include <windows.h>
  13. #include <stdlib.h>
  14. #include <stdio.h>
  15. #include <wincrypt.h>
  16. #include "strestst.h"
  17. #include <pincache.h>
  18. // ===========================================================================
  19. int Usage(void)
  20. {
  21. printf("%s -c <CSP Index> [options]\n", APP_NAME) ;
  22. printf(" -?: This message\n") ;
  23. printf(" -n <N>: # of threads to create (Def: %d)\n", StressGetDefaultThreadCount());
  24. printf(" -t <N>: End test in N minutes (Def: never end)\n");
  25. printf(" -e: Ephemeral keys\n");
  26. printf(" -u: User-protected keys (cannot be used with -e)\n");
  27. printf(" -r: Run regression tests\n");
  28. printf(" -d: Delete all key containers\n");
  29. printf(" -a<Flags> <Container>: Call CryptAcquireContext with Flags\n");
  30. printf("\nCryptAcquireContext Flags:\n");
  31. printf(" v - CRYPT_VERIFYCONTEXT (don't specify <Container>)\n");
  32. printf(" n - CRYPT_NEWKEYSET\n");
  33. printf(" l - CRYPT_MACHINE_KEYSET\n");
  34. printf(" d - CRYPT_DELETEKEYSET\n");
  35. printf(" q - CRYPT_SILENT\n");
  36. printf(" x - create a Key Exchange keyset\n");
  37. printf(" s - create a Signature keyset\n");
  38. printf(" u - request keyset to be User Protected\n");
  39. return 1;
  40. }
  41. //
  42. // Function: StressGetDefaultThreadCount
  43. //
  44. DWORD StressGetDefaultThreadCount(void)
  45. {
  46. SYSTEM_INFO SystemInfo;
  47. ZeroMemory(&SystemInfo, sizeof(SystemInfo));
  48. GetSystemInfo(&SystemInfo);
  49. return
  50. SystemInfo.dwNumberOfProcessors == 1 ?
  51. STRESS_DEFAULT_THREAD_COUNT :
  52. SystemInfo.dwNumberOfProcessors;
  53. }
  54. //
  55. // Function: MyAlloc
  56. //
  57. LPVOID MyAlloc(SIZE_T dwBytes)
  58. {
  59. return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwBytes);
  60. }
  61. //
  62. // Function: MyFree
  63. //
  64. BOOL MyFree(LPVOID lpMem)
  65. {
  66. return HeapFree(GetProcessHeap(), 0, lpMem);
  67. }
  68. //
  69. // Function: PrintBytes
  70. //
  71. #define CROW 8
  72. void PrintBytes(LPSTR pszHdr, BYTE *pb, DWORD cbSize)
  73. {
  74. ULONG cb, i;
  75. CHAR rgsz[1024];
  76. printf("\n %s, %d bytes ::\n", pszHdr, cbSize);
  77. while (cbSize > 0)
  78. {
  79. // Start every row with an extra space
  80. printf(" ");
  81. cb = min(CROW, cbSize);
  82. cbSize -= cb;
  83. for (i = 0; i < cb; i++)
  84. printf(" %02x", pb[i]);
  85. for (i = cb; i < CROW; i++)
  86. printf(" ");
  87. printf(" '");
  88. for (i = 0; i < cb; i++)
  89. {
  90. if (pb[i] >= 0x20 && pb[i] <= 0x7f)
  91. printf("%c", pb[i]);
  92. else
  93. printf(".");
  94. }
  95. printf("\n");
  96. pb += cb;
  97. }
  98. }
  99. //
  100. // Function: UnalignedImportExportRegression
  101. //
  102. DWORD UnalignedImportExportRegression(PTHREAD_DATA pThreadData)
  103. {
  104. DWORD dwError = ERROR_SUCCESS;
  105. BYTE rgbKeyBuf[2000];
  106. DWORD cbKeyBuf = sizeof(rgbKeyBuf);
  107. PBYTE pbKeyBuf = NULL;
  108. HCRYPTKEY hKey = 0;
  109. HCRYPTKEY hWrapKey = 0;
  110. BOOL fSuccess = FALSE;
  111. if (! CryptGenKey(
  112. pThreadData->hProv, CALG_RC2, 0, &hWrapKey))
  113. {
  114. printf("CryptGenKey CALG_RC2 ");
  115. goto Ret;
  116. }
  117. //
  118. // 1a) Exchange key pair PRIVATEKEYBLOB
  119. //
  120. // Unalign the output buffer
  121. pbKeyBuf = rgbKeyBuf + 1;
  122. cbKeyBuf = sizeof(rgbKeyBuf) - 1;
  123. if (! CryptExportKey(
  124. pThreadData->hExchangeKey, 0, PRIVATEKEYBLOB, 0, pbKeyBuf, &cbKeyBuf))
  125. {
  126. printf("CryptExportKey KeyEx PRIVATEKEYBLOB ");
  127. goto Ret;
  128. }
  129. if (! CryptImportKey(
  130. pThreadData->hProv, pbKeyBuf, cbKeyBuf, 0, CRYPT_EXPORTABLE, &hKey))
  131. {
  132. printf("CryptImportKey KeyEx PRIVATEKEYBLOB ");
  133. goto Ret;
  134. }
  135. if (! CryptDestroyKey(hKey))
  136. {
  137. printf("CryptDestroyKey KeyEx PRIVATEKEYBLOB ");
  138. goto Ret;
  139. }
  140. //
  141. // 1b) Exchange key pair PRIVATEKEYBLOB, encrypted
  142. //
  143. // Unalign the output buffer
  144. pbKeyBuf = rgbKeyBuf + 1;
  145. cbKeyBuf = sizeof(rgbKeyBuf) - 1;
  146. if (! CryptExportKey(
  147. pThreadData->hExchangeKey,
  148. hWrapKey,
  149. PRIVATEKEYBLOB,
  150. 0,
  151. pbKeyBuf,
  152. &cbKeyBuf))
  153. {
  154. printf("CryptExportKey KeyEx PRIVATEKEYBLOB b ");
  155. goto Ret;
  156. }
  157. if (! CryptImportKey(
  158. pThreadData->hProv,
  159. pbKeyBuf,
  160. cbKeyBuf,
  161. hWrapKey,
  162. CRYPT_EXPORTABLE,
  163. &hKey))
  164. {
  165. printf("CryptImportKey KeyEx PRIVATEKEYBLOB b ");
  166. goto Ret;
  167. }
  168. if (! CryptDestroyKey(hKey))
  169. {
  170. printf("CryptDestroyKey KeyEx PRIVATEKEYBLOB b ");
  171. goto Ret;
  172. }
  173. //
  174. // 2) Exchange key pair PUBLICKEYBLOB
  175. //
  176. // Unalign the output buffer
  177. pbKeyBuf = rgbKeyBuf + 1;
  178. cbKeyBuf = sizeof(rgbKeyBuf) - 1;
  179. if (! CryptExportKey(
  180. pThreadData->hExchangeKey, 0, PUBLICKEYBLOB, 0, pbKeyBuf, &cbKeyBuf))
  181. {
  182. printf("CryptExportKey KeyEx PUBLICKEYBLOB ");
  183. goto Ret;
  184. }
  185. if (! CryptImportKey(
  186. pThreadData->hProv,
  187. pbKeyBuf,
  188. cbKeyBuf,
  189. pThreadData->dwProvType == PROV_DSS_DH ? pThreadData->hExchangeKey : 0,
  190. 0,
  191. &hKey))
  192. {
  193. printf("CryptImportKey KeyEx PUBLICKEYBLOB ");
  194. goto Ret;
  195. }
  196. if (! CryptDestroyKey(hKey))
  197. {
  198. printf("CryptDestroyKey KeyEx PUBLICKEYBLOB ");
  199. goto Ret;
  200. }
  201. //
  202. // 3a) Signature key pair PRIVATEKEYBLOB
  203. //
  204. // Unalign the output buffer
  205. pbKeyBuf = rgbKeyBuf + 1;
  206. cbKeyBuf = sizeof(rgbKeyBuf) - 1;
  207. if (! CryptExportKey(
  208. pThreadData->hSignatureKey, 0, PRIVATEKEYBLOB, 0, pbKeyBuf, &cbKeyBuf))
  209. {
  210. printf("CryptExportKey Sig PRIVATEKEYBLOB ");
  211. goto Ret;
  212. }
  213. if (! CryptImportKey(
  214. pThreadData->hProv, pbKeyBuf, cbKeyBuf, 0, CRYPT_EXPORTABLE, &hKey))
  215. {
  216. printf("CryptImportKey Sig PRIVATEKEYBLOB ");
  217. goto Ret;
  218. }
  219. if (! CryptDestroyKey(hKey))
  220. {
  221. printf("CryptDestroyKey Sig PRIVATEKEYBLOB ");
  222. goto Ret;
  223. }
  224. //
  225. // 3b) Signature key pair PRIVATEKEYBLOB, encrypted
  226. //
  227. // Unalign the output buffer
  228. pbKeyBuf = rgbKeyBuf + 1;
  229. cbKeyBuf = sizeof(rgbKeyBuf) - 1;
  230. if (! CryptExportKey(
  231. pThreadData->hSignatureKey,
  232. hWrapKey,
  233. PRIVATEKEYBLOB,
  234. 0,
  235. pbKeyBuf,
  236. &cbKeyBuf))
  237. {
  238. printf("CryptExportKey Sig PRIVATEKEYBLOB b ");
  239. goto Ret;
  240. }
  241. if (! CryptImportKey(
  242. pThreadData->hProv,
  243. pbKeyBuf,
  244. cbKeyBuf,
  245. hWrapKey,
  246. CRYPT_EXPORTABLE,
  247. &hKey))
  248. {
  249. printf("CryptImportKey Sig PRIVATEKEYBLOB b ");
  250. goto Ret;
  251. }
  252. if (! CryptDestroyKey(hKey))
  253. {
  254. printf("CryptDestroyKey Sig PRIVATEKEYBLOB b ");
  255. goto Ret;
  256. }
  257. if (! CryptDestroyKey(hWrapKey))
  258. {
  259. printf("CryptDestroyKey CALG_RC2 ");
  260. goto Ret;
  261. }
  262. //
  263. // 4) Signature key pair PUBLICKEYBLOB
  264. //
  265. // Unalign the output buffer
  266. pbKeyBuf = rgbKeyBuf + 1;
  267. cbKeyBuf = sizeof(rgbKeyBuf) - 1;
  268. if (! CryptExportKey(
  269. pThreadData->hSignatureKey, 0, PUBLICKEYBLOB, 0, pbKeyBuf, &cbKeyBuf))
  270. {
  271. printf("CryptExportKey Sig PUBLICKEYBLOB ");
  272. goto Ret;
  273. }
  274. if (! CryptImportKey(
  275. pThreadData->hProv, pbKeyBuf, cbKeyBuf, 0, 0, &hKey))
  276. {
  277. printf("CryptImportKey Sig PUBLICKEYBLOB ");
  278. goto Ret;
  279. }
  280. if (! CryptDestroyKey(hKey))
  281. {
  282. printf("CryptDestroyKey Sig PUBLICKEYBLOB ");
  283. goto Ret;
  284. }
  285. //
  286. // 5) SIMPLEBLOB
  287. //
  288. if (pThreadData->dwProvType != PROV_DSS_DH &&
  289. pThreadData->dwProvType != PROV_DSS)
  290. {
  291. if (! CryptGenKey(
  292. pThreadData->hProv, CALG_RC2, CRYPT_EXPORTABLE, &hKey))
  293. {
  294. printf("CryptGenKey CALG_RC2 SIMPLEBLOB ");
  295. goto Ret;
  296. }
  297. // Unalign the output buffer
  298. pbKeyBuf = rgbKeyBuf + 1;
  299. cbKeyBuf = sizeof(rgbKeyBuf) - 1;
  300. if (! CryptExportKey(
  301. hKey, pThreadData->hExchangeKey, SIMPLEBLOB, 0, pbKeyBuf, &cbKeyBuf))
  302. {
  303. printf("CryptExportKey SIMPLEBLOB ");
  304. goto Ret;
  305. }
  306. if (! CryptDestroyKey(hKey))
  307. {
  308. printf("CryptDestroyKey CALG_RC2 A SIMPLEBLOB ");
  309. goto Ret;
  310. }
  311. if (! CryptImportKey(
  312. pThreadData->hProv, pbKeyBuf, cbKeyBuf, pThreadData->hExchangeKey, 0, &hKey))
  313. {
  314. printf("CryptImportKey SIMPLEBLOB ");
  315. goto Ret;
  316. }
  317. if (! CryptDestroyKey(hKey))
  318. {
  319. printf("CryptDestroyKey CALG_RC2 B SIMPLEBLOB ");
  320. goto Ret;
  321. }
  322. }
  323. //
  324. // 6) SYMMETRICWRAPKEYBLOB
  325. //
  326. if (! CryptGenKey(
  327. pThreadData->hProv, CALG_RC2, CRYPT_EXPORTABLE, &hKey))
  328. {
  329. printf("CryptGenKey CALG_RC2 SYMMETRICWRAPKEYBLOB A ");
  330. goto Ret;
  331. }
  332. if (! CryptGenKey(
  333. pThreadData->hProv, CALG_RC2, CRYPT_EXPORTABLE, &hWrapKey))
  334. {
  335. printf("CryptGenKey CALG_RC2 SYMMETRICWRAPKEYBLOB B ");
  336. goto Ret;
  337. }
  338. // Unalign the output buffer
  339. pbKeyBuf = rgbKeyBuf + 1;
  340. cbKeyBuf = sizeof(rgbKeyBuf) - 1;
  341. if (! CryptExportKey(
  342. hKey, hWrapKey, SYMMETRICWRAPKEYBLOB, 0, pbKeyBuf, &cbKeyBuf))
  343. {
  344. printf("CryptExportKey SYMMETRICWRAPKEYBLOB ");
  345. goto Ret;
  346. }
  347. if (! CryptDestroyKey(hKey))
  348. {
  349. printf("CryptDestroyKey CALG_RC2 A SYMMETRICWRAPKEYBLOB ");
  350. goto Ret;
  351. }
  352. if (! CryptImportKey(
  353. pThreadData->hProv, pbKeyBuf, cbKeyBuf, hWrapKey, 0, &hKey))
  354. {
  355. printf("CryptImportKey SYMMETRICWRAPKEYBLOB ");
  356. goto Ret;
  357. }
  358. if (! CryptDestroyKey(hKey))
  359. {
  360. printf("CryptDestroyKey CALG_RC2 B SYMMETRICWRAPKEYBLOB ");
  361. goto Ret;
  362. }
  363. if (! CryptDestroyKey(hWrapKey))
  364. {
  365. printf("CryptDestroyKey CALG_RC2 C SYMMETRICWRAPKEYBLOB ");
  366. goto Ret;
  367. }
  368. //
  369. // 7) PLAINTEXTKEYBLOB
  370. //
  371. if (! CryptGenKey(
  372. pThreadData->hProv, CALG_RC2, CRYPT_EXPORTABLE, &hKey))
  373. {
  374. printf("CryptGenKey CALG_RC2 PLAINTEXTKEYBLOB ");
  375. goto Ret;
  376. }
  377. // Unalign the output buffer
  378. pbKeyBuf = rgbKeyBuf + 1;
  379. cbKeyBuf = sizeof(rgbKeyBuf) - 1;
  380. if (! CryptExportKey(
  381. hKey, 0, PLAINTEXTKEYBLOB, 0, pbKeyBuf, &cbKeyBuf))
  382. {
  383. printf("CryptExportKey PLAINTEXTKEYBLOB ");
  384. goto Ret;
  385. }
  386. if (! CryptDestroyKey(hKey))
  387. {
  388. printf("CryptDestroyKey CALG_RC2 A PLAINTEXTKEYBLOB ");
  389. goto Ret;
  390. }
  391. if (! CryptImportKey(
  392. pThreadData->hProv, pbKeyBuf, cbKeyBuf, 0, 0, &hKey))
  393. {
  394. printf("CryptImportKey PLAINTEXTKEYBLOB ");
  395. goto Ret;
  396. }
  397. if (! CryptDestroyKey(hKey))
  398. {
  399. printf("CryptDestroyKey CALG_RC2 B PLAINTEXTKEYBLOB ");
  400. goto Ret;
  401. }
  402. fSuccess = TRUE;
  403. Ret:
  404. if (! fSuccess)
  405. printf("- error 0x%x\n", dwError = GetLastError());
  406. return dwError;
  407. }
  408. static BYTE rgbPrivateKeyWithExponentOfOne[] =
  409. {
  410. 0x07, 0x02, 0x00, 0x00, 0x00, 0xA4, 0x00, 0x00,
  411. 0x52, 0x53, 0x41, 0x32, 0x00, 0x02, 0x00, 0x00,
  412. 0x01, 0x00, 0x00, 0x00, 0xAB, 0xEF, 0xFA, 0xC6,
  413. 0x7D, 0xE8, 0xDE, 0xFB, 0x68, 0x38, 0x09, 0x92,
  414. 0xD9, 0x42, 0x7E, 0x6B, 0x89, 0x9E, 0x21, 0xD7,
  415. 0x52, 0x1C, 0x99, 0x3C, 0x17, 0x48, 0x4E, 0x3A,
  416. 0x44, 0x02, 0xF2, 0xFA, 0x74, 0x57, 0xDA, 0xE4,
  417. 0xD3, 0xC0, 0x35, 0x67, 0xFA, 0x6E, 0xDF, 0x78,
  418. 0x4C, 0x75, 0x35, 0x1C, 0xA0, 0x74, 0x49, 0xE3,
  419. 0x20, 0x13, 0x71, 0x35, 0x65, 0xDF, 0x12, 0x20,
  420. 0xF5, 0xF5, 0xF5, 0xC1, 0xED, 0x5C, 0x91, 0x36,
  421. 0x75, 0xB0, 0xA9, 0x9C, 0x04, 0xDB, 0x0C, 0x8C,
  422. 0xBF, 0x99, 0x75, 0x13, 0x7E, 0x87, 0x80, 0x4B,
  423. 0x71, 0x94, 0xB8, 0x00, 0xA0, 0x7D, 0xB7, 0x53,
  424. 0xDD, 0x20, 0x63, 0xEE, 0xF7, 0x83, 0x41, 0xFE,
  425. 0x16, 0xA7, 0x6E, 0xDF, 0x21, 0x7D, 0x76, 0xC0,
  426. 0x85, 0xD5, 0x65, 0x7F, 0x00, 0x23, 0x57, 0x45,
  427. 0x52, 0x02, 0x9D, 0xEA, 0x69, 0xAC, 0x1F, 0xFD,
  428. 0x3F, 0x8C, 0x4A, 0xD0,
  429. 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  430. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  431. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  432. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  433. 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  434. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  435. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  436. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  437. 0x64, 0xD5, 0xAA, 0xB1,
  438. 0xA6, 0x03, 0x18, 0x92, 0x03, 0xAA, 0x31, 0x2E,
  439. 0x48, 0x4B, 0x65, 0x20, 0x99, 0xCD, 0xC6, 0x0C,
  440. 0x15, 0x0C, 0xBF, 0x3E, 0xFF, 0x78, 0x95, 0x67,
  441. 0xB1, 0x74, 0x5B, 0x60,
  442. 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  443. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  444. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  445. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  446. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  447. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  448. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  449. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  450. };
  451. //
  452. // 64-bit and 56-bit DES SIMPLEBLOB's exported with
  453. // above public key. These keys are functionally
  454. // equivalent on Windows 2000 due to a buffer overrun
  455. // bug.
  456. //
  457. static BYTE g_rgbDes56BitKeyBlob[] =
  458. {
  459. 0x01, 0x02, 0x00, 0x00, 0x01, 0x66, 0x00, 0x00,
  460. 0x00, 0xa4, 0x00, 0x00, 0x29, 0x32, 0xc4, 0xd0,
  461. 0x75, 0x25, 0xa4, 0x00, 0xa8, 0x6f, 0x02, 0x35,
  462. 0x0e, 0x53, 0x75, 0xaa, 0xad, 0x8d, 0x21, 0x67,
  463. 0xf6, 0x8a, 0x93, 0x78, 0x12, 0x27, 0x5c, 0xd1,
  464. 0xa2, 0x13, 0x0f, 0xab, 0xe4, 0x68, 0x8e, 0x28,
  465. 0xcc, 0x3e, 0xf1, 0xa5, 0x52, 0xe4, 0xf7, 0xa4,
  466. 0x57, 0xaa, 0x86, 0x93, 0xc8, 0x73, 0xb1, 0x9f,
  467. 0x77, 0xc8, 0x84, 0x97, 0xe4, 0xad, 0x63, 0xad,
  468. 0x5d, 0x76, 0x02, 0x00
  469. };
  470. static BYTE g_rgbDes64BitKeyBlob[] =
  471. {
  472. 0x01, 0x02, 0x00, 0x00, 0x01, 0x66, 0x00, 0x00,
  473. 0x00, 0xa4, 0x00, 0x00, 0x00, 0x29, 0x32, 0xc4,
  474. 0xd0, 0x75, 0x25, 0xa4, 0x00, 0xa8, 0x6f, 0x02,
  475. 0x0e, 0x53, 0x75, 0xaa, 0xad, 0x8d, 0x21, 0x67,
  476. 0xf6, 0x8a, 0x93, 0x78, 0x12, 0x27, 0x5c, 0xd1,
  477. 0xa2, 0x13, 0x0f, 0xab, 0xe4, 0x68, 0x8e, 0x28,
  478. 0xcc, 0x3e, 0xf1, 0xa5, 0x52, 0xe4, 0xf7, 0xa4,
  479. 0x57, 0xaa, 0x86, 0x93, 0xc8, 0x73, 0xb1, 0x9f,
  480. 0x77, 0xc8, 0x84, 0x97, 0xe4, 0xad, 0x63, 0xad,
  481. 0x5d, 0x76, 0x02, 0x00
  482. };
  483. static BYTE g_rgbDesPlainText[] =
  484. {
  485. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
  486. };
  487. static BYTE g_rgbDesCipherText[] =
  488. {
  489. 0x3b, 0xd9, 0x09, 0xfb, 0xd6, 0xa7, 0x9c, 0x37,
  490. 0xf6, 0x5d, 0xe1, 0x50, 0x6d, 0x39, 0xb0, 0x0c
  491. };
  492. //
  493. // 112 and 128 bit "equivalent" 3Des-2Key blobs
  494. //
  495. static BYTE g_rgbDes112BitKeyBlob[] =
  496. {
  497. 0x01, 0x02, 0x00, 0x00, 0x09, 0x66, 0x00, 0x00,
  498. 0x00, 0xa4, 0x00, 0x00, 0x29, 0x32, 0xc4, 0xd0,
  499. 0x75, 0x25, 0xa4, 0x75, 0xa8, 0x6f, 0x02, 0x35,
  500. 0x0e, 0x53, 0x00, 0xaa, 0xad, 0x8d, 0x21, 0x67,
  501. 0xf6, 0x8a, 0x93, 0x78, 0x12, 0x27, 0x5c, 0xd1,
  502. 0xa2, 0x13, 0x0f, 0xab, 0xe4, 0x68, 0x8e, 0x28,
  503. 0xcc, 0x3e, 0xf1, 0xa5, 0x52, 0xe4, 0xf7, 0xa4,
  504. 0x57, 0xaa, 0x86, 0x93, 0xc8, 0x73, 0xb1, 0x9f,
  505. 0x77, 0xc8, 0x84, 0x97, 0xe4, 0xad, 0x63, 0xad,
  506. 0x5d, 0x76, 0x02, 0x00
  507. };
  508. static BYTE g_rgbDes128BitKeyBlob[] =
  509. {
  510. 0x01, 0x02, 0x00, 0x00, 0x09, 0x66, 0x00, 0x00,
  511. 0x00, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x29, 0x32,
  512. 0xc4, 0xd0, 0x75, 0x25, 0xa4, 0x75, 0xa8, 0x6f,
  513. 0x02, 0x35, 0x0e, 0x53, 0x00, 0xaa, 0xad, 0x8d,
  514. 0xf6, 0x8a, 0x93, 0x78, 0x12, 0x27, 0x5c, 0xd1,
  515. 0xa2, 0x13, 0x0f, 0xab, 0xe4, 0x68, 0x8e, 0x28,
  516. 0xcc, 0x3e, 0xf1, 0xa5, 0x52, 0xe4, 0xf7, 0xa4,
  517. 0x57, 0xaa, 0x86, 0x93, 0xc8, 0x73, 0xb1, 0x9f,
  518. 0x77, 0xc8, 0x84, 0x97, 0xe4, 0xad, 0x63, 0xad,
  519. 0x5d, 0x76, 0x02, 0x00
  520. };
  521. static BYTE g_rgb2DesCipherText[] =
  522. {
  523. 0x56, 0x03, 0xdf, 0x55, 0xeb, 0xfb, 0x76, 0x1f,
  524. 0x93, 0x38, 0xd7, 0xef, 0x8f, 0x38, 0x76, 0x49
  525. };
  526. //
  527. // 168 and 192 bit "equivalent" 3Des blobs
  528. //
  529. static BYTE g_rgbDes168BitKeyBlob[] =
  530. {
  531. 0x01, 0x02, 0x00, 0x00, 0x03, 0x66, 0x00, 0x00,
  532. 0x00, 0xa4, 0x00, 0x00, 0x29, 0x32, 0xc4, 0xd0,
  533. 0x75, 0x25, 0xa4, 0x8a, 0xa8, 0x6f, 0x02, 0x35,
  534. 0x0e, 0x53, 0x75, 0xaa, 0xad, 0x8d, 0x21, 0x67,
  535. 0xf6, 0x00, 0x93, 0x78, 0x12, 0x27, 0x5c, 0xd1,
  536. 0xa2, 0x13, 0x0f, 0xab, 0xe4, 0x68, 0x8e, 0x28,
  537. 0xcc, 0x3e, 0xf1, 0xa5, 0x52, 0xe4, 0xf7, 0xa4,
  538. 0x57, 0xaa, 0x86, 0x93, 0xc8, 0x73, 0xb1, 0x9f,
  539. 0x77, 0xc8, 0x84, 0x97, 0xe4, 0xad, 0x63, 0xad,
  540. 0x5d, 0x76, 0x02, 0x00
  541. };
  542. static BYTE g_rgbDes192BitKeyBlob[] =
  543. {
  544. 0x01, 0x02, 0x00, 0x00, 0x03, 0x66, 0x00, 0x00,
  545. 0x00, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29,
  546. 0x32, 0xc4, 0xd0, 0x75, 0x25, 0xa4, 0x8a, 0xa8,
  547. 0x6f, 0x02, 0x35, 0x0e, 0x53, 0x75, 0xaa, 0xad,
  548. 0x8d, 0x21, 0x67, 0xf6, 0x00, 0x93, 0x78, 0x12,
  549. 0xa2, 0x13, 0x0f, 0xab, 0xe4, 0x68, 0x8e, 0x28,
  550. 0xcc, 0x3e, 0xf1, 0xa5, 0x52, 0xe4, 0xf7, 0xa4,
  551. 0x57, 0xaa, 0x86, 0x93, 0xc8, 0x73, 0xb1, 0x9f,
  552. 0x77, 0xc8, 0x84, 0x97, 0xe4, 0xad, 0x63, 0xad,
  553. 0x5d, 0x76, 0x02, 0x00
  554. };
  555. static BYTE g_rgb3DesCipherText[] =
  556. {
  557. 0x25, 0x25, 0x14, 0x94, 0x6b, 0xe0, 0x69, 0x21,
  558. 0xea, 0x3d, 0xb5, 0xa6, 0x5b, 0xaa, 0x6c, 0x87
  559. };
  560. //
  561. // Function: DesImportEquivalenceTest
  562. // Purpose: Verify that the provided des key correctly
  563. // encrypts the above rgbDesPlainText.
  564. //
  565. DWORD DesImportEquivalenceTest(
  566. PTHREAD_DATA pThreadData,
  567. PBYTE pbDesKey,
  568. DWORD cbDesKey,
  569. PBYTE pbDesShortKey,
  570. DWORD cbDesShortKey,
  571. PBYTE pbCipherText,
  572. DWORD cbCipherText)
  573. {
  574. DWORD dwError = ERROR_SUCCESS;
  575. BOOL fSuccess = FALSE;
  576. HCRYPTKEY hPubKey = 0;
  577. HCRYPTKEY hDesKey = 0;
  578. PBYTE pb = NULL;
  579. DWORD cb = 0;
  580. BYTE rgbPlain[sizeof(g_rgbDesPlainText) * 2];
  581. DWORD cbPlain = sizeof(rgbPlain);
  582. BOOL fBlobError = FALSE;
  583. PBYTE p1 = NULL, p2 = NULL, p3 = NULL;
  584. if (! CryptImportKey(
  585. pThreadData->hVerifyCtx, rgbPrivateKeyWithExponentOfOne,
  586. sizeof(rgbPrivateKeyWithExponentOfOne), 0, 0, &hPubKey))
  587. {
  588. printf("CryptImportKey privatekeywithexponentofone ");
  589. goto Ret;
  590. }
  591. // Try to import the short key; should fail
  592. if (CryptImportKey(
  593. pThreadData->hVerifyCtx, pbDesShortKey, cbDesShortKey,
  594. hPubKey, 0, &hDesKey))
  595. {
  596. printf("CryptImportKey ShortDesKey should've failed ");
  597. goto Ret;
  598. }
  599. PrintBytes("Testing this des key SIMPLEBLOB", pbDesKey, cbDesKey);
  600. if (! CryptImportKey(
  601. pThreadData->hVerifyCtx, pbDesKey, cbDesKey,
  602. hPubKey, CRYPT_EXPORTABLE, &hDesKey))
  603. {
  604. printf("CryptImportKey deskeyblob ");
  605. goto Ret;
  606. }
  607. cb = sizeof(g_rgbDesPlainText);
  608. memcpy(rgbPlain, g_rgbDesPlainText, cb);
  609. if (! CryptEncrypt(
  610. hDesKey, 0, TRUE, 0, rgbPlain, &cb, cbPlain))
  611. {
  612. printf("CryptEncrypt ");
  613. goto Ret;
  614. }
  615. if (0 != memcmp(rgbPlain, pbCipherText, cbCipherText))
  616. {
  617. printf("Cipher text doesn't match\n");
  618. PrintBytes("Expected cipher text", pbCipherText, cbCipherText);
  619. PrintBytes("Actual cipher text", rgbPlain, sizeof(rgbPlain));
  620. fBlobError = TRUE;
  621. }
  622. if (! CryptExportKey(
  623. hDesKey, hPubKey, SIMPLEBLOB, 0, NULL, &cb))
  624. {
  625. printf("CryptExportKey size ");
  626. goto Ret;
  627. }
  628. if (NULL == (pb = (PBYTE) MyAlloc(cb)))
  629. return ERROR_NOT_ENOUGH_MEMORY;
  630. if (! CryptExportKey(
  631. hDesKey, hPubKey, SIMPLEBLOB, 0, pb, &cb))
  632. {
  633. printf("CryptExportKey ");
  634. goto Ret;
  635. }
  636. if (0 != memcmp(
  637. pb, pbDesKey,
  638. sizeof(SIMPLEBLOB) + sizeof(ALG_ID) + 8))
  639. {
  640. printf("Header + key portion of blob doesn't match\n");
  641. PrintBytes("Expected key blob", pbDesKey, cbDesKey);
  642. PrintBytes("Actual key blob", pb, cb);
  643. fBlobError = TRUE;
  644. }
  645. fSuccess = TRUE;
  646. Ret:
  647. if (fBlobError)
  648. dwError = -1;
  649. if (! fSuccess)
  650. printf("- error 0x%x\n", dwError = GetLastError());
  651. if (hDesKey)
  652. CryptDestroyKey(hDesKey);
  653. if (hPubKey)
  654. CryptDestroyKey(hPubKey);
  655. if (pb)
  656. MyFree(pb);
  657. return dwError;
  658. }
  659. //
  660. // Function: DesImportRegression
  661. //
  662. DWORD DesImportRegression(PTHREAD_DATA pThreadData)
  663. {
  664. DWORD dwSts;
  665. DWORD dwError = ERROR_SUCCESS;
  666. if (ERROR_SUCCESS != (dwSts =
  667. DesImportEquivalenceTest(
  668. pThreadData,
  669. g_rgbDes64BitKeyBlob,
  670. sizeof(g_rgbDes64BitKeyBlob),
  671. g_rgbDes56BitKeyBlob,
  672. sizeof(g_rgbDes56BitKeyBlob),
  673. g_rgbDesCipherText,
  674. sizeof(g_rgbDesCipherText))))
  675. dwError = dwSts;
  676. if (ERROR_SUCCESS != (dwSts =
  677. DesImportEquivalenceTest(
  678. pThreadData,
  679. g_rgbDes128BitKeyBlob,
  680. sizeof(g_rgbDes128BitKeyBlob),
  681. g_rgbDes112BitKeyBlob,
  682. sizeof(g_rgbDes112BitKeyBlob),
  683. g_rgb2DesCipherText,
  684. sizeof(g_rgb2DesCipherText))))
  685. dwError = dwSts;
  686. if (ERROR_SUCCESS != (dwSts =
  687. DesImportEquivalenceTest(
  688. pThreadData,
  689. g_rgbDes192BitKeyBlob,
  690. sizeof(g_rgbDes192BitKeyBlob),
  691. g_rgbDes168BitKeyBlob,
  692. sizeof(g_rgbDes168BitKeyBlob),
  693. g_rgb3DesCipherText,
  694. sizeof(g_rgb3DesCipherText))))
  695. dwError = dwSts;
  696. return dwError;
  697. }
  698. static BYTE rgbPlainText[] =
  699. {
  700. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  701. 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
  702. };
  703. static BYTE rgbIV[] =
  704. {
  705. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  706. 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
  707. };
  708. BYTE rgbRC2PlainTextKey [] = {
  709. 0x08, 0x02, 0x00, 0x00, 0x02, 0x66, 0x00, 0x00,
  710. 0x10, 0x00, 0x00, 0x00, 0x10, 0x62, 0x0a, 0x8a,
  711. 0x6b, 0x0d, 0x60, 0xbe, 0xf3, 0x94, 0x99, 0x12,
  712. 0xef, 0x39, 0xbf, 0x4f
  713. };
  714. BYTE rgbRC2CipherText [] = {
  715. 0xfd, 0x25, 0x3e, 0x7a, 0xff, 0xb5, 0xc2, 0x6e,
  716. 0x13, 0xcf, 0x52, 0xf1, 0xba, 0xa3, 0x9a, 0xef,
  717. 0x1c, 0xfb, 0x91, 0x88, 0x9d, 0xf7, 0xe5, 0x12
  718. };
  719. BYTE rgbDESPlainTextKey [] = {
  720. 0x08, 0x02, 0x00, 0x00, 0x01, 0x66, 0x00, 0x00,
  721. 0x08, 0x00, 0x00, 0x00, 0xef, 0x8f, 0x10, 0xec,
  722. 0xea, 0x7a, 0x2c, 0x01
  723. };
  724. BYTE rgbDESCipherText [] = {
  725. 0x13, 0x68, 0x16, 0xc5, 0x15, 0x3d, 0x59, 0x1f,
  726. 0x8e, 0x9c, 0x9c, 0x4f, 0x03, 0x7b, 0xb2, 0x12,
  727. 0x24, 0xa7, 0x81, 0x5e, 0x68, 0xb1, 0x58, 0xaa
  728. };
  729. BYTE rgb3DES112PlainTextKey [] = {
  730. 0x08, 0x02, 0x00, 0x00, 0x09, 0x66, 0x00, 0x00,
  731. 0x10, 0x00, 0x00, 0x00, 0x6d, 0x07, 0xcd, 0xe9,
  732. 0xa4, 0x23, 0xc7, 0x97, 0x4a, 0x4f, 0x5b, 0x2f,
  733. 0x34, 0x92, 0xb5, 0x92
  734. };
  735. BYTE rgb3DES112CipherText [] = {
  736. 0xf4, 0xfd, 0xde, 0x15, 0xfd, 0x50, 0xaa, 0x3c,
  737. 0x02, 0xb1, 0x07, 0x3b, 0x0f, 0x0f, 0x93, 0x23,
  738. 0xc2, 0x23, 0xda, 0x1f, 0x65, 0x81, 0x59, 0x24
  739. };
  740. BYTE rgb3DESCipherText [] = {
  741. 0xa6, 0xae, 0xa2, 0x97, 0xc4, 0x85, 0xda, 0xa7,
  742. 0x43, 0xc8, 0x5d, 0xf4, 0x97, 0xb4, 0xbc, 0x03,
  743. 0x96, 0xf9, 0xa2, 0x66, 0x9e, 0x18, 0x91, 0x4a
  744. };
  745. BYTE rgb3DESPlainTextKey [] = {
  746. 0x08, 0x02, 0x00, 0x00, 0x03, 0x66, 0x00, 0x00,
  747. 0x18, 0x00, 0x00, 0x00, 0xdc, 0x0d, 0x20, 0xf2,
  748. 0xcb, 0xa8, 0xb6, 0x15, 0x3e, 0x23, 0x38, 0xb6,
  749. 0x31, 0x62, 0x4a, 0x16, 0xa4, 0x49, 0xe5, 0xe5,
  750. 0x61, 0x76, 0x75, 0x23
  751. };
  752. BYTE rgbAES128PlainTextKey [] = {
  753. 0x08, 0x02, 0x00, 0x00, 0x0e, 0x66, 0x00, 0x00,
  754. 0x10, 0x00, 0x00, 0x00, 0x7d, 0xda, 0x8c, 0x7f,
  755. 0xac, 0x2e, 0xe7, 0xa6, 0x6f, 0x4c, 0x3b, 0x98,
  756. 0x2b, 0xe6, 0xff, 0xc9
  757. };
  758. BYTE rgbAES128CipherText [] = {
  759. 0xd7, 0xb4, 0x60, 0x15, 0x39, 0xac, 0x42, 0x8c,
  760. 0x67, 0x09, 0x0d, 0x3f, 0x45, 0xa0, 0x4e, 0xf5,
  761. 0x6b, 0x7d, 0x6d, 0x21, 0x28, 0xd7, 0x93, 0x13,
  762. 0xd8, 0x5a, 0x7a, 0x92, 0x34, 0x98, 0xfe, 0x73
  763. };
  764. BYTE rgbAES192PlainTextKey [] = {
  765. 0x08, 0x02, 0x00, 0x00, 0x0f, 0x66, 0x00, 0x00,
  766. 0x18, 0x00, 0x00, 0x00, 0x09, 0x38, 0x0e, 0xfd,
  767. 0x49, 0x16, 0x95, 0x95, 0x01, 0x6e, 0x8b, 0xfd,
  768. 0x3a, 0x34, 0x24, 0x62, 0x23, 0xd6, 0xd4, 0x01,
  769. 0x38, 0x97, 0x96, 0x48
  770. };
  771. BYTE rgbAES192CipherText [] = {
  772. 0xa6, 0x57, 0x36, 0xbb, 0xb2, 0x4f, 0x22, 0xee,
  773. 0x2b, 0xb8, 0x0b, 0x65, 0xf3, 0xc1, 0x82, 0x93,
  774. 0x92, 0xcc, 0xcc, 0x0a, 0xf3, 0x4e, 0x3b, 0x28,
  775. 0xb7, 0x6d, 0x89, 0xd3, 0x9a, 0x0c, 0xa0, 0x95
  776. };
  777. BYTE rgbAES256PlainTextKey [] = {
  778. 0x08, 0x02, 0x00, 0x00, 0x10, 0x66, 0x00, 0x00,
  779. 0x20, 0x00, 0x00, 0x00, 0xb5, 0xe8, 0xa8, 0xb3,
  780. 0x1b, 0x0b, 0x9c, 0x14, 0x9e, 0x27, 0xe8, 0x99,
  781. 0x58, 0xce, 0x89, 0x57, 0x34, 0x2f, 0x1a, 0x41,
  782. 0x29, 0x4e, 0xfe, 0x64, 0xc3, 0xe9, 0xe9, 0x2b,
  783. 0x63, 0x47, 0x58, 0x54
  784. };
  785. BYTE rgbAES256CipherText [] = {
  786. 0x51, 0xf2, 0x8d, 0x49, 0x7d, 0x10, 0xd4, 0x66,
  787. 0xe8, 0xc2, 0x70, 0xf3, 0xff, 0x19, 0xa2, 0x7e,
  788. 0xe7, 0x89, 0x1d, 0x11, 0xe7, 0x25, 0xd7, 0x42,
  789. 0x75, 0xe2, 0x72, 0x78, 0x38, 0x52, 0x30, 0xc9
  790. };
  791. typedef struct _KnownBlockCipherResult {
  792. ALG_ID ai;
  793. BYTE *pbKey;
  794. DWORD cbKey;
  795. BYTE *pbCipherText;
  796. DWORD cbCipherText;
  797. } KnownBlockCipherResult, *pKnownBlockCipherResult;
  798. KnownBlockCipherResult g_rgKnownBlockCipherResults [] = {
  799. { CALG_RC2, rgbRC2PlainTextKey, sizeof(rgbRC2PlainTextKey),
  800. rgbRC2CipherText, sizeof(rgbRC2CipherText) },
  801. { CALG_DES, rgbDESPlainTextKey, sizeof(rgbDESPlainTextKey),
  802. rgbDESCipherText, sizeof(rgbDESCipherText) },
  803. { CALG_3DES_112, rgb3DES112PlainTextKey, sizeof(rgb3DES112PlainTextKey),
  804. rgb3DES112CipherText, sizeof(rgb3DES112CipherText) },
  805. { CALG_3DES, rgb3DESPlainTextKey, sizeof(rgb3DESPlainTextKey),
  806. rgb3DESCipherText, sizeof(rgb3DESCipherText) },
  807. { CALG_AES_128, rgbAES128PlainTextKey, sizeof(rgbAES128PlainTextKey),
  808. rgbAES128CipherText, sizeof(rgbAES128CipherText) },
  809. { CALG_AES_192, rgbAES192PlainTextKey, sizeof(rgbAES192PlainTextKey),
  810. rgbAES192CipherText, sizeof(rgbAES192CipherText) },
  811. { CALG_AES_256, rgbAES256PlainTextKey, sizeof(rgbAES256PlainTextKey),
  812. rgbAES256CipherText, sizeof(rgbAES256CipherText) }
  813. };
  814. static const unsigned g_cKnownBlockCipherResults =
  815. sizeof(g_rgKnownBlockCipherResults) / sizeof(KnownBlockCipherResult);
  816. //
  817. // Function: KnownSymKeyRegression
  818. //
  819. DWORD KnownBlockCipherKeyRegression(PTHREAD_DATA pThreadData)
  820. {
  821. DWORD dwError = ERROR_SUCCESS;
  822. BOOL fSuccess = FALSE;
  823. BOOL fBlobError = FALSE;
  824. HCRYPTKEY hPubKey = 0;
  825. HCRYPTKEY hSymKey = 0;
  826. PALGNODE pAlgNode = NULL;
  827. PBYTE pb = NULL;
  828. DWORD cb = 0;
  829. DWORD cbBuf = 0;
  830. DWORD dw = 0;
  831. CHAR rgsz[1024];
  832. unsigned u;
  833. for ( pAlgNode = pThreadData->pAlgList;
  834. pAlgNode != NULL;
  835. pAlgNode = pAlgNode->pNext)
  836. {
  837. if ((ALG_CLASS_DATA_ENCRYPT != GET_ALG_CLASS(pAlgNode->EnumalgsEx.aiAlgid))
  838. || (ALG_TYPE_BLOCK != GET_ALG_TYPE(pAlgNode->EnumalgsEx.aiAlgid)))
  839. continue;
  840. for ( u = 0;
  841. u < g_cKnownBlockCipherResults &&
  842. pAlgNode->EnumalgsEx.aiAlgid != g_rgKnownBlockCipherResults[u].ai;
  843. u++);
  844. // CYLINK_MEK is not supported with PLAINTEXTKEYBLOB's
  845. if (CALG_CYLINK_MEK == pAlgNode->EnumalgsEx.aiAlgid)
  846. continue;
  847. sprintf(
  848. rgsz,
  849. "Importing 0x%x blob for CSP alg %s (0x%x)",
  850. g_rgKnownBlockCipherResults[u].ai,
  851. pAlgNode->EnumalgsEx.szName,
  852. pAlgNode->EnumalgsEx.aiAlgid);
  853. PrintBytes(
  854. rgsz,
  855. g_rgKnownBlockCipherResults[u].pbKey,
  856. g_rgKnownBlockCipherResults[u].cbKey);
  857. if (! CryptImportKey(
  858. pThreadData->hProv,
  859. g_rgKnownBlockCipherResults[u].pbKey,
  860. g_rgKnownBlockCipherResults[u].cbKey,
  861. 0, 0, &hSymKey))
  862. {
  863. printf("CryptImportKey ");
  864. goto Ret;
  865. }
  866. if (! CryptSetKeyParam(hSymKey, KP_IV, rgbIV, 0))
  867. {
  868. printf("CryptSetKeyParam ");
  869. goto Ret;
  870. }
  871. dw = CRYPT_MODE_CBC;
  872. if (! CryptSetKeyParam(hSymKey, KP_MODE, (PBYTE) &dw, 0))
  873. {
  874. printf("CryptSetKeyParam ");
  875. goto Ret;
  876. }
  877. cb = sizeof(rgbPlainText);
  878. if (! CryptEncrypt(hSymKey, 0, TRUE, 0, NULL, &cb, 0))
  879. {
  880. printf("CryptEncrypt ");
  881. goto Ret;
  882. }
  883. if (NULL == (pb = (PBYTE) MyAlloc(cb)))
  884. return ERROR_NOT_ENOUGH_MEMORY;
  885. cbBuf = cb;
  886. cb = sizeof(rgbPlainText);
  887. memcpy(pb, rgbPlainText, cb);
  888. if (! CryptEncrypt(hSymKey, 0, TRUE, 0, pb, &cb, cbBuf))
  889. {
  890. printf("CryptEncrypt ");
  891. goto Ret;
  892. }
  893. if (0 != memcmp(pb, g_rgKnownBlockCipherResults[u].pbCipherText, cb)
  894. || 0 == cb)
  895. {
  896. printf(
  897. "Ciphertext is wrong for alg %s\n",
  898. pAlgNode->EnumalgsEx.szName);
  899. PrintBytes(
  900. "Expected ciphertext",
  901. g_rgKnownBlockCipherResults[u].pbCipherText,
  902. cb);
  903. PrintBytes(
  904. "Actual ciphertext",
  905. pb, cb);
  906. fBlobError = TRUE;
  907. }
  908. }
  909. fSuccess = TRUE;
  910. Ret:
  911. if (fBlobError)
  912. dwError = -1;
  913. if ((! fSuccess) && (! fBlobError))
  914. printf("- error 0x%x\n", dwError = GetLastError());
  915. return dwError;
  916. }
  917. typedef struct _HMAC_TEST
  918. {
  919. PBYTE pbKey;
  920. DWORD cbKey;
  921. PBYTE pbData;
  922. DWORD cbData;
  923. PBYTE pbData2;
  924. DWORD cbData2;
  925. PBYTE pbHmac;
  926. DWORD cbHmac;
  927. ALG_ID aiHash;
  928. } HMAC_TEST, *PHMAC_TEST;
  929. //
  930. // Function: DoHmacTestCase
  931. //
  932. DWORD DoHmacTestCase(
  933. IN PTHREAD_DATA pThreadData,
  934. IN PHMAC_TEST pHmac)
  935. {
  936. HCRYPTKEY hKey = 0;
  937. HCRYPTHASH hHash = 0;
  938. DWORD cb = 0;
  939. BLOBHEADER *pHeader = NULL;
  940. BOOL fSuccess = FALSE;
  941. DWORD dwError = ERROR_SUCCESS;
  942. BYTE rgBuf[1024];
  943. HMAC_INFO HmacInfo;
  944. ZeroMemory(rgBuf, sizeof(rgBuf));
  945. ZeroMemory(&HmacInfo, sizeof(HmacInfo));
  946. pHeader = (BLOBHEADER *) rgBuf;
  947. pHeader->bType = PLAINTEXTKEYBLOB;
  948. pHeader->bVersion = CUR_BLOB_VERSION;
  949. pHeader->aiKeyAlg = CALG_RC2;
  950. *(DWORD*)(rgBuf + sizeof(BLOBHEADER)) = pHmac->cbKey;
  951. memcpy(
  952. rgBuf + sizeof(BLOBHEADER) + sizeof(DWORD),
  953. pHmac->pbKey, pHmac->cbKey);
  954. if (! CryptImportKey(
  955. pThreadData->hProv, rgBuf,
  956. sizeof(BLOBHEADER) + sizeof(DWORD) + pHmac->cbKey,
  957. 0, CRYPT_IPSEC_HMAC_KEY, &hKey))
  958. {
  959. printf("CryptImportKey");
  960. goto Ret;
  961. }
  962. if (! CryptCreateHash(
  963. pThreadData->hProv, CALG_HMAC, hKey, 0, &hHash))
  964. {
  965. printf("CryptCreateHash");
  966. goto Ret;
  967. }
  968. HmacInfo.HashAlgid = pHmac->aiHash;
  969. if (! CryptSetHashParam(
  970. hHash, HP_HMAC_INFO, (PBYTE) &HmacInfo, 0))
  971. {
  972. printf("CryptSetHashParam");
  973. goto Ret;
  974. }
  975. if (! CryptHashData(
  976. hHash, pHmac->pbData, pHmac->cbData, 0))
  977. {
  978. printf("CryptHashData");
  979. goto Ret;
  980. }
  981. if (pHmac->cbData2)
  982. {
  983. if (! CryptHashData(
  984. hHash, pHmac->pbData2, pHmac->cbData2, 0))
  985. {
  986. printf("CryptHashData 2");
  987. goto Ret;
  988. }
  989. }
  990. cb = sizeof(rgBuf);
  991. ZeroMemory(rgBuf, sizeof(rgBuf));
  992. if (! CryptGetHashParam(
  993. hHash, HP_HASHVAL, rgBuf, &cb, 0))
  994. {
  995. printf("CryptGetHashParam");
  996. goto Ret;
  997. }
  998. PrintBytes("Expected Hmac", pHmac->pbHmac, pHmac->cbHmac);
  999. PrintBytes("Actual Hmac", rgBuf, cb);
  1000. if ( 0 != memcmp(rgBuf, pHmac->pbHmac, cb)
  1001. || cb != pHmac->cbHmac)
  1002. goto Ret;
  1003. if (! CryptDestroyKey(hKey))
  1004. {
  1005. printf("CryptDestroyKey");
  1006. goto Ret;
  1007. }
  1008. if (! CryptDestroyHash(hHash))
  1009. {
  1010. printf("CryptDestroyHash");
  1011. goto Ret;
  1012. }
  1013. fSuccess = TRUE;
  1014. Ret:
  1015. if (! fSuccess)
  1016. {
  1017. dwError = GetLastError();
  1018. printf(" error - 0x%x\n", dwError);
  1019. if (0 == dwError)
  1020. dwError = -1;
  1021. }
  1022. return dwError;
  1023. }
  1024. //
  1025. // Function: HmacRegression
  1026. //
  1027. DWORD HmacRegression(PTHREAD_DATA pThreadData)
  1028. {
  1029. BOOL fSuccess = FALSE;
  1030. DWORD dwError = ERROR_SUCCESS;
  1031. HMAC_TEST Hmac;
  1032. // SHA Test case 1
  1033. BYTE rgKey1 [] = {
  1034. 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
  1035. 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
  1036. 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
  1037. 0x0b, 0x0b, 0x0b, 0x0b, 0x0b
  1038. };
  1039. LPSTR pszData1 = "Hi There";
  1040. BYTE rgHmac1 [] = {
  1041. 0xb6, 0x17, 0x31, 0x86, 0x55,
  1042. 0x05, 0x72, 0x64, 0xe2, 0x8b,
  1043. 0xc0, 0xb6, 0xfb, 0x37, 0x8c,
  1044. 0x8e, 0xf1, 0x46, 0xbe, 0x00
  1045. };
  1046. // SHA Test case 2
  1047. BYTE rgKey2 [] = {
  1048. 0x01, 0x02, 0x03, 0x04, 0x05,
  1049. 0x06, 0x07, 0x08, 0x09, 0x0a,
  1050. 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  1051. 0x10, 0x11, 0x12, 0x13, 0x14,
  1052. 0x15, 0x16, 0x17, 0x18, 0x19
  1053. };
  1054. BYTE rgData2 [50];
  1055. BYTE rgHmac2 [] = {
  1056. 0x4c, 0x90, 0x07, 0xf4, 0x02,
  1057. 0x62, 0x50, 0xc6, 0xbc, 0x84,
  1058. 0x14, 0xf9, 0xbf, 0x50, 0xc8,
  1059. 0x6c, 0x2d, 0x72, 0x35, 0xda
  1060. };
  1061. // SHA Test case 3
  1062. BYTE rgKey3 [80];
  1063. LPSTR pszData3 = "Test Using Larger Than Block-Size Key - Hash Key First";
  1064. BYTE rgHmac3 [] = {
  1065. 0xaa, 0x4a, 0xe5, 0xe1, 0x52,
  1066. 0x72, 0xd0, 0x0e, 0x95, 0x70,
  1067. 0x56, 0x37, 0xce, 0x8a, 0x3b,
  1068. 0x55, 0xed, 0x40, 0x21, 0x12
  1069. };
  1070. // MD5 Test case 1
  1071. // use rgKey1 (16 bytes only) and pszData1
  1072. BYTE rgHmacMD1 [] = {
  1073. 0x92, 0x94, 0x72, 0x7a,
  1074. 0x36, 0x38, 0xbb, 0x1c,
  1075. 0x13, 0xf4, 0x8e, 0xf8,
  1076. 0x15, 0x8b, 0xfc, 0x9d
  1077. };
  1078. // MD5 Test case 2
  1079. // use rgKey3 (full length) and pszData3
  1080. BYTE rgHmacMD2 [] = {
  1081. 0x6b, 0x1a, 0xb7, 0xfe,
  1082. 0x4b, 0xd7, 0xbf, 0x8f,
  1083. 0x0b, 0x62, 0xe6, 0xce,
  1084. 0x61, 0xb9, 0xd0, 0xcd
  1085. };
  1086. // IPSec MD5 vectors
  1087. BYTE rgKeyIpsec [] = {
  1088. 0x66, 0x6f, 0x6f
  1089. };
  1090. BYTE rgDataIpsecA [] = {
  1091. 0x38, 0x8e, 0x5e, 0x8a,
  1092. 0xb0, 0x79, 0x16, 0x47,
  1093. 0x29, 0x1b, 0xf0, 0x02,
  1094. 0x78, 0x5e, 0x38, 0xe5,
  1095. 0x82, 0x3c, 0x17, 0x0d
  1096. };
  1097. BYTE rgDataIpsecB [] = {
  1098. 0x34, 0xdd, 0xdb, 0x22,
  1099. 0x9e, 0x21, 0x75, 0x28,
  1100. 0x5e, 0x4d, 0x7d, 0xdf,
  1101. 0xea, 0x35, 0xc5, 0xfc,
  1102. 0x44, 0xdb, 0x62, 0xad
  1103. };
  1104. BYTE rgHmacIpsec [] = {
  1105. 0x52, 0x07, 0x38, 0x15,
  1106. 0xef, 0xb0, 0x68, 0x43,
  1107. 0x89, 0x8e, 0x0b, 0xdc,
  1108. 0x58, 0xc0, 0x70, 0xc0
  1109. };
  1110. memset(rgData2, 0xcd, sizeof(rgData2));
  1111. memset(rgKey3, 0xaa, sizeof(rgKey3));
  1112. // SHA 1
  1113. ZeroMemory(&Hmac, sizeof(HMAC_TEST));
  1114. Hmac.cbData = strlen(pszData1) * sizeof(CHAR);
  1115. Hmac.pbData = (PBYTE) pszData1;
  1116. Hmac.cbHmac = sizeof(rgHmac1);
  1117. Hmac.pbHmac = rgHmac1;
  1118. Hmac.cbKey = sizeof(rgKey1);
  1119. Hmac.pbKey = rgKey1;
  1120. Hmac.aiHash = CALG_SHA1;
  1121. if (ERROR_SUCCESS != (dwError = DoHmacTestCase(pThreadData, &Hmac)))
  1122. {
  1123. printf("ERROR: DoHmacTestCase SHA 1\n");
  1124. return dwError;
  1125. }
  1126. // SHA 2
  1127. ZeroMemory(&Hmac, sizeof(HMAC_TEST));
  1128. Hmac.cbData = sizeof(rgData2);
  1129. Hmac.pbData = rgData2;
  1130. Hmac.cbHmac = sizeof(rgHmac2);
  1131. Hmac.pbHmac = rgHmac2;
  1132. Hmac.cbKey = sizeof(rgKey2);
  1133. Hmac.pbKey = rgKey2;
  1134. Hmac.aiHash = CALG_SHA1;
  1135. if (ERROR_SUCCESS != (dwError = DoHmacTestCase(pThreadData, &Hmac)))
  1136. {
  1137. printf("ERROR: DoHmacTestCase SHA 2\n");
  1138. return dwError;
  1139. }
  1140. // SHA 3
  1141. ZeroMemory(&Hmac, sizeof(HMAC_TEST));
  1142. Hmac.cbData = strlen(pszData3) * sizeof(CHAR);
  1143. Hmac.pbData = (PBYTE) pszData3;
  1144. Hmac.cbHmac = sizeof(rgHmac3);
  1145. Hmac.pbHmac = rgHmac3;
  1146. Hmac.cbKey = sizeof(rgKey3);
  1147. Hmac.pbKey = rgKey3;
  1148. Hmac.aiHash = CALG_SHA1;
  1149. if (ERROR_SUCCESS != (dwError = DoHmacTestCase(pThreadData, &Hmac)))
  1150. {
  1151. printf("ERROR: DoHmacTestCase SHA 3\n");
  1152. return dwError;
  1153. }
  1154. // MD5 1
  1155. ZeroMemory(&Hmac, sizeof(HMAC_TEST));
  1156. Hmac.cbData = strlen(pszData1) * sizeof(CHAR);
  1157. Hmac.pbData = (PBYTE) pszData1;
  1158. Hmac.cbHmac = sizeof(rgHmacMD1);
  1159. Hmac.pbHmac = rgHmacMD1;
  1160. Hmac.cbKey = 16; // only 16-byte key for this one
  1161. Hmac.pbKey = rgKey1;
  1162. Hmac.aiHash = CALG_MD5;
  1163. if (ERROR_SUCCESS != (dwError = DoHmacTestCase(pThreadData, &Hmac)))
  1164. {
  1165. printf("ERROR: DoHmacTestCase MD5 1\n");
  1166. return dwError;
  1167. }
  1168. // MD5 2
  1169. ZeroMemory(&Hmac, sizeof(HMAC_TEST));
  1170. Hmac.cbData = strlen(pszData3) * sizeof(CHAR);
  1171. Hmac.pbData = (PBYTE) pszData3;
  1172. Hmac.cbHmac = sizeof(rgHmacMD2);
  1173. Hmac.pbHmac = rgHmacMD2;
  1174. Hmac.cbKey = sizeof(rgKey3);
  1175. Hmac.pbKey = rgKey3;
  1176. Hmac.aiHash = CALG_MD5;
  1177. if (ERROR_SUCCESS != (dwError = DoHmacTestCase(pThreadData, &Hmac)))
  1178. {
  1179. printf("ERROR: DoHmacTestCase MD5 2\n");
  1180. return dwError;
  1181. }
  1182. // MD5 Ipsec vector
  1183. ZeroMemory(&Hmac, sizeof(HMAC_TEST));
  1184. Hmac.cbData = sizeof(rgDataIpsecA);
  1185. Hmac.pbData = rgDataIpsecA;
  1186. Hmac.cbData2 = sizeof(rgDataIpsecB);
  1187. Hmac.pbData2 = rgDataIpsecB;
  1188. Hmac.cbHmac = sizeof(rgHmacIpsec);
  1189. Hmac.pbHmac = rgHmacIpsec;
  1190. Hmac.cbKey = sizeof(rgKeyIpsec);
  1191. Hmac.pbKey = rgKeyIpsec;
  1192. Hmac.aiHash = CALG_MD5;
  1193. if (ERROR_SUCCESS != (dwError = DoHmacTestCase(pThreadData, &Hmac)))
  1194. {
  1195. printf("ERROR: DoHmacTestCase MD5 Ipsec\n");
  1196. return dwError;
  1197. }
  1198. return ERROR_SUCCESS;
  1199. }
  1200. //
  1201. // Function: KeyArchiveRegression
  1202. //
  1203. // Not thread safe
  1204. //
  1205. DWORD KeyArchiveRegression(PTHREAD_DATA pThreadData)
  1206. {
  1207. HCRYPTPROV hProv = 0;
  1208. HCRYPTKEY hKey = 0;
  1209. DWORD dwError = 0;
  1210. LPSTR pszContainer = "KeyArchiveRegression";
  1211. BYTE rgbKey[2048];
  1212. DWORD cbKey;
  1213. DWORD dwData;
  1214. DWORD cbData;
  1215. BOOL fSuccess = FALSE;
  1216. CryptAcquireContext(
  1217. &hProv,
  1218. pszContainer,
  1219. pThreadData->rgszProvName,
  1220. pThreadData->dwProvType,
  1221. CRYPT_DELETEKEYSET);
  1222. if (! CryptAcquireContext(
  1223. &hProv,
  1224. pszContainer,
  1225. pThreadData->rgszProvName,
  1226. pThreadData->dwProvType,
  1227. CRYPT_NEWKEYSET))
  1228. {
  1229. printf("CryptAcquireContext newkeyset ");
  1230. goto Ret;
  1231. }
  1232. if (! CryptGenKey(
  1233. hProv,
  1234. AT_SIGNATURE,
  1235. CRYPT_ARCHIVABLE,
  1236. &hKey))
  1237. {
  1238. printf("CryptGenKey archivable ");
  1239. goto Ret;
  1240. }
  1241. cbData = sizeof(dwData);
  1242. if (! CryptGetKeyParam(
  1243. hKey, KP_PERMISSIONS, (PBYTE) &dwData, &cbData, 0))
  1244. {
  1245. printf("CryptGetKeyParam ");
  1246. goto Ret;
  1247. }
  1248. if (! ((CRYPT_ARCHIVE & dwData) && (! (CRYPT_EXPORT & dwData))))
  1249. {
  1250. printf("incorrect KP_PERMISSIONS ");
  1251. goto Ret;
  1252. }
  1253. cbKey = sizeof(rgbKey);
  1254. if (! CryptExportKey(
  1255. hKey,
  1256. 0,
  1257. PRIVATEKEYBLOB,
  1258. 0,
  1259. rgbKey,
  1260. &cbKey))
  1261. {
  1262. printf("CryptExportKey privatekeyblob ");
  1263. goto Ret;
  1264. }
  1265. if (! CryptDestroyKey(hKey))
  1266. {
  1267. printf("CryptDestroyKey ");
  1268. goto Ret;
  1269. }
  1270. if (! CryptReleaseContext(hProv, 0))
  1271. {
  1272. printf("CryptReleaseContext ");
  1273. goto Ret;
  1274. }
  1275. if (! CryptAcquireContext(
  1276. &hProv,
  1277. pszContainer,
  1278. pThreadData->rgszProvName,
  1279. pThreadData->dwProvType,
  1280. 0))
  1281. {
  1282. printf("CryptAcquireContext ");
  1283. goto Ret;
  1284. }
  1285. if (! CryptGetUserKey(hProv, AT_SIGNATURE, &hKey))
  1286. {
  1287. printf("CryptGetUserKey ");
  1288. goto Ret;
  1289. }
  1290. // try to set the key export/archive perms; should fail
  1291. cbData = sizeof(dwData);
  1292. if (! CryptGetKeyParam(
  1293. hKey, KP_PERMISSIONS, (PBYTE) &dwData, &cbData, 0))
  1294. {
  1295. printf("CryptGetKeyParam ");
  1296. goto Ret;
  1297. }
  1298. dwData |= CRYPT_EXPORT | CRYPT_ARCHIVE;
  1299. // should fail
  1300. if (CryptSetKeyParam(hKey, KP_PERMISSIONS, (PBYTE) &dwData, 0))
  1301. {
  1302. printf("CryptSetKeyParam should have failed ");
  1303. goto Ret;
  1304. }
  1305. // should fail
  1306. cbKey = sizeof(rgbKey);
  1307. if (CryptExportKey(
  1308. hKey,
  1309. 0,
  1310. PRIVATEKEYBLOB,
  1311. 0,
  1312. rgbKey,
  1313. &cbKey))
  1314. {
  1315. printf("CryptExportKey should have failed ");
  1316. goto Ret;
  1317. }
  1318. fSuccess = TRUE;
  1319. Ret:
  1320. if (! fSuccess)
  1321. printf("- error 0x%x\n", dwError = GetLastError());
  1322. if (hKey)
  1323. CryptDestroyKey(hKey);
  1324. if (hProv)
  1325. CryptReleaseContext(hProv, 0);
  1326. return dwError;
  1327. }
  1328. //
  1329. // Function: PlaintextBlobRegression
  1330. //
  1331. DWORD PlaintextBlobRegression(PTHREAD_DATA pThreadData)
  1332. {
  1333. HCRYPTKEY hKey = 0;
  1334. DWORD cbKey = 0;
  1335. PBYTE pbKey = NULL;
  1336. PALGNODE pAlgNode = NULL;
  1337. BLOBHEADER *header = NULL;
  1338. PBYTE pbTemp = NULL;
  1339. DWORD cbData, cb;
  1340. BYTE rgbData[1024];
  1341. BOOL fSuccess = FALSE;
  1342. DWORD dwError = ERROR_SUCCESS;
  1343. DWORD cbKeySize = 0;
  1344. // try an invalid key type
  1345. if (CryptExportKey(
  1346. pThreadData->hSignatureKey,
  1347. 0,
  1348. PLAINTEXTKEYBLOB,
  1349. 0,
  1350. NULL,
  1351. &cbKey))
  1352. {
  1353. printf("CryptExportKey plaintextkeyblob should have failed ");
  1354. goto Ret;
  1355. }
  1356. // try all the valid key types
  1357. for (pAlgNode = pThreadData->pAlgList; pAlgNode != NULL; pAlgNode = pAlgNode->pNext)
  1358. {
  1359. if (ALG_CLASS_DATA_ENCRYPT != GET_ALG_CLASS(pAlgNode->EnumalgsEx.aiAlgid)
  1360. || (ALG_TYPE_BLOCK != GET_ALG_TYPE(pAlgNode->EnumalgsEx.aiAlgid)
  1361. && ALG_TYPE_STREAM != GET_ALG_TYPE(pAlgNode->EnumalgsEx.aiAlgid)))
  1362. continue;
  1363. // Plaintext import not supported for CYLINK_MEK
  1364. if (CALG_CYLINK_MEK == pAlgNode->EnumalgsEx.aiAlgid)
  1365. continue;
  1366. /*
  1367. if (PROV_DSS == pThreadData->dwProvType
  1368. || PROV_DSS_DH == pThreadData->dwProvType)
  1369. {
  1370. cbKeySize = pAlgNode->EnumalgsEx.dwMaxLen / 8;
  1371. }
  1372. else
  1373. {
  1374. */
  1375. switch (pAlgNode->EnumalgsEx.aiAlgid)
  1376. {
  1377. case CALG_DES:
  1378. cbKeySize = pAlgNode->EnumalgsEx.dwMaxLen / 8 + 1;
  1379. break;
  1380. case CALG_3DES_112:
  1381. cbKeySize = pAlgNode->EnumalgsEx.dwMaxLen / 8 + 2;
  1382. break;
  1383. case CALG_3DES:
  1384. cbKeySize = pAlgNode->EnumalgsEx.dwMaxLen / 8 + 3;
  1385. break;
  1386. default:
  1387. cbKeySize = pAlgNode->EnumalgsEx.dwMaxLen / 8;
  1388. }
  1389. /*
  1390. }
  1391. */
  1392. printf(
  1393. "Importing Alg: %xh (%s), Size: %d bits\n",
  1394. pAlgNode->EnumalgsEx.aiAlgid,
  1395. pAlgNode->EnumalgsEx.szName,
  1396. cbKeySize * 8);
  1397. cbKey = sizeof(BLOBHEADER) + sizeof(DWORD) + cbKeySize;
  1398. if (NULL == (pbKey = (PBYTE) MyAlloc(cbKey)))
  1399. return ERROR_NOT_ENOUGH_MEMORY;
  1400. header = (BLOBHEADER *) pbKey;
  1401. header->aiKeyAlg = pAlgNode->EnumalgsEx.aiAlgid;
  1402. header->bType = PLAINTEXTKEYBLOB;
  1403. header->bVersion = CUR_BLOB_VERSION;
  1404. header->reserved = 0;
  1405. pbTemp = pbKey + sizeof(BLOBHEADER);
  1406. *((DWORD*)pbTemp) = cbKeySize;
  1407. pbTemp += sizeof(DWORD);
  1408. // create some key data
  1409. if (! CryptGenRandom(
  1410. pThreadData->hProv,
  1411. cbKeySize,
  1412. pbTemp))
  1413. {
  1414. printf("CryptGenRandom ");
  1415. goto Ret;
  1416. }
  1417. if (! CryptImportKey(
  1418. pThreadData->hProv,
  1419. pbKey, cbKey, 0, CRYPT_EXPORTABLE, &hKey))
  1420. {
  1421. printf("CryptImportKey ");
  1422. goto Ret;
  1423. }
  1424. MyFree(pbKey);
  1425. // create some data to encrypt
  1426. if (! CryptGenRandom(
  1427. pThreadData->hProv,
  1428. sizeof(rgbData),
  1429. rgbData))
  1430. {
  1431. printf("CryptGenRandom ");
  1432. goto Ret;
  1433. }
  1434. cbData = sizeof(rgbData);
  1435. cb = cbData / 2;
  1436. if (! CryptEncrypt(
  1437. hKey, 0, TRUE, 0, rgbData, &cb, cbData))
  1438. {
  1439. printf("CryptEncrypt ");
  1440. goto Ret;
  1441. }
  1442. if (! CryptExportKey(
  1443. hKey, 0, PLAINTEXTKEYBLOB, 0, NULL, &cbKey))
  1444. {
  1445. printf("CryptExportKey size ");
  1446. goto Ret;
  1447. }
  1448. if (NULL == (pbKey = (PBYTE) MyAlloc(cbKey)))
  1449. return ERROR_NOT_ENOUGH_MEMORY;
  1450. if (! CryptExportKey(
  1451. hKey, 0, PLAINTEXTKEYBLOB, 0, pbKey, &cbKey))
  1452. {
  1453. printf("CryptExportKey ");
  1454. goto Ret;
  1455. }
  1456. // check the blob
  1457. header = (BLOBHEADER *) pbKey;
  1458. if (pAlgNode->EnumalgsEx.aiAlgid != header->aiKeyAlg)
  1459. {
  1460. printf("header->aiKeyAlg is wrong ");
  1461. goto Ret;
  1462. }
  1463. if (CUR_BLOB_VERSION != header->bVersion)
  1464. {
  1465. printf("header->bVersion is wrong ");
  1466. goto Ret;
  1467. }
  1468. if (0 != header->reserved)
  1469. {
  1470. printf("header->reserved is wrong ");
  1471. goto Ret;
  1472. }
  1473. if (PLAINTEXTKEYBLOB != header->bType)
  1474. {
  1475. printf("header->bType is wrong ");
  1476. goto Ret;
  1477. }
  1478. pbTemp = pbKey + sizeof(BLOBHEADER);
  1479. if (cbKeySize != *((DWORD*)pbTemp))
  1480. {
  1481. printf(
  1482. "blob key size is %d, but should be %d ",
  1483. *((DWORD*)pbTemp),
  1484. cbKeySize);
  1485. goto Ret;
  1486. }
  1487. MyFree(pbKey);
  1488. if (! CryptDestroyKey(hKey))
  1489. {
  1490. printf("CryptDestroyKey ");
  1491. goto Ret;
  1492. }
  1493. }
  1494. fSuccess = TRUE;
  1495. Ret:
  1496. if (! fSuccess)
  1497. printf("- error 0x%x\n", dwError = GetLastError());
  1498. if (hKey)
  1499. CryptDestroyKey(hKey);
  1500. return dwError;
  1501. }
  1502. //
  1503. // Function: LoadAesCspRegression
  1504. //
  1505. DWORD LoadAesCspRegression(PTHREAD_DATA pThreadData)
  1506. {
  1507. DWORD dwError = 0;
  1508. BOOL fSuccess = FALSE;
  1509. HMODULE hMod = NULL;
  1510. if (NULL == (hMod = LoadLibraryEx(RSA_AES_CSP, NULL, 0)))
  1511. {
  1512. printf("LoadLibraryEx %s ", RSA_AES_CSP);
  1513. goto Ret;
  1514. }
  1515. if (! FreeLibrary(hMod))
  1516. {
  1517. printf("FreeLibrary %s ", RSA_AES_CSP);
  1518. goto Ret;
  1519. }
  1520. fSuccess = TRUE;
  1521. Ret:
  1522. if (! fSuccess)
  1523. printf("- error 0x%x\n", dwError = GetLastError());
  1524. return dwError;
  1525. }
  1526. DWORD VerifyPinCallback(PPINCACHE_PINS pPins, PVOID pvData)
  1527. {
  1528. DWORD dwReturn = *(DWORD*)pvData;
  1529. PrintBytes(
  1530. "VerifyPinCallback current pin",
  1531. pPins->pbCurrentPin, pPins->cbCurrentPin);
  1532. PrintBytes(
  1533. "VerifyPinCallback new pin",
  1534. pPins->pbNewPin, pPins->cbNewPin);
  1535. return dwReturn;
  1536. }
  1537. static USHORT l_uTestLogonID;
  1538. void SetLogonID(USHORT uLogon)
  1539. {
  1540. l_uTestLogonID = uLogon;
  1541. }
  1542. void GetLogonID(LUID *pLuid)
  1543. {
  1544. memset(pLuid, l_uTestLogonID, sizeof(LUID));
  1545. }
  1546. BOOL MyGetTokenInformation(
  1547. HANDLE TokenHandle,
  1548. TOKEN_INFORMATION_CLASS TokenInformationClass,
  1549. LPVOID TokenInformation,
  1550. DWORD TokenInformationLength,
  1551. PDWORD ReturnLength)
  1552. {
  1553. NTSTATUS status = NtQueryInformationToken(
  1554. TokenHandle, TokenInformationClass,
  1555. TokenInformation, TokenInformationLength,
  1556. ReturnLength);
  1557. if (TokenStatistics == TokenInformationClass)
  1558. {
  1559. printf("MyGetTokenInformation: intercepted TokenStatistics call\n");
  1560. GetLogonID(&((TOKEN_STATISTICS*) TokenInformation)->AuthenticationId);
  1561. }
  1562. return (S_OK == status);
  1563. }
  1564. //
  1565. // Function: PinCacheRegression
  1566. //
  1567. DWORD PinCacheRegression(PTHREAD_DATA pThreadData)
  1568. {
  1569. DWORD dwError = 0;
  1570. BOOL fSuccess = FALSE;
  1571. PINCACHE_HANDLE hCache = NULL;
  1572. BYTE rgPin[] = { 1, 2, 3, 4 };
  1573. DWORD cbPin = sizeof(rgPin);
  1574. BYTE rgPin2[] = { 5, 6, 7, 8, 9 };
  1575. BYTE *pbPin = NULL;
  1576. PFN_VERIFYPIN_CALLBACK pfnVerifyPin = VerifyPinCallback;
  1577. DWORD dwCallbackReturn;
  1578. PINCACHE_PINS Pins;
  1579. ZeroMemory(&Pins, sizeof(PINCACHE_PINS));
  1580. Pins.cbCurrentPin = sizeof(rgPin);
  1581. Pins.pbCurrentPin = rgPin;
  1582. dwCallbackReturn = 0x7070;
  1583. if (0x7070 != (dwError =
  1584. PinCacheAdd(&hCache, &Pins,
  1585. pfnVerifyPin, (PVOID) &dwCallbackReturn)))
  1586. {
  1587. printf("PinCacheAdd with callback fail ");
  1588. goto Ret;
  1589. }
  1590. //
  1591. // (0)
  1592. // Cache uninitialized
  1593. //
  1594. SetLogonID(1);
  1595. dwCallbackReturn = ERROR_SUCCESS;
  1596. if (ERROR_SUCCESS != (dwError =
  1597. PinCacheAdd(&hCache, &Pins,
  1598. pfnVerifyPin, (PVOID) &dwCallbackReturn)))
  1599. {
  1600. printf("PinCacheAdd ");
  1601. goto Ret;
  1602. }
  1603. if (ERROR_SUCCESS != (dwError = PinCacheQuery(hCache, NULL, &cbPin)))
  1604. {
  1605. printf("PinCacheQuery NULL for size ");
  1606. goto Ret;
  1607. }
  1608. if (NULL == (pbPin = (PBYTE) MyAlloc(cbPin)))
  1609. return ERROR_NOT_ENOUGH_MEMORY;
  1610. cbPin--;
  1611. if (ERROR_SUCCESS == (dwError = PinCacheQuery(hCache, pbPin, &cbPin)))
  1612. {
  1613. printf("PinCacheQuery insufficient size succeeded ");
  1614. goto Ret;
  1615. }
  1616. if (ERROR_SUCCESS != (dwError = PinCacheQuery(hCache, pbPin, &cbPin)))
  1617. {
  1618. printf("PinCacheQuery ");
  1619. goto Ret;
  1620. }
  1621. if (sizeof(rgPin) != RtlCompareMemory(pbPin, rgPin, cbPin))
  1622. {
  1623. PrintBytes("Actual cache", pbPin, cbPin);
  1624. PrintBytes("Expected cache", rgPin, sizeof(rgPin));
  1625. printf("Cache is incorrect ");
  1626. goto Ret;
  1627. }
  1628. PinCacheFlush(&hCache);
  1629. if (NULL != hCache)
  1630. {
  1631. printf("PinCacheFlush should set hCache=NULL ");
  1632. goto Ret;
  1633. }
  1634. // Re-initialize to continue tests
  1635. if (ERROR_SUCCESS != (dwError =
  1636. PinCacheAdd(&hCache, &Pins,
  1637. pfnVerifyPin, (PVOID) &dwCallbackReturn)))
  1638. {
  1639. printf("PinCacheAdd ");
  1640. goto Ret;
  1641. }
  1642. //
  1643. // (1)
  1644. // Same LogonID, same Pin
  1645. //
  1646. if (ERROR_SUCCESS != (dwError =
  1647. PinCacheAdd(&hCache, &Pins,
  1648. pfnVerifyPin, (PVOID) &dwCallbackReturn)))
  1649. {
  1650. printf("PinCacheAdd 1 ");
  1651. goto Ret;
  1652. }
  1653. cbPin = sizeof(rgPin);
  1654. if (ERROR_SUCCESS != (dwError = PinCacheQuery(hCache, pbPin, &cbPin)))
  1655. {
  1656. printf("PinCacheQuery 1 ");
  1657. goto Ret;
  1658. }
  1659. if (sizeof(rgPin) != RtlCompareMemory(pbPin, rgPin, cbPin))
  1660. {
  1661. PrintBytes("Actual cache", pbPin, cbPin);
  1662. PrintBytes("Expected cache", rgPin, sizeof(rgPin));
  1663. printf("Cache is incorrect 1 ");
  1664. goto Ret;
  1665. }
  1666. // Try a pin change
  1667. Pins.cbNewPin = sizeof(rgPin2);
  1668. Pins.pbNewPin = rgPin2;
  1669. if (ERROR_SUCCESS != (dwError =
  1670. PinCacheAdd(&hCache, &Pins,
  1671. pfnVerifyPin, (PVOID) &dwCallbackReturn)))
  1672. {
  1673. printf("PinCacheAdd 1 change ");
  1674. goto Ret;
  1675. }
  1676. if (ERROR_SUCCESS != (dwError = PinCacheQuery(hCache, NULL, &cbPin)))
  1677. {
  1678. printf("PinCacheQuery 1 change query ");
  1679. goto Ret;
  1680. }
  1681. MyFree(pbPin);
  1682. pbPin = NULL;
  1683. if (NULL == (pbPin = (PBYTE) MyAlloc(cbPin)))
  1684. return ERROR_NOT_ENOUGH_MEMORY;
  1685. if (ERROR_SUCCESS != (dwError = PinCacheQuery(hCache, pbPin, &cbPin)))
  1686. {
  1687. printf("PinCacheQuery 1 change ");
  1688. goto Ret;
  1689. }
  1690. if (sizeof(rgPin2) != RtlCompareMemory(pbPin, rgPin2, cbPin))
  1691. {
  1692. PrintBytes("Actual cache", pbPin, cbPin);
  1693. PrintBytes("Expected cache", rgPin, sizeof(rgPin));
  1694. printf("Cache is incorrect 1 change ");
  1695. goto Ret;
  1696. }
  1697. // Try a failed pin change
  1698. Pins.cbCurrentPin = sizeof(rgPin2);
  1699. Pins.pbCurrentPin = rgPin2;
  1700. Pins.cbNewPin = sizeof(rgPin);
  1701. Pins.pbNewPin = rgPin;
  1702. dwCallbackReturn = -1;
  1703. if (-1 != (dwError =
  1704. PinCacheAdd(&hCache, &Pins,
  1705. pfnVerifyPin, (PVOID) &dwCallbackReturn)))
  1706. {
  1707. printf("PinCacheAdd 1 change-fail ");
  1708. goto Ret;
  1709. }
  1710. // Cache should have been preserved
  1711. cbPin = sizeof(rgPin2);
  1712. ZeroMemory(pbPin, sizeof(rgPin2));
  1713. if (ERROR_SUCCESS != (dwError = PinCacheQuery(hCache, pbPin, &cbPin)))
  1714. {
  1715. printf("PinCacheQuery 1 change-fail ");
  1716. goto Ret;
  1717. }
  1718. if (sizeof(rgPin2) != RtlCompareMemory(pbPin, rgPin2, cbPin))
  1719. {
  1720. PrintBytes("Actual cache", pbPin, cbPin);
  1721. PrintBytes("Expected cache", rgPin2, sizeof(rgPin2));
  1722. printf("Cache is incorrect 1 change-fail ");
  1723. goto Ret;
  1724. }
  1725. //
  1726. // (2)
  1727. // Different LogonID, different Pin
  1728. //
  1729. SetLogonID(2);
  1730. Pins.cbCurrentPin -= 1;
  1731. Pins.cbNewPin = 0;
  1732. Pins.pbNewPin = NULL;
  1733. dwCallbackReturn = ERROR_SUCCESS;
  1734. if (SCARD_W_WRONG_CHV != (dwError =
  1735. PinCacheAdd(&hCache, &Pins,
  1736. pfnVerifyPin, (PVOID) &dwCallbackReturn)))
  1737. {
  1738. printf("PinCacheAdd 2 ");
  1739. goto Ret;
  1740. }
  1741. SetLogonID(1);
  1742. cbPin = sizeof(rgPin2);
  1743. if (ERROR_SUCCESS != (dwError = PinCacheQuery(hCache, pbPin, &cbPin)))
  1744. {
  1745. printf("PinCacheQuery 2 ");
  1746. goto Ret;
  1747. }
  1748. if (sizeof(rgPin2) != RtlCompareMemory(pbPin, rgPin2, cbPin))
  1749. {
  1750. PrintBytes("Actual cache", pbPin, cbPin);
  1751. PrintBytes("Expected cache", rgPin2, sizeof(rgPin2));
  1752. printf("Cache is incorrect 2 ");
  1753. goto Ret;
  1754. }
  1755. //
  1756. // (3)
  1757. // Different LogonID, same Pin
  1758. //
  1759. SetLogonID(2);
  1760. Pins.cbCurrentPin = sizeof(rgPin2);
  1761. if (ERROR_SUCCESS != (dwError =
  1762. PinCacheAdd(&hCache, &Pins,
  1763. pfnVerifyPin, (PVOID) &dwCallbackReturn)))
  1764. {
  1765. printf("PinCacheAdd 3 ");
  1766. goto Ret;
  1767. }
  1768. cbPin = sizeof(rgPin2);
  1769. if (ERROR_SUCCESS != (dwError = PinCacheQuery(hCache, pbPin, &cbPin)))
  1770. {
  1771. printf("PinCacheQuery 3 ");
  1772. goto Ret;
  1773. }
  1774. if (sizeof(rgPin2) != RtlCompareMemory(pbPin, rgPin2, cbPin))
  1775. {
  1776. PrintBytes("Actual cache", pbPin, cbPin);
  1777. PrintBytes("Expected cache", rgPin2, sizeof(rgPin2));
  1778. printf("Cache is incorrect 3 ");
  1779. goto Ret;
  1780. }
  1781. SetLogonID(1);
  1782. if (ERROR_SUCCESS != (dwError = PinCacheQuery(hCache, pbPin, &cbPin)))
  1783. {
  1784. printf("PinCacheQuery 3,1 ");
  1785. goto Ret;
  1786. }
  1787. if (0 != cbPin)
  1788. {
  1789. printf("PinCacheQuery 3,1 should have returned NULL pin ");
  1790. goto Ret;
  1791. }
  1792. //
  1793. // (4)
  1794. // Same LogonID, different Pin
  1795. //
  1796. SetLogonID(2);
  1797. Pins.cbCurrentPin -= 1;
  1798. if (SCARD_W_WRONG_CHV != (dwError =
  1799. PinCacheAdd(&hCache, &Pins,
  1800. pfnVerifyPin, (PVOID) &dwCallbackReturn)))
  1801. {
  1802. printf("PinCacheAdd 4 ");
  1803. goto Ret;
  1804. }
  1805. // cache should have been left intact
  1806. cbPin = sizeof(rgPin2);
  1807. if (ERROR_SUCCESS != (dwError = PinCacheQuery(hCache, pbPin, &cbPin)))
  1808. {
  1809. printf("PinCacheQuery 4 ");
  1810. goto Ret;
  1811. }
  1812. if (sizeof(rgPin2) != RtlCompareMemory(pbPin, rgPin2, cbPin))
  1813. {
  1814. PrintBytes("Actual cache", pbPin, cbPin);
  1815. PrintBytes("Expected cache", rgPin2, sizeof(rgPin2));
  1816. printf("Cache is incorrect 4 ");
  1817. goto Ret;
  1818. }
  1819. dwError = ERROR_SUCCESS;
  1820. fSuccess = TRUE;
  1821. Ret:
  1822. if (pbPin)
  1823. MyFree(pbPin);
  1824. if (! fSuccess)
  1825. {
  1826. printf("- error 0x%x\n", dwError);
  1827. if (0 == dwError)
  1828. return -1;
  1829. }
  1830. return dwError;
  1831. }
  1832. //
  1833. // Function: VerifyDesKeyParams
  1834. //
  1835. DWORD VerifyDesKeyParams(
  1836. IN HCRYPTKEY hKey,
  1837. IN DWORD dwExpectedKeyLen,
  1838. IN DWORD dwExpectedEffectiveKeyLen)
  1839. {
  1840. DWORD dwError = 0;
  1841. DWORD dwParam = 0;
  1842. DWORD cb = sizeof(dwParam);
  1843. BOOL fSuccess = FALSE;
  1844. if (! CryptGetKeyParam(hKey, KP_KEYLEN, (PBYTE) &dwParam, &cb, 0))
  1845. {
  1846. dwError = GetLastError();
  1847. printf("CryptGetKeyParam KP_KEYLEN ");
  1848. goto Ret;
  1849. }
  1850. if (dwExpectedKeyLen != dwParam)
  1851. {
  1852. printf(
  1853. "FAIL: VerifyDesKeyParams expected KP_KEYLEN=%d, actual=%d\n",
  1854. dwExpectedKeyLen, dwParam);
  1855. goto Ret;
  1856. }
  1857. if (! CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, (PBYTE) &dwParam, &cb, 0))
  1858. {
  1859. dwError = GetLastError();
  1860. printf("CryptGetKeyParam KP_EFFECTIVE_KEYLEN ");
  1861. goto Ret;
  1862. }
  1863. if (dwExpectedEffectiveKeyLen != dwParam)
  1864. {
  1865. printf(
  1866. "FAIL: VerifyDesKeyParams expected KP_EFFECTIVE_KEYLEN=%d, actual=%d\n",
  1867. dwExpectedEffectiveKeyLen, dwParam);
  1868. goto Ret;
  1869. }
  1870. fSuccess = TRUE;
  1871. Ret:
  1872. if (! fSuccess)
  1873. {
  1874. printf(" - error 0x%x\n", dwError);
  1875. if (0 == dwError)
  1876. dwError = -1;
  1877. }
  1878. return dwError;
  1879. }
  1880. //
  1881. // Function: DesGetKeyParamRegression
  1882. //
  1883. DWORD DesGetKeyParamRegression(PTHREAD_DATA pThreadData)
  1884. {
  1885. DWORD dwError = ERROR_SUCCESS;
  1886. BOOL fSuccess = FALSE;
  1887. HCRYPTKEY hKey = 0;
  1888. if (! CryptGenKey(pThreadData->hProv, CALG_DES, 0, &hKey))
  1889. {
  1890. dwError = GetLastError();
  1891. printf("CryptGenKey des ");
  1892. goto Ret;
  1893. }
  1894. if (ERROR_SUCCESS != (dwError = VerifyDesKeyParams(hKey, 64, 56)))
  1895. {
  1896. printf("VerifyDesKeyParams des ");
  1897. goto Ret;
  1898. }
  1899. if (! CryptDestroyKey(hKey))
  1900. {
  1901. dwError = GetLastError();
  1902. printf("CryptDestroyKey des ");
  1903. goto Ret;
  1904. }
  1905. hKey = 0;
  1906. if (! CryptGenKey(pThreadData->hProv, CALG_3DES_112, 0, &hKey))
  1907. {
  1908. dwError = GetLastError();
  1909. printf("CryptGenKey 3des_112 ");
  1910. goto Ret;
  1911. }
  1912. if (ERROR_SUCCESS != (dwError = VerifyDesKeyParams(hKey, 128, 112)))
  1913. {
  1914. printf("VerifyDesKeyParams 3des_112 ");
  1915. goto Ret;
  1916. }
  1917. if (! CryptDestroyKey(hKey))
  1918. {
  1919. dwError = GetLastError();
  1920. printf("CryptDestroyKey 3des_112 ");
  1921. goto Ret;
  1922. }
  1923. hKey = 0;
  1924. if (! CryptGenKey(pThreadData->hProv, CALG_3DES, 0, &hKey))
  1925. {
  1926. dwError = GetLastError();
  1927. printf("CryptGenKey 3des ");
  1928. goto Ret;
  1929. }
  1930. if (ERROR_SUCCESS != (dwError = VerifyDesKeyParams(hKey, 192, 168)))
  1931. {
  1932. printf("VerifyDesKeyParams 3des ");
  1933. goto Ret;
  1934. }
  1935. if (! CryptDestroyKey(hKey))
  1936. {
  1937. dwError = GetLastError();
  1938. printf("CryptDestroyKey 3des ");
  1939. goto Ret;
  1940. }
  1941. fSuccess = TRUE;
  1942. Ret:
  1943. if (! fSuccess)
  1944. {
  1945. printf("- error 0x%x\n", dwError);
  1946. if (0 == dwError)
  1947. return -1;
  1948. }
  1949. return dwError;
  1950. }
  1951. //
  1952. // Function: MacEncryptRegression
  1953. //
  1954. DWORD MacEncryptRegression(
  1955. IN PTHREAD_DATA pThreadData)
  1956. {
  1957. DWORD dwError = ERROR_SUCCESS;
  1958. BOOL fSuccess = FALSE;
  1959. HCRYPTKEY hSymKey = 0;
  1960. HCRYPTKEY hMacKey = 0;
  1961. HCRYPTKEY hMacKey2 = 0;
  1962. HCRYPTHASH hMac = 0;
  1963. BYTE rgPlaintext[31];
  1964. DWORD cb = sizeof(rgPlaintext);
  1965. DWORD cbBuf = 0;
  1966. PBYTE pbMac = NULL;
  1967. DWORD cbMac = 0;
  1968. PBYTE pb = NULL;
  1969. if (! CryptGenKey(pThreadData->hProv, CALG_RC2, 0, &hSymKey))
  1970. {
  1971. printf("CryptGenKey rc2");
  1972. goto Ret;
  1973. }
  1974. if (! CryptGenKey(pThreadData->hProv, CALG_RC2, 0, &hMacKey))
  1975. {
  1976. printf("CryptGenKey rc2 2");
  1977. goto Ret;
  1978. }
  1979. if (! CryptDuplicateKey(hMacKey, NULL, 0, &hMacKey2))
  1980. {
  1981. printf("CryptDuplicateKey");
  1982. goto Ret;
  1983. }
  1984. if (! CryptCreateHash(pThreadData->hProv, CALG_MAC, hMacKey, 0, &hMac))
  1985. {
  1986. printf("CryptCreateHash");
  1987. goto Ret;
  1988. }
  1989. while (cb--)
  1990. rgPlaintext[cb] = (BYTE) cb;
  1991. cb = sizeof(rgPlaintext);
  1992. if (! CryptEncrypt(hSymKey, 0, TRUE, 0, NULL, &cb, 0))
  1993. {
  1994. printf("CryptEncrypt size");
  1995. goto Ret;
  1996. }
  1997. if (NULL == (pb = (PBYTE) MyAlloc(cb)))
  1998. return ERROR_NOT_ENOUGH_MEMORY;
  1999. cbBuf = cb;
  2000. cb = sizeof(rgPlaintext);
  2001. if (! CryptEncrypt(hSymKey, hMac, TRUE, 0, pb, &cb, cbBuf))
  2002. {
  2003. printf("CryptEncrypt");
  2004. goto Ret;
  2005. }
  2006. if (! CryptGetHashParam(hMac, HP_HASHVAL, NULL, &cbMac, 0))
  2007. {
  2008. printf("CryptGetHashParam size");
  2009. goto Ret;
  2010. }
  2011. if (NULL == (pbMac = (PBYTE) MyAlloc(cbMac)))
  2012. return ERROR_NOT_ENOUGH_MEMORY;
  2013. if (! CryptGetHashParam(hMac, HP_HASHVAL, pbMac, &cbMac, 0))
  2014. {
  2015. printf("CryptGetHashParam");
  2016. goto Ret;
  2017. }
  2018. if (! CryptDestroyHash(hMac))
  2019. {
  2020. printf("CryptDestroyHash");
  2021. goto Ret;
  2022. }
  2023. hMac = 0;
  2024. if (! CryptCreateHash(pThreadData->hProv, CALG_MAC, hMacKey2, 0, &hMac))
  2025. {
  2026. printf("CryptCreateHash 2");
  2027. goto Ret;
  2028. }
  2029. if (! CryptDecrypt(hSymKey, hMac, TRUE, 0, pb, &cb))
  2030. {
  2031. printf("CryptDecrypt");
  2032. goto Ret;
  2033. }
  2034. MyFree(pb);
  2035. pb = NULL;
  2036. if (! CryptGetHashParam(hMac, HP_HASHVAL, NULL, &cb, 0))
  2037. {
  2038. printf("CryptGetHashParam size");
  2039. goto Ret;
  2040. }
  2041. if (NULL == (pb = (PBYTE) MyAlloc(cb)))
  2042. return ERROR_NOT_ENOUGH_MEMORY;
  2043. if (! CryptGetHashParam(hMac, HP_HASHVAL, pb, &cb, 0))
  2044. {
  2045. printf("CryptGetHashParam");
  2046. goto Ret;
  2047. }
  2048. PrintBytes("Expected Mac result", pbMac, cbMac);
  2049. PrintBytes("Actual Mac result", pb, cb);
  2050. if (0 != memcmp(pb, pbMac, cb)
  2051. || 0 == cb
  2052. || cb != cbMac)
  2053. {
  2054. goto Ret;
  2055. }
  2056. fSuccess = TRUE;
  2057. Ret:
  2058. if (! fSuccess)
  2059. {
  2060. dwError = GetLastError();
  2061. printf(" - error 0x%x\n", dwError);
  2062. if (0 == dwError)
  2063. dwError = -1;
  2064. }
  2065. if (pb)
  2066. MyFree(pb);
  2067. if (pbMac)
  2068. MyFree(pbMac);
  2069. if (hSymKey)
  2070. CryptDestroyKey(hSymKey);
  2071. if (hMacKey)
  2072. CryptDestroyKey(hMacKey);
  2073. if (hMacKey2)
  2074. CryptDestroyKey(hMacKey2);
  2075. if (hMac)
  2076. CryptDestroyHash(hMac);
  2077. return dwError;
  2078. }
  2079. //
  2080. // Function: StressEncryptionTest
  2081. //
  2082. DWORD StressEncryptionTest(
  2083. IN HCRYPTPROV hProv,
  2084. IN PENCRYPTION_TEST_DATA pTestData)
  2085. {
  2086. HCRYPTKEY hEncryptionKey = 0;
  2087. HCRYPTKEY hHashKey1 = 0;
  2088. HCRYPTKEY hHashKey2 = 0;
  2089. HCRYPTHASH hHash = 0;
  2090. PBYTE pbData = 0;
  2091. DWORD dwData = 0;
  2092. DWORD cbData = 0;
  2093. DWORD cbPlainText = 0;
  2094. DWORD cbCipherText = 0;
  2095. DWORD cbProcessed = 0;
  2096. DWORD dwKeyAlg = 0;
  2097. DWORD dwBlockLen = 0;
  2098. BOOL fFinal = FALSE;
  2099. DWORD dwError = 0;
  2100. BOOL fSuccess = FALSE;
  2101. BYTE rgbHashVal1[200];
  2102. BYTE rgbHashVal2[200];
  2103. ZeroMemory(rgbHashVal1, 200);
  2104. ZeroMemory(rgbHashVal2, 200);
  2105. if (! CryptGenKey(
  2106. hProv,
  2107. pTestData->aiEncryptionKey,
  2108. 0,
  2109. &hEncryptionKey))
  2110. {
  2111. goto Cleanup;
  2112. }
  2113. //
  2114. // Check for requested simultaneous encryption/hashing
  2115. //
  2116. if (pTestData->aiHash)
  2117. {
  2118. //
  2119. // Is this a keyed hash?
  2120. //
  2121. if (pTestData->aiHashKey)
  2122. {
  2123. if (! CryptGenKey(
  2124. hProv,
  2125. pTestData->aiHashKey,
  2126. 0,
  2127. &hHashKey1))
  2128. {
  2129. goto Cleanup;
  2130. }
  2131. //
  2132. // To verify the result of hashing the same data in two
  2133. // separate keyed hashes, the key must first be duplicated,
  2134. // since its state changes once it's used.
  2135. //
  2136. if (! CryptDuplicateKey(
  2137. hHashKey1,
  2138. NULL,
  2139. 0,
  2140. &hHashKey2))
  2141. {
  2142. goto Cleanup;
  2143. }
  2144. }
  2145. if (! CryptCreateHash(
  2146. hProv,
  2147. pTestData->aiHash,
  2148. hHashKey1,
  2149. 0,
  2150. &hHash))
  2151. {
  2152. goto Cleanup;
  2153. }
  2154. }
  2155. //
  2156. // Is this a block encryption alg?
  2157. //
  2158. if (ALG_TYPE_BLOCK & pTestData->aiEncryptionKey)
  2159. {
  2160. //
  2161. // Get the block size of this encryption alg
  2162. //
  2163. cbData = sizeof(dwBlockLen);
  2164. if (! CryptGetKeyParam(
  2165. hEncryptionKey,
  2166. KP_BLOCKLEN,
  2167. (PBYTE) &dwBlockLen,
  2168. &cbData,
  2169. 0))
  2170. {
  2171. goto Cleanup;
  2172. }
  2173. //
  2174. // Choose an "interesting" plaintext length, based on the block length
  2175. // of this alg.
  2176. //
  2177. cbPlainText = 2 * dwBlockLen + 1;
  2178. }
  2179. else
  2180. {
  2181. //
  2182. // Plaintext length for a stream encryption alg
  2183. //
  2184. cbPlainText = 500;
  2185. }
  2186. cbCipherText = cbPlainText;
  2187. //
  2188. // Determine size of ciphertext
  2189. //
  2190. if (! CryptEncrypt(
  2191. hEncryptionKey,
  2192. 0,
  2193. TRUE,
  2194. 0,
  2195. NULL,
  2196. &cbCipherText,
  2197. 0))
  2198. {
  2199. goto Cleanup;
  2200. }
  2201. if (NULL == (pbData = (PBYTE) MyAlloc(cbCipherText)))
  2202. {
  2203. goto Cleanup;
  2204. }
  2205. //
  2206. // Initialize the plaintext
  2207. //
  2208. memset(pbData, 0xDA, cbPlainText);
  2209. memset(pbData + cbPlainText, 0, cbCipherText - cbPlainText);
  2210. //
  2211. // Encrypt
  2212. //
  2213. cbProcessed = 0;
  2214. while (! fFinal)
  2215. {
  2216. if (0 == dwBlockLen)
  2217. {
  2218. cbData = cbPlainText;
  2219. fFinal = TRUE;
  2220. }
  2221. else
  2222. {
  2223. if (cbPlainText - cbProcessed > dwBlockLen)
  2224. {
  2225. cbData = dwBlockLen;
  2226. }
  2227. else
  2228. {
  2229. cbData = cbPlainText % dwBlockLen;
  2230. fFinal = TRUE;
  2231. }
  2232. }
  2233. if (! CryptEncrypt(
  2234. hEncryptionKey,
  2235. hHash,
  2236. fFinal,
  2237. 0,
  2238. pbData + cbProcessed,
  2239. &cbData,
  2240. cbCipherText))
  2241. {
  2242. goto Cleanup;
  2243. }
  2244. cbProcessed += cbData;
  2245. }
  2246. if (cbProcessed != cbCipherText)
  2247. {
  2248. goto Cleanup;
  2249. }
  2250. if (0 != hHash)
  2251. {
  2252. //
  2253. // Get hash result from encryption
  2254. //
  2255. cbData = sizeof(rgbHashVal1);
  2256. if (! CryptGetHashParam(
  2257. hHash,
  2258. HP_HASHVAL,
  2259. rgbHashVal1,
  2260. &cbData,
  2261. 0))
  2262. {
  2263. goto Cleanup;
  2264. }
  2265. if (! CryptDestroyHash(hHash))
  2266. {
  2267. goto Cleanup;
  2268. }
  2269. if (! CryptCreateHash(
  2270. hProv,
  2271. pTestData->aiHash,
  2272. hHashKey2,
  2273. 0,
  2274. &hHash))
  2275. {
  2276. goto Cleanup;
  2277. }
  2278. }
  2279. //
  2280. // Decrypt
  2281. //
  2282. cbProcessed = 0;
  2283. fFinal = FALSE;
  2284. while (! fFinal)
  2285. {
  2286. if (0 == dwBlockLen)
  2287. {
  2288. cbData = cbCipherText;
  2289. fFinal = TRUE;
  2290. }
  2291. else
  2292. {
  2293. if (cbCipherText - cbProcessed > dwBlockLen)
  2294. {
  2295. cbData = dwBlockLen;
  2296. }
  2297. else
  2298. {
  2299. cbData = cbCipherText - cbProcessed;
  2300. fFinal = TRUE;
  2301. }
  2302. }
  2303. if (! CryptDecrypt(
  2304. hEncryptionKey,
  2305. hHash,
  2306. fFinal,
  2307. 0,
  2308. pbData + cbProcessed,
  2309. &cbData))
  2310. {
  2311. goto Cleanup;
  2312. }
  2313. cbProcessed += cbData;
  2314. }
  2315. if (cbProcessed != cbPlainText)
  2316. {
  2317. goto Cleanup;
  2318. }
  2319. while (cbPlainText)
  2320. {
  2321. if (0xDA != pbData[cbPlainText - 1])
  2322. {
  2323. goto Cleanup;
  2324. }
  2325. cbPlainText--;
  2326. }
  2327. if (0 != hHash)
  2328. {
  2329. //
  2330. // Get hash result from decryption
  2331. //
  2332. cbData = sizeof(rgbHashVal2);
  2333. if (! CryptGetHashParam(
  2334. hHash,
  2335. HP_HASHVAL,
  2336. rgbHashVal2,
  2337. &cbData,
  2338. 0))
  2339. {
  2340. goto Cleanup;
  2341. }
  2342. if (0 != memcmp(rgbHashVal1, rgbHashVal2, cbData))
  2343. {
  2344. goto Cleanup;
  2345. }
  2346. }
  2347. fSuccess = TRUE;
  2348. Cleanup:
  2349. if (! fSuccess)
  2350. {
  2351. if (0 == (dwError = GetLastError()))
  2352. {
  2353. dwError = -1;
  2354. }
  2355. }
  2356. if (hEncryptionKey)
  2357. {
  2358. CryptDestroyKey(hEncryptionKey);
  2359. }
  2360. if (hHashKey1)
  2361. {
  2362. CryptDestroyKey(hHashKey1);
  2363. }
  2364. if (hHashKey2)
  2365. {
  2366. CryptDestroyKey(hHashKey2);
  2367. }
  2368. if (hHash)
  2369. {
  2370. CryptDestroyHash(hHash);
  2371. }
  2372. if (pbData)
  2373. {
  2374. MyFree(pbData);
  2375. }
  2376. return dwError;
  2377. }
  2378. //
  2379. // Function: StressTestAllEncryptionAlgs
  2380. //
  2381. DWORD StressTestAllEncryptionAlgs(
  2382. PTHREAD_DATA pThreadData,
  2383. BOOL fContinueOnMacError,
  2384. BOOL *pfMacErrorOccurred)
  2385. {
  2386. DWORD dwError = 0;
  2387. ENCRYPTION_TEST_DATA TestData;
  2388. PALGNODE pEncryptionAlg, pHashAlg, pBlockEncryptionAlg;
  2389. ZeroMemory(&TestData, sizeof(TestData));
  2390. for ( pEncryptionAlg = pThreadData->pAlgList;
  2391. NULL != pEncryptionAlg;
  2392. pEncryptionAlg = pEncryptionAlg->pNext)
  2393. {
  2394. if (! (pEncryptionAlg->EnumalgsEx.aiAlgid & ALG_CLASS_DATA_ENCRYPT))
  2395. continue;
  2396. TestData.aiEncryptionKey = pEncryptionAlg->EnumalgsEx.aiAlgid;
  2397. for ( pHashAlg = pThreadData->pAlgList;
  2398. NULL != pHashAlg;
  2399. pHashAlg = pHashAlg->pNext)
  2400. {
  2401. if ( (! (pHashAlg->EnumalgsEx.aiAlgid & ALG_CLASS_HASH &&
  2402. pHashAlg->EnumalgsEx.aiAlgid & ALG_TYPE_ANY)) ||
  2403. CALG_SSL3_SHAMD5 == pHashAlg->EnumalgsEx.aiAlgid ||
  2404. CALG_TLS1PRF == pHashAlg->EnumalgsEx.aiAlgid)
  2405. continue;
  2406. TestData.aiHash = pHashAlg->EnumalgsEx.aiAlgid;
  2407. if (CALG_MAC == pHashAlg->EnumalgsEx.aiAlgid)
  2408. {
  2409. for ( pBlockEncryptionAlg = pThreadData->pAlgList;
  2410. NULL != pBlockEncryptionAlg;
  2411. pBlockEncryptionAlg = pBlockEncryptionAlg->pNext)
  2412. {
  2413. if (! ( pBlockEncryptionAlg->EnumalgsEx.aiAlgid & ALG_CLASS_DATA_ENCRYPT &&
  2414. pBlockEncryptionAlg->EnumalgsEx.aiAlgid & ALG_TYPE_BLOCK))
  2415. continue;
  2416. TestData.aiHashKey = pBlockEncryptionAlg->EnumalgsEx.aiAlgid;
  2417. if (ERROR_SUCCESS != (dwError = StressEncryptionTest(pThreadData->hProv, &TestData)))
  2418. {
  2419. if (fContinueOnMacError)
  2420. *pfMacErrorOccurred = TRUE;
  2421. else
  2422. return dwError;
  2423. }
  2424. }
  2425. }
  2426. else
  2427. {
  2428. if (ERROR_SUCCESS != (dwError = StressEncryptionTest(pThreadData->hProv, &TestData)))
  2429. return dwError;
  2430. }
  2431. }
  2432. }
  2433. return dwError;
  2434. }
  2435. //+ ===========================================================================
  2436. //- ===========================================================================
  2437. void L_ErrorBox(LPSTR pszMsg, DWORD dwThreadNum)
  2438. {
  2439. char szErrorMsg[256] ;
  2440. sprintf(szErrorMsg, "Thread %d: %s in L_ErrorBox", dwThreadNum, pszMsg) ;
  2441. MessageBox(NULL, szErrorMsg, ERROR_CAPTION, MB_OK | MB_ICONERROR) ;
  2442. }
  2443. //+ ===========================================================================
  2444. //- ===========================================================================
  2445. void L_LastErrorBox(LPSTR pszMsg, DWORD dwThreadNum)
  2446. {
  2447. char szErrorMsg[256] ;
  2448. sprintf(szErrorMsg, "Thread %d: %s 0x%x in L_LastErrorBox", dwThreadNum, pszMsg, GetLastError()) ;
  2449. MessageBox(NULL, szErrorMsg, ERROR_CAPTION, MB_OK | MB_ICONERROR) ;
  2450. }
  2451. //+ =================================================================================
  2452. //
  2453. // L_GetKeyAlg
  2454. // Local function that given a key handle, returns the key Alg.
  2455. //
  2456. //- =================================================================================
  2457. DWORD L_GetKeyAlg(HCRYPTKEY hKey)
  2458. {
  2459. DWORD dwData = 0;
  2460. DWORD cbData=0 ;
  2461. char szErrorMsg[256];
  2462. cbData = sizeof(dwData) ;
  2463. if (!CryptGetKeyParam(
  2464. hKey,
  2465. KP_ALGID,
  2466. (PBYTE) &dwData,
  2467. &cbData,
  2468. 0))
  2469. {
  2470. GENERIC_FAIL(CryptGetKeyParam) ;
  2471. }
  2472. ErrorReturn:
  2473. return dwData;
  2474. }
  2475. //+ =================================================================================
  2476. //
  2477. // L_GetKeySize
  2478. // Local function that given a key handle, returns the key length.
  2479. //
  2480. //- =================================================================================
  2481. DWORD L_GetKeySize(HCRYPTKEY hKey)
  2482. {
  2483. DWORD dwData = 0;
  2484. DWORD cbData=0 ;
  2485. char szErrorMsg[256];
  2486. cbData = sizeof(dwData) ;
  2487. if (!CryptGetKeyParam(
  2488. hKey,
  2489. KP_KEYLEN,
  2490. (PBYTE) &dwData,
  2491. &cbData,
  2492. 0))
  2493. {
  2494. GENERIC_FAIL(CryptGetKeyParam) ;
  2495. }
  2496. ErrorReturn:
  2497. return dwData;
  2498. }
  2499. //+ ==============================================================================
  2500. //- ==============================================================================
  2501. DWORD Hlp_GetKeyAlgId(HCRYPTKEY hKey)
  2502. {
  2503. DWORD dwRetVal=0 ;
  2504. PBYTE pbData=NULL ;
  2505. DWORD cbData=sizeof(DWORD) ;
  2506. char szErrorMsg[256] ;
  2507. DWORD dwAlgId=0 ;
  2508. if (!CryptGetKeyParam(
  2509. hKey,
  2510. KP_ALGID,
  2511. (PBYTE)&dwAlgId,
  2512. &cbData,
  2513. 0))
  2514. GENERIC_FAIL(CryptGetKeyParam) ;
  2515. dwRetVal=dwAlgId ;
  2516. ErrorReturn :
  2517. return dwRetVal ;
  2518. }
  2519. //+ =================================================================================
  2520. //
  2521. // L_GetKeyParam
  2522. // Local function that given a key handle, retrieves the specified Key Param.
  2523. // The Key param is not of too much interest in this case. In a multithread scenario,
  2524. // we just care to see if the call succeeds.
  2525. //
  2526. //- =================================================================================
  2527. DWORD L_GetKeyParam(HCRYPTKEY hKey, DWORD dwParam)
  2528. {
  2529. DWORD dwRetVal=0 ;
  2530. PBYTE pbData=NULL ;
  2531. DWORD cbData=0 ;
  2532. char szErrorMsg[256] ;
  2533. DWORD dwAlgId=0 ;
  2534. DWORD dwError=0 ;
  2535. if (!CryptGetKeyParam( hKey,
  2536. dwParam,
  2537. NULL,
  2538. &cbData,
  2539. 0))
  2540. GENERIC_FAIL(CryptGetKeyParam) ;
  2541. if (NULL == (pbData = (PBYTE) MyAlloc(cbData)))
  2542. ALLOC_FAIL(pbData);
  2543. if (!CryptGetKeyParam( hKey,
  2544. dwParam,
  2545. pbData,
  2546. &cbData,
  2547. 0))
  2548. GENERIC_FAIL(CryptGetKeyParam) ;
  2549. dwRetVal=1 ;
  2550. ErrorReturn :
  2551. MyFree(pbData) ;
  2552. return dwRetVal ;
  2553. }
  2554. //+ ======================================================================================
  2555. // ProgramInit
  2556. // Acquire context
  2557. // Generate Keys that will be used by all the threads. (AT_SIGNATURE and AT_KEYEXCHANGE)
  2558. //- ======================================================================================
  2559. DWORD ProgramInit(PTHREAD_DATA pThreadData)
  2560. {
  2561. DWORD dwRetVal = 0;
  2562. char szErrorMsg[256]; // defined for GENERIC_FAIL
  2563. LPSTR pszContainer = NULL;
  2564. DWORD dwContextFlags = 0;
  2565. DWORD dwKeyFlags = CRYPT_EXPORTABLE;
  2566. if (pThreadData->fEphemeralKeys)
  2567. {
  2568. dwContextFlags = CRYPT_VERIFYCONTEXT;
  2569. }
  2570. else
  2571. {
  2572. pszContainer = KEY_CONTAINER_NAME;
  2573. dwContextFlags = CRYPT_NEWKEYSET;
  2574. CryptAcquireContext(
  2575. &pThreadData->hProv,
  2576. pszContainer,
  2577. pThreadData->rgszProvName,
  2578. pThreadData->dwProvType,
  2579. CRYPT_DELETEKEYSET);
  2580. // Create a Verify Context for some of the sub-tests to use
  2581. if (! CryptAcquireContext(
  2582. &pThreadData->hVerifyCtx,
  2583. NULL,
  2584. pThreadData->rgszProvName,
  2585. pThreadData->dwProvType,
  2586. CRYPT_VERIFYCONTEXT))
  2587. {
  2588. pThreadData->hVerifyCtx = 0;
  2589. GENERIC_FAIL(CryptAcquireContext_VERIFYCONTEXT);
  2590. }
  2591. }
  2592. if (pThreadData->fUserProtectedKeys)
  2593. dwKeyFlags |= CRYPT_USER_PROTECTED;
  2594. if (!CryptAcquireContext(
  2595. &pThreadData->hProv,
  2596. pszContainer,
  2597. pThreadData->rgszProvName,
  2598. pThreadData->dwProvType,
  2599. dwContextFlags))
  2600. {
  2601. pThreadData->hProv = 0;
  2602. GENERIC_FAIL(CryptAcquireContext_Init);
  2603. }
  2604. // Generate a sign and exchange key
  2605. if (!CryptGenKey(
  2606. pThreadData->hProv,
  2607. AT_SIGNATURE,
  2608. dwKeyFlags,
  2609. &pThreadData->hSignatureKey))
  2610. {
  2611. GENERIC_FAIL(CryptGenKey_AT_SIGNATURE);
  2612. CryptReleaseContext(pThreadData->hProv, 0);
  2613. pThreadData->hProv = 0;
  2614. pThreadData->hSignatureKey = 0;
  2615. }
  2616. if (PROV_RSA_FULL == pThreadData->dwProvType ||
  2617. PROV_DSS_DH == pThreadData->dwProvType)
  2618. {
  2619. if (!CryptGenKey(
  2620. pThreadData->hProv,
  2621. AT_KEYEXCHANGE,
  2622. dwKeyFlags,
  2623. &pThreadData->hExchangeKey))
  2624. {
  2625. GENERIC_FAIL(CryptGenKey_AT_KEYEXCHANGE);
  2626. CryptReleaseContext(pThreadData->hProv, 0);
  2627. pThreadData->hProv = 0;
  2628. pThreadData->hExchangeKey = 0;
  2629. }
  2630. }
  2631. dwRetVal=1;
  2632. ErrorReturn:
  2633. return dwRetVal;
  2634. }
  2635. // ======================================================================================
  2636. // Terminates all the threads after the specified amount of time has elapsed (-t option)
  2637. // This thread sleeps for the specified amount of time and them then turns off the
  2638. // g_dwLoopSwitch.
  2639. // ======================================================================================
  2640. void WINAPI KillProgramTimer(LPVOID pvThreadData)
  2641. {
  2642. DWORD dwSleepTime=0;
  2643. PTHREAD_DATA pThreadData = (PTHREAD_DATA) pvThreadData;
  2644. if (pThreadData->dwProgramMins)
  2645. {
  2646. dwSleepTime = pThreadData->dwProgramMins * 60 * 1000;
  2647. SleepEx(dwSleepTime, FALSE);
  2648. if (! SetEvent(pThreadData->hEndTestEvent))
  2649. {
  2650. printf("SetEvent() failed, 0x%x\n", GetLastError());
  2651. exit(1);
  2652. }
  2653. printf("All threads should be shutting down now....\n");
  2654. }
  2655. }
  2656. // ======================================================================================
  2657. // Prints the status of all the threads
  2658. // The status is represented in iteration count in ThreadStatus[i][0]
  2659. // ======================================================================================
  2660. void WINAPI PrintThreadStatus(LPVOID pvThreadData)
  2661. {
  2662. DWORD thread;
  2663. PTHREAD_DATA pThreadData = (PTHREAD_DATA) pvThreadData;
  2664. char rgStatus[256] ;
  2665. printf("\n\n\n") ;
  2666. while (WAIT_TIMEOUT == WaitForSingleObject(pThreadData->hEndTestEvent, 0))
  2667. {
  2668. Sleep(10000);
  2669. ZeroMemory(rgStatus, sizeof(rgStatus));
  2670. for (thread = 0; thread < pThreadData->dwThreadCount; thread++)
  2671. {
  2672. sprintf(
  2673. rgStatus + strlen(rgStatus),
  2674. " %4x",
  2675. pThreadData->rgdwThreadStatus[thread]);
  2676. }
  2677. printf("%s\n", rgStatus);
  2678. }
  2679. }
  2680. //+ ========================================================================
  2681. //
  2682. // Function : L_GetAllKeyParams
  2683. // Purpose : Gets all the key params and does nothing with it
  2684. //
  2685. //- ========================================================================
  2686. DWORD L_GetAllKeyParams(HCRYPTKEY hKey, DWORD dwThreadNum)
  2687. {
  2688. char szErrorMsg[256] ;
  2689. ALG_ID AlgId=0 ;
  2690. DWORD dwRetVal=0 ;
  2691. AlgId = (ALG_ID)Hlp_GetKeyAlgId(hKey) ;
  2692. // Get Keys Length
  2693. if (!L_GetKeyParam(hKey, KP_KEYLEN))
  2694. {
  2695. sprintf(szErrorMsg, "Thread %d: L_GetKeyParam KP_KEYLEN error 0x%x",
  2696. dwThreadNum, GetLastError()) ;
  2697. MessageBox(NULL, szErrorMsg, ERROR_CAPTION, MB_OK | MB_ICONERROR) ;
  2698. goto ErrorReturn ;
  2699. }
  2700. // Get ALGID
  2701. if (!L_GetKeyParam(hKey, KP_ALGID))
  2702. {
  2703. sprintf(szErrorMsg, "Thread %d: L_GetKeyParam KP_ALGID error 0x%x",
  2704. dwThreadNum, GetLastError()) ;
  2705. MessageBox(NULL, szErrorMsg, ERROR_CAPTION, MB_OK | MB_ICONERROR) ;
  2706. goto ErrorReturn ;
  2707. }
  2708. // Get KP_BLOCKLEN
  2709. // Although this is meaningful only for block cipher keys, it will not fail
  2710. // for RSA Keys. It'll just return 0 as the block len (which we don't care
  2711. // about for multi tests.
  2712. if (!L_GetKeyParam(hKey, KP_BLOCKLEN))
  2713. {
  2714. sprintf(szErrorMsg, "Thread %d: L_GetKeyParam KP_BLOCKLEN error 0x%x",
  2715. dwThreadNum, GetLastError()) ;
  2716. MessageBox(NULL, szErrorMsg, ERROR_CAPTION, MB_OK | MB_ICONERROR) ;
  2717. goto ErrorReturn ;
  2718. }
  2719. /*
  2720. if (! (ALG_CLASS_SIGNATURE == GET_ALG_CLASS(AlgId)
  2721. || ALG_CLASS_KEY_EXCHANGE == GET_ALG_CLASS(AlgId)))
  2722. {
  2723. if (!L_GetKeyParam(hKey, KP_SALT))
  2724. {
  2725. sprintf(szErrorMsg, "Thread %d: L_GetKeyParam KP_SALT error 0x%x",
  2726. dwThreadNum, GetLastError()) ;
  2727. MessageBox(NULL, szErrorMsg, ERROR_CAPTION, MB_OK | MB_ICONERROR) ;
  2728. goto ErrorReturn ;
  2729. }
  2730. }
  2731. */
  2732. // Get KP_PERMISSIONS
  2733. if (!L_GetKeyParam(hKey, KP_PERMISSIONS))
  2734. {
  2735. sprintf(szErrorMsg, "Thread %d: L_GetKeyParam KP_PERMISSION error 0x%x",
  2736. dwThreadNum, GetLastError()) ;
  2737. MessageBox(NULL, szErrorMsg, ERROR_CAPTION, MB_OK | MB_ICONERROR) ;
  2738. goto ErrorReturn ;
  2739. }
  2740. // Effective KeyLen can be queried only for RC2 key
  2741. if (CALG_RC2 == AlgId)
  2742. {
  2743. // Get KP_EFFECTIVE_KEYLEN
  2744. if (!L_GetKeyParam(hKey, KP_EFFECTIVE_KEYLEN))
  2745. {
  2746. sprintf(szErrorMsg, "Thread %d: L_GetKeyParam KP_EFFECTIVE_KEYLEN error 0x%x",
  2747. dwThreadNum, GetLastError()) ;
  2748. MessageBox(NULL, szErrorMsg, ERROR_CAPTION, MB_OK | MB_ICONERROR) ;
  2749. goto ErrorReturn ;
  2750. }
  2751. }
  2752. // These Key Params are good only for Block Cipher Keys
  2753. if (ALG_TYPE_BLOCK == GET_ALG_TYPE(AlgId)
  2754. && ALG_CLASS_DATA_ENCRYPT == GET_ALG_CLASS(AlgId))
  2755. {
  2756. // Get KP_IV
  2757. if (!L_GetKeyParam(hKey, KP_IV))
  2758. {
  2759. sprintf(szErrorMsg, "Thread %d: L_GetKeyParam KP_IV error 0x%x",
  2760. dwThreadNum, GetLastError()) ;
  2761. MessageBox(NULL, szErrorMsg, ERROR_CAPTION, MB_OK | MB_ICONERROR) ;
  2762. goto ErrorReturn ;
  2763. }
  2764. // Get KP_PADDING
  2765. if (!L_GetKeyParam(hKey, KP_PADDING))
  2766. {
  2767. sprintf(szErrorMsg, "Thread %d: L_GetKeyParam KP_PADDING error 0x%x",
  2768. dwThreadNum, GetLastError()) ;
  2769. MessageBox(NULL, szErrorMsg, ERROR_CAPTION, MB_OK | MB_ICONERROR) ;
  2770. goto ErrorReturn ;
  2771. }
  2772. // Get KP_MODE
  2773. if (!L_GetKeyParam(hKey, KP_MODE))
  2774. {
  2775. sprintf(szErrorMsg, "Thread %d: L_GetKeyParam KP_MODE error 0x%x",
  2776. dwThreadNum, GetLastError()) ;
  2777. MessageBox(NULL, szErrorMsg, ERROR_CAPTION, MB_OK | MB_ICONERROR) ;
  2778. goto ErrorReturn ;
  2779. }
  2780. // Get KP_MODE_BITS
  2781. if (!L_GetKeyParam(hKey, KP_MODE_BITS))
  2782. {
  2783. sprintf(szErrorMsg, "Thread %d: L_GetKeyParam KP_MODE_BITS error 0x%x",
  2784. dwThreadNum, GetLastError()) ;
  2785. MessageBox(NULL, szErrorMsg, ERROR_CAPTION, MB_OK | MB_ICONERROR) ;
  2786. goto ErrorReturn ;
  2787. }
  2788. }
  2789. dwRetVal=1 ;
  2790. ErrorReturn :
  2791. return dwRetVal ;
  2792. }
  2793. /*
  2794. L_ProvParam2Text
  2795. dangriff -- Modifying this function so that caller must free the psz
  2796. return value.
  2797. */
  2798. char *L_ProvParam2Text(DWORD dwParam)
  2799. {
  2800. LPSTR pszProvParamText = NULL;
  2801. if (NULL == (pszProvParamText = (LPSTR) MyAlloc(PROV_PARAM_BUFFER_SIZE)))
  2802. {
  2803. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  2804. return NULL;
  2805. }
  2806. switch(dwParam)
  2807. {
  2808. case PP_ENUMALGS :
  2809. strcpy(pszProvParamText, "PP_ENUMALGS") ;
  2810. break ;
  2811. case PP_ENUMCONTAINERS :
  2812. strcpy(pszProvParamText, "PP_ENUMCONTAINERS") ;
  2813. break ;
  2814. case PP_IMPTYPE :
  2815. strcpy(pszProvParamText, "PP_IMPTYPE") ;
  2816. break ;
  2817. case PP_NAME :
  2818. strcpy(pszProvParamText, "PP_NAME") ;
  2819. break ;
  2820. case PP_VERSION :
  2821. strcpy(pszProvParamText, "PP_VERSION") ;
  2822. break ;
  2823. case PP_CONTAINER :
  2824. strcpy(pszProvParamText, "PP_CONTAINER") ;
  2825. break ;
  2826. case PP_CHANGE_PASSWORD :
  2827. strcpy(pszProvParamText, "PP_CHANGE_PASSWORD") ;
  2828. break ;
  2829. case PP_KEYSET_SEC_DESCR :
  2830. strcpy(pszProvParamText, "PP_KEYSET_SEC_DESCR") ;
  2831. break ;
  2832. case PP_CERTCHAIN :
  2833. strcpy(pszProvParamText, "PP_CERTCHAIN") ;
  2834. break ;
  2835. case PP_KEY_TYPE_SUBTYPE :
  2836. strcpy(pszProvParamText, "PP_KEY_TYPE_SUBTYPE") ;
  2837. break ;
  2838. case PP_PROVTYPE :
  2839. strcpy(pszProvParamText, "PP_PROVTYPE") ;
  2840. break ;
  2841. case PP_KEYSTORAGE :
  2842. strcpy(pszProvParamText, "PP_KEYSTORAGE") ;
  2843. break ;
  2844. case PP_APPLI_CERT :
  2845. strcpy(pszProvParamText, "PP_APPLI_CERT") ;
  2846. break ;
  2847. case PP_SYM_KEYSIZE :
  2848. strcpy(pszProvParamText, "PP_SYM_KEYSIZE") ;
  2849. break ;
  2850. case PP_SESSION_KEYSIZE :
  2851. strcpy(pszProvParamText, "PP_SESSION_KEYSIZE") ;
  2852. break ;
  2853. case PP_UI_PROMPT :
  2854. strcpy(pszProvParamText, "PP_UI_PROMPT") ;
  2855. break ;
  2856. case PP_ENUMALGS_EX :
  2857. strcpy(pszProvParamText, "PP_ENUMALGS_EX") ;
  2858. break ;
  2859. case PP_ENUMMANDROOTS :
  2860. strcpy(pszProvParamText, "PP_ENUMMANDROOTS") ;
  2861. break ;
  2862. case PP_ENUMELECTROOTS :
  2863. strcpy(pszProvParamText, "PP_ENUMELECTROOTS") ;
  2864. break ;
  2865. case PP_KEYSET_TYPE :
  2866. strcpy(pszProvParamText, "PP_KEYSET_TYPE") ;
  2867. break ;
  2868. case PP_ADMIN_PIN :
  2869. strcpy(pszProvParamText, "PP_ADMIN_PIN") ;
  2870. break ;
  2871. case PP_KEYEXCHANGE_PIN :
  2872. strcpy(pszProvParamText, "PP_KEYEXCHANGE_PIN") ;
  2873. break ;
  2874. case PP_SIGNATURE_PIN :
  2875. strcpy(pszProvParamText, "PP_SIGNATURE_PIN") ;
  2876. break ;
  2877. case PP_SIG_KEYSIZE_INC :
  2878. strcpy(pszProvParamText, "PP_SIG_KEYSIZE_INC") ;
  2879. break ;
  2880. case PP_KEYX_KEYSIZE_INC :
  2881. strcpy(pszProvParamText, "PP_KEYX_KEYSIZE_INC") ;
  2882. break ;
  2883. case PP_UNIQUE_CONTAINER :
  2884. strcpy(pszProvParamText, "PP_UNIQUE_CONTAINER") ;
  2885. break ;
  2886. case PP_SGC_INFO :
  2887. strcpy(pszProvParamText, "PP_SGC_INFO") ;
  2888. break ;
  2889. case PP_USE_HARDWARE_RNG :
  2890. strcpy(pszProvParamText, "PP_USE_HARDWARE_RNG") ;
  2891. break ;
  2892. case PP_KEYSPEC :
  2893. strcpy(pszProvParamText, "PP_KEYSPEC") ;
  2894. break ;
  2895. case PP_ENUMEX_SIGNING_PROT :
  2896. strcpy(pszProvParamText, "PP_ENUMEX_SIGNING_PROT") ;
  2897. break ;
  2898. }
  2899. return pszProvParamText ;
  2900. }
  2901. //+ ==================================================================
  2902. //
  2903. // Function : L_GetProvParam
  2904. // Purpose : Gets the requested Prov Param
  2905. // Does nothing with the ProvParam
  2906. // Has special logic for all enumeration params
  2907. //
  2908. //- ==================================================================
  2909. DWORD L_GetProvParam(HCRYPTPROV hProv, DWORD dwParam, DWORD dwThreadNum)
  2910. {
  2911. PBYTE pbProvData=NULL ;
  2912. DWORD cbProvData=0 ;
  2913. DWORD dwFlags=0 ;
  2914. DWORD dwEnumFlag=0 ;
  2915. char szErrorMsg[256] ;
  2916. DWORD dwRetVal=0 ;
  2917. LPSTR pszProvParamText = NULL;
  2918. DWORD dwError = 0;
  2919. if ((PP_ENUMALGS == dwParam) ||
  2920. (PP_ENUMALGS_EX == dwParam) ||
  2921. (PP_ENUMCONTAINERS == dwParam))
  2922. {
  2923. dwEnumFlag = 1 ;
  2924. dwFlags = CRYPT_FIRST ;
  2925. }
  2926. // dwFlags needs to be set in the case of PP_KEYSET_SECR_DECR
  2927. if (PP_KEYSET_SEC_DESCR == dwParam)
  2928. {
  2929. dwFlags = SACL_SECURITY_INFORMATION ;
  2930. }
  2931. if (!CryptGetProvParam( hProv,
  2932. dwParam,
  2933. NULL,
  2934. &cbProvData,
  2935. dwFlags))
  2936. {
  2937. if ((ERROR_PRIVILEGE_NOT_HELD == (dwError = GetLastError())) &&
  2938. (PP_KEYSET_SEC_DESCR == dwParam))
  2939. {
  2940. // At this point the test has done it's job. The call is an expected failure call
  2941. // so we aren't going to try and make any more.
  2942. // This call with fail with that expected LastError.
  2943. dwRetVal=1 ;
  2944. goto ErrorReturn ;
  2945. }
  2946. else
  2947. {
  2948. pszProvParamText = L_ProvParam2Text(dwParam);
  2949. sprintf(szErrorMsg, "Thread %d: CryptGetProvParam 1 %s error 0x%x",
  2950. dwThreadNum, pszProvParamText, dwError) ;
  2951. MessageBox(NULL, szErrorMsg, ERROR_CAPTION, MB_OK | MB_ICONERROR) ;
  2952. MyFree(pszProvParamText);
  2953. goto ErrorReturn ;
  2954. }
  2955. }
  2956. if (NULL == (pbProvData = (PBYTE) MyAlloc(cbProvData)))
  2957. {
  2958. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  2959. return 0;
  2960. }
  2961. // If this is an enumeration, keep calling the function until
  2962. // the enumeration reaches the end.
  2963. do
  2964. {
  2965. if (!CryptGetProvParam( hProv,
  2966. dwParam,
  2967. pbProvData,
  2968. &cbProvData,
  2969. dwFlags))
  2970. {
  2971. // Have we reached the end of the enumeration ? If yes, flag it.
  2972. if (ERROR_NO_MORE_ITEMS == (dwError = GetLastError()))
  2973. {
  2974. dwEnumFlag=0 ;
  2975. }
  2976. else
  2977. {
  2978. pszProvParamText = L_ProvParam2Text(dwParam);
  2979. sprintf(szErrorMsg, "Thread %d: CryptGetProvParam 2 %s error 0x%x",
  2980. dwThreadNum, pszProvParamText, dwError) ;
  2981. MessageBox(NULL, szErrorMsg, ERROR_CAPTION, MB_OK | MB_ICONERROR) ;
  2982. MyFree(pszProvParamText);
  2983. goto ErrorReturn ;
  2984. }
  2985. }
  2986. dwFlags=0 ;
  2987. } while (dwEnumFlag) ;
  2988. dwRetVal=1 ;
  2989. ErrorReturn :
  2990. MyFree(pbProvData) ;
  2991. return dwRetVal ;
  2992. }
  2993. //+ =================================================================================
  2994. //- =================================================================================
  2995. /*
  2996. DWORD L_GetAllProvParams(HCRYPTPROV hProv, DWORD dwThreadNum)
  2997. {
  2998. DWORD dwRetVal=0 ;
  2999. EnterCriticalSection(&g_CSEnumParam);
  3000. if (!L_GetProvParam(hProv, PP_ENUMALGS, dwThreadNum))
  3001. {
  3002. LeaveCriticalSection(&g_CSEnumParam);
  3003. goto ErrorReturn;
  3004. }
  3005. LeaveCriticalSection(&g_CSEnumParam);
  3006. if (!L_CheckHeap(dwThreadNum, "after L_GetProvParam PP_ENUMALGS"))
  3007. goto ErrorReturn ;
  3008. EnterCriticalSection(&g_CSEnumParam);
  3009. if (!L_GetProvParam(hProv, PP_ENUMALGS, dwThreadNum))
  3010. {
  3011. LeaveCriticalSection(&g_CSEnumParam);
  3012. goto ErrorReturn ;
  3013. }
  3014. LeaveCriticalSection(&g_CSEnumParam);
  3015. if (!L_CheckHeap(dwThreadNum, "after L_GetProvParam PP_ENUMALGS"))
  3016. goto ErrorReturn ;
  3017. EnterCriticalSection(&g_CSEnumParam);
  3018. if (!L_GetProvParam(hProv, PP_ENUMCONTAINERS, dwThreadNum))
  3019. {
  3020. LeaveCriticalSection(&g_CSEnumParam);
  3021. goto ErrorReturn ;
  3022. }
  3023. LeaveCriticalSection(&g_CSEnumParam);
  3024. if (!L_GetProvParam(hProv, PP_NAME, dwThreadNum))
  3025. goto ErrorReturn ;
  3026. if (!L_CheckHeap(dwThreadNum, "after L_GetProvParam PP_NAME"))
  3027. goto ErrorReturn ;
  3028. if (!L_GetProvParam(hProv, PP_CONTAINER, dwThreadNum))
  3029. goto ErrorReturn ;
  3030. if (!L_CheckHeap(dwThreadNum, "after L_GetProvParam PP_CONTAINER"))
  3031. goto ErrorReturn ;
  3032. if (!L_GetProvParam(hProv, PP_IMPTYPE, dwThreadNum))
  3033. goto ErrorReturn ;
  3034. if (!L_CheckHeap(dwThreadNum, "after L_GetProvParam PP_IMPTYPE"))
  3035. goto ErrorReturn ;
  3036. if (!L_GetProvParam(hProv, PP_VERSION, dwThreadNum))
  3037. goto ErrorReturn ;
  3038. if (!L_CheckHeap(dwThreadNum, "after L_GetProvParam PP_VERSION"))
  3039. goto ErrorReturn ;
  3040. if (!L_GetProvParam(hProv, PP_KEYSET_SEC_DESCR, dwThreadNum))
  3041. goto ErrorReturn ;
  3042. if (!L_CheckHeap(dwThreadNum, "after L_GetProvParam PP_KEYSET_SEC_DESCR"))
  3043. goto ErrorReturn ;
  3044. if (!L_GetProvParam(hProv, PP_UNIQUE_CONTAINER, dwThreadNum))
  3045. goto ErrorReturn ;
  3046. if (!L_CheckHeap(dwThreadNum, "after L_GetProvParam PP_UNIQUE_CONTAINER"))
  3047. goto ErrorReturn ;
  3048. if (!L_GetProvParam(hProv, PP_PROVTYPE, dwThreadNum))
  3049. goto ErrorReturn ;
  3050. if (!L_CheckHeap(dwThreadNum, "after L_GetProvParam PP_PROVTYPE"))
  3051. goto ErrorReturn ;
  3052. if (!L_GetProvParam(hProv, PP_SIG_KEYSIZE_INC, dwThreadNum))
  3053. goto ErrorReturn ;
  3054. if (!L_CheckHeap(dwThreadNum, "after L_GetProvParam PP_SIG_KEYSIZE_INC"))
  3055. goto ErrorReturn ;
  3056. if (!L_GetProvParam(hProv, PP_KEYX_KEYSIZE_INC, dwThreadNum))
  3057. goto ErrorReturn ;
  3058. dwRetVal=1 ;
  3059. ErrorReturn :
  3060. return dwRetVal ;
  3061. }
  3062. */
  3063. //+ ======================================================================
  3064. //- ======================================================================
  3065. DWORD L_ImportAndCheckSessionKeys( HCRYPTPROV hProv,
  3066. HCRYPTKEY hKeyExch,
  3067. PBYTE pbRCx_KeyBlob,
  3068. DWORD cbRCx_KeyBlob,
  3069. PBYTE pbRCx_CipherText,
  3070. DWORD cbRCx_CipherText,
  3071. PBYTE pbPlainText,
  3072. DWORD cbPlainText,
  3073. DWORD dwThreadNum)
  3074. {
  3075. DWORD dwRetVal=0 ;
  3076. HCRYPTKEY hRCxKey=0 ;
  3077. if (!CryptImportKey(hProv,
  3078. pbRCx_KeyBlob,
  3079. cbRCx_KeyBlob,
  3080. hKeyExch,
  3081. 0,
  3082. &hRCxKey))
  3083. L_LastErrorBox("Failed to import session Key", dwThreadNum) ;
  3084. if (!CryptDecrypt(hRCxKey,
  3085. 0,
  3086. TRUE,
  3087. 0,
  3088. pbRCx_CipherText,
  3089. &cbRCx_CipherText))
  3090. L_LastErrorBox("Failed CryptDecrypt", dwThreadNum) ;
  3091. if (memcmp(pbRCx_CipherText, pbPlainText, cbPlainText))
  3092. L_ErrorBox("Ciphertext does not match plaintext after decrypting", dwThreadNum) ;
  3093. //ErrorReturn :
  3094. if (!CryptDestroyKey(hRCxKey))
  3095. L_LastErrorBox("Failed CryptDestroyKey sessionKey", dwThreadNum) ;
  3096. dwRetVal=1 ;
  3097. return dwRetVal ;
  3098. }
  3099. //+ ======================================================================
  3100. //- ======================================================================
  3101. DWORD L_TestContextAddRef(HCRYPTPROV hProv, DWORD dwThreadNum)
  3102. {
  3103. DWORD dwRetVal=0 ;
  3104. DWORD i=0 ;
  3105. DWORD dwCount=50 ;
  3106. for (i=0; i<dwCount ; i++)
  3107. {
  3108. if (!CryptContextAddRef(hProv, NULL, 0))
  3109. {
  3110. L_LastErrorBox("Failed CryptContextAddRef", dwThreadNum) ;
  3111. goto ErrorReturn ;
  3112. }
  3113. }
  3114. for (i=0; i<dwCount ; i++)
  3115. {
  3116. if (!CryptReleaseContext(hProv, 0))
  3117. {
  3118. L_LastErrorBox("Failed CryptReleaseContext (AddRef Test)", dwThreadNum) ;
  3119. goto ErrorReturn ;
  3120. }
  3121. }
  3122. dwRetVal=1 ;
  3123. ErrorReturn :
  3124. return dwRetVal ;
  3125. }
  3126. //+ ===========================================================================
  3127. // L_ExportKey
  3128. //
  3129. // Exports a session key, given the exchange key
  3130. // Mem Allocated here needs to be freed by the calling funtion.
  3131. //- ===========================================================================
  3132. DWORD L_ExportKey( HCRYPTKEY hRC_Key,
  3133. HCRYPTKEY hKeyExch,
  3134. DWORD dwType,
  3135. DWORD dwMustBeZero,
  3136. PBYTE *ppbRC_KeyBlob,
  3137. DWORD *pcbRC_KeyBlob)
  3138. {
  3139. DWORD dwRetVal=0 ;
  3140. char szErrorMsg[256] ;
  3141. if (!CryptExportKey(hRC_Key,
  3142. hKeyExch,
  3143. dwType,
  3144. 0,
  3145. NULL,
  3146. pcbRC_KeyBlob))
  3147. GENERIC_FAIL(CryptExportKey_RC) ;
  3148. if (NULL == (*ppbRC_KeyBlob = (PBYTE) MyAlloc(*pcbRC_KeyBlob)))
  3149. return 0;
  3150. memset(*ppbRC_KeyBlob, 33, *pcbRC_KeyBlob) ;
  3151. if (!CryptExportKey(hRC_Key,
  3152. hKeyExch,
  3153. SIMPLEBLOB,
  3154. 0,
  3155. *ppbRC_KeyBlob,
  3156. pcbRC_KeyBlob))
  3157. GENERIC_FAIL(CryptExportKey_RC) ;
  3158. dwRetVal=1 ;
  3159. ErrorReturn :
  3160. return dwRetVal ;
  3161. }
  3162. //+ ==========================================================================
  3163. //
  3164. //
  3165. //- ==========================================================================
  3166. DWORD L_GetHashParam(HCRYPTHASH hHash, DWORD dwParam)
  3167. {
  3168. DWORD dwRetVal=0 ;
  3169. char szErrorMsg[256] ;
  3170. PBYTE pbData=NULL ;
  3171. DWORD cbData=0 ;
  3172. if (!CryptGetHashParam( hHash,
  3173. dwParam,
  3174. NULL,
  3175. &cbData,
  3176. 0))
  3177. GENERIC_FAIL(CryptGetHashParam) ;
  3178. if (NULL == (pbData = (PBYTE) MyAlloc(cbData)))
  3179. return 0;
  3180. if (!CryptGetHashParam( hHash,
  3181. dwParam,
  3182. pbData,
  3183. &cbData,
  3184. 0))
  3185. GENERIC_FAIL(CryptGetHashParam) ;
  3186. dwRetVal=1 ;
  3187. ErrorReturn :
  3188. MyFree(pbData) ;
  3189. return dwRetVal ;
  3190. }
  3191. //+ ==========================================================================
  3192. //
  3193. //
  3194. //- ==========================================================================
  3195. DWORD L_GetAllHashParams(HCRYPTHASH hHash, DWORD dwThreadNum)
  3196. {
  3197. DWORD dwRetVal=0 ;
  3198. char szErrorMsg[256] ;
  3199. if (!L_GetHashParam(hHash, HP_ALGID))
  3200. goto ErrorReturn ;
  3201. if (!L_GetHashParam(hHash, HP_HASHSIZE))
  3202. goto ErrorReturn ;
  3203. if (!L_GetHashParam(hHash, HP_HASHVAL))
  3204. goto ErrorReturn ;
  3205. dwRetVal=1 ;
  3206. ErrorReturn :
  3207. return dwRetVal ;
  3208. }
  3209. //
  3210. // Function: ThreadAcquireContextTest
  3211. //
  3212. DWORD ThreadAcquireContextTest(PTHREAD_DATA pThreadData, DWORD dwThreadNum)
  3213. {
  3214. HCRYPTPROV hProv = 0;
  3215. HCRYPTKEY hKey = 0;
  3216. DWORD dwError = 0;
  3217. CHAR rgsz[100];
  3218. ZeroMemory(rgsz, sizeof(rgsz));
  3219. sprintf(rgsz, "%s_%d", "ThreadContainer", dwThreadNum);
  3220. if (! CryptAcquireContext(
  3221. &hProv, rgsz, pThreadData->rgszProvName,
  3222. pThreadData->dwProvType, 0))
  3223. {
  3224. dwError = GetLastError();
  3225. printf("CryptAcquireContext: %s, %d, 0x%x\n", rgsz, dwThreadNum, dwError);
  3226. if (NTE_BAD_KEYSET == dwError)
  3227. {
  3228. if (! CryptAcquireContext(
  3229. &hProv, rgsz, pThreadData->rgszProvName,
  3230. pThreadData->dwProvType, CRYPT_NEWKEYSET))
  3231. {
  3232. dwError = GetLastError();
  3233. printf("CryptAcquireContext CRYPT_NEWKEYSET: %s, %d, 0x%x\n", rgsz, dwThreadNum, dwError);
  3234. goto Ret;
  3235. }
  3236. }
  3237. else
  3238. goto Ret;
  3239. }
  3240. if (! CryptGetUserKey(hProv, AT_SIGNATURE, &hKey))
  3241. {
  3242. if (NTE_NO_KEY == (dwError = GetLastError()))
  3243. {
  3244. if (! CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey))
  3245. {
  3246. dwError = GetLastError();
  3247. goto Ret;
  3248. }
  3249. }
  3250. else
  3251. goto Ret;
  3252. }
  3253. if (! CryptDestroyKey(hKey))
  3254. {
  3255. dwError = GetLastError();
  3256. goto Ret;
  3257. }
  3258. if (! CryptReleaseContext(hProv, 0))
  3259. {
  3260. dwError = GetLastError();
  3261. goto Ret;
  3262. }
  3263. dwError = 0;
  3264. Ret:
  3265. return dwError;
  3266. }
  3267. //
  3268. // Function: ThreadHashingTest
  3269. //
  3270. DWORD ThreadHashingTest(PTHREAD_DATA pThreadData, PBYTE pbData, DWORD cbData)
  3271. {
  3272. HCRYPTHASH hHash = 0;
  3273. HCRYPTKEY hKey = 0;
  3274. BYTE rgHash[100];
  3275. DWORD cb = 0;
  3276. DWORD dwError = 0;
  3277. PALGNODE pHashAlg;
  3278. for ( pHashAlg = pThreadData->pAlgList;
  3279. NULL != pHashAlg;
  3280. pHashAlg = pHashAlg->pNext)
  3281. {
  3282. if (CALG_SHA1 != pHashAlg->EnumalgsEx.aiAlgid &&
  3283. CALG_MD5 != pHashAlg->EnumalgsEx.aiAlgid)
  3284. continue;
  3285. if (! CryptCreateHash(pThreadData->hProv, pHashAlg->EnumalgsEx.aiAlgid, 0, 0, &hHash))
  3286. {
  3287. dwError = GetLastError();
  3288. goto Ret;
  3289. }
  3290. if (! CryptHashData(hHash, pbData, cbData, 0))
  3291. {
  3292. dwError = GetLastError();
  3293. goto Ret;
  3294. }
  3295. if (! CryptHashData(hHash, pbData, cbData, 0))
  3296. {
  3297. dwError = GetLastError();
  3298. goto Ret;
  3299. }
  3300. cb = sizeof(rgHash);
  3301. if (! CryptGetHashParam(hHash, HP_HASHVAL, rgHash, &cb, 0))
  3302. {
  3303. dwError = GetLastError();
  3304. goto Ret;
  3305. }
  3306. if (! CryptDestroyHash(hHash))
  3307. {
  3308. dwError = GetLastError();
  3309. goto Ret;
  3310. }
  3311. hHash = 0;
  3312. }
  3313. //dwError = HmacRegression(pThreadData);
  3314. Ret:
  3315. return dwError;
  3316. }
  3317. //
  3318. // Function: ThreadSignatureTest
  3319. //
  3320. DWORD ThreadSignatureTest(PTHREAD_DATA pThreadData)
  3321. {
  3322. HCRYPTHASH hHash = 0;
  3323. PBYTE pbData = NULL;
  3324. DWORD cbData = 0;
  3325. PBYTE pbSignature = NULL;
  3326. DWORD cbSignature = 0;
  3327. DWORD dwError = 0;
  3328. PALGNODE pHashAlg = NULL;
  3329. if (! CryptCreateHash(
  3330. pThreadData->hProv, CALG_SHA1, 0, 0, &hHash))
  3331. {
  3332. dwError = GetLastError();
  3333. goto Ret;
  3334. }
  3335. cbData = SIGN_DATA_SIZE;
  3336. if (NULL == (pbData = (PBYTE) MyAlloc(cbData)))
  3337. {
  3338. dwError = ERROR_NOT_ENOUGH_MEMORY;
  3339. goto Ret;
  3340. }
  3341. if (! CryptGenRandom(
  3342. pThreadData->hProv, cbData, pbData))
  3343. {
  3344. dwError = GetLastError();
  3345. goto Ret;
  3346. }
  3347. if (! CryptHashData(
  3348. hHash, pbData, cbData, 0))
  3349. {
  3350. dwError = GetLastError();
  3351. goto Ret;
  3352. }
  3353. if (! CryptSignHash(
  3354. hHash, AT_SIGNATURE, NULL, 0, NULL, &cbSignature))
  3355. {
  3356. dwError = GetLastError();
  3357. goto Ret;
  3358. }
  3359. if (NULL == (pbSignature = (PBYTE) MyAlloc(cbSignature)))
  3360. {
  3361. dwError = ERROR_NOT_ENOUGH_MEMORY;
  3362. goto Ret;
  3363. }
  3364. if (! CryptSignHash(
  3365. hHash, AT_SIGNATURE, NULL, 0, pbSignature, &cbSignature))
  3366. {
  3367. dwError = GetLastError();
  3368. goto Ret;
  3369. }
  3370. if (! CryptVerifySignature(
  3371. hHash, pbSignature, cbSignature,
  3372. pThreadData->hSignatureKey, NULL, 0))
  3373. {
  3374. dwError = GetLastError();
  3375. goto Ret;
  3376. }
  3377. if (! CryptDestroyHash(hHash))
  3378. {
  3379. dwError = GetLastError();
  3380. goto Ret;
  3381. }
  3382. MyFree(pbData);
  3383. MyFree(pbSignature);
  3384. Ret:
  3385. return dwError;
  3386. }
  3387. // ======================================================================================
  3388. // MULTITHREADED routine
  3389. // ======================================================================================
  3390. void WINAPI ThreadRoutine(LPVOID pvThreadData)
  3391. {
  3392. DWORD dwThreadNum = 0;
  3393. DWORD dwError = 0;
  3394. BOOL fMacErrorOccurred = FALSE;
  3395. PTHREAD_DATA pThreadData = (PTHREAD_DATA) pvThreadData;
  3396. CHAR szErrorMsg[256];
  3397. BYTE rgbData[HASH_DATA_SIZE];
  3398. // Get identifier for this thread
  3399. EnterCriticalSection(&pThreadData->CSThreadData);
  3400. dwThreadNum = pThreadData->dwThreadID;
  3401. pThreadData->dwThreadID++;
  3402. LeaveCriticalSection(&pThreadData->CSThreadData);
  3403. if (! CryptGenRandom(pThreadData->hProv, sizeof(rgbData), rgbData))
  3404. {
  3405. dwError = GetLastError();
  3406. goto ErrorReturn;
  3407. }
  3408. do
  3409. {
  3410. if (RUN_THREAD_SIGNATURE_TEST & pThreadData->dwTestsToRun)
  3411. {
  3412. if (ERROR_SUCCESS != (dwError = ThreadSignatureTest(pThreadData)))
  3413. {
  3414. sprintf(
  3415. szErrorMsg,
  3416. "Thread %d: ThreadSignatureTest error 0x%x",
  3417. dwThreadNum,
  3418. dwError);
  3419. MessageBox(NULL, szErrorMsg, ERROR_CAPTION, MB_OK | MB_ICONERROR);
  3420. goto ErrorReturn;
  3421. }
  3422. }
  3423. if (RUN_STRESS_TEST_ALL_ENCRYPTION_ALGS & pThreadData->dwTestsToRun)
  3424. {
  3425. //
  3426. // Call new shared encryption stress tests
  3427. //
  3428. if (ERROR_SUCCESS != (dwError =
  3429. StressTestAllEncryptionAlgs(pThreadData, TRUE, &fMacErrorOccurred)))
  3430. {
  3431. sprintf(
  3432. szErrorMsg,
  3433. "Thread %d: StressTestAllEncryptionAlgs error 0x%x",
  3434. dwThreadNum,
  3435. dwError);
  3436. MessageBox(NULL, szErrorMsg, ERROR_CAPTION, MB_OK | MB_ICONERROR);
  3437. goto ErrorReturn;
  3438. }
  3439. }
  3440. if (RUN_THREAD_HASHING_TEST & pThreadData->dwTestsToRun)
  3441. {
  3442. if (ERROR_SUCCESS != (dwError = ThreadHashingTest(pThreadData, rgbData, sizeof(rgbData))))
  3443. {
  3444. sprintf(
  3445. szErrorMsg,
  3446. "Thread %d: ThreadHashingTest error 0x%x",
  3447. dwThreadNum,
  3448. dwError);
  3449. MessageBox(NULL, szErrorMsg, ERROR_CAPTION, MB_OK | MB_ICONERROR);
  3450. goto ErrorReturn;
  3451. }
  3452. }
  3453. if (RUN_THREAD_ACQUIRE_CONTEXT_TEST & pThreadData->dwTestsToRun)
  3454. {
  3455. if (ERROR_SUCCESS != (dwError = ThreadAcquireContextTest(pThreadData, dwThreadNum)))
  3456. {
  3457. sprintf(
  3458. szErrorMsg,
  3459. "Thread %d: ThreadAcquireContextTest error 0x%x",
  3460. dwThreadNum,
  3461. dwError);
  3462. MessageBox(NULL, szErrorMsg, ERROR_CAPTION, MB_OK | MB_ICONERROR);
  3463. goto ErrorReturn;
  3464. }
  3465. }
  3466. pThreadData->rgdwThreadStatus[dwThreadNum]++;
  3467. }
  3468. while (WAIT_TIMEOUT == WaitForSingleObject(pThreadData->hEndTestEvent, 0));
  3469. ErrorReturn:
  3470. if (fMacErrorOccurred)
  3471. {
  3472. printf("ERROR: Mac bug 189368 is not fixed!\n");
  3473. }
  3474. return;
  3475. }
  3476. //
  3477. // Function: GetNextRegisteredCSP
  3478. //
  3479. DWORD GetNextRegisteredCSP(
  3480. LPSTR pszCsp,
  3481. PDWORD pcbCsp,
  3482. PDWORD pdwProvType,
  3483. DWORD dwRequestedIndex)
  3484. {
  3485. static DWORD dwNextEnumIndex = 0;
  3486. DWORD dwActualIndex = 0;
  3487. DWORD dwError = 0;
  3488. dwActualIndex =
  3489. (ENUMERATE_REGISTERED_CSP == dwRequestedIndex) ?
  3490. dwNextEnumIndex :
  3491. dwRequestedIndex;
  3492. if (! CryptEnumProviders(
  3493. dwActualIndex,
  3494. NULL,
  3495. 0,
  3496. pdwProvType,
  3497. pszCsp,
  3498. pcbCsp))
  3499. {
  3500. dwError = GetLastError();
  3501. switch (dwError)
  3502. {
  3503. case ERROR_NO_MORE_ITEMS:
  3504. dwNextEnumIndex = 0;
  3505. break;
  3506. }
  3507. }
  3508. else
  3509. {
  3510. if (ENUMERATE_REGISTERED_CSP == dwRequestedIndex)
  3511. {
  3512. dwNextEnumIndex++;
  3513. }
  3514. }
  3515. return dwError;
  3516. }
  3517. //
  3518. // Function: InitializeAlgList
  3519. // Purpose: Create a list of algorithms supported by this CSP
  3520. //
  3521. DWORD InitializeAlgList(PTHREAD_DATA pThreadData)
  3522. {
  3523. PALGNODE pAlgNode = NULL, pPrevNode = NULL;
  3524. DWORD dwError = 0;
  3525. DWORD cbData = sizeof(ALGNODE);
  3526. DWORD dwFlags = CRYPT_FIRST;
  3527. if (NULL == (pThreadData->pAlgList = (PALGNODE) MyAlloc(sizeof(ALGNODE))))
  3528. return ERROR_NOT_ENOUGH_MEMORY;
  3529. pAlgNode = pThreadData->pAlgList;
  3530. while (CryptGetProvParam(
  3531. pThreadData->hProv,
  3532. PP_ENUMALGS_EX,
  3533. (PBYTE) &pAlgNode->EnumalgsEx,
  3534. &cbData,
  3535. dwFlags))
  3536. {
  3537. dwFlags = 0;
  3538. if (NULL == (pAlgNode->pNext = (PALGNODE) MyAlloc(sizeof(ALGNODE))))
  3539. return ERROR_NOT_ENOUGH_MEMORY;
  3540. pPrevNode = pAlgNode;
  3541. pAlgNode = pAlgNode->pNext;
  3542. }
  3543. if (ERROR_NO_MORE_ITEMS != (dwError = GetLastError()))
  3544. return dwError;
  3545. MyFree(pAlgNode);
  3546. pPrevNode->pNext = NULL;
  3547. return ERROR_SUCCESS;
  3548. }
  3549. //
  3550. // Function: RunRegressionTests
  3551. //
  3552. BOOL RunRegressionTests(PTHREAD_DATA pThreadData)
  3553. {
  3554. DWORD dwError = ERROR_SUCCESS;
  3555. unsigned u;
  3556. BOOL fAllPassed = TRUE;
  3557. for (u = 0; u < g_cRegressTests; u++)
  3558. {
  3559. if (pThreadData->dwProvType & g_rgRegressTests[u].dwExclude)
  3560. {
  3561. printf(
  3562. "Skipping %s\n\n", g_rgRegressTests[u].pszDescription);
  3563. continue;
  3564. }
  3565. if (ERROR_SUCCESS !=
  3566. (dwError = (g_rgRegressTests[u].pfTest)(pThreadData)))
  3567. {
  3568. printf(
  3569. "FAIL: %s, 0x%x\n\n",
  3570. g_rgRegressTests[u].pszDescription,
  3571. dwError);
  3572. fAllPassed = FALSE;
  3573. }
  3574. else
  3575. printf("PASS: %s\n\n", g_rgRegressTests[u].pszDescription);
  3576. }
  3577. return fAllPassed;
  3578. }
  3579. //
  3580. // Function: CallCryptAcquireContext
  3581. //
  3582. BOOL CallCryptAcquireContext(
  3583. IN PTHREAD_DATA pThreadData,
  3584. IN LPSTR pszOptions,
  3585. IN LPSTR pszContainer)
  3586. {
  3587. HCRYPTPROV hProv = 0;
  3588. HCRYPTKEY hKey = 0;
  3589. DWORD dwFlags = 0;
  3590. unsigned uLen = strlen(pszOptions);
  3591. ALG_ID ai = 0;
  3592. DWORD dwKeyFlags = 0;
  3593. BOOL fSuccess = TRUE;
  3594. printf(" pszContainer = %s\n", pszContainer);
  3595. printf(" dwFlags =");
  3596. while (uLen)
  3597. {
  3598. switch (pszOptions[uLen - 1])
  3599. {
  3600. case 'l':
  3601. dwFlags |= CRYPT_MACHINE_KEYSET;
  3602. printf(" CRYPT_MACHINE_KEYSET");
  3603. break;
  3604. case 'v':
  3605. dwFlags |= CRYPT_VERIFYCONTEXT;
  3606. printf(" CRYPT_VERIFYCONTEXT");
  3607. break;
  3608. case 'n':
  3609. dwFlags |= CRYPT_NEWKEYSET;
  3610. printf(" CRYPT_NEWKEYSET");
  3611. break;
  3612. case 'd':
  3613. dwFlags |= CRYPT_DELETEKEYSET;
  3614. printf(" CRYPT_DELETEKEYSET");
  3615. break;
  3616. case 'q':
  3617. dwFlags |= CRYPT_SILENT;
  3618. printf(" CRYPT_SILENT");
  3619. break;
  3620. case 'x':
  3621. ai = AT_KEYEXCHANGE;
  3622. break;
  3623. case 's':
  3624. ai = AT_SIGNATURE;
  3625. break;
  3626. case 'u':
  3627. dwKeyFlags = CRYPT_USER_PROTECTED;
  3628. break;
  3629. default:
  3630. printf(" Invalid!\n");
  3631. return FALSE;
  3632. }
  3633. uLen--;
  3634. }
  3635. printf("\n");
  3636. if (CryptAcquireContext(
  3637. &hProv, pszContainer, pThreadData->rgszProvName,
  3638. pThreadData->dwProvType, dwFlags))
  3639. {
  3640. printf("Success\n");
  3641. if (0 != ai)
  3642. {
  3643. printf("\nCalling CryptGenKey ...\n");
  3644. if (AT_KEYEXCHANGE == ai)
  3645. printf(" Algid = AT_KEYEXCHANGE\n");
  3646. else
  3647. printf(" Algid = AT_SIGNATURE\n");
  3648. if (dwKeyFlags & CRYPT_USER_PROTECTED)
  3649. printf(" dwFlags = CRYPT_USER_PROTECTED\n");
  3650. else
  3651. printf(" dwFlags =\n");
  3652. if (CryptGenKey(
  3653. hProv, ai, dwKeyFlags, &hKey))
  3654. {
  3655. printf("Success\n");
  3656. }
  3657. else
  3658. {
  3659. printf("ERROR: CryptGenKey failed - 0x%x\n", GetLastError());
  3660. fSuccess = FALSE;
  3661. }
  3662. }
  3663. }
  3664. else
  3665. {
  3666. printf("ERROR: CryptAcquireContext failed - 0x%x\n", GetLastError());
  3667. fSuccess = FALSE;
  3668. }
  3669. if (hKey)
  3670. {
  3671. if (! CryptDestroyKey(hKey))
  3672. {
  3673. printf("ERROR: CryptDestroyKey failed - 0x%x\n", GetLastError());
  3674. fSuccess = FALSE;
  3675. }
  3676. }
  3677. if (hProv)
  3678. {
  3679. if ((! dwFlags & CRYPT_DELETEKEYSET) &&
  3680. FALSE == CryptReleaseContext(hProv, 0))
  3681. {
  3682. printf("ERROR: CryptReleaseContext failed - 0x%x\n", GetLastError());
  3683. fSuccess = FALSE;
  3684. }
  3685. }
  3686. return fSuccess;
  3687. }
  3688. //
  3689. // Function: DeleteAllContainers
  3690. //
  3691. BOOL DeleteAllContainers(THREAD_DATA *pThreadData)
  3692. {
  3693. HCRYPTPROV hDefProv = 0;
  3694. HCRYPTPROV hProv = 0;
  3695. CHAR rgszContainer[MAX_PATH];
  3696. CHAR rgszDefCont[MAX_PATH];
  3697. DWORD cbContainer = MAX_PATH;
  3698. DWORD dwFlags = CRYPT_FIRST;
  3699. if (! CryptAcquireContext(
  3700. &hDefProv, NULL, pThreadData->rgszProvName,
  3701. pThreadData->dwProvType, 0))
  3702. {
  3703. printf("CryptAcquireContext default keyset failed - 0x%x\n", GetLastError());
  3704. return FALSE;
  3705. }
  3706. if (! CryptGetProvParam(
  3707. hDefProv, PP_CONTAINER, (PBYTE) rgszDefCont,
  3708. &cbContainer, 0))
  3709. {
  3710. printf("CryptGetProvParam PP_CONTAINER failed - 0x%x\n", GetLastError());
  3711. return FALSE;
  3712. }
  3713. cbContainer = MAX_PATH;
  3714. while (CryptGetProvParam(
  3715. hDefProv, PP_ENUMCONTAINERS, (PBYTE) rgszContainer,
  3716. &cbContainer, dwFlags))
  3717. {
  3718. if (dwFlags)
  3719. dwFlags = 0;
  3720. // If the enumerated container is the same as the default
  3721. // container, skip it for now
  3722. if (0 == strcmp(rgszContainer, rgszDefCont))
  3723. continue;
  3724. printf("\"%s\" - ", rgszContainer);
  3725. if (! CryptAcquireContext(
  3726. &hProv, rgszContainer, pThreadData->rgszProvName,
  3727. pThreadData->dwProvType, CRYPT_DELETEKEYSET))
  3728. printf("CryptAcquireContext CRYPT_DELETEKEYSET failed - 0x%x\n", GetLastError());
  3729. else
  3730. printf("Deleted\n");
  3731. cbContainer = MAX_PATH;
  3732. }
  3733. if (! CryptReleaseContext(hDefProv, 0))
  3734. {
  3735. printf("CryptReleaseContext failed - 0x%x\n", GetLastError());
  3736. return FALSE;
  3737. }
  3738. // Now try to delete default keyset
  3739. printf("\"%s\" - ", rgszDefCont);
  3740. if (! CryptAcquireContext(
  3741. &hProv, rgszDefCont, pThreadData->rgszProvName,
  3742. pThreadData->dwProvType, CRYPT_DELETEKEYSET))
  3743. printf("CryptAcquireContext CRYPT_DELETEKEYSET failed - 0x%x\n", GetLastError());
  3744. else
  3745. printf("Deleted\n");
  3746. return TRUE;
  3747. }
  3748. //*****************************************************
  3749. //
  3750. int _cdecl main(int argc, char * argv[])
  3751. {
  3752. HANDLE rghThread[MAX_THREADS];
  3753. DWORD rgdwThreadID[MAX_THREADS];
  3754. DWORD threadID=0;
  3755. DWORD thread_number=0;
  3756. DWORD dwErr=0;
  3757. DWORD dwArg = 0;
  3758. DWORD cbCspName = 0;
  3759. DWORD dwFreeHandle=0;
  3760. DWORD i = 0 ;
  3761. DWORD tick_StartTime=0;
  3762. char szErrorMsg[256] ;
  3763. THREAD_DATA ThreadData;
  3764. BOOL fInvalidArgs = FALSE;
  3765. PALGNODE pAlgNode = NULL;
  3766. BOOL fRunRegressions = FALSE;
  3767. BOOL fAcquireContext = FALSE;
  3768. LPSTR pszOptions = NULL;
  3769. LPSTR pszContainer = NULL;
  3770. BOOL fDeleteContainers = FALSE;
  3771. // Set high-order bit on dwSpinCount param so that the event used
  3772. // by EnterCriticalSection() will be pre-allocated by
  3773. // InitializeCriticalSectionAndSpinCount()
  3774. DWORD dwSpinCount = 0x8000;
  3775. ZeroMemory(&ThreadData, sizeof(ThreadData));
  3776. __try
  3777. {
  3778. InitializeCriticalSectionAndSpinCount(&ThreadData.CSThreadData, dwSpinCount);
  3779. }
  3780. __except (STATUS_NO_MEMORY == GetExceptionCode() ?
  3781. EXCEPTION_EXECUTE_HANDLER :
  3782. EXCEPTION_CONTINUE_SEARCH )
  3783. {
  3784. printf("InitializeCriticalSectionAndSpinCount failed: STATUS_NO_MEMORY exception\n");
  3785. exit(1);
  3786. }
  3787. // Setting all the defaults
  3788. ThreadData.dwThreadCount = StressGetDefaultThreadCount();
  3789. ThreadData.dwTestsToRun = RUN_ALL_TESTS;
  3790. while (--argc>0)
  3791. {
  3792. if (**++argv == '-')
  3793. {
  3794. switch(argv[0][1])
  3795. {
  3796. case 'n':
  3797. argv++;
  3798. argc--;
  3799. if (0 == argc || 0 == (dwArg = atoi(argv[0])))
  3800. {
  3801. fInvalidArgs = TRUE;
  3802. goto Ret;
  3803. }
  3804. ThreadData.dwThreadCount = dwArg;
  3805. break;
  3806. case 't':
  3807. argv++;
  3808. argc--;
  3809. if (0 == argc || 0 == (dwArg = atoi(argv[0])))
  3810. {
  3811. fInvalidArgs = TRUE;
  3812. goto Ret;
  3813. }
  3814. ThreadData.dwProgramMins = dwArg;
  3815. break;
  3816. case 'c':
  3817. argv++;
  3818. argc--;
  3819. if (0 == argc)
  3820. {
  3821. fInvalidArgs = TRUE;
  3822. goto Ret;
  3823. }
  3824. cbCspName = MAX_PATH;
  3825. dwErr = GetNextRegisteredCSP(
  3826. ThreadData.rgszProvName,
  3827. &cbCspName,
  3828. &ThreadData.dwProvType,
  3829. atoi(*argv));
  3830. if (ERROR_SUCCESS != dwErr)
  3831. {
  3832. fInvalidArgs = TRUE;
  3833. goto Ret;
  3834. }
  3835. break;
  3836. case 'e':
  3837. ThreadData.fEphemeralKeys = TRUE;
  3838. break;
  3839. case 'u':
  3840. ThreadData.fUserProtectedKeys = TRUE;
  3841. break;
  3842. case 'r':
  3843. fRunRegressions = TRUE;
  3844. break;
  3845. case '?':
  3846. fInvalidArgs = TRUE;
  3847. goto Ret;
  3848. case 'a':
  3849. fAcquireContext = TRUE;
  3850. pszOptions = argv[0] + 2;
  3851. if (NULL == strchr(pszOptions, 'v'))
  3852. {
  3853. argv++;
  3854. argc--;
  3855. pszContainer = *argv;
  3856. }
  3857. break;
  3858. case 'd':
  3859. fDeleteContainers = TRUE;
  3860. break;
  3861. case 'T':
  3862. argv++;
  3863. argc--;
  3864. if (0 == argc || 0 == (dwArg = atoi(argv[0])))
  3865. {
  3866. fInvalidArgs = TRUE;
  3867. goto Ret;
  3868. }
  3869. ThreadData.dwTestsToRun = dwArg;
  3870. break;
  3871. default:
  3872. fInvalidArgs = TRUE;
  3873. goto Ret;
  3874. }
  3875. }
  3876. }
  3877. //
  3878. // Check arg validity
  3879. //
  3880. if ( 0 != argc ||
  3881. 0 == ThreadData.dwProvType ||
  3882. (ThreadData.fEphemeralKeys && ThreadData.fUserProtectedKeys) ||
  3883. (fRunRegressions && fAcquireContext))
  3884. {
  3885. fInvalidArgs = TRUE;
  3886. goto Ret;
  3887. }
  3888. printf("Provider: %s, Type: %d\n\n", ThreadData.rgszProvName, ThreadData.dwProvType);
  3889. if (fDeleteContainers)
  3890. {
  3891. printf("Deleting all key containers ...\n");
  3892. if (! DeleteAllContainers(&ThreadData))
  3893. exit(1);
  3894. goto Ret;
  3895. }
  3896. if (fAcquireContext)
  3897. {
  3898. printf("Calling CryptAcquireContext ...\n");
  3899. if (! CallCryptAcquireContext(
  3900. &ThreadData, pszOptions, pszContainer))
  3901. exit(1);
  3902. goto Ret;
  3903. }
  3904. if (!ProgramInit(&ThreadData))
  3905. {
  3906. printf("ProgramInit() failed\n");
  3907. exit(1) ;
  3908. }
  3909. //
  3910. // Initialize list of supported algorithms
  3911. //
  3912. if (ERROR_SUCCESS != (dwErr = InitializeAlgList(&ThreadData)))
  3913. {
  3914. printf("InitializeAlgList failed, 0x%x\n", dwErr);
  3915. exit(1);
  3916. }
  3917. if (fRunRegressions)
  3918. {
  3919. printf("Running regression tests ...\n");
  3920. if (! RunRegressionTests(&ThreadData))
  3921. exit(1);
  3922. goto Ret;
  3923. }
  3924. //
  3925. // Summarize user options
  3926. //
  3927. printf("Number of threads: %d\n", ThreadData.dwThreadCount);
  3928. if (ThreadData.dwProgramMins)
  3929. printf(" - Timeout in %d minute(s)\n", ThreadData.dwProgramMins);
  3930. if (ThreadData.fEphemeralKeys)
  3931. printf(" - Using ephemeral keys\n");
  3932. if (ThreadData.fUserProtectedKeys)
  3933. printf(" - Using user-protected keys\n");
  3934. // Create event that can be used by the timer thread to stop
  3935. // the worker threads.
  3936. if ((ThreadData.hEndTestEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL)
  3937. {
  3938. printf("CreateEvent() failed, 0x%x\n", GetLastError());
  3939. exit(1);
  3940. }
  3941. // Create the threads
  3942. tick_StartTime = GetTickCount() ;
  3943. for (thread_number = 0; thread_number < ThreadData.dwThreadCount; thread_number++)
  3944. {
  3945. if ((rghThread[thread_number] =
  3946. CreateThread(
  3947. NULL,
  3948. 0,
  3949. (LPTHREAD_START_ROUTINE) ThreadRoutine,
  3950. &ThreadData,
  3951. 0,
  3952. &threadID)) != NULL)
  3953. {
  3954. rgdwThreadID[thread_number] = threadID ;
  3955. }
  3956. else
  3957. {
  3958. sprintf(szErrorMsg, "\n\nERROR creating thread number 0x%x. Error 0x%x",
  3959. thread_number, GetLastError()) ;
  3960. MessageBox(NULL, szErrorMsg, ERROR_CAPTION, MB_OK | MB_ICONERROR) ;
  3961. exit(0) ;
  3962. }
  3963. }
  3964. // Spawn PrintThreadStatus
  3965. rghThread[thread_number++] = CreateThread(
  3966. NULL, 0,
  3967. (LPTHREAD_START_ROUTINE)PrintThreadStatus,
  3968. &ThreadData,
  3969. 0, &threadID);
  3970. // Spawn KillProgramTimer (This will shut down all the threads and kill the program)
  3971. rghThread[thread_number++] = CreateThread(
  3972. NULL, 0,
  3973. (LPTHREAD_START_ROUTINE)KillProgramTimer,
  3974. &ThreadData,
  3975. 0, &threadID);
  3976. // Done Creating all threads
  3977. // End multithreading
  3978. dwErr = WaitForMultipleObjects(thread_number, rghThread, TRUE, INFINITE) ;
  3979. if (dwErr == WAIT_FAILED)
  3980. printf("WaitForMultipleObjects() failed, 0x%x\n", GetLastError());
  3981. if (! CryptDestroyKey(ThreadData.hSignatureKey))
  3982. {
  3983. sprintf(szErrorMsg, "FAILED CryptDestroyKey SIG error 0x%x\n", GetLastError()) ;
  3984. MessageBox(NULL, szErrorMsg, ERROR_CAPTION, MB_OK | MB_ICONERROR) ;
  3985. }
  3986. if (ThreadData.hExchangeKey && (! CryptDestroyKey(ThreadData.hExchangeKey)))
  3987. {
  3988. sprintf(szErrorMsg, "FAILED CryptDestroyKey KEYX error 0x%x\n", GetLastError()) ;
  3989. MessageBox(NULL, szErrorMsg, ERROR_CAPTION, MB_OK | MB_ICONERROR) ;
  3990. }
  3991. if (! CryptReleaseContext(ThreadData.hVerifyCtx, 0))
  3992. {
  3993. sprintf(szErrorMsg, "FAILED CryptReleaseContext 1 error 0x%x\n", GetLastError());
  3994. MessageBox(NULL, szErrorMsg, ERROR_CAPTION, MB_OK | MB_ICONERROR);
  3995. }
  3996. if (! CryptReleaseContext(ThreadData.hProv, 0))
  3997. {
  3998. sprintf(szErrorMsg, "FAILED CryptReleaseContext 2 error 0x%x\n", GetLastError()) ;
  3999. MessageBox(NULL, szErrorMsg, ERROR_CAPTION, MB_OK | MB_ICONERROR) ;
  4000. }
  4001. DeleteCriticalSection(&ThreadData.CSThreadData);
  4002. CloseHandle(ThreadData.hEndTestEvent);
  4003. while (thread_number--)
  4004. CloseHandle(rghThread[thread_number]);
  4005. Ret:
  4006. while (ThreadData.pAlgList)
  4007. {
  4008. pAlgNode = ThreadData.pAlgList->pNext;
  4009. MyFree(ThreadData.pAlgList);
  4010. ThreadData.pAlgList = pAlgNode;
  4011. }
  4012. if (fInvalidArgs)
  4013. {
  4014. Usage();
  4015. printf("\nRegistered CSP's:\n");
  4016. cbCspName = MAX_PATH;
  4017. for ( i = 0;
  4018. ERROR_SUCCESS == GetNextRegisteredCSP(
  4019. ThreadData.rgszProvName,
  4020. &cbCspName,
  4021. &ThreadData.dwProvType,
  4022. ENUMERATE_REGISTERED_CSP);
  4023. i++, cbCspName = MAX_PATH)
  4024. {
  4025. printf(" %d: %s, Type %d\n", i, ThreadData.rgszProvName, ThreadData.dwProvType);
  4026. }
  4027. exit(1);
  4028. }
  4029. return 0 ;
  4030. }