User Tools

Site Tools


mywiki:linux:ipsec

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
mywiki:linux:ipsec [2015/12/10 10:13] – [IPSEC Basic] supermywiki:linux:ipsec [2019/09/15 18:55] (current) – external edit 127.0.0.1
Line 1: Line 1:
 **IPSec Implementation in Linux** **IPSec Implementation in Linux**
 +
 +| Reference | {{:mywiki:linux:chapter10_ipsec.pdf| ipsec_xfrm }} |
  
 ====== IPSEC Basic ====== ====== IPSEC Basic ======
Line 18: Line 20:
 ====== Terms ====== ====== Terms ======
 | SP(Security policy) | a rule which decides whether a given flow needs to go for IPSec processing or not | | SP(Security policy) | a rule which decides whether a given flow needs to go for IPSec processing or not |
-| SA(Security Association) | simply the bundle of algorithms and parameters (such as keys) that is being used to encrypt and authenticate a particular flow in one direction.  IPsec uses the Security Parameter Index (SPI: an index to the security association database - SADB), along with the destination address in a packet header, which together uniquely identify a security association for that packet.  |   +| SA(Security Association) | bundle of algorithms and parameters (such as keys) that is being used to encrypt and authenticate a particular flow in one direction.  IPsec uses the Security Parameter Index (SPI: an index to the security association database - SADB), along with the destination address in a packet header, which together uniquely identify a security association for that packet.  |    
 + 
 +====== Limux Implementation ====== 
 +===== UserSpace communication via NETLINK_XFRM ===== 
 +| XFRM_MSG_NEWSA | To  add a new SA to SAD | 
 +| XFRM_MSG_DELSA | To delete a new SA to SAD | 
 +| XFRM_MSG_GETSA | To  get a new SA to SAD | 
 +| XFRM_MSG_FLUSHSA | To  flush  SAD | 
 +| XFRM_MSG_NEWPOLICY | To add a new policy to SPD | 
 +| XFRM_MSG_DELPOLICY | To delete a new policy to SPD | 
 +| XFRM_MSG_GETPOLICY | To get a new policy to SPD | 
 +| XFRM_MSG_FLUSHPOLICY | To flush SPD | 
 + 
 +===== IPSec framework in kernel ===== 
 +| ESP Protocol | net/ipv4/esp4.c, net/ipv6/esp6.c | 
 +| AH Protocol | net/ipv4/ah4.c, net/ipv6/ah6.c | 
 +| XFRM framework | net/ipv4/xfrm4_policy.c and net/ipv6/xfrm6_policy.c | 
 +| XFRM initialization | xfrm4_init() and xfrm6_init(). | 
 + 
 + 
 +===== Kernel Terms ===== 
 +| aalg | **Authentication** algo pointer | 
 +| ealg | **Encryption** algo pointer | 
 +| calg | **Compression** algo pointer | 
 +| aead | **Authentication Encryption** with Associated Data pointer | Note: if (aead == NULL); then only authentication without any encryption | 
 +| encap | Data for **encapsulator**, ie, for **special UDP** Encapsulation only | draft-ietf-ipsec-udp-encaps-06 | 
 + 
 + 
 +===== Kernel cryptography ===== 
 + 
 +| acrypto | asynchronous crypto | 
 +| cryptd |  
 +| pcrypto | for multicore environment | 
 + 
 +Algo: DES, 3DES, AES, RC5, IDEA, 3-IDEA, CAST, BLOWFISH etc... 
 + 
 +two IPSec stacks: 
 +| native netkey stack | syncronous | 
 +| traditional KLIPS stack | asynchronous | 
 + 
 +To start with, the core object of **xfrm** is the 'xfrm' member of '**struct net**'. i.e each network namespace has got a separate xfrm object. This object will be reffered to access the hash tables (remeber hash tables :) ) of SPD and SAD. Also holds the state garbage collector (state_gc_work) 
 + 
 +Data structures  
 +<file > 
 +The building block of SPD (Policy Database) is struct xfrm_policy. 
 + 
 +/* ################################################# */ 
 + 
 +struct xfrm_policy { 
 + 
 +#ifdef CONFIG_NET_NS 
 +                struct net                            *xp_net; 
 +#endif 
 +                struct hlist_node              bydst; 
 +                struct hlist_node              byidx; 
 +                /* This lock only affects elements except for entry. */ 
 +                rwlock_t                              lock; 
 +                atomic_t                              refcnt; 
 +                struct timer_list                timer; 
 +                struct flow_cache_object flo; 
 +                atomic_t                              genid; 
 +                u32                                         priority; 
 +                u32                                         index; 
 +                struct xfrm_mark             mark; 
 +                struct xfrm_selector       selector; 
 +                struct xfrm_lifetime_cfg lft; 
 +                struct xfrm_lifetime_cur curlft; 
 +                struct xfrm_policy_walk_entry walk; 
 +                struct xfrm_policy_queue polq; 
 +                u8                                           type; 
 +                u8                                           action; 
 +                u8                                           flags; 
 +                u8                                           xfrm_nr; 
 +                u16                                         family; 
 +                struct xfrm_sec_ctx        *security; 
 +                struct xfrm_tmpl              xfrm_vec[XFRM_MAX_DEPTH]; 
 +}; 
 + 
 + 
 + 
 + 
 +Important Fields: 
 + 
 +                                - refcnt is to hold the reference to the policy. 
 + 
 +                                - which embedded xfrm_selector object to hold the source and destination IP addresses, source and destination ports, protocol, interface index etc. xfrm_selector_match() API checks if the given packet matches with the XFRM selector. 
 + 
 +                                - lft:  is the policy lifetime 
 + 
 +                                - timer: to handle the policy expiry 
 + 
 +                                - polq: is a queue to push the packets when there are no states associated with this policy. 
 + 
 +                                - action: this field decides the fate of the traffic. (XFRM_POLICY_ALLOW and XFRM_POLICY_BLOCK) 
 + 
 +                                - family (v4 or v6, as mentioned this structure is common for all protocols)            
 +</file> 
 + 
 +The building block of SAD (Association Database) is struct xfrm_state  
 + 
 +<file> 
 +/* Full description of state of transformer. */ 
 + 
 +struct xfrm_state { 
 + 
 +#ifdef CONFIG_NET_NS 
 +                struct net                            *xs_net; 
 +#endif 
 +                union { 
 +                                struct hlist_node              gclist; 
 +                                struct hlist_node              bydst; 
 +                }; 
 +                struct hlist_node              bysrc; 
 +                struct hlist_node              byspi; 
 +                atomic_t                              refcnt; 
 +                spinlock_t                           lock; 
 +                struct xfrm_id                   id; 
 +                struct xfrm_selector       sel; 
 + 
 +                /* Key manager bits */ 
 + 
 +                struct xfrm_state_walk km; 
 + 
 +                /* Parameters of this state. */ 
 + 
 +                struct { 
 +                                u32                         reqid; 
 +                                u8                           mode; 
 +                                u8                           replay_window; 
 +                                u8                           aalgo, ealgo, calgo; 
 +                                u8                           flags; 
 +                                u16                         family; 
 +                                xfrm_address_t               saddr; 
 +                                int                           header_len; 
 +                                int                           trailer_len; 
 +                                u32                         extra_flags; 
 +                } props; 
 + 
 +                struct xfrm_lifetime_cfg lft; 
 + 
 +                /* Data for transformer */ 
 +                struct xfrm_algo_auth   *aalg; 
 +                struct xfrm_algo               *ealg; 
 +                struct xfrm_algo               *calg; 
 +                struct xfrm_algo_aead  *aead; 
 + 
 +                /* Data for encapsulator */ 
 + 
 +                struct xfrm_encap_tmpl               *encap; 
 + 
 +                --------------          
 + 
 +               ------------------- 
 + 
 +                /* data for replay detection */ 
 + 
 +                struct xfrm_replay_state replay; 
 + 
 +                struct xfrm_replay_state_esn *replay_esn; 
 + 
 +                struct xfrm_replay_state preplay; 
 + 
 +                struct xfrm_replay_state_esn *preplay_esn; 
 + 
 +                struct xfrm_replay          *repl; 
 + 
 +                u32                                         replay_maxage; 
 + 
 +                u32                                         replay_maxdiff; 
 + 
 +                struct timer_list                rtimer; 
 + 
 +                /* Statistics */ 
 + 
 +                struct xfrm_stats             stats; 
 + 
 +                struct xfrm_lifetime_cur curlft; 
 + 
 +                struct tasklet_hrtimer    mtimer; 
 + 
 +                /* Last used time */ 
 + 
 +                unsigned long                    lastused; 
 + 
 +                --------------------------- 
 + 
 +                ---------------------------- 
 + 
 +                /* Private data of this transformer, format is opaque, 
 + 
 +                 * interpreted by xfrm_type methods. */ 
 +                void                                       *data; 
 + 
 +
 + 
 +</file> 
 + 
 +===== IPSec kernel  APIs ===== 
 +| Xfrm_lookup() | xfrm lookup(SPD and SAD) method | 
 +| Xfrm_input() | xfrm processing for an ingress packet | 
 +| Xfrm_output() | xfrm processing for an egress packet | 
 +| Xfrm4_rcv() | IPv4 specific Rx method | 
 +| Xfrm6_rcv() | IPv6 specific Rx method | 
 +| Esp_input() | ESP processing for an ingress packet | 
 +| Esp_output() | ESP processing for an egress packet | 
 +| Ah_input() | AH processing for an ingress packet | 
 +| Ah_output() | AH processing for an egress packet | 
 +| xfrm_policy_alloc() | allocates an SPD object | 
 +| Xfrm_policy_destroy() | frees an SPD object | 
 +| xfrm_ policy_lookup | SPD lookup | 
 +| xfrm_policy_byid() | SPD lookup based on id | 
 +| Xfrm_policy_insert() | Add an entry to SPD | 
 +| Xfrm_Policy_delete() | remove an entry from SPD | 
 +| Xfrm_bundle_create() | creates a xfrm bundle | 
 +| Xfrm_policy_delete() | releases the resources of a policy object | 
 +| Xfrm_state_add() | add an entry to SAD | 
 +| Xfrm_state_delete() | free and SAD object | 
 +| xfrm_state_alloc() | allocate an SAD object | 
 +| xfrm_state_lookup_byaddr() | src address based SAD lookup | 
 +| xfrm_state_find() | SAD look up based on dst | 
 +| xfrm_state_lookup() | SAD lookup based on spi | 
 + 
 +===== IPSec SA initialize ===== 
 +It is initialized by API: **static int esp_init_state(struct xfrm_state *x)**, which is defined in file: 
 +  * net/ipv4/esp4.c 
 +  * net/ipv6/esp6.c 
 +===== IPSec Tx steps ===== 
 +<file> 
 +For better understanding I have divided the IPSec transmission process in 7 stepes as below 
 + 
 +Step-1: Transport_layer_sendmsg()  
 + 
 +Does TCP/UDP specific jobs are done here before going for route lookup 
 + 
 +Step-2: ip_route_output_slow()  
 + 
 +Xfrm_lookup() 
 + 
 +Step-3: ip_local_output() 
 + 
 +Step-4: ip_local_out() 
 + 
 + LOCAL_OUT netfilter applies here. 
 + 
 +Calls skb->dst->output(), which is xfrm4_output in case of ipv4 and xfrm6_output in the case of ipv6 
 + 
 +Step-5: xfrm4_output/xfrm6_output 
 + 
 +Step-6: esp_output()/ah_output() 
 + 
 +Step-7: ip_output() 
 + 
 +Step-8: dev_queue_xmit() 
 + 
 +Egress QoS comes here. 
 + 
 +Step-9: dev->ndo_start_xmit()  
 +</file> 
 +===== IPSec Rx steps ===== 
 +<file> 
 +For better understanding I have divided the IPSec reception process in 7 stepes, they are below 
 + 
 +Step-1: netif_receive_skb() 
 + 
 +Step-2: ip_rcv() 
 + 
 +Netfilter PRE_ROUTING applies here. 
 + 
 +Step-3: ip_receive_finish 
 + 
 +Calls ip_route_input_noref(). Which finds the route entry and set dst->output for local delivery, forwarding etc. But IPSec applies on the end systems ONLY. So we bothr if it is set for local delivery 
 + 
 +Step-4: ip_local_deliver 
 + 
 +LOCAL_IN Netfilter part here. 
 + 
 +Step-5: ip_local_deliver_finish() 
 + 
 +Based on the protocol field of  ip header (IPPROTO_AH, IPPROTO_ESP),  packet will be given to xfrm4_rcv() function 
 + 
 +Step-6:  xfrm4_rcv() 
 + 
 +Step-7: xfrm_input() 
 + 
 +Calls xfrm_state_lookup() 
 + 
 +calls esp_input()/ah_input() 
 + 
 +Once again applies the PRE_ROUTING Netfilter, but now  for the decapsulated packet 
 + 
 +Step-8: xfrm4_rcv_encap_finish() 
 + 
 +Will do the route lookup again for the decapsulated packet using ip_route_input_noref(). Again route lookup should decide for local_delivery. 
 + 
 +Step-9: ip_local_delivery() 
 + 
 +again the LOCAL_IN Netfilter for decapsulated packet 
 + 
 +now the protocol field will be TCP/UDP and the packet flows in the native reception methods of TCP/UDP and delivers to the socket 
 + 
 +Step-10: transport_layer_rcvmsg() 
 + 
 +-to userspace 
 +</file>
mywiki/linux/ipsec.1449713619.txt.gz · Last modified: (external edit)