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