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