xref: /dpdk/lib/pipeline/rte_swx_ipsec.h (revision 89b5642d0d45c22c0ceab57efe3fab3b49ff4324)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2022 Intel Corporation
3  */
4 #ifndef __INCLUDE_RTE_SWX_IPSEC_H__
5 #define __INCLUDE_RTE_SWX_IPSEC_H__
6 
7 /**
8  * @file
9  * RTE SWX Internet Protocol Security (IPsec)
10  *
11  * The IPsec block is a companion block for the SWX pipeline used to provide IPsec support to the
12  * pipeline. The block is external to the pipeline, hence it needs to be explicitly instantiated by
13  * the user and connected to a pipeline instance through the pipeline I/O ports.
14  *
15  * Main features:
16  * - IPsec inbound (encrypted input packets -> clear text output packets) and outbound (clear text
17  *   input packets -> encrypted output packets) processing support for tunnel and transport modes.
18  *
19  * Security Association (SA):
20  * - Each IPsec block instance has its own set of SAs used to process the input packets. Each SA is
21  *   identified by its unique SA ID. The IPsec inbound and outbound SAs share the same ID space.
22  * - Each input packet is first mapped to one of the existing SAs by using the SA ID and then
23  *   processed according to the identified SA. The SA ID is read from input packet. The SA ID field
24  *   is typically written by the pipeline before sending the packet to the IPsec block.
25  *
26  * Packet format:
27  * - IPsec block input packet (i.e. pipeline output packet):
28  *	- IPsec block meta-data header: @see struct rte_swx_ipsec_input_packet_metadata.
29  *	- IPv4 header.
30  *	- IPv4 payload: on the inbound path, it includes the encrypted ESP packet.
31  * - IPsec block output packet (i.e. pipeline input packet):
32  *	- IPv4 header.
33  *	- IPv4 payload: on the outbound path, it includes the encrypted ESP packet.
34  *
35  * SA update procedure:
36  * - To add a new SA, @see function rte_swx_ipsec_sa_add().
37  * - To delete an existing SA, @see function rte_swx_ipsec_sa_delete().
38  * - To update an existing SA, the control plane has to follow the following steps:
39  *   1. Add a new SA with potentially a different set of configuration parameters. This step can
40  *      fail, for example when the SA table is full.
41  *   2. Wait until no more packets are using the old SA.
42  *   3. Delete the old SA.
43  */
44 
45 #include <stdint.h>
46 #include <stdio.h>
47 #include <netinet/in.h>
48 
49 #include <rte_compat.h>
50 #include <rte_crypto_sym.h>
51 
52 #ifdef __cplusplus
53 extern "C" {
54 #endif
55 
56 /**
57  * IPsec Setup API
58  */
59 
60 /** IPsec instance opaque data structure. */
61 struct rte_swx_ipsec;
62 
63 /** Name size. */
64 #ifndef RTE_SWX_IPSEC_NAME_SIZE
65 #define RTE_SWX_IPSEC_NAME_SIZE 64
66 #endif
67 
68 /** Maximum burst size. */
69 #ifndef RTE_SWX_IPSEC_BURST_SIZE_MAX
70 #define RTE_SWX_IPSEC_BURST_SIZE_MAX 256
71 #endif
72 
73 /** IPsec burst sizes. */
74 struct rte_swx_ipsec_burst_size {
75 	/** Input ring read burst size. */
76 	uint32_t ring_rd;
77 
78 	/** Output ring write burst size. */
79 	uint32_t ring_wr;
80 
81 	/** Crypto device request queue write burst size. */
82 	uint32_t crypto_wr;
83 
84 	/** Crypto device response queue read burst size. */
85 	uint32_t crypto_rd;
86 };
87 
88 /**
89  * IPsec instance configuration parameters
90  */
91 struct rte_swx_ipsec_params {
92 	/** Input packet queue. */
93 	const char *ring_in_name;
94 
95 	/** Output packet queue.  */
96 	const char *ring_out_name;
97 
98 	/** Crypto device name. */
99 	const char *crypto_dev_name;
100 
101 	/** Crypto device queue pair ID. */
102 	uint32_t crypto_dev_queue_pair_id;
103 
104 	/** Burst size. */
105 	struct rte_swx_ipsec_burst_size bsz;
106 
107 	/** Maximum number of SAs. */
108 	uint32_t n_sa_max;
109 };
110 
111 /**
112  * IPsec input packet meta-data
113  */
114 struct rte_swx_ipsec_input_packet_metadata {
115 	/* SA ID. */
116 	uint32_t sa_id;
117 };
118 
119 /**
120  * IPsec instance find
121  *
122  * @param[in] name
123  *   IPsec instance name.
124  * @return
125  *   Valid IPsec instance handle if found or NULL otherwise.
126  */
127 __rte_experimental
128 struct rte_swx_ipsec *
129 rte_swx_ipsec_find(const char *name);
130 
131 /**
132  * IPsec instance create
133  *
134  * @param[out] ipsec
135  *   IPsec instance handle. Must point to valid memory. Contains valid pipeline handle once this
136  *   function returns successfully.
137  * @param[in] name
138  *   IPsec instance unique name.
139  * @param[in] params
140  *   IPsec instance configuration parameters.
141  * @param[in] numa_node
142  *   Non-Uniform Memory Access (NUMA) node.
143  * @return
144  *   0 on success or the following error codes otherwise:
145  *   -EINVAL: Invalid argument;
146  *   -ENOMEM: Not enough space/cannot allocate memory;
147  *   -EEXIST: Pipeline with this name already exists.
148  */
149 __rte_experimental
150 int
151 rte_swx_ipsec_create(struct rte_swx_ipsec **ipsec,
152 		     const char *name,
153 		     struct rte_swx_ipsec_params *params,
154 		     int numa_node);
155 
156 /**
157  * IPsec instance free
158  *
159  * @param[in] ipsec
160  *   IPsec instance handle.
161  */
162 __rte_experimental
163 void
164 rte_swx_ipsec_free(struct rte_swx_ipsec *ipsec);
165 
166 /**
167  * IPsec Data Plane API
168  */
169 
170 /**
171  * IPsec instance run
172  *
173  * @param[in] ipsec
174  *   IPsec instance handle.
175  */
176 __rte_experimental
177 void
178 rte_swx_ipsec_run(struct rte_swx_ipsec *ipsec);
179 
180 /*
181  * IPsec Control Plane API
182  */
183 
184 /** Maximum key size in bytes. */
185 #define RTE_SWX_IPSEC_KEY_SIZE_MAX 64
186 
187 /** IPsec SA crypto cipher parameters. */
188 struct rte_swx_ipsec_sa_cipher_params {
189 	/** Cipher algorithm. */
190 	enum rte_crypto_cipher_algorithm alg;
191 
192 	/** Cipher key. */
193 	uint8_t key[RTE_SWX_IPSEC_KEY_SIZE_MAX];
194 
195 	/** Cipher key size in bytes. */
196 	uint32_t key_size;
197 };
198 
199 /** IPsec SA crypto authentication parameters. */
200 struct rte_swx_ipsec_sa_authentication_params {
201 	/** Authentication algorithm. */
202 	enum rte_crypto_auth_algorithm alg;
203 
204 	/** Authentication key. */
205 	uint8_t key[RTE_SWX_IPSEC_KEY_SIZE_MAX];
206 
207 	/** Authentication key size in bytes. */
208 	uint32_t key_size;
209 };
210 
211 /** IPsec SA crypto Authenticated Encryption with Associated Data (AEAD) parameters. */
212 struct rte_swx_ipsec_sa_aead_params {
213 	/** AEAD algorithm. */
214 	enum rte_crypto_aead_algorithm alg;
215 
216 	/** AEAD key. */
217 	uint8_t key[RTE_SWX_IPSEC_KEY_SIZE_MAX];
218 
219 	/** AEAD key size in bytes. */
220 	uint32_t key_size;
221 };
222 
223 /** IPsec protocol encapsulation parameters. */
224 struct rte_swx_ipsec_sa_encap_params {
225 	/** Encapsulating Security Payload (ESP) header. */
226 	struct {
227 		/** Security Parameters Index (SPI) field. */
228 		uint32_t spi;
229 	} esp;
230 
231 	/** Tunnel mode when non-zero, transport mode when zero. */
232 	int tunnel_mode;
233 
234 	/** Tunnel type: Non-zero for IPv4, zero for IPv6. Valid for tunnel mode only. */
235 	int tunnel_ipv4;
236 
237 	/** Tunnel parameters. Valid for tunnel mode only. */
238 	union {
239 		/** IPv4 header. */
240 		struct {
241 			/** Source address. */
242 			struct in_addr src_addr;
243 
244 			/** Destination address. */
245 			struct in_addr dst_addr;
246 		} ipv4;
247 
248 		/** IPv6 header. */
249 		struct {
250 			/** Source address. */
251 			struct in6_addr src_addr;
252 
253 			/** Destination address. */
254 			struct in6_addr dst_addr;
255 		} ipv6;
256 	} tunnel;
257 };
258 
259 /** IPsec Security Association (SA) parameters. */
260 struct rte_swx_ipsec_sa_params {
261 	/** Crypto operation: encrypt when non-zero, decrypt when zero. */
262 	int encrypt;
263 
264 	/** Crypto operation parameters. */
265 	struct {
266 		union {
267 			struct {
268 				/** Crypto cipher operation parameters. */
269 				struct rte_swx_ipsec_sa_cipher_params cipher;
270 
271 				/** Crypto authentication operation parameters. */
272 				struct rte_swx_ipsec_sa_authentication_params auth;
273 			} cipher_auth;
274 
275 			/** Crypto AEAD operation parameters. */
276 			struct rte_swx_ipsec_sa_aead_params aead;
277 		};
278 
279 		/** Non-zero for AEAD, zero for cipher & authentication. */
280 		int is_aead;
281 	} crypto;
282 
283 	/** Packet encasulation parameters. */
284 	struct rte_swx_ipsec_sa_encap_params encap;
285 };
286 
287 /**
288  * IPsec SA add
289  *
290  * @param[in] ipsec
291  *   IPsec instance handle.
292  * @param[in] sa_params
293  *   SA parameters.
294  * @param[out] sa_id
295  *   On success, the SA ID.
296  * @return
297  *   0 on success or error code otherwise.
298  */
299 __rte_experimental
300 int
301 rte_swx_ipsec_sa_add(struct rte_swx_ipsec *ipsec,
302 		     struct rte_swx_ipsec_sa_params *sa_params,
303 		     uint32_t *sa_id);
304 
305 /**
306  * IPsec SA delete
307  *
308  * It is the responibility of the Control Plane to make sure the SA to be deleted is no longer used
309  * by the Data Plane.
310  *
311  * @param[in] ipsec
312  *   IPsec instance handle.
313  * @param[in] sa_id
314  *   The SA ID.
315  */
316 __rte_experimental
317 void
318 rte_swx_ipsec_sa_delete(struct rte_swx_ipsec *ipsec,
319 			uint32_t sa_id);
320 
321 /**
322  * IPsec SA read from string
323  *
324  * IPsec SA syntax:
325  *
326  * \<sa>
327  *    : encrypt \<crypto_params> \<encap_params>
328  *    | decrypt \<crypto_params> \<encap_params>
329  *    ;
330  *
331  * \<crypto_params>
332  *    : \<cipher> \<auth>
333  *    | \<aead>
334  *    ;
335  *
336  * \<cipher>
337  *    : cipher \<ciher_alg> key \<cipher_key>
338  *    | cipher \<cipher_alg>
339  *    ;
340  *
341  * \<auth>
342  *    : auth \<authentication_alg> key \<authentication_key>
343  *    | auth \<authentication_alg>
344  *    ;
345  *
346  * \<aead>
347  *    : aead \<aead_alg> key \<aead_key>
348  *    ;
349  *
350  * \<encap_params>
351  *    : esp spi \<spi> tunnel ipv4 srcaddr \<ipv4_src_addr> dstaddr \<ipv4_dst_addr>
352  *    | esp spi \<spi> tunnel ipv6 srcaddr \<ipv6_src_addr> dstaddr \<ipv6_dst_addr>
353  *    | esp spi \<spi> transport
354  *    ;
355  *
356  * @param[in] ipsec
357  *   IPsec instance handle.
358  * @param[in] string
359  *   String containing the SA.
360  * @param[in,out] is_blank_or_comment
361  *   On error, when its input value is not NULL, this argument is set to a non-zero value when
362  *   *string* contains a blank or comment line and to zero otherwise.
363  * @param[in,out] errmsg
364  *   On error, when its input value is not NULL, this argument points to a string with details on
365  *   the detected error.
366  * @return
367  *   Pointer to valid IPsec SA parameters data structure on success or NULL on error.
368  */
369 __rte_experimental
370 struct rte_swx_ipsec_sa_params *
371 rte_swx_ipsec_sa_read(struct rte_swx_ipsec *ipsec,
372 		      const char *string,
373 		      int *is_blank_or_comment,
374 		      const char **errmsg);
375 
376 #ifdef __cplusplus
377 }
378 #endif
379 
380 #endif
381