1 .. SPDX-License-Identifier: BSD-3-Clause
2 Copyright(c) 2018-2020 Intel Corporation.
4 IPsec Packet Processing Library
5 ===============================
7 DPDK provides a library for IPsec data-path processing.
8 The library utilizes the existing DPDK crypto-dev and
9 security API to provide the application with a transparent and
10 high performant IPsec packet processing API.
11 The library is concentrated on data-path protocols processing
12 (ESP and AH), IKE protocol(s) implementation is out of scope
18 This API operates on the IPsec Security Association (SA) level.
19 It provides functionality that allows user for given SA to process
20 inbound and outbound IPsec packets.
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.
29 The SA level API is based on top of crypto-dev/security API and relies on
30 them to perform actual cipher and integrity checking.
32 Due to the nature of the crypto-dev API (enqueue/dequeue model) the library
33 introduces an asynchronous API for IPsec packets destined to be processed by
36 The expected API call sequence for data-path processing would be:
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(...);
48 For packets destined for inline processing no extra overhead
49 is required and the synchronous API call: rte_ipsec_pkt_process()
50 is sufficient for that case.
54 For more details about the IPsec API, please refer to the *DPDK API Reference*.
56 The current implementation supports all four currently defined
59 RTE_SECURITY_ACTION_TYPE_NONE
60 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
62 In that mode the library functions perform
64 * for inbound packets:
67 - prepare *rte_crypto_op* structure for each input packet
68 - verify that integrity check and decryption performed by crypto device
69 completed successfully
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
75 * for outbound packets:
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
84 RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO
85 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
87 In that mode the library functions perform same operations as in
88 ``RTE_SECURITY_ACTION_TYPE_NONE``. The only difference is that crypto operations
89 are performed with CPU crypto synchronous API.
92 RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO
93 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
95 In that mode the library functions perform
97 * for inbound packets:
99 - verify that integrity check and decryption performed by *rte_security*
100 device completed successfully
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
107 * for outbound packets:
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
117 RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL
118 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
120 In that mode the library functions perform
122 * for inbound packets:
124 - verify that integrity check and decryption performed by *rte_security*
125 device completed successfully
127 * for outbound packets:
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
134 RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL
135 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
137 In that mode the library functions perform
139 * for inbound packets:
141 - prepare *rte_crypto_op* structure for each input packet
142 - verify that integrity check and decryption performed by crypto device
143 completed successfully
145 * for outbound packets:
147 - prepare *rte_crypto_op* structure for each input packet
148 - verify that crypto device operations (encryption, ICV generation)
149 were completed successfully
151 To accommodate future custom implementations function pointers
152 model is used for both *crypto_prepare* and *process* implementations.
157 SA database(SAD) is a table with <key, value> pairs.
159 Value is an opaque user provided pointer to the user defined SA data structure.
161 According to RFC4301 each SA can be uniquely identified by a key
164 - security parameter index(SPI)
165 - or SPI and destination IP(DIP)
166 - or SPI, DIP and source IP(SIP)
168 In case of multiple matches, longest matching key will be returned.
173 librte_ipsec SAD implementation provides ability to create/destroy SAD tables.
175 To create SAD table user has to specify how many entries of each key type is
176 required and IP protocol type (IPv4/IPv6).
182 struct rte_ipsec_sad *sad;
183 struct rte_ipsec_sad_conf conf;
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;
191 sad = rte_ipsec_sad_create("test", &conf);
195 for more information please refer to ipsec library API reference
200 Library also provides methods to add or delete key/value pairs from the SAD.
201 To add user has to specify key, key type and a value which is an opaque pointer to SA.
202 The key type reflects a set of tuple fields that will be used for lookup of the SA.
203 As mentioned above there are 3 types of a key and the representation of a key type is:
207 RTE_IPSEC_SAD_SPI_ONLY,
208 RTE_IPSEC_SAD_SPI_DIP,
209 RTE_IPSEC_SAD_SPI_DIP_SIP,
211 As an example, to add new entry into the SAD for IPv4 addresses:
215 struct rte_ipsec_sa *sa;
216 union rte_ipsec_sad_key key;
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);
224 rte_ipsec_sad_add(sad, &key, key_type, sa);
228 By performance reason it is better to keep spi/dip/sip in net byte order
229 to eliminate byteswap on lookup
231 To delete user has to specify key and key type.
233 Delete code would look like:
237 union rte_ipsec_sad_key key;
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);
245 rte_ipsec_sad_del(sad, &key, key_type);
250 Library provides lookup by the given {SPI,DIP,SIP} tuple of
251 inbound ipsec packet as a key.
253 The search key is represented by:
257 union rte_ipsec_sad_key {
258 struct rte_ipsec_sadv4_key v4;
259 struct rte_ipsec_sadv6_key v6;
262 where v4 is a tuple for IPv4:
266 struct rte_ipsec_sadv4_key {
272 and v6 is a tuple for IPv6:
276 struct rte_ipsec_sadv6_key {
282 As an example, lookup related code could look like that:
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];
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];
297 rte_ipsec_sad_lookup(sad, keys_p, vals, BURST_SZ);
299 for (i = 0; i < BURST_SZ_MAX; i++) {
301 printf("SA not found for key index %d\n", i);
303 printf("SA pointer is %p\n", vals[i]);
310 * ESP protocol tunnel mode both IPv4/IPv6.
312 * ESP protocol transport mode both IPv4/IPv6.
314 * ESN and replay window.
316 * NAT-T / UDP encapsulated ESP.
318 * TSO (only for inline crypto mode)
320 * algorithms: 3DES-CBC, AES-CBC, AES-CTR, AES-GCM, AES_CCM, CHACHA20_POLY1305,
321 AES_GMAC, HMAC-SHA1, NULL.
326 Telemetry support implements SA details and IPsec packet add data counters
327 statistics. Per SA telemetry statistics can be enabled using
328 ``rte_ipsec_telemetry_sa_add`` and disabled using
329 ``rte_ipsec_telemetry_sa_del``. Note that these calls are not thread safe.
335 The following features are not properly supported in the current version:
337 * Hard/soft limit for SA lifetime (time interval/byte count).