Added support for latency and throughput measurement of
TLS and DTLS security ops.

Signed-off-by: Akhil Goyal <gak...@marvell.com>
---
 app/test-crypto-perf/cperf_ops.c             | 144 +++++++++++++++++++
 app/test-crypto-perf/cperf_options.h         |   5 +-
 app/test-crypto-perf/cperf_options_parsing.c |  60 +++++++-
 app/test-crypto-perf/cperf_test_latency.c    |   1 +
 app/test-crypto-perf/cperf_test_throughput.c |   1 +
 app/test-crypto-perf/cperf_test_vectors.c    |   4 +-
 app/test-crypto-perf/cperf_test_verify.c     |   1 +
 app/test-crypto-perf/main.c                  |   4 +-
 doc/guides/tools/cryptoperf.rst              |   6 +
 9 files changed, 216 insertions(+), 10 deletions(-)

diff --git a/app/test-crypto-perf/cperf_ops.c b/app/test-crypto-perf/cperf_ops.c
index 84945d1313..d3fd115bc0 100644
--- a/app/test-crypto-perf/cperf_ops.c
+++ b/app/test-crypto-perf/cperf_ops.c
@@ -175,6 +175,42 @@ cperf_set_ops_security_ipsec(struct rte_crypto_op **ops,
        *tsc_start += tsc_end_temp - tsc_start_temp;
 }
 
+static void
+cperf_set_ops_security_tls(struct rte_crypto_op **ops,
+               uint32_t src_buf_offset __rte_unused,
+               uint32_t dst_buf_offset __rte_unused,
+               uint16_t nb_ops, void *sess,
+               const struct cperf_options *options,
+               const struct cperf_test_vector *test_vector,
+               uint16_t iv_offset __rte_unused, uint32_t *imix_idx,
+               uint64_t *tsc_start)
+{
+       const uint32_t test_buffer_size = options->test_buffer_size;
+       const uint32_t headroom_sz = options->headroom_sz;
+       const uint32_t segment_sz = options->segment_sz;
+       uint16_t i = 0;
+
+       RTE_SET_USED(imix_idx);
+       RTE_SET_USED(tsc_start);
+       RTE_SET_USED(test_vector);
+
+       for (i = 0; i < nb_ops; i++) {
+               struct rte_crypto_sym_op *sym_op = ops[i]->sym;
+               struct rte_mbuf *m = sym_op->m_src;
+
+               ops[i]->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
+               ops[i]->param1.tls_record.content_type = 0x17;
+               rte_security_attach_session(ops[i], sess);
+               sym_op->m_src = (struct rte_mbuf *)((uint8_t *)ops[i] + 
src_buf_offset);
+
+               m->data_off = headroom_sz;
+               m->buf_len = segment_sz;
+               m->data_len = test_buffer_size;
+               m->pkt_len = test_buffer_size;
+
+               sym_op->m_dst = NULL;
+       }
+}
 #endif
 
 static void
@@ -755,6 +791,106 @@ create_ipsec_session(struct rte_mempool *sess_mp,
        return (void *)rte_security_session_create(ctx, &sess_conf, sess_mp);
 }
 
+static void *
+create_tls_session(struct rte_mempool *sess_mp,
+               uint8_t dev_id,
+               const struct cperf_options *options,
+               const struct cperf_test_vector *test_vector,
+               uint16_t iv_offset)
+{
+       struct rte_crypto_sym_xform auth_xform = {0};
+       struct rte_crypto_sym_xform *crypto_xform;
+       struct rte_crypto_sym_xform xform = {0};
+
+       if (options->aead_algo != 0) {
+               /* Setup AEAD Parameters */
+               xform.type = RTE_CRYPTO_SYM_XFORM_AEAD;
+               xform.next = NULL;
+               xform.aead.algo = options->aead_algo;
+               xform.aead.op = options->aead_op;
+               xform.aead.iv.offset = iv_offset;
+               xform.aead.key.data = test_vector->aead_key.data;
+               xform.aead.key.length = test_vector->aead_key.length;
+               xform.aead.iv.length = test_vector->aead_iv.length;
+               xform.aead.digest_length = options->digest_sz;
+               xform.aead.aad_length = options->aead_aad_sz;
+               crypto_xform = &xform;
+       } else if (options->cipher_algo != 0 && options->auth_algo != 0) {
+               /* Setup Cipher Parameters */
+               xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+               xform.cipher.algo = options->cipher_algo;
+               xform.cipher.op = options->cipher_op;
+               xform.cipher.iv.offset = iv_offset;
+               xform.cipher.iv.length = test_vector->cipher_iv.length;
+               /* cipher different than null */
+               if (options->cipher_algo != RTE_CRYPTO_CIPHER_NULL) {
+                       xform.cipher.key.data = test_vector->cipher_key.data;
+                       xform.cipher.key.length = 
test_vector->cipher_key.length;
+               } else {
+                       xform.cipher.key.data = NULL;
+                       xform.cipher.key.length = 0;
+               }
+
+               /* Setup Auth Parameters */
+               auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH;
+               auth_xform.auth.algo = options->auth_algo;
+               auth_xform.auth.op = options->auth_op;
+               auth_xform.auth.iv.offset = iv_offset + xform.cipher.iv.length;
+               /* auth different than null */
+               if (options->auth_algo != RTE_CRYPTO_AUTH_NULL) {
+                       auth_xform.auth.digest_length = options->digest_sz;
+                       auth_xform.auth.key.length = 
test_vector->auth_key.length;
+                       auth_xform.auth.key.data = test_vector->auth_key.data;
+                       auth_xform.auth.iv.length = test_vector->auth_iv.length;
+               } else {
+                       auth_xform.auth.digest_length = 0;
+                       auth_xform.auth.key.length = 0;
+                       auth_xform.auth.key.data = NULL;
+                       auth_xform.auth.iv.length = 0;
+               }
+
+               if (options->is_outbound) {
+                       /* Currently supporting AUTH then Encrypt mode only for 
TLS. */
+                       crypto_xform = &auth_xform;
+                       auth_xform.next = &xform;
+                       xform.next = NULL;
+               } else {
+                       crypto_xform = &xform;
+                       xform.next = &auth_xform;
+                       auth_xform.next = NULL;
+               }
+       } else {
+               return NULL;
+       }
+
+       struct rte_security_tls_record_sess_options opts = {
+               .iv_gen_disable = 0,
+               .extra_padding_enable = 0,
+       };
+       struct rte_security_session_conf sess_conf = {
+               .action_type = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
+               .protocol = RTE_SECURITY_PROTOCOL_TLS_RECORD,
+               {.tls_record = {
+                       .ver = RTE_SECURITY_VERSION_TLS_1_2,
+                       .options = opts,
+               } },
+               .userdata = NULL,
+               .crypto_xform = crypto_xform,
+       };
+       if (options->tls_version)
+               sess_conf.tls_record.ver = options->tls_version;
+
+       if (options->is_outbound)
+               sess_conf.tls_record.type = RTE_SECURITY_TLS_SESS_TYPE_WRITE;
+       else
+               sess_conf.tls_record.type = RTE_SECURITY_TLS_SESS_TYPE_READ;
+
+       void *ctx = rte_cryptodev_get_sec_ctx(dev_id);
+
+       /* Create security session */
+       return (void *)rte_security_session_create(ctx, &sess_conf, sess_mp);
+}
+
 static void *
 cperf_create_session(struct rte_mempool *sess_mp,
        uint8_t dev_id,
@@ -863,6 +999,11 @@ cperf_create_session(struct rte_mempool *sess_mp,
                                options, test_vector, iv_offset);
        }
 
+       if (options->op_type == CPERF_TLS) {
+               return create_tls_session(sess_mp, dev_id,
+                               options, test_vector, iv_offset);
+       }
+
        if (options->op_type == CPERF_DOCSIS) {
                enum rte_security_docsis_direction direction;
 
@@ -1089,6 +1230,9 @@ cperf_get_op_functions(const struct cperf_options 
*options,
        case CPERF_IPSEC:
                op_fns->populate_ops = cperf_set_ops_security_ipsec;
                break;
+       case CPERF_TLS:
+               op_fns->populate_ops = cperf_set_ops_security_tls;
+               break;
 #endif
        default:
                return -1;
diff --git a/app/test-crypto-perf/cperf_options.h 
b/app/test-crypto-perf/cperf_options.h
index 6966e0b286..be36c70be1 100644
--- a/app/test-crypto-perf/cperf_options.h
+++ b/app/test-crypto-perf/cperf_options.h
@@ -55,6 +55,7 @@
 #define CPERF_PDCP_SES_HFN_EN  ("pdcp-ses-hfn-en")
 #define PDCP_DEFAULT_HFN       0x1
 #define CPERF_DOCSIS_HDR_SZ    ("docsis-hdr-sz")
+#define CPERF_TLS_VERSION      ("tls-version")
 #endif
 
 #define CPERF_CSV              ("csv-friendly")
@@ -83,7 +84,8 @@ enum cperf_op_type {
        CPERF_PDCP,
        CPERF_DOCSIS,
        CPERF_IPSEC,
-       CPERF_ASYM_MODEX
+       CPERF_ASYM_MODEX,
+       CPERF_TLS,
 };
 
 extern const char *cperf_op_type_strs[];
@@ -134,6 +136,7 @@ struct cperf_options {
        uint16_t pdcp_sdap;
        enum rte_security_pdcp_domain pdcp_domain;
        uint16_t docsis_hdr_sz;
+       enum rte_security_tls_version tls_version;
 #endif
        char device_type[RTE_CRYPTODEV_NAME_MAX_LEN];
        enum cperf_op_type op_type;
diff --git a/app/test-crypto-perf/cperf_options_parsing.c 
b/app/test-crypto-perf/cperf_options_parsing.c
index 75afedc7fd..cba6d6bc42 100644
--- a/app/test-crypto-perf/cperf_options_parsing.c
+++ b/app/test-crypto-perf/cperf_options_parsing.c
@@ -36,8 +36,8 @@ usage(char *progname)
                " --segment-sz N: set the size of the segment to use\n"
                " --desc-nb N: set number of descriptors for each crypto 
device\n"
                " --devtype TYPE: set crypto device type to use\n"
-               " --optype cipher-only / auth-only / cipher-then-auth /\n"
-               "           auth-then-cipher / aead : set operation type\n"
+               " --optype cipher-only / auth-only / cipher-then-auth / 
auth-then-cipher /\n"
+               "        aead / pdcp / docsis / ipsec / modex / tls-record : 
set operation type\n"
                " --sessionless: enable session-less crypto operations\n"
                " --out-of-place: enable out-of-place crypto operations\n"
                " --test-file NAME: set the test vector file path\n"
@@ -67,6 +67,7 @@ usage(char *progname)
                " --pdcp-ses-hfn-en: enable session based fixed HFN\n"
                " --enable-sdap: enable sdap\n"
                " --docsis-hdr-sz: set DOCSIS header size\n"
+               " --tls-version VER: set TLS VERSION <TLS1.2/TLS1.3/DTLS1.2>\n"
 #endif
                " -h: prints this help\n",
                progname);
@@ -480,7 +481,11 @@ parse_op_type(struct cperf_options *opts, const char *arg)
                {
                        cperf_op_type_strs[CPERF_ASYM_MODEX],
                        CPERF_ASYM_MODEX
-               }
+               },
+               {
+                       cperf_op_type_strs[CPERF_TLS],
+                       CPERF_TLS
+               },
        };
 
        int id = get_str_key_id_mapping(optype_namemap,
@@ -732,6 +737,45 @@ parse_pdcp_domain(struct cperf_options *opts, const char 
*arg)
        return 0;
 }
 
+const char *cperf_tls_version_strs[] = {
+       [RTE_SECURITY_VERSION_TLS_1_2] = "TLS1.2",
+       [RTE_SECURITY_VERSION_TLS_1_3] = "TLS1.3",
+       [RTE_SECURITY_VERSION_DTLS_1_2] = "DTLS1.2"
+};
+
+static int
+parse_tls_version(struct cperf_options *opts, const char *arg)
+{
+       struct name_id_map tls_version_namemap[] = {
+               {
+                       cperf_tls_version_strs
+                       [RTE_SECURITY_VERSION_TLS_1_2],
+                       RTE_SECURITY_VERSION_TLS_1_2
+               },
+               {
+                       cperf_tls_version_strs
+                       [RTE_SECURITY_VERSION_TLS_1_3],
+                       RTE_SECURITY_VERSION_TLS_1_3
+               },
+               {
+                       cperf_tls_version_strs
+                       [RTE_SECURITY_VERSION_DTLS_1_2],
+                       RTE_SECURITY_VERSION_DTLS_1_2
+               },
+       };
+
+       int id = get_str_key_id_mapping(tls_version_namemap,
+                       RTE_DIM(tls_version_namemap), arg);
+       if (id < 0) {
+               RTE_LOG(ERR, USER1, "invalid TLS version specified\n");
+               return -1;
+       }
+
+       opts->tls_version = (enum rte_security_tls_version)id;
+
+       return 0;
+}
+
 static int
 parse_pdcp_ses_hfn_en(struct cperf_options *opts, const char *arg __rte_unused)
 {
@@ -893,6 +937,7 @@ static struct option lgopts[] = {
        { CPERF_PDCP_SES_HFN_EN, no_argument, 0, 0 },
        { CPERF_ENABLE_SDAP, no_argument, 0, 0 },
        { CPERF_DOCSIS_HDR_SZ, required_argument, 0, 0 },
+       { CPERF_TLS_VERSION, required_argument, 0, 0 },
 #endif
        { CPERF_CSV, no_argument, 0, 0},
 
@@ -1010,6 +1055,7 @@ cperf_opts_parse_long(int opt_idx, struct cperf_options 
*opts)
                { CPERF_PDCP_SES_HFN_EN,        parse_pdcp_ses_hfn_en },
                { CPERF_ENABLE_SDAP,    parse_enable_sdap },
                { CPERF_DOCSIS_HDR_SZ,  parse_docsis_hdr_sz },
+               { CPERF_TLS_VERSION,    parse_tls_version },
 #endif
                { CPERF_CSV,            parse_csv_friendly},
                { CPERF_PMDCC_DELAY_MS, parse_pmd_cyclecount_delay_ms},
@@ -1190,12 +1236,12 @@ cperf_options_check(struct cperf_options *options)
        if (options->segment_sz == 0) {
                options->segment_sz = options->max_buffer_size +
                                options->digest_sz;
-               /* In IPsec operation, packet length will be increased
+               /* In IPsec and TLS operation, packet length will be increased
                 * by some bytes depend upon the algorithm, so increasing
                 * the segment size by headroom to cover most of
                 * the scenarios.
                 */
-               if (options->op_type == CPERF_IPSEC)
+               if (options->op_type == CPERF_IPSEC || options->op_type == 
CPERF_TLS)
                        options->segment_sz += RTE_PKTMBUF_HEADROOM;
        }
 
@@ -1328,7 +1374,7 @@ cperf_options_check(struct cperf_options *options)
                        return -EINVAL;
        }
 
-       if (options->op_type == CPERF_IPSEC) {
+       if (options->op_type == CPERF_IPSEC || options->op_type == CPERF_TLS) {
                if (options->aead_algo) {
                        if (options->aead_op == RTE_CRYPTO_AEAD_OP_ENCRYPT)
                                options->is_outbound = 1;
@@ -1356,6 +1402,8 @@ cperf_options_dump(struct cperf_options *opts)
        printf("#\n");
        printf("# cperf test: %s\n", cperf_test_type_strs[opts->test]);
        printf("#\n");
+       printf("# cperf operation type: %s\n", 
cperf_op_type_strs[opts->op_type]);
+       printf("#\n");
        printf("# size of crypto op / mbuf pool: %u\n", opts->pool_sz);
        printf("# total number of ops: %u\n", opts->total_ops);
        if (opts->inc_buffer_size != 0) {
diff --git a/app/test-crypto-perf/cperf_test_latency.c 
b/app/test-crypto-perf/cperf_test_latency.c
index 484bc9eb4e..99b7d7c678 100644
--- a/app/test-crypto-perf/cperf_test_latency.c
+++ b/app/test-crypto-perf/cperf_test_latency.c
@@ -52,6 +52,7 @@ cperf_latency_test_free(struct cperf_latency_ctx *ctx)
 #ifdef RTE_LIB_SECURITY
                else if (ctx->options->op_type == CPERF_PDCP ||
                         ctx->options->op_type == CPERF_DOCSIS ||
+                        ctx->options->op_type == CPERF_TLS ||
                         ctx->options->op_type == CPERF_IPSEC) {
                        void *sec_ctx = rte_cryptodev_get_sec_ctx(ctx->dev_id);
                        rte_security_session_destroy(sec_ctx, ctx->sess);
diff --git a/app/test-crypto-perf/cperf_test_throughput.c 
b/app/test-crypto-perf/cperf_test_throughput.c
index f8f8bd717f..e3d266d7a4 100644
--- a/app/test-crypto-perf/cperf_test_throughput.c
+++ b/app/test-crypto-perf/cperf_test_throughput.c
@@ -43,6 +43,7 @@ cperf_throughput_test_free(struct cperf_throughput_ctx *ctx)
 #ifdef RTE_LIB_SECURITY
                else if (ctx->options->op_type == CPERF_PDCP ||
                         ctx->options->op_type == CPERF_DOCSIS ||
+                        ctx->options->op_type == CPERF_TLS ||
                         ctx->options->op_type == CPERF_IPSEC) {
                        void *sec_ctx = rte_cryptodev_get_sec_ctx(ctx->dev_id);
 
diff --git a/app/test-crypto-perf/cperf_test_vectors.c 
b/app/test-crypto-perf/cperf_test_vectors.c
index 5cd7a229b8..3c35eea460 100644
--- a/app/test-crypto-perf/cperf_test_vectors.c
+++ b/app/test-crypto-perf/cperf_test_vectors.c
@@ -660,7 +660,7 @@ cperf_test_vector_get_dummy(struct cperf_options *options)
                t_vec->modex.elen = options->modex_data->exponent.len;
        }
 
-       if (options->op_type == CPERF_PDCP ||
+       if (options->op_type == CPERF_PDCP || options->op_type == CPERF_TLS ||
                        options->op_type == CPERF_IPSEC) {
                if (options->cipher_algo == RTE_CRYPTO_CIPHER_NULL) {
                        t_vec->cipher_key.length = 0;
@@ -795,7 +795,7 @@ cperf_test_vector_get_dummy(struct cperf_options *options)
                t_vec->auth_iv.length = options->auth_iv_sz;
        }
 
-       if (options->op_type == CPERF_AEAD ||
+       if (options->op_type == CPERF_AEAD || options->op_type == CPERF_TLS ||
                        options->op_type == CPERF_IPSEC) {
                t_vec->aead_key.length = options->aead_key_sz;
                t_vec->aead_key.data = aead_key;
diff --git a/app/test-crypto-perf/cperf_test_verify.c 
b/app/test-crypto-perf/cperf_test_verify.c
index a6c0ffe813..a57841dafb 100644
--- a/app/test-crypto-perf/cperf_test_verify.c
+++ b/app/test-crypto-perf/cperf_test_verify.c
@@ -47,6 +47,7 @@ cperf_verify_test_free(struct cperf_verify_ctx *ctx)
 #ifdef RTE_LIB_SECURITY
                else if (ctx->options->op_type == CPERF_PDCP ||
                         ctx->options->op_type == CPERF_DOCSIS ||
+                        ctx->options->op_type == CPERF_TLS ||
                         ctx->options->op_type == CPERF_IPSEC) {
                        void *sec_ctx = rte_cryptodev_get_sec_ctx(ctx->dev_id);
 
diff --git a/app/test-crypto-perf/main.c b/app/test-crypto-perf/main.c
index 6a2e5762a3..40c0b4b54f 100644
--- a/app/test-crypto-perf/main.c
+++ b/app/test-crypto-perf/main.c
@@ -43,7 +43,8 @@ const char *cperf_op_type_strs[] = {
        [CPERF_PDCP] = "pdcp",
        [CPERF_DOCSIS] = "docsis",
        [CPERF_IPSEC] = "ipsec",
-       [CPERF_ASYM_MODEX] = "modex"
+       [CPERF_ASYM_MODEX] = "modex",
+       [CPERF_TLS] = "tls-record"
 };
 
 const struct cperf_test cperf_testmap[] = {
@@ -236,6 +237,7 @@ cperf_initialize_cryptodev(struct cperf_options *opts, 
uint8_t *enabled_cdevs)
                case CPERF_PDCP:
                case CPERF_DOCSIS:
                case CPERF_IPSEC:
+               case CPERF_TLS:
                        /* Fall through */
                default:
                        conf.ff_disable |= RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO;
diff --git a/doc/guides/tools/cryptoperf.rst b/doc/guides/tools/cryptoperf.rst
index f30784674d..facf412799 100644
--- a/doc/guides/tools/cryptoperf.rst
+++ b/doc/guides/tools/cryptoperf.rst
@@ -175,6 +175,8 @@ The following are the application command-line options:
            pdcp
            docsis
            modex
+           ipsec
+           tls-record
 
         For GCM/CCM algorithms you should use aead flag.
 
@@ -340,6 +342,10 @@ The following are the application command-line options:
         Set modex length for asymmetric crypto perf test.
         Supported lengths are 60, 128, 255, 448. Default length is 128.
 
+* ``--tls-version <TLS1.2/TLS1.3/DTLS1.2>``
+
+        Set TLS/DTLS protocol version for perf test (default is TLS1.2).
+
 Test Vector File
 ~~~~~~~~~~~~~~~~
 
-- 
2.25.1

Reply via email to