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