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