From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id BFBEEA04B6; Mon, 7 Sep 2020 15:32:28 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 952FA1BF8A; Mon, 7 Sep 2020 15:32:28 +0200 (CEST) Received: from hqnvemgate25.nvidia.com (hqnvemgate25.nvidia.com [216.228.121.64]) by dpdk.org (Postfix) with ESMTP id 3F8001BE0C for ; Mon, 7 Sep 2020 15:32:26 +0200 (CEST) Received: from hqpgpgate101.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate25.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA) id ; Mon, 07 Sep 2020 06:31:35 -0700 Received: from hqmail.nvidia.com ([172.20.161.6]) by hqpgpgate101.nvidia.com (PGP Universal service); Mon, 07 Sep 2020 06:32:25 -0700 X-PGP-Universal: processed; by hqpgpgate101.nvidia.com on Mon, 07 Sep 2020 06:32:25 -0700 Received: from [172.27.8.21] (172.20.13.39) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Mon, 7 Sep 2020 13:32:16 +0000 To: Fan Zhang , CC: , , , References: <20200818121720.52090-1-roy.fan.zhang@intel.com> <20200904160945.24590-1-roy.fan.zhang@intel.com> <20200904160945.24590-2-roy.fan.zhang@intel.com> From: Suanming Mou Message-ID: Date: Mon, 7 Sep 2020 21:32:13 +0800 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Thunderbird/68.8.1 MIME-Version: 1.0 In-Reply-To: <20200904160945.24590-2-roy.fan.zhang@intel.com> Content-Type: text/plain; charset="utf-8"; format=flowed Content-Transfer-Encoding: 7bit Content-Language: en-US X-Originating-IP: [172.20.13.39] X-ClientProxiedBy: HQMAIL107.nvidia.com (172.20.187.13) To HQMAIL107.nvidia.com (172.20.187.13) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1599485495; bh=83O9VOxTlzMiDuyime2MnX8O9DX0lhIYYyZiijycLWs=; h=X-PGP-Universal:Subject:To:CC:References:From:Message-ID:Date: User-Agent:MIME-Version:In-Reply-To:Content-Type: Content-Transfer-Encoding:Content-Language:X-Originating-IP: X-ClientProxiedBy; b=heeKsaB5VBJrsoiKeCkLa2+eVBjeBT9DkVjdXW6/82a26E3z7qknQAx8sp+61iPPl 5hJNU4J2hZJthiLspPJOONVcue5UGgWEgql0SERQrf36Fplz14RLCGQsm+P16RwvwA 8A6APGDWhi07OtL+veVqksfUGRiuIhjTNXyKoTBatcyGx3iL7SAkNcXFPTMYf4EvlA aEu+vW9vf62ammvGGs6H8Hs/ZV4udht3mG5I4wHGRPhopVO87yIpmw5iE6hpv5ZhjK JoOnqcbkvbIg2l0LskBirz1CNt1ZXdeE8mAGmCDZ9dhZEjvGaoLv1E+ckFxGzfbaVY rZdEAgvIigS1Q== Subject: Re: [dpdk-dev] [dpdk-dev v2 1/2] fips_validation: add SGL support X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Hi, On 9/5/2020 12:09 AM, Fan Zhang wrote: > This patch adds SGL support to FIPS sample application. > Originally the application allocates single mbuf of 64KB - 1 > bytes data room. With the change the user may reduce the > mbuf dataroom size by using the add cmdline option. If the > input test data is longer than the user provided data room > size the application will automatically build chained mbufs > for the target cryptodev PMD to test. > > Signed-off-by: Fan Zhang > --- > doc/guides/sample_app_ug/fips_validation.rst | 6 + > examples/fips_validation/fips_validation.h | 3 +- > examples/fips_validation/main.c | 377 +++++++++++++------ > 3 files changed, 271 insertions(+), 115 deletions(-) > > diff --git a/doc/guides/sample_app_ug/fips_validation.rst b/doc/guides/sample_app_ug/fips_validation.rst > index 2953fddeb..8d3db2214 100644 > --- a/doc/guides/sample_app_ug/fips_validation.rst > +++ b/doc/guides/sample_app_ug/fips_validation.rst > @@ -96,6 +96,7 @@ The application requires a number of command line options: > -- --req-file FILE_PATH/FOLDER_PATH > --rsp-file FILE_PATH/FOLDER_PATH > [--cryptodev DEVICE_NAME] [--cryptodev-id ID] [--path-is-folder] > + --mbuf-dataroom DATAROOM_SIZE > > where, > * req-file: The path of the request file or folder, separated by > @@ -111,6 +112,11 @@ where, > * path-is-folder: If presented the application expects req-file and rsp-file > are folder paths. > > + * mbuf-dataroom: By default the application creates mbuf pool with maximum > + possible data room (65535 bytes). If the user wants to test scatter-gather > + list feature of the PMD he or she may set this value to reduce the dataroom > + size so that the input data may be dividied into multiple chained mbufs. > + > > To run the application in linux environment to test one AES FIPS test data > file for crypto_aesni_mb PMD, issue the command: > diff --git a/examples/fips_validation/fips_validation.h b/examples/fips_validation/fips_validation.h > index 75fa555fa..ecf3d54dd 100644 > --- a/examples/fips_validation/fips_validation.h > +++ b/examples/fips_validation/fips_validation.h > @@ -12,7 +12,8 @@ > #define MAX_CASE_LINE 15 > #define MAX_LINE_CHAR 204800 /*< max number of characters per line */ > #define MAX_NB_TESTS 10240 > -#define MAX_BUF_SIZE 2048 > +#define DEF_MBUF_SEG_SIZE (UINT16_MAX - sizeof(struct rte_mbuf) - \ > + RTE_PKTMBUF_HEADROOM) > #define MAX_STRING_SIZE 64 > #define MAX_DIGEST_SIZE 64 > > diff --git a/examples/fips_validation/main.c b/examples/fips_validation/main.c > index efd32a86a..fadca6e0c 100644 > --- a/examples/fips_validation/main.c > +++ b/examples/fips_validation/main.c > @@ -17,6 +17,7 @@ > > #define REQ_FILE_PATH_KEYWORD "req-file" > #define RSP_FILE_PATH_KEYWORD "rsp-file" > +#define MBUF_DATAROOM_KEYWORD "mbuf-dataroom" > #define FOLDER_KEYWORD "path-is-folder" > #define CRYPTODEV_KEYWORD "cryptodev" > #define CRYPTODEV_ID_KEYWORD "cryptodev-id" > @@ -33,15 +34,19 @@ struct cryptodev_fips_validate_env { > const char *req_path; > const char *rsp_path; > uint32_t is_path_folder; > - uint32_t dev_id; > + uint8_t dev_id; > + uint8_t dev_support_sgl; > + uint16_t mbuf_data_room; > struct rte_mempool *mpool; > struct rte_mempool *sess_mpool; > struct rte_mempool *sess_priv_mpool; > struct rte_mempool *op_pool; > struct rte_mbuf *mbuf; > + uint8_t *digest; > + uint16_t digest_len; > struct rte_crypto_op *op; > struct rte_cryptodev_sym_session *sess; > - uint32_t self_test; > + uint16_t self_test; > struct fips_dev_broken_test_config *broken_test_config; > } env; > > @@ -50,8 +55,10 @@ cryptodev_fips_validate_app_int(void) > { > struct rte_cryptodev_config conf = {rte_socket_id(), 1, 0}; > struct rte_cryptodev_qp_conf qp_conf = {128, NULL, NULL}; > + struct rte_cryptodev_info dev_info; Better to initialize the dev_info here? > uint32_t sess_sz = rte_cryptodev_sym_get_private_session_size( > env.dev_id); > + uint32_t nb_mbufs = UINT16_MAX / env.mbuf_data_room + 1; > int ret; > > if (env.self_test) { > @@ -70,8 +77,15 @@ cryptodev_fips_validate_app_int(void) > if (ret < 0) > return ret; > > - env.mpool = rte_pktmbuf_pool_create("FIPS_MEMPOOL", 128, 0, 0, > - UINT16_MAX, rte_socket_id()); > + rte_cryptodev_info_get(env.dev_id, &dev_info); > + if (dev_info.feature_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL) > + env.dev_support_sgl = 1; > + else > + env.dev_support_sgl = 0; > + > + env.mpool = rte_pktmbuf_pool_create("FIPS_MEMPOOL", nb_mbufs, > + 0, 0, sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM + > + env.mbuf_data_room, rte_socket_id()); > if (!env.mpool) > return ret; > > @@ -102,10 +116,6 @@ cryptodev_fips_validate_app_int(void) > if (!env.op_pool) > goto error_exit; > > - env.mbuf = rte_pktmbuf_alloc(env.mpool); > - if (!env.mbuf) > - goto error_exit; > - > env.op = rte_crypto_op_alloc(env.op_pool, RTE_CRYPTO_OP_TYPE_SYMMETRIC); > if (!env.op) > goto error_exit; > @@ -160,7 +170,7 @@ parse_cryptodev_arg(char *arg) > return id; > } > > - env.dev_id = (uint32_t)id; > + env.dev_id = (uint8_t)id; > > return 0; > } > @@ -191,19 +201,21 @@ parse_cryptodev_id_arg(char *arg) > static void > cryptodev_fips_validate_usage(const char *prgname) > { > + uint32_t def_mbuf_seg_size = DEF_MBUF_SEG_SIZE; > printf("%s [EAL options] --\n" > " --%s: REQUEST-FILE-PATH\n" > " --%s: RESPONSE-FILE-PATH\n" > " --%s: indicating both paths are folders\n" > + " --%s: mbuf dataroom size (default %u bytes)\n" > " --%s: CRYPTODEV-NAME\n" > " --%s: CRYPTODEV-ID-NAME\n" > " --%s: self test indicator\n" > " --%s: self broken test ID\n" > " --%s: self broken test direction\n", > prgname, REQ_FILE_PATH_KEYWORD, RSP_FILE_PATH_KEYWORD, > - FOLDER_KEYWORD, CRYPTODEV_KEYWORD, CRYPTODEV_ID_KEYWORD, > - CRYPTODEV_ST_KEYWORD, CRYPTODEV_BK_ID_KEYWORD, > - CRYPTODEV_BK_DIR_KEY); > + FOLDER_KEYWORD, MBUF_DATAROOM_KEYWORD, def_mbuf_seg_size, > + CRYPTODEV_KEYWORD, CRYPTODEV_ID_KEYWORD, CRYPTODEV_ST_KEYWORD, > + CRYPTODEV_BK_ID_KEYWORD, CRYPTODEV_BK_DIR_KEY); > } > > static int > @@ -217,6 +229,7 @@ cryptodev_fips_validate_parse_args(int argc, char **argv) > {REQ_FILE_PATH_KEYWORD, required_argument, 0, 0}, > {RSP_FILE_PATH_KEYWORD, required_argument, 0, 0}, > {FOLDER_KEYWORD, no_argument, 0, 0}, > + {MBUF_DATAROOM_KEYWORD, required_argument, 0, 0}, > {CRYPTODEV_KEYWORD, required_argument, 0, 0}, > {CRYPTODEV_ID_KEYWORD, required_argument, 0, 0}, > {CRYPTODEV_ST_KEYWORD, no_argument, 0, 0}, > @@ -227,6 +240,14 @@ cryptodev_fips_validate_parse_args(int argc, char **argv) > > argvopt = argv; > > + env.mbuf_data_room = DEF_MBUF_SEG_SIZE; > + if (rte_cryptodev_count()) > + env.dev_id = 0; > + else { > + cryptodev_fips_validate_usage(prgname); > + return -EINVAL; > + } > + > while ((opt = getopt_long(argc, argvopt, "s:", > lgopts, &option_index)) != EOF) { > > @@ -305,6 +326,23 @@ cryptodev_fips_validate_parse_args(int argc, char **argv) > cryptodev_fips_validate_usage(prgname); > return -EINVAL; > } > + } else if (strcmp(lgopts[option_index].name, > + MBUF_DATAROOM_KEYWORD) == 0) { > + uint32_t data_room_size; > + > + if (parser_read_uint32(&data_room_size, > + optarg) < 0) { > + cryptodev_fips_validate_usage(prgname); > + return -EINVAL; > + } > + > + if (data_room_size == 0 || > + data_room_size > UINT16_MAX) { > + cryptodev_fips_validate_usage(prgname); > + return -EINVAL; > + } > + > + env.mbuf_data_room = data_room_size; > } else { > cryptodev_fips_validate_usage(prgname); > return -EINVAL; > @@ -315,8 +353,7 @@ cryptodev_fips_validate_parse_args(int argc, char **argv) > } > } > > - if (env.req_path == NULL || env.rsp_path == NULL || > - env.dev_id == UINT32_MAX) { > + if (env.req_path == NULL || env.rsp_path == NULL) { > cryptodev_fips_validate_usage(prgname); > return -EINVAL; > } > @@ -451,60 +488,124 @@ struct fips_test_ops { > } test_ops; > > static int > -prepare_cipher_op(void) > +prepare_data_mbufs(struct fips_val *val) > { > - struct rte_crypto_sym_op *sym = env.op->sym; > - uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, IV_OFF); > + struct rte_mbuf *m, *head = 0; > + uint8_t *src = val->val; > + uint32_t total_len = val->len; > + uint16_t nb_seg; > + int ret = 0; > > - __rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC); > - rte_pktmbuf_reset(env.mbuf); > - > - sym->m_src = env.mbuf; > - sym->cipher.data.offset = 0; > + if (env.mbuf) > + rte_pktmbuf_free(env.mbuf); > > - memcpy(iv, vec.iv.val, vec.iv.len); > + if (total_len > RTE_MBUF_MAX_NB_SEGS) { > + RTE_LOG(ERR, USER1, "Data len %u too big\n", total_len); > + return -EPERM; > + } > > - if (info.op == FIPS_TEST_ENC_AUTH_GEN) { > - uint8_t *pt; > + nb_seg = total_len / env.mbuf_data_room; > + if (total_len % env.mbuf_data_room) > + nb_seg++; > > - if (vec.pt.len > RTE_MBUF_MAX_NB_SEGS) { > - RTE_LOG(ERR, USER1, "PT len %u\n", vec.pt.len); > - return -EPERM; > - } > + m = rte_pktmbuf_alloc(env.mpool); > + if (!m) { > + RTE_LOG(ERR, USER1, "Error %i: Not enough mbuf\n", > + -ENOMEM); > + return -ENOMEM; > + } > + head = m; > > - pt = (uint8_t *)rte_pktmbuf_append(env.mbuf, vec.pt.len); > + while (nb_seg) { > + uint16_t len = RTE_MIN(total_len, env.mbuf_data_room); > + uint8_t *dst = (uint8_t *)rte_pktmbuf_append(m, len); > > - if (!pt) { > + if (!dst) { > RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n", > -ENOMEM); > - return -ENOMEM; > + ret = -ENOMEM; > + goto error_exit; > } > > - memcpy(pt, vec.pt.val, vec.pt.len); > - sym->cipher.data.length = vec.pt.len; > + memcpy(dst, src, len); > > - } else { > - uint8_t *ct; > - > - if (vec.ct.len > RTE_MBUF_MAX_NB_SEGS) { > - RTE_LOG(ERR, USER1, "CT len %u\n", vec.ct.len); > - return -EPERM; > + if (head != m) { > + ret = rte_pktmbuf_chain(head, m); > + if (ret) { > + rte_pktmbuf_free(m); > + RTE_LOG(ERR, USER1, "Error %i: SGL build\n", > + ret); > + goto error_exit; > + } > } > + total_len -= len; > > - ct = (uint8_t *)rte_pktmbuf_append(env.mbuf, vec.ct.len); > + if (total_len) { > + if (!env.dev_support_sgl) { > + RTE_LOG(ERR, USER1, "SGL not supported\n"); > + ret = -EPERM; > + goto error_exit; > + } > > - if (!ct) { > - RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n", > - -ENOMEM); > - return -ENOMEM; > - } > + m = rte_pktmbuf_alloc(env.mpool); > + if (!m) { > + RTE_LOG(ERR, USER1, "Error %i: No memory\n", > + -ENOMEM); > + goto error_exit; > + } > + } else > + break; > + > + src += len; > + nb_seg--; > + } > + > + if (total_len) { > + RTE_LOG(ERR, USER1, "Error %i: Failed to store all data\n", > + -ENOMEM); > + goto error_exit; > + } > + > + env.mbuf = head; > + > + return 0; > + > +error_exit: > + if (head) > + rte_pktmbuf_free(head); > + return ret; > +} > + > +static int > +prepare_cipher_op(void) > +{ > + struct rte_crypto_sym_op *sym = env.op->sym; > + uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, IV_OFF); > + int ret; > + > + __rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC); > + > + memcpy(iv, vec.iv.val, vec.iv.len); > + > + if (info.op == FIPS_TEST_ENC_AUTH_GEN) { > + ret = prepare_data_mbufs(&vec.pt); > + if (ret < 0) > + return ret; > + > + sym->cipher.data.length = vec.pt.len; > + } else { > + ret = prepare_data_mbufs(&vec.ct); > + if (ret < 0) > + return ret; > > - memcpy(ct, vec.ct.val, vec.ct.len); > sym->cipher.data.length = vec.ct.len; > } > > rte_crypto_op_attach_sym_session(env.op, env.sess); > > + sym->m_src = env.mbuf; > + sym->cipher.data.offset = 0; > + > return 0; > } > > @@ -512,32 +613,33 @@ static int > prepare_auth_op(void) > { > struct rte_crypto_sym_op *sym = env.op->sym; > - uint8_t *pt; > + int ret; > > __rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC); > - rte_pktmbuf_reset(env.mbuf); > > - sym->m_src = env.mbuf; > - sym->auth.data.offset = 0; > + ret = prepare_data_mbufs(&vec.pt); > + if (ret < 0) > + return ret; > > - pt = (uint8_t *)rte_pktmbuf_append(env.mbuf, vec.pt.len + > - vec.cipher_auth.digest.len); > + if (env.digest) > + rte_free(env.digest); > > - if (!pt) { > - RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n", > - -ENOMEM); > + env.digest = rte_zmalloc(NULL, vec.cipher_auth.digest.len, > + RTE_CACHE_LINE_SIZE); > + if (!env.digest) { > + RTE_LOG(ERR, USER1, "Not enough memory\n"); > return -ENOMEM; > } > + env.digest_len = vec.cipher_auth.digest.len; > > + sym->m_src = env.mbuf; > + sym->auth.data.offset = 0; > sym->auth.data.length = vec.pt.len; > - sym->auth.digest.data = pt + vec.pt.len; > - sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( > - env.mbuf, vec.pt.len); > - > - memcpy(pt, vec.pt.val, vec.pt.len); > + sym->auth.digest.data = env.digest; > + sym->auth.digest.phys_addr = rte_malloc_virt2iova(env.digest); > > if (info.op == FIPS_TEST_DEC_AUTH_VERIF) > - memcpy(pt + vec.pt.len, vec.cipher_auth.digest.val, > + memcpy(env.digest, vec.cipher_auth.digest.val, > vec.cipher_auth.digest.len); > > rte_crypto_op_attach_sym_session(env.op, env.sess); > @@ -550,65 +652,53 @@ prepare_aead_op(void) > { > struct rte_crypto_sym_op *sym = env.op->sym; > uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, IV_OFF); > + int ret; > > __rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC); > - rte_pktmbuf_reset(env.mbuf); > > if (info.algo == FIPS_TEST_ALGO_AES_CCM) > - memcpy(iv + 1, vec.iv.val, vec.iv.len); > - else > - memcpy(iv, vec.iv.val, vec.iv.len); > + iv++; > > - sym->m_src = env.mbuf; > - sym->aead.data.offset = 0; > - sym->aead.aad.data = vec.aead.aad.val; > - sym->aead.aad.phys_addr = rte_malloc_virt2iova(sym->aead.aad.data); > + if (vec.iv.val) > + memcpy(iv, vec.iv.val, vec.iv.len); > + else > + /* if REQ file has iv length but not data, default as all 0 */ > + memset(iv, 0, vec.iv.len); > > if (info.op == FIPS_TEST_ENC_AUTH_GEN) { > - uint8_t *pt; > - > - if (vec.pt.len > RTE_MBUF_MAX_NB_SEGS) { > - RTE_LOG(ERR, USER1, "PT len %u\n", vec.pt.len); > - return -EPERM; > - } > - > - pt = (uint8_t *)rte_pktmbuf_append(env.mbuf, > - vec.pt.len + vec.aead.digest.len); > + ret = prepare_data_mbufs(&vec.pt); > + if (ret < 0) > + return ret; > > - if (!pt) { > - RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n", > - -ENOMEM); > + if (env.digest) > + rte_free(env.digest); > + env.digest = rte_zmalloc(NULL, vec.aead.digest.len, > + RTE_CACHE_LINE_SIZE); > + if (!env.digest) { > + RTE_LOG(ERR, USER1, "Not enough memory\n"); > return -ENOMEM; > } > + env.digest_len = vec.cipher_auth.digest.len; > > - memcpy(pt, vec.pt.val, vec.pt.len); > sym->aead.data.length = vec.pt.len; > - sym->aead.digest.data = pt + vec.pt.len; > - sym->aead.digest.phys_addr = rte_pktmbuf_mtophys_offset( > - env.mbuf, vec.pt.len); > + sym->aead.digest.data = env.digest; > + sym->aead.digest.phys_addr = rte_malloc_virt2iova(env.digest); > } else { > - uint8_t *ct; > - > - if (vec.ct.len > RTE_MBUF_MAX_NB_SEGS) { > - RTE_LOG(ERR, USER1, "CT len %u\n", vec.ct.len); > - return -EPERM; > - } > - > - ct = (uint8_t *)rte_pktmbuf_append(env.mbuf, vec.ct.len); > - > - if (!ct) { > - RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n", > - -ENOMEM); > - return -ENOMEM; > - } > + ret = prepare_data_mbufs(&vec.ct); > + if (ret < 0) > + return ret; > > - memcpy(ct, vec.ct.val, vec.ct.len); > sym->aead.data.length = vec.ct.len; > sym->aead.digest.data = vec.aead.digest.val; > sym->aead.digest.phys_addr = rte_malloc_virt2iova( > sym->aead.digest.data); > } > > + sym->m_src = env.mbuf; > + sym->aead.data.offset = 0; > + sym->aead.aad.data = vec.aead.aad.val; > + sym->aead.aad.phys_addr = rte_malloc_virt2iova(sym->aead.aad.data); > + > rte_crypto_op_attach_sym_session(env.op, env.sess); > > return 0; > @@ -952,11 +1042,48 @@ prepare_xts_xform(struct rte_crypto_sym_xform *xform) > return 0; > } > > -static void > +static int > get_writeback_data(struct fips_val *val) > { > - val->val = rte_pktmbuf_mtod(env.mbuf, uint8_t *); > - val->len = rte_pktmbuf_pkt_len(env.mbuf); > + struct rte_mbuf *m = env.mbuf; > + uint16_t data_len = rte_pktmbuf_pkt_len(m); > + uint16_t total_len = data_len + env.digest_len; > + uint8_t *src, *dst, *wb_data; > + > + /* in case val is reused for MCT test, try to free the buffer first */ > + if (val->val) { > + free(val->val); > + val->val = NULL; > + } > + > + wb_data = dst = calloc(1, total_len); > + if (!dst) { > + RTE_LOG(ERR, USER1, "Error %i: Not enough memory\n", -ENOMEM); > + return -ENOMEM; > + } > + > + while (m && data_len) { > + uint16_t seg_len = RTE_MIN(rte_pktmbuf_data_len(m), data_len); > + > + src = rte_pktmbuf_mtod(m, uint8_t *); > + memcpy(dst, src, seg_len); > + m = m->next; > + data_len -= seg_len; > + dst += seg_len; > + } > + > + if (data_len) { > + RTE_LOG(ERR, USER1, "Error -1: write back data\n"); > + return -1; > + } > + > + if (env.digest) > + memcpy(dst, env.digest, env.digest_len); > + > + val->val = wb_data; > + val->len = total_len; > + > + return 0; > } > > static int > @@ -1015,7 +1142,7 @@ fips_run_test(void) > static int > fips_generic_test(void) > { > - struct fips_val val; > + struct fips_val val = {NULL, 0}; > int ret; > > fips_test_write_one_case(); > @@ -1030,7 +1157,9 @@ fips_generic_test(void) > return ret; > } > > - get_writeback_data(&val); > + ret = get_writeback_data(&val); > + if (ret < 0) > + return ret; > > switch (info.file_type) { > case FIPS_TYPE_REQ: > @@ -1051,6 +1180,7 @@ fips_generic_test(void) > } > > fprintf(info.fp_wr, "\n"); > + free(val.val); > > return 0; > } > @@ -1061,7 +1191,7 @@ fips_mct_tdes_test(void) > #define TDES_BLOCK_SIZE 8 > #define TDES_EXTERN_ITER 400 > #define TDES_INTERN_ITER 10000 > - struct fips_val val, val_key; > + struct fips_val val = {NULL, 0}, val_key; > uint8_t prev_out[TDES_BLOCK_SIZE] = {0}; > uint8_t prev_prev_out[TDES_BLOCK_SIZE] = {0}; > uint8_t prev_in[TDES_BLOCK_SIZE] = {0}; > @@ -1088,7 +1218,9 @@ fips_mct_tdes_test(void) > return ret; > } > > - get_writeback_data(&val); > + ret = get_writeback_data(&val); > + if (ret < 0) > + return ret; > > if (info.op == FIPS_TEST_DEC_AUTH_VERIF) > memcpy(prev_in, vec.ct.val, TDES_BLOCK_SIZE); > @@ -1215,6 +1347,9 @@ fips_mct_tdes_test(void) > } > } > > + if (val.val) > + free(val.val); > + > return 0; > } > > @@ -1224,7 +1359,7 @@ fips_mct_aes_ecb_test(void) > #define AES_BLOCK_SIZE 16 > #define AES_EXTERN_ITER 100 > #define AES_INTERN_ITER 1000 > - struct fips_val val, val_key; > + struct fips_val val = {NULL, 0}, val_key; > uint8_t prev_out[AES_BLOCK_SIZE] = {0}; > uint32_t i, j, k; > int ret; > @@ -1246,7 +1381,9 @@ fips_mct_aes_ecb_test(void) > return ret; > } > > - get_writeback_data(&val); > + ret = get_writeback_data(&val); > + if (ret < 0) > + return ret; > > if (info.op == FIPS_TEST_ENC_AUTH_GEN) > memcpy(vec.pt.val, val.val, AES_BLOCK_SIZE); > @@ -1290,6 +1427,9 @@ fips_mct_aes_ecb_test(void) > } > } > > + if (val.val) > + free(val.val); > + > return 0; > } > static int > @@ -1298,7 +1438,7 @@ fips_mct_aes_test(void) > #define AES_BLOCK_SIZE 16 > #define AES_EXTERN_ITER 100 > #define AES_INTERN_ITER 1000 > - struct fips_val val, val_key; > + struct fips_val val = {NULL, 0}, val_key; > uint8_t prev_out[AES_BLOCK_SIZE] = {0}; > uint8_t prev_in[AES_BLOCK_SIZE] = {0}; > uint32_t i, j, k; > @@ -1394,6 +1534,9 @@ fips_mct_aes_test(void) > memcpy(vec.iv.val, val.val, AES_BLOCK_SIZE); > } > > + if (val.val) > + free(val.val); > + > return 0; > } > > @@ -1403,7 +1546,7 @@ fips_mct_sha_test(void) > #define SHA_EXTERN_ITER 100 > #define SHA_INTERN_ITER 1000 > #define SHA_MD_BLOCK 3 > - struct fips_val val, md[SHA_MD_BLOCK]; > + struct fips_val val = {NULL, 0}, md[SHA_MD_BLOCK]; > char temp[MAX_DIGEST_SIZE*2]; > int ret; > uint32_t i, j; > @@ -1477,6 +1620,9 @@ fips_mct_sha_test(void) > > rte_free(vec.pt.val); > > + if (val.val) > + free(val.val); > + > return 0; > } > > @@ -1568,7 +1714,6 @@ fips_test_one_file(void) > { > int fetch_ret = 0, ret; > > - > ret = init_test_ops(); > if (ret < 0) { > RTE_LOG(ERR, USER1, "Error %i: Init test op\n", ret); > @@ -1616,6 +1761,10 @@ fips_test_one_file(void) > > fips_test_clear(); > > - return ret; > + if (env.digest) > + rte_free(env.digest); > + if (env.mbuf) > + rte_pktmbuf_free(env.mbuf); > > + return ret; > }