Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1057 lines
26 KiB

  1. //+-----------------------------------------------------------------------
  2. //
  3. // File: MDWRAP.C
  4. //
  5. // Contents: MDx Wrapper functions
  6. //
  7. //
  8. // History: 25 Feb 92, RichardW Created
  9. //
  10. //------------------------------------------------------------------------
  11. #ifndef KERNEL_MODE
  12. #include <nt.h>
  13. #include <ntrtl.h>
  14. #include <nturtl.h>
  15. #include <windows.h>
  16. #else
  17. #include <ntifs.h>
  18. #endif
  19. #include <string.h>
  20. #include <malloc.h>
  21. #include <kerbcon.h>
  22. #include <security.h>
  23. #include <cryptdll.h>
  24. #include "md4.h"
  25. #include "md5.h"
  26. #include "des.h"
  27. typedef struct _MD5_DES_STATE_BUFFER {
  28. PCHECKSUM_BUFFER DesContext;
  29. MD5_CTX Md5Context;
  30. } MD5_DES_STATE_BUFFER, *PMD5_DES_STATE_BUFFER;
  31. typedef struct _MD5_DES_1510_STATE_BUFFER {
  32. PCHECKSUM_BUFFER DesContext;
  33. MD5_CTX Md5Context;
  34. UCHAR Confounder[DES_BLOCKLEN];
  35. } MD5_DES_1510_STATE_BUFFER, *PMD5_DES_1510_STATE_BUFFER;
  36. typedef struct _MD5_HMAC_STATE_BUFFER {
  37. MD5_CTX Md5Context;
  38. ULONG KeySize;
  39. UCHAR Key[ANYSIZE_ARRAY];
  40. } MD5_HMAC_STATE_BUFFER, *PMD5_HMAC_STATE_BUFFER;
  41. NTSTATUS NTAPI md4Initialize(ULONG, PCHECKSUM_BUFFER *);
  42. NTSTATUS NTAPI md4InitializeEx(PUCHAR,ULONG, ULONG, PCHECKSUM_BUFFER *);
  43. NTSTATUS NTAPI md4Sum(PCHECKSUM_BUFFER, ULONG, PUCHAR);
  44. NTSTATUS NTAPI md4Finalize(PCHECKSUM_BUFFER, PUCHAR);
  45. NTSTATUS NTAPI md4Finish(PCHECKSUM_BUFFER *);
  46. NTSTATUS NTAPI md5Initialize(ULONG, PCHECKSUM_BUFFER *);
  47. NTSTATUS NTAPI md5InitializeEx(PUCHAR, ULONG, ULONG, PCHECKSUM_BUFFER *);
  48. NTSTATUS NTAPI md5Sum(PCHECKSUM_BUFFER, ULONG, PUCHAR);
  49. NTSTATUS NTAPI md5Finalize(PCHECKSUM_BUFFER, PUCHAR);
  50. NTSTATUS NTAPI md5Finish(PCHECKSUM_BUFFER *);
  51. NTSTATUS NTAPI md25Initialize(ULONG, PCHECKSUM_BUFFER *);
  52. NTSTATUS NTAPI md25InitializeEx(PUCHAR, ULONG, ULONG, PCHECKSUM_BUFFER *);
  53. NTSTATUS NTAPI md25Sum(PCHECKSUM_BUFFER, ULONG, PUCHAR);
  54. NTSTATUS NTAPI md25Finalize(PCHECKSUM_BUFFER, PUCHAR);
  55. NTSTATUS NTAPI md25Finish(PCHECKSUM_BUFFER *);
  56. NTSTATUS NTAPI md5DesInitialize(ULONG, PCHECKSUM_BUFFER *);
  57. NTSTATUS NTAPI md5DesInitializeEx(PUCHAR, ULONG, ULONG, PCHECKSUM_BUFFER *);
  58. NTSTATUS NTAPI md5DesSum(PCHECKSUM_BUFFER, ULONG, PUCHAR);
  59. NTSTATUS NTAPI md5DesFinalize(PCHECKSUM_BUFFER, PUCHAR);
  60. NTSTATUS NTAPI md5DesFinish(PCHECKSUM_BUFFER *);
  61. NTSTATUS NTAPI md5Rc4Initialize(ULONG, PCHECKSUM_BUFFER *);
  62. NTSTATUS NTAPI md5Rc4InitializeEx(PUCHAR, ULONG, ULONG, PCHECKSUM_BUFFER *);
  63. NTSTATUS NTAPI md5Rc4Sum(PCHECKSUM_BUFFER, ULONG, PUCHAR);
  64. NTSTATUS NTAPI md5Rc4Finalize(PCHECKSUM_BUFFER, PUCHAR);
  65. NTSTATUS NTAPI md5Rc4Finish(PCHECKSUM_BUFFER *);
  66. NTSTATUS NTAPI md5HmacInitialize(ULONG, PCHECKSUM_BUFFER *);
  67. NTSTATUS NTAPI md5HmacInitializeEx(PUCHAR, ULONG, ULONG, PCHECKSUM_BUFFER *);
  68. NTSTATUS NTAPI md5Hmac2InitializeEx(PUCHAR, ULONG, ULONG, PCHECKSUM_BUFFER *);
  69. NTSTATUS NTAPI md5HmacSum(PCHECKSUM_BUFFER, ULONG, PUCHAR);
  70. NTSTATUS NTAPI md5HmacFinalize(PCHECKSUM_BUFFER, PUCHAR);
  71. NTSTATUS NTAPI md5HmacFinish(PCHECKSUM_BUFFER *);
  72. NTSTATUS NTAPI md5Des1510InitializeEx(PUCHAR, ULONG, ULONG, PCHECKSUM_BUFFER *);
  73. NTSTATUS NTAPI md5Des1510InitializeEx2(PUCHAR, ULONG, PUCHAR, ULONG, PCHECKSUM_BUFFER *);
  74. NTSTATUS NTAPI md5Des1510Finalize(PCHECKSUM_BUFFER, PUCHAR);
  75. NTSTATUS NTAPI md5Des1510Finish(PCHECKSUM_BUFFER *);
  76. #ifdef KERNEL_MODE
  77. #pragma alloc_text( PAGEMSG, md25Initialize )
  78. #pragma alloc_text( PAGEMSG, md25InitializeEx )
  79. #pragma alloc_text( PAGEMSG, md25Sum )
  80. #pragma alloc_text( PAGEMSG, md25Finalize )
  81. #pragma alloc_text( PAGEMSG, md25Finish )
  82. #pragma alloc_text( PAGEMSG, md5DesInitialize )
  83. #pragma alloc_text( PAGEMSG, md5DesInitializeEx )
  84. #pragma alloc_text( PAGEMSG, md5DesSum )
  85. #pragma alloc_text( PAGEMSG, md5DesFinalize )
  86. #pragma alloc_text( PAGEMSG, md5DesFinish )
  87. #pragma alloc_text( PAGEMSG, md5Rc4Initialize )
  88. #pragma alloc_text( PAGEMSG, md5Rc4InitializeEx )
  89. #pragma alloc_text( PAGEMSG, md5Rc4Sum )
  90. #pragma alloc_text( PAGEMSG, md5Rc4Finalize )
  91. #pragma alloc_text( PAGEMSG, md5Rc4Finish )
  92. #pragma alloc_text( PAGEMSG, md5HmacInitialize )
  93. #pragma alloc_text( PAGEMSG, md5HmacInitializeEx )
  94. #pragma alloc_text( PAGEMSG, md5Hmac2InitializeEx )
  95. #pragma alloc_text( PAGEMSG, md5HmacSum )
  96. #pragma alloc_text( PAGEMSG, md5HmacFinalize )
  97. #pragma alloc_text( PAGEMSG, md5HmacFinish )
  98. #pragma alloc_text( PAGEMSG, md5Des1510InitializeEx )
  99. #pragma alloc_text( PAGEMSG, md5Des1510InitializeEx2 )
  100. #pragma alloc_text( PAGEMSG, md5Des1510Finalize )
  101. #pragma alloc_text( PAGEMSG, md5Des1510Finish )
  102. #endif
  103. CHECKSUM_FUNCTION csfMD4 = {
  104. KERB_CHECKSUM_MD4, // Checksum type
  105. MD4_LEN, // Checksum length
  106. 0,
  107. md4Initialize,
  108. md4Sum,
  109. md4Finalize,
  110. md4Finish,
  111. md4InitializeEx,
  112. NULL};
  113. CHECKSUM_FUNCTION csfMD5 = {
  114. KERB_CHECKSUM_MD5, // Checksum type
  115. MD5_LEN, // Checksum length
  116. 0,
  117. md5Initialize,
  118. md5Sum,
  119. md5Finalize,
  120. md5Finish,
  121. md5InitializeEx,
  122. NULL};
  123. CHECKSUM_FUNCTION csfMD25 = {
  124. KERB_CHECKSUM_MD25, // Checksum type
  125. (MD5_LEN / 2), // Checksum length
  126. CKSUM_KEYED,
  127. md25Initialize,
  128. md25Sum,
  129. md25Finalize,
  130. md25Finish,
  131. md25InitializeEx};
  132. CHECKSUM_FUNCTION csfDES_MAC_MD5 = {
  133. KERB_CHECKSUM_DES_MAC_MD5, // Checksum type
  134. DES_BLOCKLEN, // Checksum length
  135. CKSUM_KEYED,
  136. md5DesInitialize,
  137. md5DesSum,
  138. md5DesFinalize,
  139. md5DesFinish,
  140. md5DesInitializeEx,
  141. NULL};
  142. CHECKSUM_FUNCTION csfRC4_MD5 = {
  143. KERB_CHECKSUM_RC4_MD5, // Checksum type
  144. MD5_LEN, // Checksum length
  145. CKSUM_KEYED,
  146. md5Rc4Initialize,
  147. md5Rc4Sum,
  148. md5Rc4Finalize,
  149. md5Rc4Finish,
  150. md5Rc4InitializeEx,
  151. NULL};
  152. CHECKSUM_FUNCTION csfMD5_HMAC = {
  153. KERB_CHECKSUM_MD5_HMAC, // Checksum type
  154. MD5_LEN, // Checksum length
  155. CKSUM_KEYED,
  156. md5HmacInitialize,
  157. md5HmacSum,
  158. md5HmacFinalize,
  159. md5HmacFinish,
  160. md5HmacInitializeEx,
  161. NULL};
  162. CHECKSUM_FUNCTION csfHMAC_MD5 = {
  163. KERB_CHECKSUM_HMAC_MD5, // Checksum type
  164. MD5_LEN, // Checksum length
  165. CKSUM_KEYED,
  166. md5HmacInitialize,
  167. md5HmacSum,
  168. md5HmacFinalize,
  169. md5HmacFinish,
  170. md5Hmac2InitializeEx,
  171. NULL};
  172. CHECKSUM_FUNCTION csfDES_MAC_MD5_1510 = {
  173. KERB_CHECKSUM_MD5_DES, // Checksum type
  174. DES_BLOCKLEN + MD5_LEN, // Checksum length
  175. CKSUM_KEYED,
  176. md5DesInitialize,
  177. md5DesSum,
  178. md5Des1510Finalize,
  179. md5Des1510Finish,
  180. md5Des1510InitializeEx,
  181. md5Des1510InitializeEx2};
  182. ///////////////////////////////////////////////////////////////////////////
  183. NTSTATUS NTAPI
  184. md4Initialize( ULONG dwSeed,
  185. PCHECKSUM_BUFFER * ppcsBuffer)
  186. {
  187. MD4_CTX * pMD4Context;
  188. #ifdef KERNEL_MODE
  189. pMD4Context = ExAllocatePool(NonPagedPool, sizeof(MD4_CTX));
  190. #else
  191. pMD4Context = malloc(sizeof(MD4_CTX));
  192. #endif
  193. if (!pMD4Context)
  194. {
  195. return(STATUS_NO_MEMORY);
  196. }
  197. MD4Init(pMD4Context);
  198. *ppcsBuffer = pMD4Context;
  199. return(STATUS_SUCCESS);
  200. }
  201. NTSTATUS NTAPI
  202. md4InitializeEx(
  203. PUCHAR Key,
  204. ULONG KeySize,
  205. ULONG MessageType,
  206. PCHECKSUM_BUFFER * ppcsBuffer
  207. )
  208. {
  209. return(md4Initialize(0, ppcsBuffer));
  210. }
  211. NTSTATUS NTAPI
  212. md4Sum( PCHECKSUM_BUFFER pcsBuffer,
  213. ULONG cbData,
  214. PUCHAR pbData)
  215. {
  216. MD4Update((MD4_CTX *) pcsBuffer, pbData, cbData);
  217. return(STATUS_SUCCESS);
  218. }
  219. NTSTATUS NTAPI
  220. md4Finalize( PCHECKSUM_BUFFER pcsBuffer,
  221. PUCHAR pbSum)
  222. {
  223. MD4Final((MD4_CTX *) pcsBuffer);
  224. memcpy(pbSum, ((MD4_CTX *) pcsBuffer)->digest, 16);
  225. return(STATUS_SUCCESS);
  226. }
  227. NTSTATUS NTAPI
  228. md4Finish( PCHECKSUM_BUFFER * ppcsBuffer)
  229. {
  230. #ifdef KERNEL_MODE
  231. ExFreePool(*ppcsBuffer);
  232. #else
  233. free(*ppcsBuffer);
  234. #endif
  235. *ppcsBuffer = 0;
  236. return(STATUS_SUCCESS);
  237. }
  238. ///////////////////////////////////////////////////////////////////////////
  239. NTSTATUS NTAPI
  240. md5Initialize(
  241. ULONG dwSeed,
  242. PCHECKSUM_BUFFER * ppcsBuffer)
  243. {
  244. MD5_CTX * pMD5Context;
  245. #ifdef KERNEL_MODE
  246. pMD5Context = ExAllocatePool(NonPagedPool, sizeof(MD5_CTX));
  247. #else
  248. pMD5Context = malloc(sizeof(MD5_CTX));
  249. #endif
  250. if (!pMD5Context)
  251. {
  252. return(STATUS_NO_MEMORY);
  253. }
  254. MD5Init(pMD5Context);
  255. *ppcsBuffer = pMD5Context;
  256. return(STATUS_SUCCESS);
  257. }
  258. NTSTATUS NTAPI
  259. md5InitializeEx(
  260. PUCHAR Key,
  261. ULONG KeySize,
  262. ULONG MessageType,
  263. PCHECKSUM_BUFFER * ppcsBuffer)
  264. {
  265. return(md5Initialize(0, ppcsBuffer));
  266. }
  267. NTSTATUS NTAPI
  268. md5Sum( PCHECKSUM_BUFFER pcsBuffer,
  269. ULONG cbData,
  270. PUCHAR pbData)
  271. {
  272. MD5Update((MD5_CTX *) pcsBuffer, pbData, cbData);
  273. return(STATUS_SUCCESS);
  274. }
  275. NTSTATUS NTAPI
  276. md5Finalize( PCHECKSUM_BUFFER pcsBuffer,
  277. PUCHAR pbSum)
  278. {
  279. MD5Final((MD5_CTX *) pcsBuffer);
  280. memcpy(pbSum, ((MD5_CTX *) pcsBuffer)->digest, 16);
  281. return(STATUS_SUCCESS);
  282. }
  283. NTSTATUS NTAPI
  284. md5Finish( PCHECKSUM_BUFFER * ppcsBuffer)
  285. {
  286. #ifdef KERNEL_MODE
  287. ExFreePool(*ppcsBuffer);
  288. #else
  289. free(*ppcsBuffer);
  290. #endif
  291. *ppcsBuffer = 0;
  292. return(STATUS_SUCCESS);
  293. }
  294. ///////////////////////////////////////////////////////////////////////////
  295. NTSTATUS NTAPI desPlainInitialize(PUCHAR, ULONG, ULONG, PCRYPT_STATE_BUFFER *);
  296. NTSTATUS NTAPI desEncrypt(PCRYPT_STATE_BUFFER, PUCHAR, ULONG, PUCHAR, PULONG);
  297. NTSTATUS NTAPI desFinish(PCRYPT_STATE_BUFFER *);
  298. NTSTATUS NTAPI desMacInitialize(ULONG, PCHECKSUM_BUFFER *);
  299. NTSTATUS NTAPI desMacInitializeEx(PUCHAR,ULONG, ULONG, PCHECKSUM_BUFFER *);
  300. NTSTATUS NTAPI desMacSum(PCHECKSUM_BUFFER, ULONG, PUCHAR);
  301. NTSTATUS NTAPI desMacFinalize(PCHECKSUM_BUFFER, PUCHAR);
  302. NTSTATUS NTAPI desMacFinish(PCHECKSUM_BUFFER *);
  303. NTSTATUS NTAPI
  304. md25Initialize(
  305. ULONG dwSeed,
  306. PCHECKSUM_BUFFER * ppcsBuffer)
  307. {
  308. return(STATUS_NOT_IMPLEMENTED);
  309. }
  310. NTSTATUS NTAPI
  311. md25InitializeEx(
  312. PUCHAR Key,
  313. ULONG KeySize,
  314. ULONG MessageType,
  315. PCHECKSUM_BUFFER * ppcsBuffer)
  316. {
  317. MD5_CTX * pMD5Context;
  318. NTSTATUS Status = STATUS_SUCCESS;
  319. UCHAR TempBuffer[16];
  320. ULONG OutputSize;
  321. UCHAR TempKey[DES_KEYSIZE];
  322. PCRYPT_STATE_BUFFER DesContext = NULL;
  323. PCRYPTO_SYSTEM DesSystem;
  324. ULONG Index;
  325. memset(
  326. TempBuffer,
  327. 0,
  328. sizeof(TempBuffer)
  329. );
  330. if (KeySize != DES_KEYSIZE)
  331. {
  332. return(STATUS_INVALID_PARAMETER);
  333. }
  334. #ifdef KERNEL_MODE
  335. pMD5Context = (MD5_CTX *) ExAllocatePool(NonPagedPool,sizeof(MD5_CTX));
  336. #else
  337. pMD5Context = (MD5_CTX *) LocalAlloc(0,sizeof(MD5_CTX));
  338. #endif
  339. if (!pMD5Context)
  340. {
  341. return(STATUS_INSUFFICIENT_RESOURCES);
  342. }
  343. MD5Init(pMD5Context);
  344. //
  345. // Prepare the key by byte reversing it.
  346. //
  347. for (Index = 0; Index < DES_KEYSIZE ; Index++ )
  348. {
  349. TempKey[Index] = Key[(DES_KEYSIZE - 1) - Index];
  350. }
  351. Status = CDLocateCSystem(
  352. KERB_ETYPE_DES_PLAIN,
  353. &DesSystem
  354. );
  355. if (!NT_SUCCESS(Status))
  356. {
  357. goto Cleanup;
  358. }
  359. Status = DesSystem->Initialize(
  360. TempKey,
  361. DES_KEYSIZE,
  362. 0, // no options
  363. &DesContext
  364. );
  365. if (!NT_SUCCESS(Status))
  366. {
  367. goto Cleanup;
  368. }
  369. Status = DesSystem->Encrypt(
  370. DesContext,
  371. TempBuffer,
  372. sizeof(TempBuffer),
  373. TempBuffer,
  374. &OutputSize
  375. );
  376. ASSERT(OutputSize == sizeof(TempBuffer));
  377. if (!NT_SUCCESS(Status))
  378. {
  379. goto Cleanup;
  380. }
  381. (VOID) DesSystem->Discard(&DesContext);
  382. //
  383. // Now MD5 update with the encrypted buffer
  384. //
  385. MD5Update(
  386. pMD5Context,
  387. TempBuffer,
  388. sizeof(TempBuffer)
  389. );
  390. *ppcsBuffer = (PCHECKSUM_BUFFER) pMD5Context;
  391. Cleanup:
  392. if (!NT_SUCCESS(Status) && (pMD5Context != NULL))
  393. {
  394. #ifdef KERNEL_MODE
  395. ExFreePool(pMD5Context);
  396. #else
  397. LocalFree(pMD5Context);
  398. #endif
  399. }
  400. return(Status);
  401. }
  402. NTSTATUS NTAPI
  403. md25Sum( PCHECKSUM_BUFFER pcsBuffer,
  404. ULONG cbData,
  405. PUCHAR pbData)
  406. {
  407. MD5Update((MD5_CTX *) pcsBuffer, pbData, cbData);
  408. return(STATUS_SUCCESS);
  409. }
  410. NTSTATUS NTAPI
  411. md25Finalize(
  412. PCHECKSUM_BUFFER pcsBuffer,
  413. PUCHAR pbSum)
  414. {
  415. MD5Final((MD5_CTX *) pcsBuffer);
  416. memcpy(pbSum, ((MD5_CTX *) pcsBuffer)->digest, MD5_LEN/2);
  417. return(STATUS_SUCCESS);
  418. }
  419. NTSTATUS NTAPI
  420. md25Finish( PCHECKSUM_BUFFER * ppcsBuffer)
  421. {
  422. #ifdef KERNEL_MODE
  423. ExFreePool(*ppcsBuffer);
  424. #else
  425. LocalFree(*ppcsBuffer);
  426. #endif
  427. *ppcsBuffer = 0;
  428. return(STATUS_SUCCESS);
  429. }
  430. ///////////////////////////////////////////////////////////////////////////
  431. NTSTATUS NTAPI
  432. md5DesInitialize(
  433. ULONG dwSeed,
  434. PCHECKSUM_BUFFER * ppcsBuffer)
  435. {
  436. return(STATUS_NOT_IMPLEMENTED);
  437. }
  438. NTSTATUS NTAPI
  439. md5DesInitializeEx(
  440. PUCHAR Key,
  441. ULONG KeySize,
  442. ULONG MessageType,
  443. PCHECKSUM_BUFFER * ppcsBuffer)
  444. {
  445. PMD5_DES_STATE_BUFFER pMD5Context;
  446. NTSTATUS Status = STATUS_SUCCESS;
  447. if (KeySize != DES_KEYSIZE)
  448. {
  449. return(STATUS_INVALID_PARAMETER);
  450. }
  451. #ifdef KERNEL_MODE
  452. pMD5Context = (PMD5_DES_STATE_BUFFER) ExAllocatePool(NonPagedPool,sizeof(MD5_DES_STATE_BUFFER));
  453. #else
  454. pMD5Context = (PMD5_DES_STATE_BUFFER) LocalAlloc(0,sizeof(MD5_DES_STATE_BUFFER));
  455. #endif
  456. if (!pMD5Context)
  457. {
  458. return(STATUS_INSUFFICIENT_RESOURCES);
  459. }
  460. MD5Init(&pMD5Context->Md5Context);
  461. //
  462. // Compute the initialization for the MD5
  463. //
  464. Status = desPlainInitialize(
  465. Key,
  466. KeySize,
  467. 0,
  468. &pMD5Context->DesContext
  469. );
  470. if (!NT_SUCCESS(Status))
  471. {
  472. #ifdef KERNEL_MODE
  473. ExFreePool(pMD5Context);
  474. #else
  475. LocalFree(pMD5Context);
  476. #endif
  477. return(Status);
  478. }
  479. *ppcsBuffer = (PCHECKSUM_BUFFER) pMD5Context;
  480. return(STATUS_SUCCESS);
  481. }
  482. NTSTATUS NTAPI
  483. md5DesSum( PCHECKSUM_BUFFER pcsBuffer,
  484. ULONG cbData,
  485. PUCHAR pbData)
  486. {
  487. PMD5_DES_STATE_BUFFER Context = (PMD5_DES_STATE_BUFFER) pcsBuffer;
  488. MD5Update(&Context->Md5Context, pbData, cbData);
  489. return(STATUS_SUCCESS);
  490. }
  491. NTSTATUS NTAPI
  492. md5DesFinalize( PCHECKSUM_BUFFER pcsBuffer,
  493. PUCHAR pbSum)
  494. {
  495. ULONG OutputLength;
  496. PMD5_DES_STATE_BUFFER Context = (PMD5_DES_STATE_BUFFER) pcsBuffer;
  497. MD5Final(&Context->Md5Context);
  498. desEncrypt(
  499. Context->DesContext,
  500. Context->Md5Context.digest,
  501. MD5_LEN,
  502. Context->Md5Context.digest,
  503. &OutputLength
  504. );
  505. RtlCopyMemory(
  506. pbSum,
  507. Context->Md5Context.digest + MD5_LEN-DES_BLOCKLEN,
  508. DES_BLOCKLEN
  509. );
  510. return(STATUS_SUCCESS);
  511. }
  512. NTSTATUS NTAPI
  513. md5DesFinish( PCHECKSUM_BUFFER * ppcsBuffer)
  514. {
  515. PMD5_DES_STATE_BUFFER Context = (PMD5_DES_STATE_BUFFER) *ppcsBuffer;
  516. desFinish(&Context->DesContext);
  517. #ifdef KERNEL_MODE
  518. ExFreePool(Context);
  519. #else
  520. LocalFree(Context);
  521. #endif
  522. *ppcsBuffer = 0;
  523. return(STATUS_SUCCESS);
  524. }
  525. ///////////////////////////////////////////////////////////////////////////
  526. NTSTATUS NTAPI rc4Md4Initialize(PUCHAR, ULONG, ULONG, PCRYPT_STATE_BUFFER *);
  527. NTSTATUS NTAPI rc4LmInitialize(PUCHAR, ULONG, ULONG, PCRYPT_STATE_BUFFER *);
  528. NTSTATUS NTAPI rc4ShaInitialize(PUCHAR, ULONG, ULONG, PCRYPT_STATE_BUFFER *);
  529. NTSTATUS NTAPI rc4Initialize(PUCHAR, ULONG, ULONG, ULONG, PCRYPT_STATE_BUFFER *);
  530. NTSTATUS NTAPI rc4Encrypt(PCRYPT_STATE_BUFFER, PUCHAR, ULONG, PUCHAR, PULONG);
  531. NTSTATUS NTAPI rc4Decrypt(PCRYPT_STATE_BUFFER, PUCHAR, ULONG, PUCHAR, PULONG);
  532. NTSTATUS NTAPI rc4Finish(PCRYPT_STATE_BUFFER *);
  533. NTSTATUS NTAPI
  534. md5Rc4Initialize(
  535. ULONG dwSeed,
  536. PCHECKSUM_BUFFER * ppcsBuffer)
  537. {
  538. return(STATUS_NOT_IMPLEMENTED);
  539. }
  540. NTSTATUS NTAPI
  541. md5Rc4InitializeEx(
  542. PUCHAR Key,
  543. ULONG KeySize,
  544. ULONG MessageType,
  545. PCHECKSUM_BUFFER * ppcsBuffer)
  546. {
  547. PMD5_DES_STATE_BUFFER pMD5Context;
  548. NTSTATUS Status = STATUS_SUCCESS;
  549. #ifdef KERNEL_MODE
  550. pMD5Context = (PMD5_DES_STATE_BUFFER) ExAllocatePool(NonPagedPool,sizeof(MD5_DES_STATE_BUFFER));
  551. #else
  552. pMD5Context = (PMD5_DES_STATE_BUFFER) LocalAlloc(0,sizeof(MD5_DES_STATE_BUFFER));
  553. #endif
  554. if (!pMD5Context)
  555. {
  556. return(STATUS_INSUFFICIENT_RESOURCES);
  557. }
  558. MD5Init(&pMD5Context->Md5Context);
  559. Status = rc4Initialize(
  560. Key,
  561. KeySize,
  562. 0, // no options
  563. 0,
  564. &pMD5Context->DesContext
  565. );
  566. if (!NT_SUCCESS(Status))
  567. {
  568. goto Cleanup;
  569. }
  570. if (!NT_SUCCESS(Status))
  571. {
  572. #ifdef KERNEL_MODE
  573. ExFreePool(pMD5Context);
  574. #else
  575. LocalFree(pMD5Context);
  576. #endif
  577. return(Status);
  578. }
  579. *ppcsBuffer = (PCHECKSUM_BUFFER) pMD5Context;
  580. Cleanup:
  581. if (!NT_SUCCESS(Status) && (pMD5Context != NULL))
  582. {
  583. #ifdef KERNEL_MODE
  584. ExFreePool(pMD5Context);
  585. #else
  586. LocalFree(pMD5Context);
  587. #endif
  588. }
  589. return(STATUS_SUCCESS);
  590. }
  591. NTSTATUS NTAPI
  592. md5Rc4Sum( PCHECKSUM_BUFFER pcsBuffer,
  593. ULONG cbData,
  594. PUCHAR pbData)
  595. {
  596. PMD5_DES_STATE_BUFFER Context = (PMD5_DES_STATE_BUFFER) pcsBuffer;
  597. MD5Update(&Context->Md5Context, pbData, cbData);
  598. return(STATUS_SUCCESS);
  599. }
  600. NTSTATUS NTAPI
  601. md5Rc4Finalize( PCHECKSUM_BUFFER pcsBuffer,
  602. PUCHAR pbSum)
  603. {
  604. PMD5_DES_STATE_BUFFER Context = (PMD5_DES_STATE_BUFFER) pcsBuffer;
  605. ULONG OutputSize;
  606. NTSTATUS Status;
  607. MD5Final(&Context->Md5Context);
  608. memcpy(
  609. pbSum,
  610. Context->Md5Context.digest,
  611. MD5_LEN
  612. );
  613. Status = rc4Encrypt(
  614. Context->DesContext,
  615. pbSum,
  616. MD5_LEN,
  617. pbSum,
  618. &OutputSize
  619. );
  620. ASSERT(OutputSize == MD5_LEN);
  621. if (!NT_SUCCESS(Status))
  622. {
  623. return(Status);
  624. }
  625. return(STATUS_SUCCESS);
  626. }
  627. NTSTATUS NTAPI
  628. md5Rc4Finish( PCHECKSUM_BUFFER * ppcsBuffer)
  629. {
  630. PMD5_DES_STATE_BUFFER Context = (PMD5_DES_STATE_BUFFER) *ppcsBuffer;
  631. (VOID) rc4Finish(&Context->DesContext);
  632. #ifdef KERNEL_MODE
  633. ExFreePool(Context);
  634. #else
  635. LocalFree(Context);
  636. #endif
  637. *ppcsBuffer = 0;
  638. return(STATUS_SUCCESS);
  639. }
  640. ///////////////////////////////////////////////////////////////////////////
  641. BOOLEAN
  642. md5Hmac(
  643. IN PUCHAR pbKeyMaterial,
  644. IN ULONG cbKeyMaterial,
  645. IN PUCHAR pbData,
  646. IN ULONG cbData,
  647. IN PUCHAR pbData2,
  648. IN ULONG cbData2,
  649. OUT PUCHAR HmacData
  650. );
  651. NTSTATUS NTAPI
  652. md5HmacInitialize(
  653. ULONG dwSeed,
  654. PCHECKSUM_BUFFER * ppcsBuffer)
  655. {
  656. return(STATUS_NOT_IMPLEMENTED);
  657. }
  658. NTSTATUS NTAPI
  659. md5HmacInitializeEx(
  660. PUCHAR Key,
  661. ULONG KeySize,
  662. ULONG MessageType,
  663. PCHECKSUM_BUFFER * ppcsBuffer)
  664. {
  665. PMD5_HMAC_STATE_BUFFER pMD5Context = NULL;
  666. NTSTATUS Status = STATUS_SUCCESS;
  667. #ifdef KERNEL_MODE
  668. pMD5Context = (PMD5_HMAC_STATE_BUFFER) ExAllocatePool(NonPagedPool,sizeof(MD5_HMAC_STATE_BUFFER) + KeySize);
  669. #else
  670. pMD5Context = (PMD5_HMAC_STATE_BUFFER) LocalAlloc(0,sizeof(MD5_HMAC_STATE_BUFFER) + KeySize);
  671. #endif
  672. if (!pMD5Context)
  673. {
  674. return(STATUS_INSUFFICIENT_RESOURCES);
  675. }
  676. RtlCopyMemory(
  677. pMD5Context->Key,
  678. Key,
  679. KeySize
  680. );
  681. pMD5Context->KeySize = KeySize;
  682. MD5Init(&pMD5Context->Md5Context);
  683. MD5Update(&pMD5Context->Md5Context, (PUCHAR) &MessageType, sizeof(ULONG));
  684. *ppcsBuffer = (PCHECKSUM_BUFFER) pMD5Context;
  685. return(STATUS_SUCCESS);
  686. }
  687. NTSTATUS NTAPI
  688. md5Hmac2InitializeEx(
  689. PUCHAR Key,
  690. ULONG KeySize,
  691. ULONG MessageType,
  692. PCHECKSUM_BUFFER * ppcsBuffer)
  693. {
  694. PMD5_HMAC_STATE_BUFFER pMD5Context = NULL;
  695. NTSTATUS Status = STATUS_SUCCESS;
  696. #ifdef KERNEL_MODE
  697. pMD5Context = (PMD5_HMAC_STATE_BUFFER) ExAllocatePool(NonPagedPool,sizeof(MD5_HMAC_STATE_BUFFER) + MD5_LEN);
  698. #else
  699. pMD5Context = (PMD5_HMAC_STATE_BUFFER) LocalAlloc(0,sizeof(MD5_HMAC_STATE_BUFFER) + MD5_LEN);
  700. #endif
  701. if (!pMD5Context)
  702. {
  703. return(STATUS_INSUFFICIENT_RESOURCES);
  704. }
  705. md5Hmac(
  706. Key,
  707. KeySize,
  708. "signaturekey",
  709. sizeof("signaturekey"),
  710. NULL,
  711. 0,
  712. pMD5Context->Key
  713. );
  714. pMD5Context->KeySize = MD5_LEN;
  715. MD5Init(&pMD5Context->Md5Context);
  716. MD5Update(&pMD5Context->Md5Context, (PUCHAR) &MessageType, sizeof(ULONG));
  717. *ppcsBuffer = (PCHECKSUM_BUFFER) pMD5Context;
  718. return(STATUS_SUCCESS);
  719. }
  720. NTSTATUS NTAPI
  721. md5HmacSum( PCHECKSUM_BUFFER pcsBuffer,
  722. ULONG cbData,
  723. PUCHAR pbData)
  724. {
  725. PMD5_HMAC_STATE_BUFFER Context = (PMD5_HMAC_STATE_BUFFER) pcsBuffer;
  726. MD5Update(&Context->Md5Context, pbData, cbData);
  727. return(STATUS_SUCCESS);
  728. }
  729. NTSTATUS NTAPI
  730. md5HmacFinalize( PCHECKSUM_BUFFER pcsBuffer,
  731. PUCHAR pbSum)
  732. {
  733. PMD5_HMAC_STATE_BUFFER Context = (PMD5_HMAC_STATE_BUFFER) pcsBuffer;
  734. MD5Final(&Context->Md5Context);
  735. if (!md5Hmac(
  736. Context->Key,
  737. Context->KeySize,
  738. Context->Md5Context.digest,
  739. MD5_LEN,
  740. NULL, // no secondary material
  741. 0,
  742. pbSum))
  743. {
  744. return(STATUS_UNSUCCESSFUL);
  745. }
  746. return(STATUS_SUCCESS);
  747. }
  748. NTSTATUS NTAPI
  749. md5HmacFinish( PCHECKSUM_BUFFER * ppcsBuffer)
  750. {
  751. PMD5_HMAC_STATE_BUFFER Context = (PMD5_HMAC_STATE_BUFFER) *ppcsBuffer;
  752. #ifdef KERNEL_MODE
  753. ExFreePool(Context);
  754. #else
  755. LocalFree(Context);
  756. #endif
  757. *ppcsBuffer = 0;
  758. return(STATUS_SUCCESS);
  759. }
  760. NTSTATUS NTAPI
  761. md5Des1510InitializeEx(
  762. PUCHAR Key,
  763. ULONG KeySize,
  764. ULONG MessageType,
  765. PCHECKSUM_BUFFER * ppcsBuffer
  766. )
  767. {
  768. return(STATUS_NOT_IMPLEMENTED);
  769. }
  770. NTSTATUS NTAPI
  771. md5Des1510InitializeEx2(
  772. PUCHAR Key,
  773. ULONG KeySize,
  774. PUCHAR ChecksumToVerify,
  775. ULONG MessageType,
  776. PCHECKSUM_BUFFER * ppcsBuffer
  777. )
  778. {
  779. ULONG *pul;
  780. ULONG *pul2;
  781. UCHAR FinalKey[DES_KEYSIZE];
  782. PMD5_DES_1510_STATE_BUFFER pContext = NULL;
  783. ULONG cb = DES_BLOCKLEN;
  784. NTSTATUS Status = STATUS_SUCCESS;
  785. //
  786. // Make sure we were passed an appropriate key
  787. //
  788. if (KeySize != DES_KEYSIZE)
  789. {
  790. Status = STATUS_INVALID_PARAMETER;
  791. goto Cleanup;
  792. }
  793. #ifdef KERNEL_MODE
  794. pContext = (PMD5_DES_1510_STATE_BUFFER) ExAllocatePool(NonPagedPool,sizeof(MD5_DES_1510_STATE_BUFFER));
  795. #else
  796. pContext = (PMD5_DES_1510_STATE_BUFFER) LocalAlloc(0,sizeof(MD5_DES_1510_STATE_BUFFER));
  797. #endif
  798. if (!pContext)
  799. {
  800. Status = STATUS_INSUFFICIENT_RESOURCES;
  801. goto Cleanup;
  802. }
  803. //
  804. // create the final key table
  805. //
  806. pul = (ULONG*)FinalKey;
  807. pul2 = (ULONG*)Key;
  808. *pul = *pul2 ^ 0xf0f0f0f0;
  809. pul = (ULONG*)(FinalKey + sizeof(ULONG));
  810. pul2 = (ULONG*)(Key + sizeof(ULONG));
  811. *pul = *pul2 ^ 0xf0f0f0f0;
  812. Status = desPlainInitialize(
  813. FinalKey,
  814. DES_KEYSIZE,
  815. 0,
  816. &pContext->DesContext
  817. );
  818. if (!NT_SUCCESS(Status))
  819. {
  820. goto Cleanup;
  821. }
  822. //
  823. // Checksum was not passed in so generate a confounder
  824. //
  825. if (NULL == ChecksumToVerify)
  826. {
  827. CDGenerateRandomBits(pContext->Confounder,DES_BLOCKLEN);
  828. }
  829. else
  830. {
  831. // the IV is all zero so no need to use CBC on first block
  832. Status = desEncrypt(
  833. pContext->DesContext,
  834. ChecksumToVerify,
  835. DES_BLOCKLEN,
  836. pContext->Confounder,
  837. &cb
  838. );
  839. if (!NT_SUCCESS(Status))
  840. {
  841. goto Cleanup;
  842. }
  843. }
  844. MD5Init(&pContext->Md5Context);
  845. // hash in the confounder
  846. MD5Update(&pContext->Md5Context, pContext->Confounder, DES_BLOCKLEN);
  847. *ppcsBuffer = (PCHECKSUM_BUFFER) pContext;
  848. Cleanup:
  849. if (Status != STATUS_SUCCESS)
  850. {
  851. if (NULL != pContext)
  852. {
  853. #ifdef KERNEL_MODE
  854. ExFreePool(pContext);
  855. #else
  856. LocalFree(pContext);
  857. #endif
  858. }
  859. }
  860. return(Status);
  861. }
  862. NTSTATUS NTAPI
  863. md5Des1510Finalize(
  864. PCHECKSUM_BUFFER pcsBuffer,
  865. PUCHAR pbSum)
  866. {
  867. UCHAR TmpBuffer[DES_BLOCKLEN * 2];
  868. PMD5_DES_1510_STATE_BUFFER pContext = (PMD5_DES_1510_STATE_BUFFER) pcsBuffer;
  869. ULONG cb = DES_BLOCKLEN * 2;
  870. NTSTATUS Status = STATUS_SUCCESS;
  871. memcpy(TmpBuffer, pContext->Confounder, DES_BLOCKLEN);
  872. memcpy(TmpBuffer + DES_BLOCKLEN, pContext->Md5Context.digest, DES_BLOCKLEN);
  873. Status = desEncrypt(
  874. pContext->DesContext,
  875. TmpBuffer,
  876. DES_BLOCKLEN * 2,
  877. pbSum,
  878. &cb
  879. );
  880. return(Status);
  881. }
  882. NTSTATUS NTAPI
  883. md5Des1510Finish( PCHECKSUM_BUFFER * ppcsBuffer)
  884. {
  885. PMD5_DES_1510_STATE_BUFFER pContext = (PMD5_DES_1510_STATE_BUFFER) *ppcsBuffer;
  886. desFinish(&pContext->DesContext);
  887. #ifdef KERNEL_MODE
  888. ExFreePool(pContext);
  889. #else
  890. LocalFree(pContext);
  891. #endif
  892. *ppcsBuffer = 0;
  893. return(STATUS_SUCCESS);
  894. }