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.

648 lines
21 KiB

  1. /****************************************************************************/
  2. /* tsfipsenc.c */
  3. /* */
  4. /* FIPS encrpt/decrypt */
  5. /* */
  6. /* Copyright (C) 2002-2004 Microsoft Corporation */
  7. /****************************************************************************/
  8. #include <precomp.h>
  9. #include <fipsapi.h>
  10. #include "asmint.h"
  11. const BYTE DESParityTable[] = {0x00,0x01,0x01,0x02,0x01,0x02,0x02,0x03,
  12. 0x01,0x02,0x02,0x03,0x02,0x03,0x03,0x04};
  13. // IV for all block ciphers
  14. BYTE rgbIV[] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF};
  15. #ifdef _M_IA64
  16. #define ALIGNMENT_BOUNDARY 7
  17. #else
  18. #define ALIGNMENT_BOUNDARY 3
  19. #endif
  20. //
  21. // Name: PrintData
  22. //
  23. // Purpose: Print out the data in debugger
  24. //
  25. // Returns: No
  26. //
  27. // Params: IN pKeyData: point to the data to be printed
  28. // IN cbSize: the size of the key
  29. void PrintData(BYTE *pKeyData, DWORD cbSize)
  30. {
  31. DWORD dwIndex;
  32. //
  33. //print out the key
  34. //
  35. for( dwIndex = 0; dwIndex<cbSize; dwIndex++ ) {
  36. KdPrint(("0x%x ", pKeyData[dwIndex]));
  37. if( dwIndex > 0 && (dwIndex+1) % 8 == 0 )
  38. KdPrint(("\n"));
  39. }
  40. }
  41. //
  42. // Name: Mydesparityonkey
  43. //
  44. // Purpose: Set the parity on the DES key to be odd
  45. //
  46. // Returns: No
  47. //
  48. // Params: IN/OUT pbKey: point to the key
  49. // IN cbKey: the size of the key
  50. void Mydesparityonkey(
  51. BYTE *pbKey,
  52. DWORD cbKey)
  53. {
  54. DWORD i;
  55. for (i=0; i<cbKey; i++)
  56. {
  57. if (!((DESParityTable[pbKey[i]>>4] + DESParityTable[pbKey[i]&0x0F]) % 2))
  58. pbKey[i] = pbKey[i] ^ 0x01;
  59. }
  60. }
  61. //
  62. // Name: Expandkey
  63. //
  64. // Purpose: Expand a 21-byte 3DES key to a 24-byte 3DES key (including parity bit)
  65. // by inserting a parity bit after every 7 bits in the 21-byte DES
  66. //
  67. // Returns: No
  68. //
  69. // Params: IN/OUT pbKey: point to the key
  70. ////
  71. #define PARITY_UNIT 7
  72. void Expandkey(
  73. BYTE *pbKey
  74. )
  75. {
  76. BYTE pbTemp[DES3_KEYLEN];
  77. DWORD i, dwCount;
  78. UINT16 shortTemp;
  79. BYTE *pbIn, *pbOut;
  80. RtlCopyMemory(pbTemp, pbKey, sizeof(pbTemp));
  81. dwCount = (DES3_KEYLEN * 8) / PARITY_UNIT;
  82. pbOut = pbKey;
  83. for (i=0; i<dwCount; i++) {
  84. pbIn = ((pbTemp + (PARITY_UNIT * i) / 8));
  85. //shortTemp = *(pbIn + 1);
  86. shortTemp = *pbIn + (((UINT16)*(pbIn + 1)) << 8);
  87. shortTemp = shortTemp >> ((PARITY_UNIT * i) % 8);
  88. //shortTemp = (*(unsigned short *)((pbTemp + (PARITY_UNIT * i) / 8))) >> ((PARITY_UNIT * i) % 8);
  89. *pbOut = (BYTE)(shortTemp & 0x7F);
  90. pbOut++;
  91. }
  92. }
  93. // Name: TSFIPS_Init
  94. //
  95. // Purpose: Initialize the FIPS library table.
  96. //
  97. // Returns: TRUE - succeeded
  98. // FALSE - failed
  99. //
  100. // Params: IN pFipsData: Fips data
  101. BOOL TSFIPS_Init(PSM_FIPS_Data pFipsData)
  102. {
  103. NTSTATUS status;
  104. UNICODE_STRING fipsDeviceName;
  105. PDEVICE_OBJECT pDeviceObject = NULL;
  106. PIRP pIrpFips;
  107. KEVENT event;
  108. IO_STATUS_BLOCK iostatus;
  109. BOOLEAN rc = FALSE;
  110. // Begin Initialize FIPS device
  111. RtlInitUnicodeString(
  112. &fipsDeviceName,
  113. FIPS_DEVICE_NAME);
  114. KeInitializeEvent(&event, NotificationEvent, FALSE);
  115. status = IoGetDeviceObjectPointer(
  116. &fipsDeviceName,
  117. FILE_READ_DATA,
  118. &(pFipsData->pFileObject),
  119. &(pFipsData->pDeviceObject));
  120. if (!NT_SUCCESS(status)) {
  121. KdPrint(("TSFIPS - IoGetDeviceObjectPointer failed - %X\n", status));
  122. goto HandleError;
  123. }
  124. // Irp is freed by I/O manager when next lower driver completes
  125. pIrpFips = IoBuildDeviceIoControlRequest(
  126. IOCTL_FIPS_GET_FUNCTION_TABLE,
  127. pFipsData->pDeviceObject,
  128. NULL, // no input buffer
  129. 0,
  130. &(pFipsData->FipsFunctionTable), // output buffer is func table
  131. sizeof(FIPS_FUNCTION_TABLE),
  132. FALSE, // specifies IRP_MJ_DEVICE_CONTROL
  133. &event,
  134. &iostatus);
  135. if (! pIrpFips) {
  136. // IoBuildDeviceIoControlRequest returns NULL if Irp could not be created.
  137. ObDereferenceObject(pFipsData->pFileObject);
  138. pFipsData->pFileObject = NULL;
  139. KdPrint(("TSFIPS - IoBuildDeviceIoControlRequest failed, 0x%x\n", iostatus.Status));
  140. goto HandleError;
  141. }
  142. status = IoCallDriver(
  143. pFipsData->pDeviceObject,
  144. pIrpFips);
  145. if (STATUS_PENDING == status) {
  146. KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
  147. // Lower-level driver can pass status info up via the IO_STATUS_BLOCK
  148. // in the Irp.
  149. status = iostatus.Status;
  150. }
  151. if (! NT_SUCCESS(status)) {
  152. ObDereferenceObject(pFipsData->pFileObject);
  153. pFipsData->pFileObject = NULL;
  154. KdPrint(("TSFIPS - IoCallDriver failed, 0x%x\n", status));
  155. goto HandleError;
  156. }
  157. rc = TRUE;
  158. HandleError:
  159. return rc;
  160. }
  161. // Name: TSFIPS_Term
  162. //
  163. // Purpose: Terminate the FIPS .
  164. //
  165. // Returns: No
  166. //
  167. //
  168. // Params: IN pFipsData: Fips data
  169. void TSFIPS_Term(PSM_FIPS_Data pFipsData)
  170. {
  171. if (pFipsData->pFileObject) {
  172. ObDereferenceObject(pFipsData->pFileObject);
  173. pFipsData->pFileObject = NULL;
  174. }
  175. }
  176. // Name: FipsSHAHash
  177. //
  178. // Purpose: Hash the data using SHA.
  179. //
  180. // Returns: No
  181. //
  182. // Params: IN pFipsFunctionTable: Fips function table
  183. // IN pbData: point to the data to be hashed
  184. // IN cbData: the size of the data to be hashed
  185. // OUT pbHash: point to the hash
  186. void FipsSHAHash(PFIPS_FUNCTION_TABLE pFipsFunctionTable,
  187. BYTE *pbData,
  188. DWORD cbData,
  189. BYTE *pbHash)
  190. {
  191. A_SHA_CTX HashContext;
  192. pFipsFunctionTable->FipsSHAInit(&HashContext);
  193. pFipsFunctionTable->FipsSHAUpdate(&HashContext, pbData, cbData);
  194. pFipsFunctionTable->FipsSHAFinal(&HashContext, pbHash);
  195. }
  196. // Name: FipsSHAHashEx
  197. //
  198. // Purpose: Hash 2 set of data using SHA.
  199. //
  200. // Returns: No
  201. //
  202. // Params: IN pFipsFunctionTable: Fips function table
  203. // IN pbData: point to the data to be hashed
  204. // IN cbData: the size of the data to be hashed
  205. // IN pbData2: point to the data to be hashed
  206. // IN cbData2: the size of the data to be hashed
  207. // OUT pbHash: point to the hash result
  208. void FipsSHAHashEx(PFIPS_FUNCTION_TABLE pFipsFunctionTable,
  209. BYTE *pbData,
  210. DWORD cbData,
  211. BYTE *pbData2,
  212. DWORD cbData2,
  213. BYTE *pbHash)
  214. {
  215. A_SHA_CTX HashContext;
  216. pFipsFunctionTable->FipsSHAInit(&HashContext);
  217. pFipsFunctionTable->FipsSHAUpdate(&HashContext, pbData, cbData);
  218. pFipsFunctionTable->FipsSHAUpdate(&HashContext, pbData2, cbData2);
  219. pFipsFunctionTable->FipsSHAFinal(&HashContext, pbHash);
  220. }
  221. // Name: FipsHmacSHAHash
  222. //
  223. // Purpose: Hash the data using HmacSHA.
  224. //
  225. // Returns: No
  226. //
  227. // Params: IN pFipsFunctionTable: Fips function table
  228. // IN pbData: point to the data to be hashed
  229. // IN cbData: the size of the data to be hashed
  230. // IN pbKey: point to the key used for calculating hash
  231. // IN cbKey: the size of the key
  232. // OUT pbHash: point to the hash result
  233. void FipsHmacSHAHash(PFIPS_FUNCTION_TABLE pFipsFunctionTable,
  234. BYTE *pbData,
  235. DWORD cbData,
  236. BYTE *pbKey,
  237. DWORD cbKey,
  238. BYTE *pbHash)
  239. {
  240. A_SHA_CTX HashContext;
  241. pFipsFunctionTable->FipsHmacSHAInit(&HashContext, pbKey, cbKey);
  242. pFipsFunctionTable->FipsHmacSHAUpdate(&HashContext, pbData, cbData);
  243. pFipsFunctionTable->FipsHmacSHAFinal(&HashContext, pbKey, cbKey, pbHash);
  244. }
  245. // Name: FipsHmacSHAHashEx
  246. //
  247. // Purpose: Hash the 2 set ofdata using HmacSHA.
  248. //
  249. // Returns: No
  250. //
  251. // Params: IN pFipsFunctionTable: Fips function table
  252. // IN pbData: point to the data to be hashed
  253. // IN cbData: the size of the data to be hashed
  254. // IN pbData2: point to the data to be hashed
  255. // IN cbData2: the size of the data to be hashed
  256. // IN pbKey: point to the key used for calculating hash
  257. // IN cbKey: the size of the key
  258. // OUT pbHash: point to the hash result
  259. void FipsHmacSHAHashEx(PFIPS_FUNCTION_TABLE pFipsFunctionTable,
  260. BYTE *pbData,
  261. DWORD cbData,
  262. BYTE *pbData2,
  263. DWORD cbData2,
  264. BYTE *pbKey,
  265. DWORD cbKey,
  266. BYTE *pbHash)
  267. {
  268. A_SHA_CTX HashContext;
  269. pFipsFunctionTable->FipsHmacSHAInit(&HashContext, pbKey, cbKey);
  270. pFipsFunctionTable->FipsHmacSHAUpdate(&HashContext, pbData, cbData);
  271. pFipsFunctionTable->FipsHmacSHAUpdate(&HashContext, pbData2, cbData2);
  272. pFipsFunctionTable->FipsHmacSHAFinal(&HashContext, pbKey, cbKey, pbHash);
  273. }
  274. // Name: FipsDeriveKey
  275. //
  276. // Purpose: Derive the key from the hash.
  277. //
  278. // Returns: No
  279. //
  280. // Params: IN pFipsFunctionTable: Fips function table
  281. // IN rgbSHABase: hash data used to derive the key
  282. // IN cbSHABase: size of the hash
  283. // OUT pKeyData: point to the derived DESkey
  284. // OUT pKeyTable: point to the derived DES key table
  285. void FipsDeriveKey(PFIPS_FUNCTION_TABLE pFipsFunctionTable,
  286. BYTE *rgbSHABase,
  287. DWORD cbSHABase,
  288. BYTE *pKeyData,
  289. PDES3TABLE pKeyTable)
  290. {
  291. BOOL rc = FALSE;
  292. //
  293. //Generate the key as follows
  294. //1. Hash the secret. Call the result H1 (rgbSHABase in our case)
  295. //2. Use 1st 21 bytes of [H1|H1] as the 3DES key
  296. //3. Expand the 21-byte 3DES key to a 24-byte 3DES key (including parity bit), which
  297. // will be used by CryptAPI
  298. //4. Set the parity on the 3DES key to be odd
  299. //
  300. //Step 2 - [H1|H1]
  301. //
  302. RtlCopyMemory(pKeyData, rgbSHABase, cbSHABase);
  303. RtlCopyMemory(pKeyData + cbSHABase, rgbSHABase, MAX_FIPS_SESSION_KEY_SIZE - cbSHABase);
  304. //
  305. //Step 3 - Expand the key
  306. //
  307. Expandkey(pKeyData);
  308. //
  309. //Step 4 - Set parity
  310. //
  311. Mydesparityonkey(pKeyData, MAX_FIPS_SESSION_KEY_SIZE);
  312. //DES3TABLE Des3Table;
  313. pFipsFunctionTable->Fips3Des3Key(pKeyTable, pKeyData);
  314. }
  315. // Name: TSFIPS_MakeSessionKeys
  316. //
  317. // Purpose: Make the key from client/server random numbers
  318. //
  319. // Returns: TRUE if succeeded
  320. //
  321. // Params: IN pFipsData: Fips Data
  322. // IN pRandomKey: Randow numbers used to generate key
  323. // IN pEnumMethod: To generate Encrypt or Decrypt key, If NULL, both keys
  324. // IN bPassThroughStack: If it's the passthrough stack in shadow
  325. BOOL TSFIPS_MakeSessionKeys(PSM_FIPS_Data pFipsData,
  326. LPRANDOM_KEYS_PAIR pRandomKey,
  327. CryptMethod *pEnumMethod,
  328. BOOL bPassThroughStack)
  329. {
  330. BYTE rgbSHABase1[A_SHA_DIGEST_LEN];
  331. BYTE rgbSHABase2[A_SHA_DIGEST_LEN];
  332. BYTE Signature[A_SHA_DIGEST_LEN];
  333. BYTE *pKey1, *pKey2;
  334. A_SHA_CTX HashContext;
  335. memset(rgbSHABase1, 0, sizeof(rgbSHABase1));
  336. memset(rgbSHABase2, 0, sizeof(rgbSHABase2));
  337. // Server Encrypt/Client Decrypt key
  338. if ((pEnumMethod == NULL) ||
  339. (*pEnumMethod == Encrypt)) {
  340. pFipsData->FipsFunctionTable.FipsSHAInit(&HashContext);
  341. pFipsData->FipsFunctionTable.FipsSHAUpdate(&HashContext, pRandomKey->clientRandom, RANDOM_KEY_LENGTH/2);
  342. pFipsData->FipsFunctionTable.FipsSHAUpdate(&HashContext, pRandomKey->serverRandom, RANDOM_KEY_LENGTH/2);
  343. pFipsData->FipsFunctionTable.FipsSHAFinal(&HashContext, rgbSHABase1);
  344. if (!bPassThroughStack) {
  345. FipsDeriveKey(&(pFipsData->FipsFunctionTable), rgbSHABase1, sizeof(rgbSHABase1),
  346. pFipsData->bEncKey, &(pFipsData->EncTable));
  347. pKey1 = pFipsData->bEncKey;
  348. // Set IV
  349. RtlCopyMemory(pFipsData->bEncIv, rgbIV, sizeof(rgbIV));
  350. }
  351. else {
  352. // If it's passthrough stack in shadow, it's server decrypt key
  353. FipsDeriveKey(&(pFipsData->FipsFunctionTable), rgbSHABase1, sizeof(rgbSHABase1),
  354. pFipsData->bDecKey, &(pFipsData->DecTable));
  355. pKey1 = pFipsData->bDecKey;
  356. // Set IV
  357. RtlCopyMemory(pFipsData->bDecIv, rgbIV, sizeof(rgbIV));
  358. }
  359. }
  360. // Client Encrypt/Server Decrypt key
  361. if ((pEnumMethod == NULL) ||
  362. (*pEnumMethod == Decrypt)) {
  363. pFipsData->FipsFunctionTable.FipsSHAInit(&HashContext);
  364. pFipsData->FipsFunctionTable.FipsSHAUpdate(&HashContext, pRandomKey->clientRandom + RANDOM_KEY_LENGTH/2, RANDOM_KEY_LENGTH/2);
  365. pFipsData->FipsFunctionTable.FipsSHAUpdate(&HashContext, pRandomKey->serverRandom + RANDOM_KEY_LENGTH/2, RANDOM_KEY_LENGTH/2);
  366. pFipsData->FipsFunctionTable.FipsSHAFinal(&HashContext, rgbSHABase2);
  367. if (!bPassThroughStack) {
  368. FipsDeriveKey(&(pFipsData->FipsFunctionTable), rgbSHABase2, sizeof(rgbSHABase2),
  369. pFipsData->bDecKey, &(pFipsData->DecTable));
  370. pKey2 = pFipsData->bDecKey;
  371. // Set IV
  372. RtlCopyMemory(pFipsData->bDecIv, rgbIV, sizeof(rgbIV));
  373. }
  374. else {
  375. // It's passthrough stack in shadow, it's server encrypt key
  376. FipsDeriveKey(&(pFipsData->FipsFunctionTable), rgbSHABase2, sizeof(rgbSHABase2),
  377. pFipsData->bEncKey, &(pFipsData->EncTable));
  378. pKey2 = pFipsData->bEncKey;
  379. // Set IV
  380. RtlCopyMemory(pFipsData->bEncIv, rgbIV, sizeof(rgbIV));
  381. }
  382. }
  383. //
  384. // Get the signing key
  385. // The signing key is SHA(rgbSHABase1|rgbSHABase2)
  386. //
  387. if (pEnumMethod == NULL) {
  388. FipsSHAHashEx(&(pFipsData->FipsFunctionTable), rgbSHABase1, sizeof(rgbSHABase1), rgbSHABase2,
  389. sizeof(rgbSHABase2), pFipsData->bSignKey);
  390. }
  391. return TRUE;
  392. }
  393. // Name: TSFIPS_AdjustDataLen
  394. //
  395. // Purpose: In Block encryption mode, adjust the data len to multiple of blocks
  396. //
  397. // Returns: Adjusted data length
  398. //
  399. // Params: IN dataLen: Data length needed to be encrypted
  400. UINT32 TSFIPS_AdjustDataLen(UINT32 dataLen)
  401. {
  402. return (dataLen - dataLen % FIPS_BLOCK_LEN + FIPS_BLOCK_LEN);
  403. }
  404. // Name: TSFIPS_EncryptData
  405. //
  406. // Purpose: Encrypt the data and compute the signature
  407. //
  408. // Returns: TRUE if successfully encrypted the data
  409. //
  410. // Params: IN pFipsData: Fips Data
  411. // IN/OUT pbData: pointer to the data buffer being encrypted, encrypted data is
  412. // returned in the same buffer.
  413. // IN dwDataLen: data length to be encrypted
  414. // IN dwPadLen: padding length in the data buffer
  415. // OUT pbSignature: pointer to a signature buffer where the data signature is returned.
  416. // IN dwEncryptionCount: running counter of all encryptions
  417. BOOL TSFIPS_EncryptData(
  418. PSM_FIPS_Data pFipsData,
  419. LPBYTE pbData,
  420. DWORD dwDataLen,
  421. DWORD dwPadLen,
  422. LPBYTE pbSignature,
  423. DWORD dwEncryptionCount)
  424. {
  425. UINT8 Pad;
  426. BYTE rgbSHA[A_SHA_DIGEST_LEN];
  427. BYTE pbHmac[A_SHA_DIGEST_LEN];
  428. BOOL rc = FALSE;
  429. BYTE *pTempBuffer = NULL;
  430. BOOL bGetNewBuffer = FALSE;
  431. // Pad the the data with the padding size
  432. Pad = (UINT8)dwPadLen;
  433. memset(pbData + dwDataLen - dwPadLen, Pad, dwPadLen);
  434. // Compute signature
  435. FipsHmacSHAHashEx(&(pFipsData->FipsFunctionTable), pbData, dwDataLen - dwPadLen, (BYTE *)&dwEncryptionCount,
  436. sizeof(dwEncryptionCount), pFipsData->bSignKey, sizeof(pFipsData->bSignKey), pbHmac);
  437. // Take the 1st 8 bytes of Hmac as signature
  438. RtlCopyMemory(pbSignature, pbHmac, MAX_SIGN_SIZE);
  439. // FipsBlockCBC need the data buffer to be aligned
  440. // so allocate a new buffer to hold the data if pbData is not aligned
  441. if ((ULONG_PTR)pbData & ALIGNMENT_BOUNDARY) {
  442. pTempBuffer = (BYTE *)ExAllocatePoolWithTag(PagedPool, dwDataLen, WD_ALLOC_TAG);
  443. if (pTempBuffer == NULL) {
  444. goto Exit;
  445. }
  446. RtlCopyMemory(pTempBuffer, pbData, dwDataLen);
  447. bGetNewBuffer = TRUE;
  448. }
  449. else {
  450. pTempBuffer = pbData;
  451. }
  452. pFipsData->FipsFunctionTable.FipsBlockCBC(FIPS_CBC_3DES,
  453. pTempBuffer,
  454. pTempBuffer,
  455. dwDataLen,
  456. &(pFipsData->EncTable),
  457. ENCRYPT,
  458. pFipsData->bEncIv);
  459. // Need to copy the data back if we allocate a new buffer to hold the data
  460. if (bGetNewBuffer) {
  461. RtlCopyMemory(pbData, pTempBuffer, dwDataLen);
  462. ExFreePool(pTempBuffer);
  463. }
  464. rc = TRUE;
  465. Exit:
  466. return rc;
  467. }
  468. // Name: TSFIPS_DecryptData
  469. //
  470. // Purpose: Decrypt the data and compare the signature
  471. //
  472. // Returns: TRUE if successfully decrypted the data
  473. //
  474. // Params: IN pFipsData: Fips Data
  475. // IN/OUT pbData: pointer to the data buffer being decrypted, decrypted data is
  476. // returned in the same buffer.
  477. // IN dwDataLen: data length to be decrypted
  478. // IN dwPadLen: padding length in the data buffer
  479. // IN pbSignature: pointer to a signature buffer
  480. // IN dwDecryptionCount: running counter of all encryptions
  481. BOOL TSFIPS_DecryptData(
  482. PSM_FIPS_Data pFipsData,
  483. LPBYTE pbData,
  484. DWORD dwDataLen,
  485. DWORD dwPadLen,
  486. LPBYTE pbSignature,
  487. DWORD dwDecryptionCount)
  488. {
  489. BOOL rc = FALSE;
  490. BYTE abSignature[A_SHA_DIGEST_LEN];
  491. BYTE rgbSHA[A_SHA_DIGEST_LEN];
  492. BYTE *pTempBuffer = NULL;
  493. BOOL bGetNewBuffer = FALSE;
  494. // dwPadLen should always be less than dwDataLen, if it's not the case
  495. // it means we're under attack so bail out here
  496. if (dwPadLen >= dwDataLen) {
  497. goto Exit;
  498. }
  499. // FipsBlockCBC need the data buffer to be aligned
  500. // so allocate a new buffer to hold the data if pbData is not aligned
  501. if ((ULONG_PTR)pbData & ALIGNMENT_BOUNDARY) {
  502. pTempBuffer = (BYTE *)ExAllocatePoolWithTag(PagedPool, dwDataLen, WD_ALLOC_TAG);
  503. if (pTempBuffer == NULL) {
  504. goto Exit;
  505. }
  506. RtlCopyMemory(pTempBuffer, pbData, dwDataLen);
  507. bGetNewBuffer = TRUE;
  508. }
  509. else {
  510. pTempBuffer = pbData;
  511. }
  512. pFipsData->FipsFunctionTable.FipsBlockCBC(FIPS_CBC_3DES,
  513. pTempBuffer,
  514. pTempBuffer,
  515. dwDataLen,
  516. &(pFipsData->DecTable),
  517. DECRYPT,
  518. pFipsData->bDecIv);
  519. // Need to copy the data back if we allocate a new buffer to hold the data
  520. if (bGetNewBuffer) {
  521. RtlCopyMemory(pbData, pTempBuffer, dwDataLen);
  522. ExFreePool(pTempBuffer);
  523. }
  524. // Compute signature
  525. FipsHmacSHAHashEx(&(pFipsData->FipsFunctionTable), pbData, dwDataLen - dwPadLen, (BYTE *)&dwDecryptionCount,
  526. sizeof(dwDecryptionCount), pFipsData->bSignKey, sizeof(pFipsData->bSignKey), abSignature);
  527. //
  528. // check to see the sigature match.
  529. //
  530. if(!memcmp(
  531. (LPBYTE)abSignature,
  532. pbSignature,
  533. MAX_SIGN_SIZE)) {
  534. rc = TRUE;;
  535. }
  536. Exit:
  537. return rc;
  538. }