Difference between revisions of "VPP/IPSec"

From fd.io
< VPP
Jump to: navigation, search
m (fix RFC for IPsec (4301, not 4031). fix grammar ("an SPD" not "and SPD"). fix SPD creation example.)
(small spelling error)
Line 36: Line 36:
 
*2) VPP has two interface types, ipsec and -ipsec-gre, that act exactly like a IP-in-IP and GRE tunnel respectively that have ESP as an output feature
 
*2) VPP has two interface types, ipsec and -ipsec-gre, that act exactly like a IP-in-IP and GRE tunnel respectively that have ESP as an output feature
 
*3) the API above is a concatenation of the 'create ipip tunnel ...' and 'ipsec sa add ...' APIs and needs to track changes in both.
 
*3) the API above is a concatenation of the 'create ipip tunnel ...' and 'ipsec sa add ...' APIs and needs to track changes in both.
*4) the use has no control over whether the ESP mode is tunnel mode or transport mode.
+
*4) the user has no control over whether the ESP mode is tunnel mode or transport mode.
  
 
==== Proposed Model ====
 
==== Proposed Model ====

Revision as of 00:02, 10 December 2019

IPSec

Basics

Two flavours of IPSec are available: Tunnel and Policy mode.

Tunnel Mode

An IP-in-IP or GRE tunnel is 'protected' by a pair of Security Associations (SA) - one for inbound/local traffic and one for outbound/remote. All ESP packets whose SPI matches that of the inbound SA are 'classified' to have arrived on the tunnel. All packets that egress the tunnel are ESP protected using the outbound SA.

Current Model

The current model for creating such a protected tunnel is a dedicated interface type; either ipsec or ipsec-gre. These are created e.g.;

 create ipsec tunnel local-ip 10.0.0.1 remote-ip 10.0.0.2 local-spi 100 remote-spi 101 local-crypto-key A11E51E5B1E0 remote-crypto-key A11E51E5B1E0 crypto-alg aes-gcm-128

This command will create: one tunnel ipsecX and two associated SAs.

DBGvpp# sh int
              Name               Idx    State  MTU (L3/IP4/IP6/MPLS)     Counter          Count     
ipsec0                            6      up          9000/0/0/0     
DBGvpp# sh ipsec sa
[0] sa 0x80000000 spi 101 mode tunnel protocol esp tunnel 
[1] sa 0xc0000000 spi 100 mode tunnel protocol esp tunnel 
DBGvpp# sh ipsec tun
Tunnel interfaces
  ipsec0
   out-bound sa: [1] sa 0xc0000000 spi 100 mode tunnel protocol esp tunnel 
    in-bound sa: [0] sa 0x80000000 spi 101 mode tunnel protocol esp tunnel 


There are several drawbacks to this approach:

  • 1) for the API user to know the ID/index of the created SAs (in order to read stats) it must use the dump API s to determine which SAs are associated with the tunnel. The SAs have an automatically generated SA-ID.
  • 2) VPP has two interface types, ipsec and -ipsec-gre, that act exactly like a IP-in-IP and GRE tunnel respectively that have ESP as an output feature
  • 3) the API above is a concatenation of the 'create ipip tunnel ...' and 'ipsec sa add ...' APIs and needs to track changes in both.
  • 4) the user has no control over whether the ESP mode is tunnel mode or transport mode.

Proposed Model

A separation of the creation of the interface, SAs and the protection that they provide:

 create ipip tunnel src 10.0.0.1 dst 10.0.0.2
 ipsec sa add 20 spi 200 crypto-key A11E51E5B111 crypto-alg aes-gcm-128
 ipsec sa add 30 spi 300 crypto-key A11E51E5B222 crypto-alg aes-gcm-128
 ipsec tunnel protect ipip0 sa-in 20 sa-out 30

This results in:

DBGvpp# sh int
              Name               Idx    State  MTU (L3/IP4/IP6/MPLS)     Counter          Count     
ipip0                             6      up          9000/0/0/0     
DBGvpp# sh ipsec sa
[0] sa 0x14 spi 200 mode transport protocol esp 
[1] sa 0x1e spi 300 mode transport protocol esp 
DBGvpp# sh ipsec protect    
ipip0
 output-sa:
  [1] sa 0x1e spi 300 mode transport protocol esp 
 input-sa:
  [0] sa 0x14 spi 200 mode transport protocol esp 

Note that the SAs are in transport mode. For tunnels the ESP acts on the post-encapsulated packet. So if this packet:

     +---------+------+
     | Payload | O-IP |
     +---------+------+

where O-IP is the overlay IP addrees that was routed into the tunnel, the resulting encapsulated packet will be:

     +---------+------+------+
     | Payload | O-IP | T-IP |
     +---------+------+------+

where T-IP is the tunnel's src.dst IP addresses. If the SAs used for protection are in transport mode then the ESP is inserted before T-IP, i.e.:

     +---------+------+-----+------+
     | Payload | O-IP | ESP | T-IP |
     +---------+------+-----+------+

If the SAs used for protection are in tunnel mode then another encapsulation occurs, i.e.:

     +---------+------+------+-----+------+
     | Payload | O-IP | T-IP | ESP | C-IP |
     +---------+------+------+-----+------+

where C-IP are the crypto endpoint IP addresses defined as the tunnel endpoints in the SA. The mode for the inbound and outbound SA must be the same.

This approach solves all the above drawbacks:

  • 1) the user is directly responsible fro constructing the SAs so knows their identity.
  • 2) we reuse the existing IP-in-IP (or GRE) tunnel
  • 3) re-use of the separate APIs for the creation of the tunnel and SAs
  • 4) the mode of the SA controls the mode of the ESP encapsulation.

The drawback, from the user's perspective, is that what used to take 1 API call now takes 4.

For VPP code this introduces a new data-type, an ipsec-tun-protection, which acts as the 'binding' between the tunnel and its associated SAs.

Rekeying a tunnel is achevied by updating the tunnel protection to provide the new set of protecting SAs. It is also possible to rekey a tunnel in 3 phases to achieve a make-before break:T

  • 1) the inbould set of SAs includes both the old and the new inbound SA
 ipsec tun protect ipip0 sa-in [old, new] sa-out old
  • 2) after some time (when it is considered the peer has updated to the new inbound SA) we switch to using the new outbound SA.
 ipsec tun protect ipip0 sa-in [old, new] sa-out new
  • 3) after some more time or when the SA stats say traffic has arrived on the new inbound SA, we can safely remove the old inbound SA
 ipsec tun protect ipip0 sa-in [new] sa-out new

Policy Mode

Policy mode follows the use of IPSec as described in RFC4301.

First an SPD is created:

 ipsec spd add 1

SAs are created to protected traffic:

 ipsec sa add id 2 spi X ...

that match given policies:

 ipsec policy add spd AA action .. sa 2 [inbound|outbound] [match criteria]

then the SPD is applied to an interface:

 set interface ipsec spd eth0 AA

traffic that ingresses and egresses eth0 is subject to the inbound and outbound policies respectively of the SPD


IPSec Implementations

There are many implementations for IPSec that are open sourced, principally there is the suite of implementations (both SW and HW) that are provided by the DPDK crypto-devices and openSSL. As of 19.04 VPP also has its own IPSec implementation that makes use of Intel's vector cyptographic instructions.

There are two, slightly overlapping, mechanisms to choose an implementation; backends and engines. Engines were introduced in 19.04 and is the preferred mechanism we are migrating away from backends as time and resource permits.

Engines and/or backends apply to both modes of IPSec as described above.

Backends

As of 19.04 there are only two backends; native (i.e. use engined - the default) and DPDK (provided by the dpdk plugin). Backends must provide their own ESP and/or AH VPP nodes to perform the packet encrypt and decrypt -in other words a backend must provide the full packet switch path. This is a real barrier to the use of some new crypto library and a significant effort for the community to support.

DBGvpp# sh ipsec backends 
IPsec AH backends available:
           Name                     Index             Active  
  crypto engine backend      0                 yes   
IPsec ESP backends available:
           Name                     Index             Active  
  crypto engine backend      0                 yes   
      dpdk backend                 1                  no   


Engines

The default IPSEc backend makes use of 'engines' that provide a byte stream based encrypt/decrypt service. The API between VPP and the engine is represented as an 'operation'. Each operation specifies, e.g., the algorithm[s] and keys and the address of the data to encrypt and the location to place any output.

There are three engines to choose from:

DBGvpp# sh crypto engines
Name                Prio    Description
ia32                100     Intel IA32 ISA Optimized Crypto
ipsecmb             80      Intel(R) Multi-Buffer Crypto for IPsec Library 0.52.0
openssl             50      OpenSSL

The engines are all plugins. Each engine registers at a given priority and indicates its capability to support a particular cryptographic algorithm. Not all engines support all algorithms. The engines are listed above in priority order.

DBGvpp# sh crypto handlers 
Algo                Type                Active              Candidates
des-cbc             encrypt             openssl             openssl 
                    decrypt             openssl             openssl 
3des-cbc            encrypt             openssl             openssl 
                    decrypt             openssl             openssl 
aes-128-cbc         encrypt             ia32                ia32 ipsecmb openssl 
                    decrypt             ia32                ia32 ipsecmb openssl 
aes-192-cbc         encrypt             ia32                ia32 ipsecmb openssl 
                    decrypt             ia32                ia32 ipsecmb openssl 
aes-256-cbc         encrypt             ia32                ia32 ipsecmb openssl 
                    decrypt             ia32                ia32 ipsecmb openssl 
aes-128-ctr         encrypt             openssl             openssl 
                    decrypt             openssl             openssl 
aes-192-ctr         encrypt             openssl             openssl 
                    decrypt             openssl             openssl 
aes-256-ctr         encrypt             openssl             openssl 
                    decrypt             openssl             openssl 
aes-128-gcm         aead-encrypt        ipsecmb             ipsecmb openssl 
                    aead-decrypt        ipsecmb             ipsecmb openssl 
aes-192-gcm         aead-encrypt        ipsecmb             ipsecmb openssl 
                    aead-decrypt        ipsecmb             ipsecmb openssl 
aes-256-gcm         aead-encrypt        ipsecmb             ipsecmb openssl 
                    aead-decrypt        ipsecmb             ipsecmb openssl 
hmac-md5            hmac                openssl             openssl 
hmac-sha-1          hmac                ipsecmb             ipsecmb openssl 
hmac-sha-224        hmac                ipsecmb             ipsecmb openssl 
hmac-sha-256        hmac                ipsecmb             ipsecmb openssl 
hmac-sha-384        hmac                ipsecmb             ipsecmb openssl 
hmac-sha-512        hmac                ipsecmb             ipsecmb openssl