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