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 #ifdef __cplusplus 16 extern "C" { 17 #endif 18 19 20 #include <rte_mbuf.h> 21 #include <rte_memory.h> 22 #include <rte_mempool.h> 23 #include <rte_common.h> 24 25 #include "rte_crypto_sym.h" 26 #include "rte_crypto_asym.h" 27 28 /** Crypto operation types */ 29 enum rte_crypto_op_type { 30 RTE_CRYPTO_OP_TYPE_UNDEFINED, 31 /**< Undefined operation type */ 32 RTE_CRYPTO_OP_TYPE_SYMMETRIC, 33 /**< Symmetric operation */ 34 RTE_CRYPTO_OP_TYPE_ASYMMETRIC 35 /**< Asymmetric operation */ 36 }; 37 38 /** Status of crypto operation */ 39 enum rte_crypto_op_status { 40 RTE_CRYPTO_OP_STATUS_SUCCESS, 41 /**< Operation completed successfully */ 42 RTE_CRYPTO_OP_STATUS_NOT_PROCESSED, 43 /**< Operation has not yet been processed by a crypto device */ 44 RTE_CRYPTO_OP_STATUS_AUTH_FAILED, 45 /**< Authentication verification failed */ 46 RTE_CRYPTO_OP_STATUS_INVALID_SESSION, 47 /**< 48 * Symmetric operation failed due to invalid session arguments, or if 49 * in session-less mode, failed to allocate private operation material. 50 */ 51 RTE_CRYPTO_OP_STATUS_INVALID_ARGS, 52 /**< Operation failed due to invalid arguments in request */ 53 RTE_CRYPTO_OP_STATUS_ERROR, 54 /**< Error handling operation */ 55 }; 56 57 /** 58 * Crypto operation session type. This is used to specify whether a crypto 59 * operation has session structure attached for immutable parameters or if all 60 * operation information is included in the operation data structure. 61 */ 62 enum rte_crypto_op_sess_type { 63 RTE_CRYPTO_OP_WITH_SESSION, /**< Session based crypto operation */ 64 RTE_CRYPTO_OP_SESSIONLESS, /**< Session-less crypto operation */ 65 RTE_CRYPTO_OP_SECURITY_SESSION /**< Security session crypto operation */ 66 }; 67 68 /** 69 * Cryptographic Operation. 70 * 71 * This structure contains data relating to performing cryptographic 72 * operations. This operation structure is used to contain any operation which 73 * is supported by the cryptodev API, PMDs should check the type parameter to 74 * verify that the operation is a support function of the device. Crypto 75 * operations are enqueued and dequeued in crypto PMDs using the 76 * rte_cryptodev_enqueue_burst() / rte_cryptodev_dequeue_burst() . 77 */ 78 struct rte_crypto_op { 79 __extension__ 80 union { 81 uint64_t raw; 82 __extension__ 83 struct { 84 uint8_t type; 85 /**< operation type */ 86 uint8_t status; 87 /**< 88 * operation status - this is reset to 89 * RTE_CRYPTO_OP_STATUS_NOT_PROCESSED on allocation 90 * from mempool and will be set to 91 * RTE_CRYPTO_OP_STATUS_SUCCESS after crypto operation 92 * is successfully processed by a crypto PMD 93 */ 94 uint8_t sess_type; 95 /**< operation session type */ 96 uint8_t reserved[3]; 97 /**< Reserved bytes to fill 64 bits for 98 * future additions 99 */ 100 uint16_t private_data_offset; 101 /**< Offset to indicate start of private data (if any). 102 * The offset is counted from the start of the 103 * rte_crypto_op including IV. 104 * The private data may be used by the application 105 * to store information which should remain untouched 106 * in the library/driver 107 */ 108 }; 109 }; 110 struct rte_mempool *mempool; 111 /**< crypto operation mempool which operation is allocated from */ 112 113 rte_iova_t phys_addr; 114 /**< physical address of crypto operation */ 115 116 __extension__ 117 union { 118 struct rte_crypto_sym_op sym[0]; 119 /**< Symmetric operation parameters */ 120 121 struct rte_crypto_asym_op asym[0]; 122 /**< Asymmetric operation parameters */ 123 124 }; /**< operation specific parameters */ 125 }; 126 127 /** 128 * Reset the fields of a crypto operation to their default values. 129 * 130 * @param op The crypto operation to be reset. 131 * @param type The crypto operation type. 132 */ 133 static inline void 134 __rte_crypto_op_reset(struct rte_crypto_op *op, enum rte_crypto_op_type type) 135 { 136 op->type = type; 137 op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED; 138 op->sess_type = RTE_CRYPTO_OP_SESSIONLESS; 139 140 switch (type) { 141 case RTE_CRYPTO_OP_TYPE_SYMMETRIC: 142 __rte_crypto_sym_op_reset(op->sym); 143 break; 144 case RTE_CRYPTO_OP_TYPE_ASYMMETRIC: 145 memset(op->asym, 0, sizeof(struct rte_crypto_asym_op)); 146 break; 147 case RTE_CRYPTO_OP_TYPE_UNDEFINED: 148 default: 149 break; 150 } 151 } 152 153 /** 154 * Private data structure belonging to a crypto symmetric operation pool. 155 */ 156 struct rte_crypto_op_pool_private { 157 enum rte_crypto_op_type type; 158 /**< Crypto op pool type operation. */ 159 uint16_t priv_size; 160 /**< Size of private area in each crypto operation. */ 161 }; 162 163 164 /** 165 * Returns the size of private data allocated with each rte_crypto_op object by 166 * the mempool 167 * 168 * @param mempool rte_crypto_op mempool 169 * 170 * @return private data size 171 */ 172 static inline uint16_t 173 __rte_crypto_op_get_priv_data_size(struct rte_mempool *mempool) 174 { 175 struct rte_crypto_op_pool_private *priv = 176 (struct rte_crypto_op_pool_private *) rte_mempool_get_priv(mempool); 177 178 return priv->priv_size; 179 } 180 181 182 /** 183 * Creates a crypto operation pool 184 * 185 * @param name pool name 186 * @param type crypto operation type, use 187 * RTE_CRYPTO_OP_TYPE_UNDEFINED for a pool which 188 * supports all operation types 189 * @param nb_elts number of elements in pool 190 * @param cache_size Number of elements to cache on lcore, see 191 * *rte_mempool_create* for further details about 192 * cache size 193 * @param priv_size Size of private data to allocate with each 194 * operation 195 * @param socket_id Socket to allocate memory on 196 * 197 * @return 198 * - On success pointer to mempool 199 * - On failure NULL 200 */ 201 extern struct rte_mempool * 202 rte_crypto_op_pool_create(const char *name, enum rte_crypto_op_type type, 203 unsigned nb_elts, unsigned cache_size, uint16_t priv_size, 204 int socket_id); 205 206 /** 207 * Bulk allocate raw element from mempool and return as crypto operations 208 * 209 * @param mempool crypto operation mempool. 210 * @param type crypto operation type. 211 * @param ops Array to place allocated crypto operations 212 * @param nb_ops Number of crypto operations to allocate 213 * 214 * @returns 215 * - On success returns number of ops allocated 216 */ 217 static inline int 218 __rte_crypto_op_raw_bulk_alloc(struct rte_mempool *mempool, 219 enum rte_crypto_op_type type, 220 struct rte_crypto_op **ops, uint16_t nb_ops) 221 { 222 struct rte_crypto_op_pool_private *priv; 223 224 priv = (struct rte_crypto_op_pool_private *) rte_mempool_get_priv(mempool); 225 if (unlikely(priv->type != type && 226 priv->type != RTE_CRYPTO_OP_TYPE_UNDEFINED)) 227 return -EINVAL; 228 229 if (rte_mempool_get_bulk(mempool, (void **)ops, nb_ops) == 0) 230 return nb_ops; 231 232 return 0; 233 } 234 235 /** 236 * Allocate a crypto operation from a mempool with default parameters set 237 * 238 * @param mempool crypto operation mempool 239 * @param type operation type to allocate 240 * 241 * @returns 242 * - On success returns a valid rte_crypto_op structure 243 * - On failure returns NULL 244 */ 245 static inline struct rte_crypto_op * 246 rte_crypto_op_alloc(struct rte_mempool *mempool, enum rte_crypto_op_type type) 247 { 248 struct rte_crypto_op *op = NULL; 249 int retval; 250 251 retval = __rte_crypto_op_raw_bulk_alloc(mempool, type, &op, 1); 252 if (unlikely(retval != 1)) 253 return NULL; 254 255 __rte_crypto_op_reset(op, type); 256 257 return op; 258 } 259 260 261 /** 262 * Bulk allocate crypto operations from a mempool with default parameters set 263 * 264 * @param mempool crypto operation mempool 265 * @param type operation type to allocate 266 * @param ops Array to place allocated crypto operations 267 * @param nb_ops Number of crypto operations to allocate 268 * 269 * @returns 270 * - nb_ops if the number of operations requested were allocated. 271 * - 0 if the requested number of ops are not available. 272 * None are allocated in this case. 273 */ 274 275 static inline unsigned 276 rte_crypto_op_bulk_alloc(struct rte_mempool *mempool, 277 enum rte_crypto_op_type type, 278 struct rte_crypto_op **ops, uint16_t nb_ops) 279 { 280 int i; 281 282 if (unlikely(__rte_crypto_op_raw_bulk_alloc(mempool, type, ops, nb_ops) 283 != nb_ops)) 284 return 0; 285 286 for (i = 0; i < nb_ops; i++) 287 __rte_crypto_op_reset(ops[i], type); 288 289 return nb_ops; 290 } 291 292 293 294 /** 295 * Returns a pointer to the private data of a crypto operation if 296 * that operation has enough capacity for requested size. 297 * 298 * @param op crypto operation. 299 * @param size size of space requested in private data. 300 * 301 * @returns 302 * - if sufficient space available returns pointer to start of private data 303 * - if insufficient space returns NULL 304 */ 305 static inline void * 306 __rte_crypto_op_get_priv_data(struct rte_crypto_op *op, uint32_t size) 307 { 308 uint32_t priv_size; 309 310 if (likely(op->mempool != NULL)) { 311 priv_size = __rte_crypto_op_get_priv_data_size(op->mempool); 312 313 if (likely(priv_size >= size)) { 314 if (op->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) 315 return (void *)((uint8_t *)(op + 1) + 316 sizeof(struct rte_crypto_sym_op)); 317 if (op->type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC) 318 return (void *)((uint8_t *)(op + 1) + 319 sizeof(struct rte_crypto_asym_op)); 320 } 321 } 322 323 return NULL; 324 } 325 326 /** 327 * free crypto operation structure 328 * If operation has been allocate from a rte_mempool, then the operation will 329 * be returned to the mempool. 330 * 331 * @param op symmetric crypto operation 332 */ 333 static inline void 334 rte_crypto_op_free(struct rte_crypto_op *op) 335 { 336 if (op != NULL && op->mempool != NULL) 337 rte_mempool_put(op->mempool, op); 338 } 339 340 /** 341 * Allocate a symmetric crypto operation in the private data of an mbuf. 342 * 343 * @param m mbuf which is associated with the crypto operation, the 344 * operation will be allocated in the private data of that 345 * mbuf. 346 * 347 * @returns 348 * - On success returns a pointer to the crypto operation. 349 * - On failure returns NULL. 350 */ 351 static inline struct rte_crypto_op * 352 rte_crypto_sym_op_alloc_from_mbuf_priv_data(struct rte_mbuf *m) 353 { 354 if (unlikely(m == NULL)) 355 return NULL; 356 357 /* 358 * check that the mbuf's private data size is sufficient to contain a 359 * crypto operation 360 */ 361 if (unlikely(m->priv_size < (sizeof(struct rte_crypto_op) + 362 sizeof(struct rte_crypto_sym_op)))) 363 return NULL; 364 365 /* private data starts immediately after the mbuf header in the mbuf. */ 366 struct rte_crypto_op *op = (struct rte_crypto_op *)(m + 1); 367 368 __rte_crypto_op_reset(op, RTE_CRYPTO_OP_TYPE_SYMMETRIC); 369 370 op->mempool = NULL; 371 op->sym->m_src = m; 372 373 return op; 374 } 375 376 /** 377 * Allocate space for symmetric crypto xforms in the private data space of the 378 * crypto operation. This also defaults the crypto xform type and configures 379 * the chaining of the xforms in the crypto operation 380 * 381 * @return 382 * - On success returns pointer to first crypto xform in crypto operations chain 383 * - On failure returns NULL 384 */ 385 static inline struct rte_crypto_sym_xform * 386 rte_crypto_op_sym_xforms_alloc(struct rte_crypto_op *op, uint8_t nb_xforms) 387 { 388 void *priv_data; 389 uint32_t size; 390 391 if (unlikely(op->type != RTE_CRYPTO_OP_TYPE_SYMMETRIC)) 392 return NULL; 393 394 size = sizeof(struct rte_crypto_sym_xform) * nb_xforms; 395 396 priv_data = __rte_crypto_op_get_priv_data(op, size); 397 if (priv_data == NULL) 398 return NULL; 399 400 return __rte_crypto_sym_op_sym_xforms_alloc(op->sym, priv_data, 401 nb_xforms); 402 } 403 404 405 /** 406 * Attach a session to a crypto operation 407 * 408 * @param op crypto operation, must be of type symmetric 409 * @param sess cryptodev session 410 */ 411 static inline int 412 rte_crypto_op_attach_sym_session(struct rte_crypto_op *op, 413 struct rte_cryptodev_sym_session *sess) 414 { 415 if (unlikely(op->type != RTE_CRYPTO_OP_TYPE_SYMMETRIC)) 416 return -1; 417 418 op->sess_type = RTE_CRYPTO_OP_WITH_SESSION; 419 420 return __rte_crypto_sym_op_attach_sym_session(op->sym, sess); 421 } 422 423 /** 424 * Attach a asymmetric session to a crypto operation 425 * 426 * @param op crypto operation, must be of type asymmetric 427 * @param sess cryptodev session 428 */ 429 static inline int 430 rte_crypto_op_attach_asym_session(struct rte_crypto_op *op, 431 struct rte_cryptodev_asym_session *sess) 432 { 433 if (unlikely(op->type != RTE_CRYPTO_OP_TYPE_ASYMMETRIC)) 434 return -1; 435 436 op->sess_type = RTE_CRYPTO_OP_WITH_SESSION; 437 op->asym->session = sess; 438 return 0; 439 } 440 441 #ifdef __cplusplus 442 } 443 #endif 444 445 #endif /* _RTE_CRYPTO_H_ */ 446