018ce0e607b02f490ee784dd0da1125d70ee2dd2
[dpdk.git] / app / test-crypto-perf / cperf_ops.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2016-2017 Intel Corporation. All rights reserved.
5  *
6  *   Redistribution and use in source and binary forms, with or without
7  *   modification, are permitted provided that the following conditions
8  *   are met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  *       notice, this list of conditions and the following disclaimer.
12  *     * Redistributions in binary form must reproduce the above copyright
13  *       notice, this list of conditions and the following disclaimer in
14  *       the documentation and/or other materials provided with the
15  *       distribution.
16  *     * Neither the name of Intel Corporation nor the names of its
17  *       contributors may be used to endorse or promote products derived
18  *       from this software without specific prior written permission.
19  *
20  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #include <rte_cryptodev.h>
34
35 #include "cperf_ops.h"
36 #include "cperf_test_vectors.h"
37
38 static int
39 cperf_set_ops_null_cipher(struct rte_crypto_op **ops,
40                 struct rte_mbuf **bufs_in, struct rte_mbuf **bufs_out,
41                 uint16_t nb_ops, struct rte_cryptodev_sym_session *sess,
42                 const struct cperf_options *options,
43                 const struct cperf_test_vector *test_vector __rte_unused,
44                 uint16_t iv_offset __rte_unused)
45 {
46         uint16_t i;
47
48         for (i = 0; i < nb_ops; i++) {
49                 struct rte_crypto_sym_op *sym_op = ops[i]->sym;
50
51                 rte_crypto_op_attach_sym_session(ops[i], sess);
52
53                 sym_op->m_src = bufs_in[i];
54                 sym_op->m_dst = bufs_out[i];
55
56                 /* cipher parameters */
57                 sym_op->cipher.data.length = options->test_buffer_size;
58                 sym_op->cipher.data.offset = 0;
59         }
60
61         return 0;
62 }
63
64 static int
65 cperf_set_ops_null_auth(struct rte_crypto_op **ops,
66                 struct rte_mbuf **bufs_in, struct rte_mbuf **bufs_out,
67                 uint16_t nb_ops, struct rte_cryptodev_sym_session *sess,
68                 const struct cperf_options *options,
69                 const struct cperf_test_vector *test_vector __rte_unused,
70                 uint16_t iv_offset __rte_unused)
71 {
72         uint16_t i;
73
74         for (i = 0; i < nb_ops; i++) {
75                 struct rte_crypto_sym_op *sym_op = ops[i]->sym;
76
77                 rte_crypto_op_attach_sym_session(ops[i], sess);
78
79                 sym_op->m_src = bufs_in[i];
80                 sym_op->m_dst = bufs_out[i];
81
82                 /* auth parameters */
83                 sym_op->auth.data.length = options->test_buffer_size;
84                 sym_op->auth.data.offset = 0;
85         }
86
87         return 0;
88 }
89
90 static int
91 cperf_set_ops_cipher(struct rte_crypto_op **ops,
92                 struct rte_mbuf **bufs_in, struct rte_mbuf **bufs_out,
93                 uint16_t nb_ops, struct rte_cryptodev_sym_session *sess,
94                 const struct cperf_options *options,
95                 const struct cperf_test_vector *test_vector,
96                 uint16_t iv_offset)
97 {
98         uint16_t i;
99
100         for (i = 0; i < nb_ops; i++) {
101                 struct rte_crypto_sym_op *sym_op = ops[i]->sym;
102
103                 rte_crypto_op_attach_sym_session(ops[i], sess);
104
105                 sym_op->m_src = bufs_in[i];
106                 sym_op->m_dst = bufs_out[i];
107
108                 /* cipher parameters */
109                 sym_op->cipher.iv.offset = iv_offset;
110                 sym_op->cipher.iv.length = test_vector->iv.length;
111
112                 if (options->cipher_algo == RTE_CRYPTO_CIPHER_SNOW3G_UEA2 ||
113                                 options->cipher_algo == RTE_CRYPTO_CIPHER_KASUMI_F8 ||
114                                 options->cipher_algo == RTE_CRYPTO_CIPHER_ZUC_EEA3)
115                         sym_op->cipher.data.length = options->test_buffer_size << 3;
116                 else
117                         sym_op->cipher.data.length = options->test_buffer_size;
118
119                 sym_op->cipher.data.offset = 0;
120         }
121
122         if (options->test == CPERF_TEST_TYPE_VERIFY) {
123                 for (i = 0; i < nb_ops; i++) {
124                         uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ops[i],
125                                         uint8_t *, iv_offset);
126
127                         memcpy(iv_ptr, test_vector->iv.data,
128                                         test_vector->iv.length);
129         }       }
130
131         return 0;
132 }
133
134 static int
135 cperf_set_ops_auth(struct rte_crypto_op **ops,
136                 struct rte_mbuf **bufs_in, struct rte_mbuf **bufs_out,
137                 uint16_t nb_ops, struct rte_cryptodev_sym_session *sess,
138                 const struct cperf_options *options,
139                 const struct cperf_test_vector *test_vector,
140                 uint16_t iv_offset __rte_unused)
141 {
142         uint16_t i;
143
144         for (i = 0; i < nb_ops; i++) {
145                 struct rte_crypto_sym_op *sym_op = ops[i]->sym;
146
147                 rte_crypto_op_attach_sym_session(ops[i], sess);
148
149                 sym_op->m_src = bufs_in[i];
150                 sym_op->m_dst = bufs_out[i];
151
152                 /* authentication parameters */
153                 if (options->auth_op == RTE_CRYPTO_AUTH_OP_VERIFY) {
154                         sym_op->auth.digest.data = test_vector->digest.data;
155                         sym_op->auth.digest.phys_addr =
156                                         test_vector->digest.phys_addr;
157                         sym_op->auth.digest.length = options->auth_digest_sz;
158                 } else {
159
160                         uint32_t offset = options->test_buffer_size;
161                         struct rte_mbuf *buf, *tbuf;
162
163                         if (options->out_of_place) {
164                                 buf =  bufs_out[i];
165                         } else {
166                                 tbuf =  bufs_in[i];
167                                 while ((tbuf->next != NULL) &&
168                                                 (offset >= tbuf->data_len)) {
169                                         offset -= tbuf->data_len;
170                                         tbuf = tbuf->next;
171                                 }
172                                 buf = tbuf;
173                         }
174
175                         sym_op->auth.digest.data = rte_pktmbuf_mtod_offset(buf,
176                                         uint8_t *, offset);
177                         sym_op->auth.digest.phys_addr =
178                                         rte_pktmbuf_mtophys_offset(buf, offset);
179                         sym_op->auth.digest.length = options->auth_digest_sz;
180                         sym_op->auth.aad.phys_addr = test_vector->aad.phys_addr;
181                         sym_op->auth.aad.data = test_vector->aad.data;
182                         sym_op->auth.aad.length = options->auth_aad_sz;
183
184                 }
185
186                 if (options->auth_algo == RTE_CRYPTO_AUTH_SNOW3G_UIA2 ||
187                                 options->auth_algo == RTE_CRYPTO_AUTH_KASUMI_F9 ||
188                                 options->auth_algo == RTE_CRYPTO_AUTH_ZUC_EIA3)
189                         sym_op->auth.data.length = options->test_buffer_size << 3;
190                 else
191                         sym_op->auth.data.length = options->test_buffer_size;
192
193                 sym_op->auth.data.offset = 0;
194         }
195
196         return 0;
197 }
198
199 static int
200 cperf_set_ops_cipher_auth(struct rte_crypto_op **ops,
201                 struct rte_mbuf **bufs_in, struct rte_mbuf **bufs_out,
202                 uint16_t nb_ops, struct rte_cryptodev_sym_session *sess,
203                 const struct cperf_options *options,
204                 const struct cperf_test_vector *test_vector,
205                 uint16_t iv_offset)
206 {
207         uint16_t i;
208
209         for (i = 0; i < nb_ops; i++) {
210                 struct rte_crypto_sym_op *sym_op = ops[i]->sym;
211
212                 rte_crypto_op_attach_sym_session(ops[i], sess);
213
214                 sym_op->m_src = bufs_in[i];
215                 sym_op->m_dst = bufs_out[i];
216
217                 /* cipher parameters */
218                 sym_op->cipher.iv.offset = iv_offset;
219                 sym_op->cipher.iv.length = test_vector->iv.length;
220
221                 if (options->cipher_algo == RTE_CRYPTO_CIPHER_SNOW3G_UEA2 ||
222                                 options->cipher_algo == RTE_CRYPTO_CIPHER_KASUMI_F8 ||
223                                 options->cipher_algo == RTE_CRYPTO_CIPHER_ZUC_EEA3)
224                         sym_op->cipher.data.length = options->test_buffer_size << 3;
225                 else
226                         sym_op->cipher.data.length = options->test_buffer_size;
227
228                 sym_op->cipher.data.offset = 0;
229
230                 /* authentication parameters */
231                 if (options->auth_op == RTE_CRYPTO_AUTH_OP_VERIFY) {
232                         sym_op->auth.digest.data = test_vector->digest.data;
233                         sym_op->auth.digest.phys_addr =
234                                         test_vector->digest.phys_addr;
235                         sym_op->auth.digest.length = options->auth_digest_sz;
236                 } else {
237
238                         uint32_t offset = options->test_buffer_size;
239                         struct rte_mbuf *buf, *tbuf;
240
241                         if (options->out_of_place) {
242                                 buf =  bufs_out[i];
243                         } else {
244                                 tbuf =  bufs_in[i];
245                                 while ((tbuf->next != NULL) &&
246                                                 (offset >= tbuf->data_len)) {
247                                         offset -= tbuf->data_len;
248                                         tbuf = tbuf->next;
249                                 }
250                                 buf = tbuf;
251                         }
252
253                         sym_op->auth.digest.data = rte_pktmbuf_mtod_offset(buf,
254                                         uint8_t *, offset);
255                         sym_op->auth.digest.phys_addr =
256                                         rte_pktmbuf_mtophys_offset(buf, offset);
257                         sym_op->auth.digest.length = options->auth_digest_sz;
258                         sym_op->auth.aad.phys_addr = test_vector->aad.phys_addr;
259                         sym_op->auth.aad.data = test_vector->aad.data;
260                         sym_op->auth.aad.length = options->auth_aad_sz;
261                 }
262
263                 if (options->auth_algo == RTE_CRYPTO_AUTH_SNOW3G_UIA2 ||
264                                 options->auth_algo == RTE_CRYPTO_AUTH_KASUMI_F9 ||
265                                 options->auth_algo == RTE_CRYPTO_AUTH_ZUC_EIA3)
266                         sym_op->auth.data.length = options->test_buffer_size << 3;
267                 else
268                         sym_op->auth.data.length = options->test_buffer_size;
269
270                 sym_op->auth.data.offset = 0;
271         }
272
273         if (options->test == CPERF_TEST_TYPE_VERIFY) {
274                 for (i = 0; i < nb_ops; i++) {
275                         uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ops[i],
276                                         uint8_t *, iv_offset);
277
278                         memcpy(iv_ptr, test_vector->iv.data,
279                                         test_vector->iv.length);
280                 }
281         }
282
283         return 0;
284 }
285
286 static int
287 cperf_set_ops_aead(struct rte_crypto_op **ops,
288                 struct rte_mbuf **bufs_in, struct rte_mbuf **bufs_out,
289                 uint16_t nb_ops, struct rte_cryptodev_sym_session *sess,
290                 const struct cperf_options *options,
291                 const struct cperf_test_vector *test_vector,
292                 uint16_t iv_offset)
293 {
294         uint16_t i;
295
296         for (i = 0; i < nb_ops; i++) {
297                 struct rte_crypto_sym_op *sym_op = ops[i]->sym;
298
299                 rte_crypto_op_attach_sym_session(ops[i], sess);
300
301                 sym_op->m_src = bufs_in[i];
302                 sym_op->m_dst = bufs_out[i];
303
304                 /* cipher parameters */
305                 sym_op->cipher.iv.offset = iv_offset;
306                 sym_op->cipher.iv.length = test_vector->iv.length;
307
308                 sym_op->cipher.data.length = options->test_buffer_size;
309                 sym_op->cipher.data.offset =
310                                 RTE_ALIGN_CEIL(options->auth_aad_sz, 16);
311
312                 sym_op->auth.aad.data = rte_pktmbuf_mtod(bufs_in[i], uint8_t *);
313                 sym_op->auth.aad.phys_addr = rte_pktmbuf_mtophys(bufs_in[i]);
314                 sym_op->auth.aad.length = options->auth_aad_sz;
315
316                 /* authentication parameters */
317                 if (options->auth_op == RTE_CRYPTO_AUTH_OP_VERIFY) {
318                         sym_op->auth.digest.data = test_vector->digest.data;
319                         sym_op->auth.digest.phys_addr =
320                                         test_vector->digest.phys_addr;
321                         sym_op->auth.digest.length = options->auth_digest_sz;
322                 } else {
323
324                         uint32_t offset = sym_op->cipher.data.length +
325                                                 sym_op->cipher.data.offset;
326                         struct rte_mbuf *buf, *tbuf;
327
328                         if (options->out_of_place) {
329                                 buf =  bufs_out[i];
330                         } else {
331                                 tbuf =  bufs_in[i];
332                                 while ((tbuf->next != NULL) &&
333                                                 (offset >= tbuf->data_len)) {
334                                         offset -= tbuf->data_len;
335                                         tbuf = tbuf->next;
336                                 }
337                                 buf = tbuf;
338                         }
339
340                         sym_op->auth.digest.data = rte_pktmbuf_mtod_offset(buf,
341                                         uint8_t *, offset);
342                         sym_op->auth.digest.phys_addr =
343                                         rte_pktmbuf_mtophys_offset(buf, offset);
344
345                         sym_op->auth.digest.length = options->auth_digest_sz;
346                 }
347
348                 sym_op->auth.data.length = options->test_buffer_size;
349                 sym_op->auth.data.offset = options->auth_aad_sz;
350         }
351
352         if (options->test == CPERF_TEST_TYPE_VERIFY) {
353                 for (i = 0; i < nb_ops; i++) {
354                         uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ops[i],
355                                         uint8_t *, iv_offset);
356
357                         memcpy(iv_ptr, test_vector->iv.data,
358                                         test_vector->iv.length);
359                 }
360         }
361
362         return 0;
363 }
364
365 static struct rte_cryptodev_sym_session *
366 cperf_create_session(uint8_t dev_id,
367         const struct cperf_options *options,
368         const struct cperf_test_vector *test_vector)
369 {
370         struct rte_crypto_sym_xform cipher_xform;
371         struct rte_crypto_sym_xform auth_xform;
372         struct rte_cryptodev_sym_session *sess = NULL;
373
374         /*
375          * cipher only
376          */
377         if (options->op_type == CPERF_CIPHER_ONLY) {
378                 cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
379                 cipher_xform.next = NULL;
380                 cipher_xform.cipher.algo = options->cipher_algo;
381                 cipher_xform.cipher.op = options->cipher_op;
382
383                 /* cipher different than null */
384                 if (options->cipher_algo != RTE_CRYPTO_CIPHER_NULL) {
385                         cipher_xform.cipher.key.data =
386                                         test_vector->cipher_key.data;
387                         cipher_xform.cipher.key.length =
388                                         test_vector->cipher_key.length;
389                 } else {
390                         cipher_xform.cipher.key.data = NULL;
391                         cipher_xform.cipher.key.length = 0;
392                 }
393                 /* create crypto session */
394                 sess = rte_cryptodev_sym_session_create(dev_id, &cipher_xform);
395         /*
396          *  auth only
397          */
398         } else if (options->op_type == CPERF_AUTH_ONLY) {
399                 auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH;
400                 auth_xform.next = NULL;
401                 auth_xform.auth.algo = options->auth_algo;
402                 auth_xform.auth.op = options->auth_op;
403
404                 /* auth different than null */
405                 if (options->auth_algo != RTE_CRYPTO_AUTH_NULL) {
406                         auth_xform.auth.digest_length =
407                                         options->auth_digest_sz;
408                         auth_xform.auth.add_auth_data_length =
409                                         options->auth_aad_sz;
410                         auth_xform.auth.key.length =
411                                         test_vector->auth_key.length;
412                         auth_xform.auth.key.data = test_vector->auth_key.data;
413                 } else {
414                         auth_xform.auth.digest_length = 0;
415                         auth_xform.auth.add_auth_data_length = 0;
416                         auth_xform.auth.key.length = 0;
417                         auth_xform.auth.key.data = NULL;
418                 }
419                 /* create crypto session */
420                 sess =  rte_cryptodev_sym_session_create(dev_id, &auth_xform);
421         /*
422          * cipher and auth
423          */
424         } else if (options->op_type == CPERF_CIPHER_THEN_AUTH
425                         || options->op_type == CPERF_AUTH_THEN_CIPHER
426                         || options->op_type == CPERF_AEAD) {
427
428                 /*
429                  * cipher
430                  */
431                 cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
432                 cipher_xform.next = NULL;
433                 cipher_xform.cipher.algo = options->cipher_algo;
434                 cipher_xform.cipher.op = options->cipher_op;
435
436                 /* cipher different than null */
437                 if (options->cipher_algo != RTE_CRYPTO_CIPHER_NULL) {
438                         cipher_xform.cipher.key.data =
439                                         test_vector->cipher_key.data;
440                         cipher_xform.cipher.key.length =
441                                         test_vector->cipher_key.length;
442                 } else {
443                         cipher_xform.cipher.key.data = NULL;
444                         cipher_xform.cipher.key.length = 0;
445                 }
446
447                 /*
448                  * auth
449                  */
450                 auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH;
451                 auth_xform.next = NULL;
452                 auth_xform.auth.algo = options->auth_algo;
453                 auth_xform.auth.op = options->auth_op;
454
455                 /* auth different than null */
456                 if (options->auth_algo != RTE_CRYPTO_AUTH_NULL) {
457                         auth_xform.auth.digest_length = options->auth_digest_sz;
458                         auth_xform.auth.add_auth_data_length =
459                                         options->auth_aad_sz;
460                         /* auth options for aes gcm */
461                         if (options->cipher_algo == RTE_CRYPTO_CIPHER_AES_GCM &&
462                                 options->auth_algo == RTE_CRYPTO_AUTH_AES_GCM) {
463                                 auth_xform.auth.key.length = 0;
464                                 auth_xform.auth.key.data = NULL;
465                         } else { /* auth options for others */
466                                 auth_xform.auth.key.length =
467                                         test_vector->auth_key.length;
468                                 auth_xform.auth.key.data =
469                                                 test_vector->auth_key.data;
470                         }
471                 } else {
472                         auth_xform.auth.digest_length = 0;
473                         auth_xform.auth.add_auth_data_length = 0;
474                         auth_xform.auth.key.length = 0;
475                         auth_xform.auth.key.data = NULL;
476                 }
477
478                 /* create crypto session for aes gcm */
479                 if (options->cipher_algo == RTE_CRYPTO_CIPHER_AES_GCM) {
480                         if (options->cipher_op ==
481                                         RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
482                                 cipher_xform.next = &auth_xform;
483                                 /* create crypto session */
484                                 sess = rte_cryptodev_sym_session_create(dev_id,
485                                         &cipher_xform);
486                         } else { /* decrypt */
487                                 auth_xform.next = &cipher_xform;
488                                 /* create crypto session */
489                                 sess = rte_cryptodev_sym_session_create(dev_id,
490                                         &auth_xform);
491                         }
492                 } else { /* create crypto session for other */
493                         /* cipher then auth */
494                         if (options->op_type == CPERF_CIPHER_THEN_AUTH) {
495                                 cipher_xform.next = &auth_xform;
496                                 /* create crypto session */
497                                 sess = rte_cryptodev_sym_session_create(dev_id,
498                                                 &cipher_xform);
499                         } else { /* auth then cipher */
500                                 auth_xform.next = &cipher_xform;
501                                 /* create crypto session */
502                                 sess = rte_cryptodev_sym_session_create(dev_id,
503                                                 &auth_xform);
504                         }
505                 }
506         }
507         return sess;
508 }
509
510 int
511 cperf_get_op_functions(const struct cperf_options *options,
512                 struct cperf_op_fns *op_fns)
513 {
514         memset(op_fns, 0, sizeof(struct cperf_op_fns));
515
516         op_fns->sess_create = cperf_create_session;
517
518         if (options->op_type == CPERF_AEAD
519                         || options->op_type == CPERF_AUTH_THEN_CIPHER
520                         || options->op_type == CPERF_CIPHER_THEN_AUTH) {
521                 if (options->cipher_algo == RTE_CRYPTO_CIPHER_AES_GCM &&
522                                 options->auth_algo == RTE_CRYPTO_AUTH_AES_GCM)
523                         op_fns->populate_ops = cperf_set_ops_aead;
524                 else
525                         op_fns->populate_ops = cperf_set_ops_cipher_auth;
526                 return 0;
527         }
528         if (options->op_type == CPERF_AUTH_ONLY) {
529                 if (options->auth_algo == RTE_CRYPTO_AUTH_NULL)
530                         op_fns->populate_ops = cperf_set_ops_null_auth;
531                 else
532                         op_fns->populate_ops = cperf_set_ops_auth;
533                 return 0;
534         }
535         if (options->op_type == CPERF_CIPHER_ONLY) {
536                 if (options->cipher_algo == RTE_CRYPTO_CIPHER_NULL)
537                         op_fns->populate_ops = cperf_set_ops_null_cipher;
538                 else
539                         op_fns->populate_ops = cperf_set_ops_cipher;
540                 return 0;
541         }
542
543         return -1;
544 }