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.

917 lines
25 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. efs.c
  5. Abstract:
  6. This module contains the code that implements the EFS
  7. file system filter driver.
  8. Author:
  9. Robert Gu (robertg) 29-Oct-1996
  10. Environment:
  11. Kernel mode
  12. Revision History:
  13. --*/
  14. #include "efs.h"
  15. #include "efsrtl.h"
  16. #define BUFFER_SIZE 1024
  17. #define BUFFER_REG_VAL L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\NTFS\\EFS\\Parameters"
  18. #define MAX_ALLOC_BUFFER L"MaximumBlob"
  19. #define EFS_KERNEL_CACHE_PERIOD L"EFSKCACHEPERIOD"
  20. //
  21. // Global storage for this file system filter driver.
  22. //
  23. EFS_DATA EfsData;
  24. WORK_QUEUE_ITEM EfsShutdownCleanupWorkItem;
  25. //
  26. // $EFS stream name
  27. //
  28. WCHAR AttrName[5] = L"$EFS";
  29. #if DBG
  30. ULONG EFSDebug = 0;
  31. #endif
  32. ENCRYPTION_CALL_BACK EFSCallBackTable = {
  33. ENCRYPTION_CURRENT_INTERFACE_VERSION,
  34. ENCRYPTION_ALL_STREAMS,
  35. EfsOpenFile,
  36. NULL,
  37. EFSFilePostCreate,
  38. EfsFileControl,
  39. EfsFileControl,
  40. EFSFsControl,
  41. EfsRead,
  42. EfsWrite,
  43. EfsFreeContext
  44. };
  45. VOID
  46. EfspShutdownCleanup(
  47. IN PVOID Parameter
  48. );
  49. //
  50. // Assign text sections for each routine.
  51. //
  52. #ifdef ALLOC_PRAGMA
  53. #pragma alloc_text(PAGE, EfspShutdownCleanup)
  54. #pragma alloc_text(PAGE, EfsInitialization)
  55. #pragma alloc_text(PAGE, EfsGetSessionKey)
  56. #pragma alloc_text(PAGE, GetKeyBlobLength)
  57. #pragma alloc_text(PAGE, GetKeyBlobBuffer)
  58. #pragma alloc_text(PAGE, SetKeyTable)
  59. #pragma alloc_text(PAGE, EfsInitFips)
  60. #endif
  61. VOID
  62. EfspShutdownCleanup(
  63. IN PVOID Parameter
  64. )
  65. {
  66. PEPROCESS LsaProcess;
  67. PAGED_CODE();
  68. UNREFERENCED_PARAMETER(Parameter);
  69. if (EfsData.LsaProcess) {
  70. LsaProcess = EfsData.LsaProcess;
  71. EfsData.LsaProcess = NULL;
  72. ObDereferenceObject(LsaProcess);
  73. }
  74. }
  75. NTSTATUS
  76. EfsInitialization(
  77. void
  78. )
  79. /*++
  80. Routine Description:
  81. This is the initialization routine for the general purpose file system
  82. filter driver. This routine creates the device object that represents this
  83. driver in the system and registers it for watching all file systems that
  84. register or unregister themselves as active file systems.
  85. Arguments:
  86. DriverObject - Pointer to driver object created by the system.
  87. Return Value:
  88. The function value is the final status from the initialization operation.
  89. --*/
  90. {
  91. UNICODE_STRING nameString;
  92. PDEVICE_EXTENSION deviceExtension;
  93. PFILE_OBJECT fileObject;
  94. NTSTATUS status;
  95. HANDLE threadHdl;
  96. ULONG i;
  97. OBJECT_ATTRIBUTES objAttr;
  98. UNICODE_STRING efsInitEventName;
  99. UNICODE_STRING efsBufValue;
  100. ULONG resultLength;
  101. PKEY_VALUE_PARTIAL_INFORMATION pPartialValue = NULL;
  102. HANDLE efsKey;
  103. EFS_INIT_DATAEXG InitDataFromSrv;
  104. PAGED_CODE();
  105. //
  106. // Mark our global data record
  107. //
  108. EfsData.AllocMaxBuffer = FALSE;
  109. EfsData.FipsFileObject = NULL;
  110. EfsData.FipsFunctionTable.Fips3Des = NULL;
  111. EfsData.FipsFunctionTable.Fips3Des3Key = NULL;
  112. EfsData.EfsDriverCacheLength = DefaultTimeExpirePeriod;
  113. RtlInitUnicodeString( &efsBufValue, BUFFER_REG_VAL );
  114. InitializeObjectAttributes(
  115. &objAttr,
  116. &efsBufValue,
  117. OBJ_CASE_INSENSITIVE,
  118. NULL,
  119. NULL
  120. );
  121. status = ZwOpenKey(
  122. &efsKey,
  123. KEY_READ,
  124. &objAttr);
  125. if (NT_SUCCESS(status)) {
  126. pPartialValue = (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePool(NonPagedPool, BUFFER_SIZE);
  127. if (pPartialValue) {
  128. RtlInitUnicodeString(&efsBufValue, MAX_ALLOC_BUFFER);
  129. status = ZwQueryValueKey(
  130. efsKey,
  131. &efsBufValue,
  132. KeyValuePartialInformation,
  133. (PVOID)pPartialValue,
  134. BUFFER_SIZE,
  135. &resultLength
  136. );
  137. if (NT_SUCCESS(status)) {
  138. ASSERT(pPartialValue->Type == REG_DWORD);
  139. if (*((PLONG)&(pPartialValue->Data))){
  140. EfsData.AllocMaxBuffer = TRUE;
  141. }
  142. }
  143. RtlInitUnicodeString(&efsBufValue, EFS_KERNEL_CACHE_PERIOD);
  144. status = ZwQueryValueKey(
  145. efsKey,
  146. &efsBufValue,
  147. KeyValuePartialInformation,
  148. (PVOID)pPartialValue,
  149. BUFFER_SIZE,
  150. &resultLength
  151. );
  152. if (NT_SUCCESS(status)) {
  153. ASSERT(pPartialValue->Type == REG_DWORD);
  154. if (((*((DWORD *)&(pPartialValue->Data))) >= MINCACHEPERIOD) &&
  155. ((*((DWORD *)&(pPartialValue->Data))) <= MAXCACHEPERIOD)){
  156. EfsData.EfsDriverCacheLength = *((DWORD *)&(pPartialValue->Data));
  157. EfsData.EfsDriverCacheLength *= 10000000;
  158. }
  159. }
  160. ExFreePool(pPartialValue);
  161. }
  162. ZwClose(efsKey);
  163. }
  164. EfsData.NodeTypeCode = EFS_NTC_DATA_HEADER;
  165. EfsData.NodeByteSize = sizeof( EFS_DATA );
  166. EfsData.EfsInitialized = FALSE;
  167. EfsData.InitEventHandle = NULL;
  168. EfsData.LsaProcess = NULL;
  169. //
  170. // Initialize global data structures.
  171. //
  172. ExInitializeWorkItem( &EfsShutdownCleanupWorkItem,
  173. &EfspShutdownCleanup,
  174. NULL );
  175. status = PoQueueShutdownWorkItem( &EfsShutdownCleanupWorkItem );
  176. if (!NT_SUCCESS(status)) {
  177. return status;
  178. }
  179. InitializeListHead( &(EfsData.EfsOpenCacheList) );
  180. InitializeListHead( &(EfsData.EfsKeyLookAsideList) );
  181. ExInitializeFastMutex( &(EfsData.EfsKeyBlobMemSrcMutex) );
  182. ExInitializeFastMutex( &(EfsData.EfsOpenCacheMutex) );
  183. //
  184. // Initialize the event lookaside list
  185. //
  186. ExInitializeNPagedLookasideList(&(EfsData.EfsEventPool),
  187. NULL,
  188. NULL,
  189. 0,
  190. sizeof(KEVENT),
  191. 'levE',
  192. EFS_EVENTDEPTH
  193. );
  194. //
  195. // Try to allocate at least one event in the list. This one will be used for
  196. // sure later.
  197. //
  198. {
  199. PVOID pTryEvent;
  200. pTryEvent = ExAllocateFromNPagedLookasideList(&(EfsData.EfsEventPool));
  201. if ( NULL == pTryEvent ){
  202. //
  203. // Free previously allocated memory
  204. //
  205. ExDeleteNPagedLookasideList(&(EfsData.EfsEventPool));
  206. return STATUS_NO_MEMORY;
  207. }
  208. ExFreeToNPagedLookasideList(&(EfsData.EfsEventPool), pTryEvent);
  209. }
  210. //
  211. // Initialize the context lookaside list
  212. //
  213. ExInitializeNPagedLookasideList(&(EfsData.EfsContextPool),
  214. NULL,
  215. NULL,
  216. 0,
  217. sizeof(EFS_CONTEXT),
  218. 'nocE',
  219. EFS_CONTEXTDEPTH
  220. );
  221. //
  222. // Initialize the cache lookaside list
  223. //
  224. ExInitializePagedLookasideList(&(EfsData.EfsOpenCachePool),
  225. NULL,
  226. NULL,
  227. 0,
  228. sizeof(OPEN_CACHE),
  229. 'hcoE',
  230. EFS_CACHEDEPTH
  231. );
  232. ExInitializePagedLookasideList(&(EfsData.EfsMemSourceItem),
  233. NULL,
  234. NULL,
  235. 0,
  236. sizeof(KEY_BLOB_RAMPOOL),
  237. 'msfE',
  238. EFS_ALGDEPTH
  239. );
  240. ExInitializeNPagedLookasideList(&(EfsData.EfsLookAside),
  241. NULL,
  242. NULL,
  243. 0,
  244. sizeof(NPAGED_LOOKASIDE_LIST),
  245. 'msfE',
  246. EFS_ALGDEPTH
  247. );
  248. status = NtOfsRegisterCallBacks( Encryption, &EFSCallBackTable );
  249. if (!NT_SUCCESS(status)) {
  250. //
  251. // Register callback failed
  252. //
  253. ExDeleteNPagedLookasideList(&(EfsData.EfsEventPool));
  254. ExDeleteNPagedLookasideList(&(EfsData.EfsContextPool));
  255. ExDeletePagedLookasideList(&(EfsData.EfsOpenCachePool));
  256. ExDeletePagedLookasideList(&(EfsData.EfsMemSourceItem));
  257. ExDeleteNPagedLookasideList(&(EfsData.EfsLookAside));
  258. return status;
  259. }
  260. RtlInitUnicodeString(&(EfsData.EfsName), &AttrName[0]);
  261. //
  262. // Create an event
  263. //
  264. RtlInitUnicodeString( &efsInitEventName, L"\\EFSInitEvent" );
  265. InitializeObjectAttributes(
  266. &objAttr,
  267. &efsInitEventName,
  268. 0,
  269. NULL,
  270. NULL
  271. );
  272. //
  273. // Try to create an event. If the event was not created, the EFS
  274. // server is not loaded yet. We will create a thread waiting for
  275. // EFS server to be loaded. If the event was already created, we
  276. // will just go ahead and get the session key from the EFS server.
  277. //
  278. status = ZwCreateEvent(
  279. &(EfsData.InitEventHandle),
  280. EVENT_MODIFY_STATE,
  281. &objAttr,
  282. NotificationEvent,
  283. FALSE
  284. );
  285. if (!NT_SUCCESS(status)) {
  286. if ( STATUS_OBJECT_NAME_COLLISION == status ){
  287. //
  288. // EFS server has been loaded. This is the normal case.
  289. // Call server to get the session key.
  290. //
  291. status = GenerateSessionKey(
  292. &InitDataFromSrv
  293. );
  294. if (NT_SUCCESS( status )) {
  295. //
  296. // Set session key
  297. //
  298. RtlCopyMemory( &(EfsData.SessionKey[0]), InitDataFromSrv.Key, DES_KEYSIZE );
  299. deskey( (DESTable*)&(EfsData.SessionDesTable[0]),
  300. &(EfsData.SessionKey[0]));
  301. status = PsLookupProcessByProcessId(
  302. InitDataFromSrv.LsaProcessID,
  303. &(EfsData.LsaProcess)
  304. );
  305. RtlSecureZeroMemory(&InitDataFromSrv, sizeof(EFS_INIT_DATAEXG));
  306. if (NT_SUCCESS( status )) {
  307. EfsData.EfsInitialized = TRUE;
  308. if ( PsGetCurrentProcess() != EfsData.LsaProcess ){
  309. KAPC_STATE ApcState;
  310. KeStackAttachProcess (
  311. EfsData.LsaProcess,
  312. &ApcState
  313. );
  314. InitSecurityInterface();
  315. KeUnstackDetachProcess(&ApcState);
  316. } else {
  317. InitSecurityInterface();
  318. }
  319. EfsInitFips();
  320. } else {
  321. #if DBG
  322. if ( (EFSTRACEALL | EFSTRACELIGHT) & EFSDebug ){
  323. DbgPrint("PsLookupProcessByProcessId failed, status = %x\n",status);
  324. }
  325. #endif
  326. //
  327. // Failed to get the process pointer
  328. //
  329. ExDeleteNPagedLookasideList(&(EfsData.EfsEventPool));
  330. ExDeleteNPagedLookasideList(&(EfsData.EfsContextPool));
  331. ExDeletePagedLookasideList(&(EfsData.EfsOpenCachePool));
  332. ExDeletePagedLookasideList(&(EfsData.EfsMemSourceItem));
  333. ExDeleteNPagedLookasideList(&(EfsData.EfsLookAside));
  334. }
  335. } else {
  336. #if DBG
  337. if ( (EFSTRACEALL | EFSTRACELIGHT) & EFSDebug ){
  338. DbgPrint("GenerateSessionKey failed, status = %x\n",status);
  339. }
  340. #endif
  341. //
  342. // Failed to get the session key
  343. //
  344. ExDeleteNPagedLookasideList(&(EfsData.EfsEventPool));
  345. ExDeleteNPagedLookasideList(&(EfsData.EfsContextPool));
  346. ExDeletePagedLookasideList(&(EfsData.EfsOpenCachePool));
  347. ExDeletePagedLookasideList(&(EfsData.EfsMemSourceItem));
  348. ExDeleteNPagedLookasideList(&(EfsData.EfsLookAside));
  349. }
  350. } else {
  351. //
  352. // Unexpected error occured. EFS cannot be loaded
  353. //
  354. #if DBG
  355. if ( (EFSTRACEALL | EFSTRACELIGHT ) & EFSDebug ){
  356. DbgPrint("EFSFILTER: Efs init event creation failed.%x\n", status);
  357. }
  358. #endif
  359. ExDeleteNPagedLookasideList(&(EfsData.EfsEventPool));
  360. ExDeleteNPagedLookasideList(&(EfsData.EfsContextPool));
  361. ExDeletePagedLookasideList(&(EfsData.EfsOpenCachePool));
  362. ExDeletePagedLookasideList(&(EfsData.EfsMemSourceItem));
  363. ExDeleteNPagedLookasideList(&(EfsData.EfsLookAside));
  364. }
  365. } else {
  366. //
  367. // The server is not ready yet.
  368. // Create a thread and wait for the server in that thread
  369. //
  370. status = PsCreateSystemThread(
  371. &threadHdl,
  372. GENERIC_ALL,
  373. NULL,
  374. NULL,
  375. NULL,
  376. EfsGetSessionKey,
  377. NULL
  378. );
  379. if ( NT_SUCCESS( status ) ){
  380. ZwClose( threadHdl );
  381. } else {
  382. ExDeleteNPagedLookasideList(&(EfsData.EfsEventPool));
  383. ExDeleteNPagedLookasideList(&(EfsData.EfsContextPool));
  384. ExDeletePagedLookasideList(&(EfsData.EfsOpenCachePool));
  385. ExDeletePagedLookasideList(&(EfsData.EfsMemSourceItem));
  386. ExDeleteNPagedLookasideList(&(EfsData.EfsLookAside));
  387. }
  388. }
  389. return status;
  390. }
  391. VOID
  392. EfsUninitialization(
  393. VOID
  394. )
  395. {
  396. PLIST_ENTRY pLink;
  397. PKEY_BLOB_RAMPOOL pTmpItem;
  398. PNPAGED_LOOKASIDE_LIST MemSrcList;
  399. while (!IsListEmpty (&EfsData.EfsKeyLookAsideList)) {
  400. pLink = RemoveHeadList (&EfsData.EfsKeyLookAsideList);
  401. pTmpItem = CONTAINING_RECORD(pLink, KEY_BLOB_RAMPOOL, MemSourceChain);
  402. MemSrcList = pTmpItem->MemSourceList;
  403. ExDeleteNPagedLookasideList(MemSrcList);
  404. ExFreeToNPagedLookasideList(&(EfsData.EfsLookAside), MemSrcList );
  405. ExFreeToPagedLookasideList(&(EfsData.EfsMemSourceItem), pTmpItem );
  406. }
  407. ExDeleteNPagedLookasideList(&(EfsData.EfsEventPool));
  408. ExDeleteNPagedLookasideList(&(EfsData.EfsContextPool));
  409. ExDeletePagedLookasideList(&(EfsData.EfsOpenCachePool));
  410. ExDeletePagedLookasideList(&(EfsData.EfsMemSourceItem));
  411. ExDeleteNPagedLookasideList(&(EfsData.EfsLookAside));
  412. if (EfsData.FipsFileObject) {
  413. ObDereferenceObject(EfsData.FipsFileObject);
  414. EfsData.FipsFileObject = NULL;
  415. }
  416. }
  417. VOID
  418. EfsGetSessionKey(
  419. IN PVOID StartContext
  420. )
  421. /*++
  422. Routine Description:
  423. This routine is invoked in DriverEntry. It runs in a seperate thread.
  424. The purpose of this routine is to wait for the EFS server. And Get the session key.
  425. Arguments:
  426. StartContext - Start context of the thread.
  427. Return Value:
  428. None.
  429. --*/
  430. {
  431. SECURITY_DESCRIPTOR efsInitEventSecurityDescriptor;
  432. NTSTATUS status;
  433. EFS_INIT_DATAEXG InitDataFromSrv;
  434. #if DBG
  435. if ( EFSTRACEALL & EFSDebug ){
  436. DbgPrint( "EFSFILTER: Thread started. %x\n", EfsData.NodeTypeCode );
  437. }
  438. #endif
  439. status = ZwWaitForSingleObject (
  440. EfsData.InitEventHandle,
  441. FALSE,
  442. (PLARGE_INTEGER)NULL
  443. );
  444. ZwClose( EfsData.InitEventHandle );
  445. //
  446. // Call server to get the session key
  447. //
  448. status = GenerateSessionKey(
  449. &InitDataFromSrv
  450. );
  451. if (!NT_SUCCESS( status )) {
  452. #if DBG
  453. if ( (EFSTRACEALL | EFSTRACELIGHT) & EFSDebug ){
  454. DbgPrint("GenerateSessionKey failed, status = %x\n",status);
  455. }
  456. #endif
  457. return;
  458. }
  459. //
  460. // Set session key
  461. //
  462. RtlCopyMemory( &(EfsData.SessionKey[0]), InitDataFromSrv.Key, DES_KEYSIZE );
  463. deskey( (DESTable*)&(EfsData.SessionDesTable[0]),
  464. &(EfsData.SessionKey[0]));
  465. status = PsLookupProcessByProcessId(
  466. InitDataFromSrv.LsaProcessID,
  467. &(EfsData.LsaProcess)
  468. );
  469. RtlSecureZeroMemory(&InitDataFromSrv, sizeof(EFS_INIT_DATAEXG));
  470. if (NT_SUCCESS( status )) {
  471. EfsData.EfsInitialized = TRUE;
  472. if ( PsGetCurrentProcess() != EfsData.LsaProcess ){
  473. KAPC_STATE ApcState;
  474. //KeAttachProcess(EfsData.LsaProcess);
  475. KeStackAttachProcess (
  476. EfsData.LsaProcess,
  477. &ApcState
  478. );
  479. InitSecurityInterface();
  480. //KeDetachProcess();
  481. KeUnstackDetachProcess(&ApcState);
  482. } else {
  483. InitSecurityInterface();
  484. }
  485. EfsInitFips();
  486. } else {
  487. #if DBG
  488. if ( (EFSTRACEALL | EFSTRACELIGHT) & EFSDebug ){
  489. DbgPrint("PsLookupProcessByProcessId failed, status = %x\n",status);
  490. }
  491. #endif
  492. }
  493. return;
  494. }
  495. ULONG GetKeyBlobLength(
  496. ULONG AlgID
  497. )
  498. {
  499. if (EfsData.AllocMaxBuffer) {
  500. return AES_KEY_BLOB_LENGTH_256;
  501. }
  502. switch (AlgID){
  503. case CALG_DESX:
  504. return DESX_KEY_BLOB_LENGTH;
  505. case CALG_3DES:
  506. return DES3_KEY_BLOB_LENGTH;
  507. case CALG_AES_256:
  508. return AES_KEY_BLOB_LENGTH_256;
  509. case CALG_DES:
  510. default:
  511. return DES_KEY_BLOB_LENGTH;
  512. }
  513. return 0;
  514. }
  515. PKEY_BLOB
  516. GetKeyBlobBuffer(
  517. ULONG AlgID
  518. )
  519. {
  520. PNPAGED_LOOKASIDE_LIST MemSrcList = NULL;
  521. PKEY_BLOB_RAMPOOL KeyBlobPoolListItem = NULL;
  522. PKEY_BLOB_RAMPOOL pTmpItem = NULL;
  523. ULONG KeyBlobLength;
  524. PLIST_ENTRY pLink = NULL;
  525. PKEY_BLOB NewKeyBlob;
  526. KeyBlobLength = GetKeyBlobLength(AlgID);
  527. if (!KeyBlobLength){
  528. ASSERT(KeyBlobLength);
  529. return NULL;
  530. }
  531. ExAcquireFastMutex( &(EfsData.EfsKeyBlobMemSrcMutex));
  532. for (pLink = EfsData.EfsKeyLookAsideList.Flink; pLink != &(EfsData.EfsKeyLookAsideList); pLink = pLink->Flink) {
  533. pTmpItem = CONTAINING_RECORD(pLink, KEY_BLOB_RAMPOOL, MemSourceChain);
  534. if (pTmpItem->AlgorithmID == AlgID) {
  535. //
  536. // The lookaside list already exists
  537. //
  538. MemSrcList = pTmpItem->MemSourceList;
  539. break;
  540. }
  541. }
  542. ExReleaseFastMutex( &(EfsData.EfsKeyBlobMemSrcMutex) );
  543. if ( MemSrcList == NULL ) {
  544. //
  545. // No lookaside for this type of key. Go and create one item.
  546. //
  547. MemSrcList = (PNPAGED_LOOKASIDE_LIST)ExAllocateFromNPagedLookasideList(&(EfsData.EfsLookAside));
  548. KeyBlobPoolListItem = (PKEY_BLOB_RAMPOOL) ExAllocateFromPagedLookasideList(&(EfsData.EfsMemSourceItem));
  549. if ( (NULL == MemSrcList) || (NULL == KeyBlobPoolListItem) ){
  550. if (MemSrcList) {
  551. ExFreeToNPagedLookasideList(&(EfsData.EfsLookAside), MemSrcList );
  552. }
  553. if (KeyBlobPoolListItem){
  554. ExFreeToPagedLookasideList(&(EfsData.EfsMemSourceItem), KeyBlobPoolListItem );
  555. }
  556. return NULL;
  557. }
  558. RtlZeroMemory( KeyBlobPoolListItem, sizeof( KEY_BLOB_RAMPOOL ) );
  559. KeyBlobPoolListItem->MemSourceList = MemSrcList;
  560. KeyBlobPoolListItem->AlgorithmID = AlgID;
  561. ExInitializeNPagedLookasideList(
  562. MemSrcList,
  563. NULL,
  564. NULL,
  565. 0,
  566. KeyBlobLength,
  567. 'msfE',
  568. EFS_KEYDEPTH
  569. );
  570. ExAcquireFastMutex( &(EfsData.EfsKeyBlobMemSrcMutex));
  571. InsertHeadList( &(EfsData.EfsKeyLookAsideList), &(KeyBlobPoolListItem->MemSourceChain));
  572. ExReleaseFastMutex( &(EfsData.EfsKeyBlobMemSrcMutex) );
  573. }
  574. //
  575. // Allocate the Key Blob
  576. //
  577. NewKeyBlob = (PKEY_BLOB)ExAllocateFromNPagedLookasideList(MemSrcList);
  578. if (NewKeyBlob){
  579. NewKeyBlob->AlgorithmID = AlgID;
  580. NewKeyBlob->KeyLength = KeyBlobLength;
  581. NewKeyBlob->MemSource = MemSrcList;
  582. }
  583. return NewKeyBlob;
  584. }
  585. BOOLEAN
  586. SetKeyTable(
  587. PKEY_BLOB KeyBlob,
  588. PEFS_KEY EfsKey
  589. )
  590. {
  591. char DesXTmpKey[DESX_KEYSIZE];
  592. switch ( EfsKey->Algorithm ){
  593. case CALG_3DES:
  594. if (EfsData.AllocMaxBuffer) {
  595. RtlZeroMemory( &(KeyBlob->Key[0]) + DES3_TABLESIZE, KeyBlob->KeyLength - DES3_KEY_BLOB_LENGTH);
  596. }
  597. if (EfsData.FipsFunctionTable.Fips3Des3Key) {
  598. EfsData.FipsFunctionTable.Fips3Des3Key(
  599. (DES3TABLE*) &(KeyBlob->Key[0]),
  600. ((char *)EfsKey) + sizeof ( EFS_KEY )
  601. );
  602. } else {
  603. return FALSE;
  604. }
  605. //tripledes3key(
  606. // (DES3TABLE*) &(KeyBlob->Key[0]),
  607. // ((char *)EfsKey) + sizeof ( EFS_KEY )
  608. // );
  609. break;
  610. case CALG_DESX:
  611. //
  612. // Flush the non used area.
  613. //
  614. if (EfsData.AllocMaxBuffer) {
  615. RtlZeroMemory( &(KeyBlob->Key[0]) + DESX_TABLESIZE, KeyBlob->KeyLength - DESX_KEY_BLOB_LENGTH);
  616. }
  617. desexpand128to192(
  618. ((char *)EfsKey) + sizeof ( EFS_KEY ),
  619. DesXTmpKey
  620. );
  621. desxkey(
  622. (DESXTable*) &(KeyBlob->Key[0]),
  623. DesXTmpKey
  624. );
  625. break;
  626. case CALG_AES_256:
  627. aeskey(
  628. (AESTable*) &(KeyBlob->Key[0]),
  629. ((char *)EfsKey) + sizeof ( EFS_KEY ),
  630. AES_ROUNDS_256
  631. );
  632. break;
  633. case CALG_DES:
  634. default:
  635. if (EfsData.AllocMaxBuffer) {
  636. RtlZeroMemory( &(KeyBlob->Key[0]) + DES_TABLESIZE, KeyBlob->KeyLength - DES_KEY_BLOB_LENGTH);
  637. }
  638. deskey(
  639. (DESTable*) &(KeyBlob->Key[0]),
  640. ((char *)EfsKey) + sizeof ( EFS_KEY )
  641. );
  642. break;
  643. }
  644. return TRUE;
  645. }
  646. BOOLEAN
  647. EfsInitFips(VOID)
  648. /*++
  649. Routine Description:
  650. Initialize the FIPS library table.
  651. Arguments:
  652. Return Value:
  653. TRUE/FALSE.
  654. --*/
  655. {
  656. UNICODE_STRING deviceName;
  657. NTSTATUS status;
  658. PDEVICE_OBJECT pDeviceObject;
  659. // PFILE_OBJECT pFileObject = NULL;
  660. PIRP pIrp;
  661. IO_STATUS_BLOCK IoStatusBlock;
  662. PAGED_CODE();
  663. RtlInitUnicodeString(&deviceName, FIPS_DEVICE_NAME);
  664. //
  665. // Get the file and device objects for FIPS.
  666. //
  667. status = IoGetDeviceObjectPointer( &deviceName,
  668. FILE_ALL_ACCESS,
  669. &EfsData.FipsFileObject,
  670. &pDeviceObject);
  671. if (status != STATUS_SUCCESS) {
  672. return FALSE;
  673. }
  674. //
  675. // Build the request to send to FIPS to get library table.
  676. //
  677. pIrp = IoBuildDeviceIoControlRequest( IOCTL_FIPS_GET_FUNCTION_TABLE,
  678. pDeviceObject,
  679. NULL,
  680. 0,
  681. &EfsData.FipsFunctionTable,
  682. sizeof(FIPS_FUNCTION_TABLE),
  683. FALSE,
  684. NULL,
  685. &IoStatusBlock
  686. );
  687. if (pIrp == NULL) {
  688. #if DBG
  689. DbgPrint("EfsInitFips: IoBuildDeviceIoControlRequest IOCTL_FIPS_GET_FUNCTION_TABLE failed.\n");
  690. #endif
  691. ObDereferenceObject(EfsData.FipsFileObject);
  692. EfsData.FipsFileObject = NULL;
  693. return FALSE;
  694. }
  695. status = IoCallDriver(pDeviceObject, pIrp);
  696. if (status != STATUS_SUCCESS) {
  697. ObDereferenceObject(EfsData.FipsFileObject);
  698. EfsData.FipsFileObject = NULL;
  699. #if DBG
  700. DbgPrint("EfsInitFips: IoCallDriver failed, status = %x\n",status);
  701. #endif
  702. return FALSE;
  703. }
  704. return TRUE;
  705. }