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