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.

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