dpdk/app/test/test_cryptodev_blockcipher.c
<<
>>
Prefs
   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
  24static int
  25verify_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
  68static int
  69test_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
 298iterate:
 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
 804error_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
 824static int
 825blockcipher_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
 841static int
 842aes_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
 884static int
 885aes_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
 925static int
 926aes_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
 955static int
 956triple_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
 992static int
 993triple_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
1023static int
1024des_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
1053static int
1054des_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
1083static int
1084authonly_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
1127struct unit_test_suite *
1128build_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
1217void
1218free_blockcipher_test_suite(struct unit_test_suite *ts)
1219{
1220        free(ts);
1221}
1222
1223#endif /* !RTE_EXEC_ENV_WINDOWS */
1224