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