53fd4718af8c4512e51363b0bae8150759f94a96
[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 verify_algo_support(const struct blockcipher_test_case *t,
25                 const uint8_t dev_id, const uint32_t digest_len)
26 {
27         int ret = 0;
28         const struct blockcipher_test_data *tdata = t->test_data;
29         struct rte_cryptodev_sym_capability_idx cap_idx;
30         const struct rte_cryptodev_symmetric_capability *capability;
31
32         if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
33                 cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
34                 cap_idx.algo.cipher = tdata->crypto_algo;
35                 capability = rte_cryptodev_sym_capability_get(dev_id, &cap_idx);
36                 if (capability == NULL)
37                         return -1;
38
39                 if (cap_idx.algo.cipher != RTE_CRYPTO_CIPHER_NULL &&
40                                 !(t->test_data->wrapped_key))
41                         ret = rte_cryptodev_sym_capability_check_cipher(capability,
42                                                         tdata->cipher_key.len,
43                                                         tdata->iv.len);
44                 if (ret != 0)
45                         return -1;
46         }
47
48         if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) {
49                 cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
50                 cap_idx.algo.auth = tdata->auth_algo;
51                 capability = rte_cryptodev_sym_capability_get(dev_id, &cap_idx);
52                 if (capability == NULL)
53                         return -1;
54
55                 if (cap_idx.algo.auth != RTE_CRYPTO_AUTH_NULL)
56                         ret = rte_cryptodev_sym_capability_check_auth(capability,
57                                                         tdata->auth_key.len,
58                                                         digest_len,
59                                                         0);
60                 if (ret != 0)
61                         return -1;
62         }
63
64         return 0;
65 }
66
67 static int
68 test_blockcipher_one_case(const struct blockcipher_test_case *t,
69         struct rte_mempool *mbuf_pool,
70         struct rte_mempool *op_mpool,
71         struct rte_mempool *sess_mpool,
72         struct rte_mempool *sess_priv_mpool,
73         uint8_t dev_id,
74         char *test_msg)
75 {
76         struct rte_mbuf *ibuf = NULL;
77         struct rte_mbuf *obuf = NULL;
78         struct rte_mbuf *iobuf;
79         struct rte_crypto_sym_xform *cipher_xform = NULL;
80         struct rte_crypto_sym_xform *auth_xform = NULL;
81         struct rte_crypto_sym_xform *init_xform = NULL;
82         struct rte_crypto_sym_op *sym_op = NULL;
83         struct rte_crypto_op *op = NULL;
84         struct rte_cryptodev_info dev_info;
85         struct rte_cryptodev_sym_session *sess = NULL;
86
87         int status = TEST_SUCCESS;
88         const struct blockcipher_test_data *tdata = t->test_data;
89         uint8_t cipher_key[tdata->cipher_key.len];
90         uint8_t auth_key[tdata->auth_key.len];
91         uint32_t buf_len = tdata->ciphertext.len;
92         uint32_t digest_len = tdata->digest.len;
93         char *buf_p = NULL;
94         uint8_t src_pattern = 0xa5;
95         uint8_t dst_pattern = 0xb6;
96         uint8_t tmp_src_buf[MBUF_SIZE];
97         uint8_t tmp_dst_buf[MBUF_SIZE];
98         uint32_t pad_len;
99
100         int nb_segs = 1;
101         uint32_t nb_iterates = 0;
102
103         rte_cryptodev_info_get(dev_id, &dev_info);
104         uint64_t feat_flags = dev_info.feature_flags;
105
106         if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
107                 if (!(feat_flags & RTE_CRYPTODEV_FF_SYM_SESSIONLESS)) {
108                         printf("Device doesn't support sessionless operations "
109                                 "Test Skipped.\n");
110                         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
111                                 "SKIPPED");
112                         return TEST_SKIPPED;
113                 }
114         }
115         if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_DIGEST_ENCRYPTED) {
116                 if (!(feat_flags & RTE_CRYPTODEV_FF_DIGEST_ENCRYPTED)) {
117                         printf("Device doesn't support encrypted digest "
118                                 "Test Skipped.\n");
119                         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
120                                 "SKIPPED");
121                         return TEST_SKIPPED;
122                 }
123         }
124         if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SG) {
125                 uint64_t oop_flag = RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT;
126
127                 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
128                         if (!(feat_flags & oop_flag)) {
129                                 printf("Device doesn't support out-of-place "
130                                         "scatter-gather in input mbuf. "
131                                         "Test Skipped.\n");
132                                 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
133                                         "SKIPPED");
134                                 return TEST_SKIPPED;
135                         }
136                 } else {
137                         if (!(feat_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL)) {
138                                 printf("Device doesn't support in-place "
139                                         "scatter-gather mbufs. "
140                                         "Test Skipped.\n");
141                                 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
142                                         "SKIPPED");
143                                 return TEST_SKIPPED;
144                         }
145                 }
146
147                 nb_segs = 3;
148         }
149         if (!!(feat_flags & RTE_CRYPTODEV_FF_CIPHER_WRAPPED_KEY) ^
150                 tdata->wrapped_key) {
151                 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
152                         "SKIPPED");
153                 return TEST_SKIPPED;
154         }
155
156         if (global_api_test_type == CRYPTODEV_RAW_API_TEST &&
157                 !(feat_flags & RTE_CRYPTODEV_FF_SYM_RAW_DP)) {
158                 printf("Device doesn't support raw data-path APIs. "
159                         "Test Skipped.\n");
160                 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "SKIPPED");
161                 return TEST_SKIPPED;
162         }
163
164         if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
165                 uint64_t oop_flags = RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT |
166                         RTE_CRYPTODEV_FF_OOP_LB_IN_SGL_OUT |
167                         RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT |
168                         RTE_CRYPTODEV_FF_OOP_SGL_IN_SGL_OUT;
169                 if (!(feat_flags & oop_flags)) {
170                         printf("Device doesn't support out-of-place operations."
171                                 "Test Skipped.\n");
172                         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
173                                 "SKIPPED");
174                         return TEST_SKIPPED;
175                 }
176                 if (global_api_test_type == CRYPTODEV_RAW_API_TEST) {
177                         printf("Raw Data Path APIs do not support OOP, "
178                                 "Test Skipped.\n");
179                         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "SKIPPED");
180                         status = TEST_SKIPPED;
181                         goto error_exit;
182                 }
183         }
184
185         if (tdata->cipher_key.len)
186                 memcpy(cipher_key, tdata->cipher_key.data,
187                         tdata->cipher_key.len);
188         if (tdata->auth_key.len)
189                 memcpy(auth_key, tdata->auth_key.data,
190                         tdata->auth_key.len);
191
192         /* Check if PMD is capable of performing that test */
193         if (verify_algo_support(t, dev_id, digest_len) < 0) {
194                 RTE_LOG(DEBUG, USER1,
195                         "Device does not support this algorithm."
196                         "Test Skipped.\n");
197                 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "SKIPPED");
198                 return TEST_SKIPPED;
199         }
200
201         /* preparing data */
202         if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH)
203                 buf_len += digest_len;
204
205         pad_len = RTE_ALIGN(buf_len, 16) - buf_len;
206         if (t->op_mask & BLOCKCIPHER_TEST_OP_DIGEST_ENCRYPTED)
207                 buf_len += pad_len;
208
209         /* for contiguous mbuf, nb_segs is 1 */
210         ibuf = create_segmented_mbuf(mbuf_pool,
211                         tdata->ciphertext.len, nb_segs, src_pattern);
212         if (ibuf == NULL) {
213                 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
214                         "line %u FAILED: %s",
215                         __LINE__, "Cannot create source mbuf");
216                 status = TEST_FAILED;
217                 goto error_exit;
218         }
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                 if (t->op_mask & BLOCKCIPHER_TEST_OP_DIGEST_ENCRYPTED)
234                         rte_memcpy(buf_p,
235                                 tdata->ciphertext.data + tdata->ciphertext.len,
236                                  digest_len);
237                 else
238                         rte_memcpy(buf_p, tdata->digest.data, digest_len);
239         else
240                 memset(buf_p, 0, digest_len);
241         if (t->op_mask & BLOCKCIPHER_TEST_OP_DIGEST_ENCRYPTED) {
242                 buf_p = rte_pktmbuf_append(ibuf, pad_len);
243                 if (!buf_p) {
244                         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
245                                 "FAILED: %s", __LINE__,
246                                 "No room to append mbuf");
247                         status = TEST_FAILED;
248                         goto error_exit;
249                 }
250                 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) {
251                         const uint8_t *temp_p = tdata->ciphertext.data +
252                                         tdata->ciphertext.len +
253                                         digest_len;
254                         rte_memcpy(buf_p, temp_p, pad_len);
255                 } else
256                         memset(buf_p, 0xa5, pad_len);
257         }
258
259         if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
260                 obuf = rte_pktmbuf_alloc(mbuf_pool);
261                 if (!obuf) {
262                         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
263                                 "FAILED: %s", __LINE__,
264                                 "Allocation of rte_mbuf failed");
265                         status = TEST_FAILED;
266                         goto error_exit;
267                 }
268                 memset(obuf->buf_addr, dst_pattern, obuf->buf_len);
269
270                 buf_p = rte_pktmbuf_append(obuf, buf_len + pad_len);
271                 if (!buf_p) {
272                         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
273                                 "FAILED: %s", __LINE__,
274                                 "No room to append mbuf");
275                         status = TEST_FAILED;
276                         goto error_exit;
277                 }
278                 memset(buf_p, 0, buf_len);
279         }
280
281         /* Generate Crypto op data structure */
282         op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
283         if (!op) {
284                 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
285                         "line %u FAILED: %s",
286                         __LINE__, "Failed to allocate symmetric crypto "
287                         "operation struct");
288                 status = TEST_FAILED;
289                 goto error_exit;
290         }
291
292         sym_op = op->sym;
293
294 iterate:
295         if (nb_iterates) {
296                 struct rte_mbuf *tmp_buf = ibuf;
297
298                 ibuf = obuf;
299                 obuf = tmp_buf;
300
301                 rte_pktmbuf_reset(ibuf);
302                 rte_pktmbuf_reset(obuf);
303
304                 rte_pktmbuf_append(ibuf, tdata->ciphertext.len);
305
306                 /* only encryption requires plaintext.data input,
307                  * decryption/(digest gen)/(digest verify) use ciphertext.data
308                  * to be computed
309                  */
310                 if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT)
311                         pktmbuf_write(ibuf, 0, tdata->plaintext.len,
312                                         tdata->plaintext.data);
313                 else
314                         pktmbuf_write(ibuf, 0, tdata->ciphertext.len,
315                                         tdata->ciphertext.data);
316
317                 buf_p = rte_pktmbuf_append(ibuf, digest_len);
318                 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY)
319                         rte_memcpy(buf_p, tdata->digest.data, digest_len);
320                 else
321                         memset(buf_p, 0, digest_len);
322
323                 memset(obuf->buf_addr, dst_pattern, obuf->buf_len);
324
325                 buf_p = rte_pktmbuf_append(obuf, buf_len);
326                 if (!buf_p) {
327                         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
328                                 "FAILED: %s", __LINE__,
329                                 "No room to append mbuf");
330                         status = TEST_FAILED;
331                         goto error_exit;
332                 }
333                 memset(buf_p, 0, buf_len);
334         }
335
336         sym_op->m_src = ibuf;
337
338         if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
339                 sym_op->m_dst = obuf;
340                 iobuf = obuf;
341         } else {
342                 sym_op->m_dst = NULL;
343                 iobuf = ibuf;
344         }
345
346         /* sessionless op requires allocate xform using
347          * rte_crypto_op_sym_xforms_alloc(), otherwise rte_zmalloc()
348          * is used
349          */
350         if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
351                 uint32_t n_xforms = 0;
352
353                 if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER)
354                         n_xforms++;
355                 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH)
356                         n_xforms++;
357
358                 if (rte_crypto_op_sym_xforms_alloc(op, n_xforms)
359                         == NULL) {
360                         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
361                                 "FAILED: %s", __LINE__, "Failed to "
362                                 "allocate space for crypto transforms");
363                         status = TEST_FAILED;
364                         goto error_exit;
365                 }
366         } else {
367                 cipher_xform = rte_zmalloc(NULL,
368                         sizeof(struct rte_crypto_sym_xform), 0);
369
370                 auth_xform = rte_zmalloc(NULL,
371                         sizeof(struct rte_crypto_sym_xform), 0);
372
373                 if (!cipher_xform || !auth_xform) {
374                         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
375                                 "FAILED: %s", __LINE__, "Failed to "
376                                 "allocate memory for crypto transforms");
377                         status = TEST_FAILED;
378                         goto error_exit;
379                 }
380         }
381
382         /* preparing xform, for sessioned op, init_xform is initialized
383          * here and later as param in rte_cryptodev_sym_session_create() call
384          */
385         if (t->op_mask == BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN) {
386                 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
387                         cipher_xform = op->sym->xform;
388                         auth_xform = cipher_xform->next;
389                         auth_xform->next = NULL;
390                 } else {
391                         cipher_xform->next = auth_xform;
392                         auth_xform->next = NULL;
393                         init_xform = cipher_xform;
394                 }
395         } else if (t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC) {
396                 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
397                         auth_xform = op->sym->xform;
398                         cipher_xform = auth_xform->next;
399                         cipher_xform->next = NULL;
400                 } else {
401                         auth_xform->next = cipher_xform;
402                         cipher_xform->next = NULL;
403                         init_xform = auth_xform;
404                 }
405         } else if (t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_GEN_ENC) {
406                 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
407                         auth_xform = op->sym->xform;
408                         cipher_xform = auth_xform->next;
409                         cipher_xform->next = NULL;
410                 } else {
411                         auth_xform->next = cipher_xform;
412                         cipher_xform->next = NULL;
413                         init_xform = auth_xform;
414                 }
415         } else if (t->op_mask == BLOCKCIPHER_TEST_OP_DEC_AUTH_VERIFY) {
416                 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
417                         cipher_xform = op->sym->xform;
418                         auth_xform = cipher_xform->next;
419                         auth_xform->next = NULL;
420                 } else {
421                         cipher_xform->next = auth_xform;
422                         auth_xform->next = NULL;
423                         init_xform = cipher_xform;
424                 }
425         } else if ((t->op_mask == BLOCKCIPHER_TEST_OP_ENCRYPT) ||
426                         (t->op_mask == BLOCKCIPHER_TEST_OP_DECRYPT)) {
427                 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)
428                         cipher_xform = op->sym->xform;
429                 else
430                         init_xform = cipher_xform;
431                 cipher_xform->next = NULL;
432         } else if ((t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_GEN) ||
433                         (t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_VERIFY)) {
434                 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)
435                         auth_xform = op->sym->xform;
436                 else
437                         init_xform = auth_xform;
438                 auth_xform->next = NULL;
439         } else {
440                 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
441                         "line %u FAILED: %s",
442                         __LINE__, "Unrecognized operation");
443                 status = TEST_FAILED;
444                 goto error_exit;
445         }
446
447         /*configure xforms & sym_op cipher and auth data*/
448         if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
449                 cipher_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
450                 cipher_xform->cipher.algo = tdata->crypto_algo;
451                 if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT)
452                         cipher_xform->cipher.op =
453                                 RTE_CRYPTO_CIPHER_OP_ENCRYPT;
454                 else
455                         cipher_xform->cipher.op =
456                                 RTE_CRYPTO_CIPHER_OP_DECRYPT;
457                 cipher_xform->cipher.key.data = cipher_key;
458                 cipher_xform->cipher.key.length = tdata->cipher_key.len;
459                 cipher_xform->cipher.iv.offset = IV_OFFSET;
460                 cipher_xform->cipher.dataunit_len = tdata->xts_dataunit_len;
461
462                 if (tdata->crypto_algo == RTE_CRYPTO_CIPHER_NULL)
463                         cipher_xform->cipher.iv.length = 0;
464                 else
465                         cipher_xform->cipher.iv.length = tdata->iv.len;
466
467                 sym_op->cipher.data.offset = tdata->cipher_offset;
468                 sym_op->cipher.data.length = tdata->ciphertext.len -
469                                 tdata->cipher_offset;
470                 if (t->op_mask & BLOCKCIPHER_TEST_OP_DIGEST_ENCRYPTED) {
471                         sym_op->cipher.data.length += tdata->digest.len;
472                         sym_op->cipher.data.length += pad_len;
473                 }
474                 rte_memcpy(rte_crypto_op_ctod_offset(op, uint8_t *, IV_OFFSET),
475                                 tdata->iv.data,
476                                 tdata->iv.len);
477         }
478
479         if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) {
480                 uint32_t digest_offset = tdata->ciphertext.len;
481
482                 auth_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
483                 auth_xform->auth.algo = tdata->auth_algo;
484                 auth_xform->auth.key.length = tdata->auth_key.len;
485                 auth_xform->auth.key.data = auth_key;
486                 auth_xform->auth.digest_length = digest_len;
487
488                 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) {
489                         auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_GENERATE;
490                         sym_op->auth.digest.data = pktmbuf_mtod_offset
491                                 (iobuf, digest_offset);
492                         sym_op->auth.digest.phys_addr =
493                                 pktmbuf_iova_offset(iobuf,
494                                         digest_offset);
495                 } else {
496                         auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_VERIFY;
497                         sym_op->auth.digest.data = pktmbuf_mtod_offset
498                                 (sym_op->m_src, digest_offset);
499                         sym_op->auth.digest.phys_addr =
500                                 pktmbuf_iova_offset(sym_op->m_src,
501                                         digest_offset);
502                 }
503
504                 sym_op->auth.data.offset = tdata->auth_offset;
505                 sym_op->auth.data.length = tdata->ciphertext.len -
506                                 tdata->auth_offset;
507         }
508
509         /**
510          * Create session for sessioned op. For mbuf iteration test,
511          * skip the session creation for the second iteration.
512          */
513         if (!(t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) &&
514                         nb_iterates == 0) {
515                 sess = rte_cryptodev_sym_session_create(sess_mpool);
516
517                 status = rte_cryptodev_sym_session_init(dev_id, sess,
518                                 init_xform, sess_priv_mpool);
519                 if (status == -ENOTSUP) {
520                         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "UNSUPPORTED");
521                         status = TEST_SKIPPED;
522                         goto error_exit;
523                 }
524                 if (!sess || status < 0) {
525                         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
526                                 "FAILED: %s", __LINE__,
527                                 "Session creation failed");
528                         status = TEST_FAILED;
529                         goto error_exit;
530                 }
531
532                 /* attach symmetric crypto session to crypto operations */
533                 rte_crypto_op_attach_sym_session(op, sess);
534         }
535
536         debug_hexdump(stdout, "m_src(before):",
537                         sym_op->m_src->buf_addr, sym_op->m_src->buf_len);
538         rte_memcpy(tmp_src_buf, sym_op->m_src->buf_addr,
539                                                 sym_op->m_src->buf_len);
540         if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
541                 debug_hexdump(stdout, "m_dst(before):",
542                         sym_op->m_dst->buf_addr, sym_op->m_dst->buf_len);
543                 rte_memcpy(tmp_dst_buf, sym_op->m_dst->buf_addr,
544                                                 sym_op->m_dst->buf_len);
545         }
546
547         /* Process crypto operation */
548         if (global_api_test_type == CRYPTODEV_RAW_API_TEST) {
549                 uint8_t is_cipher = 0, is_auth = 0;
550                 if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER)
551                         is_cipher = 1;
552                 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH)
553                         is_auth = 1;
554
555                 process_sym_raw_dp_op(dev_id, 0, op, is_cipher, is_auth, 0,
556                                 tdata->iv.len);
557         } else {
558                 if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
559                         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
560                                 "line %u FAILED: %s",
561                                 __LINE__, "Error sending packet for encryption");
562                         status = TEST_FAILED;
563                         goto error_exit;
564                 }
565
566                 op = NULL;
567
568                 while (rte_cryptodev_dequeue_burst(dev_id, 0, &op, 1) == 0)
569                         rte_pause();
570
571                 if (!op) {
572                         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
573                                 "line %u FAILED: %s",
574                                 __LINE__, "Failed to process sym crypto op");
575                         status = TEST_FAILED;
576                         goto error_exit;
577                 }
578         }
579
580         debug_hexdump(stdout, "m_src(after):",
581                         sym_op->m_src->buf_addr, sym_op->m_src->buf_len);
582         if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP)
583                 debug_hexdump(stdout, "m_dst(after):",
584                         sym_op->m_dst->buf_addr, sym_op->m_dst->buf_len);
585
586         /* Verify results */
587         if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
588                 if ((t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) &&
589                         (op->status == RTE_CRYPTO_OP_STATUS_AUTH_FAILED))
590                         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
591                                 "FAILED: Digest verification failed "
592                                 "(0x%X)", __LINE__, op->status);
593                 else
594                         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
595                                 "FAILED: Operation failed "
596                                 "(0x%X)", __LINE__, op->status);
597                 status = TEST_FAILED;
598                 goto error_exit;
599         }
600
601         if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
602                 uint8_t buffer[2048];
603                 const uint8_t *compare_ref;
604                 uint32_t compare_len;
605
606                 if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) {
607                         compare_ref = tdata->ciphertext.data +
608                                         tdata->cipher_offset;
609                         compare_len = tdata->ciphertext.len -
610                                         tdata->cipher_offset;
611                         if (t->op_mask & BLOCKCIPHER_TEST_OP_DIGEST_ENCRYPTED)
612                                 compare_len += tdata->digest.len;
613                 } else {
614                         compare_ref = tdata->plaintext.data +
615                                         tdata->cipher_offset;
616                         compare_len = tdata->plaintext.len -
617                                         tdata->cipher_offset;
618                 }
619
620                 if (memcmp(rte_pktmbuf_read(iobuf, tdata->cipher_offset,
621                                 compare_len, buffer), compare_ref,
622                                 compare_len)) {
623                         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
624                                 "FAILED: %s", __LINE__,
625                                 "Crypto data not as expected");
626                         status = TEST_FAILED;
627                         goto error_exit;
628                 }
629         }
630
631         /* Check digest data only in enc-then-auth_gen case.
632          * In auth_gen-then-enc case, cipher text contains both encrypted
633          * plain text and encrypted digest value. If cipher text is correct,
634          * it implies digest is also generated properly.
635          */
636         if (!(t->op_mask & BLOCKCIPHER_TEST_OP_DIGEST_ENCRYPTED))
637                 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) {
638                         uint8_t *auth_res = pktmbuf_mtod_offset(iobuf,
639                                                 tdata->ciphertext.len);
640
641                         if (memcmp(auth_res, tdata->digest.data, digest_len)) {
642                                 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
643                                         "FAILED: %s", __LINE__, "Generated "
644                                         "digest data not as expected");
645                                 status = TEST_FAILED;
646                                 goto error_exit;
647                         }
648                 }
649
650         /* The only parts that should have changed in the buffer are
651          * plaintext/ciphertext and digest.
652          * In OOP only the dest buffer should change.
653          */
654         if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
655                 struct rte_mbuf *mbuf;
656                 uint8_t value;
657                 uint32_t head_unchanged_len, changed_len = 0;
658                 uint32_t i;
659                 uint32_t hdroom_used = 0, tlroom_used = 0;
660                 uint32_t hdroom = 0;
661
662                 mbuf = sym_op->m_src;
663                 /*
664                  * Crypto PMDs specify the headroom & tailroom it would use
665                  * when processing the crypto operation. PMD is free to modify
666                  * this space, and so the verification check should skip that
667                  * block.
668                  */
669                 hdroom_used = dev_info.min_mbuf_headroom_req;
670                 tlroom_used = dev_info.min_mbuf_tailroom_req;
671
672                 /* Get headroom */
673                 hdroom = rte_pktmbuf_headroom(mbuf);
674
675                 head_unchanged_len = mbuf->buf_len;
676
677                 for (i = 0; i < mbuf->buf_len; i++) {
678
679                         /* Skip headroom used by PMD */
680                         if (i == hdroom - hdroom_used)
681                                 i += hdroom_used;
682
683                         /* Skip tailroom used by PMD */
684                         if (i == (hdroom + mbuf->data_len))
685                                 i += tlroom_used;
686
687                         value = *((uint8_t *)(mbuf->buf_addr)+i);
688                         if (value != tmp_src_buf[i]) {
689                                 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
690         "line %u FAILED: OOP src outer mbuf data (0x%x) not as expected (0x%x)",
691                                         __LINE__, value, tmp_src_buf[i]);
692                                 status = TEST_FAILED;
693                                 goto error_exit;
694                         }
695                 }
696
697                 mbuf = sym_op->m_dst;
698                 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) {
699                         head_unchanged_len = hdroom + sym_op->auth.data.offset;
700                         changed_len = sym_op->auth.data.length;
701                         if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN)
702                                 changed_len += digest_len;
703                 } else {
704                         /* cipher-only */
705                         head_unchanged_len = hdroom +
706                                         sym_op->cipher.data.offset;
707                         changed_len = sym_op->cipher.data.length;
708                 }
709
710                 if (t->op_mask & BLOCKCIPHER_TEST_OP_DIGEST_ENCRYPTED)
711                         changed_len = sym_op->cipher.data.length +
712                                 digest_len + pad_len;
713
714                 for (i = 0; i < mbuf->buf_len; i++) {
715                         if (i == head_unchanged_len)
716                                 i += changed_len;
717                         value = *((uint8_t *)(mbuf->buf_addr)+i);
718                         if (value != tmp_dst_buf[i]) {
719                                 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
720                                 "line %u FAILED: OOP dst outer mbuf data "
721                                 "(0x%x) not as expected (0x%x)",
722                                 __LINE__, value, tmp_dst_buf[i]);
723                                 status = TEST_FAILED;
724                                 goto error_exit;
725                         }
726                 }
727
728                 if (!nb_iterates) {
729                         nb_iterates++;
730                         goto iterate;
731                 }
732         } else {
733                 /* In-place operation */
734                 struct rte_mbuf *mbuf;
735                 uint8_t value;
736                 uint32_t head_unchanged_len = 0, changed_len = 0;
737                 uint32_t i;
738                 uint32_t hdroom_used = 0, tlroom_used = 0;
739                 uint32_t hdroom = 0;
740
741                 /*
742                  * Crypto PMDs specify the headroom & tailroom it would use
743                  * when processing the crypto operation. PMD is free to modify
744                  * this space, and so the verification check should skip that
745                  * block.
746                  */
747                 hdroom_used = dev_info.min_mbuf_headroom_req;
748                 tlroom_used = dev_info.min_mbuf_tailroom_req;
749
750                 mbuf = sym_op->m_src;
751
752                 /* Get headroom */
753                 hdroom = rte_pktmbuf_headroom(mbuf);
754
755                 if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
756                         head_unchanged_len = hdroom +
757                                         sym_op->cipher.data.offset;
758                         changed_len = sym_op->cipher.data.length;
759                 } else {
760                         /* auth-only */
761                         head_unchanged_len = hdroom +
762                                         sym_op->auth.data.offset +
763                                         sym_op->auth.data.length;
764                         changed_len = 0;
765                 }
766
767                 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN)
768                         changed_len += digest_len;
769
770                 if (t->op_mask & BLOCKCIPHER_TEST_OP_DIGEST_ENCRYPTED)
771                         changed_len = sym_op->cipher.data.length;
772
773                 for (i = 0; i < mbuf->buf_len; i++) {
774
775                         /* Skip headroom used by PMD */
776                         if (i == hdroom - hdroom_used)
777                                 i += hdroom_used;
778
779                         if (i == head_unchanged_len)
780                                 i += changed_len;
781
782                         /* Skip tailroom used by PMD */
783                         if (i == (hdroom + mbuf->data_len))
784                                 i += tlroom_used;
785
786                         value = *((uint8_t *)(mbuf->buf_addr)+i);
787                         if (value != tmp_src_buf[i]) {
788                                 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
789                                 "line %u FAILED: outer mbuf data (0x%x) "
790                                 "not as expected (0x%x)",
791                                 __LINE__, value, tmp_src_buf[i]);
792                                 status = TEST_FAILED;
793                                 goto error_exit;
794                         }
795                 }
796         }
797
798         snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "PASS");
799
800 error_exit:
801         if (!(t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)) {
802                 if (sess) {
803                         rte_cryptodev_sym_session_clear(dev_id, sess);
804                         rte_cryptodev_sym_session_free(sess);
805                 }
806                 if (cipher_xform)
807                         rte_free(cipher_xform);
808                 if (auth_xform)
809                         rte_free(auth_xform);
810         }
811
812         if (op)
813                 rte_crypto_op_free(op);
814
815         if (obuf)
816                 rte_pktmbuf_free(obuf);
817
818         if (ibuf)
819                 rte_pktmbuf_free(ibuf);
820
821         return status;
822 }
823
824 static int
825 blockcipher_test_case_run(const void *data)
826 {
827         const struct blockcipher_test_case *tc_data = data;
828         int status;
829         char test_msg[BLOCKCIPHER_TEST_MSG_LEN + 1];
830
831         status = test_blockcipher_one_case(tc_data,
832                         p_testsuite_params->mbuf_pool,
833                         p_testsuite_params->op_mpool,
834                         p_testsuite_params->session_mpool,
835                         p_testsuite_params->session_priv_mpool,
836                         p_testsuite_params->valid_devs[0],
837                         test_msg);
838         return status;
839 }
840
841 static int
842 aes_chain_setup(void)
843 {
844         uint8_t dev_id = p_testsuite_params->valid_devs[0];
845         struct rte_cryptodev_info dev_info;
846         uint64_t feat_flags;
847         const enum rte_crypto_cipher_algorithm ciphers[] = {
848                 RTE_CRYPTO_CIPHER_NULL,
849                 RTE_CRYPTO_CIPHER_AES_CTR,
850                 RTE_CRYPTO_CIPHER_AES_CBC
851         };
852         const enum rte_crypto_auth_algorithm auths[] = {
853                 RTE_CRYPTO_AUTH_NULL,
854                 RTE_CRYPTO_AUTH_SHA1_HMAC,
855                 RTE_CRYPTO_AUTH_AES_XCBC_MAC,
856                 RTE_CRYPTO_AUTH_SHA256_HMAC,
857                 RTE_CRYPTO_AUTH_SHA512_HMAC,
858                 RTE_CRYPTO_AUTH_SHA224_HMAC,
859                 RTE_CRYPTO_AUTH_SHA384_HMAC
860         };
861
862         rte_cryptodev_info_get(dev_id, &dev_info);
863         feat_flags = dev_info.feature_flags;
864
865         if (!(feat_flags & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) ||
866                         ((global_api_test_type == CRYPTODEV_RAW_API_TEST) &&
867                         !(feat_flags & RTE_CRYPTODEV_FF_SYM_RAW_DP))) {
868                 RTE_LOG(INFO, USER1, "Feature flag requirements for AES Chain "
869                                 "testsuite not met\n");
870                 return TEST_SKIPPED;
871         }
872
873         if (check_cipher_capabilities_supported(ciphers, RTE_DIM(ciphers)) != 0
874                         && check_auth_capabilities_supported(auths,
875                         RTE_DIM(auths)) != 0) {
876                 RTE_LOG(INFO, USER1, "Capability requirements for AES Chain "
877                                 "testsuite not met\n");
878                 return TEST_SKIPPED;
879         }
880
881         return 0;
882 }
883
884 static int
885 aes_cipheronly_setup(void)
886 {
887         uint8_t dev_id = p_testsuite_params->valid_devs[0];
888         struct rte_cryptodev_info dev_info;
889         uint64_t feat_flags;
890         const enum rte_crypto_cipher_algorithm ciphers[] = {
891                 RTE_CRYPTO_CIPHER_NULL,
892                 RTE_CRYPTO_CIPHER_AES_CTR,
893                 RTE_CRYPTO_CIPHER_AES_CBC,
894                 RTE_CRYPTO_CIPHER_AES_ECB,
895                 RTE_CRYPTO_CIPHER_AES_XTS
896         };
897         const enum rte_crypto_auth_algorithm auths[] = {
898                 RTE_CRYPTO_AUTH_NULL,
899                 RTE_CRYPTO_AUTH_SHA1_HMAC,
900                 RTE_CRYPTO_AUTH_AES_XCBC_MAC
901         };
902
903         rte_cryptodev_info_get(dev_id, &dev_info);
904         feat_flags = dev_info.feature_flags;
905
906         if (!(feat_flags & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) ||
907                         ((global_api_test_type == CRYPTODEV_RAW_API_TEST) &&
908                         !(feat_flags & RTE_CRYPTODEV_FF_SYM_RAW_DP))) {
909                 RTE_LOG(INFO, USER1, "Feature flag requirements for AES Cipheronly "
910                                 "testsuite not met\n");
911                 return TEST_SKIPPED;
912         }
913
914         if (check_cipher_capabilities_supported(ciphers, RTE_DIM(ciphers)) != 0
915                         && check_auth_capabilities_supported(auths,
916                         RTE_DIM(auths)) != 0) {
917                 RTE_LOG(INFO, USER1, "Capability requirements for AES Cipheronly "
918                                 "testsuite not met\n");
919                 return TEST_SKIPPED;
920         }
921
922         return 0;
923 }
924
925 static int
926 aes_docsis_setup(void)
927 {
928         uint8_t dev_id = p_testsuite_params->valid_devs[0];
929         struct rte_cryptodev_info dev_info;
930         uint64_t feat_flags;
931         const enum rte_crypto_cipher_algorithm ciphers[] = {
932                 RTE_CRYPTO_CIPHER_AES_DOCSISBPI
933         };
934
935         rte_cryptodev_info_get(dev_id, &dev_info);
936         feat_flags = dev_info.feature_flags;
937
938         /* Data-path service does not support DOCSIS yet */
939         if (!(feat_flags & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) ||
940                         (global_api_test_type == CRYPTODEV_RAW_API_TEST)) {
941                 RTE_LOG(INFO, USER1, "Feature flag requirements for AES Docsis "
942                                 "testsuite not met\n");
943                 return TEST_SKIPPED;
944         }
945
946         if (check_cipher_capabilities_supported(ciphers, RTE_DIM(ciphers)) != 0) {
947                 RTE_LOG(INFO, USER1, "Capability requirements for AES Docsis "
948                                 "testsuite not met\n");
949                 return TEST_SKIPPED;
950         }
951
952         return 0;
953 }
954
955 static int
956 triple_des_chain_setup(void)
957 {
958         uint8_t dev_id = p_testsuite_params->valid_devs[0];
959         struct rte_cryptodev_info dev_info;
960         uint64_t feat_flags;
961         const enum rte_crypto_cipher_algorithm ciphers[] = {
962                 RTE_CRYPTO_CIPHER_3DES_CTR,
963                 RTE_CRYPTO_CIPHER_3DES_CBC
964         };
965         const enum rte_crypto_auth_algorithm auths[] = {
966                 RTE_CRYPTO_AUTH_SHA1_HMAC,
967                 RTE_CRYPTO_AUTH_SHA1
968         };
969
970         rte_cryptodev_info_get(dev_id, &dev_info);
971         feat_flags = dev_info.feature_flags;
972
973         if (!(feat_flags & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) ||
974                         ((global_api_test_type == CRYPTODEV_RAW_API_TEST) &&
975                         !(feat_flags & RTE_CRYPTODEV_FF_SYM_RAW_DP))) {
976                 RTE_LOG(INFO, USER1, "Feature flag requirements for 3DES Chain "
977                                 "testsuite not met\n");
978                 return TEST_SKIPPED;
979         }
980
981         if (check_cipher_capabilities_supported(ciphers, RTE_DIM(ciphers)) != 0
982                         && check_auth_capabilities_supported(auths,
983                         RTE_DIM(auths)) != 0) {
984                 RTE_LOG(INFO, USER1, "Capability requirements for 3DES Chain "
985                                 "testsuite not met\n");
986                 return TEST_SKIPPED;
987         }
988
989         return 0;
990 }
991
992 static int
993 triple_des_cipheronly_setup(void)
994 {
995         uint8_t dev_id = p_testsuite_params->valid_devs[0];
996         struct rte_cryptodev_info dev_info;
997         uint64_t feat_flags;
998         const enum rte_crypto_cipher_algorithm ciphers[] = {
999                 RTE_CRYPTO_CIPHER_3DES_CTR,
1000                 RTE_CRYPTO_CIPHER_3DES_CBC
1001         };
1002
1003         rte_cryptodev_info_get(dev_id, &dev_info);
1004         feat_flags = dev_info.feature_flags;
1005
1006         if (!(feat_flags & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) ||
1007                         ((global_api_test_type == CRYPTODEV_RAW_API_TEST) &&
1008                         !(feat_flags & RTE_CRYPTODEV_FF_SYM_RAW_DP))) {
1009                 RTE_LOG(INFO, USER1, "Feature flag requirements for 3DES "
1010                                 "Cipheronly testsuite not met\n");
1011                 return TEST_SKIPPED;
1012         }
1013
1014         if (check_cipher_capabilities_supported(ciphers, RTE_DIM(ciphers)) != 0) {
1015                 RTE_LOG(INFO, USER1, "Capability requirements for 3DES "
1016                                 "Cipheronly testsuite not met\n");
1017                 return TEST_SKIPPED;
1018         }
1019
1020         return 0;
1021 }
1022
1023 static int
1024 des_cipheronly_setup(void)
1025 {
1026         uint8_t dev_id = p_testsuite_params->valid_devs[0];
1027         struct rte_cryptodev_info dev_info;
1028         uint64_t feat_flags;
1029         const enum rte_crypto_cipher_algorithm ciphers[] = {
1030                 RTE_CRYPTO_CIPHER_DES_CBC
1031         };
1032
1033         rte_cryptodev_info_get(dev_id, &dev_info);
1034         feat_flags = dev_info.feature_flags;
1035
1036         if (!(feat_flags & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) ||
1037                         ((global_api_test_type == CRYPTODEV_RAW_API_TEST) &&
1038                         !(feat_flags & RTE_CRYPTODEV_FF_SYM_RAW_DP))) {
1039                 RTE_LOG(INFO, USER1, "Feature flag requirements for DES "
1040                                 "Cipheronly testsuite not met\n");
1041                 return TEST_SKIPPED;
1042         }
1043
1044         if (check_cipher_capabilities_supported(ciphers, RTE_DIM(ciphers)) != 0) {
1045                 RTE_LOG(INFO, USER1, "Capability requirements for DES "
1046                                 "Cipheronly testsuite not met\n");
1047                 return TEST_SKIPPED;
1048         }
1049
1050         return 0;
1051 }
1052
1053 static int
1054 des_docsis_setup(void)
1055 {
1056         uint8_t dev_id = p_testsuite_params->valid_devs[0];
1057         struct rte_cryptodev_info dev_info;
1058         uint64_t feat_flags;
1059         const enum rte_crypto_cipher_algorithm ciphers[] = {
1060                 RTE_CRYPTO_CIPHER_DES_DOCSISBPI
1061         };
1062
1063         rte_cryptodev_info_get(dev_id, &dev_info);
1064         feat_flags = dev_info.feature_flags;
1065
1066         /* Data-path service does not support DOCSIS yet */
1067         if (!(feat_flags & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) ||
1068                         (global_api_test_type == CRYPTODEV_RAW_API_TEST)) {
1069                 RTE_LOG(INFO, USER1, "Feature flag requirements for DES Docsis "
1070                                 "testsuite not met\n");
1071                 return TEST_SKIPPED;
1072         }
1073
1074         if (check_cipher_capabilities_supported(ciphers, RTE_DIM(ciphers)) != 0) {
1075                 RTE_LOG(INFO, USER1, "Capability requirements for DES Docsis "
1076                                 "testsuite not met\n");
1077                 return TEST_SKIPPED;
1078         }
1079
1080         return 0;
1081 }
1082
1083 static int
1084 authonly_setup(void)
1085 {
1086         uint8_t dev_id = p_testsuite_params->valid_devs[0];
1087         struct rte_cryptodev_info dev_info;
1088         uint64_t feat_flags;
1089         const enum rte_crypto_auth_algorithm auths[] = {
1090                 RTE_CRYPTO_AUTH_MD5,
1091                 RTE_CRYPTO_AUTH_MD5_HMAC,
1092                 RTE_CRYPTO_AUTH_SHA1,
1093                 RTE_CRYPTO_AUTH_SHA1_HMAC,
1094                 RTE_CRYPTO_AUTH_SHA224,
1095                 RTE_CRYPTO_AUTH_SHA224_HMAC,
1096                 RTE_CRYPTO_AUTH_SHA256,
1097                 RTE_CRYPTO_AUTH_SHA256_HMAC,
1098                 RTE_CRYPTO_AUTH_SHA384,
1099                 RTE_CRYPTO_AUTH_SHA384_HMAC,
1100                 RTE_CRYPTO_AUTH_SHA512,
1101                 RTE_CRYPTO_AUTH_SHA512_HMAC,
1102                 RTE_CRYPTO_AUTH_AES_CMAC,
1103                 RTE_CRYPTO_AUTH_NULL,
1104                 RTE_CRYPTO_AUTH_AES_XCBC_MAC
1105         };
1106
1107         rte_cryptodev_info_get(dev_id, &dev_info);
1108         feat_flags = dev_info.feature_flags;
1109
1110         if (!(feat_flags & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) ||
1111                         ((global_api_test_type == CRYPTODEV_RAW_API_TEST) &&
1112                         !(feat_flags & RTE_CRYPTODEV_FF_SYM_RAW_DP))) {
1113                 RTE_LOG(INFO, USER1, "Feature flag requirements for Auth Only "
1114                                 "testsuite not met\n");
1115                 return TEST_SKIPPED;
1116         }
1117
1118         if (check_auth_capabilities_supported(auths, RTE_DIM(auths)) != 0) {
1119                 RTE_LOG(INFO, USER1, "Capability requirements for Auth Only "
1120                                 "testsuite not met\n");
1121                 return TEST_SKIPPED;
1122         }
1123
1124         return 0;
1125 }
1126
1127 struct unit_test_suite *
1128 build_blockcipher_test_suite(enum blockcipher_test_type test_type)
1129 {
1130         int i, n_test_cases = 0;
1131         struct unit_test_suite *ts;
1132         const char *ts_name = NULL;
1133         const struct blockcipher_test_case *blk_tcs;
1134         struct unit_test_case *tc;
1135         int (*ts_setup)(void) = NULL;
1136
1137         switch (test_type) {
1138         case BLKCIPHER_AES_CHAIN_TYPE:
1139                 n_test_cases = RTE_DIM(aes_chain_test_cases);
1140                 blk_tcs = aes_chain_test_cases;
1141                 ts_name = "AES Chain";
1142                 ts_setup = aes_chain_setup;
1143                 break;
1144         case BLKCIPHER_AES_CIPHERONLY_TYPE:
1145                 n_test_cases = RTE_DIM(aes_cipheronly_test_cases);
1146                 blk_tcs = aes_cipheronly_test_cases;
1147                 ts_name = "AES Cipher Only";
1148                 ts_setup = aes_cipheronly_setup;
1149                 break;
1150         case BLKCIPHER_AES_DOCSIS_TYPE:
1151                 n_test_cases = RTE_DIM(aes_docsis_test_cases);
1152                 blk_tcs = aes_docsis_test_cases;
1153                 ts_name = "AES Docsis";
1154                 ts_setup = aes_docsis_setup;
1155                 break;
1156         case BLKCIPHER_3DES_CHAIN_TYPE:
1157                 n_test_cases = RTE_DIM(triple_des_chain_test_cases);
1158                 blk_tcs = triple_des_chain_test_cases;
1159                 ts_name = "3DES Chain";
1160                 ts_setup = triple_des_chain_setup;
1161                 break;
1162         case BLKCIPHER_3DES_CIPHERONLY_TYPE:
1163                 n_test_cases = RTE_DIM(triple_des_cipheronly_test_cases);
1164                 blk_tcs = triple_des_cipheronly_test_cases;
1165                 ts_name = "3DES Cipher Only";
1166                 ts_setup = triple_des_cipheronly_setup;
1167                 break;
1168         case BLKCIPHER_DES_CIPHERONLY_TYPE:
1169                 n_test_cases = RTE_DIM(des_cipheronly_test_cases);
1170                 blk_tcs = des_cipheronly_test_cases;
1171                 ts_name = "DES Cipher Only";
1172                 ts_setup = des_cipheronly_setup;
1173                 break;
1174         case BLKCIPHER_DES_DOCSIS_TYPE:
1175                 n_test_cases = RTE_DIM(des_docsis_test_cases);
1176                 blk_tcs = des_docsis_test_cases;
1177                 ts_name = "DES Docsis";
1178                 ts_setup = des_docsis_setup;
1179                 break;
1180         case BLKCIPHER_AUTHONLY_TYPE:
1181                 n_test_cases = RTE_DIM(hash_test_cases);
1182                 blk_tcs = hash_test_cases;
1183                 ts_name = "Auth Only";
1184                 ts_setup = authonly_setup;
1185                 break;
1186         default:
1187                 break;
1188         }
1189
1190         ts = calloc(1, sizeof(struct unit_test_suite) +
1191                         (sizeof(struct unit_test_case) * (n_test_cases + 1)));
1192         ts->suite_name = ts_name;
1193         ts->setup = ts_setup;
1194
1195         for (i = 0; i < n_test_cases; i++) {
1196                 tc = &ts->unit_test_cases[i];
1197                 tc->name = blk_tcs[i].test_descr;
1198                 tc->enabled = 1;
1199                 tc->setup = ut_setup;
1200                 tc->teardown = ut_teardown;
1201                 tc->testcase = NULL;
1202                 tc->testcase_with_data = blockcipher_test_case_run;
1203                 tc->data = &blk_tcs[i];
1204         }
1205         tc = &ts->unit_test_cases[i];
1206         tc->name = NULL;
1207         tc->enabled = 0;
1208         tc->setup = NULL;
1209         tc->teardown = NULL;
1210         tc->testcase = NULL;
1211         tc->testcase_with_data = NULL;
1212         tc->data = NULL;
1213
1214         return ts;
1215 }
1216
1217 void
1218 free_blockcipher_test_suite(struct unit_test_suite *ts)
1219 {
1220         free(ts);
1221 }