1.. SPDX-License-Identifier: BSD-3-Clause 2 Copyright(c) 2018-2020 Intel Corporation. 3 4IPsec Packet Processing Library 5=============================== 6 7DPDK provides a library for IPsec data-path processing. 8The library utilizes the existing DPDK crypto-dev and 9security API to provide the application with a transparent and 10high performant IPsec packet processing API. 11The library is concentrated on data-path protocols processing 12(ESP and AH), IKE protocol(s) implementation is out of scope 13for this library. 14 15SA level API 16------------ 17 18This API operates on the IPsec Security Association (SA) level. 19It provides functionality that allows user for given SA to process 20inbound and outbound IPsec packets. 21 22To be more specific: 23 24* for inbound ESP/AH packets perform decryption, authentication, integrity checking, remove ESP/AH related headers 25* for outbound packets perform payload encryption, attach ICV, update/add IP headers, add ESP/AH headers/trailers, 26* setup related mbuf fields (ol_flags, tx_offloads, etc.). 27* initialize/un-initialize given SA based on user provided parameters. 28 29The SA level API is based on top of crypto-dev/security API and relies on 30them to perform actual cipher and integrity checking. 31 32Due to the nature of the crypto-dev API (enqueue/dequeue model) the library 33introduces an asynchronous API for IPsec packets destined to be processed by 34the crypto-device. 35 36The expected API call sequence for data-path processing would be: 37 38.. code-block:: c 39 40 /* enqueue for processing by crypto-device */ 41 rte_ipsec_pkt_crypto_prepare(...); 42 rte_cryptodev_enqueue_burst(...); 43 /* dequeue from crypto-device and do final processing (if any) */ 44 rte_cryptodev_dequeue_burst(...); 45 rte_ipsec_pkt_crypto_group(...); /* optional */ 46 rte_ipsec_pkt_process(...); 47 48For packets destined for inline processing no extra overhead 49is required and the synchronous API call: rte_ipsec_pkt_process() 50is sufficient for that case. 51 52.. note:: 53 54 For more details about the IPsec API, please refer to the *DPDK API Reference*. 55 56The current implementation supports all four currently defined 57rte_security types: 58 59RTE_SECURITY_ACTION_TYPE_NONE 60~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 61 62In that mode the library functions perform 63 64* for inbound packets: 65 66 - check SQN 67 - prepare *rte_crypto_op* structure for each input packet 68 - verify that integrity check and decryption performed by crypto device 69 completed successfully 70 - check padding data 71 - remove outer IP header (tunnel mode) / update IP header (transport mode) 72 - remove ESP header and trailer, padding, IV and ICV data 73 - update SA replay window 74 75* for outbound packets: 76 77 - generate SQN and IV 78 - add outer IP header (tunnel mode) / update IP header (transport mode) 79 - add ESP header and trailer, padding and IV data 80 - prepare *rte_crypto_op* structure for each input packet 81 - verify that crypto device operations (encryption, ICV generation) 82 were completed successfully 83 84RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO 85~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 86 87In that mode the library functions perform same operations as in 88``RTE_SECURITY_ACTION_TYPE_NONE``. The only difference is that crypto operations 89are performed with CPU crypto synchronous API. 90 91 92RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO 93~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 94 95In that mode the library functions perform 96 97* for inbound packets: 98 99 - verify that integrity check and decryption performed by *rte_security* 100 device completed successfully 101 - check SQN 102 - check padding data 103 - remove outer IP header (tunnel mode) / update IP header (transport mode) 104 - remove ESP header and trailer, padding, IV and ICV data 105 - update SA replay window 106 107* for outbound packets: 108 109 - generate SQN and IV 110 - add outer IP header (tunnel mode) / update IP header (transport mode) 111 - add ESP header and trailer, padding and IV data 112 - update *ol_flags* inside *struct rte_mbuf* to indicate that 113 inline-crypto processing has to be performed by HW on this packet 114 - invoke *rte_security* device specific *set_pkt_metadata()* to associate 115 security device specific data with the packet 116 117RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL 118~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 119 120In that mode the library functions perform 121 122* for inbound packets: 123 124 - verify that integrity check and decryption performed by *rte_security* 125 device completed successfully 126 127* for outbound packets: 128 129 - update *ol_flags* inside *struct rte_mbuf* to indicate that 130 inline-crypto processing has to be performed by HW on this packet 131 - invoke *rte_security* device specific *set_pkt_metadata()* to associate 132 security device specific data with the packet 133 134RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL 135~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 136 137In that mode the library functions perform 138 139* for inbound packets: 140 141 - prepare *rte_crypto_op* structure for each input packet 142 - verify that integrity check and decryption performed by crypto device 143 completed successfully 144 145* for outbound packets: 146 147 - prepare *rte_crypto_op* structure for each input packet 148 - verify that crypto device operations (encryption, ICV generation) 149 were completed successfully 150 151To accommodate future custom implementations function pointers 152model is used for both *crypto_prepare* and *process* implementations. 153 154SA database API 155---------------- 156 157SA database(SAD) is a table with <key, value> pairs. 158 159Value is an opaque user provided pointer to the user defined SA data structure. 160 161According to RFC4301 each SA can be uniquely identified by a key 162which is either: 163 164 - security parameter index(SPI) 165 - or SPI and destination IP(DIP) 166 - or SPI, DIP and source IP(SIP) 167 168In case of multiple matches, longest matching key will be returned. 169 170Create/destroy 171~~~~~~~~~~~~~~ 172 173librte_ipsec SAD implementation provides ability to create/destroy SAD tables. 174 175To create SAD table user has to specify how many entries of each key type is 176required and IP protocol type (IPv4/IPv6). 177As an example: 178 179 180.. code-block:: c 181 182 struct rte_ipsec_sad *sad; 183 struct rte_ipsec_sad_conf conf; 184 185 conf.socket_id = -1; 186 conf.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = some_nb_rules_spi_only; 187 conf.max_sa[RTE_IPSEC_SAD_SPI_DIP] = some_nb_rules_spi_dip; 188 conf.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = some_nb_rules_spi_dip_sip; 189 conf.flags = RTE_IPSEC_SAD_FLAG_RW_CONCURRENCY; 190 191 sad = rte_ipsec_sad_create("test", &conf); 192 193.. note:: 194 195 for more information please refer to ipsec library API reference 196 197Add/delete rules 198~~~~~~~~~~~~~~~~ 199 200Library also provides methods to add or delete key/value pairs from the SAD. 201To add user has to specify key, key type and a value which is an opaque pointer to SA. 202The key type reflects a set of tuple fields that will be used for lookup of the SA. 203As mentioned above there are 3 types of a key and the representation of a key type is: 204 205.. code-block:: c 206 207 RTE_IPSEC_SAD_SPI_ONLY, 208 RTE_IPSEC_SAD_SPI_DIP, 209 RTE_IPSEC_SAD_SPI_DIP_SIP, 210 211As an example, to add new entry into the SAD for IPv4 addresses: 212 213.. code-block:: c 214 215 struct rte_ipsec_sa *sa; 216 union rte_ipsec_sad_key key; 217 218 key.v4.spi = rte_cpu_to_be_32(spi_val); 219 if (key_type >= RTE_IPSEC_SAD_SPI_DIP) /* DIP is optional*/ 220 key.v4.dip = rte_cpu_to_be_32(dip_val); 221 if (key_type == RTE_IPSEC_SAD_SPI_DIP_SIP) /* SIP is optional*/ 222 key.v4.sip = rte_cpu_to_be_32(sip_val); 223 224 rte_ipsec_sad_add(sad, &key, key_type, sa); 225 226.. note:: 227 228 By performance reason it is better to keep spi/dip/sip in net byte order 229 to eliminate byteswap on lookup 230 231To delete user has to specify key and key type. 232 233Delete code would look like: 234 235.. code-block:: c 236 237 union rte_ipsec_sad_key key; 238 239 key.v4.spi = rte_cpu_to_be_32(necessary_spi); 240 if (key_type >= RTE_IPSEC_SAD_SPI_DIP) /* DIP is optional*/ 241 key.v4.dip = rte_cpu_to_be_32(necessary_dip); 242 if (key_type == RTE_IPSEC_SAD_SPI_DIP_SIP) /* SIP is optional*/ 243 key.v4.sip = rte_cpu_to_be_32(necessary_sip); 244 245 rte_ipsec_sad_del(sad, &key, key_type); 246 247 248Lookup 249~~~~~~ 250Library provides lookup by the given {SPI,DIP,SIP} tuple of 251inbound ipsec packet as a key. 252 253The search key is represented by: 254 255.. code-block:: c 256 257 union rte_ipsec_sad_key { 258 struct rte_ipsec_sadv4_key v4; 259 struct rte_ipsec_sadv6_key v6; 260 }; 261 262where v4 is a tuple for IPv4: 263 264.. code-block:: c 265 266 struct rte_ipsec_sadv4_key { 267 uint32_t spi; 268 uint32_t dip; 269 uint32_t sip; 270 }; 271 272and v6 is a tuple for IPv6: 273 274.. code-block:: c 275 276 struct rte_ipsec_sadv6_key { 277 uint32_t spi; 278 struct rte_ipv6_addr dip; 279 struct rte_ipv6_addr sip; 280 }; 281 282As an example, lookup related code could look like that: 283 284.. code-block:: c 285 286 int i; 287 union rte_ipsec_sad_key keys[BURST_SZ]; 288 const union rte_ipsec_sad_key *keys_p[BURST_SZ]; 289 void *vals[BURST_SZ]; 290 291 for (i = 0; i < BURST_SZ_MAX; i++) { 292 keys[i].v4.spi = esp_hdr[i]->spi; 293 keys[i].v4.dip = ipv4_hdr[i]->dst_addr; 294 keys[i].v4.sip = ipv4_hdr[i]->src_addr; 295 keys_p[i] = &keys[i]; 296 } 297 rte_ipsec_sad_lookup(sad, keys_p, vals, BURST_SZ); 298 299 for (i = 0; i < BURST_SZ_MAX; i++) { 300 if (vals[i] == NULL) 301 printf("SA not found for key index %d\n", i); 302 else 303 printf("SA pointer is %p\n", vals[i]); 304 } 305 306 307Supported features 308------------------ 309 310* ESP protocol tunnel mode both IPv4/IPv6. 311 312* ESP protocol transport mode both IPv4/IPv6. 313 314* ESN and replay window. 315 316* NAT-T / UDP encapsulated ESP. 317 318* TSO (only for inline crypto mode) 319 320* algorithms: 3DES-CBC, AES-CBC, AES-CTR, AES-GCM, AES_CCM, CHACHA20_POLY1305, 321 AES_GMAC, HMAC-SHA1, NULL. 322 323 324Telemetry support 325------------------ 326 327Telemetry support implements SA details and IPsec packet add data counters 328statistics. Per SA telemetry statistics can be enabled using 329``rte_ipsec_telemetry_sa_add`` and disabled using 330``rte_ipsec_telemetry_sa_del``. Note that these calls are not thread safe. 331 332Stateless IPsec packet processing 333--------------------------------- 334 335Support for stateless IPsec packet processing allows use of custom 336sequence number to be used for IPsec outbound processing. 337 338``rte_ipsec_pkt_stateless_prepare()`` takes as input the state parameter 339from the application and prepares the packet for IPsec processing. 340 341Limitations 342----------- 343 344The following features are not properly supported in the current version: 345 346* Hard/soft limit for SA lifetime (time interval/byte count). 347