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