0f45a3c8fddead36dcd78b6ce0f7b0b214bf1065
[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.data = rte_crypto_op_ctod_offset(ops[i],
110                                                         uint8_t *, iv_offset);
111                 sym_op->cipher.iv.phys_addr = rte_crypto_op_ctophys_offset(ops[i],
112                                                         iv_offset);
113                 sym_op->cipher.iv.length = test_vector->iv.length;
114
115                 if (options->cipher_algo == RTE_CRYPTO_CIPHER_SNOW3G_UEA2 ||
116                                 options->cipher_algo == RTE_CRYPTO_CIPHER_KASUMI_F8 ||
117                                 options->cipher_algo == RTE_CRYPTO_CIPHER_ZUC_EEA3)
118                         sym_op->cipher.data.length = options->test_buffer_size << 3;
119                 else
120                         sym_op->cipher.data.length = options->test_buffer_size;
121
122                 sym_op->cipher.data.offset = 0;
123         }
124
125         if (options->test == CPERF_TEST_TYPE_VERIFY) {
126                 for (i = 0; i < nb_ops; i++)
127                         memcpy(ops[i]->sym->cipher.iv.data,
128                                 test_vector->iv.data,
129                                 test_vector->iv.length);
130         }
131
132         return 0;
133 }
134
135 static int
136 cperf_set_ops_auth(struct rte_crypto_op **ops,
137                 struct rte_mbuf **bufs_in, struct rte_mbuf **bufs_out,
138                 uint16_t nb_ops, struct rte_cryptodev_sym_session *sess,
139                 const struct cperf_options *options,
140                 const struct cperf_test_vector *test_vector,
141                 uint16_t iv_offset __rte_unused)
142 {
143         uint16_t i;
144
145         for (i = 0; i < nb_ops; i++) {
146                 struct rte_crypto_sym_op *sym_op = ops[i]->sym;
147
148                 rte_crypto_op_attach_sym_session(ops[i], sess);
149
150                 sym_op->m_src = bufs_in[i];
151                 sym_op->m_dst = bufs_out[i];
152
153                 /* authentication parameters */
154                 if (options->auth_op == RTE_CRYPTO_AUTH_OP_VERIFY) {
155                         sym_op->auth.digest.data = test_vector->digest.data;
156                         sym_op->auth.digest.phys_addr =
157                                         test_vector->digest.phys_addr;
158                         sym_op->auth.digest.length = options->auth_digest_sz;
159                 } else {
160
161                         uint32_t offset = options->test_buffer_size;
162                         struct rte_mbuf *buf, *tbuf;
163
164                         if (options->out_of_place) {
165                                 buf =  bufs_out[i];
166                         } else {
167                                 tbuf =  bufs_in[i];
168                                 while ((tbuf->next != NULL) &&
169                                                 (offset >= tbuf->data_len)) {
170                                         offset -= tbuf->data_len;
171                                         tbuf = tbuf->next;
172                                 }
173                                 buf = tbuf;
174                         }
175
176                         sym_op->auth.digest.data = rte_pktmbuf_mtod_offset(buf,
177                                         uint8_t *, offset);
178                         sym_op->auth.digest.phys_addr =
179                                         rte_pktmbuf_mtophys_offset(buf, offset);
180                         sym_op->auth.digest.length = options->auth_digest_sz;
181                         sym_op->auth.aad.phys_addr = test_vector->aad.phys_addr;
182                         sym_op->auth.aad.data = test_vector->aad.data;
183                         sym_op->auth.aad.length = options->auth_aad_sz;
184
185                 }
186
187                 if (options->auth_algo == RTE_CRYPTO_AUTH_SNOW3G_UIA2 ||
188                                 options->auth_algo == RTE_CRYPTO_AUTH_KASUMI_F9 ||
189                                 options->auth_algo == RTE_CRYPTO_AUTH_ZUC_EIA3)
190                         sym_op->auth.data.length = options->test_buffer_size << 3;
191                 else
192                         sym_op->auth.data.length = options->test_buffer_size;
193
194                 sym_op->auth.data.offset = 0;
195         }
196
197         return 0;
198 }
199
200 static int
201 cperf_set_ops_cipher_auth(struct rte_crypto_op **ops,
202                 struct rte_mbuf **bufs_in, struct rte_mbuf **bufs_out,
203                 uint16_t nb_ops, struct rte_cryptodev_sym_session *sess,
204                 const struct cperf_options *options,
205                 const struct cperf_test_vector *test_vector,
206                 uint16_t iv_offset)
207 {
208         uint16_t i;
209
210         for (i = 0; i < nb_ops; i++) {
211                 struct rte_crypto_sym_op *sym_op = ops[i]->sym;
212
213                 rte_crypto_op_attach_sym_session(ops[i], sess);
214
215                 sym_op->m_src = bufs_in[i];
216                 sym_op->m_dst = bufs_out[i];
217
218                 /* cipher parameters */
219                 sym_op->cipher.iv.data = rte_crypto_op_ctod_offset(ops[i],
220                                                         uint8_t *, iv_offset);
221                 sym_op->cipher.iv.phys_addr = rte_crypto_op_ctophys_offset(ops[i],
222                                                         iv_offset);
223                 sym_op->cipher.iv.length = test_vector->iv.length;
224
225                 if (options->cipher_algo == RTE_CRYPTO_CIPHER_SNOW3G_UEA2 ||
226                                 options->cipher_algo == RTE_CRYPTO_CIPHER_KASUMI_F8 ||
227                                 options->cipher_algo == RTE_CRYPTO_CIPHER_ZUC_EEA3)
228                         sym_op->cipher.data.length = options->test_buffer_size << 3;
229                 else
230                         sym_op->cipher.data.length = options->test_buffer_size;
231
232                 sym_op->cipher.data.offset = 0;
233
234                 /* authentication parameters */
235                 if (options->auth_op == RTE_CRYPTO_AUTH_OP_VERIFY) {
236                         sym_op->auth.digest.data = test_vector->digest.data;
237                         sym_op->auth.digest.phys_addr =
238                                         test_vector->digest.phys_addr;
239                         sym_op->auth.digest.length = options->auth_digest_sz;
240                 } else {
241
242                         uint32_t offset = options->test_buffer_size;
243                         struct rte_mbuf *buf, *tbuf;
244
245                         if (options->out_of_place) {
246                                 buf =  bufs_out[i];
247                         } else {
248                                 tbuf =  bufs_in[i];
249                                 while ((tbuf->next != NULL) &&
250                                                 (offset >= tbuf->data_len)) {
251                                         offset -= tbuf->data_len;
252                                         tbuf = tbuf->next;
253                                 }
254                                 buf = tbuf;
255                         }
256
257                         sym_op->auth.digest.data = rte_pktmbuf_mtod_offset(buf,
258                                         uint8_t *, offset);
259                         sym_op->auth.digest.phys_addr =
260                                         rte_pktmbuf_mtophys_offset(buf, offset);
261                         sym_op->auth.digest.length = options->auth_digest_sz;
262                         sym_op->auth.aad.phys_addr = test_vector->aad.phys_addr;
263                         sym_op->auth.aad.data = test_vector->aad.data;
264                         sym_op->auth.aad.length = options->auth_aad_sz;
265                 }
266
267                 if (options->auth_algo == RTE_CRYPTO_AUTH_SNOW3G_UIA2 ||
268                                 options->auth_algo == RTE_CRYPTO_AUTH_KASUMI_F9 ||
269                                 options->auth_algo == RTE_CRYPTO_AUTH_ZUC_EIA3)
270                         sym_op->auth.data.length = options->test_buffer_size << 3;
271                 else
272                         sym_op->auth.data.length = options->test_buffer_size;
273
274                 sym_op->auth.data.offset = 0;
275         }
276
277         if (options->test == CPERF_TEST_TYPE_VERIFY) {
278                 for (i = 0; i < nb_ops; i++)
279                         memcpy(ops[i]->sym->cipher.iv.data,
280                                 test_vector->iv.data,
281                                 test_vector->iv.length);
282         }
283
284         return 0;
285 }
286
287 static int
288 cperf_set_ops_aead(struct rte_crypto_op **ops,
289                 struct rte_mbuf **bufs_in, struct rte_mbuf **bufs_out,
290                 uint16_t nb_ops, struct rte_cryptodev_sym_session *sess,
291                 const struct cperf_options *options,
292                 const struct cperf_test_vector *test_vector,
293                 uint16_t iv_offset)
294 {
295         uint16_t i;
296
297         for (i = 0; i < nb_ops; i++) {
298                 struct rte_crypto_sym_op *sym_op = ops[i]->sym;
299
300                 rte_crypto_op_attach_sym_session(ops[i], sess);
301
302                 sym_op->m_src = bufs_in[i];
303                 sym_op->m_dst = bufs_out[i];
304
305                 /* cipher parameters */
306                 sym_op->cipher.iv.data = rte_crypto_op_ctod_offset(ops[i],
307                                                         uint8_t *, iv_offset);
308                 sym_op->cipher.iv.phys_addr = rte_crypto_op_ctophys_offset(ops[i],
309                                                         iv_offset);
310                 sym_op->cipher.iv.length = test_vector->iv.length;
311
312                 sym_op->cipher.data.length = options->test_buffer_size;
313                 sym_op->cipher.data.offset =
314                                 RTE_ALIGN_CEIL(options->auth_aad_sz, 16);
315
316                 sym_op->auth.aad.data = rte_pktmbuf_mtod(bufs_in[i], uint8_t *);
317                 sym_op->auth.aad.phys_addr = rte_pktmbuf_mtophys(bufs_in[i]);
318                 sym_op->auth.aad.length = options->auth_aad_sz;
319
320                 /* authentication parameters */
321                 if (options->auth_op == RTE_CRYPTO_AUTH_OP_VERIFY) {
322                         sym_op->auth.digest.data = test_vector->digest.data;
323                         sym_op->auth.digest.phys_addr =
324                                         test_vector->digest.phys_addr;
325                         sym_op->auth.digest.length = options->auth_digest_sz;
326                 } else {
327
328                         uint32_t offset = sym_op->cipher.data.length +
329                                                 sym_op->cipher.data.offset;
330                         struct rte_mbuf *buf, *tbuf;
331
332                         if (options->out_of_place) {
333                                 buf =  bufs_out[i];
334                         } else {
335                                 tbuf =  bufs_in[i];
336                                 while ((tbuf->next != NULL) &&
337                                                 (offset >= tbuf->data_len)) {
338                                         offset -= tbuf->data_len;
339                                         tbuf = tbuf->next;
340                                 }
341                                 buf = tbuf;
342                         }
343
344                         sym_op->auth.digest.data = rte_pktmbuf_mtod_offset(buf,
345                                         uint8_t *, offset);
346                         sym_op->auth.digest.phys_addr =
347                                         rte_pktmbuf_mtophys_offset(buf, offset);
348
349                         sym_op->auth.digest.length = options->auth_digest_sz;
350                 }
351
352                 sym_op->auth.data.length = options->test_buffer_size;
353                 sym_op->auth.data.offset = options->auth_aad_sz;
354         }
355
356         if (options->test == CPERF_TEST_TYPE_VERIFY) {
357                 for (i = 0; i < nb_ops; i++)
358                         memcpy(ops[i]->sym->cipher.iv.data,
359                                 test_vector->iv.data,
360                                 test_vector->iv.length);
361         }
362
363         return 0;
364 }
365
366 static struct rte_cryptodev_sym_session *
367 cperf_create_session(uint8_t dev_id,
368         const struct cperf_options *options,
369         const struct cperf_test_vector *test_vector)
370 {
371         struct rte_crypto_sym_xform cipher_xform;
372         struct rte_crypto_sym_xform auth_xform;
373         struct rte_cryptodev_sym_session *sess = NULL;
374
375         /*
376          * cipher only
377          */
378         if (options->op_type == CPERF_CIPHER_ONLY) {
379                 cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
380                 cipher_xform.next = NULL;
381                 cipher_xform.cipher.algo = options->cipher_algo;
382                 cipher_xform.cipher.op = options->cipher_op;
383
384                 /* cipher different than null */
385                 if (options->cipher_algo != RTE_CRYPTO_CIPHER_NULL) {
386                         cipher_xform.cipher.key.data =
387                                         test_vector->cipher_key.data;
388                         cipher_xform.cipher.key.length =
389                                         test_vector->cipher_key.length;
390                 } else {
391                         cipher_xform.cipher.key.data = NULL;
392                         cipher_xform.cipher.key.length = 0;
393                 }
394                 /* create crypto session */
395                 sess = rte_cryptodev_sym_session_create(dev_id, &cipher_xform);
396         /*
397          *  auth only
398          */
399         } else if (options->op_type == CPERF_AUTH_ONLY) {
400                 auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH;
401                 auth_xform.next = NULL;
402                 auth_xform.auth.algo = options->auth_algo;
403                 auth_xform.auth.op = options->auth_op;
404
405                 /* auth different than null */
406                 if (options->auth_algo != RTE_CRYPTO_AUTH_NULL) {
407                         auth_xform.auth.digest_length =
408                                         options->auth_digest_sz;
409                         auth_xform.auth.add_auth_data_length =
410                                         options->auth_aad_sz;
411                         auth_xform.auth.key.length =
412                                         test_vector->auth_key.length;
413                         auth_xform.auth.key.data = test_vector->auth_key.data;
414                 } else {
415                         auth_xform.auth.digest_length = 0;
416                         auth_xform.auth.add_auth_data_length = 0;
417                         auth_xform.auth.key.length = 0;
418                         auth_xform.auth.key.data = NULL;
419                 }
420                 /* create crypto session */
421                 sess =  rte_cryptodev_sym_session_create(dev_id, &auth_xform);
422         /*
423          * cipher and auth
424          */
425         } else if (options->op_type == CPERF_CIPHER_THEN_AUTH
426                         || options->op_type == CPERF_AUTH_THEN_CIPHER
427                         || options->op_type == CPERF_AEAD) {
428
429                 /*
430                  * cipher
431                  */
432                 cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
433                 cipher_xform.next = NULL;
434                 cipher_xform.cipher.algo = options->cipher_algo;
435                 cipher_xform.cipher.op = options->cipher_op;
436
437                 /* cipher different than null */
438                 if (options->cipher_algo != RTE_CRYPTO_CIPHER_NULL) {
439                         cipher_xform.cipher.key.data =
440                                         test_vector->cipher_key.data;
441                         cipher_xform.cipher.key.length =
442                                         test_vector->cipher_key.length;
443                 } else {
444                         cipher_xform.cipher.key.data = NULL;
445                         cipher_xform.cipher.key.length = 0;
446                 }
447
448                 /*
449                  * auth
450                  */
451                 auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH;
452                 auth_xform.next = NULL;
453                 auth_xform.auth.algo = options->auth_algo;
454                 auth_xform.auth.op = options->auth_op;
455
456                 /* auth different than null */
457                 if (options->auth_algo != RTE_CRYPTO_AUTH_NULL) {
458                         auth_xform.auth.digest_length = options->auth_digest_sz;
459                         auth_xform.auth.add_auth_data_length =
460                                         options->auth_aad_sz;
461                         /* auth options for aes gcm */
462                         if (options->cipher_algo == RTE_CRYPTO_CIPHER_AES_GCM &&
463                                 options->auth_algo == RTE_CRYPTO_AUTH_AES_GCM) {
464                                 auth_xform.auth.key.length = 0;
465                                 auth_xform.auth.key.data = NULL;
466                         } else { /* auth options for others */
467                                 auth_xform.auth.key.length =
468                                         test_vector->auth_key.length;
469                                 auth_xform.auth.key.data =
470                                                 test_vector->auth_key.data;
471                         }
472                 } else {
473                         auth_xform.auth.digest_length = 0;
474                         auth_xform.auth.add_auth_data_length = 0;
475                         auth_xform.auth.key.length = 0;
476                         auth_xform.auth.key.data = NULL;
477                 }
478
479                 /* create crypto session for aes gcm */
480                 if (options->cipher_algo == RTE_CRYPTO_CIPHER_AES_GCM) {
481                         if (options->cipher_op ==
482                                         RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
483                                 cipher_xform.next = &auth_xform;
484                                 /* create crypto session */
485                                 sess = rte_cryptodev_sym_session_create(dev_id,
486                                         &cipher_xform);
487                         } else { /* decrypt */
488                                 auth_xform.next = &cipher_xform;
489                                 /* create crypto session */
490                                 sess = rte_cryptodev_sym_session_create(dev_id,
491                                         &auth_xform);
492                         }
493                 } else { /* create crypto session for other */
494                         /* cipher then auth */
495                         if (options->op_type == CPERF_CIPHER_THEN_AUTH) {
496                                 cipher_xform.next = &auth_xform;
497                                 /* create crypto session */
498                                 sess = rte_cryptodev_sym_session_create(dev_id,
499                                                 &cipher_xform);
500                         } else { /* auth then cipher */
501                                 auth_xform.next = &cipher_xform;
502                                 /* create crypto session */
503                                 sess = rte_cryptodev_sym_session_create(dev_id,
504                                                 &auth_xform);
505                         }
506                 }
507         }
508         return sess;
509 }
510
511 int
512 cperf_get_op_functions(const struct cperf_options *options,
513                 struct cperf_op_fns *op_fns)
514 {
515         memset(op_fns, 0, sizeof(struct cperf_op_fns));
516
517         op_fns->sess_create = cperf_create_session;
518
519         if (options->op_type == CPERF_AEAD
520                         || options->op_type == CPERF_AUTH_THEN_CIPHER
521                         || options->op_type == CPERF_CIPHER_THEN_AUTH) {
522                 if (options->cipher_algo == RTE_CRYPTO_CIPHER_AES_GCM &&
523                                 options->auth_algo == RTE_CRYPTO_AUTH_AES_GCM)
524                         op_fns->populate_ops = cperf_set_ops_aead;
525                 else
526                         op_fns->populate_ops = cperf_set_ops_cipher_auth;
527                 return 0;
528         }
529         if (options->op_type == CPERF_AUTH_ONLY) {
530                 if (options->auth_algo == RTE_CRYPTO_AUTH_NULL)
531                         op_fns->populate_ops = cperf_set_ops_null_auth;
532                 else
533                         op_fns->populate_ops = cperf_set_ops_auth;
534                 return 0;
535         }
536         if (options->op_type == CPERF_CIPHER_ONLY) {
537                 if (options->cipher_algo == RTE_CRYPTO_CIPHER_NULL)
538                         op_fns->populate_ops = cperf_set_ops_null_cipher;
539                 else
540                         op_fns->populate_ops = cperf_set_ops_cipher;
541                 return 0;
542         }
543
544         return -1;
545 }