Security Policy Database (SPD) and Security Association Database (SAD)

Jump to: navigation, search

Table of Contents >> IPsec/IKE Programmer's Reference


SPD specifies the policies that determine the disposition of all IP traffic inbound or outbound from a host or a security gateway. SAD is a security association table, containing parameters that are associated with each security association.

SPD

The SPD must be consulted during the processing of all traffic (both inbound and outbound), including non-IPsec traffic. The policy entries in SPD are totally ordered, and the first matched policy will be used to process the traffic. For example, we have two IPv4 subnet networks, subnet A 1.1.1.0/24 and subnet B 2.2.1.0/24, with security gateway GA and GB, as shown in Figure 5. This diagram could also be degraded to a host A to subnet B, or even host A to host B, in such cases, GA or GB becomes an IPsec-enabled host.

Figure 5: Subnet Network 1.1.1.0/24, and 2.2.1.0/24

Figure 5: Subnet Network 1.1.1.0/24, and 2.2.1.0/24

The SPD table at GA is shown in Table 1.

Table 1: SPD table at GA (Suppose we have 10 policy entries at GA)
index Direction Local IP(sharing?) Local port(sharing?) Remt ip(sharing?) Remt port(sharing?) Protocol(sharing?) Inbound 1st SA entry Outbound 1st SA entry Action Policy 1st content
9 In & Out 1.1.1.12 Y 80 Y 2.2.1.0/24 Y Any Y TCP Y sa15 sa25 IPSEC Cont1
8 In & Out 1.1.1.0/24 Y Any Y 2.2.1.0/24 Y Any Y Any N sa10 sa20 IPSEC Cont3
. ...
... In
... Out
0 In & Out Any Any Any Any Any NULL NULL BYPASS NULL

The policy order determines the packet processing behavior. The policy table is always looked up from the very top (the most preferred one) to the very bottom (the lest preferred one, with policy index equal to zero). The first matched policy will be used to process the packet. The policy index number 0 is recommended to be an ALL-BYPASS or ALL-DISCARD policy, otherwise, if a packet cannot find a suitable policy, a 'NO-POLICY' error will return.

In table 1, policy index No.9 is the preferred policy applying to both INBOUND and OUTBOUND matched traffic. If traffic does not match policy No.9's selector, we check against the next policy, i.e. policy No.8, and then policy No. 7, and so on down to policy No. 0.

A policy has one or more policy contents, and each content corresponds to an IPsec protocol, either AH or ESP, but not both. If a policy needs both ESP and AH, two separate policy contents must be used, and they are linked together through the next content pointer. For example, policy No.9 requires both ESP and AH. ESP tunnel mode must be performed before the AH transport mode protection. The policy contents are shown in figure 6.


Figure 6: Policy Content Linked List

Figure 6: Policy Content Linked List

For data format like IP + AH + ESP + IP+ DATA, Treck calls the ESP in tunnel mode and the AH in transport mode, and for data format like IP + AH + IP + ESP + IP+ DATA, Treck calls both ESP and AH in tunnel mode.

SAD

SA is generated according to the policy contents. Each SA is able to provide security service of either AH or ESP, but not both. If both ESP and AH are required, a group of SA (i.e. SA bundle) is required.

The YES-NO sharing flag of each policy determines how to build SA according to the policy. It indicates whether the corresponding selector field uses policy value or packet value. (See RFC 2401 Page 15 for details of policy value against packet value) If NO sharing is defined, we use packet value to build SA. If YES is defined, we use policy value to build SA. For example, policy index No.8, the policy selector/protocol field is set to be ANY but prohibits sharing (NO sharing), thus, although both TCP and UDP matches this policy, they must use different SA, i.e., use different encryption key and authentication keys to protect the traffic. If sharing is allowed, we will use the policy value (ANY protocol) to build SA, and both TCP and UDP will use the same SA.

The SAD table is a hash table. The triple value <SPI, destination IP, and Protocol> are hashed. Each SA also contains traffic selector, which may or may not equal to the policy traffic selector. (When SA sharing is fully granted, these two selectors will be the same).

Outbound Processing

If IPsec is desired, each outbound packet is compared against the SPD to determine what processing is required for the packet.

  1. Match the packet's selector fields against the outbound policies in the SPD to locate the FIRST appropriate policy.
  2. Determine the action according to the policy located. If discard is required, the packet is discarded, (packet information may be logged). If packet is allowed to bypass IPsec processing, skip the following IPsec processing. Go to step 6.
  3. If IPsec processing is required, locate the appropriate SA generated by this policy's innermost policy content using the first-outbound-sa pointer for a certain policy. If no SA is found and IKE is not activated, drop the packet. Otherwise, if IKE is activated, queue the packet and initiate IKE negotiation.
  4. Use the SA found in last step to do the required IPsec processing.
  5. Go back to step 3 to determine if there is outer policy content. Find the SA according to the outer policy content if outer policy content exists. If no more outer policy content, go to step 6.
  6. Send the packet out.

At step 3 above, the packet will be queued if IKE starts. The packet processing procedure will be resumed when IKE finishes the negotiation and the SA is ready.

For TCP socket, the SA(s) used to protect the traffic will be queued in the socket pointer. The next time sending packets through this socket, policy and SA lookup is not required.

Inbound Processing

The following steps are taken to process IPsec inbound packet [see RFC 2401]:

  1. When an IPsec protected packet is received, use the packet's destination address (outer IP header), IPsec protocol, and SPI to look up the SA in the SAD. If the SA lookup fails, drop the packet and log/report the error.
  2. Use the SA found in (1) to do the IPsec processing, e.g., authenticate and decrypt. Meanwhile, save the SA and its order for later verification usage.
  3. Process the next header, if it is IPsec header, go back to step 1; if it is another IP header (SA found in (1) must be in tunnel mode), remove the tunnel, and process the next header again. If a transport protocol header is encountered, go to step 4
  4. Find the incoming policy in the SPD using the inner IP header information.
  5. Check whether the required IPsec processing has been applied. i.e., verify that the SA's saved in (2) match the kind and order of SA's required by the policy found in (4).

If the SA verification procedure returns no error, pass the resulting packet to the transport layer or forward the packet.

Treck SPD and SAD features

  • SPD management APIs are provided with the capability of single policy adding, bundle policy adding, bulk-loading policy adding, policy deleting and SPD clearing.
  • SAD management APIs are provided with the capability of adding, removing, and clearing.
  • SPD and SAD are maintained in separate tables.
  • SPD is searched linearly in order to find the first match, while SAD is maintained as hash table.
  • SPD and SAD selectors are based on local and remote IP addresses, in host type, subnet type or range type. (Fully qualified domain name is also supported at the user's interface), local and remote ports, and traffic protocol. SA using policy value or packet value is also configurable.

Multiple Phase 2 Proposals

IPsec Policies support multiple proposals and multiple transforms extending the flexibility of security policy. To enable this functionality, define TM_USE_MULTIPLE_PROPOSALS in <trsystem.h> at compile time. When using Multiple Proposals, the Proposal Number and Transform Number must be specified with the policy definition. The approach that must be used depends on the way in which the policy is created.

Proposal Number and Transform Number

Section 4.2 of RFC 2408, Internet Security Association and Key Management Protocol (ISAKMP), describes the requirements for an SA Proposal during IKE negotiation. Of special interest are the rules that define Proposal and Transform Payloads. More specifically, the rules that govern the Proposal Number and Transforms Number given a particular target offer must be well understood as the Multiple Proposal implementation exposes this flexibility directly to the configuration process. While perhaps a little complicated to IPsec newcomers, this approach was chosen to avoid ambiguity which comes from implementations which seek to simplify the problem domain yet in the end create confusion when one tries to map the chosen model to the distinct rules. Once these rules are understood, the flexible set of combinations that ISAKMP (and thus IPsec) provides can be realized through proper configuration of the Proposal Number and Transform Number within a Policy Content (ttPolicyContent). As previously mentioned, the methodology used to arrive at this results is dependent on the approach taken. The following sections describe each approach.

Restoring Policies with tfPolicyRestore()

When bulk-loading IPsec Policies, the Proposal Number and Transform Number must be specified within ttIpsecPolicyPair following the rules described by RFC 2408.

Without Multiple Proposals, the procedure for adding a bulk-loaded bundle defines a bundle to contain two consecutive entries in the ttIpsecPolicyPair array with the same Selector index. This remains the same when using Multiple Proposals, however note that each ttIpsecPolicyPair entry must use the same Priority if Priority-based Processing is being utilized. Also note that the IKE Policy must be the same if IKE Policies are being used.

When creating IPsec Policies in this fashion, the Policy Content's Proposal Number and Transform Number are overwritten with those specified in ttIpsecPolicyPair.

OR Proposal with tfPolicyRestore()

A sample OR proposal could be created with the following:

pListPtr[0]->ippPriority = 10;
pListPtr[0]->ippIkePolicy = 3;
pListPtr[0]->ippSelectorIndex = 0;
pListPtr[0]->ippPlcycontentIndex = 5;
pListPtr[0]->ippProposalNumber = 1;
pListPtr[0]->ippTransformNumber = 1;
pListPtr[1]->ippPriority = 10;
pListPtr[1]->ippIkePolicy = 3;
pListPtr[1]->ippSelectorIndex = 0;
pListPtr[1]->ippPlcycontentIndex = 6;
pListPtr[1]->ippProposalNumber = 1;
pListPtr[1]->ippTransformNumber = 2;

This would create a Policy which results in an offer that is an OR of the Policy Content index 5 and Policy Content index 6. Obviously the Policy Contents described by index 5 and index 6 could be of different protocols (AH/ESP) and different modes (tunnel/transport).

AND Proposal with tfPolicyRestore()

A sample AND proposal could be created with the following:

pListPtr[0]->ippPriority = 10;
pListPtr[0]->ippIkePolicy = 3;
pListPtr[0]->ippSelectorIndex = 0;
pListPtr[0]->ippPlcycontentIndex = 5;
pListPtr[0]->ippProposalNumber = 1;
pListPtr[0]->ippTransformNumber = 1;
pListPtr[1]->ippPriority = 10;
pListPtr[1]->ippIkePolicy = 3;
pListPtr[1]->ippSelectorIndex = 0;
pListPtr[1]->ippPlcycontentIndex = 6;
pListPtr[1]->ippProposalNumber = 1;
pListPtr[1]->ippTransformNumber = 1;

This would create a Policy which results in an offer that is an AND of the Policy Content index 5 and Policy Content index 6. The Policy Contents described by index 5 and index 6 would have to be transforms of the same protocol, i.e. both ESP or both AH, and also of the same mode, i.e. both tunnel or both transport.

Complex Proposal with tfPolicyRestore()

A more complex proposal could be created with the following:

pListPtr[0]->ippPriority = 10;
pListPtr[0]->ippIkePolicy = 3;
pListPtr[0]->ippSelectorIndex = 0;
pListPtr[0]->ippPlcycontentIndex = 5;
pListPtr[0]->ippProposalNumber = 1;
pListPtr[0]->ippTransformNumber = 1;
pListPtr[1]->ippPriority = 10;
pListPtr[1]->ippIkePolicy = 3;
pListPtr[1]->ippSelectorIndex = 0;
pListPtr[1]->ippPlcycontentIndex = 6;
pListPtr[1]->ippProposalNumber = 1;
pListPtr[1]->ippTransformNumber = 2;
pListPtr[2]->ippPriority = 10;
pListPtr[2]->ippIkePolicy = 3;
pListPtr[2]->ippSelectorIndex = 0;
pListPtr[2]->ippPlcycontentIndex = 7;
pListPtr[2]->ippProposalNumber = 1;
pListPtr[2]->ippTransformNumber = 1;
pListPtr[3]->ippPriority = 10;
pListPtr[3]->ippIkePolicy = 3;
pListPtr[3]->ippSelectorIndex = 0;
pListPtr[3]->ippPlcycontentIndex = 8;
pListPtr[3]->ippProposalNumber = 1;
pListPtr[3]->ippTransformNumber = 2;
pListPtr[4]->ippPriority = 10;
pListPtr[4]->ippIkePolicy = 3;
pListPtr[4]->ippSelectorIndex = 0;
pListPtr[4]->ippPlcycontentIndex = 9;
pListPtr[4]->ippProposalNumber = 2;
pListPtr[4]->ippTransformNumber = 1;

This would create the following offer (where PCx = Policy Content x): ((PC5 or PC6) and (PC7 or PC8)) or (PC9)

Adding IPsec Policies with tfPolicyAdd()

When adding IPsec Policies with tfPolicyAdd(), the Proposal Number and Transform Number are specified directly in the ttPolicyContent structure.


Note Note: There are several data members specific to the use of TM_USE_MULTIPLE_PROPOSALS. These should never be modified at any time. Future revisions will hide these data members from the user.


Note Note: It is important to understand the difference between a ttPolicyContent that is to be used with tfPolicyAdd() and one that is to be used with tfPolicyRestore(). A single ttPolicyContent cannot be used with both because of the overlapping Proposal and Transform number information. Thus, bulk-load Policy Content structures independent of those which are to be added with tfPolicyAdd().


IPsec Policies with Multiple Proposals must be verified and committed to the Policy Database in an atomic step. As a result, and despite the modifications to use the Proposal Number and Transform Number mentioned above, there is another final step to "close" an IPsec Policy once all Proposals and Transforms have been added:

  1. Call tfPolicyAdd() with the additional Proposal Number and Transform Number included.
  2. Call tfPolicyAddBundle() to add additional Proposals and/or Transforms using the same Priority (if applicable), IKE Policy (if applicable).
  3. Do one of the following:
    1. Call tfPolicyAddBundle() with outerContentPtr set to NULL.
    2. Call tfPolicyValidate() using the ttPolicyEntryPtr.
    3. Call tfPolicyValidateByPriority() using the policy priority.

To add an IPsec Policy with a single Policy Content, skip step #2. Note that this applies only when defining TM_USE_MULTIPLE_PROPOSALS.

Creating Manual SA Bundles

Create manual SA bundles using tfSadbRecordManualAddByPriority().

Enhanced Bundle Processing

When using Multiple Proposals, IPsec Bundles are processed in a single negotiation rather than with multiple negotiations. For example, without Multiple Proposals, a bundle that specifies AH/ESP will result in a Quick Mode negotiation for the AH SA and, given success, another Quick Mode negotiation for the ESP SA. With Multiple Proposals, the AH/ESP bundle results in a single Quick Mode exchange.

Retrieval of SAs by IPsec Policy

To iterate through all existing IPsec SAs for a specified IPsec policy use tfSadbRecordGetByPolicy().

Removal of IPsec SAs

To remove IPsec SAs use tfSadbRecordClearAll() and tfSadbRecordClearByPriority().


Table of Contents >> IPsec/IKE Programmer's Reference