test/mbuf: add unit test on mbuf flag names
[dpdk.git] / app / test / test_cryptodev_blockcipher.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2015-2017 Intel Corporation
3  */
4
5 #include <rte_common.h>
6 #include <rte_hexdump.h>
7 #include <rte_mbuf.h>
8 #include <rte_malloc.h>
9 #include <rte_memcpy.h>
10 #include <rte_pause.h>
11
12 #include <rte_crypto.h>
13 #include <rte_cryptodev.h>
14 #include <rte_cryptodev_pmd.h>
15
16 #include "test.h"
17 #include "test_cryptodev.h"
18 #include "test_cryptodev_blockcipher.h"
19 #include "test_cryptodev_aes_test_vectors.h"
20 #include "test_cryptodev_des_test_vectors.h"
21 #include "test_cryptodev_hash_test_vectors.h"
22
23 static int
24 test_blockcipher_one_case(const struct blockcipher_test_case *t,
25         struct rte_mempool *mbuf_pool,
26         struct rte_mempool *op_mpool,
27         struct rte_mempool *sess_mpool,
28         struct rte_mempool *sess_priv_mpool,
29         uint8_t dev_id,
30         int driver_id,
31         char *test_msg)
32 {
33         struct rte_mbuf *ibuf = NULL;
34         struct rte_mbuf *obuf = NULL;
35         struct rte_mbuf *iobuf;
36         struct rte_crypto_sym_xform *cipher_xform = NULL;
37         struct rte_crypto_sym_xform *auth_xform = NULL;
38         struct rte_crypto_sym_xform *init_xform = NULL;
39         struct rte_crypto_sym_op *sym_op = NULL;
40         struct rte_crypto_op *op = NULL;
41         struct rte_cryptodev_info dev_info;
42         struct rte_cryptodev_sym_session *sess = NULL;
43
44         int status = TEST_SUCCESS;
45         const struct blockcipher_test_data *tdata = t->test_data;
46         uint8_t cipher_key[tdata->cipher_key.len];
47         uint8_t auth_key[tdata->auth_key.len];
48         uint32_t buf_len = tdata->ciphertext.len;
49         uint32_t digest_len = 0;
50         char *buf_p = NULL;
51         uint8_t src_pattern = 0xa5;
52         uint8_t dst_pattern = 0xb6;
53         uint8_t tmp_src_buf[MBUF_SIZE];
54         uint8_t tmp_dst_buf[MBUF_SIZE];
55
56         int openssl_pmd = rte_cryptodev_driver_id_get(
57                         RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD));
58         int ccp_pmd = rte_cryptodev_driver_id_get(
59                         RTE_STR(CRYPTODEV_NAME_CCP_PMD));
60         int scheduler_pmd = rte_cryptodev_driver_id_get(
61                         RTE_STR(CRYPTODEV_NAME_SCHEDULER_PMD));
62         int armv8_pmd = rte_cryptodev_driver_id_get(
63                         RTE_STR(CRYPTODEV_NAME_ARMV8_PMD));
64         int aesni_mb_pmd = rte_cryptodev_driver_id_get(
65                         RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD));
66         int qat_pmd = rte_cryptodev_driver_id_get(
67                         RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD));
68         int dpaa2_sec_pmd = rte_cryptodev_driver_id_get(
69                         RTE_STR(CRYPTODEV_NAME_DPAA2_SEC_PMD));
70         int dpaa_sec_pmd = rte_cryptodev_driver_id_get(
71                         RTE_STR(CRYPTODEV_NAME_DPAA_SEC_PMD));
72         int caam_jr_pmd = rte_cryptodev_driver_id_get(
73                         RTE_STR(CRYPTODEV_NAME_CAAM_JR_PMD));
74         int mrvl_pmd = rte_cryptodev_driver_id_get(
75                         RTE_STR(CRYPTODEV_NAME_MVSAM_PMD));
76         int virtio_pmd = rte_cryptodev_driver_id_get(
77                         RTE_STR(CRYPTODEV_NAME_VIRTIO_PMD));
78         int octeontx_pmd = rte_cryptodev_driver_id_get(
79                         RTE_STR(CRYPTODEV_NAME_OCTEONTX_SYM_PMD));
80         int null_pmd = rte_cryptodev_driver_id_get(
81                                 RTE_STR(CRYPTODEV_NAME_NULL_PMD));
82         int nitrox_pmd = rte_cryptodev_driver_id_get(
83                         RTE_STR(CRYPTODEV_NAME_NITROX_PMD));
84
85         int nb_segs = 1;
86         uint32_t nb_iterates = 0;
87
88         rte_cryptodev_info_get(dev_id, &dev_info);
89
90         if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SG) {
91                 uint64_t feat_flags = dev_info.feature_flags;
92                 uint64_t oop_flag = RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT;
93
94                 if (t->feature_mask && BLOCKCIPHER_TEST_FEATURE_OOP) {
95                         if (!(feat_flags & oop_flag)) {
96                                 printf("Device doesn't support out-of-place "
97                                         "scatter-gather in input mbuf. "
98                                         "Test Skipped.\n");
99                                 return 0;
100                         }
101                 } else {
102                         if (!(feat_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL)) {
103                                 printf("Device doesn't support in-place "
104                                         "scatter-gather mbufs. "
105                                         "Test Skipped.\n");
106                                 return 0;
107                         }
108                 }
109
110                 nb_segs = 3;
111         }
112
113         if (tdata->cipher_key.len)
114                 memcpy(cipher_key, tdata->cipher_key.data,
115                         tdata->cipher_key.len);
116         if (tdata->auth_key.len)
117                 memcpy(auth_key, tdata->auth_key.data,
118                         tdata->auth_key.len);
119
120         if (driver_id == dpaa2_sec_pmd ||
121                         driver_id == dpaa_sec_pmd ||
122                         driver_id == caam_jr_pmd ||
123                         driver_id == qat_pmd ||
124                         driver_id == openssl_pmd ||
125                         driver_id == armv8_pmd ||
126                         driver_id == mrvl_pmd ||
127                         driver_id == ccp_pmd ||
128                         driver_id == virtio_pmd ||
129                         driver_id == octeontx_pmd ||
130                         driver_id == null_pmd ||
131                         driver_id == nitrox_pmd) { /* Fall through */
132                 digest_len = tdata->digest.len;
133         } else if (driver_id == aesni_mb_pmd ||
134                         driver_id == scheduler_pmd) {
135                 digest_len = tdata->digest.truncated_len;
136         } else {
137                 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
138                         "line %u FAILED: %s",
139                         __LINE__, "Unsupported PMD type");
140                 status = TEST_FAILED;
141                 goto error_exit;
142         }
143
144         /* preparing data */
145         if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH)
146                 buf_len += digest_len;
147
148         /* for contiguous mbuf, nb_segs is 1 */
149         ibuf = create_segmented_mbuf(mbuf_pool,
150                         tdata->ciphertext.len, nb_segs, src_pattern);
151         if (ibuf == NULL) {
152                 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
153                         "line %u FAILED: %s",
154                         __LINE__, "Cannot create source mbuf");
155                 status = TEST_FAILED;
156                 goto error_exit;
157         }
158
159         /* only encryption requires plaintext.data input,
160          * decryption/(digest gen)/(digest verify) use ciphertext.data
161          * to be computed
162          */
163         if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT)
164                 pktmbuf_write(ibuf, 0, tdata->plaintext.len,
165                                 tdata->plaintext.data);
166         else
167                 pktmbuf_write(ibuf, 0, tdata->ciphertext.len,
168                                 tdata->ciphertext.data);
169
170         buf_p = rte_pktmbuf_append(ibuf, digest_len);
171         if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY)
172                 rte_memcpy(buf_p, tdata->digest.data, digest_len);
173         else
174                 memset(buf_p, 0, digest_len);
175
176         if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
177                 obuf = rte_pktmbuf_alloc(mbuf_pool);
178                 if (!obuf) {
179                         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
180                                 "FAILED: %s", __LINE__,
181                                 "Allocation of rte_mbuf failed");
182                         status = TEST_FAILED;
183                         goto error_exit;
184                 }
185                 memset(obuf->buf_addr, dst_pattern, obuf->buf_len);
186
187                 buf_p = rte_pktmbuf_append(obuf, buf_len);
188                 if (!buf_p) {
189                         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
190                                 "FAILED: %s", __LINE__,
191                                 "No room to append mbuf");
192                         status = TEST_FAILED;
193                         goto error_exit;
194                 }
195                 memset(buf_p, 0, buf_len);
196         }
197
198         /* Generate Crypto op data structure */
199         op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
200         if (!op) {
201                 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
202                         "line %u FAILED: %s",
203                         __LINE__, "Failed to allocate symmetric crypto "
204                         "operation struct");
205                 status = TEST_FAILED;
206                 goto error_exit;
207         }
208
209         sym_op = op->sym;
210
211 iterate:
212         if (nb_iterates) {
213                 struct rte_mbuf *tmp_buf = ibuf;
214
215                 ibuf = obuf;
216                 obuf = tmp_buf;
217
218                 rte_pktmbuf_reset(ibuf);
219                 rte_pktmbuf_reset(obuf);
220
221                 rte_pktmbuf_append(ibuf, tdata->ciphertext.len);
222
223                 /* only encryption requires plaintext.data input,
224                  * decryption/(digest gen)/(digest verify) use ciphertext.data
225                  * to be computed
226                  */
227                 if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT)
228                         pktmbuf_write(ibuf, 0, tdata->plaintext.len,
229                                         tdata->plaintext.data);
230                 else
231                         pktmbuf_write(ibuf, 0, tdata->ciphertext.len,
232                                         tdata->ciphertext.data);
233
234                 buf_p = rte_pktmbuf_append(ibuf, digest_len);
235                 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY)
236                         rte_memcpy(buf_p, tdata->digest.data, digest_len);
237                 else
238                         memset(buf_p, 0, digest_len);
239
240                 memset(obuf->buf_addr, dst_pattern, obuf->buf_len);
241
242                 buf_p = rte_pktmbuf_append(obuf, buf_len);
243                 if (!buf_p) {
244                         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
245                                 "FAILED: %s", __LINE__,
246                                 "No room to append mbuf");
247                         status = TEST_FAILED;
248                         goto error_exit;
249                 }
250                 memset(buf_p, 0, buf_len);
251         }
252
253         sym_op->m_src = ibuf;
254
255         if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
256                 sym_op->m_dst = obuf;
257                 iobuf = obuf;
258         } else {
259                 sym_op->m_dst = NULL;
260                 iobuf = ibuf;
261         }
262
263         /* sessionless op requires allocate xform using
264          * rte_crypto_op_sym_xforms_alloc(), otherwise rte_zmalloc()
265          * is used
266          */
267         if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
268                 uint32_t n_xforms = 0;
269
270                 if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER)
271                         n_xforms++;
272                 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH)
273                         n_xforms++;
274
275                 if (rte_crypto_op_sym_xforms_alloc(op, n_xforms)
276                         == NULL) {
277                         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
278                                 "FAILED: %s", __LINE__, "Failed to "
279                                 "allocate space for crypto transforms");
280                         status = TEST_FAILED;
281                         goto error_exit;
282                 }
283         } else {
284                 cipher_xform = rte_zmalloc(NULL,
285                         sizeof(struct rte_crypto_sym_xform), 0);
286
287                 auth_xform = rte_zmalloc(NULL,
288                         sizeof(struct rte_crypto_sym_xform), 0);
289
290                 if (!cipher_xform || !auth_xform) {
291                         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
292                                 "FAILED: %s", __LINE__, "Failed to "
293                                 "allocate memory for crypto transforms");
294                         status = TEST_FAILED;
295                         goto error_exit;
296                 }
297         }
298
299         /* preparing xform, for sessioned op, init_xform is initialized
300          * here and later as param in rte_cryptodev_sym_session_create() call
301          */
302         if (t->op_mask == BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN) {
303                 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
304                         cipher_xform = op->sym->xform;
305                         auth_xform = cipher_xform->next;
306                         auth_xform->next = NULL;
307                 } else {
308                         cipher_xform->next = auth_xform;
309                         auth_xform->next = NULL;
310                         init_xform = cipher_xform;
311                 }
312         } else if (t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC) {
313                 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
314                         auth_xform = op->sym->xform;
315                         cipher_xform = auth_xform->next;
316                         cipher_xform->next = NULL;
317                 } else {
318                         auth_xform->next = cipher_xform;
319                         cipher_xform->next = NULL;
320                         init_xform = auth_xform;
321                 }
322         } else if ((t->op_mask == BLOCKCIPHER_TEST_OP_ENCRYPT) ||
323                         (t->op_mask == BLOCKCIPHER_TEST_OP_DECRYPT)) {
324                 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)
325                         cipher_xform = op->sym->xform;
326                 else
327                         init_xform = cipher_xform;
328                 cipher_xform->next = NULL;
329         } else if ((t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_GEN) ||
330                         (t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_VERIFY)) {
331                 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)
332                         auth_xform = op->sym->xform;
333                 else
334                         init_xform = auth_xform;
335                 auth_xform->next = NULL;
336         } else {
337                 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
338                         "line %u FAILED: %s",
339                         __LINE__, "Unrecognized operation");
340                 status = TEST_FAILED;
341                 goto error_exit;
342         }
343
344         /*configure xforms & sym_op cipher and auth data*/
345         if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
346                 cipher_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
347                 cipher_xform->cipher.algo = tdata->crypto_algo;
348                 if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT)
349                         cipher_xform->cipher.op =
350                                 RTE_CRYPTO_CIPHER_OP_ENCRYPT;
351                 else
352                         cipher_xform->cipher.op =
353                                 RTE_CRYPTO_CIPHER_OP_DECRYPT;
354                 cipher_xform->cipher.key.data = cipher_key;
355                 cipher_xform->cipher.key.length = tdata->cipher_key.len;
356                 cipher_xform->cipher.iv.offset = IV_OFFSET;
357                 cipher_xform->cipher.iv.length = tdata->iv.len;
358
359                 sym_op->cipher.data.offset = tdata->cipher_offset;
360                 sym_op->cipher.data.length = tdata->ciphertext.len -
361                                 tdata->cipher_offset;
362                 rte_memcpy(rte_crypto_op_ctod_offset(op, uint8_t *, IV_OFFSET),
363                                 tdata->iv.data,
364                                 tdata->iv.len);
365         }
366
367         if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) {
368                 uint32_t digest_offset = tdata->ciphertext.len;
369
370                 auth_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
371                 auth_xform->auth.algo = tdata->auth_algo;
372                 auth_xform->auth.key.length = tdata->auth_key.len;
373                 auth_xform->auth.key.data = auth_key;
374                 auth_xform->auth.digest_length = digest_len;
375
376                 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) {
377                         auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_GENERATE;
378                         sym_op->auth.digest.data = pktmbuf_mtod_offset
379                                 (iobuf, digest_offset);
380                         sym_op->auth.digest.phys_addr =
381                                 pktmbuf_iova_offset(iobuf,
382                                         digest_offset);
383                 } else {
384                         auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_VERIFY;
385                         sym_op->auth.digest.data = pktmbuf_mtod_offset
386                                 (sym_op->m_src, digest_offset);
387                         sym_op->auth.digest.phys_addr =
388                                 pktmbuf_iova_offset(sym_op->m_src,
389                                         digest_offset);
390                 }
391
392                 sym_op->auth.data.offset = tdata->auth_offset;
393                 sym_op->auth.data.length = tdata->ciphertext.len -
394                                 tdata->auth_offset;
395         }
396
397         /**
398          * Create session for sessioned op. For mbuf iteration test,
399          * skip the session creation for the second iteration.
400          */
401         if (!(t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) &&
402                         nb_iterates == 0) {
403                 sess = rte_cryptodev_sym_session_create(sess_mpool);
404
405                 rte_cryptodev_sym_session_init(dev_id, sess, init_xform,
406                                 sess_priv_mpool);
407                 if (!sess) {
408                         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
409                                 "FAILED: %s", __LINE__,
410                                 "Session creation failed");
411                         status = TEST_FAILED;
412                         goto error_exit;
413                 }
414
415                 /* attach symmetric crypto session to crypto operations */
416                 rte_crypto_op_attach_sym_session(op, sess);
417         }
418
419         debug_hexdump(stdout, "m_src(before):",
420                         sym_op->m_src->buf_addr, sym_op->m_src->buf_len);
421         rte_memcpy(tmp_src_buf, sym_op->m_src->buf_addr,
422                                                 sym_op->m_src->buf_len);
423         if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
424                 debug_hexdump(stdout, "m_dst(before):",
425                         sym_op->m_dst->buf_addr, sym_op->m_dst->buf_len);
426                 rte_memcpy(tmp_dst_buf, sym_op->m_dst->buf_addr,
427                                                 sym_op->m_dst->buf_len);
428         }
429
430         /* Process crypto operation */
431         if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
432                 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
433                         "line %u FAILED: %s",
434                         __LINE__, "Error sending packet for encryption");
435                 status = TEST_FAILED;
436                 goto error_exit;
437         }
438
439         op = NULL;
440
441         while (rte_cryptodev_dequeue_burst(dev_id, 0, &op, 1) == 0)
442                 rte_pause();
443
444         if (!op) {
445                 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
446                         "line %u FAILED: %s",
447                         __LINE__, "Failed to process sym crypto op");
448                 status = TEST_FAILED;
449                 goto error_exit;
450         }
451
452         debug_hexdump(stdout, "m_src(after):",
453                         sym_op->m_src->buf_addr, sym_op->m_src->buf_len);
454         if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP)
455                 debug_hexdump(stdout, "m_dst(after):",
456                         sym_op->m_dst->buf_addr, sym_op->m_dst->buf_len);
457
458         /* Verify results */
459         if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
460                 if ((t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) &&
461                         (op->status == RTE_CRYPTO_OP_STATUS_AUTH_FAILED))
462                         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
463                                 "FAILED: Digest verification failed "
464                                 "(0x%X)", __LINE__, op->status);
465                 else
466                         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
467                                 "FAILED: Operation failed "
468                                 "(0x%X)", __LINE__, op->status);
469                 status = TEST_FAILED;
470                 goto error_exit;
471         }
472
473         if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
474                 uint8_t buffer[2048];
475                 const uint8_t *compare_ref;
476                 uint32_t compare_len;
477
478                 if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) {
479                         compare_ref = tdata->ciphertext.data +
480                                         tdata->cipher_offset;
481                         compare_len = tdata->ciphertext.len -
482                                         tdata->cipher_offset;
483                 } else {
484                         compare_ref = tdata->plaintext.data +
485                                         tdata->cipher_offset;
486                         compare_len = tdata->plaintext.len -
487                                         tdata->cipher_offset;
488                 }
489
490                 if (memcmp(rte_pktmbuf_read(iobuf, tdata->cipher_offset,
491                                 compare_len, buffer), compare_ref,
492                                 compare_len)) {
493                         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
494                                 "FAILED: %s", __LINE__,
495                                 "Crypto data not as expected");
496                         status = TEST_FAILED;
497                         goto error_exit;
498                 }
499         }
500
501         if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) {
502                 uint8_t *auth_res = pktmbuf_mtod_offset(iobuf,
503                                         tdata->ciphertext.len);
504
505                 if (memcmp(auth_res, tdata->digest.data, digest_len)) {
506                         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
507                                 "FAILED: %s", __LINE__, "Generated "
508                                 "digest data not as expected");
509                         status = TEST_FAILED;
510                         goto error_exit;
511                 }
512         }
513
514         /* The only parts that should have changed in the buffer are
515          * plaintext/ciphertext and digest.
516          * In OOP only the dest buffer should change.
517          */
518         if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
519                 struct rte_mbuf *mbuf;
520                 uint8_t value;
521                 uint32_t head_unchanged_len, changed_len = 0;
522                 uint32_t i;
523                 uint32_t hdroom_used = 0, tlroom_used = 0;
524                 uint32_t hdroom = 0;
525
526                 mbuf = sym_op->m_src;
527                 /*
528                  * Crypto PMDs specify the headroom & tailroom it would use
529                  * when processing the crypto operation. PMD is free to modify
530                  * this space, and so the verification check should skip that
531                  * block.
532                  */
533                 hdroom_used = dev_info.min_mbuf_headroom_req;
534                 tlroom_used = dev_info.min_mbuf_tailroom_req;
535
536                 /* Get headroom */
537                 hdroom = rte_pktmbuf_headroom(mbuf);
538
539                 head_unchanged_len = mbuf->buf_len;
540
541                 for (i = 0; i < mbuf->buf_len; i++) {
542
543                         /* Skip headroom used by PMD */
544                         if (i == hdroom - hdroom_used)
545                                 i += hdroom_used;
546
547                         /* Skip tailroom used by PMD */
548                         if (i == (hdroom + mbuf->data_len))
549                                 i += tlroom_used;
550
551                         value = *((uint8_t *)(mbuf->buf_addr)+i);
552                         if (value != tmp_src_buf[i]) {
553                                 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
554         "line %u FAILED: OOP src outer mbuf data (0x%x) not as expected (0x%x)",
555                                         __LINE__, value, tmp_src_buf[i]);
556                                 status = TEST_FAILED;
557                                 goto error_exit;
558                         }
559                 }
560
561                 mbuf = sym_op->m_dst;
562                 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) {
563                         head_unchanged_len = hdroom + sym_op->auth.data.offset;
564                         changed_len = sym_op->auth.data.length;
565                         if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN)
566                                 changed_len += digest_len;
567                 } else {
568                         /* cipher-only */
569                         head_unchanged_len = hdroom +
570                                         sym_op->cipher.data.offset;
571                         changed_len = sym_op->cipher.data.length;
572                 }
573
574                 for (i = 0; i < mbuf->buf_len; i++) {
575                         if (i == head_unchanged_len)
576                                 i += changed_len;
577                         value = *((uint8_t *)(mbuf->buf_addr)+i);
578                         if (value != tmp_dst_buf[i]) {
579                                 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
580                                 "line %u FAILED: OOP dst outer mbuf data "
581                                 "(0x%x) not as expected (0x%x)",
582                                 __LINE__, value, tmp_dst_buf[i]);
583                                 status = TEST_FAILED;
584                                 goto error_exit;
585                         }
586                 }
587
588                 if (!nb_iterates) {
589                         nb_iterates++;
590                         goto iterate;
591                 }
592         } else {
593                 /* In-place operation */
594                 struct rte_mbuf *mbuf;
595                 uint8_t value;
596                 uint32_t head_unchanged_len = 0, changed_len = 0;
597                 uint32_t i;
598                 uint32_t hdroom_used = 0, tlroom_used = 0;
599                 uint32_t hdroom = 0;
600
601                 /*
602                  * Crypto PMDs specify the headroom & tailroom it would use
603                  * when processing the crypto operation. PMD is free to modify
604                  * this space, and so the verification check should skip that
605                  * block.
606                  */
607                 hdroom_used = dev_info.min_mbuf_headroom_req;
608                 tlroom_used = dev_info.min_mbuf_tailroom_req;
609
610                 mbuf = sym_op->m_src;
611
612                 /* Get headroom */
613                 hdroom = rte_pktmbuf_headroom(mbuf);
614
615                 if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
616                         head_unchanged_len = hdroom +
617                                         sym_op->cipher.data.offset;
618                         changed_len = sym_op->cipher.data.length;
619                 } else {
620                         /* auth-only */
621                         head_unchanged_len = hdroom +
622                                         sym_op->auth.data.offset +
623                                         sym_op->auth.data.length;
624                         changed_len = 0;
625                 }
626
627                 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN)
628                         changed_len += digest_len;
629
630                 for (i = 0; i < mbuf->buf_len; i++) {
631
632                         /* Skip headroom used by PMD */
633                         if (i == hdroom - hdroom_used)
634                                 i += hdroom_used;
635
636                         if (i == head_unchanged_len)
637                                 i += changed_len;
638
639                         /* Skip tailroom used by PMD */
640                         if (i == (hdroom + mbuf->data_len))
641                                 i += tlroom_used;
642
643                         value = *((uint8_t *)(mbuf->buf_addr)+i);
644                         if (value != tmp_src_buf[i]) {
645                                 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
646                                 "line %u FAILED: outer mbuf data (0x%x) "
647                                 "not as expected (0x%x)",
648                                 __LINE__, value, tmp_src_buf[i]);
649                                 status = TEST_FAILED;
650                                 goto error_exit;
651                         }
652                 }
653         }
654
655         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "PASS");
656
657 error_exit:
658         if (!(t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)) {
659                 if (sess) {
660                         rte_cryptodev_sym_session_clear(dev_id, sess);
661                         rte_cryptodev_sym_session_free(sess);
662                 }
663                 if (cipher_xform)
664                         rte_free(cipher_xform);
665                 if (auth_xform)
666                         rte_free(auth_xform);
667         }
668
669         if (op)
670                 rte_crypto_op_free(op);
671
672         if (obuf)
673                 rte_pktmbuf_free(obuf);
674
675         if (ibuf)
676                 rte_pktmbuf_free(ibuf);
677
678         return status;
679 }
680
681 int
682 test_blockcipher_all_tests(struct rte_mempool *mbuf_pool,
683         struct rte_mempool *op_mpool,
684         struct rte_mempool *sess_mpool,
685         struct rte_mempool *sess_priv_mpool,
686         uint8_t dev_id,
687         int driver_id,
688         enum blockcipher_test_type test_type)
689 {
690         int status, overall_status = TEST_SUCCESS;
691         uint32_t i, test_index = 0;
692         char test_msg[BLOCKCIPHER_TEST_MSG_LEN + 1];
693         uint32_t n_test_cases = 0;
694         uint32_t target_pmd_mask = 0;
695         const struct blockcipher_test_case *tcs = NULL;
696
697         int openssl_pmd = rte_cryptodev_driver_id_get(
698                         RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD));
699         int ccp_pmd = rte_cryptodev_driver_id_get(
700                         RTE_STR(CRYPTODEV_NAME_CCP_PMD));
701         int dpaa2_sec_pmd = rte_cryptodev_driver_id_get(
702                         RTE_STR(CRYPTODEV_NAME_DPAA2_SEC_PMD));
703         int dpaa_sec_pmd = rte_cryptodev_driver_id_get(
704                         RTE_STR(CRYPTODEV_NAME_DPAA_SEC_PMD));
705         int caam_jr_pmd = rte_cryptodev_driver_id_get(
706                         RTE_STR(CRYPTODEV_NAME_CAAM_JR_PMD));
707         int scheduler_pmd = rte_cryptodev_driver_id_get(
708                         RTE_STR(CRYPTODEV_NAME_SCHEDULER_PMD));
709         int armv8_pmd = rte_cryptodev_driver_id_get(
710                         RTE_STR(CRYPTODEV_NAME_ARMV8_PMD));
711         int aesni_mb_pmd = rte_cryptodev_driver_id_get(
712                         RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD));
713         int qat_pmd = rte_cryptodev_driver_id_get(
714                         RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD));
715         int mrvl_pmd = rte_cryptodev_driver_id_get(
716                         RTE_STR(CRYPTODEV_NAME_MVSAM_PMD));
717         int virtio_pmd = rte_cryptodev_driver_id_get(
718                         RTE_STR(CRYPTODEV_NAME_VIRTIO_PMD));
719         int octeontx_pmd = rte_cryptodev_driver_id_get(
720                         RTE_STR(CRYPTODEV_NAME_OCTEONTX_SYM_PMD));
721         int null_pmd = rte_cryptodev_driver_id_get(
722                                 RTE_STR(CRYPTODEV_NAME_NULL_PMD));
723         int nitrox_pmd = rte_cryptodev_driver_id_get(
724                         RTE_STR(CRYPTODEV_NAME_NITROX_PMD));
725
726         switch (test_type) {
727         case BLKCIPHER_AES_CHAIN_TYPE:
728                 n_test_cases = sizeof(aes_chain_test_cases) /
729                 sizeof(aes_chain_test_cases[0]);
730                 tcs = aes_chain_test_cases;
731                 break;
732         case BLKCIPHER_AES_CIPHERONLY_TYPE:
733                 n_test_cases = sizeof(aes_cipheronly_test_cases) /
734                 sizeof(aes_cipheronly_test_cases[0]);
735                 tcs = aes_cipheronly_test_cases;
736                 break;
737         case BLKCIPHER_AES_DOCSIS_TYPE:
738                 n_test_cases = sizeof(aes_docsis_test_cases) /
739                 sizeof(aes_docsis_test_cases[0]);
740                 tcs = aes_docsis_test_cases;
741                 break;
742         case BLKCIPHER_3DES_CHAIN_TYPE:
743                 n_test_cases = sizeof(triple_des_chain_test_cases) /
744                 sizeof(triple_des_chain_test_cases[0]);
745                 tcs = triple_des_chain_test_cases;
746                 break;
747         case BLKCIPHER_3DES_CIPHERONLY_TYPE:
748                 n_test_cases = sizeof(triple_des_cipheronly_test_cases) /
749                 sizeof(triple_des_cipheronly_test_cases[0]);
750                 tcs = triple_des_cipheronly_test_cases;
751                 break;
752         case BLKCIPHER_DES_CIPHERONLY_TYPE:
753                 n_test_cases = sizeof(des_cipheronly_test_cases) /
754                 sizeof(des_cipheronly_test_cases[0]);
755                 tcs = des_cipheronly_test_cases;
756                 break;
757         case BLKCIPHER_DES_DOCSIS_TYPE:
758                 n_test_cases = sizeof(des_docsis_test_cases) /
759                 sizeof(des_docsis_test_cases[0]);
760                 tcs = des_docsis_test_cases;
761                 break;
762         case BLKCIPHER_AUTHONLY_TYPE:
763                 n_test_cases = sizeof(hash_test_cases) /
764                 sizeof(hash_test_cases[0]);
765                 tcs = hash_test_cases;
766                 break;
767         default:
768                 break;
769         }
770
771         if (driver_id == aesni_mb_pmd)
772                 target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB;
773         else if (driver_id == qat_pmd)
774                 target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT;
775         else if (driver_id == openssl_pmd)
776                 target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL;
777         else if (driver_id == armv8_pmd)
778                 target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8;
779         else if (driver_id == scheduler_pmd)
780                 target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER;
781         else if (driver_id == dpaa2_sec_pmd)
782                 target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC;
783         else if (driver_id == ccp_pmd)
784                 target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_CCP;
785         else if (driver_id == dpaa_sec_pmd)
786                 target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC;
787         else if (driver_id == caam_jr_pmd)
788                 target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR;
789         else if (driver_id == mrvl_pmd)
790                 target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MVSAM;
791         else if (driver_id == virtio_pmd)
792                 target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO;
793         else if (driver_id == octeontx_pmd)
794                 target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX;
795         else if (driver_id == null_pmd)
796                 target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_NULL;
797         else if (driver_id == nitrox_pmd)
798                 target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_NITROX;
799         else
800                 TEST_ASSERT(0, "Unrecognized cryptodev type");
801
802         for (i = 0; i < n_test_cases; i++) {
803                 const struct blockcipher_test_case *tc = &tcs[i];
804
805                 if (!(tc->pmd_mask & target_pmd_mask))
806                         continue;
807
808                 status = test_blockcipher_one_case(tc, mbuf_pool, op_mpool,
809                         sess_mpool, sess_priv_mpool, dev_id, driver_id,
810                         test_msg);
811
812                 printf("  %u) TestCase %s %s\n", test_index ++,
813                         tc->test_descr, test_msg);
814
815                 if (status != TEST_SUCCESS) {
816                         if (overall_status == TEST_SUCCESS)
817                                 overall_status = status;
818
819                         if (tc->feature_mask & BLOCKCIPHER_TEST_FEATURE_STOPPER)
820                                 break;
821                 }
822         }
823
824         return overall_status;
825 }