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.

311 lines
11 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. // IPsec Database data structures.
  14. //
  15. #ifndef SECURITY_INCLUDED
  16. #define SECURITY_INCLUDED 1
  17. //#define IPSEC_DEBUG
  18. // Return values for SPLookup.
  19. #define LOOKUP_DROP 0x01
  20. #define LOOKUP_CONT 0x02
  21. #define LOOKUP_BYPASS 0x04
  22. #define LOOKUP_IKE_NEG 0x08
  23. #define NO_TUNNEL -1
  24. #define SA_INVALID 0
  25. #define SA_VALID 1
  26. #define SA_NEGOTIATING 2
  27. #define SA_REMOVED 4
  28. // Bound the raw key size that we'll accept when creating an SA.
  29. // REVIEW: This should be big enough to handle any rational key. Is it?
  30. #define MAX_KEY_SIZE 1024
  31. #define MAX_CONTEXT_SIZE 128
  32. #define MAX_RESULT_SIZE 32
  33. //
  34. // IPSecSpec - IPsec Specification.
  35. // This is the protocol and mode used for IPsec. The RemoteIPAddr is set
  36. // when a tunnel to a security gateway is used.
  37. //
  38. typedef struct IPSecSpec {
  39. uint Protocol; // IP Protocol of IPSec employed, 0 for *.
  40. uint Mode; // Transport or Tunnel.
  41. IPv6Addr RemoteSecGWIPAddr; // Set when Security Gateway Tunnel is used.
  42. } IPSecSpec;
  43. //
  44. // Security algorithms have these prototypes.
  45. // The 'Context' is per-algorithm specific.
  46. //
  47. // REVIEW: This enough for both encryption and authentication?
  48. //
  49. typedef void AlgorithmKeyPrepProc(uchar *RawKey, uint RawKeySize, uchar *Key);
  50. typedef void AlgorithmInitProc(void *Context, uchar *Key);
  51. typedef void AlgorithmOpProc(void *Context, uchar *Key, uchar *Data,
  52. uint Len);
  53. typedef void AlgorithmFinalProc(void *Context, uchar *Key, uchar *Result);
  54. // REVIEW: Use Algorithm specific ContextSize or just have a universal max?
  55. // REVIEW: Ditto for KeySize.
  56. typedef struct SecurityAlgorithm {
  57. ushort KeySize; // Bytes used by key information.
  58. ushort ContextSize; // Bytes used by contextual information.
  59. uint ResultSize; // Bytes returned by FinalProc.
  60. AlgorithmKeyPrepProc *PrepareKey; // Key preprocessing.
  61. AlgorithmInitProc *Initialize; // Prepare algorithm (estab. context).
  62. AlgorithmOpProc *Operate; // Run algorithm on increment of data.
  63. AlgorithmFinalProc *Finalize; // Get final result.
  64. } SecurityAlgorithm;
  65. extern void
  66. AlgorithmsInit(void);
  67. typedef struct SecurityPolicy SecurityPolicy;
  68. typedef struct SecurityAssociation SecurityAssociation;
  69. //
  70. // Security Policy Database structure.
  71. //
  72. // Contains all the information relevant to a security policy.
  73. //
  74. struct SecurityPolicy { // SP entry.
  75. SecurityPolicy *Next;
  76. SecurityPolicy *Prev;
  77. uint RemoteAddrField; // Single, range, or wildcard.
  78. uint RemoteAddrSelector; // Packet or policy.
  79. IPv6Addr RemoteAddr; // Start of range or single value.
  80. IPv6Addr RemoteAddrData; // End of range.
  81. uint LocalAddrField; // Single, range, or wildcard.
  82. uint LocalAddrSelector; // Packet or policy.
  83. IPv6Addr LocalAddr; // Start of range or single value.
  84. IPv6Addr LocalAddrData; // End of range.
  85. uint TransportProtoSelector; // Packet or policy.
  86. ushort TransportProto; // If NONE, protocol is opaque (and
  87. // the ports should be skipped too).
  88. uint RemotePortField; // Single, range, or wildcard.
  89. uint RemotePortSelector; // Packet or policy.
  90. ushort RemotePort; // Start of range or single value.
  91. ushort RemotePortData; // End of range.
  92. uint LocalPortField; // Single, range, or wildcard.
  93. uint LocalPortSelector; // Packet or policy.
  94. ushort LocalPort; // Start of range or single value.
  95. ushort LocalPortData; // End of range.
  96. uint SecPolicyFlag; // Bypass/Discard/Apply.
  97. IPSecSpec IPSecSpec; // IPsec Protocol and Mode.
  98. void *Name; // Required (gag) selector type for
  99. // system or user@system identifiers.
  100. // If NULL, this selector is opaque.
  101. uint DirectionFlag; // Direction of traffic.
  102. SecurityPolicy *SABundle; // Policy for use IPsec nesting.
  103. SecurityPolicy *PrevSABundle; // Pointer used during SP deletion.
  104. SecurityAssociation *OutboundSA; // Pointer to outbound SA.
  105. SecurityAssociation *InboundSA; // Pointer to inbound SA.
  106. uint Index; // Index used during ioctl.
  107. uint IFIndex; // Interface index (0 to wildcard).
  108. uint RefCnt; // Reference count.
  109. uint NestCount; // Count of nested IPSec for Bundles.
  110. uint Valid;
  111. };
  112. //
  113. // Security Association (SA) Database structure.
  114. //
  115. // A unique SA is the tuple of the SPI, the destination address,
  116. // and the IPSec protocol of the packet. For packets with
  117. // multiple IPSec extension headers, there are multiple SAs,
  118. // comprising an SA Bundle.
  119. //
  120. // The SA selectors are the same as the SP selectors. If the selector entry
  121. // in the SP has the take from policy flag set, the matching selector entry
  122. // in the SA contains NONE (0) since the SP and SA selector are the same.
  123. // If the selector entry in the SP has the take from packet flag set, the
  124. // matching selector entry in the SA contains the value from the packet.
  125. //
  126. struct SecurityAssociation { // SA entry.
  127. SecurityAssociation *Next;
  128. SecurityAssociation *Prev;
  129. ulong SPI; // Security Parameter Index.
  130. IPv6Addr SADestAddr; // Destination address.
  131. uint IPSecProto; // IPSec protocol.
  132. ulong SequenceNum; // Used by anti-replay algorithms.
  133. uint SequenceNumOverflowFlag; // What to do when sequence number
  134. // overflows.
  135. #ifdef IPSEC_DEBUG
  136. uchar *RawKey; // For debugging key problems.
  137. uint RawKeyLength;
  138. #endif
  139. uchar *Key; // Pointer to secret key.
  140. uint KeyLength; // Key length in bytes.
  141. uint AlgorithmId; // Algorithm to apply.
  142. IPv6Addr DestAddr; // Packet value or NONE.
  143. IPv6Addr SrcAddr; // Packet value or NONE.
  144. ushort TransportProto; // Packet value or NONE.
  145. ushort DestPort; // Packet value or NONE.
  146. ushort SrcPort; // Packet value or NONE.
  147. uint DirectionFlag; // Direction of traffic.
  148. SecurityAssociation *ChainedSecAssoc; // Chained SA pointer.
  149. SecurityPolicy *SecPolicy; // Pointer to SP entry. Only set
  150. // for first entry of a chain or
  151. // single entry.
  152. uint Index; // Index used during ioctl.
  153. uint RefCnt; // Reference Count.
  154. uint Valid; // This entry still valid?
  155. };
  156. __inline void
  157. AddRefSA(SecurityAssociation *SA)
  158. {
  159. InterlockedIncrement(&SA->RefCnt);
  160. }
  161. //
  162. // Structure used to link "seen" SAs onto packet structure.
  163. // REVIEW: using uints for Mode and NextHeader is wasteful.
  164. //
  165. struct SALinkage {
  166. SALinkage *Next; // Next entry on stack of "seen" SAs.
  167. SecurityAssociation *This; // SA used to accept this packet.
  168. uint Mode; // Mode received in (Transport or Tunnel).
  169. uint NextHeader; // Header following one associated with this.
  170. };
  171. // Lookup result.
  172. struct IPSecProc {
  173. SecurityAssociation *SA;
  174. uint Mode; // Tunnel or Transport.
  175. uchar *AuthData; // Where to put authentication data.
  176. uint Offset; // Where to start doing the authentication (ESP only).
  177. uint BundleSize; // Array Size only first element has actual size.
  178. uint ByteSize; // Amount of bytes for this IPSec header.
  179. };
  180. //
  181. // Global variables.
  182. //
  183. extern KSPIN_LOCK IPSecLock;
  184. extern SecurityPolicy *SecurityPolicyList; // List of current policies.
  185. extern SecurityAssociation *SecurityAssociationList; // List of associations.
  186. extern ulong SecurityStateValidationCounter; // For validating cached state.
  187. extern SecurityAlgorithm AlgorithmTable[]; // Array of IPSec Algorithms.
  188. extern int MobilitySecurity; // Mobility security (on or off).
  189. __inline void
  190. InvalidateSecurityState(void)
  191. {
  192. InterlockedIncrement(&SecurityStateValidationCounter);
  193. }
  194. //
  195. // Function prototypes.
  196. //
  197. extern void
  198. RemoveSecurityAssociation(SecurityAssociation *SA);
  199. extern int
  200. DeleteSA(SecurityAssociation *SA);
  201. extern void
  202. ReleaseSA(SecurityAssociation *SA);
  203. extern void
  204. RemoveSecurityPolicy(SecurityPolicy *SP);
  205. extern int
  206. DeleteSP(SecurityPolicy *SP);
  207. extern int
  208. InboundSecurityCheck(IPv6Packet *Packet, ushort TransportProtocol,
  209. ushort SourcePort, ushort DestPort, Interface *IF);
  210. extern void
  211. FreeIPSecToDo(IPSecProc *IPSecToDo, uint Number);
  212. extern IPSecProc *
  213. OutboundSPLookup(IPv6Addr *SourceAddr, IPv6Addr *DestAddr,
  214. ushort TransportProtocol, ushort SourcePort,
  215. ushort DestPort, Interface *IF, uint *Action);
  216. extern SecurityPolicy *
  217. FindSecurityPolicyMatch(SecurityPolicy *List, uint IFIndex, uint PolicyIndex);
  218. extern SecurityAssociation *
  219. FindSecurityAssociationMatch(ulong Index);
  220. extern int
  221. InsertSecurityPolicy(SecurityPolicy *SP);
  222. extern int
  223. InsertSecurityAssociation(SecurityAssociation *SA);
  224. extern ulong
  225. GetSecurityPolicyIndex(SecurityPolicy *SP);
  226. extern uint
  227. IPSecBytesToInsert(IPSecProc *IPSecToDo, int *TunnelStart,
  228. uint *TrailerLength);
  229. extern uint
  230. IPSecInsertHeaders(uint Mode, IPSecProc *IPSecToDo, uchar **InsertPoint,
  231. uchar *NewMemory, PNDIS_PACKET Packet,
  232. uint *TotalPacketSize, uchar *PrevNextHdr,
  233. uint TunnelStart, uint *BytesInserted,
  234. uint *NumESPTrailers, uint *JUST_ESP);
  235. extern uint
  236. IPSecAdjustMutableFields(uchar *InsertPoint, IPv6RoutingHeader *SavedRtHdr);
  237. extern void
  238. IPSecAuthenticatePacket(uint Mode, IPSecProc *IPSecToDo, uchar *InsertPoint,
  239. uint *TunnelStart, uchar *NewMemory,
  240. uchar *EndNewMemory, PNDIS_BUFFER NewBuffer1);
  241. #ifdef IPSEC_DEBUG
  242. extern void
  243. dump_encoded_mesg(uchar *buff, uint len);
  244. extern
  245. void DumpKey(uchar *buff, uint len);
  246. #endif
  247. #endif // SECURITY_INCLUDED