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