xref: /dpdk/lib/pipeline/rte_swx_ipsec.h (revision 5ac1abdd37aa43692603cd8670111c354014766f)
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 #include <rte_ip6.h>
52 
53 #ifdef __cplusplus
54 extern "C" {
55 #endif
56 
57 /**
58  * IPsec Setup API
59  */
60 
61 /** IPsec instance opaque data structure. */
62 struct rte_swx_ipsec;
63 
64 /** Name size. */
65 #ifndef RTE_SWX_IPSEC_NAME_SIZE
66 #define RTE_SWX_IPSEC_NAME_SIZE 64
67 #endif
68 
69 /** Maximum burst size. */
70 #ifndef RTE_SWX_IPSEC_BURST_SIZE_MAX
71 #define RTE_SWX_IPSEC_BURST_SIZE_MAX 256
72 #endif
73 
74 /** IPsec burst sizes. */
75 struct rte_swx_ipsec_burst_size {
76 	/** Input ring read burst size. */
77 	uint32_t ring_rd;
78 
79 	/** Output ring write burst size. */
80 	uint32_t ring_wr;
81 
82 	/** Crypto device request queue write burst size. */
83 	uint32_t crypto_wr;
84 
85 	/** Crypto device response queue read burst size. */
86 	uint32_t crypto_rd;
87 };
88 
89 /**
90  * IPsec instance configuration parameters
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 struct rte_swx_ipsec_input_packet_metadata {
116 	/* SA ID. */
117 	uint32_t sa_id;
118 };
119 
120 /**
121  * IPsec instance find
122  *
123  * @param[in] name
124  *   IPsec instance name.
125  * @return
126  *   Valid IPsec instance handle if found or NULL otherwise.
127  */
128 __rte_experimental
129 struct rte_swx_ipsec *
130 rte_swx_ipsec_find(const char *name);
131 
132 /**
133  * IPsec instance create
134  *
135  * @param[out] ipsec
136  *   IPsec instance handle. Must point to valid memory. Contains valid pipeline handle once this
137  *   function returns successfully.
138  * @param[in] name
139  *   IPsec instance unique name.
140  * @param[in] params
141  *   IPsec instance configuration parameters.
142  * @param[in] numa_node
143  *   Non-Uniform Memory Access (NUMA) node.
144  * @return
145  *   0 on success or the following error codes otherwise:
146  *   -EINVAL: Invalid argument;
147  *   -ENOMEM: Not enough space/cannot allocate memory;
148  *   -EEXIST: Pipeline with this name already exists.
149  */
150 __rte_experimental
151 int
152 rte_swx_ipsec_create(struct rte_swx_ipsec **ipsec,
153 		     const char *name,
154 		     struct rte_swx_ipsec_params *params,
155 		     int numa_node);
156 
157 /**
158  * IPsec instance free
159  *
160  * @param[in] ipsec
161  *   IPsec instance handle.
162  */
163 __rte_experimental
164 void
165 rte_swx_ipsec_free(struct rte_swx_ipsec *ipsec);
166 
167 /**
168  * IPsec Data Plane API
169  */
170 
171 /**
172  * IPsec instance run
173  *
174  * @param[in] ipsec
175  *   IPsec instance handle.
176  */
177 __rte_experimental
178 void
179 rte_swx_ipsec_run(struct rte_swx_ipsec *ipsec);
180 
181 /*
182  * IPsec Control Plane API
183  */
184 
185 /** Maximum key size in bytes. */
186 #define RTE_SWX_IPSEC_KEY_SIZE_MAX 64
187 
188 /** IPsec SA crypto cipher parameters. */
189 struct rte_swx_ipsec_sa_cipher_params {
190 	/** Cipher algorithm. */
191 	enum rte_crypto_cipher_algorithm alg;
192 
193 	/** Cipher key. */
194 	uint8_t key[RTE_SWX_IPSEC_KEY_SIZE_MAX];
195 
196 	/** Cipher key size in bytes. */
197 	uint32_t key_size;
198 };
199 
200 /** IPsec SA crypto authentication parameters. */
201 struct rte_swx_ipsec_sa_authentication_params {
202 	/** Authentication algorithm. */
203 	enum rte_crypto_auth_algorithm alg;
204 
205 	/** Authentication key. */
206 	uint8_t key[RTE_SWX_IPSEC_KEY_SIZE_MAX];
207 
208 	/** Authentication key size in bytes. */
209 	uint32_t key_size;
210 };
211 
212 /** IPsec SA crypto Authenticated Encryption with Associated Data (AEAD) parameters. */
213 struct rte_swx_ipsec_sa_aead_params {
214 	/** AEAD algorithm. */
215 	enum rte_crypto_aead_algorithm alg;
216 
217 	/** AEAD key. */
218 	uint8_t key[RTE_SWX_IPSEC_KEY_SIZE_MAX];
219 
220 	/** AEAD key size in bytes. */
221 	uint32_t key_size;
222 };
223 
224 /** IPsec protocol encapsulation parameters. */
225 struct rte_swx_ipsec_sa_encap_params {
226 	/** Encapsulating Security Payload (ESP) header. */
227 	struct {
228 		/** Security Parameters Index (SPI) field. */
229 		uint32_t spi;
230 	} esp;
231 
232 	/** Tunnel mode when non-zero, transport mode when zero. */
233 	int tunnel_mode;
234 
235 	/** Tunnel type: Non-zero for IPv4, zero for IPv6. Valid for tunnel mode only. */
236 	int tunnel_ipv4;
237 
238 	/** Tunnel parameters. Valid for tunnel mode only. */
239 	union {
240 		/** IPv4 header. */
241 		struct {
242 			/** Source address. */
243 			struct in_addr src_addr;
244 
245 			/** Destination address. */
246 			struct in_addr dst_addr;
247 		} ipv4;
248 
249 		/** IPv6 header. */
250 		struct {
251 			/** Source address. */
252 			struct rte_ipv6_addr src_addr;
253 
254 			/** Destination address. */
255 			struct rte_ipv6_addr dst_addr;
256 		} ipv6;
257 	} tunnel;
258 };
259 
260 /** IPsec Security Association (SA) parameters. */
261 struct rte_swx_ipsec_sa_params {
262 	/** Crypto operation: encrypt when non-zero, decrypt when zero. */
263 	int encrypt;
264 
265 	/** Crypto operation parameters. */
266 	struct {
267 		union {
268 			struct {
269 				/** Crypto cipher operation parameters. */
270 				struct rte_swx_ipsec_sa_cipher_params cipher;
271 
272 				/** Crypto authentication operation parameters. */
273 				struct rte_swx_ipsec_sa_authentication_params auth;
274 			} cipher_auth;
275 
276 			/** Crypto AEAD operation parameters. */
277 			struct rte_swx_ipsec_sa_aead_params aead;
278 		};
279 
280 		/** Non-zero for AEAD, zero for cipher & authentication. */
281 		int is_aead;
282 	} crypto;
283 
284 	/** Packet encasulation parameters. */
285 	struct rte_swx_ipsec_sa_encap_params encap;
286 };
287 
288 /**
289  * IPsec SA add
290  *
291  * @param[in] ipsec
292  *   IPsec instance handle.
293  * @param[in] sa_params
294  *   SA parameters.
295  * @param[out] sa_id
296  *   On success, the SA ID.
297  * @return
298  *   0 on success or error code otherwise.
299  */
300 __rte_experimental
301 int
302 rte_swx_ipsec_sa_add(struct rte_swx_ipsec *ipsec,
303 		     struct rte_swx_ipsec_sa_params *sa_params,
304 		     uint32_t *sa_id);
305 
306 /**
307  * IPsec SA delete
308  *
309  * It is the responibility of the Control Plane to make sure the SA to be deleted is no longer used
310  * by the Data Plane.
311  *
312  * @param[in] ipsec
313  *   IPsec instance handle.
314  * @param[in] sa_id
315  *   The SA ID.
316  */
317 __rte_experimental
318 void
319 rte_swx_ipsec_sa_delete(struct rte_swx_ipsec *ipsec,
320 			uint32_t sa_id);
321 
322 /**
323  * IPsec SA read from string
324  *
325  * IPsec SA syntax:
326  *
327  * \<sa>
328  *    : encrypt \<crypto_params> \<encap_params>
329  *    | decrypt \<crypto_params> \<encap_params>
330  *    ;
331  *
332  * \<crypto_params>
333  *    : \<cipher> \<auth>
334  *    | \<aead>
335  *    ;
336  *
337  * \<cipher>
338  *    : cipher \<ciher_alg> key \<cipher_key>
339  *    | cipher \<cipher_alg>
340  *    ;
341  *
342  * \<auth>
343  *    : auth \<authentication_alg> key \<authentication_key>
344  *    | auth \<authentication_alg>
345  *    ;
346  *
347  * \<aead>
348  *    : aead \<aead_alg> key \<aead_key>
349  *    ;
350  *
351  * \<encap_params>
352  *    : esp spi \<spi> tunnel ipv4 srcaddr \<ipv4_src_addr> dstaddr \<ipv4_dst_addr>
353  *    | esp spi \<spi> tunnel ipv6 srcaddr \<ipv6_src_addr> dstaddr \<ipv6_dst_addr>
354  *    | esp spi \<spi> transport
355  *    ;
356  *
357  * @param[in] ipsec
358  *   IPsec instance handle.
359  * @param[in] string
360  *   String containing the SA.
361  * @param[in,out] is_blank_or_comment
362  *   On error, when its input value is not NULL, this argument is set to a non-zero value when
363  *   *string* contains a blank or comment line and to zero otherwise.
364  * @param[in,out] errmsg
365  *   On error, when its input value is not NULL, this argument points to a string with details on
366  *   the detected error.
367  * @return
368  *   Pointer to valid IPsec SA parameters data structure on success or NULL on error.
369  */
370 __rte_experimental
371 struct rte_swx_ipsec_sa_params *
372 rte_swx_ipsec_sa_read(struct rte_swx_ipsec *ipsec,
373 		      const char *string,
374 		      int *is_blank_or_comment,
375 		      const char **errmsg);
376 
377 #ifdef __cplusplus
378 }
379 #endif
380 
381 #endif
382