1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2016-2017 Intel Corporation 3 */ 4 5 #ifndef _RTE_CRYPTO_H_ 6 #define _RTE_CRYPTO_H_ 7 8 /** 9 * @file rte_crypto.h 10 * 11 * RTE Cryptography Common Definitions 12 */ 13 14 15 #include <rte_mbuf.h> 16 #include <rte_memory.h> 17 #include <rte_mempool.h> 18 #include <rte_common.h> 19 20 #include "rte_crypto_sym.h" 21 #include "rte_crypto_asym.h" 22 23 #ifdef __cplusplus 24 extern "C" { 25 #endif 26 27 /** Crypto operation types */ 28 enum rte_crypto_op_type { 29 RTE_CRYPTO_OP_TYPE_UNDEFINED, 30 /**< Undefined operation type */ 31 RTE_CRYPTO_OP_TYPE_SYMMETRIC, 32 /**< Symmetric operation */ 33 RTE_CRYPTO_OP_TYPE_ASYMMETRIC 34 /**< Asymmetric operation */ 35 }; 36 37 /** Status of crypto operation */ 38 enum rte_crypto_op_status { 39 RTE_CRYPTO_OP_STATUS_SUCCESS, 40 /**< Operation completed successfully */ 41 RTE_CRYPTO_OP_STATUS_NOT_PROCESSED, 42 /**< Operation has not yet been processed by a crypto device */ 43 RTE_CRYPTO_OP_STATUS_AUTH_FAILED, 44 /**< Authentication verification failed */ 45 RTE_CRYPTO_OP_STATUS_INVALID_SESSION, 46 /**< 47 * Symmetric operation failed due to invalid session arguments, or if 48 * in session-less mode, failed to allocate private operation material. 49 */ 50 RTE_CRYPTO_OP_STATUS_INVALID_ARGS, 51 /**< Operation failed due to invalid arguments in request */ 52 RTE_CRYPTO_OP_STATUS_ERROR, 53 /**< Error handling operation */ 54 }; 55 56 /** 57 * Crypto operation session type. This is used to specify whether a crypto 58 * operation has session structure attached for immutable parameters or if all 59 * operation information is included in the operation data structure. 60 */ 61 enum rte_crypto_op_sess_type { 62 RTE_CRYPTO_OP_WITH_SESSION, /**< Session based crypto operation */ 63 RTE_CRYPTO_OP_SESSIONLESS, /**< Session-less crypto operation */ 64 RTE_CRYPTO_OP_SECURITY_SESSION /**< Security session crypto operation */ 65 }; 66 67 /* Auxiliary flags related to crypto operation */ 68 #define RTE_CRYPTO_OP_AUX_FLAGS_SESS_SOFT_EXPIRY (1 << 0) 69 /**< Session soft expiry limit has been reached. 70 * Applicable for any session that has a soft lifetime feature supported. 71 * 72 * @see rte_security_ipsec_lifetime 73 * @see rte_security_tls_record_lifetime 74 */ 75 76 /* Auxiliary flags related to IPsec offload with RTE_SECURITY */ 77 78 #define RTE_CRYPTO_OP_AUX_FLAGS_IPSEC_SOFT_EXPIRY RTE_CRYPTO_OP_AUX_FLAGS_SESS_SOFT_EXPIRY 79 /**< SA soft expiry limit has been reached */ 80 81 /** 82 * Cryptographic Operation. 83 * 84 * This structure contains data relating to performing cryptographic 85 * operations. This operation structure is used to contain any operation which 86 * is supported by the cryptodev API, PMDs should check the type parameter to 87 * verify that the operation is a support function of the device. Crypto 88 * operations are enqueued and dequeued in crypto PMDs using the 89 * rte_cryptodev_enqueue_burst() / rte_cryptodev_dequeue_burst() . 90 */ 91 struct rte_crypto_op { 92 __extension__ 93 union { 94 uint64_t raw; 95 __extension__ 96 struct { 97 uint8_t type; 98 /**< operation type */ 99 uint8_t status; 100 /**< 101 * operation status - this is reset to 102 * RTE_CRYPTO_OP_STATUS_NOT_PROCESSED on allocation 103 * from mempool and will be set to 104 * RTE_CRYPTO_OP_STATUS_SUCCESS after crypto operation 105 * is successfully processed by a crypto PMD 106 */ 107 uint8_t sess_type; 108 /**< operation session type */ 109 uint8_t aux_flags; 110 /**< Operation specific auxiliary/additional flags. 111 * These flags carry additional information from/to the 112 * operation. Processing of the same is optional. 113 * 114 * The flags are defined as RTE_CRYPTO_OP_AUX_FLAGS_* and 115 * would be set by PMD for application consumption when 116 * the status is RTE_CRYPTO_OP_STATUS_SUCCESS. 117 * In case of errors, the value of this field is undefined. 118 * 119 * With TLS record offload (RTE_SECURITY_PROTOCOL_TLS_RECORD), 120 * application may provide the extra padding required for the plaintext 121 * provided. This field can be used for passing the same in units of 8B. 122 * The value would be set by application for PMD consumption. 123 * 124 * @see struct rte_security_tls_record_sess_options 125 */ 126 union { 127 struct { 128 uint8_t content_type; 129 /**< Content type. The field can act both as input 130 * and output. 131 * 132 * As input, for passing message type in case of record 133 * write (encrypt) operation. Applicable for, 134 * 1. TLS 1.2 135 * 2. TLS 1.3 136 * 3. DTLS 1.2 137 * 138 * As output, for returning message type in case of record 139 * read (decrypt) operation. Applicable for, 140 * 1. TLS 1.3 141 * 142 * Message types are listed as RTE_TLS_TYPE_* and 143 * RTE_DTLS_TYPE_*. 144 */ 145 } tls_record; 146 /**< TLS record */ 147 } param1; 148 /**< Additional per operation parameter 1. */ 149 uint8_t reserved[1]; 150 /**< Reserved bytes to fill 64 bits for 151 * future additions 152 */ 153 uint16_t private_data_offset; 154 /**< Offset to indicate start of private data (if any). 155 * The offset is counted from the start of the 156 * rte_crypto_op including IV. 157 * The private data may be used by the application 158 * to store information which should remain untouched 159 * in the library/driver 160 */ 161 }; 162 }; 163 struct rte_mempool *mempool; 164 /**< crypto operation mempool which operation is allocated from */ 165 166 rte_iova_t phys_addr; 167 /**< physical address of crypto operation */ 168 169 /* empty structures do not have zero size in C++ leading to compilation errors 170 * with clang about structure/union having different sizes in C and C++. 171 * While things are clearer with an explicit union, since each field is 172 * zero-sized it's not actually needed, so omit it for C++ 173 */ 174 #ifndef __cplusplus 175 __extension__ 176 union { 177 #endif 178 struct rte_crypto_sym_op sym[0]; 179 /**< Symmetric operation parameters */ 180 181 struct rte_crypto_asym_op asym[0]; 182 /**< Asymmetric operation parameters */ 183 184 #ifndef __cplusplus 185 }; /**< operation specific parameters */ 186 #endif 187 }; 188 189 /** 190 * Reset the fields of a crypto operation to their default values. 191 * 192 * @param op The crypto operation to be reset. 193 * @param type The crypto operation type. 194 */ 195 static inline void 196 __rte_crypto_op_reset(struct rte_crypto_op *op, enum rte_crypto_op_type type) 197 { 198 op->type = type; 199 op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED; 200 op->sess_type = RTE_CRYPTO_OP_SESSIONLESS; 201 202 switch (type) { 203 case RTE_CRYPTO_OP_TYPE_SYMMETRIC: 204 __rte_crypto_sym_op_reset(op->sym); 205 break; 206 case RTE_CRYPTO_OP_TYPE_ASYMMETRIC: 207 memset(op->asym, 0, sizeof(struct rte_crypto_asym_op)); 208 break; 209 case RTE_CRYPTO_OP_TYPE_UNDEFINED: 210 default: 211 break; 212 } 213 } 214 215 /** 216 * Private data structure belonging to a crypto symmetric operation pool. 217 */ 218 struct rte_crypto_op_pool_private { 219 enum rte_crypto_op_type type; 220 /**< Crypto op pool type operation. */ 221 uint16_t priv_size; 222 /**< Size of private area in each crypto operation. */ 223 }; 224 225 226 /** 227 * Returns the size of private data allocated with each rte_crypto_op object by 228 * the mempool 229 * 230 * @param mempool rte_crypto_op mempool 231 * 232 * @return private data size 233 */ 234 static inline uint16_t 235 __rte_crypto_op_get_priv_data_size(struct rte_mempool *mempool) 236 { 237 struct rte_crypto_op_pool_private *priv = 238 (struct rte_crypto_op_pool_private *) rte_mempool_get_priv(mempool); 239 240 return priv->priv_size; 241 } 242 243 244 /** 245 * Creates a crypto operation pool 246 * 247 * @param name pool name 248 * @param type crypto operation type, use 249 * RTE_CRYPTO_OP_TYPE_UNDEFINED for a pool which 250 * supports all operation types 251 * @param nb_elts number of elements in pool 252 * @param cache_size Number of elements to cache on lcore, see 253 * *rte_mempool_create* for further details about 254 * cache size 255 * @param priv_size Size of private data to allocate with each 256 * operation 257 * @param socket_id Socket to allocate memory on 258 * 259 * @return 260 * - On success pointer to mempool 261 * - On failure NULL 262 */ 263 struct rte_mempool * 264 rte_crypto_op_pool_create(const char *name, enum rte_crypto_op_type type, 265 unsigned nb_elts, unsigned cache_size, uint16_t priv_size, 266 int socket_id); 267 268 /** 269 * Bulk allocate raw element from mempool and return as crypto operations 270 * 271 * @param mempool crypto operation mempool. 272 * @param type crypto operation type. 273 * @param ops Array to place allocated crypto operations 274 * @param nb_ops Number of crypto operations to allocate 275 * 276 * @returns 277 * - On success returns number of ops allocated 278 */ 279 static inline int 280 __rte_crypto_op_raw_bulk_alloc(struct rte_mempool *mempool, 281 enum rte_crypto_op_type type, 282 struct rte_crypto_op **ops, uint16_t nb_ops) 283 { 284 struct rte_crypto_op_pool_private *priv; 285 286 priv = (struct rte_crypto_op_pool_private *) rte_mempool_get_priv(mempool); 287 if (unlikely(priv->type != type && 288 priv->type != RTE_CRYPTO_OP_TYPE_UNDEFINED)) 289 return -EINVAL; 290 291 if (rte_mempool_get_bulk(mempool, (void **)ops, nb_ops) == 0) 292 return nb_ops; 293 294 return 0; 295 } 296 297 /** 298 * Allocate a crypto operation from a mempool with default parameters set 299 * 300 * @param mempool crypto operation mempool 301 * @param type operation type to allocate 302 * 303 * @returns 304 * - On success returns a valid rte_crypto_op structure 305 * - On failure returns NULL 306 */ 307 static inline struct rte_crypto_op * 308 rte_crypto_op_alloc(struct rte_mempool *mempool, enum rte_crypto_op_type type) 309 { 310 struct rte_crypto_op *op = NULL; 311 int retval; 312 313 retval = __rte_crypto_op_raw_bulk_alloc(mempool, type, &op, 1); 314 if (unlikely(retval != 1)) 315 return NULL; 316 317 __rte_crypto_op_reset(op, type); 318 319 return op; 320 } 321 322 323 /** 324 * Bulk allocate crypto operations from a mempool with default parameters set 325 * 326 * @param mempool crypto operation mempool 327 * @param type operation type to allocate 328 * @param ops Array to place allocated crypto operations 329 * @param nb_ops Number of crypto operations to allocate 330 * 331 * @returns 332 * - nb_ops if the number of operations requested were allocated. 333 * - 0 if the requested number of ops are not available. 334 * None are allocated in this case. 335 */ 336 337 static inline unsigned 338 rte_crypto_op_bulk_alloc(struct rte_mempool *mempool, 339 enum rte_crypto_op_type type, 340 struct rte_crypto_op **ops, uint16_t nb_ops) 341 { 342 int i; 343 344 if (unlikely(__rte_crypto_op_raw_bulk_alloc(mempool, type, ops, nb_ops) 345 != nb_ops)) 346 return 0; 347 348 for (i = 0; i < nb_ops; i++) 349 __rte_crypto_op_reset(ops[i], type); 350 351 return nb_ops; 352 } 353 354 355 356 /** 357 * Returns a pointer to the private data of a crypto operation if 358 * that operation has enough capacity for requested size. 359 * 360 * @param op crypto operation. 361 * @param size size of space requested in private data. 362 * 363 * @returns 364 * - if sufficient space available returns pointer to start of private data 365 * - if insufficient space returns NULL 366 */ 367 static inline void * 368 __rte_crypto_op_get_priv_data(struct rte_crypto_op *op, uint32_t size) 369 { 370 uint32_t priv_size; 371 372 if (likely(op->mempool != NULL)) { 373 priv_size = __rte_crypto_op_get_priv_data_size(op->mempool); 374 375 if (likely(priv_size >= size)) { 376 if (op->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) 377 return (void *)((uint8_t *)(op + 1) + 378 sizeof(struct rte_crypto_sym_op)); 379 if (op->type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC) 380 return (void *)((uint8_t *)(op + 1) + 381 sizeof(struct rte_crypto_asym_op)); 382 } 383 } 384 385 return NULL; 386 } 387 388 /** 389 * free crypto operation structure 390 * If operation has been allocate from a rte_mempool, then the operation will 391 * be returned to the mempool. 392 * 393 * @param op 394 * Pointer to symmetric crypto operation allocated with rte_crypto_op_alloc() 395 * If op is NULL, no operation is performed. 396 */ 397 static inline void 398 rte_crypto_op_free(struct rte_crypto_op *op) 399 { 400 if (op != NULL && op->mempool != NULL) 401 rte_mempool_put(op->mempool, op); 402 } 403 404 /** 405 * Allocate a symmetric crypto operation in the private data of an mbuf. 406 * 407 * @param m mbuf which is associated with the crypto operation, the 408 * operation will be allocated in the private data of that 409 * mbuf. 410 * 411 * @returns 412 * - On success returns a pointer to the crypto operation. 413 * - On failure returns NULL. 414 */ 415 static inline struct rte_crypto_op * 416 rte_crypto_sym_op_alloc_from_mbuf_priv_data(struct rte_mbuf *m) 417 { 418 if (unlikely(m == NULL)) 419 return NULL; 420 421 /* 422 * check that the mbuf's private data size is sufficient to contain a 423 * crypto operation 424 */ 425 if (unlikely(m->priv_size < (sizeof(struct rte_crypto_op) + 426 sizeof(struct rte_crypto_sym_op)))) 427 return NULL; 428 429 /* private data starts immediately after the mbuf header in the mbuf. */ 430 struct rte_crypto_op *op = (struct rte_crypto_op *)(m + 1); 431 432 __rte_crypto_op_reset(op, RTE_CRYPTO_OP_TYPE_SYMMETRIC); 433 434 op->mempool = NULL; 435 op->sym->m_src = m; 436 437 return op; 438 } 439 440 /** 441 * Allocate space for symmetric crypto xforms in the private data space of the 442 * crypto operation. This also defaults the crypto xform type and configures 443 * the chaining of the xforms in the crypto operation 444 * 445 * @return 446 * - On success returns pointer to first crypto xform in crypto operations chain 447 * - On failure returns NULL 448 */ 449 static inline struct rte_crypto_sym_xform * 450 rte_crypto_op_sym_xforms_alloc(struct rte_crypto_op *op, uint8_t nb_xforms) 451 { 452 void *priv_data; 453 uint32_t size; 454 455 if (unlikely(op->type != RTE_CRYPTO_OP_TYPE_SYMMETRIC)) 456 return NULL; 457 458 size = sizeof(struct rte_crypto_sym_xform) * nb_xforms; 459 460 priv_data = __rte_crypto_op_get_priv_data(op, size); 461 if (priv_data == NULL) 462 return NULL; 463 464 return __rte_crypto_sym_op_sym_xforms_alloc(op->sym, priv_data, 465 nb_xforms); 466 } 467 468 469 /** 470 * Attach a session to a crypto operation 471 * 472 * @param op crypto operation, must be of type symmetric 473 * @param sess cryptodev session 474 */ 475 static inline int 476 rte_crypto_op_attach_sym_session(struct rte_crypto_op *op, void *sess) 477 { 478 if (unlikely(op->type != RTE_CRYPTO_OP_TYPE_SYMMETRIC)) 479 return -1; 480 481 op->sess_type = RTE_CRYPTO_OP_WITH_SESSION; 482 483 return __rte_crypto_sym_op_attach_sym_session(op->sym, sess); 484 } 485 486 /** 487 * Attach a asymmetric session to a crypto operation 488 * 489 * @param op crypto operation, must be of type asymmetric 490 * @param sess cryptodev session 491 */ 492 static inline int 493 rte_crypto_op_attach_asym_session(struct rte_crypto_op *op, 494 struct rte_cryptodev_asym_session *sess) 495 { 496 if (unlikely(op->type != RTE_CRYPTO_OP_TYPE_ASYMMETRIC)) 497 return -1; 498 499 op->sess_type = RTE_CRYPTO_OP_WITH_SESSION; 500 op->asym->session = sess; 501 return 0; 502 } 503 504 #ifdef __cplusplus 505 } 506 #endif 507 508 #endif /* _RTE_CRYPTO_H_ */ 509