]>
Commit | Line | Data |
---|---|---|
9f95a23c | 1 | .. SPDX-License-Identifier: BSD-3-Clause |
f67539c2 | 2 | Copyright(c) 2018-2020 Intel Corporation. |
9f95a23c TL |
3 | |
4 | IPsec Packet Processing Library | |
5 | =============================== | |
6 | ||
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 | |
13 | for this library. | |
14 | ||
15 | SA level API | |
16 | ------------ | |
17 | ||
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. | |
21 | ||
22 | To 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 | ||
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. | |
31 | ||
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 | |
34 | the crypto-device. | |
35 | ||
36 | The 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 | ||
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. | |
51 | ||
52 | .. note:: | |
53 | ||
54 | For more details about the IPsec API, please refer to the *DPDK API Reference*. | |
55 | ||
56 | The current implementation supports all four currently defined | |
57 | rte_security types: | |
58 | ||
59 | RTE_SECURITY_ACTION_TYPE_NONE | |
60 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
61 | ||
62 | In 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 | ||
f67539c2 TL |
84 | RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO |
85 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
86 | ||
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. | |
90 | ||
91 | ||
9f95a23c TL |
92 | RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO |
93 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
94 | ||
95 | In 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 | ||
117 | RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL | |
118 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
119 | ||
120 | In 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 | ||
134 | RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL | |
135 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
136 | ||
137 | In 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 | ||
151 | To accommodate future custom implementations function pointers | |
152 | model is used for both *crypto_prepare* and *process* implementations. | |
153 | ||
f67539c2 TL |
154 | SA database API |
155 | ---------------- | |
156 | ||
157 | SA database(SAD) is a table with <key, value> pairs. | |
158 | ||
159 | Value is an opaque user provided pointer to the user defined SA data structure. | |
160 | ||
161 | According to RFC4301 each SA can be uniquely identified by a key | |
162 | which is either: | |
163 | ||
164 | - security parameter index(SPI) | |
165 | - or SPI and destination IP(DIP) | |
166 | - or SPI, DIP and source IP(SIP) | |
167 | ||
168 | In case of multiple matches, longest matching key will be returned. | |
169 | ||
170 | Create/destroy | |
171 | ~~~~~~~~~~~~~~ | |
172 | ||
173 | librte_ipsec SAD implementation provides ability to create/destroy SAD tables. | |
174 | ||
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). | |
177 | As 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 | ||
197 | Add/delete rules | |
198 | ~~~~~~~~~~~~~~~~ | |
199 | ||
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: | |
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 | ||
211 | As 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 | ||
231 | To delete user has to specify key and key type. | |
232 | ||
233 | Delete 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 | ||
248 | Lookup | |
249 | ~~~~~~ | |
250 | Library provides lookup by the given {SPI,DIP,SIP} tuple of | |
251 | inbound ipsec packet as a key. | |
252 | ||
253 | The 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 | ||
262 | where 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 | ||
272 | and v6 is a tuple for IPv6: | |
273 | ||
274 | .. code-block:: c | |
275 | ||
276 | struct rte_ipsec_sadv6_key { | |
277 | uint32_t spi; | |
278 | uint8_t dip[16]; | |
279 | uint8_t sip[16]; | |
280 | }; | |
281 | ||
282 | As 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 | ||
9f95a23c TL |
306 | |
307 | Supported 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 | * algorithms: 3DES-CBC, AES-CBC, AES-CTR, AES-GCM, HMAC-SHA1, NULL. | |
317 | ||
318 | ||
319 | Limitations | |
320 | ----------- | |
321 | ||
322 | The following features are not properly supported in the current version: | |
323 | ||
9f95a23c | 324 | * Hard/soft limit for SA lifetime (time interval/byte count). |