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.

2970 lines
94 KiB

  1. // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil -*- (for GNU Emacs)
  2. //
  3. // Copyright (c) 1985-2000 Microsoft Corporation
  4. //
  5. // This file is part of the Microsoft Research IPv6 Network Protocol Stack.
  6. // You should have received a copy of the Microsoft End-User License Agreement
  7. // for this software along with this release; see the file "license.txt".
  8. // If not, please see http://www.research.microsoft.com/msripv6/license.htm,
  9. // or write to Microsoft Research, One Microsoft Way, Redmond, WA 98052-6399.
  10. //
  11. // Abstract:
  12. //
  13. // IP security routines for Internet Protocol Version 6.
  14. //
  15. #include "oscfg.h"
  16. #include "ndis.h"
  17. #include "ip6imp.h"
  18. #include "ip6def.h"
  19. #include "ipsec.h"
  20. #include "security.h"
  21. #include "alloca.h"
  22. //
  23. // Global Variables.
  24. //
  25. KSPIN_LOCK IPSecLock;
  26. SecurityPolicy *SecurityPolicyList;
  27. SecurityAssociation *SecurityAssociationList = NULL;
  28. ulong SecurityStateValidationCounter;
  29. uchar Zero[max(MAXUCHAR, MAX_RESULT_SIZE)] = {0};
  30. SecurityAlgorithm AlgorithmTable[NUM_ALGORITHMS];
  31. #ifdef IPSEC_DEBUG
  32. void dump_encoded_mesg(uchar *buff, uint len)
  33. {
  34. uint i, cnt = 0;
  35. uint bytes = 0;
  36. uint wrds = 0;
  37. uchar *buf = buff;
  38. for (i = 0; i < len; i++) {
  39. if (wrds == 0) {
  40. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_IPSEC,
  41. "&%02x: ", cnt));
  42. }
  43. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_IPSEC,
  44. "%02x", *buf));
  45. buf++;
  46. bytes++;
  47. if (!(bytes % 4)) {
  48. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_IPSEC,
  49. " "));
  50. bytes = 0;
  51. }
  52. wrds++;
  53. if (!(wrds % 16)) {
  54. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_IPSEC,
  55. "\n"));
  56. wrds = 0;
  57. cnt += 16;
  58. }
  59. }
  60. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_IPSEC,
  61. "\n"));
  62. }
  63. void DumpKey(uchar *buff, uint len)
  64. {
  65. uint i;
  66. for (i = 0; i < len; i++) {
  67. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_IPSEC,
  68. "|%c", buff[i]));
  69. }
  70. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_IPSEC,
  71. "|\n"));
  72. }
  73. #endif
  74. //* SPCheckAddr - Compare IP address in packet to IP address in policy.
  75. //
  76. // SPAddrField specifies the type of comparison:
  77. // WILDCARD_VALUE, SINGLE_VALUE, or RANGE_VALUE.
  78. //
  79. int
  80. SPCheckAddr(
  81. IPv6Addr *PacketAddr,
  82. uint SPAddrField,
  83. IPv6Addr *SPAddr,
  84. IPv6Addr *SPAddrData)
  85. {
  86. int Result;
  87. switch (SPAddrField) {
  88. case WILDCARD_VALUE:
  89. //
  90. // Always a match since the address is don't care.
  91. //
  92. Result = TRUE;
  93. break;
  94. case SINGLE_VALUE:
  95. //
  96. // Check if the address of the packet matches the SP selector.
  97. //
  98. Result = IP6_ADDR_EQUAL(PacketAddr, SPAddr);
  99. break;
  100. case RANGE_VALUE:
  101. //
  102. // Check if the address is in the specified selector range.
  103. //
  104. Result = (IP6_ADDR_LTEQ(SPAddr, PacketAddr) &&
  105. IP6_ADDR_LTEQ(PacketAddr, SPAddrData));
  106. break;
  107. default:
  108. //
  109. // Should never happen.
  110. //
  111. ABORTMSG("SPCheckAddr: invalid SPAddrField value");
  112. Result = FALSE;
  113. }
  114. return Result;
  115. }
  116. //* SPCheckPort - Compare port in packet to port in policy.
  117. //
  118. uint
  119. SPCheckPort(
  120. ushort PacketPort,
  121. uint SPPortField,
  122. ushort SPPort,
  123. ushort SPPortData)
  124. {
  125. uint Result = FALSE;
  126. switch (SPPortField) {
  127. case WILDCARD_VALUE:
  128. // Always a match since the port is don't care.
  129. Result = TRUE;
  130. break;
  131. case SINGLE_VALUE:
  132. // Check if the port of the packet matches the SP selector.
  133. if (PacketPort == SPPort) {
  134. Result = TRUE;
  135. }
  136. break;
  137. case RANGE_VALUE:
  138. // Check if port is between range.
  139. if (PacketPort >= SPPort && PacketPort <= SPPortData) {
  140. Result = TRUE;
  141. }
  142. break;
  143. default:
  144. //
  145. // Should never happen.
  146. //
  147. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INTERNAL_ERROR,
  148. "SPCheckPort: invalid value for SPPortField (%u)\n",
  149. SPPortField));
  150. }
  151. return Result;
  152. }
  153. //* ReleaseSA
  154. //
  155. // Releases a reference to an SA.
  156. //
  157. void
  158. ReleaseSA(SecurityAssociation *SA)
  159. {
  160. if (InterlockedDecrement((PLONG)&SA->RefCnt) == 0) {
  161. //
  162. // No more references, so deallocate it.
  163. //
  164. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_STATE,
  165. "Freeing SA: %p\n", SA));
  166. RemoveSecurityAssociation(SA);
  167. ExFreePool(SA);
  168. }
  169. }
  170. //* DeleteSA - Invalidate a security association.
  171. //
  172. // The SA is removed from the SA chain. All pointers from the SA entry are
  173. // removed and the related reference counts decremented. The SP pointers to
  174. // the SA can be removed; however, there could be references from the temp SA
  175. // holders used during IPSec traffic processing.
  176. //
  177. // The temp SA references (IPSecProc and SALinkage) remove the references
  178. // when traffic processing is done. The case can occur where the SA is
  179. // deleted but the temp SA holder still has a reference. In that case,
  180. // the SA is not removed from the global list.
  181. //
  182. int
  183. DeleteSA(
  184. SecurityAssociation *SA)
  185. {
  186. SecurityAssociation *FirstSA, *PrevSA = NULL;
  187. uint Direction;
  188. //
  189. // Get the start of the SA Chain.
  190. //
  191. Direction = SA->DirectionFlag;
  192. if (Direction == INBOUND) {
  193. FirstSA = SA->SecPolicy->InboundSA;
  194. } else {
  195. FirstSA = SA->SecPolicy->OutboundSA;
  196. }
  197. //
  198. // Find the invalid SA and keep track of the SA before it.
  199. //
  200. while (FirstSA != SA) {
  201. PrevSA = FirstSA;
  202. if (PrevSA == NULL) {
  203. // This is a problem it should never happen.
  204. // REVIEW: Can we change this to an ASSERT?
  205. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_RARE,
  206. "DeleteSA: SA was not found\n"));
  207. return FALSE;
  208. }
  209. FirstSA = FirstSA->ChainedSecAssoc;
  210. }
  211. //
  212. // Remove the SA from the SA Chain.
  213. //
  214. // Check if the invalid SA is the First SA of the chain.
  215. if (PrevSA == NULL) {
  216. // The invalid SA is the first SA so the SP needs to be adjusted.
  217. if (Direction == INBOUND) {
  218. SA->SecPolicy->InboundSA = FirstSA->ChainedSecAssoc;
  219. } else {
  220. SA->SecPolicy->OutboundSA = FirstSA->ChainedSecAssoc;
  221. }
  222. } else {
  223. // Just a entry in the Chain.
  224. PrevSA->ChainedSecAssoc = FirstSA->ChainedSecAssoc;
  225. }
  226. // Decrement the reference count of the SP.
  227. SA->SecPolicy->RefCnt--;
  228. // Remove the reference to the SP.
  229. SA->SecPolicy = NULL;
  230. SA->Valid = SA_REMOVED;
  231. // Decrement the reference count of the SA.
  232. ReleaseSA(SA);
  233. InvalidateSecurityState();
  234. return TRUE;
  235. }
  236. //* RemoveSecurityPolicy
  237. //
  238. // Remove a policy from the global list.
  239. // References are not held for the global list links.
  240. //
  241. void
  242. RemoveSecurityPolicy(SecurityPolicy *SP)
  243. {
  244. if (SP->Prev == NULL) {
  245. SecurityPolicyList = SP->Next;
  246. } else {
  247. SP->Prev->Next = SP->Next;
  248. }
  249. if (SP->Next != NULL) {
  250. SP->Next->Prev = SP->Prev;
  251. }
  252. }
  253. //* DeleteSP - Removes an SP entry from the kernel.
  254. //
  255. // The removal of an SP makes all the SAs belonging to the SP invalid.
  256. // Unlike the SA removal, this removes every reference to the invalid SP.
  257. // Therefore, a check does not need to be made to ensure the SP is valid.
  258. //
  259. // Called with the security lock held.
  260. //
  261. int
  262. DeleteSP(
  263. SecurityPolicy *SP)
  264. {
  265. //
  266. // Remove the SP's SAs.
  267. //
  268. while (SP->InboundSA != NULL) {
  269. if (!(DeleteSA(SP->InboundSA))) {
  270. return FALSE;
  271. }
  272. }
  273. while (SP->OutboundSA != NULL) {
  274. if (!(DeleteSA(SP->OutboundSA))) {
  275. return FALSE;
  276. }
  277. }
  278. //
  279. // Take it off the global list.
  280. //
  281. RemoveSecurityPolicy(SP);
  282. // Check if this is part of an SA bundle.
  283. if (SP->SABundle != NULL) {
  284. SecurityPolicy *PrevSABundle, *NextSABundle;
  285. //
  286. // The SP pointer being removed is a middle or first SABundle pointer.
  287. //
  288. PrevSABundle = SP->PrevSABundle;
  289. NextSABundle = SP->SABundle;
  290. NextSABundle->PrevSABundle = PrevSABundle;
  291. if (PrevSABundle == NULL) {
  292. // First SABundle pointer.
  293. NextSABundle->RefCnt--;
  294. } else {
  295. //
  296. // Clean up the SABundle deletion affects on other SP pointers.
  297. //
  298. while (PrevSABundle != NULL) {
  299. PrevSABundle->NestCount--;
  300. PrevSABundle->SABundle = NextSABundle;
  301. NextSABundle = PrevSABundle;
  302. PrevSABundle = PrevSABundle->PrevSABundle;
  303. }
  304. SP->RefCnt--;
  305. }
  306. SP->RefCnt--;
  307. }
  308. //
  309. // Check if anything else is referencing the invalid SP.
  310. // All the interfaces and SA references have been removed.
  311. // The only thing left are SABundle pointers.
  312. //
  313. if (SP->RefCnt != 0) {
  314. SecurityPolicy *PrevSABundle, *NextSABundle;
  315. //
  316. // The SP pointer being removed is the last of the bundle pointers.
  317. //
  318. PrevSABundle = SP->PrevSABundle;
  319. NextSABundle = SP->SABundle;
  320. ASSERT(PrevSABundle != NULL);
  321. ASSERT(NextSABundle == NULL);
  322. PrevSABundle->RefCnt--;
  323. //
  324. // Cleanup the SABundle deletion affects on other SP pointers.
  325. //
  326. while (PrevSABundle != NULL) {
  327. PrevSABundle->NestCount--;
  328. PrevSABundle->SABundle = NextSABundle;
  329. NextSABundle = PrevSABundle;
  330. PrevSABundle = PrevSABundle->PrevSABundle;
  331. }
  332. SP->RefCnt--;
  333. // Now the reference count better be zero.
  334. if (SP->RefCnt != 0) {
  335. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_RARE,
  336. "DeleteSP: The SP list is corrupt!\n"));
  337. return FALSE;
  338. }
  339. }
  340. // Free the memory.
  341. ExFreePool(SP);
  342. InvalidateSecurityState();
  343. return TRUE;
  344. }
  345. //* RemoveSecurityAssociation
  346. //
  347. // Remove an association from the global list.
  348. // References are not held for the global list links.
  349. //
  350. void
  351. RemoveSecurityAssociation(SecurityAssociation *SA)
  352. {
  353. if (SA->Prev == NULL) {
  354. SecurityAssociationList = SA->Next;
  355. } else {
  356. SA->Prev->Next = SA->Next;
  357. }
  358. if (SA->Next != NULL) {
  359. SA->Next->Prev = SA->Prev;
  360. }
  361. }
  362. //* FreeIPSecToDo
  363. //
  364. void
  365. FreeIPSecToDo(
  366. IPSecProc *IPSecToDo,
  367. uint Number)
  368. {
  369. uint i;
  370. for (i = 0; i < Number; i++) {
  371. ReleaseSA(IPSecToDo[i].SA);
  372. }
  373. ExFreePool(IPSecToDo);
  374. }
  375. //* InboundSAFind - find a SA in the Security Association Database.
  376. //
  377. // A Security Association on a receiving machine is uniquely identified
  378. // by the tuple of SPI, IP Destination, and security protocol.
  379. //
  380. // REVIEW: Since we can choose our SPI's to be system-wide unique, we
  381. // REVIEW: could do the lookup solely via SPI and just verify the others.
  382. //
  383. // REVIEW: Should we do our IP Destination lookup via ADE? Faster.
  384. //
  385. SecurityAssociation *
  386. InboundSAFind(
  387. ulong SPI, // Security Parameter Index.
  388. IPv6Addr *Dest, // Destination address.
  389. uint Protocol) // Security protocol in use (e.g. AH or ESP).
  390. {
  391. SecurityAssociation *SA;
  392. KIRQL OldIrql;
  393. // Get Security Lock.
  394. KeAcquireSpinLock(&IPSecLock, &OldIrql);
  395. // Start at the first SA entry.
  396. for (SA = SecurityAssociationList; SA != NULL; SA = SA->Next) {
  397. // Check SPI.
  398. if (SPI == SA->SPI) {
  399. // Check destination IP address and IPSec protocol.
  400. if (IP6_ADDR_EQUAL(Dest, &SA->SADestAddr) &&
  401. (Protocol == SA->IPSecProto)) {
  402. // Check direction.
  403. if (SA->DirectionFlag == INBOUND) {
  404. // Check if the SA entry is valid.
  405. if (SA->Valid == SA_VALID) {
  406. AddRefSA(SA);
  407. break;
  408. }
  409. // Not valid so continue checking.
  410. continue;
  411. }
  412. }
  413. }
  414. }
  415. // Release lock.
  416. KeReleaseSpinLock(&IPSecLock, OldIrql);
  417. return SA;
  418. }
  419. //* InboundSALookup - Check the matched SP for a matching SA.
  420. //
  421. // In the SABundle case, this function is called recursively to compare all
  422. // the SA entries. Note, the selectors are not compared for SABundles.
  423. //
  424. uint
  425. InboundSALookup(
  426. SecurityPolicy *SP,
  427. SALinkage *SAPerformed)
  428. {
  429. SecurityAssociation *SA;
  430. uint Result = FALSE;
  431. for (SA = SP->InboundSA; SA != NULL; SA = SA->ChainedSecAssoc) {
  432. if (SA == SAPerformed->This && SA->DirectionFlag == INBOUND) {
  433. //
  434. // Check if the SP entry is a bundle.
  435. //
  436. if (SP->SABundle != NULL && SAPerformed->Next != NULL) {
  437. // Recursive call.
  438. if (InboundSALookup(SP->SABundle, SAPerformed->Next)) {
  439. Result = TRUE;
  440. break;
  441. }
  442. } else if (SP->SABundle == NULL && SAPerformed->Next == NULL) {
  443. // Found a match and no bundle to check.
  444. if (SA->Valid == SA_VALID) {
  445. Result = TRUE;
  446. } else {
  447. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_RARE,
  448. "InboundSALookup: Invalid SA\n"));
  449. }
  450. break;
  451. } else {
  452. // SAs in packet disagree with SABundle so no match.
  453. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_RARE,
  454. "InboundSALookup: SA seen disagrees with SA "
  455. "in SABundle\n"));
  456. break;
  457. }
  458. }
  459. }
  460. return Result;
  461. }
  462. //* InboundSecurityCheck - IPSec processing verification.
  463. //
  464. // This function is called from the transport layer. The policy selectors
  465. // are compared with the packet to find a match. The search continues
  466. // until there is a match.
  467. //
  468. // The RFC says that the inbound SPD does not need to be ordered.
  469. // However if that is the case, then Bypass and discard mode couldn't
  470. // be used to quickly handle a packet. Also since most of the SPs are
  471. // bidirectional, the SP entries are ordered. We require the administrator
  472. // to order the policies.
  473. //
  474. int
  475. InboundSecurityCheck(
  476. IPv6Packet *Packet,
  477. ushort TransportProtocol,
  478. ushort SourcePort,
  479. ushort DestPort,
  480. Interface *IF)
  481. {
  482. SecurityPolicy *SP;
  483. int Result = FALSE;
  484. KIRQL OldIrql;
  485. //
  486. // Get IPSec lock then get interface lock.
  487. // REVIEW: Do we still need to grab the IF lock here?
  488. //
  489. KeAcquireSpinLock(&IPSecLock, &OldIrql);
  490. KeAcquireSpinLockAtDpcLevel(&IF->Lock);
  491. for (SP = SecurityPolicyList; SP != NULL; SP = SP->Next) {
  492. // Check Interface.
  493. if ((SP->IFIndex != 0) && (SP->IFIndex != IF->Index))
  494. continue;
  495. // Check Direction of SP.
  496. if (!(SP->DirectionFlag == INBOUND ||
  497. SP->DirectionFlag == BIDIRECTIONAL)) {
  498. continue;
  499. }
  500. // Check Remote Address.
  501. if (!SPCheckAddr(AlignAddr(&Packet->IP->Source), SP->RemoteAddrField,
  502. &SP->RemoteAddr, &SP->RemoteAddrData)) {
  503. continue;
  504. }
  505. // Check Local Address.
  506. if (!SPCheckAddr(AlignAddr(&Packet->IP->Dest), SP->LocalAddrField,
  507. &SP->LocalAddr, &SP->LocalAddrData)) {
  508. continue;
  509. }
  510. // Check Transport Protocol.
  511. if (SP->TransportProto == NONE) {
  512. // None so protocol passed.
  513. } else {
  514. if (SP->TransportProto != TransportProtocol) {
  515. continue;
  516. } else {
  517. // Check Remote Port.
  518. if (!SPCheckPort(SourcePort, SP->RemotePortField,
  519. SP->RemotePort, SP->RemotePortData)) {
  520. continue;
  521. }
  522. // Check Local Port.
  523. if (!SPCheckPort(DestPort, SP->LocalPortField,
  524. SP->LocalPort, SP->LocalPortData)) {
  525. continue;
  526. }
  527. }
  528. }
  529. // Check if the packet should be dropped.
  530. if (SP->SecPolicyFlag == IPSEC_DISCARD) {
  531. //
  532. // Packet is dropped by transport layer.
  533. // This essentially denies traffic.
  534. //
  535. break;
  536. }
  537. // Check if packet bypassed IPSec processing.
  538. if (Packet->SAPerformed == NULL) {
  539. //
  540. // Check if this is bypass mode.
  541. //
  542. if (SP->SecPolicyFlag == IPSEC_BYPASS) {
  543. // Packet is okay to be processed by transport layer.
  544. Result = TRUE;
  545. break;
  546. }
  547. // Check other policies, may change this to dropping later.
  548. continue;
  549. }
  550. //
  551. // Getting here means the packet saw an SA.
  552. //
  553. // Check IPSec mode.
  554. if (SP->IPSecSpec.Mode != Packet->SAPerformed->Mode) {
  555. //
  556. // Wrong mode for this traffic drop packet.
  557. //
  558. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  559. "InboundSecurityCheck: Wrong IPSec mode for traffic "
  560. "Policy #%d\n", SP->Index));
  561. break;
  562. }
  563. // Check SA pointer.
  564. if (!InboundSALookup(SP, Packet->SAPerformed)) {
  565. //
  566. // SA lookup failed.
  567. //
  568. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  569. "InboundSecurityCheck: SA lookup failed Policy #%d\n",
  570. SP->Index));
  571. break;
  572. }
  573. // Successful verification of IPSec.
  574. Result = TRUE;
  575. break;
  576. }
  577. // Release locks.
  578. KeReleaseSpinLockFromDpcLevel(&IF->Lock);
  579. KeReleaseSpinLock(&IPSecLock, OldIrql);
  580. return Result;
  581. }
  582. //* OutboundSALookup - Find a SA for the matching SP.
  583. //
  584. // This function is called after an SP match is found. The SAs associated
  585. // with the SP are searched for a match. If match is found, a check to see
  586. // if the SP contains a bundle is done. A bundle causes a similar lookup.
  587. // If any of the bundle SAs are not found, the lookup is a failure.
  588. //
  589. IPSecProc *
  590. OutboundSALookup(
  591. IPv6Addr *SourceAddr,
  592. IPv6Addr *DestAddr,
  593. ushort TransportProtocol,
  594. ushort DestPort,
  595. ushort SourcePort,
  596. SecurityPolicy *SP,
  597. uint *Action)
  598. {
  599. SecurityAssociation *SA;
  600. uint i;
  601. uint BundleCount = 0;
  602. IPSecProc *IPSecToDo = NULL;
  603. *Action = LOOKUP_DROP;
  604. //
  605. // Find the SA entry associated with the found SP entry.
  606. // If there is a bundle, a subsequent search finds the bundled SAs.
  607. //
  608. for (SA = SP->OutboundSA; SA != NULL; SA = SA->ChainedSecAssoc) {
  609. if (SP->RemoteAddrSelector == PACKET_SELECTOR) {
  610. // Check Remote Address.
  611. if (!IP6_ADDR_EQUAL(DestAddr, &SA->DestAddr)) {
  612. continue;
  613. }
  614. }
  615. if (SP->LocalAddrSelector == PACKET_SELECTOR) {
  616. // Check Remote Address.
  617. if (!IP6_ADDR_EQUAL(SourceAddr, &SA->SrcAddr)) {
  618. continue;
  619. }
  620. }
  621. if (SP->RemotePortSelector == PACKET_SELECTOR) {
  622. if (DestPort != SA->DestPort) {
  623. continue;
  624. }
  625. }
  626. if (SP->LocalPortSelector == PACKET_SELECTOR) {
  627. if (SourcePort != SA->SrcPort) {
  628. continue;
  629. }
  630. }
  631. if (SP->TransportProtoSelector == PACKET_SELECTOR) {
  632. if (TransportProtocol != SA->TransportProto) {
  633. continue;
  634. }
  635. }
  636. // Check if the SA is valid.
  637. if (SA->Valid != SA_VALID) {
  638. // SA is invalid continue checking.
  639. continue;
  640. }
  641. //
  642. // Match found.
  643. //
  644. #ifdef IPSEC_DEBUG
  645. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_IPSEC,
  646. "Send using SP->Index=%d, SA->Index=%d\n",
  647. SP->Index, SA->Index));
  648. #endif
  649. BundleCount = SP->NestCount;
  650. // Allocate the IPSecToDo array.
  651. IPSecToDo = ExAllocatePool(NonPagedPool,
  652. (sizeof *IPSecToDo) * BundleCount);
  653. if (IPSecToDo == NULL) {
  654. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  655. "OutboundSALookup: "
  656. "Couldn't allocate memory for IPSecToDo!?!\n"));
  657. return NULL;
  658. }
  659. //
  660. // Fill in IPSecToDo first entry.
  661. //
  662. IPSecToDo[0].SA = SA;
  663. AddRefSA(SA);
  664. IPSecToDo[0].Mode = SP->IPSecSpec.Mode;
  665. IPSecToDo[0].BundleSize = SP->NestCount;
  666. *Action = LOOKUP_CONT;
  667. break;
  668. } // end of for (SA = SP->OutboundSA; ...)
  669. // Check if there is a bundled SA.
  670. for (i = 1; i < BundleCount; i++) {
  671. *Action = LOOKUP_DROP;
  672. // Check to make sure the bundle pointer is not null (safety check).
  673. if (SP->SABundle == NULL) {
  674. // This is bad so exit loop.
  675. // Free IPSecToDo memory.
  676. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INTERNAL_ERROR,
  677. "OutboundSALookup: SP entry %d SABundle pointer is "
  678. "NULL\n", SP->Index));
  679. FreeIPSecToDo(IPSecToDo, i);
  680. break;
  681. }
  682. SP = SP->SABundle;
  683. // Search through the SAs for this SP.
  684. for (SA = SP->OutboundSA; SA != NULL; SA = SA->ChainedSecAssoc) {
  685. if (SP->RemoteAddrSelector == PACKET_SELECTOR) {
  686. // Check Remote Address.
  687. if (!IP6_ADDR_EQUAL(DestAddr, &SA->DestAddr)) {
  688. continue;
  689. }
  690. }
  691. if (SP->LocalAddrSelector == PACKET_SELECTOR) {
  692. // Check Remote Address.
  693. if (!IP6_ADDR_EQUAL(SourceAddr, &SA->SrcAddr)) {
  694. continue;
  695. }
  696. }
  697. if (SP->RemotePortSelector == PACKET_SELECTOR) {
  698. if (DestPort != SA->DestPort) {
  699. continue;
  700. }
  701. }
  702. if (SP->LocalPortSelector == PACKET_SELECTOR) {
  703. if (SourcePort != SA->SrcPort) {
  704. continue;
  705. }
  706. }
  707. if (SP->TransportProtoSelector == PACKET_SELECTOR) {
  708. if (TransportProtocol != SA->TransportProto) {
  709. continue;
  710. }
  711. }
  712. // Check if the SA is valid.
  713. if (SA->Valid != SA_VALID) {
  714. // SA is invalid continue checking.
  715. continue;
  716. }
  717. //
  718. // Match found.
  719. //
  720. #ifdef IPSEC_DEBUG
  721. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_IPSEC,
  722. "Send using SP->Index=%d, SA->Index=%d\n",
  723. SP->Index, SA->Index));
  724. #endif
  725. //
  726. // Fill in IPSecToDo entry.
  727. //
  728. IPSecToDo[i].SA = SA;
  729. AddRefSA(SA);
  730. IPSecToDo[i].Mode = SP->IPSecSpec.Mode;
  731. IPSecToDo[i].BundleSize = SP->NestCount;
  732. *Action = LOOKUP_CONT;
  733. break;
  734. } // end of for (SA = SP->OutboundSA; ...)
  735. // Check if the match was found.
  736. if (*Action == LOOKUP_DROP) {
  737. // No match so free IPSecToDo memory.
  738. FreeIPSecToDo(IPSecToDo, i);
  739. break;
  740. }
  741. } // end of for (i = 1; ...)
  742. return IPSecToDo;
  743. }
  744. //* OutboundSPLookup - Do the IPSec processing associated with an outbound SP.
  745. //
  746. // This function is called from the transport layer to find an appropriate
  747. // SA or SABundle associated with the traffic. The Outbound SPD is sorted
  748. // so the first SP found is for this traffic.
  749. //
  750. IPSecProc *
  751. OutboundSPLookup(
  752. IPv6Addr *SourceAddr, // Source Address.
  753. IPv6Addr *DestAddr, // Destination Address.
  754. ushort TransportProtocol, // Transport Protocol.
  755. ushort SourcePort, // Source Port.
  756. ushort DestPort, // Destination Port.
  757. Interface *IF, // Interface Pointer.
  758. uint *Action) // Action to do.
  759. {
  760. SecurityPolicy *SP;
  761. KIRQL OldIrql;
  762. IPSecProc *IPSecToDo;
  763. IPSecToDo = NULL;
  764. *Action = LOOKUP_DROP;
  765. //
  766. // Get IPSec lock then get interface lock.
  767. // REVIEW: Do we still need to grab the IF lock here?
  768. //
  769. KeAcquireSpinLock(&IPSecLock, &OldIrql);
  770. KeAcquireSpinLockAtDpcLevel(&IF->Lock);
  771. for (SP = SecurityPolicyList; SP != NULL; SP = SP->Next) {
  772. // Check Interface.
  773. if ((SP->IFIndex != 0) && (SP->IFIndex != IF->Index))
  774. continue;
  775. // Check Direction of SP.
  776. if (!(SP->DirectionFlag == OUTBOUND ||
  777. SP->DirectionFlag == BIDIRECTIONAL)) {
  778. continue;
  779. }
  780. // Check Remote Address.
  781. if (!SPCheckAddr(DestAddr, SP->RemoteAddrField,
  782. &SP->RemoteAddr, &SP->RemoteAddrData)) {
  783. continue;
  784. }
  785. // Check Local Address.
  786. if (!SPCheckAddr(SourceAddr, SP->LocalAddrField,
  787. &SP->LocalAddr, &SP->LocalAddrData)) {
  788. continue;
  789. }
  790. // Check Transport Protocol.
  791. if (SP->TransportProto == NONE) {
  792. // None so protocol passed.
  793. } else {
  794. if (SP->TransportProto != TransportProtocol) {
  795. continue;
  796. } else {
  797. // Check Remote Port.
  798. if (!SPCheckPort(DestPort, SP->RemotePortField,
  799. SP->RemotePort, SP->RemotePortData)) {
  800. continue;
  801. }
  802. // Check Local Port.
  803. if (!SPCheckPort(SourcePort, SP->LocalPortField,
  804. SP->LocalPort, SP->LocalPortData)) {
  805. continue;
  806. }
  807. }
  808. }
  809. //
  810. // Check IPSec Action.
  811. //
  812. if (SP->SecPolicyFlag == IPSEC_APPLY) {
  813. // Search for an SA entry that matches.
  814. IPSecToDo = OutboundSALookup(SourceAddr, DestAddr,
  815. TransportProtocol, DestPort,
  816. SourcePort, SP, Action);
  817. if (IPSecToDo == NULL) {
  818. // No SA was found for the outgoing traffic.
  819. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  820. "OutboundSPLookup: No SA found for SP entry %d\n",
  821. SP->Index));
  822. *Action = LOOKUP_DROP;
  823. }
  824. } else {
  825. if (SP->SecPolicyFlag == IPSEC_DISCARD) {
  826. // Packet is dropped.
  827. IPSecToDo = NULL;
  828. *Action = LOOKUP_DROP;
  829. } else {
  830. //
  831. // This is Bypass or "App determines" mode.
  832. // REVIEW: What is the app determine mode?
  833. //
  834. IPSecToDo = NULL;
  835. *Action = LOOKUP_BYPASS;
  836. }
  837. }
  838. break;
  839. }
  840. // Release locks.
  841. KeReleaseSpinLockFromDpcLevel(&IF->Lock);
  842. KeReleaseSpinLock(&IPSecLock, OldIrql);
  843. return IPSecToDo;
  844. }
  845. //* PerformDeferredAHProcessing - Helper for AuthenticationHeaderReceive
  846. //
  847. // This routine handles processing the AH authentication algorithm over
  848. // a given extension header once we know which header logically follows it.
  849. //
  850. void
  851. PerformDeferredAHProcessing(
  852. SecurityAlgorithm *Alg, // Authentication algorithm to use.
  853. void *Context, // Context to use with algorithm.
  854. uchar *Key, // Key to use with algorithm.
  855. uint AmountSkipped, // Size of headers not included in AH validation.
  856. void *Data, // Start of header we're currently processing.
  857. uchar ThisHeader, // Which header we're currently processing.
  858. uchar NextHeader) // Header logically following this one.
  859. {
  860. uint Dummy;
  861. ushort PayloadLength;
  862. switch(ThisHeader) {
  863. case IP_PROTOCOL_V6: {
  864. IPv6Header UNALIGNED *IP = (IPv6Header UNALIGNED *)Data;
  865. //
  866. // REVIEW: Cache IPv6 header so we can give it to Operate as a single
  867. // REVIEW: chunk and avoid all these individual calls? More efficient?
  868. //
  869. // In VersClassFlow, only the IP version is immutable.
  870. Dummy = IP_VERSION;
  871. //
  872. // For non-jumbograms, the payload length needs to be altered to
  873. // reflect the lack of those headers which aren't included in the
  874. // authentication check.
  875. //
  876. PayloadLength = net_short(IP->PayloadLength);
  877. if (PayloadLength != 0) {
  878. PayloadLength = PayloadLength - AmountSkipped;
  879. }
  880. PayloadLength = net_short(PayloadLength);
  881. #ifdef IPSEC_DEBUG
  882. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_IPSEC,
  883. "\nAH Receive Data:\n"));
  884. dump_encoded_mesg((uchar *)&Dummy, 4);
  885. dump_encoded_mesg((uchar *)&PayloadLength, 2);
  886. dump_encoded_mesg((uchar *)&NextHeader, 1);
  887. #endif
  888. (*Alg->Operate)(Context, Key, (uchar *)&Dummy, 4);
  889. (*Alg->Operate)(Context, Key, (uchar *)&PayloadLength, 2);
  890. (*Alg->Operate)(Context, Key, (uchar *)&NextHeader, 1);
  891. Dummy = 0; // Hop Limit is mutable.
  892. #ifdef IPSEC_DEBUG
  893. dump_encoded_mesg((uchar *)&Dummy, 1);
  894. dump_encoded_mesg((uchar *)&IP->Source, 2 * sizeof(IPv6Addr));
  895. #endif
  896. (*Alg->Operate)(Context, Key, (uchar *)&Dummy, 1);
  897. (*Alg->Operate)(Context, Key, (uchar *)&IP->Source,
  898. 2 * sizeof(IPv6Addr));
  899. break;
  900. }
  901. case IP_PROTOCOL_HOP_BY_HOP:
  902. case IP_PROTOCOL_DEST_OPTS: {
  903. IPv6OptionsHeader UNALIGNED *Ext;
  904. uint HdrLen, Amount;
  905. uchar *Start, *Current;
  906. //
  907. // The options headers have the NextHeader field as the first byte.
  908. //
  909. C_ASSERT(FIELD_OFFSET(IPv6OptionsHeader, NextHeader) == 0);
  910. //
  911. // First feed the NextHeader field into the algorithm.
  912. // We use the one that logically follows, not the one in the header.
  913. //
  914. #ifdef IPSEC_DEBUG
  915. dump_encoded_mesg(&NextHeader, 1);
  916. #endif
  917. (*Alg->Operate)(Context, Key, &NextHeader, 1);
  918. //
  919. // Now feed the rest of this header into the algorithm.
  920. // This includes the remainder of the base header and any
  921. // non-mutable options. For mutable options, we feed the
  922. // algorithm with the equivalent number of zeroes.
  923. //
  924. Ext = (IPv6OptionsHeader UNALIGNED *)Data;
  925. HdrLen = (Ext->HeaderExtLength + 1) * EXT_LEN_UNIT;
  926. Start = (uchar *)Data + 1;
  927. Current = (uchar *)Data + sizeof(IPv6OptionsHeader);
  928. HdrLen -= sizeof(IPv6OptionsHeader);
  929. while (HdrLen) {
  930. if (*Current == OPT6_PAD_1) {
  931. //
  932. // This is the special one byte pad option. Immutable.
  933. //
  934. Current++;
  935. HdrLen--;
  936. continue;
  937. }
  938. if ((*Current == OPT6_JUMBO_PAYLOAD) && (AmountSkipped != 0 )) {
  939. //
  940. // Special case for jumbo payload option where we have to
  941. // update the payload length to reflect skipped headers.
  942. //
  943. //
  944. // First feed in everything up to the option data.
  945. //
  946. Amount = (uint)(Current - Start) + sizeof(OptionHeader);
  947. #ifdef IPSEC_DEBUG
  948. dump_encoded_mesg(Start, Amount);
  949. #endif
  950. (*Alg->Operate)(Context, Key, Start, Amount);
  951. //
  952. // Adjust the payload length before feeding it in.
  953. //
  954. Current += sizeof(OptionHeader);
  955. Dummy = net_long(net_long(*(ulong *)Current) - AmountSkipped);
  956. #ifdef IPSEC_DEBUG
  957. dump_encoded_mesg((uchar *)&Dummy, 4);
  958. #endif
  959. (*Alg->Operate)(Context, Key, (uchar *)&Dummy, 4);
  960. HdrLen -= sizeof(OptionHeader) + sizeof(ulong);
  961. Current += sizeof(ulong);
  962. Start = Current;
  963. continue;
  964. }
  965. if (OPT6_ISMUTABLE(*Current)) {
  966. //
  967. // This option's data is mutable. Everything preceeding
  968. // the option data is not.
  969. //
  970. Amount = (uint)(Current - Start) + 2; // Immutable amount.
  971. #ifdef IPSEC_DEBUG
  972. dump_encoded_mesg(Start, Amount);
  973. #endif
  974. (*Alg->Operate)(Context, Key, Start, Amount);
  975. Current++; // Now on option data length byte.
  976. Amount = *Current; // Mutable amount.
  977. #ifdef IPSEC_DEBUG
  978. dump_encoded_mesg(Zero, Amount);
  979. #endif
  980. (*Alg->Operate)(Context, Key, Zero, Amount);
  981. HdrLen -= Amount + 2;
  982. Current += Amount + 1;
  983. Start = Current;
  984. } else {
  985. //
  986. // This option's data is not mutable.
  987. // Just skip over it.
  988. //
  989. Current++; // Now on option data length byte.
  990. Amount = *Current;
  991. HdrLen -= Amount + 2;
  992. Current += Amount + 1;
  993. }
  994. }
  995. if (Start != Current) {
  996. //
  997. // Option block ends with an immutable region.
  998. //
  999. Amount = (uint)(Current - Start);
  1000. #ifdef IPSEC_DEBUG
  1001. dump_encoded_mesg(Start, Amount);
  1002. #endif
  1003. (*Alg->Operate)(Context, Key, Start, Amount);
  1004. }
  1005. break;
  1006. }
  1007. case IP_PROTOCOL_ROUTING: {
  1008. IPv6RoutingHeader UNALIGNED *Route;
  1009. uint HdrLen;
  1010. //
  1011. // The routing header has the NextHeader field as the first byte.
  1012. //
  1013. C_ASSERT(FIELD_OFFSET(IPv6RoutingHeader, NextHeader) == 0);
  1014. //
  1015. // First feed the NextHeader field into the algorithm.
  1016. // We use the one that logically follows, not the one in the header.
  1017. //
  1018. #ifdef IPSEC_DEBUG
  1019. dump_encoded_mesg(&NextHeader, 1);
  1020. #endif
  1021. (*Alg->Operate)(Context, Key, &NextHeader, 1);
  1022. //
  1023. // Now feed the rest of this header into the algorithm.
  1024. // It's all immutable.
  1025. //
  1026. Route = (IPv6RoutingHeader UNALIGNED *)Data;
  1027. HdrLen = ((Route->HeaderExtLength + 1) * EXT_LEN_UNIT) - 1;
  1028. ((uchar *)Data)++;
  1029. #ifdef IPSEC_DEBUG
  1030. dump_encoded_mesg(Data, HdrLen);
  1031. #endif
  1032. (*Alg->Operate)(Context, Key, Data, HdrLen);
  1033. break;
  1034. }
  1035. default:
  1036. //
  1037. // Unrecognized header.
  1038. // The only way this can happen is if somebody later adds code
  1039. // to AuthenticationHeaderReceive to call this function for a
  1040. // new header and neglects to add corresponding support here.
  1041. //
  1042. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  1043. "PerformDeferredAHProcessing: "
  1044. "Unsupported header = %d\n",
  1045. ThisHeader));
  1046. ABORT();
  1047. }
  1048. }
  1049. //* AuthenticationHeaderReceive - Handle an IPv6 AH header.
  1050. //
  1051. // This is the routine called to process an Authentication Header,
  1052. // next header value of 51.
  1053. //
  1054. uchar
  1055. AuthenticationHeaderReceive(
  1056. IPv6Packet *Packet) // Packet handed to us by IPv6Receive.
  1057. {
  1058. AHHeader UNALIGNED *AH;
  1059. SecurityAssociation *SA;
  1060. SecurityAlgorithm *Alg;
  1061. uint ResultSize, AHHeaderLen;
  1062. void *Context;
  1063. uchar *Result, *AuthData;
  1064. SALinkage *SAPerformed;
  1065. uint SavePosition;
  1066. void *SaveData;
  1067. uint SaveContigSize;
  1068. uint SaveTotalSize;
  1069. void *SaveAuxList = NULL;
  1070. uchar NextHeader, DeferredHeader;
  1071. void *DeferredData;
  1072. uint Done;
  1073. //
  1074. // Verify that we have enough contiguous data to overlay an Authentication
  1075. // Header structure on the incoming packet. Then do so and skip over it.
  1076. //
  1077. if (! PacketPullup(Packet, sizeof(AHHeader), 1, 0)) {
  1078. // Pullup failed.
  1079. if (Packet->TotalSize < sizeof(AHHeader))
  1080. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  1081. "AuthenticationHeaderReceive: Incoming packet too small"
  1082. " to contain authentication header\n"));
  1083. return IP_PROTOCOL_NONE; // Drop packet.
  1084. }
  1085. AH = (AHHeader UNALIGNED *)Packet->Data;
  1086. // Remember offset to this header's NextHeader field.
  1087. Packet->NextHeaderPosition = Packet->Position +
  1088. FIELD_OFFSET(AHHeader, NextHeader);
  1089. AdjustPacketParams(Packet, sizeof(AHHeader));
  1090. //
  1091. // Lookup Security Association in the Security Association Database.
  1092. //
  1093. SA = InboundSAFind(net_long(AH->SPI),
  1094. AlignAddr(&Packet->IP->Dest),
  1095. IP_PROTOCOL_AH);
  1096. if (SA == NULL) {
  1097. // No SA exists for this packet.
  1098. // Drop packet. NOTE: This is an auditable event.
  1099. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  1100. "AuthenticationHeaderReceive: "
  1101. "No matching SA in database\n"));
  1102. return IP_PROTOCOL_NONE;
  1103. }
  1104. //
  1105. // Verify the Sequence Number if required to do so by the SA.
  1106. // Since we only support manual keying currently, we treat all SAs
  1107. // as not requiring this check.
  1108. // TBD: Will need to change this when we add support for dynamic
  1109. // TBD: keying (IKE).
  1110. //
  1111. //
  1112. // Perform Integrity check.
  1113. //
  1114. // First ensure that the amount of Authentication Data claimed to exist
  1115. // in this packet by the AH header's PayloadLen field is large enough to
  1116. // contain the amount that is required by the algorithm specified in the
  1117. // SA. Note that the former may contain padding to make it a multiple
  1118. // of 32 bits. Then check the packet size to ensure that it is big
  1119. // enough to hold what the header claims is present.
  1120. //
  1121. AHHeaderLen = (AH->PayloadLen + 2) * 4;
  1122. if (AHHeaderLen < sizeof (AHHeader)) {
  1123. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  1124. "AuthenticationHeaderReceive: Bogus AH header length\n"));
  1125. goto ErrorReturn;
  1126. }
  1127. AHHeaderLen -= sizeof(AHHeader); // May include padding.
  1128. Alg = &AlgorithmTable[SA->AlgorithmId];
  1129. ResultSize = Alg->ResultSize; // Does not include padding.
  1130. if (ResultSize > AHHeaderLen) {
  1131. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  1132. "AuthenticationHeaderReceive: Incoming packet's AHHeader"
  1133. " length inconsistent with algorithm's AuthData size\n"));
  1134. goto ErrorReturn;
  1135. }
  1136. if (! PacketPullup(Packet, AHHeaderLen, 1, 0)) {
  1137. // Pullup failed.
  1138. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  1139. "AuthenticationHeaderReceive: Incoming packet too small"
  1140. " to contain authentication data\n"));
  1141. goto ErrorReturn;
  1142. }
  1143. AuthData = (uchar *)Packet->Data;
  1144. AdjustPacketParams(Packet, AHHeaderLen);
  1145. //
  1146. // AH authenticates everything (expect mutable fields) starting from
  1147. // the previous IPv6 header. Stash away our current position (so we can
  1148. // restore it later) and backup to the previous IPv6 header.
  1149. //
  1150. SavePosition = Packet->Position;
  1151. SaveData = Packet->Data;
  1152. SaveContigSize = Packet->ContigSize;
  1153. SaveTotalSize = Packet->TotalSize;
  1154. SaveAuxList = Packet->AuxList;
  1155. PositionPacketAt(Packet, Packet->IPPosition);
  1156. Packet->AuxList = NULL;
  1157. //
  1158. // Initialize this particular algorithm.
  1159. //
  1160. Context = alloca(Alg->ContextSize);
  1161. (*Alg->Initialize)(Context, SA->Key);
  1162. //
  1163. // Run algorithm over packet data. We start with the IP header that
  1164. // encapsulates this AH header. We proceed through the end of the
  1165. // packet, skipping over certain headers which are not part of the
  1166. // logical packet being secured. We also treat any mutable fields
  1167. // as zero for the purpose of the algorithm calculation.
  1168. //
  1169. // Note: We only search for mutable fields in Destination Options
  1170. // headers that appear before this AH header. While the spec doesn't
  1171. // explicitly spell this out anywhere, this is the behavior that makes
  1172. // the most sense and we've verified this interpretation in the working
  1173. // group. However, because of this, our interpretation fails a TAHI test.
  1174. // TAHI will hopefully fix their test, if they haven't already.
  1175. //
  1176. //
  1177. // Start by pulling up the IP header and seeing which header physically
  1178. // follows it.
  1179. //
  1180. if (! PacketPullup(Packet, sizeof(IPv6Header),
  1181. __builtin_alignof(IPv6Addr), 0)) {
  1182. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  1183. "AuthenticationHeaderReceive: Out of memory!?!\n"));
  1184. goto ErrorReturn;
  1185. }
  1186. NextHeader = Packet->IP->NextHeader;
  1187. //
  1188. // Defer processing of this header until after we've determined
  1189. // whether or not we'll be skipping the following header. This allows us
  1190. // to use the correct NextHeader field value when running the algorithm.
  1191. //
  1192. DeferredHeader = IP_PROTOCOL_V6;
  1193. DeferredData = Packet->Data;
  1194. AdjustPacketParams(Packet, sizeof(IPv6Header));
  1195. //
  1196. // Continue over the various extension headers until we reach the
  1197. // AH header for which we're running this authentication algoritm.
  1198. // We've already parsed this far, so we know these headers are legit.
  1199. //
  1200. for (Done = FALSE; !Done;) {
  1201. switch (NextHeader) {
  1202. case IP_PROTOCOL_HOP_BY_HOP:
  1203. case IP_PROTOCOL_DEST_OPTS: {
  1204. IPv6OptionsHeader *Ext;
  1205. uint HdrLen;
  1206. //
  1207. // These headers are not skipped, so process the header
  1208. // logically preceeding this one. Its NextHeader field
  1209. // will contain the Protocol value for this header.
  1210. //
  1211. PerformDeferredAHProcessing(Alg, Context, SA->Key,
  1212. Packet->SkippedHeaderLength,
  1213. DeferredData, DeferredHeader,
  1214. NextHeader);
  1215. //
  1216. // Remember this header for deferred processing.
  1217. //
  1218. DeferredHeader = NextHeader;
  1219. //
  1220. // Get the extension header and all the options pulled up
  1221. // into one nice contiguous chunk.
  1222. //
  1223. if (! PacketPullup(Packet, sizeof(ExtensionHeader),
  1224. __builtin_alignof(ExtensionHeader), 0)) {
  1225. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  1226. "AuthenticationHeaderReceive: "
  1227. "Out of mem!?!\n"));
  1228. goto ErrorReturn;
  1229. }
  1230. Ext = (IPv6OptionsHeader *)Packet->Data;
  1231. NextHeader = Ext->NextHeader;
  1232. HdrLen = (Ext->HeaderExtLength + 1) * EXT_LEN_UNIT;
  1233. if (! PacketPullup(Packet, HdrLen, 1, 0)) {
  1234. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  1235. "AuthenticationHeaderReceive: "
  1236. "Out of mem!?!\n"));
  1237. goto ErrorReturn;
  1238. }
  1239. //
  1240. // Remember where this header starts for deferred processing.
  1241. //
  1242. DeferredData = Packet->Data;
  1243. AdjustPacketParams(Packet, HdrLen);
  1244. break;
  1245. }
  1246. case IP_PROTOCOL_ROUTING: {
  1247. IPv6RoutingHeader *Route;
  1248. uint HdrLen;
  1249. //
  1250. // This header is not skipped, so process the header
  1251. // logically preceeding this one. Its NextHeader field
  1252. // will contain the Protocol value for this header.
  1253. //
  1254. PerformDeferredAHProcessing(Alg, Context, SA->Key,
  1255. Packet->SkippedHeaderLength,
  1256. DeferredData, DeferredHeader,
  1257. IP_PROTOCOL_ROUTING);
  1258. //
  1259. // Remember this header for deferred processing.
  1260. //
  1261. DeferredHeader = IP_PROTOCOL_ROUTING;
  1262. //
  1263. // Get the extension header and all the options pulled up
  1264. // into one nice contiguous chunk.
  1265. //
  1266. if (! PacketPullup(Packet, sizeof(IPv6RoutingHeader),
  1267. __builtin_alignof(IPv6RoutingHeader), 0)) {
  1268. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  1269. "AuthenticationHeaderReceive: "
  1270. "Out of mem!?!\n"));
  1271. goto ErrorReturn;
  1272. }
  1273. Route = (IPv6RoutingHeader *)Packet->Data;
  1274. NextHeader = Route->NextHeader;
  1275. HdrLen = (Route->HeaderExtLength + 1) * EXT_LEN_UNIT;
  1276. if (! PacketPullup(Packet, HdrLen, 1, 0)) {
  1277. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  1278. "AuthenticationHeaderReceive: "
  1279. "Out of mem!?!\n"));
  1280. goto ErrorReturn;
  1281. }
  1282. //
  1283. // Remember where this header starts for deferred processing.
  1284. //
  1285. DeferredData = Packet->Data;
  1286. AdjustPacketParams(Packet, HdrLen);
  1287. break;
  1288. }
  1289. case IP_PROTOCOL_AH: {
  1290. //
  1291. // We don't know yet whether we'll be including this AH header
  1292. // in the algorithm calculation we're currently running.
  1293. // See below.
  1294. //
  1295. AHHeader UNALIGNED *ThisAH;
  1296. uint ThisHdrLen;
  1297. uint Padding;
  1298. //
  1299. // Pullup the AH header.
  1300. //
  1301. if (! PacketPullup(Packet, sizeof(AHHeader), 1, 0)) {
  1302. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  1303. "AuthenticationHeaderReceive: "
  1304. "Out of mem!?!\n"));
  1305. goto ErrorReturn;
  1306. }
  1307. ThisAH = (AHHeader UNALIGNED *)Packet->Data;
  1308. AdjustPacketParams(Packet, sizeof(AHHeader));
  1309. ThisHdrLen = ((ThisAH->PayloadLen + 2) * 4) - sizeof(AHHeader);
  1310. if (! PacketPullup(Packet, ThisHdrLen, 1, 0)) {
  1311. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  1312. "AuthenticationHeaderReceive: "
  1313. "Out of mem!?!\n"));
  1314. goto ErrorReturn;
  1315. }
  1316. AdjustPacketParams(Packet, ThisHdrLen);
  1317. //
  1318. // If this is another AH header encapsulating the one we are
  1319. // currently processing, then don't include it in the integrity
  1320. // check as per AH spec section 3.3.
  1321. //
  1322. if (Packet->Position != SavePosition) {
  1323. NextHeader = ThisAH->NextHeader;
  1324. break;
  1325. }
  1326. //
  1327. // Otherwise this is the AH header that we're currently processing,
  1328. // and we include it in its own integrity check. But first we
  1329. // need to process the header logically preceeding this one (which
  1330. // we previously defered). Its NextHeader field will contain the
  1331. // Protocol value for this header.
  1332. //
  1333. PerformDeferredAHProcessing(Alg, Context, SA->Key,
  1334. Packet->SkippedHeaderLength,
  1335. DeferredData, DeferredHeader,
  1336. IP_PROTOCOL_AH);
  1337. //
  1338. // Now process this AH header. We do not need to defer processing
  1339. // of this header, since everything following it is included in
  1340. // the check. The Authentication Data is mutable, the rest of the
  1341. // AH header is not.
  1342. //
  1343. ASSERT(Packet->TotalSize == SaveTotalSize);
  1344. #ifdef IPSEC_DEBUG
  1345. dump_encoded_mesg((uchar *)AH, sizeof(AHHeader));
  1346. #endif
  1347. (*Alg->Operate)(Context, SA->Key, (uchar *)AH, sizeof(AHHeader));
  1348. #ifdef IPSEC_DEBUG
  1349. dump_encoded_mesg(Zero, ResultSize);
  1350. #endif
  1351. (*Alg->Operate)(Context, SA->Key, Zero, ResultSize);
  1352. //
  1353. // The Authentication Data may be padded. This padding is
  1354. // included as non-mutable in the integrity calculation.
  1355. // REVIEW: We should double-check our interpretation of the RFC
  1356. // about this with the IPSec working group.
  1357. //
  1358. Padding = AHHeaderLen - ResultSize;
  1359. if (Padding != 0) {
  1360. #ifdef IPSEC_DEBUG
  1361. dump_encoded_mesg((uchar *)(Packet->Data) - Padding, Padding);
  1362. #endif
  1363. (*Alg->Operate)(Context, SA->Key,
  1364. (uchar *)(Packet->Data) - Padding, Padding);
  1365. }
  1366. Done = TRUE;
  1367. break;
  1368. }
  1369. case IP_PROTOCOL_ESP: {
  1370. //
  1371. // We don't include other IPSec headers in the integrity check
  1372. // as per AH spec section 3.3. So just skip over this. Tricky
  1373. // part is that the NextHeader was in the ESP trailer which we've
  1374. // already thrown away at this point.
  1375. //
  1376. ESPHeader UNALIGNED *ThisESP;
  1377. ulong ThisSPI;
  1378. SALinkage *ThisSAL;
  1379. //
  1380. // Get the SPI out of the ESP header so we can identify its
  1381. // SALinkage entry on the SAPerformed chain. Skip over the
  1382. // ESP header while we're at it.
  1383. //
  1384. if (! PacketPullup(Packet, sizeof(ESPHeader), 1, 0)) {
  1385. // Pullup failed.
  1386. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  1387. "AuthenticationHeaderReceive: Out of mem!?!\n"));
  1388. goto ErrorReturn;
  1389. }
  1390. ThisESP = (ESPHeader UNALIGNED *)Packet->Data;
  1391. AdjustPacketParams(Packet, sizeof(ESPHeader));
  1392. ThisSPI = net_long(ThisESP->SPI);
  1393. //
  1394. // Find the SALinkage entry on the SAPerformed chain with the
  1395. // matching SPI. It must be present.
  1396. // REVIEW: This code assumes we made SPIs system-wide unique.
  1397. //
  1398. for (ThisSAL = Packet->SAPerformed;
  1399. ThisSAL->This->SPI != ThisSPI; ThisSAL = ThisSAL->Next)
  1400. ASSERT(ThisSAL->Next != NULL);
  1401. //
  1402. // Pull NextHeader value out of the SALinkage (where we stashed
  1403. // it back in EncapsulatingSecurityPayloadReceive).
  1404. //
  1405. NextHeader = (uchar)ThisSAL->NextHeader;
  1406. break;
  1407. }
  1408. case IP_PROTOCOL_FRAGMENT: {
  1409. //
  1410. // We normally won't encounter a fragment header here,
  1411. // since reassembly will occur before authentication.
  1412. // However, our implementation optimizes the reassembly of
  1413. // single-fragment packets by leaving the fragment header in
  1414. // place. When performing the authentication calculation,
  1415. // we treat such fragment headers as if they didn't exist.
  1416. //
  1417. FragmentHeader UNALIGNED *Frag;
  1418. if (! PacketPullup(Packet, sizeof(FragmentHeader), 1, 0)) {
  1419. KdPrintEx((DPFLTR_TCPIP_ID, DPFLTR_NTOS_ERROR,
  1420. "AuthenticationHeaderReceive: Out of mem!?\n"));
  1421. goto ErrorReturn;
  1422. }
  1423. Frag = (FragmentHeader UNALIGNED *)Packet->Data;
  1424. NextHeader = Frag->NextHeader;
  1425. AdjustPacketParams(Packet, sizeof(FragmentHeader));
  1426. break;
  1427. }
  1428. default:
  1429. // Unrecognized header.
  1430. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  1431. "AuthenticationHeaderReceive: "
  1432. "Unsupported header = %d\n",
  1433. NextHeader));
  1434. goto ErrorReturn;
  1435. }
  1436. }
  1437. //
  1438. // Everything inside this AH header is treated as immutable.
  1439. //
  1440. // REVIEW: For performance reasons, the ContigSize check could be moved
  1441. // REVIEW: before the loop for the additional code space cost of
  1442. // REVIEW: duplicating the PacketPullup call.
  1443. //
  1444. while (Packet->TotalSize != 0) {
  1445. if (Packet->ContigSize == 0) {
  1446. //
  1447. // Ran out of contiguous data.
  1448. // Get next buffer in packet.
  1449. //
  1450. PacketPullupSubr(Packet, 0, 1, 0); // Moves to next buffer.
  1451. }
  1452. #ifdef IPSEC_DEBUG
  1453. dump_encoded_mesg(Packet->Data, Packet->ContigSize);
  1454. #endif
  1455. (*Alg->Operate)(Context, SA->Key, Packet->Data, Packet->ContigSize);
  1456. AdjustPacketParams(Packet, Packet->ContigSize);
  1457. }
  1458. //
  1459. // Get final result from the algorithm.
  1460. //
  1461. Result = alloca(ResultSize);
  1462. (*Alg->Finalize)(Context, SA->Key, Result);
  1463. #ifdef IPSEC_DEBUG
  1464. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_IPSEC,
  1465. "Recv Key (%d bytes)): ", SA->RawKeyLength));
  1466. DumpKey(SA->RawKey, SA->RawKeyLength);
  1467. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_IPSEC,
  1468. "Recv AuthData:\n"));
  1469. dump_encoded_mesg(Result, ResultSize);
  1470. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_IPSEC,
  1471. "Sent AuthData:\n"));
  1472. dump_encoded_mesg(AuthData, ResultSize);
  1473. #endif
  1474. //
  1475. // Compare result to authentication data in packet. They should match.
  1476. //
  1477. if (RtlCompareMemory(Result, AuthData, ResultSize) != ResultSize) {
  1478. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  1479. "AuthenticationHeaderReceive: Failed integrity check\n"));
  1480. goto ErrorReturn;
  1481. }
  1482. //
  1483. // Restore our packet position (to just after AH Header).
  1484. //
  1485. PacketPullupCleanup(Packet);
  1486. Packet->Position = SavePosition;
  1487. Packet->Data = SaveData;
  1488. Packet->ContigSize = SaveContigSize;
  1489. Packet->TotalSize = SaveTotalSize;
  1490. Packet->AuxList = SaveAuxList;
  1491. SaveAuxList = NULL;
  1492. //
  1493. // Nested AH headers don't include this one in their calculations.
  1494. //
  1495. Packet->SkippedHeaderLength += sizeof(AHHeader) + AHHeaderLen;
  1496. //
  1497. // Add this SA to the list of those that this packet has passed.
  1498. //
  1499. SAPerformed = ExAllocatePool(NonPagedPool, sizeof *SAPerformed);
  1500. if (SAPerformed == NULL) {
  1501. ErrorReturn:
  1502. ReleaseSA(SA);
  1503. if (SaveAuxList != NULL) {
  1504. PacketPullupCleanup(Packet);
  1505. Packet->AuxList = SaveAuxList;
  1506. }
  1507. return IP_PROTOCOL_NONE; // Drop packet.
  1508. }
  1509. SAPerformed->This = SA;
  1510. SAPerformed->Next = Packet->SAPerformed; // This SA is now first on list.
  1511. SAPerformed->Mode = TRANSPORT; // Assume trans until we see an IPv6Header.
  1512. Packet->SAPerformed = SAPerformed;
  1513. return AH->NextHeader;
  1514. }
  1515. //* EncapsulatingSecurityPayloadReceive - Handle an IPv6 ESP header.
  1516. //
  1517. // This is the routine called to process an Encapsulating Security Payload,
  1518. // next header value of 50.
  1519. //
  1520. uchar
  1521. EncapsulatingSecurityPayloadReceive(
  1522. IPv6Packet *Packet) // Packet handed to us by IPv6Receive.
  1523. {
  1524. ESPHeader UNALIGNED *ESP;
  1525. ESPTrailer TrailerBuffer;
  1526. ESPTrailer UNALIGNED *ESPT;
  1527. SecurityAssociation *SA;
  1528. PNDIS_BUFFER NdisBuffer;
  1529. SALinkage *SAPerformed;
  1530. //
  1531. // Verify that we have enough contiguous data to overlay an Encapsulating
  1532. // Security Payload Header structure on the incoming packet. Since the
  1533. // authentication check covers the ESP header, we don't skip over it yet.
  1534. //
  1535. if (! PacketPullup(Packet, sizeof(ESPHeader), 1, 0)) {
  1536. // Pullup failed.
  1537. if (Packet->TotalSize < sizeof(ESPHeader))
  1538. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  1539. "EncapsulatingSecurityPayloadReceive: "
  1540. "Incoming packet too small to contain ESP header\n"));
  1541. return IP_PROTOCOL_NONE; // Drop packet.
  1542. }
  1543. ESP = (ESPHeader UNALIGNED *)Packet->Data;
  1544. //
  1545. // Lookup Security Association in the Security Association Database.
  1546. //
  1547. SA = InboundSAFind(net_long(ESP->SPI),
  1548. AlignAddr(&Packet->IP->Dest),
  1549. IP_PROTOCOL_ESP);
  1550. if (SA == NULL){
  1551. // No SA exists for this packet.
  1552. // Drop packet. NOTE: This is an auditable event.
  1553. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  1554. "EncapsulatingSecurityPayloadReceive: "
  1555. "No SA found for the packet\n"));
  1556. return IP_PROTOCOL_NONE;
  1557. }
  1558. //
  1559. // Verify the Sequence Number if required to do so by the SA.
  1560. // Since we only support manual keying currently, we treat all SAs
  1561. // as not requiring this check.
  1562. // TBD: Will need to change this when we add support for dynamic
  1563. // TBD: keying (IKE).
  1564. //
  1565. //
  1566. // Perform integrity check if authentication has been selected.
  1567. // TBD: When (if?) we add encryption support, we'll want to check the
  1568. // TBD: SA to see if authentication is desired. Hardwired for now.
  1569. //
  1570. {
  1571. SecurityAlgorithm *Alg;
  1572. uint AuthDataSize;
  1573. uint PayloadLength;
  1574. void *Context;
  1575. IPv6Packet Clone;
  1576. uint DoNow = 0;
  1577. uchar *AuthData;
  1578. uchar *Result;
  1579. //
  1580. // First ensure that the incoming packet is large enough to hold the
  1581. // Authentication Data required by the algorithm specified in the SA.
  1582. // Then calculate the amount of data covered by authentication.
  1583. //
  1584. Alg = &AlgorithmTable[SA->AlgorithmId];
  1585. AuthDataSize = Alg->ResultSize;
  1586. if (Packet->TotalSize < sizeof(ESPHeader) + sizeof(ESPTrailer) +
  1587. AuthDataSize) {
  1588. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  1589. "EncapsulatingSecurityPaylofadReceive: "
  1590. "Packet too short to hold Authentication Data\n"));
  1591. goto ErrorReturn;
  1592. }
  1593. PayloadLength = Packet->TotalSize - AuthDataSize;
  1594. //
  1595. // Clone the packet positioning information so we can step through
  1596. // the packet without losing our current place. Start clone with
  1597. // a fresh pullup history, however.
  1598. //
  1599. Clone = *Packet;
  1600. Clone.AuxList = NULL;
  1601. #ifdef IPSEC_DEBUG
  1602. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_IPSEC,
  1603. "\nESP Receive Data:\n"));
  1604. #endif
  1605. //
  1606. // Initialize this particular algorithm.
  1607. //
  1608. Context = alloca(Alg->ContextSize);
  1609. (*Alg->Initialize)(Context, SA->Key);
  1610. //
  1611. // Run algorithm over packet data.
  1612. // ESP authenticates everything beginning with the ESP Header and
  1613. // ending just prior to the Authentication Data.
  1614. //
  1615. while (PayloadLength != 0) {
  1616. DoNow = MIN(PayloadLength, Clone.ContigSize);
  1617. #ifdef IPSEC_DEBUG
  1618. dump_encoded_mesg(Clone.Data, DoNow);
  1619. #endif
  1620. (*Alg->Operate)(Context, SA->Key, Clone.Data, DoNow);
  1621. if (DoNow < PayloadLength) {
  1622. //
  1623. // Not done yet, must have run out of contiguous data.
  1624. // Get next buffer in packet.
  1625. //
  1626. AdjustPacketParams(&Clone, DoNow);
  1627. PacketPullupSubr(&Clone, 0, 1, 0); // Moves to next buffer.
  1628. }
  1629. PayloadLength -= DoNow;
  1630. }
  1631. AdjustPacketParams(&Clone, DoNow);
  1632. //
  1633. // Get final result from the algorithm.
  1634. //
  1635. Result = alloca(AuthDataSize);
  1636. (*Alg->Finalize)(Context, SA->Key, Result);
  1637. #ifdef IPSEC_DEBUG
  1638. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_IPSEC,
  1639. "Calculated AuthData:\n"));
  1640. dump_encoded_mesg(Result, AuthDataSize);
  1641. #endif
  1642. //
  1643. // The Authentication Data immediately follows the region of
  1644. // authentication coverage. So our clone should be positioned
  1645. // at the beginning of it. Ensure that it's contiguous.
  1646. //
  1647. if (! PacketPullup(&Clone, AuthDataSize, 1, 0)) {
  1648. // Pullup failed. Should never happen due to earlier check.
  1649. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  1650. "EncapsulatingSecurityPayloadReceive: "
  1651. "Incoming packet too small for Auth Data\n"));
  1652. goto ErrorReturn;
  1653. }
  1654. // Point to Authentication data.
  1655. AuthData = Clone.Data;
  1656. #ifdef IPSEC_DEBUG
  1657. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_IPSEC,
  1658. "Received AuthData:\n"));
  1659. dump_encoded_mesg(AuthData, AuthDataSize);
  1660. #endif
  1661. //
  1662. // Compare our result to the Authentication Data. They should match.
  1663. //
  1664. if (RtlCompareMemory(Result, AuthData, AuthDataSize) != AuthDataSize) {
  1665. //
  1666. // Integrity check failed. NOTE: This is an auditable event.
  1667. //
  1668. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  1669. "EncapsulatingSecurityPayloadReceive: "
  1670. "Failed integrity check\n"));
  1671. PacketPullupCleanup(&Clone);
  1672. goto ErrorReturn;
  1673. }
  1674. //
  1675. // Done with the clone, clean up after it.
  1676. //
  1677. PacketPullupCleanup(&Clone);
  1678. //
  1679. // Truncate our packet to no longer include the Authentication Data.
  1680. //
  1681. Packet->TotalSize -= AuthDataSize;
  1682. if (Packet->ContigSize > Packet->TotalSize)
  1683. Packet->ContigSize = Packet->TotalSize;
  1684. }
  1685. //
  1686. // We can consume the ESP Header now since it isn't
  1687. // covered by confidentiality.
  1688. //
  1689. AdjustPacketParams(Packet, sizeof(ESPHeader));
  1690. //
  1691. // Decrypt Packet if confidentiality has been selected.
  1692. // TBD: When (if?) we add encryption support, we'll want to check the
  1693. // TBD: SA to see if encryption is desired. Hardwired for now.
  1694. //
  1695. #if 0
  1696. if (0) {
  1697. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NET_ERROR,
  1698. "EncapsulatingSecurityPayloadReceive: "
  1699. "SA requested confidentiality -- unsupported feature\n"));
  1700. goto ErrorReturn;
  1701. }
  1702. #endif
  1703. //
  1704. // Remove trailer and padding (if any). Note that padding may appear
  1705. // even in the no-encryption case in order to align the Authentication
  1706. // Data on a four byte boundary.
  1707. //
  1708. if (Packet->NdisPacket == NULL) {
  1709. //
  1710. // This packet must be just a single contiguous region.
  1711. // Finding the trailer is a simple matter of arithmetic.
  1712. //
  1713. ESPT = (ESPTrailer UNALIGNED *)
  1714. ((uchar *)Packet->Data + Packet->TotalSize - sizeof(ESPTrailer));
  1715. } else {
  1716. //
  1717. // Need to find the trailer in the Ndis buffer chain.
  1718. //
  1719. NdisQueryPacket(Packet->NdisPacket, NULL, NULL, &NdisBuffer, NULL);
  1720. ESPT = (ESPTrailer UNALIGNED *)
  1721. GetDataFromNdis(NdisBuffer,
  1722. Packet->Position + Packet->TotalSize -
  1723. sizeof(ESPTrailer),
  1724. sizeof(ESPTrailer),
  1725. (uchar *)&TrailerBuffer);
  1726. }
  1727. Packet->TotalSize -= sizeof(ESPTrailer);
  1728. if (ESPT->PadLength > Packet->TotalSize) {
  1729. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_BAD_PACKET,
  1730. "EncapsulatingSecurityPayloadReceive: "
  1731. "PadLength impossibly large (%u of %u bytes)\n",
  1732. ESPT->PadLength, Packet->TotalSize));
  1733. goto ErrorReturn;
  1734. }
  1735. // Remember offset to this header's NextHeader field.
  1736. Packet->NextHeaderPosition = Packet->Position + Packet->TotalSize +
  1737. FIELD_OFFSET(ESPTrailer, NextHeader);
  1738. // Remove padding.
  1739. Packet->TotalSize -= ESPT->PadLength;
  1740. if (Packet->ContigSize > Packet->TotalSize)
  1741. Packet->ContigSize = Packet->TotalSize;
  1742. //
  1743. // Encapsulated AH headers don't include this ESP header when
  1744. // authenticating the packet.
  1745. //
  1746. Packet->SkippedHeaderLength += sizeof(ESPHeader) + sizeof(ESPTrailer) +
  1747. ESPT->PadLength;
  1748. //
  1749. // Add this SA to the list of those that this packet has passed.
  1750. //
  1751. SAPerformed = ExAllocatePool(NonPagedPool, sizeof *SAPerformed);
  1752. if (SAPerformed == NULL) {
  1753. ErrorReturn:
  1754. ReleaseSA(SA);
  1755. return IP_PROTOCOL_NONE; // Drop packet.
  1756. }
  1757. SAPerformed->This = SA;
  1758. SAPerformed->Next = Packet->SAPerformed; // This SA is now first on list.
  1759. SAPerformed->Mode = TRANSPORT; // Assume trans until we see an IPv6Header.
  1760. SAPerformed->NextHeader = ESPT->NextHeader;
  1761. Packet->SAPerformed = SAPerformed;
  1762. return ESPT->NextHeader;
  1763. }
  1764. //* InsertSecurityPolicy
  1765. //
  1766. // Add a security policy to the global list (a.k.a. "SecurityPolicyList").
  1767. // The global list is doubly-linked, ordered by the index value with the
  1768. // higher numbers (more specific policies) first.
  1769. //
  1770. // Called with security lock held.
  1771. //
  1772. int
  1773. InsertSecurityPolicy(
  1774. SecurityPolicy *NewSP) // Policy to insert.
  1775. {
  1776. SecurityPolicy *CurrentSP, *PrevSP;
  1777. //
  1778. // Run through the SP list looking for place to insert.
  1779. //
  1780. CurrentSP = PrevSP = SecurityPolicyList;
  1781. while (CurrentSP != NULL) {
  1782. if (CurrentSP->Index <= NewSP->Index) {
  1783. break;
  1784. }
  1785. // Move down the list.
  1786. PrevSP = CurrentSP;
  1787. CurrentSP = CurrentSP->Next;
  1788. }
  1789. //
  1790. // See where we ended up.
  1791. //
  1792. if (CurrentSP == NULL) {
  1793. //
  1794. // Ran off the end of the list.
  1795. // New entry will become the last element.
  1796. //
  1797. NewSP->Next = NULL;
  1798. } else {
  1799. //
  1800. // Check for duplicate entries.
  1801. //
  1802. if (CurrentSP->Index == NewSP->Index) {
  1803. // A policy with this index value already exists.
  1804. return FALSE;
  1805. }
  1806. //
  1807. // Put new one before 'current'.
  1808. //
  1809. NewSP->Next = CurrentSP;
  1810. NewSP->Prev = CurrentSP->Prev;
  1811. CurrentSP->Prev = NewSP;
  1812. }
  1813. if (CurrentSP == SecurityPolicyList) {
  1814. //
  1815. // Still at the front of the list.
  1816. // New entry becomes new list head.
  1817. //
  1818. NewSP->Prev = NULL;
  1819. SecurityPolicyList = NewSP;
  1820. } else {
  1821. //
  1822. // Add new entry after 'previous'.
  1823. //
  1824. NewSP->Prev = PrevSP;
  1825. PrevSP->Next = NewSP;
  1826. }
  1827. InvalidateSecurityState();
  1828. return TRUE;
  1829. }
  1830. //* InsertSecurityAssociation - Insert SA entry on SecurityAssociationList.
  1831. //
  1832. // Add a security association to the global list.
  1833. // The global list is doubly-linked, ordered by the index value with the
  1834. // higher numbers first.
  1835. // REVIEW: the order is arbitrary - just to look nicer when print out.
  1836. //
  1837. int
  1838. InsertSecurityAssociation(
  1839. SecurityAssociation *NewSA) // Association to insert.
  1840. {
  1841. SecurityAssociation *CurrentSA, *PrevSA;
  1842. //
  1843. // Run through the SA list looking for place to insert.
  1844. //
  1845. CurrentSA = PrevSA = SecurityAssociationList;
  1846. while (CurrentSA != NULL) {
  1847. if (CurrentSA->Index <= NewSA->Index) {
  1848. break;
  1849. }
  1850. // Move down the list.
  1851. PrevSA = CurrentSA;
  1852. CurrentSA = CurrentSA->Next;
  1853. }
  1854. //
  1855. // See where we ended up.
  1856. //
  1857. if (CurrentSA == NULL) {
  1858. //
  1859. // Ran off the end of the list.
  1860. // New entry will become the last element.
  1861. //
  1862. NewSA->Next = NULL;
  1863. } else {
  1864. //
  1865. // Check for duplicate entries.
  1866. //
  1867. if (CurrentSA->Index == NewSA->Index) {
  1868. // An association with this index value already exists.
  1869. return FALSE;
  1870. }
  1871. //
  1872. // Put new one before 'current'.
  1873. //
  1874. NewSA->Next = CurrentSA;
  1875. NewSA->Prev = CurrentSA->Prev;
  1876. CurrentSA->Prev = NewSA;
  1877. }
  1878. if (CurrentSA == SecurityAssociationList) {
  1879. //
  1880. // Still at the front of the list.
  1881. // New entry becomes new list head.
  1882. //
  1883. NewSA->Prev = NULL;
  1884. SecurityAssociationList = NewSA;
  1885. } else {
  1886. //
  1887. // Add new entry after 'previous'.
  1888. //
  1889. NewSA->Prev = PrevSA;
  1890. PrevSA->Next = NewSA;
  1891. }
  1892. InvalidateSecurityState();
  1893. return TRUE;
  1894. }
  1895. //* FindSecurityPolicyMatch - Find matching SP entry.
  1896. //
  1897. // Called with security lock held.
  1898. //
  1899. SecurityPolicy *
  1900. FindSecurityPolicyMatch(
  1901. SecurityPolicy *Start, // Head of list to search.
  1902. uint InterfaceIndex, // Interface number to match, 0 to wildcard.
  1903. uint PolicyIndex) // Policy number to match, 0 to wildcard.
  1904. {
  1905. SecurityPolicy *ThisSP;
  1906. //
  1907. // Search the Security Policy List for a match.
  1908. //
  1909. for (ThisSP = Start; ThisSP != NULL; ThisSP = ThisSP->Next) {
  1910. //
  1911. // Desired policy must be wildcarded or match.
  1912. //
  1913. if ((PolicyIndex != 0) && (PolicyIndex != ThisSP->Index))
  1914. continue;
  1915. //
  1916. // Interface must be wildcarded or match. Note that the policy,
  1917. // as well as the query, may have a wildcarded interface index.
  1918. //
  1919. if ((InterfaceIndex != 0) && (ThisSP->IFIndex != 0) &&
  1920. (InterfaceIndex != ThisSP->IFIndex))
  1921. continue;
  1922. break; // Match.
  1923. }
  1924. return ThisSP;
  1925. }
  1926. //* FindSecurityAssociationMatch - Find SA Entry corresponding to index value.
  1927. //
  1928. // Called with security lock held.
  1929. //
  1930. SecurityAssociation *
  1931. FindSecurityAssociationMatch(
  1932. ulong Index) // Association number to match, 0 to wildcard.
  1933. {
  1934. SecurityAssociation *ThisSA;
  1935. //
  1936. // Search the Security Association List starting with the first SA.
  1937. //
  1938. for (ThisSA = SecurityAssociationList; ThisSA != NULL;
  1939. ThisSA = ThisSA->Next) {
  1940. //
  1941. // Desired association must be wildcarded or match.
  1942. //
  1943. if ((Index == 0) || (Index == ThisSA->Index))
  1944. break;
  1945. }
  1946. return ThisSA;
  1947. }
  1948. //* GetSecurityPolicyIndex - Return SP Index or NONE.
  1949. //
  1950. ulong
  1951. GetSecurityPolicyIndex(
  1952. SecurityPolicy *SP)
  1953. {
  1954. ulong Index = NONE;
  1955. // Get Index from SP.
  1956. if (SP != NULL) {
  1957. Index = SP->Index;
  1958. }
  1959. return Index;
  1960. }
  1961. //* IPSecInit - Initialize the Common SPD.
  1962. //
  1963. int
  1964. IPSecInit(void)
  1965. {
  1966. SecurityPolicy *SP;
  1967. // Allocate memory for Security Policy.
  1968. SP = ExAllocatePool(NonPagedPool, sizeof *SP);
  1969. if (SP == NULL) {
  1970. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  1971. "IPSecInit - couldn't allocate pool for SP!?!\n"));
  1972. return FALSE;
  1973. }
  1974. //
  1975. // Initialize a default common policy that allows everything.
  1976. //
  1977. SP->Next = NULL;
  1978. SP->Prev = NULL;
  1979. SP->RemoteAddrField = WILDCARD_VALUE;
  1980. SP->RemoteAddr = UnspecifiedAddr;
  1981. SP->RemoteAddrData = UnspecifiedAddr;
  1982. SP->RemoteAddrSelector = POLICY_SELECTOR;
  1983. SP->LocalAddrField = WILDCARD_VALUE;
  1984. SP->LocalAddr = UnspecifiedAddr;
  1985. SP->LocalAddrData = UnspecifiedAddr;
  1986. SP->LocalAddrSelector = POLICY_SELECTOR;
  1987. SP->TransportProto = NONE;
  1988. SP->TransportProtoSelector = POLICY_SELECTOR;
  1989. SP->RemotePortField = WILDCARD_VALUE;
  1990. SP->RemotePort = NONE;
  1991. SP->RemotePortData = NONE;
  1992. SP->RemotePortSelector = POLICY_SELECTOR;
  1993. SP->LocalPortField = WILDCARD_VALUE;
  1994. SP->LocalPort = NONE;
  1995. SP->LocalPortData = NONE;
  1996. SP->LocalPortSelector = POLICY_SELECTOR;
  1997. SP->SecPolicyFlag = IPSEC_BYPASS;
  1998. SP->IPSecSpec.Protocol = NONE;
  1999. SP->IPSecSpec.Mode = NONE;
  2000. SP->IPSecSpec.RemoteSecGWIPAddr = UnspecifiedAddr;
  2001. SP->DirectionFlag = BIDIRECTIONAL;
  2002. SP->OutboundSA = NULL;
  2003. SP->InboundSA = NULL;
  2004. SP->SABundle = NULL;
  2005. SP->Index = 1;
  2006. SP->RefCnt = 0;
  2007. SP->IFIndex = 0;
  2008. //
  2009. // Initialize the global Security Policy list with the default policy.
  2010. //
  2011. SecurityPolicyList = SP;
  2012. KeInitializeSpinLock(&IPSecLock);
  2013. //
  2014. // Initialize the security algorithms table.
  2015. //
  2016. AlgorithmsInit();
  2017. return(TRUE);
  2018. }
  2019. //* IPSecUnload
  2020. //
  2021. // Cleanup and prepare for stack unload.
  2022. //
  2023. void
  2024. IPSecUnload(void)
  2025. {
  2026. KIRQL OldIrql;
  2027. // Get Security Lock.
  2028. KeAcquireSpinLock(&IPSecLock, &OldIrql);
  2029. //
  2030. // Delete all the policies on the global Security Policy list.
  2031. // This will take out any associations hanging off them as well.
  2032. //
  2033. while (SecurityPolicyList != NULL) {
  2034. DeleteSP(SecurityPolicyList);
  2035. }
  2036. // Release lock.
  2037. KeReleaseSpinLock(&IPSecLock, OldIrql);
  2038. }
  2039. //* IPSecBytesToInsert
  2040. //
  2041. uint
  2042. IPSecBytesToInsert(
  2043. IPSecProc *IPSecToDo,
  2044. uint *TunnelStart,
  2045. uint *TrailerLength)
  2046. {
  2047. uint i, Padding;
  2048. uint BytesInHeader, BytesToInsert = 0, BytesForTrailer = 0;
  2049. SecurityAlgorithm *Alg;
  2050. SecurityAssociation *SA;
  2051. uint IPSEC_TUNNEL = FALSE;
  2052. for (i = 0; i < IPSecToDo->BundleSize; i++) {
  2053. SA = IPSecToDo[i].SA;
  2054. Alg = &AlgorithmTable[SA->AlgorithmId];
  2055. //
  2056. // Calculate bytes to insert for each IPSec header..
  2057. //
  2058. // Check if this is tunnel or transport mode.
  2059. if (IPSecToDo[i].Mode == TUNNEL) {
  2060. // Outer IPv6 header.
  2061. BytesToInsert += sizeof(IPv6Header);
  2062. if (!IPSEC_TUNNEL) {
  2063. // Set the tunnel start location.
  2064. *TunnelStart = i;
  2065. IPSEC_TUNNEL = TRUE;
  2066. }
  2067. }
  2068. // Check which IPSec protocol.
  2069. if (SA->IPSecProto == IP_PROTOCOL_AH) {
  2070. BytesInHeader = (sizeof(AHHeader) + Alg->ResultSize);
  2071. //
  2072. // The AH header must be a integral multiple of 64 bits in length.
  2073. // Check if padding needs to be added to the ICV result to make
  2074. // the Auth Data field a legitimate length.
  2075. //
  2076. Padding = BytesInHeader % 8;
  2077. if (Padding != 0) {
  2078. BytesInHeader += (8 - Padding);
  2079. }
  2080. ASSERT(BytesInHeader % 8 == 0);
  2081. } else {
  2082. BytesInHeader = sizeof(ESPHeader);
  2083. BytesForTrailer += (sizeof(ESPTrailer) + Alg->ResultSize);
  2084. }
  2085. // Store the byte size of the IPSec header.
  2086. IPSecToDo[i].ByteSize = BytesInHeader;
  2087. // Add the IPSec header size to the total bytes to insert.
  2088. BytesToInsert += BytesInHeader;
  2089. }
  2090. // See if our caller wants the trailer length too.
  2091. if (TrailerLength != NULL)
  2092. *TrailerLength = BytesForTrailer;
  2093. return BytesToInsert;
  2094. }
  2095. //* IPSecInsertHeaders
  2096. //
  2097. uint
  2098. IPSecInsertHeaders(
  2099. uint Mode, // Transport or Tunnel.
  2100. IPSecProc *IPSecToDo,
  2101. uchar **InsertPoint,
  2102. uchar *NewMemory,
  2103. PNDIS_PACKET Packet,
  2104. uint *TotalPacketSize,
  2105. uchar *PrevNextHdr,
  2106. uint TunnelStart,
  2107. uint *BytesInserted,
  2108. uint *NumESPTrailers,
  2109. uint *JUST_ESP)
  2110. {
  2111. uint i, NumHeaders = 0;
  2112. AHHeader *AH;
  2113. ESPHeader *ESP;
  2114. uchar NextHeader;
  2115. uint Padding, j;
  2116. ESPTrailer *ESPTlr;
  2117. PNDIS_BUFFER ESPTlrBuffer;
  2118. uchar *ESPTlrMemory;
  2119. uint ESPTlrBufSize;
  2120. NDIS_STATUS Status;
  2121. SecurityAlgorithm *Alg;
  2122. SecurityAssociation *SA;
  2123. uint Action = LOOKUP_CONT;
  2124. NextHeader = *PrevNextHdr;
  2125. if (Mode == TRANSPORT) {
  2126. i = 0;
  2127. if (TunnelStart != NO_TUNNEL) {
  2128. NumHeaders = TunnelStart;
  2129. } else {
  2130. NumHeaders = IPSecToDo->BundleSize;
  2131. }
  2132. } else {
  2133. // Tunnel.
  2134. i = TunnelStart;
  2135. // Get the end of the tunnels.
  2136. for (j = TunnelStart + 1; j < IPSecToDo->BundleSize; j++) {
  2137. if (IPSecToDo[j].Mode == TUNNEL) {
  2138. // Another tunnel.
  2139. NumHeaders = j;
  2140. break;
  2141. }
  2142. }
  2143. if (NumHeaders == 0) {
  2144. // No other tunnels.
  2145. NumHeaders = IPSecToDo->BundleSize;
  2146. }
  2147. }
  2148. *JUST_ESP = TRUE;
  2149. for (i; i < NumHeaders; i++) {
  2150. SA = IPSecToDo[i].SA;
  2151. if (SA->IPSecProto == IP_PROTOCOL_AH) {
  2152. *JUST_ESP = FALSE;
  2153. // Move insert point up to start of AH Header.
  2154. *InsertPoint -= IPSecToDo[i].ByteSize;
  2155. *BytesInserted += IPSecToDo[i].ByteSize;
  2156. AH = (AHHeader *)(*InsertPoint);
  2157. //
  2158. // Insert AH Header.
  2159. //
  2160. AH->NextHeader = NextHeader;
  2161. // Set previous header's next header field to AH.
  2162. NextHeader = IP_PROTOCOL_AH;
  2163. // Payload length is in 32 bit counts.
  2164. AH->PayloadLen = (IPSecToDo[i].ByteSize / 4) - 2;
  2165. AH->Reserved = 0;
  2166. AH->SPI = net_long(SA->SPI);
  2167. // TBD: Note that when we add support for dynamic keying,
  2168. // TBD: we'll also need to check for sequence number wrap here.
  2169. AH->Seq = net_long(InterlockedIncrement((PLONG)&SA->SequenceNum));
  2170. //
  2171. // Store point where to put AH Auth Data after authentication.
  2172. //
  2173. IPSecToDo[i].AuthData = (*InsertPoint) + sizeof(AHHeader);
  2174. //
  2175. // Zero out Auth Data and padding.
  2176. // The Auth Data value will be filled in later.
  2177. //
  2178. RtlZeroMemory(IPSecToDo[i].AuthData,
  2179. IPSecToDo[i].ByteSize - sizeof(AHHeader));
  2180. } else {
  2181. // ESP.
  2182. Alg = &AlgorithmTable[SA->AlgorithmId];
  2183. // Move insert point up to start of ESP Header.
  2184. *InsertPoint -= IPSecToDo[i].ByteSize;
  2185. *BytesInserted += IPSecToDo[i].ByteSize;
  2186. ESP = (ESPHeader *)(*InsertPoint);
  2187. //
  2188. // Insert ESP Header.
  2189. //
  2190. ESP->SPI = net_long(SA->SPI);
  2191. // TBD: Note that when we add support for dynamic keying,
  2192. // TBD: we'll also need to check for sequence number wrap here.
  2193. ESP->Seq = net_long(InterlockedIncrement((PLONG)&SA->SequenceNum));
  2194. //
  2195. // Compute padding that needs to be added in ESP Trailer.
  2196. // The PadLength and Next header must end of a 4-byte boundary
  2197. // with respect to the start of the IPv6 header.
  2198. // TotalPacketSize is the length of everything in the original
  2199. // packet from the start of the IPv6 header.
  2200. //
  2201. Padding = *TotalPacketSize % 4;
  2202. if (Padding == 0) {
  2203. Padding = 2;
  2204. } else if (Padding == 2) {
  2205. Padding = 0;
  2206. }
  2207. // Adjust total packet size to account for padding.
  2208. *TotalPacketSize += Padding;
  2209. // Where to start the Authentication for this ESP header.
  2210. IPSecToDo[i].Offset = (uint)((*InsertPoint) - NewMemory);
  2211. ESPTlrBufSize = Padding + sizeof(ESPTrailer) + Alg->ResultSize;
  2212. *BytesInserted += ESPTlrBufSize;
  2213. //
  2214. // Allocate ESP Trailer.
  2215. //
  2216. ESPTlrMemory = ExAllocatePool(NonPagedPool, ESPTlrBufSize);
  2217. if (ESPTlrMemory == NULL) {
  2218. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  2219. "InsertTransportIPSec: "
  2220. "Couldn't allocate ESPTlrMemory!?!\n"));
  2221. Action = LOOKUP_DROP;
  2222. break;
  2223. }
  2224. NdisAllocateBuffer(&Status, &ESPTlrBuffer, IPv6BufferPool,
  2225. ESPTlrMemory, ESPTlrBufSize);
  2226. if (Status != NDIS_STATUS_SUCCESS) {
  2227. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR,
  2228. "InsertTransportIPSec: "
  2229. "Couldn't allocate ESP Trailer buffer!?!\n"));
  2230. ExFreePool(ESPTlrMemory);
  2231. Action = LOOKUP_DROP;
  2232. break;
  2233. }
  2234. // Format Padding.
  2235. for (j = 0; j < Padding; j++) {
  2236. // Add padding.
  2237. *(ESPTlrMemory + j) = j + 1;
  2238. }
  2239. ESPTlr = (ESPTrailer *)(ESPTlrMemory + Padding);
  2240. //
  2241. // Format ESP Trailer.
  2242. //
  2243. ESPTlr->PadLength = (uchar)j;
  2244. ESPTlr->NextHeader = NextHeader;
  2245. // Set previous header's next header field to ESP.
  2246. NextHeader = IP_PROTOCOL_ESP;
  2247. //
  2248. // Store pointer of where to put ESP Authentication Data.
  2249. //
  2250. IPSecToDo[i].AuthData = ESPTlrMemory + Padding +
  2251. sizeof(ESPTrailer);
  2252. // Set Authentication Data to 0s (MUTABLE).
  2253. RtlZeroMemory(IPSecToDo[i].AuthData, Alg->ResultSize);
  2254. // Link the ESP trailer to the back of the buffer chain.
  2255. NdisChainBufferAtBack(Packet, ESPTlrBuffer);
  2256. // Increment the number of ESP trailers present.
  2257. *NumESPTrailers += 1;
  2258. } // end of else
  2259. } // end of for (i; i < NumHeaders; i++)
  2260. *PrevNextHdr = NextHeader;
  2261. return Action;
  2262. }
  2263. //* IPSecAdjustMutableFields
  2264. //
  2265. uint
  2266. IPSecAdjustMutableFields(
  2267. uchar *Data,
  2268. IPv6RoutingHeader *SavedRtHdr)
  2269. {
  2270. uint i;
  2271. uchar NextHeader;
  2272. IPv6Header UNALIGNED *IP;
  2273. //
  2274. // Walk original buffer starting at IP header and continuing to the end
  2275. // of the mutable headers, zeroing the mutable fields.
  2276. //
  2277. IP = (IPv6Header UNALIGNED *)Data;
  2278. // In VersClassFlow, only the IP version is immutable, so zero the rest.
  2279. IP->VersClassFlow = IP_VERSION;
  2280. // Hop limit is mutable.
  2281. IP->HopLimit = 0;
  2282. NextHeader = IP->NextHeader;
  2283. Data = (uchar *)(IP + 1);
  2284. //
  2285. // Loop through the original headers. Zero out the mutable fields.
  2286. //
  2287. for (;;) {
  2288. switch (NextHeader) {
  2289. case IP_PROTOCOL_AH:
  2290. case IP_PROTOCOL_ESP:
  2291. // done.
  2292. return LOOKUP_CONT;
  2293. case IP_PROTOCOL_HOP_BY_HOP:
  2294. case IP_PROTOCOL_DEST_OPTS: {
  2295. IPv6OptionsHeader *NewOptHdr;
  2296. uint HdrLen, Amount;
  2297. uchar *Current;
  2298. NewOptHdr = (IPv6OptionsHeader *)Data;
  2299. HdrLen = (NewOptHdr->HeaderExtLength + 1) * EXT_LEN_UNIT;
  2300. Data += HdrLen;
  2301. //
  2302. // Run through options to see if any are mutable.
  2303. //
  2304. Current = (uchar *)NewOptHdr + sizeof(IPv6OptionsHeader);
  2305. HdrLen -= sizeof(IPv6OptionsHeader);
  2306. while (HdrLen) {
  2307. if (*Current == OPT6_PAD_1) {
  2308. //
  2309. // This is the special one byte pad option. Immutable.
  2310. //
  2311. Current++;
  2312. HdrLen--;
  2313. continue;
  2314. }
  2315. if (OPT6_ISMUTABLE(*Current)) {
  2316. //
  2317. // This option's data is mutable. Everything preceeding
  2318. // the option data is not.
  2319. //
  2320. Current++; // Now on option data length byte.
  2321. Amount = *Current; // Mutable amount.
  2322. Current++; // Now on first data byte.
  2323. RtlZeroMemory(Current, Amount);
  2324. HdrLen -= Amount + 2;
  2325. Current += Amount;
  2326. } else {
  2327. //
  2328. // This option's data is not mutable.
  2329. // Just skip over it.
  2330. //
  2331. Current++; // Now on option data length byte.
  2332. Amount = *Current;
  2333. HdrLen -= Amount + 2;
  2334. Current += Amount + 1;
  2335. }
  2336. }
  2337. NextHeader = NewOptHdr->NextHeader;
  2338. break;
  2339. }
  2340. case IP_PROTOCOL_ROUTING: {
  2341. IPv6RoutingHeader *NewRtHdr;
  2342. IPv6Addr *RecvRtAddr, *SendRtAddr;
  2343. // Verify there is a SavedRtHdr.
  2344. if (SavedRtHdr == NULL) {
  2345. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INTERNAL_ERROR,
  2346. "IPSecAdjustMutableFields: "
  2347. "No Saved routing header"));
  2348. return LOOKUP_DROP;
  2349. }
  2350. // Point to the saved first routing address.
  2351. SendRtAddr = (IPv6Addr *)(SavedRtHdr + 1);
  2352. // New buffer routing header.
  2353. NewRtHdr = (IPv6RoutingHeader *)Data;
  2354. // Point to the first routing address.
  2355. RecvRtAddr = (IPv6Addr *)(NewRtHdr + 1);
  2356. NewRtHdr->SegmentsLeft = 0;
  2357. // Copy the IP dest addr to first routing address.
  2358. RtlCopyMemory(RecvRtAddr, &IP->Dest, sizeof(IPv6Addr));
  2359. for (i = 0; i < (uint)(SavedRtHdr->SegmentsLeft - 1); i++) {
  2360. //
  2361. // Copy the routing addresses as they will look
  2362. // at receive.
  2363. //
  2364. RtlCopyMemory(&RecvRtAddr[i+1], &SendRtAddr[i],
  2365. sizeof(IPv6Addr));
  2366. }
  2367. // Copy the last routing address to the IP dest address.
  2368. RtlCopyMemory(&IP->Dest, &SendRtAddr[i], sizeof(IPv6Addr));
  2369. Data += (NewRtHdr->HeaderExtLength + 1) * 8;
  2370. NextHeader = NewRtHdr->NextHeader;
  2371. break;
  2372. }
  2373. default:
  2374. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INTERNAL_ERROR,
  2375. "IPSecAdjustMutableFields: Don't support header %d\n",
  2376. NextHeader));
  2377. return LOOKUP_DROP;
  2378. }// end of switch(NextHeader);
  2379. } // end of for (;;)
  2380. }
  2381. //* IPSecAuthenticatePacket
  2382. //
  2383. void
  2384. IPSecAuthenticatePacket(
  2385. uint Mode,
  2386. IPSecProc *IPSecToDo,
  2387. uchar *InsertPoint,
  2388. uint *TunnelStart,
  2389. uchar *NewMemory,
  2390. uchar *EndNewMemory,
  2391. PNDIS_BUFFER NewBuffer1)
  2392. {
  2393. uchar *Data;
  2394. uint i, NumHeaders = 0, DataLen, j;
  2395. void *Context;
  2396. void *VirtualAddr;
  2397. PNDIS_BUFFER NextBuffer;
  2398. SecurityAlgorithm *Alg;
  2399. SecurityAssociation *SA;
  2400. if (Mode == TRANSPORT) {
  2401. i = 0;
  2402. if (*TunnelStart != NO_TUNNEL) {
  2403. NumHeaders = *TunnelStart;
  2404. } else {
  2405. NumHeaders = IPSecToDo->BundleSize;
  2406. }
  2407. } else {
  2408. // Tunnel.
  2409. i = *TunnelStart;
  2410. // Get the end of the tunnels.
  2411. for (j = *TunnelStart + 1; j < IPSecToDo->BundleSize; j++) {
  2412. if (IPSecToDo[j].Mode == TUNNEL) {
  2413. // Another tunnel.
  2414. NumHeaders = j;
  2415. break;
  2416. }
  2417. }
  2418. if (NumHeaders == 0) {
  2419. // No other tunnels.
  2420. NumHeaders = IPSecToDo->BundleSize;
  2421. }
  2422. // Set TunnelStart for loop in IPv6Send2().
  2423. *TunnelStart = NumHeaders;
  2424. }
  2425. for (i; i < NumHeaders; i++) {
  2426. SA = IPSecToDo[i].SA;
  2427. Alg = &AlgorithmTable[SA->AlgorithmId];
  2428. if (SA->IPSecProto == IP_PROTOCOL_AH) {
  2429. uint FirstIPSecHeader = NumHeaders - 1;
  2430. // AH starts at the IP header.
  2431. Data = InsertPoint;
  2432. //
  2433. // Check if there are other IPSec headers after this in the
  2434. // same IP area (IP_"after"<IP Area>_Data). Other IPSec headers
  2435. // need to be ignored in the authentication calculation.
  2436. // NOTE: This is not a required IPSec header combination.
  2437. //
  2438. if (i < FirstIPSecHeader) {
  2439. uchar *StopPoint;
  2440. uint n;
  2441. n = i + 1;
  2442. //
  2443. // There are some other IPSec headers.
  2444. // Need to authenticate from the IP header to
  2445. // the last header before the first IPSec header hit.
  2446. // Then if there is no ESP, just authenticate from the
  2447. // current IPSec header to the end of the packet.
  2448. // If there is ESP, need to ignore the ESP trailers.
  2449. //
  2450. //
  2451. // Calculate start of first IPSec header.
  2452. //
  2453. if (IPSecToDo[FirstIPSecHeader].SA->IPSecProto ==
  2454. IP_PROTOCOL_AH) {
  2455. StopPoint = (IPSecToDo[FirstIPSecHeader].AuthData -
  2456. sizeof(AHHeader));
  2457. } else {
  2458. StopPoint = NewMemory + IPSecToDo[FirstIPSecHeader].Offset;
  2459. }
  2460. // Length from IP to first IPSec header.
  2461. DataLen = (uint)(StopPoint - Data);
  2462. // Initialize Context.
  2463. Context = alloca(Alg->ContextSize);
  2464. (*Alg->Initialize)(Context, SA->Key);
  2465. // Authentication to the first IPSec header.
  2466. (*Alg->Operate)(Context, SA->Key, Data, DataLen);
  2467. // Set the data start to the current IPSec header.
  2468. Data = IPSecToDo[i].AuthData - sizeof(AHHeader);
  2469. DataLen = (uint)(EndNewMemory - Data);
  2470. //
  2471. // Authenticate from current IPSec header to the
  2472. // end of the new allocated buffer.
  2473. //
  2474. (*Alg->Operate)(Context, SA->Key, Data, DataLen);
  2475. //
  2476. // Need to authenticate other buffers if there are any.
  2477. // Ignore the ESP trailers.
  2478. //
  2479. // Check for an ESP header closest to the current IPSec header.
  2480. while (n < NumHeaders) {
  2481. if (IPSecToDo[n].SA->IPSecProto == IP_PROTOCOL_ESP) {
  2482. break;
  2483. }
  2484. n++;
  2485. }
  2486. // Get the next buffer in the packet.
  2487. NdisGetNextBuffer(NewBuffer1, &NextBuffer);
  2488. while (NextBuffer != NULL) {
  2489. // Get the start of the data and the data length.
  2490. NdisQueryBuffer(NextBuffer, &VirtualAddr, &DataLen);
  2491. Data = (uchar *)VirtualAddr;
  2492. //
  2493. // Check if this is the ESP Trailer by seeing if the
  2494. // AuthData storage is in the buffer.
  2495. //
  2496. if (n < NumHeaders)
  2497. if (IPSecToDo[n].AuthData > Data &&
  2498. IPSecToDo[n].AuthData < (Data + DataLen)) {
  2499. // Stop here this is the ESP trailer.
  2500. break;
  2501. }
  2502. // Feed the buffer to the Authentication function.
  2503. (*Alg->Operate)(Context, SA->Key, Data, DataLen);
  2504. // Get the next buffer in the packet.
  2505. NdisGetNextBuffer(NextBuffer, &NextBuffer)
  2506. } // end of while (NextBuffer != NULL)
  2507. // Get the Authentication Data.
  2508. (*Alg->Finalize)(Context, SA->Key, IPSecToDo[i].AuthData);
  2509. // Resume loop for other IPSec headers.
  2510. continue;
  2511. }
  2512. } else { // ESP.
  2513. // ESP starts the authentication at the ESP header.
  2514. Data = NewMemory + IPSecToDo[i].Offset;
  2515. }
  2516. DataLen = (uint)(EndNewMemory - Data);
  2517. // Initialize Context.
  2518. Context = alloca(Alg->ContextSize);
  2519. (*Alg->Initialize)(Context, SA->Key);
  2520. #ifdef IPSEC_DEBUG
  2521. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_IPSEC,
  2522. "\nSend Data[%d]:\n", i));
  2523. dump_encoded_mesg(Data, DataLen);
  2524. #endif
  2525. // Feed the new buffer to the Authentication function.
  2526. (*Alg->Operate)(Context, SA->Key, Data, DataLen);
  2527. // Get the next buffer in the packet.
  2528. NdisGetNextBuffer(NewBuffer1, &NextBuffer);
  2529. while (NextBuffer != NULL) {
  2530. // Get the start of the data and the data length.
  2531. NdisQueryBuffer(NextBuffer, &VirtualAddr, &DataLen);
  2532. Data = (uchar *)VirtualAddr;
  2533. //
  2534. // Check if this is the ESP Trailer by seeing if the
  2535. // AuthData storage is in the buffer.
  2536. //
  2537. if (SA->IPSecProto == IP_PROTOCOL_ESP &&
  2538. IPSecToDo[i].AuthData > Data &&
  2539. IPSecToDo[i].AuthData < (Data + DataLen)) {
  2540. // Don't include the Authentication Data
  2541. // in the ICV calculation.
  2542. DataLen = (uint)(IPSecToDo[i].AuthData - Data);
  2543. #ifdef IPSEC_DEBUG
  2544. dump_encoded_mesg(Data, DataLen);
  2545. #endif
  2546. // Feed the buffer to the Authentication function.
  2547. (*Alg->Operate)(Context, SA->Key, Data, DataLen);
  2548. break;
  2549. }
  2550. #ifdef IPSEC_DEBUG
  2551. dump_encoded_mesg(Data, DataLen);
  2552. #endif
  2553. // Feed the buffer to the Authentication function.
  2554. (*Alg->Operate)(Context, SA->Key, Data, DataLen);
  2555. // Get the next buffer in the packet.
  2556. NdisGetNextBuffer(NextBuffer, &NextBuffer)
  2557. } // end of while (NextBuffer != NULL)
  2558. // Get the Authentication Data.
  2559. (*Alg->Finalize)(Context, SA->Key, IPSecToDo[i].AuthData);
  2560. #ifdef IPSEC_DEBUG
  2561. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_IPSEC,
  2562. "Send Key (%d bytes): ", SA->RawKeyLength));
  2563. DumpKey(SA->RawKey, SA->RawKeyLength);
  2564. KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INFO_IPSEC,
  2565. "Send AuthData:\n"));
  2566. dump_encoded_mesg(IPSecToDo[i].AuthData, Alg->ResultSize);
  2567. #endif
  2568. } // end of for (i = 0; ...)
  2569. }