Branch data Line data Source code
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 : 8500 : __rte_crypto_op_reset(struct rte_crypto_op *op, enum rte_crypto_op_type type)
197 : : {
198 : 8500 : op->type = type;
199 : 8500 : op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
200 : 8500 : op->sess_type = RTE_CRYPTO_OP_SESSIONLESS;
201 : :
202 [ + + - ]: 8500 : switch (type) {
203 : 8434 : case RTE_CRYPTO_OP_TYPE_SYMMETRIC:
204 : 8434 : __rte_crypto_sym_op_reset(op->sym);
205 : : break;
206 : 66 : case RTE_CRYPTO_OP_TYPE_ASYMMETRIC:
207 : 66 : 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 : 8500 : }
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 : 10 : 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 [ + + ]: 299 : __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 [ - + - - ]: 299 : if (unlikely(priv->type != type &&
288 : : priv->type != RTE_CRYPTO_OP_TYPE_UNDEFINED))
289 : : return -EINVAL;
290 : :
291 [ + + + - ]: 597 : if (rte_mempool_get_bulk(mempool, (void **)ops, nb_ops) == 0)
292 : 299 : 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 : 299 : rte_crypto_op_alloc(struct rte_mempool *mempool, enum rte_crypto_op_type type)
309 : : {
310 : 299 : struct rte_crypto_op *op = NULL;
311 : : int retval;
312 : :
313 : 299 : retval = __rte_crypto_op_raw_bulk_alloc(mempool, type, &op, 1);
314 [ + - ]: 299 : if (unlikely(retval != 1))
315 : : return NULL;
316 : :
317 : 299 : __rte_crypto_op_reset(op, type);
318 : :
319 : 299 : 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 : 0 : 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 [ # # ]: 0 : if (unlikely(__rte_crypto_op_raw_bulk_alloc(mempool, type, ops, nb_ops)
345 : : != nb_ops))
346 : : return 0;
347 : :
348 [ # # ]: 0 : for (i = 0; i < nb_ops; i++)
349 : 0 : __rte_crypto_op_reset(ops[i], type);
350 : :
351 : 0 : 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 : 10 : if (likely(op->mempool != NULL)) {
373 : 10 : priv_size = __rte_crypto_op_get_priv_data_size(op->mempool);
374 : :
375 [ + - ]: 10 : if (likely(priv_size >= size)) {
376 [ + - ]: 10 : if (op->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC)
377 : 10 : return (void *)((uint8_t *)(op + 1) +
378 : : sizeof(struct rte_crypto_sym_op));
379 [ # # ]: 0 : if (op->type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC)
380 : 0 : 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 : 620 : rte_crypto_op_free(struct rte_crypto_op *op)
399 : : {
400 [ + + + - ]: 620 : if (op != NULL && op->mempool != NULL)
401 : 294 : rte_mempool_put(op->mempool, op);
402 : 620 : }
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 : 10 : 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 [ + - ]: 10 : if (unlikely(op->type != RTE_CRYPTO_OP_TYPE_SYMMETRIC))
456 : : return NULL;
457 : :
458 [ + - ]: 10 : 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 : 10 : 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 : 0 : rte_crypto_op_attach_sym_session(struct rte_crypto_op *op, void *sess)
477 : : {
478 [ + - + - : 234 : if (unlikely(op->type != RTE_CRYPTO_OP_TYPE_SYMMETRIC))
+ - + - -
- + - + -
- - - - +
- + - + -
+ - - - +
- + - - -
- - - - -
- - - + -
+ - - - ]
479 : : return -1;
480 : :
481 : 234 : op->sess_type = RTE_CRYPTO_OP_WITH_SESSION;
482 : :
483 : 234 : 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 [ - - - - : 24 : if (unlikely(op->type != RTE_CRYPTO_OP_TYPE_ASYMMETRIC))
- - + - -
- - - + -
+ - + - +
- - - - -
- - - - -
- - - - -
+ - + - +
- + - + -
+ - + - +
- + - +
- ]
497 : : return -1;
498 : :
499 : 24 : op->sess_type = RTE_CRYPTO_OP_WITH_SESSION;
500 : 24 : op->asym->session = sess;
501 : 24 : return 0;
502 : : }
503 : :
504 : : #ifdef __cplusplus
505 : : }
506 : : #endif
507 : :
508 : : #endif /* _RTE_CRYPTO_H_ */
|