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