Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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