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