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