e8397803ef79056a05b1cf15cb6187e9897d4c6d
[dpdk.git] / drivers / crypto / aesni_mb / rte_aesni_mb_pmd_ops.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2015-2017 Intel Corporation
3  */
4
5 #include <string.h>
6
7 #include <rte_common.h>
8 #include <rte_malloc.h>
9 #include <rte_cryptodev_pmd.h>
10
11 #include "rte_aesni_mb_pmd_private.h"
12
13
14 static const struct rte_cryptodev_capabilities aesni_mb_pmd_capabilities[] = {
15         {       /* MD5 HMAC */
16                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
17                 {.sym = {
18                         .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
19                         {.auth = {
20                                 .algo = RTE_CRYPTO_AUTH_MD5_HMAC,
21                                 .block_size = 64,
22                                 .key_size = {
23                                         .min = 1,
24                                         .max = 64,
25                                         .increment = 1
26                                 },
27                                 .digest_size = {
28 #if IMB_VERSION_NUM >= IMB_VERSION(0, 50, 0)
29                                         .min = 1,
30                                         .max = 16,
31                                         .increment = 1
32 #else
33                                         .min = 12,
34                                         .max = 12,
35                                         .increment = 0
36 #endif
37                                 },
38                                 .iv_size = { 0 }
39                         }, }
40                 }, }
41         },
42         {       /* SHA1 HMAC */
43                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
44                 {.sym = {
45                         .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
46                         {.auth = {
47                                 .algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
48                                 .block_size = 64,
49                                 .key_size = {
50                                         .min = 1,
51                                         .max = 64,
52                                         .increment = 1
53                                 },
54                                 .digest_size = {
55 #if IMB_VERSION_NUM >= IMB_VERSION(0, 50, 0)
56                                         .min = 1,
57                                         .max = 20,
58                                         .increment = 1
59 #else
60                                         .min = 12,
61                                         .max = 12,
62                                         .increment = 0
63 #endif
64                                 },
65                                 .iv_size = { 0 }
66                         }, }
67                 }, }
68         },
69         {       /* SHA224 HMAC */
70                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
71                 {.sym = {
72                         .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
73                         {.auth = {
74                                 .algo = RTE_CRYPTO_AUTH_SHA224_HMAC,
75                                 .block_size = 64,
76                                 .key_size = {
77                                         .min = 1,
78                                         .max = 64,
79                                         .increment = 1
80                                 },
81                                 .digest_size = {
82 #if IMB_VERSION_NUM >= IMB_VERSION(0, 50, 0)
83                                         .min = 1,
84                                         .max = 28,
85                                         .increment = 1
86 #else
87                                         .min = 14,
88                                         .max = 14,
89                                         .increment = 0
90 #endif
91                                 },
92                                 .iv_size = { 0 }
93                         }, }
94                 }, }
95         },
96         {       /* SHA256 HMAC */
97                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
98                 {.sym = {
99                         .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
100                         {.auth = {
101                                 .algo = RTE_CRYPTO_AUTH_SHA256_HMAC,
102                                 .block_size = 64,
103                                 .key_size = {
104                                         .min = 1,
105                                         .max = 64,
106                                         .increment = 1
107                                 },
108                                 .digest_size = {
109 #if IMB_VERSION_NUM >= IMB_VERSION(0, 50, 0)
110                                         .min = 1,
111                                         .max = 32,
112                                         .increment = 1
113 #else
114                                         .min = 16,
115                                         .max = 16,
116                                         .increment = 0
117 #endif
118                                 },
119                                 .iv_size = { 0 }
120                         }, }
121                 }, }
122         },
123         {       /* SHA384 HMAC */
124                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
125                 {.sym = {
126                         .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
127                         {.auth = {
128                                 .algo = RTE_CRYPTO_AUTH_SHA384_HMAC,
129                                 .block_size = 128,
130                                 .key_size = {
131                                         .min = 1,
132                                         .max = 128,
133                                         .increment = 1
134                                 },
135                                 .digest_size = {
136 #if IMB_VERSION_NUM >= IMB_VERSION(0, 50, 0)
137                                         .min = 1,
138                                         .max = 48,
139                                         .increment = 1
140 #else
141                                         .min = 24,
142                                         .max = 24,
143                                         .increment = 0
144 #endif
145                                 },
146                                 .iv_size = { 0 }
147                         }, }
148                 }, }
149         },
150         {       /* SHA512 HMAC */
151                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
152                 {.sym = {
153                         .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
154                         {.auth = {
155                                 .algo = RTE_CRYPTO_AUTH_SHA512_HMAC,
156                                 .block_size = 128,
157                                 .key_size = {
158                                         .min = 1,
159                                         .max = 128,
160                                         .increment = 1
161                                 },
162                                 .digest_size = {
163 #if IMB_VERSION_NUM >= IMB_VERSION(0, 50, 0)
164                                         .min = 1,
165                                         .max = 64,
166                                         .increment = 1
167 #else
168                                         .min = 32,
169                                         .max = 32,
170                                         .increment = 0
171 #endif
172                                 },
173                                 .iv_size = { 0 }
174                         }, }
175                 }, }
176         },
177         {       /* AES XCBC HMAC */
178                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
179                 {.sym = {
180                         .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
181                         {.auth = {
182                                 .algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC,
183                                 .block_size = 16,
184                                 .key_size = {
185                                         .min = 16,
186                                         .max = 16,
187                                         .increment = 0
188                                 },
189                                 .digest_size = {
190                                         .min = 12,
191                                         .max = 12,
192                                         .increment = 0
193                                 },
194                                 .iv_size = { 0 }
195                         }, }
196                 }, }
197         },
198         {       /* AES CBC */
199                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
200                 {.sym = {
201                         .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
202                         {.cipher = {
203                                 .algo = RTE_CRYPTO_CIPHER_AES_CBC,
204                                 .block_size = 16,
205                                 .key_size = {
206                                         .min = 16,
207                                         .max = 32,
208                                         .increment = 8
209                                 },
210                                 .iv_size = {
211                                         .min = 16,
212                                         .max = 16,
213                                         .increment = 0
214                                 }
215                         }, }
216                 }, }
217         },
218         {       /* AES CTR */
219                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
220                 {.sym = {
221                         .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
222                         {.cipher = {
223                                 .algo = RTE_CRYPTO_CIPHER_AES_CTR,
224                                 .block_size = 16,
225                                 .key_size = {
226                                         .min = 16,
227                                         .max = 32,
228                                         .increment = 8
229                                 },
230                                 .iv_size = {
231                                         .min = 12,
232                                         .max = 16,
233                                         .increment = 4
234                                 }
235                         }, }
236                 }, }
237         },
238         {       /* AES DOCSIS BPI */
239                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
240                 {.sym = {
241                         .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
242                         {.cipher = {
243                                 .algo = RTE_CRYPTO_CIPHER_AES_DOCSISBPI,
244                                 .block_size = 16,
245                                 .key_size = {
246                                         .min = 16,
247                                         .max = 16,
248                                         .increment = 0
249                                 },
250                                 .iv_size = {
251                                         .min = 16,
252                                         .max = 16,
253                                         .increment = 0
254                                 }
255                         }, }
256                 }, }
257         },
258         {       /* DES CBC */
259                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
260                 {.sym = {
261                         .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
262                         {.cipher = {
263                                 .algo = RTE_CRYPTO_CIPHER_DES_CBC,
264                                 .block_size = 8,
265                                 .key_size = {
266                                         .min = 8,
267                                         .max = 8,
268                                         .increment = 0
269                                 },
270                                 .iv_size = {
271                                         .min = 8,
272                                         .max = 8,
273                                         .increment = 0
274                                 }
275                         }, }
276                 }, }
277         },
278         {       /*  3DES CBC */
279                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
280                 {.sym = {
281                         .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
282                         {.cipher = {
283                                 .algo = RTE_CRYPTO_CIPHER_3DES_CBC,
284                                 .block_size = 8,
285                                 .key_size = {
286                                         .min = 8,
287                                         .max = 24,
288                                         .increment = 8
289                                 },
290                                 .iv_size = {
291                                         .min = 8,
292                                         .max = 8,
293                                         .increment = 0
294                                 }
295                         }, }
296                 }, }
297         },
298         {       /* DES DOCSIS BPI */
299                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
300                 {.sym = {
301                         .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
302                         {.cipher = {
303                                 .algo = RTE_CRYPTO_CIPHER_DES_DOCSISBPI,
304                                 .block_size = 8,
305                                 .key_size = {
306                                         .min = 8,
307                                         .max = 8,
308                                         .increment = 0
309                                 },
310                                 .iv_size = {
311                                         .min = 8,
312                                         .max = 8,
313                                         .increment = 0
314                                 }
315                         }, }
316                 }, }
317         },
318         {       /* AES CCM */
319                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
320                 {.sym = {
321                         .xform_type = RTE_CRYPTO_SYM_XFORM_AEAD,
322                         {.aead = {
323                                 .algo = RTE_CRYPTO_AEAD_AES_CCM,
324                                 .block_size = 16,
325                                 .key_size = {
326                                         .min = 16,
327                                         .max = 16,
328                                         .increment = 0
329                                 },
330                                 .digest_size = {
331                                         .min = 4,
332                                         .max = 16,
333                                         .increment = 2
334                                 },
335                                 .aad_size = {
336                                         .min = 0,
337                                         .max = 46,
338                                         .increment = 1
339                                 },
340                                 .iv_size = {
341                                         .min = 7,
342                                         .max = 13,
343                                         .increment = 1
344                                 },
345                         }, }
346                 }, }
347         },
348         {       /* AES CMAC */
349                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
350                 {.sym = {
351                         .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
352                         {.auth = {
353                                 .algo = RTE_CRYPTO_AUTH_AES_CMAC,
354                                 .block_size = 16,
355                                 .key_size = {
356                                         .min = 16,
357                                         .max = 16,
358                                         .increment = 0
359                                 },
360                                 .digest_size = {
361                                         .min = 12,
362                                         .max = 16,
363                                         .increment = 4
364                                 },
365                                 .iv_size = { 0 }
366                         }, }
367                 }, }
368         },
369         RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
370 };
371
372
373 /** Configure device */
374 static int
375 aesni_mb_pmd_config(__rte_unused struct rte_cryptodev *dev,
376                 __rte_unused struct rte_cryptodev_config *config)
377 {
378         return 0;
379 }
380
381 /** Start device */
382 static int
383 aesni_mb_pmd_start(__rte_unused struct rte_cryptodev *dev)
384 {
385         return 0;
386 }
387
388 /** Stop device */
389 static void
390 aesni_mb_pmd_stop(__rte_unused struct rte_cryptodev *dev)
391 {
392 }
393
394 /** Close device */
395 static int
396 aesni_mb_pmd_close(__rte_unused struct rte_cryptodev *dev)
397 {
398         return 0;
399 }
400
401
402 /** Get device statistics */
403 static void
404 aesni_mb_pmd_stats_get(struct rte_cryptodev *dev,
405                 struct rte_cryptodev_stats *stats)
406 {
407         int qp_id;
408
409         for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
410                 struct aesni_mb_qp *qp = dev->data->queue_pairs[qp_id];
411
412                 stats->enqueued_count += qp->stats.enqueued_count;
413                 stats->dequeued_count += qp->stats.dequeued_count;
414
415                 stats->enqueue_err_count += qp->stats.enqueue_err_count;
416                 stats->dequeue_err_count += qp->stats.dequeue_err_count;
417         }
418 }
419
420 /** Reset device statistics */
421 static void
422 aesni_mb_pmd_stats_reset(struct rte_cryptodev *dev)
423 {
424         int qp_id;
425
426         for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
427                 struct aesni_mb_qp *qp = dev->data->queue_pairs[qp_id];
428
429                 memset(&qp->stats, 0, sizeof(qp->stats));
430         }
431 }
432
433
434 /** Get device info */
435 static void
436 aesni_mb_pmd_info_get(struct rte_cryptodev *dev,
437                 struct rte_cryptodev_info *dev_info)
438 {
439         struct aesni_mb_private *internals = dev->data->dev_private;
440
441         if (dev_info != NULL) {
442                 dev_info->driver_id = dev->driver_id;
443                 dev_info->feature_flags = dev->feature_flags;
444                 dev_info->capabilities = aesni_mb_pmd_capabilities;
445                 dev_info->max_nb_queue_pairs = internals->max_nb_queue_pairs;
446                 /* No limit of number of sessions */
447                 dev_info->sym.max_nb_sessions = 0;
448         }
449 }
450
451 /** Release queue pair */
452 static int
453 aesni_mb_pmd_qp_release(struct rte_cryptodev *dev, uint16_t qp_id)
454 {
455         struct aesni_mb_qp *qp = dev->data->queue_pairs[qp_id];
456         struct rte_ring *r = NULL;
457
458         if (qp != NULL) {
459                 r = rte_ring_lookup(qp->name);
460                 if (r)
461                         rte_ring_free(r);
462                 if (qp->mb_mgr)
463                         free_mb_mgr(qp->mb_mgr);
464                 rte_free(qp);
465                 dev->data->queue_pairs[qp_id] = NULL;
466         }
467         return 0;
468 }
469
470 /** set a unique name for the queue pair based on it's name, dev_id and qp_id */
471 static int
472 aesni_mb_pmd_qp_set_unique_name(struct rte_cryptodev *dev,
473                 struct aesni_mb_qp *qp)
474 {
475         unsigned n = snprintf(qp->name, sizeof(qp->name),
476                         "aesni_mb_pmd_%u_qp_%u",
477                         dev->data->dev_id, qp->id);
478
479         if (n >= sizeof(qp->name))
480                 return -1;
481
482         return 0;
483 }
484
485 /** Create a ring to place processed operations on */
486 static struct rte_ring *
487 aesni_mb_pmd_qp_create_processed_ops_ring(struct aesni_mb_qp *qp,
488                 const char *str, unsigned int ring_size, int socket_id)
489 {
490         struct rte_ring *r;
491         char ring_name[RTE_CRYPTODEV_NAME_MAX_LEN];
492
493         unsigned int n = snprintf(ring_name, sizeof(ring_name),
494                                 "%s_%s",
495                                 qp->name, str);
496
497         if (n >= sizeof(ring_name))
498                 return NULL;
499
500         r = rte_ring_lookup(ring_name);
501         if (r) {
502                 if (rte_ring_get_size(r) >= ring_size) {
503                         AESNI_MB_LOG(INFO, "Reusing existing ring %s for processed ops",
504                         ring_name);
505                         return r;
506                 }
507
508                 AESNI_MB_LOG(ERR, "Unable to reuse existing ring %s for processed ops",
509                         ring_name);
510                 return NULL;
511         }
512
513         return rte_ring_create(ring_name, ring_size, socket_id,
514                         RING_F_SP_ENQ | RING_F_SC_DEQ);
515 }
516
517 /** Setup a queue pair */
518 static int
519 aesni_mb_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
520                 const struct rte_cryptodev_qp_conf *qp_conf,
521                 int socket_id, struct rte_mempool *session_pool)
522 {
523         struct aesni_mb_qp *qp = NULL;
524         struct aesni_mb_private *internals = dev->data->dev_private;
525         int ret = -1;
526
527         /* Free memory prior to re-allocation if needed. */
528         if (dev->data->queue_pairs[qp_id] != NULL)
529                 aesni_mb_pmd_qp_release(dev, qp_id);
530
531         /* Allocate the queue pair data structure. */
532         qp = rte_zmalloc_socket("AES-NI PMD Queue Pair", sizeof(*qp),
533                                         RTE_CACHE_LINE_SIZE, socket_id);
534         if (qp == NULL)
535                 return -ENOMEM;
536
537         qp->id = qp_id;
538         dev->data->queue_pairs[qp_id] = qp;
539
540         if (aesni_mb_pmd_qp_set_unique_name(dev, qp))
541                 goto qp_setup_cleanup;
542
543
544         qp->mb_mgr = alloc_mb_mgr(0);
545         if (qp->mb_mgr == NULL) {
546                 ret = -ENOMEM;
547                 goto qp_setup_cleanup;
548         }
549
550         qp->op_fns = &job_ops[internals->vector_mode];
551
552         qp->ingress_queue = aesni_mb_pmd_qp_create_processed_ops_ring(qp,
553                         "ingress", qp_conf->nb_descriptors, socket_id);
554         if (qp->ingress_queue == NULL) {
555                 ret = -1;
556                 goto qp_setup_cleanup;
557         }
558
559         qp->sess_mp = session_pool;
560
561         memset(&qp->stats, 0, sizeof(qp->stats));
562
563         char mp_name[RTE_MEMPOOL_NAMESIZE];
564
565         snprintf(mp_name, RTE_MEMPOOL_NAMESIZE,
566                                 "digest_mp_%u_%u", dev->data->dev_id, qp_id);
567
568         /* Initialise multi-buffer manager */
569         (*qp->op_fns->job.init_mgr)(qp->mb_mgr);
570         return 0;
571
572 qp_setup_cleanup:
573         if (qp) {
574                 if (qp->mb_mgr == NULL)
575                         free_mb_mgr(qp->mb_mgr);
576                 rte_free(qp);
577         }
578
579         return ret;
580 }
581
582 /** Return the number of allocated queue pairs */
583 static uint32_t
584 aesni_mb_pmd_qp_count(struct rte_cryptodev *dev)
585 {
586         return dev->data->nb_queue_pairs;
587 }
588
589 /** Returns the size of the aesni multi-buffer session structure */
590 static unsigned
591 aesni_mb_pmd_sym_session_get_size(struct rte_cryptodev *dev __rte_unused)
592 {
593         return sizeof(struct aesni_mb_session);
594 }
595
596 /** Configure a aesni multi-buffer session from a crypto xform chain */
597 static int
598 aesni_mb_pmd_sym_session_configure(struct rte_cryptodev *dev,
599                 struct rte_crypto_sym_xform *xform,
600                 struct rte_cryptodev_sym_session *sess,
601                 struct rte_mempool *mempool)
602 {
603         void *sess_private_data;
604         struct aesni_mb_private *internals = dev->data->dev_private;
605         int ret;
606
607         if (unlikely(sess == NULL)) {
608                 AESNI_MB_LOG(ERR, "invalid session struct");
609                 return -EINVAL;
610         }
611
612         if (rte_mempool_get(mempool, &sess_private_data)) {
613                 AESNI_MB_LOG(ERR,
614                                 "Couldn't get object from session mempool");
615                 return -ENOMEM;
616         }
617
618         ret = aesni_mb_set_session_parameters(&job_ops[internals->vector_mode],
619                         sess_private_data, xform);
620         if (ret != 0) {
621                 AESNI_MB_LOG(ERR, "failed configure session parameters");
622
623                 /* Return session to mempool */
624                 rte_mempool_put(mempool, sess_private_data);
625                 return ret;
626         }
627
628         set_sym_session_private_data(sess, dev->driver_id,
629                         sess_private_data);
630
631         return 0;
632 }
633
634 /** Clear the memory of session so it doesn't leave key material behind */
635 static void
636 aesni_mb_pmd_sym_session_clear(struct rte_cryptodev *dev,
637                 struct rte_cryptodev_sym_session *sess)
638 {
639         uint8_t index = dev->driver_id;
640         void *sess_priv = get_sym_session_private_data(sess, index);
641
642         /* Zero out the whole structure */
643         if (sess_priv) {
644                 memset(sess_priv, 0, sizeof(struct aesni_mb_session));
645                 struct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv);
646                 set_sym_session_private_data(sess, index, NULL);
647                 rte_mempool_put(sess_mp, sess_priv);
648         }
649 }
650
651 struct rte_cryptodev_ops aesni_mb_pmd_ops = {
652                 .dev_configure          = aesni_mb_pmd_config,
653                 .dev_start              = aesni_mb_pmd_start,
654                 .dev_stop               = aesni_mb_pmd_stop,
655                 .dev_close              = aesni_mb_pmd_close,
656
657                 .stats_get              = aesni_mb_pmd_stats_get,
658                 .stats_reset            = aesni_mb_pmd_stats_reset,
659
660                 .dev_infos_get          = aesni_mb_pmd_info_get,
661
662                 .queue_pair_setup       = aesni_mb_pmd_qp_setup,
663                 .queue_pair_release     = aesni_mb_pmd_qp_release,
664                 .queue_pair_count       = aesni_mb_pmd_qp_count,
665
666                 .sym_session_get_size   = aesni_mb_pmd_sym_session_get_size,
667                 .sym_session_configure  = aesni_mb_pmd_sym_session_configure,
668                 .sym_session_clear      = aesni_mb_pmd_sym_session_clear
669 };
670
671 struct rte_cryptodev_ops *rte_aesni_mb_pmd_ops = &aesni_mb_pmd_ops;