* Re: [PATCH v1] ethdev: fix multi-process NULL dereference crashes
From: Remy Horton @ 2017-01-11 15:01 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
In-Reply-To: <2497925.MaStIBMC1a@xps13>
On 11/01/2017 14:22, Thomas Monjalon wrote:
> 2017-01-11 02:42, Remy Horton:
>> Even though only primary processes should setup PMDs, secondary
>> processes were also blanket zeroing ethernet device memory. The
>> result was NULL dereference crashes in multi-process setups.
>> Fixes: 7f95f78a8aea ("ethdev: clear data when allocating device")
>
> I think it can be fixed by this patch:
>
> http://dpdk.org/ml/archives/dev/2017-January/054220.html
Close call - really depends how the (likley) merge conflict is resolved...
..Remy
^ permalink raw reply
* Re: [PATCH] cryptodev: fix for loop in rte_cryptodev_pmd_get_named_dev
From: De Lara Guarch, Pablo @ 2017-01-11 14:57 UTC (permalink / raw)
To: Trahe, Fiona, Zhang, Roy Fan, dev@dpdk.org; +Cc: stable@dpdk.org
In-Reply-To: <348A99DA5F5B7549AA880327E580B4358916A5F1@IRSMSX101.ger.corp.intel.com>
> -----Original Message-----
> From: Trahe, Fiona
> Sent: Wednesday, January 11, 2017 2:29 PM
> To: Zhang, Roy Fan; dev@dpdk.org
> Cc: De Lara Guarch, Pablo
> Subject: RE: [dpdk-dev] [PATCH] cryptodev: fix for loop in
> rte_cryptodev_pmd_get_named_dev
>
>
>
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Fan Zhang
> > Sent: Wednesday, January 11, 2017 2:10 PM
> > To: dev@dpdk.org
> > Cc: De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>
> > Subject: [dpdk-dev] [PATCH] cryptodev: fix for loop in
> > rte_cryptodev_pmd_get_named_dev
> >
> > Fixes: d11b0f30 ("cryptodev: introduce API and framework for crypto
> > devices")
> >
> > This patch fixes the dev value update problem in
> > rte_cryptodev_pmd_get_named_dev, orginally, dev won't be updated
> > after the initiail step in the loop.
> >
> > Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
> Acked-by: Fiona Trahe <fiona.trahe@intel.com>
CC'ing stable@dpdk.org.
Applied to dpdk-next-crypto.
Thanks,
Pablo
^ permalink raw reply
* Re: [PATCH v8 00/25] Support VFD on i40e
From: Ferruh Yigit @ 2017-01-11 14:53 UTC (permalink / raw)
To: Vincent JARDIN, Zhang, Helin, Lu, Wenzhuo, dev
Cc: 'JOSHI, KAUSTUBH', 'DANIELS, EDWARD',
'ZELEZNIAK, ALEX'
In-Reply-To: <ea5d8fdb-2de3-3dbf-bbb5-5c2099c8c73a@6wind.com>
On 1/11/2017 1:14 PM, Vincent JARDIN wrote:
> Le 10/01/2017 à 22:32, Ferruh Yigit a écrit :
>> What do you think to continue high level DPDK PF discussion in mail
>> thread for other pathset? So that we can continue to work on this one.
>
> First, we need to assess or not if it makes sense to go toward Linux
> kernel or DPDK based PF. If Linux kernel is used, then DPDK does not
> need VFD related modifications.
DPDK PF <--> DPDK VF is already supported. This patchset is not
introducing it.
This patchset adds more PF <-> VF communication to a specific driver,
and this is done in PMD specific way, so update is limited to PMD.
>From my scope, this patchset looks good.
And how assessment can be done, with which quorum, can it be done in a
way without blocking the patchset?
>
> VFD demonstrates that there are some needs of features, but it pushes
> the new path of a fork of PF drivers.
^ permalink raw reply
* Re: [PATCH v8 00/25] Support VFD on i40e
From: JOSHI, KAUSTUBH (KAUSTUBH) @ 2017-01-11 14:51 UTC (permalink / raw)
To: Vincent Jardin
Cc: Zhang, Helin, Lu, Wenzhuo, dev@dpdk.org,
DANIELS, EDWARD S (EDWARD), ZELEZNIAK, ALEX
In-Reply-To: <D7DEE17C-809D-45A8-A505-1DD744A81211@research.att.com>
Also, the kernel drivers have no concept of passing VF messages to upstream "decision making” (or policy enforcement) software like VFd.
On Jan 11, 2017, at 9:49 AM, Kaustubh Joshi <kaustubh@research.att.com<mailto:kaustubh@research.att.com>> wrote:
When Alex from our team started working on Niantic last year, the following were the list of gaps in the kernel drivers we had a need to fill:
Direct traffic to VF based on more than one outer VLAN tags
Optionally strip on ingress (to PF) and insert on egress VLAN tag
Disable/enable MAC and VLAN anti spoofing separately
Mirror traffic from one VF to the other
Enable/Disable local switching per VF
Collect statistics per VF pkts/octets in/out
Enable/disable Mcast/unknown unicast per VF
Manage up to 8 TC per VF with one strict priority queue
Manage per VF per TC bandwidth allocations
Manage LACP status visibility to the VFs (for NIC teaming using SRIOV)
Most of these are VF management functions, and there is no standardized way to do VF management in the kernel drivers. Besides, most of the use-cases around SRIOV need DPDK in the VF anyway (so the target communities are aligned) and the PF DPDK driver for ixgbe already existed, so it made sense to add them there - no forking of the PF driver was involved and there is no additional duplicate code.
Cheers
KJ
On Jan 11, 2017, at 6:03 AM, Vincent Jardin <vincent.jardin@6wind.com<mailto:vincent.jardin@6wind.com>> wrote:
Please can you list the gaps of the Kernel API?
Thank you,
Vincent
Le 11 janvier 2017 3:59:45 AM "JOSHI, KAUSTUBH (KAUSTUBH)" <kaustubh@research.att.com<mailto:kaustubh@research.att.com>> a écrit :
Hi Vincent,
Greetings! Jumping into this debate a bit late, but let me share our point of view based on how we are using this code within AT&T for our NFV cloud.
Actually, we first started with trying to do the configuration within the kernel drivers as you suggest, but quickly realized that besides the practical problem of kernel upstreaming being a much more arduous road (which can be overcome), the bigger problem was that there is no standardization in the configuration interfaces for the NICs in the kernel community. So different drivers do things differently and expose different settings, and no forum exists to drive towards such standardization. This was leading to vendors have to maintain patched versions of drivers for doing PF configuration, which is not a desirable situation.
So, to build a portable (to multiple NICs) SRIOV VF manager like VFd, DPDK seemed like a good a forum with some hope for driving towards a standard set of interfaces and without having to worry about a lot of legacy baggage and old hardware. Especially since DPDK already takes on the role of configuring NICs for the data plane functions anyway - both PF and VF drivers will have to be included for data plane usage anyway - we viewed that adding VF config options will not cause any forking, but simply flush out the DPDK drivers and their interfaces to be more complete. These APIs could be optional, so new vendors aren’t obligated to add them.
Furthermore, allowing VF config using the DPDK PF driver also has the side benefit of allowing a complete SRIOV system (both VF and PF) to be built entirely with DPDK, also making version alignment easier.
We started with Niantic, which already had PF and VF drivers, and things have worked out very well with it. However, we would like VFd to be a multi-NIC vendor agnostic VF management tool, which is why we’ve been asking for making the PF config APIs richer.
Regards
KJ
On Jan 10, 2017, at 3:23 PM, Vincent Jardin <vincent.jardin@6wind.com<mailto:vincent.jardin@6wind.com>> wrote:
Nope. First one needs to assess if DPDK should be intensively used to become a PF knowing Linux can do the jobs. Linux kernel community does not like the forking of Kernel drivers, I tend to agree that we should not keep duplicating options that can be solved with the Linux kernel.
Best regards,
Vincent
^ permalink raw reply
* Re: [PATCH v8 00/25] Support VFD on i40e
From: JOSHI, KAUSTUBH (KAUSTUBH) @ 2017-01-11 14:49 UTC (permalink / raw)
To: Vincent Jardin
Cc: Zhang, Helin, Lu, Wenzhuo, dev@dpdk.org,
DANIELS, EDWARD S (EDWARD), ZELEZNIAK, ALEX
In-Reply-To: <1598d329eb0.27fc.bb328046f2889bc8f44aafa891a44dd2@6wind.com>
When Alex from our team started working on Niantic last year, the following were the list of gaps in the kernel drivers we had a need to fill:
Direct traffic to VF based on more than one outer VLAN tags
Optionally strip on ingress (to PF) and insert on egress VLAN tag
Disable/enable MAC and VLAN anti spoofing separately
Mirror traffic from one VF to the other
Enable/Disable local switching per VF
Collect statistics per VF pkts/octets in/out
Enable/disable Mcast/unknown unicast per VF
Manage up to 8 TC per VF with one strict priority queue
Manage per VF per TC bandwidth allocations
Manage LACP status visibility to the VFs (for NIC teaming using SRIOV)
Most of these are VF management functions, and there is no standardized way to do VF management in the kernel drivers. Besides, most of the use-cases around SRIOV need DPDK in the VF anyway (so the target communities are aligned) and the PF DPDK driver for ixgbe already existed, so it made sense to add them there - no forking of the PF driver was involved and there is no additional duplicate code.
Cheers
KJ
On Jan 11, 2017, at 6:03 AM, Vincent Jardin <vincent.jardin@6wind.com<mailto:vincent.jardin@6wind.com>> wrote:
Please can you list the gaps of the Kernel API?
Thank you,
Vincent
Le 11 janvier 2017 3:59:45 AM "JOSHI, KAUSTUBH (KAUSTUBH)" <kaustubh@research.att.com<mailto:kaustubh@research.att.com>> a écrit :
Hi Vincent,
Greetings! Jumping into this debate a bit late, but let me share our point of view based on how we are using this code within AT&T for our NFV cloud.
Actually, we first started with trying to do the configuration within the kernel drivers as you suggest, but quickly realized that besides the practical problem of kernel upstreaming being a much more arduous road (which can be overcome), the bigger problem was that there is no standardization in the configuration interfaces for the NICs in the kernel community. So different drivers do things differently and expose different settings, and no forum exists to drive towards such standardization. This was leading to vendors have to maintain patched versions of drivers for doing PF configuration, which is not a desirable situation.
So, to build a portable (to multiple NICs) SRIOV VF manager like VFd, DPDK seemed like a good a forum with some hope for driving towards a standard set of interfaces and without having to worry about a lot of legacy baggage and old hardware. Especially since DPDK already takes on the role of configuring NICs for the data plane functions anyway - both PF and VF drivers will have to be included for data plane usage anyway - we viewed that adding VF config options will not cause any forking, but simply flush out the DPDK drivers and their interfaces to be more complete. These APIs could be optional, so new vendors aren’t obligated to add them.
Furthermore, allowing VF config using the DPDK PF driver also has the side benefit of allowing a complete SRIOV system (both VF and PF) to be built entirely with DPDK, also making version alignment easier.
We started with Niantic, which already had PF and VF drivers, and things have worked out very well with it. However, we would like VFd to be a multi-NIC vendor agnostic VF management tool, which is why we’ve been asking for making the PF config APIs richer.
Regards
KJ
On Jan 10, 2017, at 3:23 PM, Vincent Jardin <vincent.jardin@6wind.com<mailto:vincent.jardin@6wind.com>> wrote:
Nope. First one needs to assess if DPDK should be intensively used to become a PF knowing Linux can do the jobs. Linux kernel community does not like the forking of Kernel drivers, I tend to agree that we should not keep duplicating options that can be solved with the Linux kernel.
Best regards,
Vincent
^ permalink raw reply
* Re: [dpdk-stable] [PATCH 1/2] net/virtio: fix performance regression due to TSO enabling
From: Thomas Monjalon @ 2017-01-11 14:51 UTC (permalink / raw)
To: Yuanhan Liu, Jianbo Liu, Jerin Jacob, Jan Viktorin, Chao Zhu
Cc: dev, Tan Jianfeng, Wang Zhihong, Olivier Matz, Maxime Coquelin,
Michael S. Tsirkin
In-Reply-To: <1484108832-19907-2-git-send-email-yuanhan.liu@linux.intel.com>
2017-01-11 12:27, Yuanhan Liu:
> The fact that virtio net header is initiated to zero in PMD driver
> init stage means that these costly writes are unnecessary and could
> be avoided:
>
> if (hdr->csum_start != 0)
> hdr->csum_start = 0;
>
> And that's what the macro ASSIGN_UNLESS_EQUAL does. With this, the
> performance drop introduced by TSO enabling is recovered: it could
> be up to 20% in micro benchmarking.
This patch is adding a condition to assignments.
We need a benchmark on other architectures like ARM. Please anyone?
[...]
> +/* avoid write operation when necessary, to lessen cache issues */
> +#define ASSIGN_UNLESS_EQUAL(var, val) do { \
> + if ((var) != (val)) \
> + (var) = (val); \
> +} while (0)
^ permalink raw reply
* Re: [PATCH 8/8] eal: VMBUS infrastructure
From: Jan Blunck @ 2017-01-11 14:49 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev, Stephen Hemminger
In-Reply-To: <20170107181756.1944-9-sthemmin@microsoft.com>
On Sat, Jan 7, 2017 at 7:17 PM, Stephen Hemminger
<stephen@networkplumber.org> wrote:
> Add support for VMBUS on Hyper-V/Azure. VMBUS is similar to PCI
> but has different addressing and internal API's.
>
> Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
> ---
> lib/librte_eal/common/Makefile | 2 +-
> lib/librte_eal/common/eal_common_devargs.c | 7 +
> lib/librte_eal/common/eal_common_options.c | 38 ++
> lib/librte_eal/common/eal_internal_cfg.h | 1 +
> lib/librte_eal/common/eal_options.h | 6 +
> lib/librte_eal/common/eal_private.h | 5 +
> lib/librte_eal/common/include/rte_devargs.h | 8 +
> lib/librte_eal/common/include/rte_vmbus.h | 249 ++++++++
> lib/librte_eal/linuxapp/eal/Makefile | 6 +
> lib/librte_eal/linuxapp/eal/eal.c | 13 +
> lib/librte_eal/linuxapp/eal/eal_vmbus.c | 911 ++++++++++++++++++++++++++++
> lib/librte_ether/rte_ethdev.c | 90 +++
> lib/librte_ether/rte_ethdev.h | 31 +
> mk/rte.app.mk | 1 +
> 14 files changed, 1367 insertions(+), 1 deletion(-)
> create mode 100644 lib/librte_eal/common/include/rte_vmbus.h
> create mode 100644 lib/librte_eal/linuxapp/eal/eal_vmbus.c
>
> diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
> index 09a3d3af..ceb77bed 100644
> --- a/lib/librte_eal/common/Makefile
> +++ b/lib/librte_eal/common/Makefile
> @@ -33,7 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
>
> INC := rte_branch_prediction.h rte_common.h
> INC += rte_debug.h rte_eal.h rte_errno.h rte_launch.h rte_lcore.h
> -INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h
> +INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h rte_vmbus.h
> INC += rte_per_lcore.h rte_random.h
> INC += rte_tailq.h rte_interrupts.h rte_alarm.h
> INC += rte_string_fns.h rte_version.h
> diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c
> index e403717b..934ca840 100644
> --- a/lib/librte_eal/common/eal_common_devargs.c
> +++ b/lib/librte_eal/common/eal_common_devargs.c
> @@ -113,6 +113,13 @@ rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str)
> goto fail;
>
> break;
> + case RTE_DEVTYPE_WHITELISTED_VMBUS:
> + case RTE_DEVTYPE_BLACKLISTED_VMBUS:
> +#ifdef RTE_LIBRTE_HV_PMD
> + if (uuid_parse(buf, devargs->uuid) == 0)
> + break;
> +#endif
> + goto fail;
> }
>
> free(buf);
> diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
> index f36bc556..1a2b418c 100644
> --- a/lib/librte_eal/common/eal_common_options.c
> +++ b/lib/librte_eal/common/eal_common_options.c
> @@ -95,6 +95,11 @@ eal_long_options[] = {
> {OPT_VFIO_INTR, 1, NULL, OPT_VFIO_INTR_NUM },
> {OPT_VMWARE_TSC_MAP, 0, NULL, OPT_VMWARE_TSC_MAP_NUM },
> {OPT_XEN_DOM0, 0, NULL, OPT_XEN_DOM0_NUM },
> +#ifdef RTE_LIBRTE_HV_PMD
> + {OPT_NO_VMBUS, 0, NULL, OPT_NO_VMBUS_NUM },
> + {OPT_VMBUS_BLACKLIST, 1, NULL, OPT_VMBUS_BLACKLIST_NUM },
> + {OPT_VMBUS_WHITELIST, 1, NULL, OPT_VMBUS_WHITELIST_NUM },
> +#endif
> {0, 0, NULL, 0 }
> };
>
> @@ -858,6 +863,21 @@ eal_parse_common_option(int opt, const char *optarg,
> conf->no_pci = 1;
> break;
>
> +#ifdef RTE_LIBRTE_HV_PMD
> + case OPT_NO_VMBUS_NUM:
> + conf->no_vmbus = 1;
> + break;
> + case OPT_VMBUS_BLACKLIST_NUM:
> + if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_VMBUS,
> + optarg) < 0)
> + return -1;
> + break;
> + case OPT_VMBUS_WHITELIST_NUM:
> + if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_VMBUS,
> + optarg) < 0)
> + return -1;
> + break;
> +#endif
> case OPT_NO_HPET_NUM:
> conf->no_hpet = 1;
> break;
> @@ -1017,6 +1037,14 @@ eal_check_common_options(struct internal_config *internal_cfg)
> return -1;
> }
>
> +#ifdef RTE_LIBRTE_HV_PMD
> + if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_VMBUS) != 0 &&
> + rte_eal_devargs_type_count(RTE_DEVTYPE_BLACKLISTED_VMBUS) != 0) {
> + RTE_LOG(ERR, EAL, "Options vmbus blacklist and whitelist "
> + "cannot be used at the same time\n");
> + return -1;
> + }
> +#endif
> return 0;
> }
>
> @@ -1066,5 +1094,15 @@ eal_common_usage(void)
> " --"OPT_NO_PCI" Disable PCI\n"
> " --"OPT_NO_HPET" Disable HPET\n"
> " --"OPT_NO_SHCONF" No shared config (mmap'd files)\n"
> +#ifdef RTE_LIBRTE_HV_PMD
> + " --"OPT_NO_VMBUS" Disable VMBUS\n"
> + " --"OPT_VMBUS_BLACKLIST" Add a VMBUS device to black list.\n"
> + " Prevent EAL from using this PCI device. The argument\n"
> + " format is device UUID.\n"
> + " --"OPT_VMBUS_WHITELIST" Add a VMBUS device to white list.\n"
> + " Only use the specified VMBUS devices. The argument format\n"
> + " is device UUID This option can be present\n"
> + " several times (once per device).\n"
> +#endif
> "\n", RTE_MAX_LCORE);
> }
> diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
> index 5f1367eb..4b6af937 100644
> --- a/lib/librte_eal/common/eal_internal_cfg.h
> +++ b/lib/librte_eal/common/eal_internal_cfg.h
> @@ -67,6 +67,7 @@ struct internal_config {
> unsigned hugepage_unlink; /**< true to unlink backing files */
> volatile unsigned xen_dom0_support; /**< support app running on Xen Dom0*/
> volatile unsigned no_pci; /**< true to disable PCI */
> + volatile unsigned no_vmbus; /**< true to disable VMBUS */
> volatile unsigned no_hpet; /**< true to disable HPET */
> volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
> * instead of native TSC */
> diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
> index a881c62e..156727e7 100644
> --- a/lib/librte_eal/common/eal_options.h
> +++ b/lib/librte_eal/common/eal_options.h
> @@ -83,6 +83,12 @@ enum {
> OPT_VMWARE_TSC_MAP_NUM,
> #define OPT_XEN_DOM0 "xen-dom0"
> OPT_XEN_DOM0_NUM,
> +#define OPT_NO_VMBUS "no-vmbus"
> + OPT_NO_VMBUS_NUM,
> +#define OPT_VMBUS_BLACKLIST "vmbus-blacklist"
> + OPT_VMBUS_BLACKLIST_NUM,
> +#define OPT_VMBUS_WHITELIST "vmbus-whitelist"
> + OPT_VMBUS_WHITELIST_NUM,
> OPT_LONG_MAX_NUM
> };
>
> diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
> index 9e7d8f6b..c856c63e 100644
> --- a/lib/librte_eal/common/eal_private.h
> +++ b/lib/librte_eal/common/eal_private.h
> @@ -210,6 +210,11 @@ int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
> struct mapped_pci_resource *uio_res, int map_idx);
>
> /**
> + * VMBUS related functions and structures
> + */
> +int rte_eal_vmbus_init(void);
> +
> +/**
> * Init tail queues for non-EAL library structures. This is to allow
> * the rings, mempools, etc. lists to be shared among multiple processes
> *
> diff --git a/lib/librte_eal/common/include/rte_devargs.h b/lib/librte_eal/common/include/rte_devargs.h
> index 88120a1c..c079d289 100644
> --- a/lib/librte_eal/common/include/rte_devargs.h
> +++ b/lib/librte_eal/common/include/rte_devargs.h
> @@ -51,6 +51,9 @@ extern "C" {
> #include <stdio.h>
> #include <sys/queue.h>
> #include <rte_pci.h>
> +#ifdef RTE_LIBRTE_HV_PMD
> +#include <uuid/uuid.h>
> +#endif
>
> /**
> * Type of generic device
> @@ -59,6 +62,8 @@ enum rte_devtype {
> RTE_DEVTYPE_WHITELISTED_PCI,
> RTE_DEVTYPE_BLACKLISTED_PCI,
> RTE_DEVTYPE_VIRTUAL,
> + RTE_DEVTYPE_WHITELISTED_VMBUS,
> + RTE_DEVTYPE_BLACKLISTED_VMBUS,
> };
>
> /**
> @@ -88,6 +93,9 @@ struct rte_devargs {
> /** Driver name. */
> char drv_name[32];
> } virt;
> +#ifdef RTE_LIBRTE_HV_PMD
> + uuid_t uuid;
> +#endif
> };
> /** Arguments string as given by user or "" for no argument. */
> char *args;
> diff --git a/lib/librte_eal/common/include/rte_vmbus.h b/lib/librte_eal/common/include/rte_vmbus.h
> new file mode 100644
> index 00000000..f96d753e
> --- /dev/null
> +++ b/lib/librte_eal/common/include/rte_vmbus.h
> @@ -0,0 +1,249 @@
> +/*-
> + * BSD LICENSE
> + *
> + * Copyright(c) 2013-2016 Brocade Communications Systems, Inc.
> + * Copyright(c) 2016 Microsoft Corporation
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * * Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * * Redistributions in binary form must reproduce the above copyright
> + * notice, this list of conditions and the following disclaimer in
> + * the documentation and/or other materials provided with the
> + * distribution.
> + * * Neither the name of Intel Corporation nor the names of its
> + * contributors may be used to endorse or promote products derived
> + * from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + *
> + */
> +
> +#ifndef _RTE_VMBUS_H_
> +#define _RTE_VMBUS_H_
> +
> +/**
> + * @file
> + *
> + * RTE VMBUS Interface
> + */
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <limits.h>
> +#include <errno.h>
> +#include <uuid/uuid.h>
> +#include <sys/queue.h>
> +#include <stdint.h>
> +#include <inttypes.h>
> +
> +#include <rte_debug.h>
> +#include <rte_interrupts.h>
> +#include <rte_dev.h>
> +
> +TAILQ_HEAD(vmbus_device_list, rte_vmbus_device);
> +TAILQ_HEAD(vmbus_driver_list, rte_vmbus_driver);
> +
> +extern struct vmbus_driver_list vmbus_driver_list;
> +extern struct vmbus_device_list vmbus_device_list;
> +
> +/** Pathname of VMBUS devices directory. */
> +#define SYSFS_VMBUS_DEVICES "/sys/bus/vmbus/devices"
> +
> +#define UUID_BUF_SZ (36 + 1)
> +
> +
> +/** Maximum number of VMBUS resources. */
> +#define VMBUS_MAX_RESOURCE 7
> +
> +/**
> + * A structure describing a VMBUS device.
> + */
> +struct rte_vmbus_device {
> + TAILQ_ENTRY(rte_vmbus_device) next; /**< Next probed VMBUS device. */
> + struct rte_device device; /**< Inherit core device */
> + uuid_t device_id; /**< VMBUS device id */
> + uuid_t class_id; /**< VMBUS device type */
> + uint32_t relid; /**< VMBUS id for notification */
> + uint8_t monitor_id;
> + struct rte_intr_handle intr_handle; /**< Interrupt handle */
> + const struct rte_vmbus_driver *driver; /**< Associated driver */
> +
> + struct rte_mem_resource mem_resource[VMBUS_MAX_RESOURCE];
> + /**< VMBUS Memory Resource */
> + char sysfs_name[]; /**< Name in sysfs bus directory */
> +};
> +
> +struct rte_vmbus_driver;
> +
> +/**
> + * Initialisation function for the driver called during VMBUS probing.
> + */
> +typedef int (vmbus_probe_t)(struct rte_vmbus_driver *,
> + struct rte_vmbus_device *);
> +
> +/**
> + * Uninitialisation function for the driver called during hotplugging.
> + */
> +typedef int (vmbus_remove_t)(struct rte_vmbus_device *);
> +
> +/**
> + * A structure describing a VMBUS driver.
> + */
> +struct rte_vmbus_driver {
> + TAILQ_ENTRY(rte_vmbus_driver) next; /**< Next in list. */
> + struct rte_driver driver;
> + vmbus_probe_t *probe; /**< Device Probe function. */
> + vmbus_remove_t *remove; /**< Device Remove function. */
> +
> + const uuid_t *id_table; /**< ID table. */
> +};
> +
> +struct vmbus_map {
> + void *addr;
> + char *path;
> + uint64_t offset;
> + uint64_t size;
> + uint64_t phaddr;
> +};
> +
> +/*
> + * For multi-process we need to reproduce all vmbus mappings in secondary
> + * processes, so save them in a tailq.
> + */
> +struct mapped_vmbus_resource {
> + TAILQ_ENTRY(mapped_vmbus_resource) next;
> +
> + uuid_t uuid;
> + char path[PATH_MAX];
> + int nb_maps;
> + struct vmbus_map maps[VMBUS_MAX_RESOURCE];
> +};
> +
> +TAILQ_HEAD(mapped_vmbus_res_list, mapped_vmbus_resource);
> +
> +/**
> + * Scan the content of the VMBUS bus, and the devices in the devices list
> + *
> + * @return
> + * 0 on success, negative on error
> + */
> +int rte_eal_vmbus_scan(void);
> +
> +/**
> + * Probe the VMBUS bus for registered drivers.
> + *
> + * Scan the content of the VMBUS bus, and call the probe() function for
> + * all registered drivers that have a matching entry in its id_table
> + * for discovered devices.
> + *
> + * @return
> + * - 0 on success.
> + * - Negative on error.
> + */
> +int rte_eal_vmbus_probe(void);
> +
> +/**
> + * Map the VMBUS device resources in user space virtual memory address
> + *
> + * @param dev
> + * A pointer to a rte_vmbus_device structure describing the device
> + * to use
> + *
> + * @return
> + * 0 on success, negative on error and positive if no driver
> + * is found for the device.
> + */
> +int rte_eal_vmbus_map_device(struct rte_vmbus_device *dev);
> +
> +/**
> + * Unmap this device
> + *
> + * @param dev
> + * A pointer to a rte_vmbus_device structure describing the device
> + * to use
> + */
> +void rte_eal_vmbus_unmap_device(struct rte_vmbus_device *dev);
> +
> +/**
> + * Probe the single VMBUS device.
> + *
> + * Scan the content of the VMBUS bus, and find the vmbus device
> + * specified by device uuid, then call the probe() function for
> + * registered driver that has a matching entry in its id_table for
> + * discovered device.
> + *
> + * @param id
> + * The VMBUS device uuid.
> + * @return
> + * - 0 on success.
> + * - Negative on error.
> + */
> +int rte_eal_vmbus_probe_one(uuid_t id);
> +
> +/**
> + * Close the single VMBUS device.
> + *
> + * Scan the content of the VMBUS bus, and find the vmbus device id,
> + * then call the remove() function for registered driver that has a
> + * matching entry in its id_table for discovered device.
> + *
> + * @param id
> + * The VMBUS device uuid.
> + * @return
> + * - 0 on success.
> + * - Negative on error.
> + */
> +int rte_eal_vmbus_detach(uuid_t id);
> +
> +/**
> + * Register a VMBUS driver.
> + *
> + * @param driver
> + * A pointer to a rte_vmbus_driver structure describing the driver
> + * to be registered.
> + */
> +void rte_eal_vmbus_register(struct rte_vmbus_driver *driver);
> +
> +/** Helper for VMBUS device registration from driver nstance */
> +#define RTE_PMD_REGISTER_VMBUS(nm, vmbus_drv) \
> +RTE_INIT(vmbusinitfn_ ##nm); \
> +static void vmbusinitfn_ ##nm(void) \
> +{\
> + (vmbus_drv).driver.name = RTE_STR(nm);\
> + (vmbus_drv).driver.type = PMD_VMBUS; \
> + rte_eal_vmbus_register(&vmbus_drv); \
> +} \
> +RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
> +
> +/**
> + * Unregister a VMBUS driver.
> + *
> + * @param driver
> + * A pointer to a rte_vmbus_driver structure describing the driver
> + * to be unregistered.
> + */
> +void rte_eal_vmbus_unregister(struct rte_vmbus_driver *driver);
The register/unregister need to get exported via the map file too.
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _RTE_VMBUS_H_ */
> diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
> index 4e206f09..f6ca3848 100644
> --- a/lib/librte_eal/linuxapp/eal/Makefile
> +++ b/lib/librte_eal/linuxapp/eal/Makefile
> @@ -71,6 +71,11 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_timer.c
> SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_interrupts.c
> SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_alarm.c
>
> +ifeq ($(CONFIG_RTE_LIBRTE_HV_PMD),y)
> +SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_vmbus.c
> +LDLIBS += -luuid
> +endif
> +
> # from common dir
> SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_lcore.c
> SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c
> @@ -114,6 +119,7 @@ CFLAGS_eal_hugepage_info.o := -D_GNU_SOURCE
> CFLAGS_eal_pci.o := -D_GNU_SOURCE
> CFLAGS_eal_pci_uio.o := -D_GNU_SOURCE
> CFLAGS_eal_pci_vfio.o := -D_GNU_SOURCE
> +CFLAGS_eal_vmbux.o := -D_GNU_SOURCE
> CFLAGS_eal_common_whitelist.o := -D_GNU_SOURCE
> CFLAGS_eal_common_options.o := -D_GNU_SOURCE
> CFLAGS_eal_common_thread.o := -D_GNU_SOURCE
> diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
> index 16dd5b9c..1bc0814a 100644
> --- a/lib/librte_eal/linuxapp/eal/eal.c
> +++ b/lib/librte_eal/linuxapp/eal/eal.c
> @@ -70,6 +70,9 @@
> #include <rte_cpuflags.h>
> #include <rte_interrupts.h>
> #include <rte_pci.h>
> +#ifdef RTE_LIBRTE_HV_PMD
> +#include <rte_vmbus.h>
> +#endif
> #include <rte_dev.h>
> #include <rte_devargs.h>
> #include <rte_common.h>
> @@ -830,6 +833,11 @@ rte_eal_init(int argc, char **argv)
>
> eal_check_mem_on_local_socket();
>
> +#ifdef RTE_LIBRTE_HV_PMD
> + if (rte_eal_vmbus_init() < 0)
> + RTE_LOG(ERR, EAL, "Cannot init VMBUS\n");
> +#endif
> +
> if (eal_plugins_init() < 0)
> rte_panic("Cannot init plugins\n");
>
> @@ -884,6 +892,11 @@ rte_eal_init(int argc, char **argv)
> if (rte_eal_pci_probe())
> rte_panic("Cannot probe PCI\n");
>
> +#ifdef RTE_LIBRTE_HV_PMD
> + if (rte_eal_vmbus_probe() < 0)
> + rte_panic("Cannot probe VMBUS\n");
> +#endif
> +
> if (rte_eal_dev_init() < 0)
> rte_panic("Cannot init pmd devices\n");
>
> diff --git a/lib/librte_eal/linuxapp/eal/eal_vmbus.c b/lib/librte_eal/linuxapp/eal/eal_vmbus.c
> new file mode 100644
> index 00000000..729f93a9
> --- /dev/null
> +++ b/lib/librte_eal/linuxapp/eal/eal_vmbus.c
> @@ -0,0 +1,911 @@
> +/*-
> + * BSD LICENSE
> + *
> + * Copyright(c) 2013-2016 Brocade Communications Systems, Inc.
> + * Copyright(c) 2016 Microsoft Corporation
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * * Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * * Redistributions in binary form must reproduce the above copyright
> + * notice, this list of conditions and the following disclaimer in
> + * the documentation and/or other materials provided with the
> + * distribution.
> + * * Neither the name of Intel Corporation nor the names of its
> + * contributors may be used to endorse or promote products derived
> + * from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + *
> + */
> +
> +#include <string.h>
> +#include <unistd.h>
> +#include <dirent.h>
> +#include <fcntl.h>
> +#include <sys/mman.h>
> +
> +#include <rte_eal.h>
> +#include <rte_tailq.h>
> +#include <rte_log.h>
> +#include <rte_devargs.h>
> +#include <rte_vmbus.h>
> +#include <rte_malloc.h>
> +
> +#include "eal_private.h"
> +#include "eal_pci_init.h"
> +#include "eal_filesystem.h"
> +
> +struct vmbus_driver_list vmbus_driver_list =
> + TAILQ_HEAD_INITIALIZER(vmbus_driver_list);
> +struct vmbus_device_list vmbus_device_list =
> + TAILQ_HEAD_INITIALIZER(vmbus_device_list);
> +
> +static void *vmbus_map_addr;
> +
> +static struct rte_tailq_elem rte_vmbus_uio_tailq = {
> + .name = "UIO_RESOURCE_LIST",
> +};
> +EAL_REGISTER_TAILQ(rte_vmbus_uio_tailq);
> +
> +/*
> + * parse a sysfs file containing one integer value
> + * different to the eal version, as it needs to work with 64-bit values
> + */
> +static int
> +vmbus_get_sysfs_uuid(const char *filename, uuid_t uu)
> +{
> + char buf[BUFSIZ];
> + char *cp, *in = buf;
> + FILE *f;
> +
> + f = fopen(filename, "r");
> + if (f == NULL) {
> + RTE_LOG(ERR, EAL, "%s(): cannot open sysfs value %s\n",
> + __func__, filename);
> + return -1;
> + }
> +
> + if (fgets(buf, sizeof(buf), f) == NULL) {
> + RTE_LOG(ERR, EAL, "%s(): cannot read sysfs value %s\n",
> + __func__, filename);
> + fclose(f);
> + return -1;
> + }
> + fclose(f);
> +
> + cp = strchr(buf, '\n');
> + if (cp)
> + *cp = '\0';
> +
> + /* strip { } notation */
> + if (buf[0] == '{') {
> + in = buf + 1;
> + cp = strchr(in, '}');
> + if (cp)
> + *cp = '\0';
> + }
> +
> + if (uuid_parse(in, uu) < 0) {
> + RTE_LOG(ERR, EAL, "%s %s not a valid UUID\n",
> + filename, buf);
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +/* map a particular resource from a file */
> +static void *
> +vmbus_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
> + int flags)
> +{
> + void *mapaddr;
> +
> + /* Map the memory resource of device */
> + mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
> + MAP_SHARED | flags, fd, offset);
> + if (mapaddr == MAP_FAILED ||
> + (requested_addr != NULL && mapaddr != requested_addr)) {
> + RTE_LOG(ERR, EAL,
> + "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s)\n",
> + __func__, fd, requested_addr,
> + (unsigned long)size, (unsigned long)offset,
> + strerror(errno));
> + } else
> + RTE_LOG(DEBUG, EAL, " VMBUS memory mapped at %p\n", mapaddr);
> +
> + return mapaddr;
> +}
> +
> +/* unmap a particular resource */
> +static void
> +vmbus_unmap_resource(void *requested_addr, size_t size)
> +{
> + if (requested_addr == NULL)
> + return;
> +
> + /* Unmap the VMBUS memory resource of device */
> + if (munmap(requested_addr, size)) {
> + RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
> + __func__, requested_addr, (unsigned long)size,
> + strerror(errno));
> + } else
> + RTE_LOG(DEBUG, EAL, " VMBUS memory unmapped at %p\n",
> + requested_addr);
> +}
> +
> +/* Only supports current kernel version
> + * Unlike PCI there is no option (or need) to create UIO device.
> + */
> +static int vmbus_get_uio_dev(const char *name,
> + char *dstbuf, size_t buflen)
> +{
> + char dirname[PATH_MAX];
> + unsigned int uio_num;
> + struct dirent *e;
> + DIR *dir;
> +
> + snprintf(dirname, sizeof(dirname),
> + "/sys/bus/vmbus/devices/%s/uio", name);
> +
> + dir = opendir(dirname);
> + if (dir == NULL) {
> + RTE_LOG(ERR, EAL, "Cannot map uio resources for %s: %s\n",
> + name, strerror(errno));
> + return -1;
> + }
> +
> + /* take the first file starting with "uio" */
> + while ((e = readdir(dir)) != NULL) {
> + if (sscanf(e->d_name, "uio%u", &uio_num) != 1)
> + continue;
> +
> + snprintf(dstbuf, buflen, "%s/uio%u", dirname, uio_num);
> + break;
> + }
> + closedir(dir);
> +
> + return e ? (int) uio_num : -1;
> +}
> +
> +/*
> + * parse a sysfs file containing one integer value
> + * different to the eal version, as it needs to work with 64-bit values
> + */
> +static int
> +vmbus_parse_sysfs_value(const char *dir, const char *name,
> + uint64_t *val)
> +{
> + char filename[PATH_MAX];
> + FILE *f;
> + char buf[BUFSIZ];
> + char *end = NULL;
> +
> + snprintf(filename, sizeof(filename), "%s/%s", dir, name);
> + f = fopen(filename, "r");
> + if (f == NULL) {
> + RTE_LOG(ERR, EAL, "%s(): cannot open sysfs value %s\n",
> + __func__, filename);
> + return -1;
> + }
> +
> + if (fgets(buf, sizeof(buf), f) == NULL) {
> + RTE_LOG(ERR, EAL, "%s(): cannot read sysfs value %s\n",
> + __func__, filename);
> + fclose(f);
> + return -1;
> + }
> + fclose(f);
> +
> + *val = strtoull(buf, &end, 0);
> + if ((buf[0] == '\0') || (end == NULL) || (*end != '\n')) {
> + RTE_LOG(ERR, EAL, "%s(): cannot parse sysfs value %s\n",
> + __func__, filename);
> + return -1;
> + }
> + return 0;
> +}
> +
> +/* Get mappings out of values provided by uio */
> +static int
> +vmbus_uio_get_mappings(const char *uioname,
> + struct vmbus_map maps[])
> +{
> + int i;
> +
> + for (i = 0; i != VMBUS_MAX_RESOURCE; i++) {
> + struct vmbus_map *map = &maps[i];
> + char dirname[PATH_MAX];
> +
> + /* check if map directory exists */
> + snprintf(dirname, sizeof(dirname),
> + "%s/maps/map%d", uioname, i);
> +
> + if (access(dirname, F_OK) != 0)
> + break;
> +
> + /* get mapping offset */
> + if (vmbus_parse_sysfs_value(dirname, "offset",
> + &map->offset) < 0)
> + return -1;
> +
> + /* get mapping size */
> + if (vmbus_parse_sysfs_value(dirname, "size",
> + &map->size) < 0)
> + return -1;
> +
> + /* get mapping physical address */
> + if (vmbus_parse_sysfs_value(dirname, "addr",
> + &maps->phaddr) < 0)
> + return -1;
> + }
> +
> + return i;
> +}
> +
> +static void
> +vmbus_uio_free_resource(struct rte_vmbus_device *dev,
> + struct mapped_vmbus_resource *uio_res)
> +{
> + rte_free(uio_res);
> +
> + if (dev->intr_handle.fd) {
> + close(dev->intr_handle.fd);
> + dev->intr_handle.fd = -1;
> + dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
> + }
> +}
> +
> +static struct mapped_vmbus_resource *
> +vmbus_uio_alloc_resource(struct rte_vmbus_device *dev)
> +{
> + struct mapped_vmbus_resource *uio_res;
> + char dirname[PATH_MAX], devname[PATH_MAX];
> + int uio_num, nb_maps;
> +
> + uio_num = vmbus_get_uio_dev(dev->sysfs_name, dirname, sizeof(dirname));
> + if (uio_num < 0) {
> + RTE_LOG(WARNING, EAL,
> + " %s not managed by UIO driver, skipping\n",
> + dev->sysfs_name);
> + return NULL;
> + }
> +
> + /* allocate the mapping details for secondary processes*/
> + uio_res = rte_zmalloc("UIO_RES", sizeof(*uio_res), 0);
> + if (uio_res == NULL) {
> + RTE_LOG(ERR, EAL,
> + "%s(): cannot store uio mmap details\n", __func__);
> + goto error;
> + }
> +
> + snprintf(devname, sizeof(devname), "/dev/uio%u", uio_num);
> + dev->intr_handle.fd = open(devname, O_RDWR);
> + if (dev->intr_handle.fd < 0) {
> + RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
> + devname, strerror(errno));
> + goto error;
> + }
> +
> + dev->intr_handle.type = RTE_INTR_HANDLE_UIO_INTX;
> +
> + snprintf(uio_res->path, sizeof(uio_res->path), "%s", devname);
> + uuid_copy(uio_res->uuid, dev->device_id);
> +
> + nb_maps = vmbus_uio_get_mappings(dirname, uio_res->maps);
> + if (nb_maps < 0)
> + goto error;
> +
> + RTE_LOG(DEBUG, EAL, "Found %d memory maps for device %s\n",
> + nb_maps, dev->sysfs_name);
> +
> + return uio_res;
> +
> + error:
> + vmbus_uio_free_resource(dev, uio_res);
> + return NULL;
> +}
> +
> +static int
> +vmbus_uio_map_resource_by_index(struct rte_vmbus_device *dev,
> + unsigned int res_idx,
> + struct mapped_vmbus_resource *uio_res,
> + unsigned int map_idx)
> +{
> + struct vmbus_map *maps = uio_res->maps;
> + char devname[PATH_MAX];
> + void *mapaddr;
> + int fd;
> +
> + snprintf(devname, sizeof(devname),
> + "/sys/bus/vmbus/%s/resource%u", dev->sysfs_name, res_idx);
> +
> + fd = open(devname, O_RDWR);
> + if (fd < 0) {
> + RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
> + devname, strerror(errno));
> + return -1;
> + }
> +
> + /* allocate memory to keep path */
> + maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
> + if (maps[map_idx].path == NULL) {
> + RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
> + strerror(errno));
> + return -1;
> + }
> +
> + /* try mapping somewhere close to the end of hugepages */
> + if (vmbus_map_addr == NULL)
> + vmbus_map_addr = pci_find_max_end_va();
> +
> + mapaddr = vmbus_map_resource(vmbus_map_addr, fd, 0,
> + dev->mem_resource[res_idx].len, 0);
> + close(fd);
> + if (mapaddr == MAP_FAILED) {
> + rte_free(maps[map_idx].path);
> + return -1;
> + }
> +
> + vmbus_map_addr = RTE_PTR_ADD(mapaddr,
> + dev->mem_resource[res_idx].len);
> +
> + maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
> + maps[map_idx].size = dev->mem_resource[res_idx].len;
> + maps[map_idx].addr = mapaddr;
> + maps[map_idx].offset = 0;
> + strcpy(maps[map_idx].path, devname);
> + dev->mem_resource[res_idx].addr = mapaddr;
> +
> + return 0;
> +}
> +
> +static void
> +vmbus_uio_unmap(struct mapped_vmbus_resource *uio_res)
> +{
> + int i;
> +
> + if (uio_res == NULL)
> + return;
> +
> + for (i = 0; i != uio_res->nb_maps; i++) {
> + vmbus_unmap_resource(uio_res->maps[i].addr,
> + uio_res->maps[i].size);
> +
> + if (rte_eal_process_type() == RTE_PROC_PRIMARY)
> + rte_free(uio_res->maps[i].path);
> + }
> +}
> +
> +static struct mapped_vmbus_resource *
> +vmbus_uio_find_resource(struct rte_vmbus_device *dev)
> +{
> + struct mapped_vmbus_resource *uio_res;
> + struct mapped_vmbus_res_list *uio_res_list =
> + RTE_TAILQ_CAST(rte_vmbus_uio_tailq.head,
> + mapped_vmbus_res_list);
> +
> + if (dev == NULL)
> + return NULL;
> +
> + TAILQ_FOREACH(uio_res, uio_res_list, next) {
> + if (uuid_compare(uio_res->uuid, dev->device_id) == 0)
> + return uio_res;
> + }
> + return NULL;
> +}
> +
> +/* unmap the VMBUS resource of a VMBUS device in virtual memory */
> +static void
> +vmbus_uio_unmap_resource(struct rte_vmbus_device *dev)
> +{
> + struct mapped_vmbus_resource *uio_res;
> + struct mapped_vmbus_res_list *uio_res_list =
> + RTE_TAILQ_CAST(rte_vmbus_uio_tailq.head,
> + mapped_vmbus_res_list);
> +
> + if (dev == NULL)
> + return;
> +
> + /* find an entry for the device */
> + uio_res = vmbus_uio_find_resource(dev);
> + if (uio_res == NULL)
> + return;
> +
> + /* secondary processes - just free maps */
> + if (rte_eal_process_type() != RTE_PROC_PRIMARY)
> + return vmbus_uio_unmap(uio_res);
> +
> + TAILQ_REMOVE(uio_res_list, uio_res, next);
> +
> + /* unmap all resources */
> + vmbus_uio_unmap(uio_res);
> +
> + /* free uio resource */
> + rte_free(uio_res);
> +
> + /* close fd if in primary process */
> + close(dev->intr_handle.fd);
> + if (dev->intr_handle.uio_cfg_fd >= 0) {
> + close(dev->intr_handle.uio_cfg_fd);
> + dev->intr_handle.uio_cfg_fd = -1;
> + }
> +
> + dev->intr_handle.fd = -1;
> + dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
> +}
> +
> +static int
> +vmbus_uio_map_secondary(struct rte_vmbus_device *dev)
> +{
> + struct mapped_vmbus_resource *uio_res;
> + struct mapped_vmbus_res_list *uio_res_list =
> + RTE_TAILQ_CAST(rte_vmbus_uio_tailq.head,
> + mapped_vmbus_res_list);
> +
> + TAILQ_FOREACH(uio_res, uio_res_list, next) {
> + int i;
> +
> + /* skip this element if it doesn't match our id */
> + if (uuid_compare(uio_res->uuid, dev->device_id))
> + continue;
> +
> + for (i = 0; i != uio_res->nb_maps; i++) {
> + void *mapaddr;
> + int fd;
> +
> + fd = open(uio_res->maps[i].path, O_RDWR);
> + if (fd < 0) {
> + RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
> + uio_res->maps[i].path, strerror(errno));
> + return -1;
> + }
> +
> + mapaddr = vmbus_map_resource(uio_res->maps[i].addr, fd,
> + uio_res->maps[i].offset,
> + uio_res->maps[i].size, 0);
> + /* fd is not needed in slave process, close it */
> + close(fd);
> +
> + if (mapaddr == uio_res->maps[i].addr)
> + continue;
> +
> + RTE_LOG(ERR, EAL,
> + "Cannot mmap device resource file %s to address: %p\n",
> + uio_res->maps[i].path,
> + uio_res->maps[i].addr);
> +
> + /* unmap addrs correctly mapped */
> + while (i != 0) {
> + --i;
> + vmbus_unmap_resource(uio_res->maps[i].addr,
> + uio_res->maps[i].size);
> + }
> + return -1;
> +
> + }
> + return 0;
> + }
> +
> + RTE_LOG(ERR, EAL, "Cannot find resource for device\n");
> + return 1;
> +}
> +
> +/* map the resources of a vmbus device in virtual memory */
> +int
> +rte_eal_vmbus_map_device(struct rte_vmbus_device *dev)
> +{
> + struct mapped_vmbus_resource *uio_res;
> + struct mapped_vmbus_res_list *uio_res_list =
> + RTE_TAILQ_CAST(rte_vmbus_uio_tailq.head, mapped_vmbus_res_list);
> + int i, ret, map_idx = 0;
> +
> + dev->intr_handle.fd = -1;
> + dev->intr_handle.uio_cfg_fd = -1;
> + dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
> +
> + /* secondary processes - use already recorded details */
> + if (rte_eal_process_type() != RTE_PROC_PRIMARY)
> + return vmbus_uio_map_secondary(dev);
> +
> + /* allocate uio resource */
> + uio_res = vmbus_uio_alloc_resource(dev);
> + if (uio_res == NULL)
> + return -1;
> +
> + /* Map all BARs */
> + for (i = 0; i != VMBUS_MAX_RESOURCE; i++) {
> + uint64_t phaddr;
> +
> + /* skip empty BAR */
> + phaddr = dev->mem_resource[i].phys_addr;
> + if (phaddr == 0)
> + continue;
> +
> + ret = vmbus_uio_map_resource_by_index(dev, i,
> + uio_res, map_idx);
> + if (ret)
> + goto error;
> +
> + map_idx++;
> + }
> +
> + uio_res->nb_maps = map_idx;
> +
> + TAILQ_INSERT_TAIL(uio_res_list, uio_res, next);
> +
> + return 0;
> +error:
> + for (i = 0; i < map_idx; i++) {
> + vmbus_unmap_resource(uio_res->maps[i].addr,
> + uio_res->maps[i].size);
> + rte_free(uio_res->maps[i].path);
> + }
> + vmbus_uio_free_resource(dev, uio_res);
> + return -1;
> +}
> +
> +/* Scan one vmbus sysfs entry, and fill the devices list from it. */
> +static int
> +vmbus_scan_one(const char *name)
> +{
> + struct rte_vmbus_device *dev, *dev2;
> + char filename[PATH_MAX];
> + char dirname[PATH_MAX];
> + unsigned long tmp;
> +
> + dev = malloc(sizeof(*dev) + strlen(name) + 1);
> + if (dev == NULL)
> + return -1;
> +
> + memset(dev, 0, sizeof(*dev));
> + strcpy(dev->sysfs_name, name);
> + if (dev->sysfs_name == NULL)
> + goto error;
> +
> + /* sysfs base directory
> + * /sys/bus/vmbus/devices/7a08391f-f5a0-4ac0-9802-d13fd964f8df
> + * or on older kernel
> + * /sys/bus/vmbus/devices/vmbus_1
> + */
> + snprintf(dirname, sizeof(dirname), "%s/%s",
> + SYSFS_VMBUS_DEVICES, name);
> +
> + /* get device id */
> + snprintf(filename, sizeof(filename), "%s/device_id", dirname);
> + if (vmbus_get_sysfs_uuid(filename, dev->device_id) < 0)
> + goto error;
> +
> + /* get device class */
> + snprintf(filename, sizeof(filename), "%s/class_id", dirname);
> + if (vmbus_get_sysfs_uuid(filename, dev->class_id) < 0)
> + goto error;
> +
> + /* get relid */
> + snprintf(filename, sizeof(filename), "%s/id", dirname);
> + if (eal_parse_sysfs_value(filename, &tmp) < 0)
> + goto error;
> + dev->relid = tmp;
> +
> + /* get monitor id */
> + snprintf(filename, sizeof(filename), "%s/monitor_id", dirname);
> + if (eal_parse_sysfs_value(filename, &tmp) < 0)
> + goto error;
> + dev->monitor_id = tmp;
> +
> + /* get numa node */
> + snprintf(filename, sizeof(filename), "%s/numa_node",
> + dirname);
> + if (eal_parse_sysfs_value(filename, &tmp) < 0)
> + /* if no NUMA support, set default to 0 */
> + dev->device.numa_node = 0;
> + else
> + dev->device.numa_node = tmp;
> +
> + /* device is valid, add in list (sorted) */
> + RTE_LOG(DEBUG, EAL, "Adding vmbus device %s\n", name);
> +
> + TAILQ_FOREACH(dev2, &vmbus_device_list, next) {
> + int ret;
> +
> + ret = uuid_compare(dev->device_id, dev->device_id);
> + if (ret > 0)
> + continue;
> +
> + if (ret < 0) {
> + TAILQ_INSERT_BEFORE(dev2, dev, next);
> + rte_eal_device_insert(&dev->device);
> + } else { /* already registered */
> + memmove(dev2->mem_resource, dev->mem_resource,
> + sizeof(dev->mem_resource));
> + free(dev);
> + }
> + return 0;
> + }
> +
> + rte_eal_device_insert(&dev->device);
> + TAILQ_INSERT_TAIL(&vmbus_device_list, dev, next);
> +
> + return 0;
> +error:
> + free(dev);
> + return -1;
> +}
> +
> +/*
> + * Scan the content of the vmbus, and the devices in the devices list
> + */
> +static int
> +vmbus_scan(void)
> +{
> + struct dirent *e;
> + DIR *dir;
> +
> + dir = opendir(SYSFS_VMBUS_DEVICES);
> + if (dir == NULL) {
> + if (errno == ENOENT)
> + return 0;
> +
> + RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
> + __func__, strerror(errno));
> + return -1;
> + }
> +
> + while ((e = readdir(dir)) != NULL) {
> + if (e->d_name[0] == '.')
> + continue;
> +
> + if (vmbus_scan_one(e->d_name) < 0)
> + goto error;
> + }
> + closedir(dir);
> + return 0;
> +
> +error:
> + closedir(dir);
> + return -1;
> +}
> +
> +/* Init the VMBUS EAL subsystem */
> +int rte_eal_vmbus_init(void)
> +{
> + /* VMBUS can be disabled */
> + if (internal_config.no_vmbus)
> + return 0;
> +
> + if (vmbus_scan() < 0) {
> + RTE_LOG(ERR, EAL, "%s(): Cannot scan vmbus\n", __func__);
> + return -1;
> + }
> + return 0;
> +}
> +
> +/* Below is PROBE part of eal_vmbus library */
> +
> +/*
> + * If device ID match, call the devinit() function of the driver.
> + */
> +static int
> +rte_eal_vmbus_probe_one_driver(struct rte_vmbus_driver *dr,
> + struct rte_vmbus_device *dev)
> +{
> + const uuid_t *id_table;
> +
> + RTE_LOG(DEBUG, EAL, " probe driver: %s\n", dr->driver.name);
> +
> + for (id_table = dr->id_table; !uuid_is_null(*id_table); ++id_table) {
> + struct rte_devargs *args;
> + char guid[UUID_BUF_SZ];
> + int ret;
> +
> + /* skip devices not assocaited with this device class */
> + if (uuid_compare(*id_table, dev->class_id) != 0)
> + continue;
> +
> + uuid_unparse(dev->device_id, guid);
> + RTE_LOG(INFO, EAL, "VMBUS device %s on NUMA socket %i\n",
> + guid, dev->device.numa_node);
> +
> + /* no initialization when blacklisted, return without error */
> + args = dev->device.devargs;
> + if (args && args->type == RTE_DEVTYPE_BLACKLISTED_VMBUS) {
> + RTE_LOG(INFO, EAL, " Device is blacklisted, not initializing\n");
> + return 1;
> + }
> +
> + RTE_LOG(INFO, EAL, " probe driver: %s\n", dr->driver.name);
> +
> + /* map resources for device */
> + ret = rte_eal_vmbus_map_device(dev);
> + if (ret != 0)
> + return ret;
> +
> + /* reference driver structure */
> + dev->driver = dr;
> +
> + /* call the driver probe() function */
> + ret = dr->probe(dr, dev);
> + if (ret)
> + dev->driver = NULL;
> +
> + return ret;
> + }
> +
> + /* return positive value if driver doesn't support this device */
> + return 1;
> +}
> +
> +
> +/*
> + * If vendor/device ID match, call the remove() function of the
> + * driver.
> + */
> +static int
> +vmbus_detach_dev(struct rte_vmbus_driver *dr,
> + struct rte_vmbus_device *dev)
> +{
> + const uuid_t *id_table;
> +
> + for (id_table = dr->id_table; !uuid_is_null(*id_table); ++id_table) {
> + char guid[UUID_BUF_SZ];
> +
> + /* skip devices not assocaited with this device class */
> + if (uuid_compare(*id_table, dev->class_id) != 0)
> + continue;
> +
> + uuid_unparse(dev->device_id, guid);
> + RTE_LOG(INFO, EAL, "VMBUS device %s on NUMA socket %i\n",
> + guid, dev->device.numa_node);
> +
> + RTE_LOG(DEBUG, EAL, " remove driver: %s\n", dr->driver.name);
> +
> + if (dr->remove && (dr->remove(dev) < 0))
> + return -1; /* negative value is an error */
> +
> + /* clear driver structure */
> + dev->driver = NULL;
> +
> + vmbus_uio_unmap_resource(dev);
> + return 0;
> + }
> +
> + /* return positive value if driver doesn't support this device */
> + return 1;
> +}
> +
> +/*
> + * call the devinit() function of all
> + * registered drivers for the vmbus device. Return -1 if no driver is
> + * found for this class of vmbus device.
> + * The present assumption is that we have drivers only for vmbus network
> + * devices. That's why we don't check driver's id_table now.
> + */
> +static int
> +vmbus_probe_all_drivers(struct rte_vmbus_device *dev)
> +{
> + struct rte_vmbus_driver *dr = NULL;
> + int ret;
> +
> + TAILQ_FOREACH(dr, &vmbus_driver_list, next) {
> + ret = rte_eal_vmbus_probe_one_driver(dr, dev);
> + if (ret < 0) {
> + /* negative value is an error */
> + RTE_LOG(ERR, EAL, "Failed to probe driver %s\n",
> + dr->driver.name);
> + return -1;
> + }
> + /* positive value means driver doesn't support it */
> + if (ret > 0)
> + continue;
> +
> + return 0;
> + }
> +
> + return 1;
> +}
> +
> +
> +/*
> + * If device ID matches, call the remove() function of all
> + * registered driver for the given device. Return -1 if initialization
> + * failed, return 1 if no driver is found for this device.
> + */
> +static int
> +vmbus_detach_all_drivers(struct rte_vmbus_device *dev)
> +{
> + struct rte_vmbus_driver *dr;
> + int rc = 0;
> +
> + if (dev == NULL)
> + return -1;
> +
> + TAILQ_FOREACH(dr, &vmbus_driver_list, next) {
> + rc = vmbus_detach_dev(dr, dev);
> + if (rc < 0)
> + /* negative value is an error */
> + return -1;
> + if (rc > 0)
> + /* positive value means driver doesn't support it */
> + continue;
> + return 0;
> + }
> + return 1;
> +}
> +
> +/* Detach device specified by its VMBUS id */
> +int
> +rte_eal_vmbus_detach(uuid_t device_id)
> +{
> + struct rte_vmbus_device *dev;
> + char ubuf[UUID_BUF_SZ];
> +
> + TAILQ_FOREACH(dev, &vmbus_device_list, next) {
> + if (uuid_compare(dev->device_id, device_id) != 0)
> + continue;
> +
> + if (vmbus_detach_all_drivers(dev) < 0)
> + goto err_return;
> +
> + TAILQ_REMOVE(&vmbus_device_list, dev, next);
> + free(dev);
> + return 0;
> + }
> + return -1;
> +
> +err_return:
> + uuid_unparse(device_id, ubuf);
> + RTE_LOG(WARNING, EAL, "Requested device %s cannot be used\n",
> + ubuf);
> + return -1;
> +}
> +
> +/*
> + * Scan the vmbus, and call the devinit() function for
> + * all registered drivers that have a matching entry in its id_table
> + * for discovered devices.
> + */
> +int
> +rte_eal_vmbus_probe(void)
> +{
> + struct rte_vmbus_device *dev = NULL;
> +
> + TAILQ_FOREACH(dev, &vmbus_device_list, next) {
> + char ubuf[UUID_BUF_SZ];
> +
> + uuid_unparse(dev->device_id, ubuf);
> +
> + RTE_LOG(DEBUG, EAL, "Probing driver for device %s ...\n",
> + ubuf);
> + vmbus_probe_all_drivers(dev);
> + }
> + return 0;
> +}
> +
> +/* register vmbus driver */
> +void
> +rte_eal_vmbus_register(struct rte_vmbus_driver *driver)
> +{
> + TAILQ_INSERT_TAIL(&vmbus_driver_list, driver, next);
> +}
> +
> +/* unregister vmbus driver */
> +void
> +rte_eal_vmbus_unregister(struct rte_vmbus_driver *driver)
> +{
> + TAILQ_REMOVE(&vmbus_driver_list, driver, next);
> +}
> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> index 7c212096..b69af0f0 100644
> --- a/lib/librte_ether/rte_ethdev.c
> +++ b/lib/librte_ether/rte_ethdev.c
> @@ -3334,3 +3334,93 @@ rte_eth_dev_l2_tunnel_offload_set(uint8_t port_id,
> -ENOTSUP);
> return (*dev->dev_ops->l2_tunnel_offload_set)(dev, l2_tunnel, mask, en);
> }
> +
> +
> +#ifdef RTE_LIBRTE_HV_PMD
> +int
> +rte_eth_dev_vmbus_probe(struct rte_vmbus_driver *vmbus_drv,
> + struct rte_vmbus_device *vmbus_dev)
> +{
> + struct eth_driver *eth_drv = (struct eth_driver *)vmbus_drv;
> + struct rte_eth_dev *eth_dev;
> + char ustr[UUID_BUF_SZ];
> + int diag;
> +
> + uuid_unparse(vmbus_dev->device_id, ustr);
> +
> + eth_dev = rte_eth_dev_allocate(ustr);
> + if (eth_dev == NULL)
> + return -ENOMEM;
> +
> + if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> + eth_dev->data->dev_private = rte_zmalloc("ethdev private structure",
> + eth_drv->dev_private_size,
> + RTE_CACHE_LINE_SIZE);
> + if (eth_dev->data->dev_private == NULL)
> + rte_panic("Cannot allocate memzone for private port data\n");
> + }
> +
> + eth_dev->device = &vmbus_dev->device;
> + eth_dev->driver = eth_drv;
> + eth_dev->data->rx_mbuf_alloc_failed = 0;
> +
> + /* init user callbacks */
> + TAILQ_INIT(&(eth_dev->link_intr_cbs));
> +
> + /*
> + * Set the default maximum frame size.
> + */
> + eth_dev->data->mtu = ETHER_MTU;
> +
> + /* Invoke PMD device initialization function */
> + diag = (*eth_drv->eth_dev_init)(eth_dev);
> + if (diag == 0)
> + return 0;
> +
> + RTE_PMD_DEBUG_TRACE("driver %s: eth_dev_init(%s) failed\n",
> + vmbus_drv->driver.name, ustr);
> +
> + if (rte_eal_process_type() == RTE_PROC_PRIMARY)
> + rte_free(eth_dev->data->dev_private);
> +
> + return diag;
> +}
> +
> +int
> +rte_eth_dev_vmbus_remove(struct rte_vmbus_device *vmbus_dev)
> +{
> + const struct eth_driver *eth_drv;
> + struct rte_eth_dev *eth_dev;
> + char ustr[UUID_BUF_SZ];
> + int ret;
> +
> + if (vmbus_dev == NULL)
> + return -EINVAL;
> +
> + uuid_unparse(vmbus_dev->device_id, ustr);
> + eth_dev = rte_eth_dev_allocated(ustr);
> + if (eth_dev == NULL)
> + return -ENODEV;
> +
> + eth_drv = (const struct eth_driver *)vmbus_dev->driver;
> +
> + /* Invoke PMD device uninit function */
> + if (*eth_drv->eth_dev_uninit) {
> + ret = (*eth_drv->eth_dev_uninit)(eth_dev);
> + if (ret)
> + return ret;
> + }
> +
> + /* free ether device */
> + rte_eth_dev_release_port(eth_dev);
> +
> + if (rte_eal_process_type() == RTE_PROC_PRIMARY)
> + rte_free(eth_dev->data->dev_private);
> +
> + eth_dev->device = NULL;
> + eth_dev->driver = NULL;
> + eth_dev->data = NULL;
> +
> + return 0;
> +}
> +#endif
> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> index 1a62a322..2a8c1eed 100644
> --- a/lib/librte_ether/rte_ethdev.h
> +++ b/lib/librte_ether/rte_ethdev.h
> @@ -180,6 +180,9 @@ extern "C" {
> #include <rte_log.h>
> #include <rte_interrupts.h>
> #include <rte_pci.h>
> +#ifdef RTE_LIBRTE_HV_PMD
> +#include <rte_vmbus.h>
> +#endif
> #include <rte_dev.h>
> #include <rte_devargs.h>
> #include <rte_errno.h>
> @@ -1908,6 +1911,17 @@ struct rte_pci_eth_driver {
> struct eth_driver eth_drv; /**< Ethernet driver. */
> };
>
> +#ifdef RTE_LIBRTE_HV_PMD
> +/**
> + * @internal
> + * The structure associated with a PMD VMBUS Ethernet driver.
> + */
> +struct rte_vmbus_eth_driver {
> + struct rte_vmbus_driver vmbus_drv; /**< Underlying VMBUS driver. */
> + struct eth_driver eth_drv; /**< Ethernet driver. */
> +};
> +#endif
> +
> /**
> * Convert a numerical speed in Mbps to a bitmap flag that can be used in
> * the bitmap link_speeds of the struct rte_eth_conf
> @@ -4543,6 +4557,23 @@ int rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
> */
> int rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev);
>
> +#ifdef RTE_LIBRTE_HV_PMD
> +/**
> + * @internal
> + * Wrapper for use by vmbus drivers as a .probe function to attach to a ethdev
> + * interface.
> + */
> +int rte_eth_dev_vmbus_probe(struct rte_vmbus_driver *vmbus_drv,
> + struct rte_vmbus_device *vmbus_dev);
> +
> +/**
> + * @internal
> + * Wrapper for use by vmbus drivers as a .remove function to detach a ethdev
> + * interface.
> + */
> +int rte_eth_dev_vmbus_remove(struct rte_vmbus_device *vmbus_dev);
> +#endif
> +
> #ifdef __cplusplus
> }
> #endif
> diff --git a/mk/rte.app.mk b/mk/rte.app.mk
> index f75f0e24..6b304084 100644
> --- a/mk/rte.app.mk
> +++ b/mk/rte.app.mk
> @@ -130,6 +130,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_VHOST),y)
> _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_VHOST) += -lrte_pmd_vhost
> endif # $(CONFIG_RTE_LIBRTE_VHOST)
> _LDLIBS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += -lrte_pmd_vmxnet3_uio
> +_LDLIBS-$(CONFIG_RTE_LIBRTE_HV_PMD) += -luuid
>
> ifeq ($(CONFIG_RTE_LIBRTE_CRYPTODEV),y)
> _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -lrte_pmd_aesni_mb
> --
> 2.11.0
>
^ permalink raw reply
* Re: [PATCH v8 00/25] Support VFD on i40e
From: Zhang, Helin @ 2017-01-11 14:32 UTC (permalink / raw)
To: Vincent Jardin, JOSHI, KAUSTUBH (KAUSTUBH)
Cc: Lu, Wenzhuo, dev@dpdk.org, DANIELS, EDWARD S (EDWARD),
ZELEZNIAK, ALEX
In-Reply-To: <1598d329eb0.27fc.bb328046f2889bc8f44aafa891a44dd2@6wind.com>
> -----Original Message-----
> From: Vincent Jardin [mailto:vincent.jardin@6wind.com]
> Sent: Wednesday, January 11, 2017 7:04 PM
> To: JOSHI, KAUSTUBH (KAUSTUBH)
> Cc: Zhang, Helin; Lu, Wenzhuo; dev@dpdk.org; DANIELS, EDWARD S
> (EDWARD); ZELEZNIAK, ALEX
> Subject: Re: [dpdk-dev] [PATCH v8 00/25] Support VFD on i40e
>
> Please can you list the gaps of the Kernel API?
>
> Thank you,
> Vincent
>
>
> Le 11 janvier 2017 3:59:45 AM "JOSHI, KAUSTUBH (KAUSTUBH)"
> <kaustubh@research.att.com> a écrit :
>
> > Hi Vincent,
> >
> > Greetings! Jumping into this debate a bit late, but let me share our
> > point of view based on how we are using this code within AT&T for our NFV
> cloud.
> >
> > Actually, we first started with trying to do the configuration within
> > the kernel drivers as you suggest, but quickly realized that besides
> > the practical problem of kernel upstreaming being a much more arduous
> > road (which can be overcome), the bigger problem was that there is no
> > standardization in the configuration interfaces for the NICs in the
> > kernel community. So different drivers do things differently and
> > expose different settings, and no forum exists to drive towards such
> > standardization. This was leading to vendors have to maintain patched
> > versions of drivers for doing PF configuration, which is not a desirable
> situation.
> >
> > So, to build a portable (to multiple NICs) SRIOV VF manager like VFd,
> > DPDK seemed like a good a forum with some hope for driving towards a
> > standard set of interfaces and without having to worry about a lot of
> > legacy baggage and old hardware. Especially since DPDK already takes
> > on the role of configuring NICs for the data plane functions anyway -
> > both PF and VF drivers will have to be included for data plane usage
> > anyway - we viewed that adding VF config options will not cause any
> > forking, but simply flush out the DPDK drivers and their interfaces to
> > be more complete. These APIs could be optional, so new vendors aren’t
> obligated to add them.
> >
> > Furthermore, allowing VF config using the DPDK PF driver also has the
> > side benefit of allowing a complete SRIOV system (both VF and PF) to
> > be built entirely with DPDK, also making version alignment easier.
> >
> > We started with Niantic, which already had PF and VF drivers, and
> > things have worked out very well with it. However, we would like VFd
> > to be a multi-NIC vendor agnostic VF management tool, which is why
> > we’ve been asking for making the PF config APIs richer.
> >
> > Regards
> >
> > KJ
> >
> >
> >> On Jan 10, 2017, at 3:23 PM, Vincent Jardin <vincent.jardin@6wind.com>
> wrote:
> >>
> >> Nope. First one needs to assess if DPDK should be intensively used to
> >> become a PF knowing Linux can do the jobs. Linux kernel community
> >> does not like the forking of Kernel drivers, I tend to agree that we
> >> should not keep duplicating options that can be solved with the Linux
> kernel.
As a PF host driver is not new to DPDK. From very early igb and ixgbe were
developed to be a PF host driver, then i40e.
In addition, I guess Linux kernel community does not like entire DPDK at all.
For now, the VFD features is added in the PMD itself, which does not require
all PMD to enable that.
I'd suggest to treat it as an experiment feature to keep it in the specifical PMD,
until it is popular enough and mature enough, then we can think about adding
it to ethdev layer as generic features for all PMDs.
This type of feature can help to address the real needs of at&t, who is the
pioneer of this feature. Having a real user of a feaure might be a good
reason to try this way.
Regards,
Helin
> >>
> >> Best regards,
> >> Vincent
> >>
> >>
> >
>
^ permalink raw reply
* Re: [PATCH] cryptodev: fix for loop in rte_cryptodev_pmd_get_named_dev
From: Trahe, Fiona @ 2017-01-11 14:29 UTC (permalink / raw)
To: Zhang, Roy Fan, dev@dpdk.org; +Cc: De Lara Guarch, Pablo
In-Reply-To: <1484143787-8336-1-git-send-email-roy.fan.zhang@intel.com>
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Fan Zhang
> Sent: Wednesday, January 11, 2017 2:10 PM
> To: dev@dpdk.org
> Cc: De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>
> Subject: [dpdk-dev] [PATCH] cryptodev: fix for loop in
> rte_cryptodev_pmd_get_named_dev
>
> Fixes: d11b0f30 ("cryptodev: introduce API and framework for crypto
> devices")
>
> This patch fixes the dev value update problem in
> rte_cryptodev_pmd_get_named_dev, orginally, dev won't be updated
> after the initiail step in the loop.
>
> Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
Acked-by: Fiona Trahe <fiona.trahe@intel.com>
^ permalink raw reply
* [PATCH] net/ixgbe: fix API parameter checking
From: Bernard Iremonger @ 2017-01-11 14:25 UTC (permalink / raw)
To: dev, wenzhuo.lu; +Cc: Bernard Iremonger, stable
Add checks to rte_pmd_ixgbe_* API's to ensure that the port
is an ixgbe port.
Fixes: 49e248223e9f ("net/ixgbe: add API for VF management")
CC: stable@dpdk.org
Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
drivers/net/ixgbe/ixgbe_ethdev.c | 71 ++++++++++++++++++++++++++++++++++++++--
1 file changed, 69 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index b7ddd4f..ca14104 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -1,7 +1,7 @@
/*-
* BSD LICENSE
*
- * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -4066,6 +4066,12 @@ rte_pmd_ixgbe_set_vf_mac_addr(uint8_t port, uint16_t vf,
dev = &rte_eth_devices[port];
rte_eth_dev_info_get(port, &dev_info);
+ if (!strstr(dev_info.driver_name, "ixgbe"))
+ return -ENOTSUP;
+
+ if (strstr(dev_info.driver_name, "ixgbe_vf"))
+ return -ENOTSUP;
+
if (vf >= dev_info.max_vfs)
return -EINVAL;
@@ -4564,6 +4570,12 @@ rte_pmd_ixgbe_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on)
dev = &rte_eth_devices[port];
rte_eth_dev_info_get(port, &dev_info);
+ if (!strstr(dev_info.driver_name, "ixgbe"))
+ return -ENOTSUP;
+
+ if (strstr(dev_info.driver_name, "ixgbe_vf"))
+ return -ENOTSUP;
+
if (vf >= dev_info.max_vfs)
return -EINVAL;
@@ -4591,6 +4603,12 @@ rte_pmd_ixgbe_set_vf_mac_anti_spoof(uint8_t port, uint16_t vf, uint8_t on)
dev = &rte_eth_devices[port];
rte_eth_dev_info_get(port, &dev_info);
+ if (!strstr(dev_info.driver_name, "ixgbe"))
+ return -ENOTSUP;
+
+ if (strstr(dev_info.driver_name, "ixgbe_vf"))
+ return -ENOTSUP;
+
if (vf >= dev_info.max_vfs)
return -EINVAL;
@@ -4617,10 +4635,16 @@ rte_pmd_ixgbe_set_vf_vlan_insert(uint8_t port, uint16_t vf, uint16_t vlan_id)
dev = &rte_eth_devices[port];
rte_eth_dev_info_get(port, &dev_info);
+ if (!strstr(dev_info.driver_name, "ixgbe"))
+ return -ENOTSUP;
+
+ if (strstr(dev_info.driver_name, "ixgbe_vf"))
+ return -ENOTSUP;
+
if (vf >= dev_info.max_vfs)
return -EINVAL;
- if (vlan_id > 4095)
+ if (vlan_id > ETHER_MAX_VLAN_ID)
return -EINVAL;
hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -4643,10 +4667,18 @@ rte_pmd_ixgbe_set_tx_loopback(uint8_t port, uint8_t on)
struct ixgbe_hw *hw;
uint32_t ctrl;
struct rte_eth_dev *dev;
+ struct rte_eth_dev_info dev_info;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
dev = &rte_eth_devices[port];
+ rte_eth_dev_info_get(port, &dev_info);
+
+ if (!strstr(dev_info.driver_name, "ixgbe"))
+ return -ENOTSUP;
+
+ if (strstr(dev_info.driver_name, "ixgbe_vf"))
+ return -ENOTSUP;
if (on > 1)
return -EINVAL;
@@ -4672,10 +4704,18 @@ rte_pmd_ixgbe_set_all_queues_drop_en(uint8_t port, uint8_t on)
int i;
int num_queues = (int)(IXGBE_QDE_IDX_MASK >> IXGBE_QDE_IDX_SHIFT);
struct rte_eth_dev *dev;
+ struct rte_eth_dev_info dev_info;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
dev = &rte_eth_devices[port];
+ rte_eth_dev_info_get(port, &dev_info);
+
+ if (!strstr(dev_info.driver_name, "ixgbe"))
+ return -ENOTSUP;
+
+ if (strstr(dev_info.driver_name, "ixgbe_vf"))
+ return -ENOTSUP;
if (on > 1)
return -EINVAL;
@@ -4704,6 +4744,12 @@ rte_pmd_ixgbe_set_vf_split_drop_en(uint8_t port, uint16_t vf, uint8_t on)
dev = &rte_eth_devices[port];
rte_eth_dev_info_get(port, &dev_info);
+ if (!strstr(dev_info.driver_name, "ixgbe"))
+ return -ENOTSUP;
+
+ if (strstr(dev_info.driver_name, "ixgbe_vf"))
+ return -ENOTSUP;
+
/* only support VF's 0 to 63 */
if ((vf >= dev_info.max_vfs) || (vf > 63))
return -EINVAL;
@@ -4736,6 +4782,12 @@ rte_pmd_ixgbe_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on)
dev = &rte_eth_devices[port];
rte_eth_dev_info_get(port, &dev_info);
+ if (!strstr(dev_info.driver_name, "ixgbe"))
+ return -ENOTSUP;
+
+ if (strstr(dev_info.driver_name, "ixgbe_vf"))
+ return -ENOTSUP;
+
if (vf >= dev_info.max_vfs)
return -EINVAL;
@@ -4775,6 +4827,9 @@ rte_pmd_ixgbe_set_vf_rxmode(uint8_t port, uint16_t vf, uint16_t rx_mask, uint8_t
dev = &rte_eth_devices[port];
rte_eth_dev_info_get(port, &dev_info);
+ if (!strstr(dev_info.driver_name, "ixgbe"))
+ return -ENOTSUP;
+
if (strstr(dev_info.driver_name, "ixgbe_vf"))
return -ENOTSUP;
@@ -4822,6 +4877,9 @@ rte_pmd_ixgbe_set_vf_rx(uint8_t port, uint16_t vf, uint8_t on)
dev = &rte_eth_devices[port];
rte_eth_dev_info_get(port, &dev_info);
+ if (!strstr(dev_info.driver_name, "ixgbe"))
+ return -ENOTSUP;
+
if (strstr(dev_info.driver_name, "ixgbe_vf"))
return -ENOTSUP;
@@ -4873,6 +4931,9 @@ rte_pmd_ixgbe_set_vf_tx(uint8_t port, uint16_t vf, uint8_t on)
dev = &rte_eth_devices[port];
rte_eth_dev_info_get(port, &dev_info);
+ if (!strstr(dev_info.driver_name, "ixgbe"))
+ return -ENOTSUP;
+
if (strstr(dev_info.driver_name, "ixgbe_vf"))
return -ENOTSUP;
@@ -4922,6 +4983,9 @@ rte_pmd_ixgbe_set_vf_vlan_filter(uint8_t port, uint16_t vlan,
dev = &rte_eth_devices[port];
rte_eth_dev_info_get(port, &dev_info);
+ if (!strstr(dev_info.driver_name, "ixgbe"))
+ return -ENOTSUP;
+
if (strstr(dev_info.driver_name, "ixgbe_vf"))
return -ENOTSUP;
@@ -4965,6 +5029,9 @@ int rte_pmd_ixgbe_set_vf_rate_limit(uint8_t port, uint16_t vf,
rte_eth_dev_info_get(port, &dev_info);
rte_eth_link_get_nowait(port, &link);
+ if (!strstr(dev_info.driver_name, "ixgbe"))
+ return -ENOTSUP;
+
if (strstr(dev_info.driver_name, "ixgbe_vf"))
return -ENOTSUP;
--
2.10.1
^ permalink raw reply related
* Re: [PATCH v1] ethdev: fix multi-process NULL dereference crashes
From: Thomas Monjalon @ 2017-01-11 14:22 UTC (permalink / raw)
To: Remy Horton; +Cc: dev
In-Reply-To: <1484073764-15001-1-git-send-email-remy.horton@intel.com>
2017-01-11 02:42, Remy Horton:
> Even though only primary processes should setup PMDs, secondary
> processes were also blanket zeroing ethernet device memory. The
> result was NULL dereference crashes in multi-process setups.
>
> Fixes: 7f95f78a8aea ("ethdev: clear data when allocating device")
I think it can be fixed by this patch:
http://dpdk.org/ml/archives/dev/2017-January/054220.html
^ permalink raw reply
* [PATCH v3 2/2] app/crypto-perf: introduce new performance test application
From: Slawomir Mrozowicz @ 2017-01-11 16:07 UTC (permalink / raw)
To: dev
Cc: Slawomir Mrozowicz, Declan Doherty, Piotr Azarewicz,
Marcin Kerlin, Michal Kobylinski
In-Reply-To: <1484150829-20734-1-git-send-email-slawomirx.mrozowicz@intel.com>
This patchset introduce new application which allows measuring
performance parameters of PMDs available in crypto tree. The goal of
this application is to replace existing performance tests in app/test.
Parameters available are: throughput (--ptest throughput) and latency
(--ptest latency). User can use multiply cores to run tests on but only
one type of crypto PMD can be measured during single application
execution. Cipher parameters, type of device, type of operation and
chain mode have to be specified in the command line as application
parameters. These parameters are checked using device capabilities
structure.
Couple of new library functions in librte_cryptodev are introduced for
application use.
To build the application a CONFIG_RTE_APP_CRYPTO_PERF flag has to be set
(it is set by default).
Example of usage: -c 0xc0 --vdev crypto_aesni_mb_pmd -w 0000:00:00.0 --
--ptest throughput --devtype crypto_aesni_mb --optype cipher-then-auth
--cipher-algo aes-cbc --cipher-op encrypt --cipher-key-sz 16 --auth-algo
sha1-hmac --auth-op generate --auth-key-sz 64 --auth-digest-sz 12
--total-ops 10000000 --burst-sz 32 --buffer-sz 64
Signed-off-by: Declan Doherty <declan.doherty@intel.com>
Signed-off-by: Slawomir Mrozowicz <slawomirx.mrozowicz@intel.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Signed-off-by: Marcin Kerlin <marcinx.kerlin@intel.com>
Signed-off-by: Michal Kobylinski <michalx.kobylinski@intel.com>
---
v2 changes:
- add latency measurement by single operation instead of burst
- add processing of chained mbufs
- add handling of test vectors file and create example of the files
- add verify operation after performance measurement
- add check of input options
- simplify application output to allow output to be easily
- add processing out of place
- add coalescing functionality
- add documentation files
v3 changes:
- fix compile in dynamic mode
- fix logic in check option
- change application name and directory
---
MAINTAINERS | 4 +
app/Makefile | 1 +
app/test-crypto-perf/Makefile | 51 ++
app/test-crypto-perf/cperf.h | 58 ++
app/test-crypto-perf/cperf_ops.c | 474 ++++++++++++
app/test-crypto-perf/cperf_ops.h | 66 ++
app/test-crypto-perf/cperf_options.h | 104 +++
app/test-crypto-perf/cperf_options_parsing.c | 875 +++++++++++++++++++++++
app/test-crypto-perf/cperf_test_latency.c | 685 ++++++++++++++++++
app/test-crypto-perf/cperf_test_latency.h | 57 ++
app/test-crypto-perf/cperf_test_throughput.c | 651 +++++++++++++++++
app/test-crypto-perf/cperf_test_throughput.h | 58 ++
app/test-crypto-perf/cperf_test_vector_parsing.c | 500 +++++++++++++
app/test-crypto-perf/cperf_test_vector_parsing.h | 73 ++
app/test-crypto-perf/cperf_test_vectors.c | 476 ++++++++++++
app/test-crypto-perf/cperf_test_vectors.h | 98 +++
app/test-crypto-perf/cperf_verify_parser.c | 314 ++++++++
app/test-crypto-perf/data/aes_cbc_128_sha.data | 503 +++++++++++++
app/test-crypto-perf/data/aes_cbc_192_sha.data | 504 +++++++++++++
app/test-crypto-perf/data/aes_cbc_256_sha.data | 504 +++++++++++++
app/test-crypto-perf/main.c | 411 +++++++++++
config/common_base | 6 +
doc/guides/rel_notes/release_17_02.rst | 4 +
doc/guides/tools/cryptoperf.rst | 397 ++++++++++
doc/guides/tools/index.rst | 1 +
25 files changed, 6875 insertions(+)
create mode 100644 app/test-crypto-perf/Makefile
create mode 100644 app/test-crypto-perf/cperf.h
create mode 100644 app/test-crypto-perf/cperf_ops.c
create mode 100644 app/test-crypto-perf/cperf_ops.h
create mode 100644 app/test-crypto-perf/cperf_options.h
create mode 100644 app/test-crypto-perf/cperf_options_parsing.c
create mode 100644 app/test-crypto-perf/cperf_test_latency.c
create mode 100644 app/test-crypto-perf/cperf_test_latency.h
create mode 100644 app/test-crypto-perf/cperf_test_throughput.c
create mode 100644 app/test-crypto-perf/cperf_test_throughput.h
create mode 100644 app/test-crypto-perf/cperf_test_vector_parsing.c
create mode 100644 app/test-crypto-perf/cperf_test_vector_parsing.h
create mode 100644 app/test-crypto-perf/cperf_test_vectors.c
create mode 100644 app/test-crypto-perf/cperf_test_vectors.h
create mode 100644 app/test-crypto-perf/cperf_verify_parser.c
create mode 100644 app/test-crypto-perf/data/aes_cbc_128_sha.data
create mode 100644 app/test-crypto-perf/data/aes_cbc_192_sha.data
create mode 100644 app/test-crypto-perf/data/aes_cbc_256_sha.data
create mode 100644 app/test-crypto-perf/main.c
create mode 100644 doc/guides/tools/cryptoperf.rst
diff --git a/MAINTAINERS b/MAINTAINERS
index ebc97b8..f129830 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -625,6 +625,10 @@ M: Reshma Pattan <reshma.pattan@intel.com>
F: app/proc_info/
F: doc/guides/tools/proc_info.rst
+Performance test application
+M: Declan Doherty <declan.doherty@intel.com>
+F: app/test-crypto-perf/
+F: doc/guides/tools/cryptoperf.rst
Other Example Applications
--------------------------
diff --git a/app/Makefile b/app/Makefile
index 30ec292..73d157e 100644
--- a/app/Makefile
+++ b/app/Makefile
@@ -38,5 +38,6 @@ DIRS-$(CONFIG_RTE_TEST_PMD) += test-pmd
DIRS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_test
DIRS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += proc_info
DIRS-$(CONFIG_RTE_LIBRTE_PDUMP) += pdump
+DIRS-$(CONFIG_RTE_APP_CRYPTO_PERF) += test-crypto-perf
include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/app/test-crypto-perf/Makefile b/app/test-crypto-perf/Makefile
new file mode 100644
index 0000000..1f99ffb
--- /dev/null
+++ b/app/test-crypto-perf/Makefile
@@ -0,0 +1,51 @@
+# BSD LICENSE
+#
+# Copyright(c) 2016 Intel Corporation. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+
+APP = dpdk-test-crypto-perf
+
+CFLAGS += $(WERROR_FLAGS)
+
+# all source are stored in SRCS-y
+SRCS-y := main.c
+SRCS-y += cperf_ops.c
+SRCS-y += cperf_options_parsing.c
+SRCS-y += cperf_test_vectors.c
+SRCS-y += cperf_test_throughput.c
+SRCS-y += cperf_test_latency.c
+SRCS-y += cperf_test_vector_parsing.c
+
+# this application needs libraries first
+DEPDIRS-y += lib
+
+include $(RTE_SDK)/mk/rte.app.mk
+
diff --git a/app/test-crypto-perf/cperf.h b/app/test-crypto-perf/cperf.h
new file mode 100644
index 0000000..0f570f0
--- /dev/null
+++ b/app/test-crypto-perf/cperf.h
@@ -0,0 +1,58 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _CPERF_
+#define _CPERF_
+
+#include <rte_crypto.h>
+
+#include "cperf_ops.h"
+
+struct cperf_options;
+struct cperf_test_vector;
+struct cperf_op_fns;
+
+typedef void *(*cperf_constructor_t)(uint8_t dev_id, uint16_t qp_id,
+ const struct cperf_options *options,
+ const struct cperf_test_vector *t_vec,
+ const struct cperf_op_fns *op_fns);
+
+typedef int (*cperf_runner_t)(void *test_ctx);
+typedef void (*cperf_destructor_t)(void *test_ctx);
+
+struct cperf_test {
+ cperf_constructor_t constructor;
+ cperf_runner_t runner;
+ cperf_destructor_t destructor;
+};
+
+#endif /* _CPERF_ */
diff --git a/app/test-crypto-perf/cperf_ops.c b/app/test-crypto-perf/cperf_ops.c
new file mode 100644
index 0000000..afc1e4e
--- /dev/null
+++ b/app/test-crypto-perf/cperf_ops.c
@@ -0,0 +1,474 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <rte_cryptodev.h>
+
+#include "cperf_ops.h"
+#include "cperf_test_vectors.h"
+
+static int
+cperf_set_ops_null_cipher(struct rte_crypto_op **ops,
+ struct rte_mbuf **bufs_in, struct rte_mbuf **bufs_out,
+ uint16_t nb_ops, struct rte_cryptodev_sym_session *sess,
+ const struct cperf_options *options,
+ const struct cperf_test_vector *test_vector __rte_unused)
+{
+ uint16_t i;
+
+ for (i = 0; i < nb_ops; i++) {
+ struct rte_crypto_sym_op *sym_op = ops[i]->sym;
+
+ rte_crypto_op_attach_sym_session(ops[i], sess);
+
+ sym_op->m_src = bufs_in[i];
+ sym_op->m_dst = bufs_out[i];
+
+ /* cipher parameters */
+ sym_op->cipher.data.length = options->buffer_sz;
+ sym_op->cipher.data.offset = 0;
+ }
+
+ return 0;
+}
+
+static int
+cperf_set_ops_null_auth(struct rte_crypto_op **ops,
+ struct rte_mbuf **bufs_in, struct rte_mbuf **bufs_out,
+ uint16_t nb_ops, struct rte_cryptodev_sym_session *sess,
+ const struct cperf_options *options,
+ const struct cperf_test_vector *test_vector __rte_unused)
+{
+ uint16_t i;
+
+ for (i = 0; i < nb_ops; i++) {
+ struct rte_crypto_sym_op *sym_op = ops[i]->sym;
+
+ rte_crypto_op_attach_sym_session(ops[i], sess);
+
+ sym_op->m_src = bufs_in[i];
+ sym_op->m_dst = bufs_out[i];
+
+ /* auth parameters */
+ sym_op->auth.data.length = options->buffer_sz;
+ sym_op->auth.data.offset = 0;
+ }
+
+ return 0;
+}
+
+static int
+cperf_set_ops_cipher(struct rte_crypto_op **ops,
+ struct rte_mbuf **bufs_in, struct rte_mbuf **bufs_out,
+ uint16_t nb_ops, struct rte_cryptodev_sym_session *sess,
+ const struct cperf_options *options,
+ const struct cperf_test_vector *test_vector)
+{
+ uint16_t i;
+
+ for (i = 0; i < nb_ops; i++) {
+ struct rte_crypto_sym_op *sym_op = ops[i]->sym;
+
+ rte_crypto_op_attach_sym_session(ops[i], sess);
+
+ sym_op->m_src = bufs_in[i];
+ sym_op->m_dst = bufs_out[i];
+
+ /* cipher parameters */
+ sym_op->cipher.iv.data = test_vector->iv.data;
+ sym_op->cipher.iv.phys_addr = test_vector->iv.phys_addr;
+ sym_op->cipher.iv.length = test_vector->iv.length;
+
+ sym_op->cipher.data.length = options->buffer_sz;
+ sym_op->cipher.data.offset = 0;
+ }
+
+ return 0;
+}
+
+static int
+cperf_set_ops_auth(struct rte_crypto_op **ops,
+ struct rte_mbuf **bufs_in, struct rte_mbuf **bufs_out,
+ uint16_t nb_ops, struct rte_cryptodev_sym_session *sess,
+ const struct cperf_options *options,
+ const struct cperf_test_vector *test_vector)
+{
+ uint16_t i;
+
+ for (i = 0; i < nb_ops; i++) {
+ struct rte_crypto_sym_op *sym_op = ops[i]->sym;
+
+ rte_crypto_op_attach_sym_session(ops[i], sess);
+
+ sym_op->m_src = bufs_in[i];
+ sym_op->m_dst = bufs_out[i];
+
+ /* authentication parameters */
+ if (options->auth_op == RTE_CRYPTO_AUTH_OP_VERIFY) {
+ sym_op->auth.digest.data = test_vector->digest.data;
+ sym_op->auth.digest.phys_addr =
+ test_vector->digest.phys_addr;
+ sym_op->auth.digest.length = options->auth_digest_sz;
+ } else {
+
+ uint32_t offset = options->buffer_sz;
+ struct rte_mbuf *buf, *tbuf;
+
+ if (options->out_of_place) {
+ buf = bufs_out[i];
+ } else {
+ buf = bufs_in[i];
+
+ tbuf = buf;
+ while ((tbuf->next != NULL) &&
+ (offset >= tbuf->data_len)) {
+ offset -= tbuf->data_len;
+ tbuf = tbuf->next;
+ }
+ }
+
+ sym_op->auth.digest.data = rte_pktmbuf_mtod_offset(buf,
+ uint8_t *, offset);
+ sym_op->auth.digest.phys_addr =
+ rte_pktmbuf_mtophys_offset(buf, offset);
+ sym_op->auth.digest.length = options->auth_digest_sz;
+ sym_op->auth.aad.phys_addr = test_vector->aad.phys_addr;
+ sym_op->auth.aad.data = test_vector->aad.data;
+ sym_op->auth.aad.length = options->auth_aad_sz;
+
+ }
+
+ sym_op->auth.data.length = options->buffer_sz;
+ sym_op->auth.data.offset = 0;
+ }
+
+ return 0;
+}
+
+static int
+cperf_set_ops_cipher_auth(struct rte_crypto_op **ops,
+ struct rte_mbuf **bufs_in, struct rte_mbuf **bufs_out,
+ uint16_t nb_ops, struct rte_cryptodev_sym_session *sess,
+ const struct cperf_options *options,
+ const struct cperf_test_vector *test_vector)
+{
+ uint16_t i;
+
+ for (i = 0; i < nb_ops; i++) {
+ struct rte_crypto_sym_op *sym_op = ops[i]->sym;
+
+ rte_crypto_op_attach_sym_session(ops[i], sess);
+
+ sym_op->m_src = bufs_in[i];
+ sym_op->m_dst = bufs_out[i];
+
+ /* cipher parameters */
+ sym_op->cipher.iv.data = test_vector->iv.data;
+ sym_op->cipher.iv.phys_addr = test_vector->iv.phys_addr;
+ sym_op->cipher.iv.length = test_vector->iv.length;
+
+ sym_op->cipher.data.length = options->buffer_sz;
+ sym_op->cipher.data.offset = 0;
+
+ /* authentication parameters */
+ if (options->auth_op == RTE_CRYPTO_AUTH_OP_VERIFY) {
+ sym_op->auth.digest.data = test_vector->digest.data;
+ sym_op->auth.digest.phys_addr =
+ test_vector->digest.phys_addr;
+ sym_op->auth.digest.length = options->auth_digest_sz;
+ } else {
+
+ uint32_t offset = options->buffer_sz;
+ struct rte_mbuf *buf, *tbuf;
+
+ if (options->out_of_place) {
+ buf = bufs_out[i];
+ } else {
+ buf = bufs_in[i];
+
+ tbuf = buf;
+ while ((tbuf->next != NULL) &&
+ (offset >= tbuf->data_len)) {
+ offset -= tbuf->data_len;
+ tbuf = tbuf->next;
+ }
+ }
+
+ sym_op->auth.digest.data = rte_pktmbuf_mtod_offset(buf,
+ uint8_t *, offset);
+ sym_op->auth.digest.phys_addr =
+ rte_pktmbuf_mtophys_offset(buf, offset);
+ sym_op->auth.digest.length = options->auth_digest_sz;
+ sym_op->auth.aad.phys_addr = test_vector->aad.phys_addr;
+ sym_op->auth.aad.data = test_vector->aad.data;
+ sym_op->auth.aad.length = options->auth_aad_sz;
+ }
+
+ sym_op->auth.data.length = options->buffer_sz;
+ sym_op->auth.data.offset = 0;
+ }
+
+ return 0;
+}
+
+static int
+cperf_set_ops_aead(struct rte_crypto_op **ops,
+ struct rte_mbuf **bufs_in, struct rte_mbuf **bufs_out,
+ uint16_t nb_ops, struct rte_cryptodev_sym_session *sess,
+ const struct cperf_options *options,
+ const struct cperf_test_vector *test_vector)
+{
+ uint16_t i;
+
+ for (i = 0; i < nb_ops; i++) {
+ struct rte_crypto_sym_op *sym_op = ops[i]->sym;
+
+ rte_crypto_op_attach_sym_session(ops[i], sess);
+
+ sym_op->m_src = bufs_in[i];
+ sym_op->m_dst = bufs_out[i];
+
+ /* cipher parameters */
+ sym_op->cipher.iv.data = test_vector->iv.data;
+ sym_op->cipher.iv.phys_addr = test_vector->iv.phys_addr;
+ sym_op->cipher.iv.length = test_vector->iv.length;
+
+ sym_op->cipher.data.length = options->buffer_sz;
+ sym_op->cipher.data.offset =
+ RTE_ALIGN_CEIL(options->auth_aad_sz, 16);
+
+ sym_op->auth.aad.data = rte_pktmbuf_mtod(bufs_in[i], uint8_t *);
+ sym_op->auth.aad.phys_addr = rte_pktmbuf_mtophys(bufs_in[i]);
+ sym_op->auth.aad.length = options->auth_aad_sz;
+
+ /* authentication parameters */
+ if (options->auth_op == RTE_CRYPTO_AUTH_OP_VERIFY) {
+ sym_op->auth.digest.data = test_vector->digest.data;
+ sym_op->auth.digest.phys_addr =
+ test_vector->digest.phys_addr;
+ sym_op->auth.digest.length = options->auth_digest_sz;
+ } else {
+
+ uint32_t offset = sym_op->cipher.data.length +
+ sym_op->cipher.data.offset;
+ struct rte_mbuf *buf, *tbuf;
+
+ if (options->out_of_place) {
+ buf = bufs_out[i];
+ } else {
+ buf = bufs_in[i];
+
+ tbuf = buf;
+ while ((tbuf->next != NULL) &&
+ (offset >= tbuf->data_len)) {
+ offset -= tbuf->data_len;
+ tbuf = tbuf->next;
+ }
+ }
+
+ sym_op->auth.digest.data = rte_pktmbuf_mtod_offset(buf,
+ uint8_t *, offset);
+ sym_op->auth.digest.phys_addr =
+ rte_pktmbuf_mtophys_offset(buf, offset);
+
+ sym_op->auth.digest.length = options->auth_digest_sz;
+ }
+
+ sym_op->auth.data.length = options->buffer_sz;
+ sym_op->auth.data.offset = options->auth_aad_sz;
+ }
+
+ return 0;
+}
+
+static struct rte_cryptodev_sym_session *
+cperf_create_session(uint8_t dev_id,
+ const struct cperf_options *options,
+ const struct cperf_test_vector *test_vector)
+{
+ struct rte_crypto_sym_xform cipher_xform;
+ struct rte_crypto_sym_xform auth_xform;
+ struct rte_cryptodev_sym_session *sess = NULL;
+
+ /*
+ * cipher only
+ */
+ if (options->op_type == CPERF_CIPHER_ONLY) {
+ cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+ cipher_xform.next = NULL;
+ cipher_xform.cipher.algo = options->cipher_algo;
+ cipher_xform.cipher.op = options->cipher_op;
+
+ /* cipher different than null */
+ if (options->cipher_algo != RTE_CRYPTO_CIPHER_NULL) {
+ cipher_xform.cipher.key.data =
+ test_vector->cipher_key.data;
+ cipher_xform.cipher.key.length =
+ test_vector->cipher_key.length;
+ }
+ /* create crypto session */
+ sess = rte_cryptodev_sym_session_create(dev_id, &cipher_xform);
+ /*
+ * auth only
+ */
+ } else if (options->op_type == CPERF_AUTH_ONLY) {
+ auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH;
+ auth_xform.next = NULL;
+ auth_xform.auth.algo = options->auth_algo;
+ auth_xform.auth.op = options->auth_op;
+
+ /* auth different than null */
+ if (options->auth_algo != RTE_CRYPTO_AUTH_NULL) {
+ auth_xform.auth.digest_length =
+ options->auth_digest_sz;
+ auth_xform.auth.add_auth_data_length =
+ options->auth_aad_sz;
+ auth_xform.auth.key.length =
+ test_vector->auth_key.length;
+ auth_xform.auth.key.data = test_vector->auth_key.data;
+ }
+ /* create crypto session */
+ sess = rte_cryptodev_sym_session_create(dev_id, &auth_xform);
+ /*
+ * cipher and auth
+ */
+ } else if (options->op_type == CPERF_CIPHER_THEN_AUTH
+ || options->op_type == CPERF_AUTH_THEN_CIPHER
+ || options->op_type == CPERF_AEAD) {
+
+ /*
+ * cipher
+ */
+ cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+ cipher_xform.next = NULL;
+ cipher_xform.cipher.algo = options->cipher_algo;
+ cipher_xform.cipher.op = options->cipher_op;
+
+ /* cipher different than null */
+ if (options->cipher_algo != RTE_CRYPTO_CIPHER_NULL) {
+ cipher_xform.cipher.key.data =
+ test_vector->cipher_key.data;
+ cipher_xform.cipher.key.length =
+ test_vector->cipher_key.length;
+ }
+
+ /*
+ * auth
+ */
+ auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH;
+ auth_xform.next = NULL;
+ auth_xform.auth.algo = options->auth_algo;
+ auth_xform.auth.op = options->auth_op;
+
+ /* auth different than null */
+ if (options->auth_algo != RTE_CRYPTO_AUTH_NULL) {
+ auth_xform.auth.digest_length = options->auth_digest_sz;
+ auth_xform.auth.add_auth_data_length =
+ options->auth_aad_sz;
+ /* auth options for aes gcm */
+ if (options->cipher_algo == RTE_CRYPTO_CIPHER_AES_GCM &&
+ options->auth_algo == RTE_CRYPTO_AUTH_AES_GCM) {
+ auth_xform.auth.key.length = 0;
+ auth_xform.auth.key.data = NULL;
+ } else { /* auth options for others */
+ auth_xform.auth.key.length =
+ test_vector->auth_key.length;
+ auth_xform.auth.key.data =
+ test_vector->auth_key.data;
+ }
+ }
+
+ /* create crypto session for aes gcm */
+ if (options->cipher_algo == RTE_CRYPTO_CIPHER_AES_GCM) {
+ if (options->cipher_op ==
+ RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
+ cipher_xform.next = &auth_xform;
+ /* create crypto session */
+ sess = rte_cryptodev_sym_session_create(dev_id,
+ &cipher_xform);
+ } else { /* decrypt */
+ auth_xform.next = &cipher_xform;
+ /* create crypto session */
+ sess = rte_cryptodev_sym_session_create(dev_id,
+ &auth_xform);
+ }
+ } else { /* create crypto session for other */
+ /* cipher then auth */
+ if (options->op_type == CPERF_CIPHER_THEN_AUTH) {
+ cipher_xform.next = &auth_xform;
+ /* create crypto session */
+ sess = rte_cryptodev_sym_session_create(dev_id,
+ &cipher_xform);
+ } else { /* auth then cipher */
+ auth_xform.next = &cipher_xform;
+ /* create crypto session */
+ sess = rte_cryptodev_sym_session_create(dev_id,
+ &auth_xform);
+ }
+ }
+ }
+ return sess;
+}
+
+struct cperf_op_fns ops;
+
+const struct cperf_op_fns *
+cperf_get_op_functions(const struct cperf_options *options)
+{
+ ops.sess_create = cperf_create_session;
+
+ if (options->op_type == CPERF_AEAD
+ || options->op_type == CPERF_AUTH_THEN_CIPHER
+ || options->op_type == CPERF_CIPHER_THEN_AUTH) {
+ if (options->cipher_algo == RTE_CRYPTO_CIPHER_AES_GCM &&
+ options->auth_algo == RTE_CRYPTO_AUTH_AES_GCM)
+ ops.populate_ops = cperf_set_ops_aead;
+ else
+ ops.populate_ops = cperf_set_ops_cipher_auth;
+ return &ops;
+ }
+ if (options->op_type == CPERF_AUTH_ONLY) {
+ if (options->auth_algo == RTE_CRYPTO_AUTH_NULL)
+ ops.populate_ops = cperf_set_ops_null_auth;
+ else
+ ops.populate_ops = cperf_set_ops_auth;
+ return &ops;
+ }
+ if (options->op_type == CPERF_CIPHER_ONLY) {
+ if (options->cipher_algo == RTE_CRYPTO_CIPHER_NULL)
+ ops.populate_ops = cperf_set_ops_null_cipher;
+ else
+ ops.populate_ops = cperf_set_ops_cipher;
+ return &ops;
+ }
+
+ return NULL;
+}
diff --git a/app/test-crypto-perf/cperf_ops.h b/app/test-crypto-perf/cperf_ops.h
new file mode 100644
index 0000000..8117aab
--- /dev/null
+++ b/app/test-crypto-perf/cperf_ops.h
@@ -0,0 +1,66 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _CPERF_OPS_
+#define _CPERF_OPS_
+
+#include <rte_crypto.h>
+
+#include "cperf.h"
+#include "cperf_options.h"
+#include "cperf_test_vectors.h"
+
+
+typedef struct rte_cryptodev_sym_session *(*cperf_sessions_create_t)(
+ uint8_t dev_id, const struct cperf_options *options,
+ const struct cperf_test_vector *test_vector);
+
+typedef int (*cperf_populate_ops_t)(struct rte_crypto_op **ops,
+ struct rte_mbuf **bufs_in, struct rte_mbuf **bufs_out,
+ uint16_t nb_ops, struct rte_cryptodev_sym_session *sess,
+ const struct cperf_options *options,
+ const struct cperf_test_vector *test_vector);
+
+
+typedef int (*cperf_verify_crypto_op_t)(struct rte_mbuf *m,
+ const struct cperf_options *options,
+ const struct cperf_test_vector *test_vector);
+
+struct cperf_op_fns {
+ cperf_sessions_create_t sess_create;
+ cperf_populate_ops_t populate_ops;
+};
+
+const struct cperf_op_fns *
+cperf_get_op_functions(const struct cperf_options *options);
+
+#endif /* _CPERF_OPS_ */
diff --git a/app/test-crypto-perf/cperf_options.h b/app/test-crypto-perf/cperf_options.h
new file mode 100644
index 0000000..96b7511
--- /dev/null
+++ b/app/test-crypto-perf/cperf_options.h
@@ -0,0 +1,104 @@
+
+#ifndef _CPERF_OPTIONS_
+#define _CPERF_OPTIONS_
+
+#include <rte_crypto.h>
+
+#define CPERF_PTEST_TYPE ("ptest")
+#define CPERF_SILENT ("silent")
+
+#define CPERF_POOL_SIZE ("pool-sz")
+#define CPERF_TOTAL_OPS ("total-ops")
+#define CPERF_BURST_SIZE ("burst-sz")
+#define CPERF_BUFFER_SIZE ("buffer-sz")
+#define CPERF_SEGMENTS_NB ("segments-nb")
+
+#define CPERF_DEVTYPE ("devtype")
+#define CPERF_OPTYPE ("optype")
+#define CPERF_SESSIONLESS ("sessionless")
+#define CPERF_OUT_OF_PLACE ("out-of-place")
+#define CPERF_VERIFY ("verify")
+#define CPERF_TEST_FILE ("test-file")
+#define CPERF_TEST_NAME ("test-name")
+
+#define CPERF_CIPHER_ALGO ("cipher-algo")
+#define CPERF_CIPHER_OP ("cipher-op")
+#define CPERF_CIPHER_KEY_SZ ("cipher-key-sz")
+#define CPERF_CIPHER_IV_SZ ("cipher-iv-sz")
+
+#define CPERF_AUTH_ALGO ("auth-algo")
+#define CPERF_AUTH_OP ("auth-op")
+#define CPERF_AUTH_KEY_SZ ("auth-key-sz")
+#define CPERF_AUTH_DIGEST_SZ ("auth-digest-sz")
+#define CPERF_AUTH_AAD_SZ ("auth-aad-sz")
+#define CPERF_CSV ("csv-friendly")
+
+
+enum cperf_perf_test_type {
+ CPERF_TEST_TYPE_THROUGHPUT,
+ CPERF_TEST_TYPE_CYCLECOUNT,
+ CPERF_TEST_TYPE_LATENCY
+};
+
+
+extern const char *cperf_test_type_strs[];
+
+enum cperf_op_type {
+ CPERF_CIPHER_ONLY = 1,
+ CPERF_AUTH_ONLY,
+ CPERF_CIPHER_THEN_AUTH,
+ CPERF_AUTH_THEN_CIPHER,
+ CPERF_AEAD
+};
+
+extern const char *cperf_op_type_strs[];
+
+struct cperf_options {
+ enum cperf_perf_test_type test;
+
+ uint32_t pool_sz;
+ uint32_t total_ops;
+ uint32_t burst_sz;
+ uint32_t buffer_sz;
+ uint32_t segments_nb;
+
+ char device_type[RTE_CRYPTODEV_NAME_LEN];
+ enum cperf_op_type op_type;
+
+ uint32_t sessionless:1;
+ uint32_t out_of_place:1;
+ uint32_t verify:1;
+ uint32_t silent:1;
+ uint32_t csv:1;
+
+ char *test_file;
+ char *test_name;
+
+ enum rte_crypto_cipher_algorithm cipher_algo;
+ enum rte_crypto_cipher_operation cipher_op;
+
+ uint16_t cipher_key_sz;
+ uint16_t cipher_iv_sz;
+
+ enum rte_crypto_auth_algorithm auth_algo;
+ enum rte_crypto_auth_operation auth_op;
+
+ uint16_t auth_key_sz;
+ uint16_t auth_digest_sz;
+ uint16_t auth_aad_sz;
+};
+
+void
+cperf_options_default(struct cperf_options *options);
+
+int
+cperf_options_parse(struct cperf_options *options,
+ int argc, char **argv);
+
+int
+cperf_options_check(struct cperf_options *options);
+
+void
+cperf_options_dump(struct cperf_options *options);
+
+#endif
diff --git a/app/test-crypto-perf/cperf_options_parsing.c b/app/test-crypto-perf/cperf_options_parsing.c
new file mode 100644
index 0000000..291826b
--- /dev/null
+++ b/app/test-crypto-perf/cperf_options_parsing.c
@@ -0,0 +1,875 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <getopt.h>
+#include <unistd.h>
+
+#include <rte_malloc.h>
+
+#include "cperf_options.h"
+
+struct name_id_map {
+ const char *name;
+ uint32_t id;
+};
+
+static int
+get_str_key_id_mapping(struct name_id_map *map, unsigned int map_len,
+ const char *str_key)
+{
+ unsigned int i;
+
+ for (i = 0; i < map_len; i++) {
+
+ if (strcmp(str_key, map[i].name) == 0)
+ return map[i].id;
+ }
+
+ return -1;
+}
+
+static int
+parse_cperf_test_type(struct cperf_options *opts, const char *arg)
+{
+ struct name_id_map cperftest_namemap[] = {
+ {
+ cperf_test_type_strs[CPERF_TEST_TYPE_THROUGHPUT],
+ CPERF_TEST_TYPE_THROUGHPUT
+ },
+ {
+ cperf_test_type_strs[CPERF_TEST_TYPE_CYCLECOUNT],
+ CPERF_TEST_TYPE_CYCLECOUNT
+ },
+ {
+ cperf_test_type_strs[CPERF_TEST_TYPE_LATENCY],
+ CPERF_TEST_TYPE_LATENCY
+ }
+ };
+
+ int id = get_str_key_id_mapping(
+ (struct name_id_map *)cperftest_namemap,
+ RTE_DIM(cperftest_namemap), arg);
+ if (id < 0) {
+ RTE_LOG(ERR, USER1, "failed to parse test type");
+ return -1;
+ }
+
+ opts->test = (enum cperf_perf_test_type)id;
+
+ return 0;
+}
+
+static int
+parse_uint32_t(uint32_t *value, const char *arg)
+{
+ char *end = NULL;
+ unsigned long n = strtoul(arg, &end, 10);
+
+ if ((optarg[0] == '\0') || (end == NULL) || (*end != '\0'))
+ return -1;
+
+ if (n > UINT32_MAX)
+ return -ERANGE;
+
+ *value = (uint32_t) n;
+
+ return 0;
+}
+
+static int
+parse_uint16_t(uint16_t *value, const char *arg)
+{
+ uint32_t val = 0;
+ int ret = parse_uint32_t(&val, arg);
+
+ if (ret < 0)
+ return ret;
+
+ if (val > UINT16_MAX)
+ return -ERANGE;
+
+ *value = (uint16_t) val;
+
+ return 0;
+}
+
+static int
+parse_total_ops(struct cperf_options *opts, const char *arg)
+{
+ int ret = parse_uint32_t(&opts->total_ops, arg);
+
+ if (ret)
+ RTE_LOG(ERR, USER1, "failed to parse total operations count");
+
+ return ret;
+}
+
+static int
+parse_pool_sz(struct cperf_options *opts, const char *arg)
+{
+ int ret = parse_uint32_t(&opts->pool_sz, arg);
+
+ if (ret)
+ RTE_LOG(ERR, USER1, "failed to parse pool size");
+ return ret;
+}
+
+static int
+parse_burst_sz(struct cperf_options *opts, const char *arg)
+{
+ int ret = parse_uint32_t(&opts->burst_sz, arg);
+
+ if (ret)
+ RTE_LOG(ERR, USER1, "failed to parse burst size");
+ return ret;
+}
+
+static int
+parse_buffer_sz(struct cperf_options *opts, const char *arg)
+{
+ uint32_t i, valid_buf_sz[] = {
+ 32, 64, 128, 256, 384, 512, 768, 1024, 1280, 1536, 1792,
+ 2048
+ };
+
+ if (parse_uint32_t(&opts->buffer_sz, arg)) {
+ RTE_LOG(ERR, USER1, "failed to parse buffer size");
+ return -1;
+ }
+
+ for (i = 0; i < RTE_DIM(valid_buf_sz); i++)
+ if (valid_buf_sz[i] == opts->buffer_sz)
+ return 0;
+
+ RTE_LOG(ERR, USER1, "invalid buffer size specified");
+ return -1;
+}
+
+static int
+parse_segments_nb(struct cperf_options *opts, const char *arg)
+{
+ int ret = parse_uint32_t(&opts->segments_nb, arg);
+
+ if (ret) {
+ RTE_LOG(ERR, USER1, "failed to parse segments number\n");
+ return -1;
+ }
+
+ if ((opts->segments_nb == 0) || (opts->segments_nb > 255)) {
+ RTE_LOG(ERR, USER1, "invalid segments number specified\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+parse_device_type(struct cperf_options *opts, const char *arg)
+{
+ if (strlen(arg) > (sizeof(opts->device_type) - 1))
+ return -1;
+
+ strncpy(opts->device_type, arg, sizeof(opts->device_type));
+
+ return 0;
+}
+
+static int
+parse_op_type(struct cperf_options *opts, const char *arg)
+{
+ struct name_id_map optype_namemap[] = {
+ {
+ cperf_op_type_strs[CPERF_CIPHER_ONLY],
+ CPERF_CIPHER_ONLY
+ },
+ {
+ cperf_op_type_strs[CPERF_AUTH_ONLY],
+ CPERF_AUTH_ONLY
+ },
+ {
+ cperf_op_type_strs[CPERF_CIPHER_THEN_AUTH],
+ CPERF_CIPHER_THEN_AUTH
+ },
+ {
+ cperf_op_type_strs[CPERF_AUTH_THEN_CIPHER],
+ CPERF_AUTH_THEN_CIPHER
+ },
+ {
+ cperf_op_type_strs[CPERF_AEAD],
+ CPERF_AEAD
+ }
+ };
+
+ int id = get_str_key_id_mapping(optype_namemap,
+ RTE_DIM(optype_namemap), arg);
+ if (id < 0) {
+ RTE_LOG(ERR, USER1, "invalid opt type specified\n");
+ return -1;
+ }
+
+ opts->op_type = (enum cperf_op_type)id;
+
+ return 0;
+}
+
+static int
+parse_sessionless(struct cperf_options *opts,
+ const char *arg __rte_unused)
+{
+ opts->sessionless = 1;
+ return 0;
+}
+
+static int
+parse_out_of_place(struct cperf_options *opts,
+ const char *arg __rte_unused)
+{
+ opts->out_of_place = 1;
+ return 0;
+}
+
+static int
+parse_verify(struct cperf_options *opts,
+ const char *arg __rte_unused)
+{
+ opts->verify = 1;
+
+ return 0;
+}
+
+static int
+parse_test_file(struct cperf_options *opts,
+ const char *arg)
+{
+ opts->test_file = strdup(arg);
+ if (access(opts->test_file, F_OK) != -1)
+ return 0;
+ RTE_LOG(ERR, USER1, "Test vector file doesn't exist\n");
+
+ return -1;
+}
+
+static int
+parse_test_name(struct cperf_options *opts,
+ const char *arg)
+{
+ char *test_name = (char *) rte_zmalloc(NULL,
+ sizeof(char) * (strlen(arg) + 3), 0);
+ snprintf(test_name, strlen(arg) + 3, "[%s]", arg);
+ opts->test_name = test_name;
+
+ return 0;
+}
+
+static int
+parse_silent(struct cperf_options *opts,
+ const char *arg __rte_unused)
+{
+ opts->silent = 1;
+
+ return 0;
+}
+
+static int
+parse_cipher_algo(struct cperf_options *opts, const char *arg)
+{
+ struct name_id_map cipher_algo_namemap[] = {
+ {
+ rte_crypto_cipher_algorithm_strings
+ [RTE_CRYPTO_CIPHER_3DES_CBC],
+ RTE_CRYPTO_CIPHER_3DES_CBC
+ },
+ {
+ rte_crypto_cipher_algorithm_strings
+ [RTE_CRYPTO_CIPHER_3DES_ECB],
+ RTE_CRYPTO_CIPHER_3DES_ECB
+ },
+ {
+ rte_crypto_cipher_algorithm_strings
+ [RTE_CRYPTO_CIPHER_3DES_CTR],
+ RTE_CRYPTO_CIPHER_3DES_CTR
+ },
+ {
+ rte_crypto_cipher_algorithm_strings
+ [RTE_CRYPTO_CIPHER_AES_CBC],
+ RTE_CRYPTO_CIPHER_AES_CBC
+ },
+ {
+ rte_crypto_cipher_algorithm_strings
+ [RTE_CRYPTO_CIPHER_AES_CCM],
+ RTE_CRYPTO_CIPHER_AES_CCM
+ },
+ {
+ rte_crypto_cipher_algorithm_strings
+ [RTE_CRYPTO_CIPHER_AES_CTR],
+ RTE_CRYPTO_CIPHER_AES_CTR
+ },
+ {
+ rte_crypto_cipher_algorithm_strings
+ [RTE_CRYPTO_CIPHER_AES_ECB],
+ RTE_CRYPTO_CIPHER_AES_ECB
+ },
+ {
+ rte_crypto_cipher_algorithm_strings
+ [RTE_CRYPTO_CIPHER_AES_GCM],
+ RTE_CRYPTO_CIPHER_AES_GCM
+ },
+ {
+ rte_crypto_cipher_algorithm_strings
+ [RTE_CRYPTO_CIPHER_AES_F8],
+ RTE_CRYPTO_CIPHER_AES_F8
+ },
+ {
+ rte_crypto_cipher_algorithm_strings
+ [RTE_CRYPTO_CIPHER_AES_XTS],
+ RTE_CRYPTO_CIPHER_AES_XTS
+ },
+ {
+ rte_crypto_cipher_algorithm_strings
+ [RTE_CRYPTO_CIPHER_ARC4],
+ RTE_CRYPTO_CIPHER_ARC4
+ },
+ {
+ rte_crypto_cipher_algorithm_strings
+ [RTE_CRYPTO_CIPHER_NULL],
+ RTE_CRYPTO_CIPHER_NULL
+ },
+ {
+ rte_crypto_cipher_algorithm_strings
+ [RTE_CRYPTO_CIPHER_KASUMI_F8],
+ RTE_CRYPTO_CIPHER_KASUMI_F8
+ },
+ {
+ rte_crypto_cipher_algorithm_strings
+ [RTE_CRYPTO_CIPHER_SNOW3G_UEA2],
+ RTE_CRYPTO_CIPHER_SNOW3G_UEA2
+ },
+ {
+ rte_crypto_cipher_algorithm_strings
+ [RTE_CRYPTO_CIPHER_ZUC_EEA3],
+ RTE_CRYPTO_CIPHER_ZUC_EEA3
+ },
+ };
+
+
+ int id = get_str_key_id_mapping(cipher_algo_namemap,
+ RTE_DIM(cipher_algo_namemap), arg);
+ if (id < 0) {
+ RTE_LOG(ERR, USER1, "Invalid cipher algorithm specified/n");
+ return -1;
+ }
+
+ opts->cipher_algo = (enum rte_crypto_cipher_algorithm)id;
+
+ return 0;
+}
+
+static int
+parse_cipher_op(struct cperf_options *opts, const char *arg)
+{
+ struct name_id_map cipher_op_namemap[] = {
+ {
+ rte_crypto_cipher_operation_strings
+ [RTE_CRYPTO_CIPHER_OP_ENCRYPT],
+ RTE_CRYPTO_CIPHER_OP_ENCRYPT },
+ {
+ rte_crypto_cipher_operation_strings
+ [RTE_CRYPTO_CIPHER_OP_DECRYPT],
+ RTE_CRYPTO_CIPHER_OP_DECRYPT
+ }
+ };
+
+ int id = get_str_key_id_mapping(cipher_op_namemap,
+ RTE_DIM(cipher_op_namemap), arg);
+ if (id < 0) {
+ RTE_LOG(ERR, USER1, "Invalid cipher operation specified/n");
+ return -1;
+ }
+
+ opts->cipher_op = (enum rte_crypto_cipher_operation)id;
+
+ return 0;
+}
+
+static int
+parse_cipher_key_sz(struct cperf_options *opts, const char *arg)
+{
+ return parse_uint16_t(&opts->cipher_key_sz, arg);
+}
+
+static int
+parse_cipher_iv_sz(struct cperf_options *opts, const char *arg)
+{
+ return parse_uint16_t(&opts->cipher_iv_sz, arg);
+}
+
+static int
+parse_auth_algo(struct cperf_options *opts, const char *arg) {
+ struct name_id_map cipher_auth_namemap[] = {
+ {
+ rte_crypto_auth_algorithm_strings
+ [RTE_CRYPTO_AUTH_AES_CBC_MAC],
+ RTE_CRYPTO_AUTH_AES_CBC_MAC
+ },
+ {
+ rte_crypto_auth_algorithm_strings
+ [RTE_CRYPTO_AUTH_AES_CCM],
+ RTE_CRYPTO_AUTH_AES_CCM
+ },
+ {
+ rte_crypto_auth_algorithm_strings
+ [RTE_CRYPTO_AUTH_AES_CMAC],
+ RTE_CRYPTO_AUTH_AES_CMAC
+ },
+ {
+ rte_crypto_auth_algorithm_strings
+ [RTE_CRYPTO_AUTH_AES_GCM],
+ RTE_CRYPTO_AUTH_AES_GCM
+ },
+ {
+ rte_crypto_auth_algorithm_strings
+ [RTE_CRYPTO_AUTH_AES_GMAC],
+ RTE_CRYPTO_AUTH_AES_GMAC
+ },
+ {
+ rte_crypto_auth_algorithm_strings
+ [RTE_CRYPTO_AUTH_AES_XCBC_MAC],
+ RTE_CRYPTO_AUTH_AES_XCBC_MAC
+ },
+ {
+ rte_crypto_auth_algorithm_strings
+ [RTE_CRYPTO_AUTH_MD5],
+ RTE_CRYPTO_AUTH_MD5
+ },
+ {
+ rte_crypto_auth_algorithm_strings
+ [RTE_CRYPTO_AUTH_MD5_HMAC],
+ RTE_CRYPTO_AUTH_MD5_HMAC
+ },
+ {
+ rte_crypto_auth_algorithm_strings
+ [RTE_CRYPTO_AUTH_SHA1],
+ RTE_CRYPTO_AUTH_SHA1
+ },
+ {
+ rte_crypto_auth_algorithm_strings
+ [RTE_CRYPTO_AUTH_SHA1_HMAC],
+ RTE_CRYPTO_AUTH_SHA1_HMAC
+ },
+ {
+ rte_crypto_auth_algorithm_strings
+ [RTE_CRYPTO_AUTH_SHA224],
+ RTE_CRYPTO_AUTH_SHA224
+ },
+ {
+ rte_crypto_auth_algorithm_strings
+ [RTE_CRYPTO_AUTH_SHA224_HMAC],
+ RTE_CRYPTO_AUTH_SHA224_HMAC
+ },
+ {
+ rte_crypto_auth_algorithm_strings
+ [RTE_CRYPTO_AUTH_SHA256],
+ RTE_CRYPTO_AUTH_SHA256
+ },
+ {
+ rte_crypto_auth_algorithm_strings
+ [RTE_CRYPTO_AUTH_SHA256_HMAC],
+ RTE_CRYPTO_AUTH_SHA256_HMAC
+ },
+ {
+ rte_crypto_auth_algorithm_strings
+ [RTE_CRYPTO_AUTH_SHA384],
+ RTE_CRYPTO_AUTH_SHA384
+ },
+ {
+ rte_crypto_auth_algorithm_strings
+ [RTE_CRYPTO_AUTH_SHA384_HMAC],
+ RTE_CRYPTO_AUTH_SHA384_HMAC
+ },
+ {
+ rte_crypto_auth_algorithm_strings
+ [RTE_CRYPTO_AUTH_SHA512],
+ RTE_CRYPTO_AUTH_SHA512
+ },
+ {
+ rte_crypto_auth_algorithm_strings
+ [RTE_CRYPTO_AUTH_SHA512_HMAC],
+ RTE_CRYPTO_AUTH_SHA512_HMAC
+ },
+ {
+ rte_crypto_auth_algorithm_strings
+ [RTE_CRYPTO_AUTH_KASUMI_F9],
+ RTE_CRYPTO_AUTH_KASUMI_F9
+ },
+ {
+ rte_crypto_auth_algorithm_strings
+ [RTE_CRYPTO_AUTH_SNOW3G_UIA2],
+ RTE_CRYPTO_AUTH_SNOW3G_UIA2
+ },
+ {
+ rte_crypto_auth_algorithm_strings
+ [RTE_CRYPTO_AUTH_ZUC_EIA3],
+ RTE_CRYPTO_AUTH_ZUC_EIA3
+ },
+ };
+
+
+ int id = get_str_key_id_mapping(cipher_auth_namemap,
+ RTE_DIM(cipher_auth_namemap), arg);
+ if (id < 0) {
+ RTE_LOG(ERR, USER1, "invalid authentication algorithm specified"
+ "\n");
+ return -1;
+ }
+
+ opts->auth_algo = (enum rte_crypto_auth_algorithm)id;
+
+ return 0;
+}
+
+static int
+parse_auth_op(struct cperf_options *opts, const char *arg)
+{
+ struct name_id_map auth_op_namemap[] = {
+ {
+ rte_crypto_auth_operation_strings
+ [RTE_CRYPTO_AUTH_OP_GENERATE],
+ RTE_CRYPTO_AUTH_OP_GENERATE },
+ {
+ rte_crypto_auth_operation_strings
+ [RTE_CRYPTO_AUTH_OP_VERIFY],
+ RTE_CRYPTO_AUTH_OP_VERIFY
+ }
+ };
+
+ int id = get_str_key_id_mapping(auth_op_namemap,
+ RTE_DIM(auth_op_namemap), arg);
+ if (id < 0) {
+ RTE_LOG(ERR, USER1, "invalid authentication operation specified"
+ "\n");
+ return -1;
+ }
+
+ opts->auth_op = (enum rte_crypto_auth_operation)id;
+
+ return 0;
+}
+
+static int
+parse_auth_key_sz(struct cperf_options *opts, const char *arg)
+{
+ return parse_uint16_t(&opts->auth_key_sz, arg);
+}
+
+static int
+parse_auth_digest_sz(struct cperf_options *opts, const char *arg)
+{
+ return parse_uint16_t(&opts->auth_digest_sz, arg);
+}
+
+static int
+parse_auth_aad_sz(struct cperf_options *opts, const char *arg)
+{
+ return parse_uint16_t(&opts->auth_aad_sz, arg);
+}
+
+static int
+parse_csv_friendly(struct cperf_options *opts, const char *arg __rte_unused)
+{
+ opts->csv = 1;
+ opts->silent = 1;
+ return 0;
+}
+
+typedef int (*option_parser_t)(struct cperf_options *opts,
+ const char *arg);
+
+struct long_opt_parser {
+ const char *lgopt_name;
+ option_parser_t parser_fn;
+
+};
+
+static struct option lgopts[] = {
+
+ { CPERF_PTEST_TYPE, required_argument, 0, 0 },
+
+ { CPERF_POOL_SIZE, required_argument, 0, 0 },
+ { CPERF_TOTAL_OPS, required_argument, 0, 0 },
+ { CPERF_BURST_SIZE, required_argument, 0, 0 },
+ { CPERF_BUFFER_SIZE, required_argument, 0, 0 },
+ { CPERF_SEGMENTS_NB, required_argument, 0, 0 },
+
+ { CPERF_DEVTYPE, required_argument, 0, 0 },
+ { CPERF_OPTYPE, required_argument, 0, 0 },
+
+ { CPERF_SILENT, no_argument, 0, 0 },
+ { CPERF_SESSIONLESS, no_argument, 0, 0 },
+ { CPERF_OUT_OF_PLACE, no_argument, 0, 0 },
+ { CPERF_VERIFY, no_argument, 0, 0 },
+ { CPERF_TEST_FILE, required_argument, 0, 0 },
+ { CPERF_TEST_NAME, required_argument, 0, 0 },
+
+ { CPERF_CIPHER_ALGO, required_argument, 0, 0 },
+ { CPERF_CIPHER_OP, required_argument, 0, 0 },
+
+ { CPERF_CIPHER_KEY_SZ, required_argument, 0, 0 },
+ { CPERF_CIPHER_IV_SZ, required_argument, 0, 0 },
+
+ { CPERF_AUTH_ALGO, required_argument, 0, 0 },
+ { CPERF_AUTH_OP, required_argument, 0, 0 },
+
+ { CPERF_AUTH_KEY_SZ, required_argument, 0, 0 },
+ { CPERF_AUTH_DIGEST_SZ, required_argument, 0, 0 },
+ { CPERF_AUTH_AAD_SZ, required_argument, 0, 0 },
+ { CPERF_CSV, no_argument, 0, 0},
+
+ { NULL, 0, 0, 0 }
+};
+
+void
+cperf_options_default(struct cperf_options *opts)
+{
+ opts->test = CPERF_TEST_TYPE_THROUGHPUT;
+
+ opts->pool_sz = 100000;
+ opts->total_ops = 10000000;
+ opts->burst_sz = 32;
+ opts->buffer_sz = 64;
+ opts->segments_nb = 1;
+
+ strncpy(opts->device_type, "crypto_aesni_mb",
+ sizeof(opts->device_type));
+
+ opts->op_type = CPERF_CIPHER_THEN_AUTH;
+
+ opts->silent = 0;
+ opts->verify = 0;
+ opts->test_file = NULL;
+ opts->test_name = NULL;
+ opts->sessionless = 0;
+ opts->out_of_place = 0;
+
+ opts->cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC;
+ opts->cipher_op = RTE_CRYPTO_CIPHER_OP_ENCRYPT;
+ opts->cipher_key_sz = 16;
+ opts->cipher_iv_sz = 16;
+
+ opts->auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC;
+ opts->auth_op = RTE_CRYPTO_AUTH_OP_GENERATE;
+
+ opts->auth_key_sz = 64;
+ opts->auth_digest_sz = 12;
+ opts->auth_aad_sz = 0;
+}
+
+static int
+cperf_opts_parse_long(int opt_idx, struct cperf_options *opts)
+{
+ struct long_opt_parser parsermap[] = {
+ { CPERF_PTEST_TYPE, parse_cperf_test_type },
+ { CPERF_SILENT, parse_silent },
+ { CPERF_POOL_SIZE, parse_pool_sz },
+ { CPERF_TOTAL_OPS, parse_total_ops },
+ { CPERF_BURST_SIZE, parse_burst_sz },
+ { CPERF_BUFFER_SIZE, parse_buffer_sz },
+ { CPERF_SEGMENTS_NB, parse_segments_nb },
+ { CPERF_DEVTYPE, parse_device_type },
+ { CPERF_OPTYPE, parse_op_type },
+ { CPERF_SESSIONLESS, parse_sessionless },
+ { CPERF_OUT_OF_PLACE, parse_out_of_place },
+ { CPERF_VERIFY, parse_verify },
+ { CPERF_TEST_FILE, parse_test_file },
+ { CPERF_TEST_NAME, parse_test_name },
+ { CPERF_CIPHER_ALGO, parse_cipher_algo },
+ { CPERF_CIPHER_OP, parse_cipher_op },
+ { CPERF_CIPHER_KEY_SZ, parse_cipher_key_sz },
+ { CPERF_CIPHER_IV_SZ, parse_cipher_iv_sz },
+ { CPERF_AUTH_ALGO, parse_auth_algo },
+ { CPERF_AUTH_OP, parse_auth_op },
+ { CPERF_AUTH_KEY_SZ, parse_auth_key_sz },
+ { CPERF_AUTH_DIGEST_SZ, parse_auth_digest_sz },
+ { CPERF_AUTH_AAD_SZ, parse_auth_aad_sz },
+ { CPERF_CSV, parse_csv_friendly},
+ };
+ unsigned int i;
+
+ for (i = 0; i < RTE_DIM(parsermap); i++) {
+ if (strncmp(lgopts[opt_idx].name, parsermap[i].lgopt_name,
+ strlen(lgopts[opt_idx].name)) == 0)
+ return parsermap[i].parser_fn(opts, optarg);
+ }
+
+ return -EINVAL;
+}
+
+int
+cperf_options_parse(struct cperf_options *options, int argc, char **argv)
+{
+ int opt, retval, opt_idx;
+
+ while ((opt = getopt_long(argc, argv, "", lgopts, &opt_idx)) != EOF) {
+ switch (opt) {
+ /* long options */
+ case 0:
+
+ retval = cperf_opts_parse_long(opt_idx, options);
+ if (retval != 0)
+ return retval;
+
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+int
+cperf_options_check(struct cperf_options *options)
+{
+ if (options->segments_nb > options->buffer_sz) {
+ RTE_LOG(ERR, USER1,
+ "Segments number greater than buffer size.\n");
+ return -EINVAL;
+ }
+
+ if (options->verify && options->test_file == NULL) {
+ RTE_LOG(ERR, USER1, "Define path to the file with test"
+ " vectors.\n");
+ return -EINVAL;
+ }
+
+ if (options->test_name != NULL && options->test_file == NULL) {
+ RTE_LOG(ERR, USER1, "Define path to the file with test"
+ " vectors.\n");
+ return -EINVAL;
+ }
+
+ if (options->auth_op == RTE_CRYPTO_AUTH_OP_VERIFY &&
+ options->test_file == NULL) {
+ RTE_LOG(ERR, USER1, "Define path to the file with test"
+ " vectors.\n");
+ return -EINVAL;
+ }
+
+ if (options->verify &&
+ options->total_ops > options->pool_sz) {
+ RTE_LOG(ERR, USER1, "Total number of ops must be less than or"
+ " equal to the pool size.\n");
+ return -EINVAL;
+ }
+
+ if (options->op_type == CPERF_CIPHER_THEN_AUTH) {
+ if (options->cipher_op != RTE_CRYPTO_CIPHER_OP_ENCRYPT &&
+ options->auth_op !=
+ RTE_CRYPTO_AUTH_OP_GENERATE) {
+ RTE_LOG(ERR, USER1, "Option cipher then auth must use"
+ " options: encrypt and generate.\n");
+ return -EINVAL;
+ }
+ } else if (options->op_type == CPERF_AUTH_THEN_CIPHER) {
+ if (options->cipher_op != RTE_CRYPTO_CIPHER_OP_DECRYPT &&
+ options->auth_op !=
+ RTE_CRYPTO_AUTH_OP_VERIFY) {
+ RTE_LOG(ERR, USER1, "Option auth then cipher must use"
+ " options: decrypt and verify.\n");
+ return -EINVAL;
+ }
+ } else if (options->op_type == CPERF_AEAD) {
+ if (!(options->cipher_op == RTE_CRYPTO_CIPHER_OP_ENCRYPT &&
+ options->auth_op ==
+ RTE_CRYPTO_AUTH_OP_GENERATE) &&
+ !(options->cipher_op ==
+ RTE_CRYPTO_CIPHER_OP_DECRYPT &&
+ options->auth_op ==
+ RTE_CRYPTO_AUTH_OP_VERIFY)) {
+ RTE_LOG(ERR, USER1, "Use together options: encrypt and"
+ " generate or decrypt and verify.\n");
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+void
+cperf_options_dump(struct cperf_options *opts)
+{
+ printf("# Crypto Performance Application Options:\n");
+ printf("#\n");
+ printf("# cperf test: %s\n", cperf_test_type_strs[opts->test]);
+ printf("#\n");
+ printf("# size of crypto op / mbuf pool: %u\n", opts->pool_sz);
+ printf("# total number of ops: %u\n", opts->total_ops);
+ printf("# burst size: %u\n", opts->burst_sz);
+ printf("# buffer size: %u\n", opts->buffer_sz);
+ printf("# segments per buffer: %u\n", opts->segments_nb);
+ printf("#\n");
+ printf("# cryptodev type: %s\n", opts->device_type);
+ printf("#\n");
+ printf("# crypto operation: %s\n", cperf_op_type_strs[opts->op_type]);
+ printf("# verify operation: %s\n", opts->verify ? "yes" : "no");
+ printf("# sessionless: %s\n", opts->sessionless ? "yes" : "no");
+ printf("# out of place: %s\n", opts->out_of_place ? "yes" : "no");
+
+ printf("#\n");
+
+ if (opts->op_type == CPERF_AUTH_ONLY ||
+ opts->op_type == CPERF_CIPHER_THEN_AUTH ||
+ opts->op_type == CPERF_AUTH_THEN_CIPHER ||
+ opts->op_type == CPERF_AEAD) {
+ printf("# auth algorithm: %s\n",
+ rte_crypto_auth_algorithm_strings[opts->auth_algo]);
+ printf("# auth operation: %s\n",
+ rte_crypto_auth_operation_strings[opts->auth_op]);
+ printf("# auth key size: %u\n", opts->auth_key_sz);
+ printf("# auth digest size: %u\n", opts->auth_digest_sz);
+ printf("# auth aad size: %u\n", opts->auth_aad_sz);
+ printf("#\n");
+ }
+
+ if (opts->op_type == CPERF_CIPHER_ONLY ||
+ opts->op_type == CPERF_CIPHER_THEN_AUTH ||
+ opts->op_type == CPERF_AUTH_THEN_CIPHER ||
+ opts->op_type == CPERF_AEAD) {
+ printf("# cipher algorithm: %s\n",
+ rte_crypto_cipher_algorithm_strings[opts->cipher_algo]);
+ printf("# cipher operation: %s\n",
+ rte_crypto_cipher_operation_strings[opts->cipher_op]);
+ printf("# cipher key size: %u\n", opts->cipher_key_sz);
+ printf("# cipher iv size: %u\n", opts->cipher_iv_sz);
+ printf("#\n");
+ }
+}
diff --git a/app/test-crypto-perf/cperf_test_latency.c b/app/test-crypto-perf/cperf_test_latency.c
new file mode 100644
index 0000000..3196c2f
--- /dev/null
+++ b/app/test-crypto-perf/cperf_test_latency.c
@@ -0,0 +1,685 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <rte_malloc.h>
+#include <rte_cycles.h>
+#include <rte_crypto.h>
+#include <rte_cryptodev.h>
+
+#include "cperf_test_latency.h"
+#include "cperf_ops.h"
+
+
+struct cperf_latency_results {
+
+ uint64_t ops_failed;
+
+ uint64_t enqd_tot;
+ uint64_t enqd_max;
+ uint64_t enqd_min;
+
+ uint64_t deqd_tot;
+ uint64_t deqd_max;
+ uint64_t deqd_min;
+
+ uint64_t cycles_tot;
+ uint64_t cycles_max;
+ uint64_t cycles_min;
+
+ uint64_t burst_num;
+ uint64_t num;
+};
+
+struct cperf_op_result {
+ uint64_t tsc_start;
+ uint64_t tsc_end;
+ enum rte_crypto_op_status status;
+};
+
+struct cperf_latency_ctx {
+ uint8_t dev_id;
+ uint16_t qp_id;
+ uint8_t lcore_id;
+
+ struct rte_mempool *pkt_mbuf_pool_in;
+ struct rte_mempool *pkt_mbuf_pool_out;
+ struct rte_mbuf **mbufs_in;
+ struct rte_mbuf **mbufs_out;
+
+ struct rte_mempool *crypto_op_pool;
+
+ struct rte_cryptodev_sym_session *sess;
+
+ cperf_populate_ops_t populate_ops;
+ cperf_verify_crypto_op_t verify_op_output;
+
+ const struct cperf_options *options;
+ const struct cperf_test_vector *test_vector;
+ struct cperf_op_result *res;
+ struct cperf_latency_results results;
+};
+
+#define max(a, b) (a > b ? (uint64_t)a : (uint64_t)b)
+#define min(a, b) (a < b ? (uint64_t)a : (uint64_t)b)
+
+static void
+cperf_latency_test_free(struct cperf_latency_ctx *ctx, uint32_t mbuf_nb)
+{
+ uint32_t i;
+
+ if (ctx) {
+ if (ctx->sess)
+ rte_cryptodev_sym_session_free(ctx->dev_id, ctx->sess);
+
+ if (ctx->mbufs_in) {
+ for (i = 0; i < mbuf_nb; i++)
+ rte_pktmbuf_free(ctx->mbufs_in[i]);
+
+ rte_free(ctx->mbufs_in);
+ }
+
+ if (ctx->mbufs_out) {
+ for (i = 0; i < mbuf_nb; i++) {
+ if (ctx->mbufs_out[i] != NULL)
+ rte_pktmbuf_free(ctx->mbufs_out[i]);
+ }
+
+ rte_free(ctx->mbufs_out);
+ }
+
+ if (ctx->pkt_mbuf_pool_in)
+ rte_mempool_free(ctx->pkt_mbuf_pool_in);
+
+ if (ctx->pkt_mbuf_pool_out)
+ rte_mempool_free(ctx->pkt_mbuf_pool_out);
+
+ if (ctx->crypto_op_pool)
+ rte_mempool_free(ctx->crypto_op_pool);
+
+ rte_free(ctx->res);
+ rte_free(ctx);
+ }
+}
+
+static struct rte_mbuf *
+cperf_mbuf_create(struct rte_mempool *mempool,
+ uint32_t segments_nb,
+ const struct cperf_options *options,
+ const struct cperf_test_vector *test_vector)
+{
+ struct rte_mbuf *mbuf;
+ uint32_t segment_sz = options->buffer_sz / segments_nb;
+ uint32_t last_sz = options->buffer_sz % segments_nb;
+ uint8_t *mbuf_data;
+ uint8_t *test_data =
+ (options->cipher_op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) ?
+ test_vector->plaintext.data :
+ test_vector->ciphertext.data;
+
+ mbuf = rte_pktmbuf_alloc(mempool);
+ if (mbuf == NULL)
+ goto error;
+
+ mbuf_data = (uint8_t *)rte_pktmbuf_append(mbuf, segment_sz);
+ if (mbuf_data == NULL)
+ goto error;
+
+ memcpy(mbuf_data, test_data, segment_sz);
+ test_data += segment_sz;
+ segments_nb--;
+
+ while (segments_nb) {
+ struct rte_mbuf *m;
+
+ m = rte_pktmbuf_alloc(mempool);
+ if (m == NULL)
+ goto error;
+
+ rte_pktmbuf_chain(mbuf, m);
+
+ mbuf_data = (uint8_t *)rte_pktmbuf_append(mbuf, segment_sz);
+ if (mbuf_data == NULL)
+ goto error;
+
+ memcpy(mbuf_data, test_data, segment_sz);
+ test_data += segment_sz;
+ segments_nb--;
+ }
+
+ if (last_sz) {
+ mbuf_data = (uint8_t *)rte_pktmbuf_append(mbuf, last_sz);
+ if (mbuf_data == NULL)
+ goto error;
+
+ memcpy(mbuf_data, test_data, last_sz);
+ }
+
+ mbuf_data = (uint8_t *)rte_pktmbuf_append(mbuf,
+ options->auth_digest_sz);
+ if (mbuf_data == NULL)
+ goto error;
+
+ if (options->op_type == CPERF_AEAD) {
+ uint8_t *aead = (uint8_t *)rte_pktmbuf_prepend(mbuf,
+ RTE_ALIGN_CEIL(options->auth_aad_sz, 16));
+
+ if (aead == NULL)
+ goto error;
+
+ memcpy(aead, test_vector->aad.data, test_vector->aad.length);
+ }
+
+ return mbuf;
+error:
+ if (mbuf != NULL)
+ rte_pktmbuf_free(mbuf);
+
+ return NULL;
+}
+
+void *
+cperf_latency_test_constructor(uint8_t dev_id, uint16_t qp_id,
+ const struct cperf_options *options,
+ const struct cperf_test_vector *test_vector,
+ const struct cperf_op_fns *op_fns)
+{
+ struct cperf_latency_ctx *ctx = NULL;
+ unsigned int mbuf_idx = 0;
+ char pool_name[32] = "";
+
+ ctx = rte_malloc(NULL, sizeof(struct cperf_latency_ctx), 0);
+ if (ctx == NULL)
+ goto err;
+
+ ctx->dev_id = dev_id;
+ ctx->qp_id = qp_id;
+
+ ctx->populate_ops = op_fns->populate_ops;
+ ctx->options = options;
+ ctx->test_vector = test_vector;
+
+ ctx->sess = op_fns->sess_create(dev_id, options, test_vector);
+ if (ctx->sess == NULL)
+ goto err;
+
+ snprintf(pool_name, sizeof(pool_name), "cperf_pool_in_cdev_%d",
+ dev_id);
+
+ ctx->pkt_mbuf_pool_in = rte_pktmbuf_pool_create(pool_name,
+ options->pool_sz * options->segments_nb, 0, 0,
+ RTE_PKTMBUF_HEADROOM +
+ RTE_CACHE_LINE_ROUNDUP(
+ (options->buffer_sz / options->segments_nb) +
+ (options->buffer_sz % options->segments_nb) +
+ options->auth_digest_sz),
+ rte_socket_id());
+
+ if (ctx->pkt_mbuf_pool_in == NULL)
+ goto err;
+
+ /* Generate mbufs_in with plaintext populated for test */
+ if (ctx->options->pool_sz % ctx->options->burst_sz)
+ goto err;
+
+ ctx->mbufs_in = rte_malloc(NULL,
+ (sizeof(struct rte_mbuf *) *
+ ctx->options->pool_sz), 0);
+
+ for (mbuf_idx = 0; mbuf_idx < options->pool_sz; mbuf_idx++) {
+ ctx->mbufs_in[mbuf_idx] = cperf_mbuf_create(
+ ctx->pkt_mbuf_pool_in, options->segments_nb,
+ options, test_vector);
+ if (ctx->mbufs_in[mbuf_idx] == NULL)
+ goto err;
+ }
+
+ if (options->out_of_place == 1) {
+
+ snprintf(pool_name, sizeof(pool_name),
+ "cperf_pool_out_cdev_%d",
+ dev_id);
+
+ ctx->pkt_mbuf_pool_out = rte_pktmbuf_pool_create(
+ pool_name, options->pool_sz, 0, 0,
+ RTE_PKTMBUF_HEADROOM +
+ RTE_CACHE_LINE_ROUNDUP(
+ options->buffer_sz +
+ options->auth_digest_sz),
+ rte_socket_id());
+
+ if (ctx->pkt_mbuf_pool_out == NULL)
+ goto err;
+ }
+
+ ctx->mbufs_out = rte_malloc(NULL,
+ (sizeof(struct rte_mbuf *) *
+ ctx->options->pool_sz), 0);
+
+ for (mbuf_idx = 0; mbuf_idx < options->pool_sz; mbuf_idx++) {
+ if (options->out_of_place == 1) {
+ ctx->mbufs_out[mbuf_idx] = cperf_mbuf_create(
+ ctx->pkt_mbuf_pool_out, 1,
+ options, test_vector);
+ if (ctx->mbufs_out[mbuf_idx] == NULL)
+ goto err;
+ } else {
+ ctx->mbufs_out[mbuf_idx] = NULL;
+ }
+ }
+
+ snprintf(pool_name, sizeof(pool_name), "cperf_op_pool_cdev_%d",
+ dev_id);
+
+ ctx->crypto_op_pool = rte_crypto_op_pool_create(pool_name,
+ RTE_CRYPTO_OP_TYPE_SYMMETRIC, options->pool_sz, 0, 0,
+ rte_socket_id());
+ if (ctx->crypto_op_pool == NULL)
+ goto err;
+
+ ctx->res = rte_malloc(NULL, sizeof(struct cperf_op_result) *
+ ctx->options->total_ops, 0);
+
+ if (ctx->res == NULL)
+ goto err;
+
+ return ctx;
+err:
+ cperf_latency_test_free(ctx, mbuf_idx);
+
+ return NULL;
+}
+
+static int
+cperf_latency_test_verifier(struct rte_mbuf *mbuf,
+ const struct cperf_options *options,
+ const struct cperf_test_vector *vector)
+{
+ const struct rte_mbuf *m;
+ uint32_t len;
+ uint16_t nb_segs;
+ uint8_t *data;
+ uint32_t cipher_offset, auth_offset;
+ uint8_t cipher, auth;
+ int res = 0;
+
+ m = mbuf;
+ nb_segs = m->nb_segs;
+ len = 0;
+ while (m && nb_segs != 0) {
+ len += m->data_len;
+ m = m->next;
+ nb_segs--;
+ }
+
+ data = rte_malloc(NULL, len, 0);
+ if (data == NULL)
+ return 1;
+
+ m = mbuf;
+ nb_segs = m->nb_segs;
+ len = 0;
+ while (m && nb_segs != 0) {
+ memcpy(data + len, rte_pktmbuf_mtod(m, uint8_t *),
+ m->data_len);
+ len += m->data_len;
+ m = m->next;
+ nb_segs--;
+ }
+
+ switch (options->op_type) {
+ case CPERF_CIPHER_ONLY:
+ cipher = 1;
+ cipher_offset = 0;
+ auth = 0;
+ auth_offset = 0;
+ break;
+ case CPERF_CIPHER_THEN_AUTH:
+ cipher = 1;
+ cipher_offset = 0;
+ auth = 1;
+ auth_offset = vector->plaintext.length;
+ break;
+ case CPERF_AUTH_ONLY:
+ cipher = 0;
+ cipher_offset = 0;
+ auth = 1;
+ auth_offset = vector->plaintext.length;
+ break;
+ case CPERF_AUTH_THEN_CIPHER:
+ cipher = 1;
+ cipher_offset = 0;
+ auth = 1;
+ auth_offset = vector->plaintext.length;
+ break;
+ case CPERF_AEAD:
+ cipher = 1;
+ cipher_offset = vector->aad.length;
+ auth = 1;
+ auth_offset = vector->aad.length + vector->plaintext.length;
+ break;
+ }
+
+ if (cipher == 1) {
+ if (options->cipher_op == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
+ res += memcmp(data + cipher_offset,
+ vector->ciphertext.data,
+ vector->ciphertext.length);
+ else
+ res += memcmp(data + cipher_offset,
+ vector->plaintext.data,
+ vector->plaintext.length);
+ }
+
+ if (auth == 1) {
+ if (options->auth_op == RTE_CRYPTO_AUTH_OP_GENERATE)
+ res += memcmp(data + auth_offset,
+ vector->digest.data,
+ vector->digest.length);
+ }
+
+ if (res != 0)
+ res = 1;
+
+ return res;
+}
+
+int
+cperf_latency_test_runner(void *arg)
+{
+ struct cperf_latency_ctx *ctx = arg;
+ struct cperf_op_result *pres;
+
+ if (ctx == NULL)
+ return 0;
+
+ struct rte_crypto_op *ops[ctx->options->burst_sz];
+ struct rte_crypto_op *ops_processed[ctx->options->burst_sz];
+ uint64_t ops_enqd = 0, ops_deqd = 0;
+ uint16_t ops_unused = 0;
+ uint64_t m_idx = 0, b_idx = 0, i;
+
+ uint64_t tsc_val, tsc_end, tsc_start;
+ uint64_t tsc_max = 0, tsc_min = ~0UL, tsc_tot = 0, tsc_idx = 0;
+ uint64_t enqd_max = 0, enqd_min = ~0UL, enqd_tot = 0;
+ uint64_t deqd_max = 0, deqd_min = ~0UL, deqd_tot = 0;
+
+ uint32_t lcore = rte_lcore_id();
+
+#ifdef CPERF_LINEARIZATION_ENABLE
+ struct rte_cryptodev_info dev_info;
+ int linearize = 0;
+
+ /* Check if source mbufs require coalescing */
+ if (ctx->options->segments_nb > 1) {
+ rte_cryptodev_info_get(ctx->dev_id, &dev_info);
+ if ((dev_info.feature_flags &
+ RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER) == 0)
+ linearize = 1;
+ }
+#endif /* CPERF_LINEARIZATION_ENABLE */
+
+ ctx->lcore_id = lcore;
+
+ while (enqd_tot < ctx->options->total_ops) {
+
+ uint16_t burst_size = ((enqd_tot + ctx->options->burst_sz)
+ <= ctx->options->total_ops) ?
+ ctx->options->burst_sz :
+ ctx->options->total_ops -
+ enqd_tot;
+ uint16_t ops_needed = burst_size - ops_unused;
+
+ /* Allocate crypto ops from pool */
+ if (ops_needed != rte_crypto_op_bulk_alloc(
+ ctx->crypto_op_pool,
+ RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+ ops, ops_needed))
+ return -1;
+
+ /* Setup crypto op, attach mbuf etc */
+ (ctx->populate_ops)(ops, &ctx->mbufs_in[m_idx],
+ &ctx->mbufs_out[m_idx],
+ ops_needed, ctx->sess, ctx->options,
+ ctx->test_vector);
+
+ tsc_start = rte_rdtsc_precise();
+
+#ifdef CPERF_LINEARIZATION_ENABLE
+ if (linearize) {
+ /* PMD doesn't support scatter-gather and source buffer
+ * is segmented.
+ * We need to linearize it before enqueuing.
+ */
+ for (i = 0; i < burst_size; i++)
+ rte_pktmbuf_linearize(ops[i]->sym->m_src);
+ }
+#endif /* CPERF_LINEARIZATION_ENABLE */
+
+ /* Enqueue burst of ops on crypto device */
+ ops_enqd = rte_cryptodev_enqueue_burst(ctx->dev_id, ctx->qp_id,
+ ops, burst_size);
+
+ /* Dequeue processed burst of ops from crypto device */
+ ops_deqd = rte_cryptodev_dequeue_burst(ctx->dev_id, ctx->qp_id,
+ ops_processed, ctx->options->burst_sz);
+
+ tsc_end = rte_rdtsc_precise();
+
+ for (i = 0; i < burst_size; i++) {
+ ctx->res[tsc_idx].tsc_start = tsc_start;
+ ops[i]->opaque_data = (void *)&ctx->res[tsc_idx];
+ tsc_idx++;
+ }
+
+ /*
+ * Calculate number of ops not enqueued (mainly for hw
+ * accelerators whose ingress queue can fill up).
+ */
+ ops_unused = burst_size - ops_enqd;
+
+ if (likely(ops_deqd)) {
+ /*
+ * free crypto ops so they can be reused. We don't free
+ * the mbufs here as we don't want to reuse them as
+ * the crypto operation will change the data and cause
+ * failures.
+ */
+ for (i = 0; i < ops_deqd; i++) {
+ pres = (struct cperf_op_result *)
+ (ops_processed[i]->opaque_data);
+ pres->tsc_end = tsc_end;
+ pres->status = ops_processed[i]->status;
+
+ rte_crypto_op_free(ops_processed[i]);
+ }
+
+ deqd_tot += ops_deqd;
+ deqd_max = max(ops_deqd, deqd_max);
+ deqd_min = min(ops_deqd, deqd_min);
+ }
+
+ enqd_tot += ops_enqd;
+ enqd_max = max(ops_enqd, enqd_max);
+ enqd_min = min(ops_enqd, enqd_min);
+
+ m_idx += ops_needed;
+ m_idx = m_idx + ctx->options->burst_sz > ctx->options->pool_sz ?
+ 0 : m_idx;
+ b_idx++;
+ }
+
+ /* Dequeue any operations still in the crypto device */
+ while (deqd_tot < ctx->options->total_ops) {
+ /* Sending 0 length burst to flush sw crypto device */
+ rte_cryptodev_enqueue_burst(ctx->dev_id, ctx->qp_id, NULL, 0);
+
+ /* dequeue burst */
+ ops_deqd = rte_cryptodev_dequeue_burst(ctx->dev_id, ctx->qp_id,
+ ops_processed, ctx->options->burst_sz);
+
+ tsc_end = rte_rdtsc_precise();
+
+ if (ops_deqd != 0) {
+ for (i = 0; i < ops_deqd; i++) {
+ pres = (struct cperf_op_result *)
+ (ops_processed[i]->opaque_data);
+ pres->tsc_end = tsc_end;
+ pres->status = ops_processed[i]->status;
+
+ rte_crypto_op_free(ops_processed[i]);
+ }
+
+ deqd_tot += ops_deqd;
+ deqd_max = max(ops_deqd, deqd_max);
+ deqd_min = min(ops_deqd, deqd_min);
+ }
+ }
+
+ for (i = 0; i < tsc_idx; i++) {
+ tsc_val = ctx->res[i].tsc_end - ctx->res[i].tsc_start;
+ tsc_max = max(tsc_val, tsc_max);
+ tsc_min = min(tsc_val, tsc_min);
+ tsc_tot += tsc_val;
+ }
+
+ if (ctx->options->verify) {
+ struct rte_mbuf **mbufs;
+
+ if (ctx->options->out_of_place == 1)
+ mbufs = ctx->mbufs_out;
+ else
+ mbufs = ctx->mbufs_in;
+
+ for (i = 0; i < ctx->options->total_ops; i++) {
+
+ if (ctx->res[i].status != RTE_CRYPTO_OP_STATUS_SUCCESS
+ || cperf_latency_test_verifier(mbufs[i],
+ ctx->options,
+ ctx->test_vector)) {
+
+ ctx->results.ops_failed++;
+ }
+ }
+ }
+
+ ctx->results.enqd_tot = enqd_tot;
+ ctx->results.enqd_max = enqd_max;
+ ctx->results.enqd_min = enqd_min;
+
+ ctx->results.deqd_tot = deqd_tot;
+ ctx->results.deqd_max = deqd_max;
+ ctx->results.deqd_min = deqd_min;
+
+ ctx->results.cycles_tot = tsc_tot;
+ ctx->results.cycles_max = tsc_max;
+ ctx->results.cycles_min = tsc_min;
+
+ ctx->results.burst_num = b_idx;
+ ctx->results.num = tsc_idx;
+
+ return 0;
+}
+
+void
+cperf_latency_test_destructor(void *arg)
+{
+ struct cperf_latency_ctx *ctx = arg;
+ uint64_t i;
+ if (ctx == NULL)
+ return;
+ static int only_once;
+ uint64_t etot, eavg, emax, emin;
+ uint64_t dtot, davg, dmax, dmin;
+ uint64_t ctot, cavg, cmax, cmin;
+ double ttot, tavg, tmax, tmin;
+
+ const uint64_t tunit = 1000000; /* us */
+ const uint64_t tsc_hz = rte_get_tsc_hz();
+
+ etot = ctx->results.enqd_tot;
+ eavg = ctx->results.enqd_tot / ctx->results.burst_num;
+ emax = ctx->results.enqd_max;
+ emin = ctx->results.enqd_min;
+
+ dtot = ctx->results.deqd_tot;
+ davg = ctx->results.deqd_tot / ctx->results.burst_num;
+ dmax = ctx->results.deqd_max;
+ dmin = ctx->results.deqd_min;
+
+ ctot = ctx->results.cycles_tot;
+ cavg = ctx->results.cycles_tot / ctx->results.num;
+ cmax = ctx->results.cycles_max;
+ cmin = ctx->results.cycles_min;
+
+ ttot = tunit*(double)(ctot) / tsc_hz;
+ tavg = tunit*(double)(cavg) / tsc_hz;
+ tmax = tunit*(double)(cmax) / tsc_hz;
+ tmin = tunit*(double)(cmin) / tsc_hz;
+
+ if (ctx->options->csv) {
+ if (!only_once)
+ printf("\n# lcore, Pakt Seq #, Packet Size, cycles,"
+ " time (us)");
+
+ for (i = 0; i < ctx->options->total_ops; i++) {
+
+ printf("\n%u;%lu;%lu;%.3f", ctx->lcore_id, i + 1,
+ ctx->res[i].tsc_end - ctx->res[i].tsc_start,
+ tunit * (double) (ctx->res[i].tsc_end
+ - ctx->res[i].tsc_start)
+ / tsc_hz);
+
+ }
+ only_once = 1;
+ } else {
+ printf("\n# Device %d on lcore %u\n", ctx->dev_id,
+ ctx->lcore_id);
+ printf("\n# total operations: %u", ctx->options->total_ops);
+ printf("\n# verified failed: %lu", ctx->results.ops_failed);
+ printf("\n# burst number: %lu", ctx->results.burst_num);
+ printf("\n#");
+ printf("\n# \t Total\t Average\t Maximum\t "
+ " Minimum");
+ printf("\n# enqueued\t%12lu\t%10lu\t%10lu\t%10lu", etot, eavg,
+ emax, emin);
+ printf("\n# dequeued\t%12lu\t%10lu\t%10lu\t%10lu", dtot, davg,
+ dmax, dmin);
+ printf("\n# cycles\t%12lu\t%10lu\t%10lu\t%10lu", ctot, cavg,
+ cmax, cmin);
+ printf("\n# time [us]\t%12.0f\t%10.3f\t%10.3f\t%10.3f", ttot,
+ tavg, tmax, tmin);
+ printf("\n\n");
+
+ }
+ cperf_latency_test_free(ctx, ctx->options->pool_sz);
+
+}
diff --git a/app/test-crypto-perf/cperf_test_latency.h b/app/test-crypto-perf/cperf_test_latency.h
new file mode 100644
index 0000000..5e3eea8
--- /dev/null
+++ b/app/test-crypto-perf/cperf_test_latency.h
@@ -0,0 +1,57 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _CPERF_LATENCY_
+#define _CPERF_LATENCY_
+
+#include <stdint.h>
+
+#include <rte_mbuf.h>
+
+#include "cperf.h"
+#include "cperf_ops.h"
+#include "cperf_options.h"
+#include "cperf_test_vectors.h"
+
+void *
+cperf_latency_test_constructor(uint8_t dev_id, uint16_t qp_id,
+ const struct cperf_options *options,
+ const struct cperf_test_vector *test_vector,
+ const struct cperf_op_fns *ops_fn);
+
+int
+cperf_latency_test_runner(void *test_ctx);
+
+void
+cperf_latency_test_destructor(void *test_ctx);
+
+#endif /* _CPERF_LATENCY_ */
diff --git a/app/test-crypto-perf/cperf_test_throughput.c b/app/test-crypto-perf/cperf_test_throughput.c
new file mode 100644
index 0000000..5128267
--- /dev/null
+++ b/app/test-crypto-perf/cperf_test_throughput.c
@@ -0,0 +1,651 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <rte_malloc.h>
+#include <rte_cycles.h>
+#include <rte_crypto.h>
+#include <rte_cryptodev.h>
+
+#include "cperf_test_throughput.h"
+#include "cperf_ops.h"
+
+struct cperf_throughput_results {
+ uint64_t ops_enqueued;
+ uint64_t ops_dequeued;
+
+ uint64_t ops_enqueued_failed;
+ uint64_t ops_dequeued_failed;
+
+ uint64_t ops_failed;
+
+ double ops_per_second;
+ double throughput_gbps;
+ double cycles_per_byte;
+};
+
+struct cperf_throughput_ctx {
+ uint8_t dev_id;
+ uint16_t qp_id;
+ uint8_t lcore_id;
+
+ struct rte_mempool *pkt_mbuf_pool_in;
+ struct rte_mempool *pkt_mbuf_pool_out;
+ struct rte_mbuf **mbufs_in;
+ struct rte_mbuf **mbufs_out;
+
+ struct rte_mempool *crypto_op_pool;
+
+ struct rte_cryptodev_sym_session *sess;
+
+ cperf_populate_ops_t populate_ops;
+ cperf_verify_crypto_op_t verify_op_output;
+
+ const struct cperf_options *options;
+ const struct cperf_test_vector *test_vector;
+ struct cperf_throughput_results results;
+
+};
+
+struct cperf_op_result {
+ enum rte_crypto_op_status status;
+};
+
+static void
+cperf_throughput_test_free(struct cperf_throughput_ctx *ctx, uint32_t mbuf_nb)
+{
+ uint32_t i;
+
+ if (ctx) {
+ if (ctx->sess)
+ rte_cryptodev_sym_session_free(ctx->dev_id, ctx->sess);
+
+ if (ctx->mbufs_in) {
+ for (i = 0; i < mbuf_nb; i++)
+ rte_pktmbuf_free(ctx->mbufs_in[i]);
+
+ rte_free(ctx->mbufs_in);
+ }
+
+ if (ctx->mbufs_out) {
+ for (i = 0; i < mbuf_nb; i++) {
+ if (ctx->mbufs_out[i] != NULL)
+ rte_pktmbuf_free(ctx->mbufs_out[i]);
+ }
+
+ rte_free(ctx->mbufs_out);
+ }
+
+ if (ctx->pkt_mbuf_pool_in)
+ rte_mempool_free(ctx->pkt_mbuf_pool_in);
+
+ if (ctx->pkt_mbuf_pool_out)
+ rte_mempool_free(ctx->pkt_mbuf_pool_out);
+
+ if (ctx->crypto_op_pool)
+ rte_mempool_free(ctx->crypto_op_pool);
+
+ rte_free(ctx);
+ }
+}
+
+static struct rte_mbuf *
+cperf_mbuf_create(struct rte_mempool *mempool,
+ uint32_t segments_nb,
+ const struct cperf_options *options,
+ const struct cperf_test_vector *test_vector)
+{
+ struct rte_mbuf *mbuf;
+ uint32_t segment_sz = options->buffer_sz / segments_nb;
+ uint32_t last_sz = options->buffer_sz % segments_nb;
+ uint8_t *mbuf_data;
+ uint8_t *test_data =
+ (options->cipher_op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) ?
+ test_vector->plaintext.data :
+ test_vector->ciphertext.data;
+
+ mbuf = rte_pktmbuf_alloc(mempool);
+ if (mbuf == NULL)
+ goto error;
+
+ mbuf_data = (uint8_t *)rte_pktmbuf_append(mbuf, segment_sz);
+ if (mbuf_data == NULL)
+ goto error;
+
+ memcpy(mbuf_data, test_data, segment_sz);
+ test_data += segment_sz;
+ segments_nb--;
+
+ while (segments_nb) {
+ struct rte_mbuf *m;
+
+ m = rte_pktmbuf_alloc(mempool);
+ if (m == NULL)
+ goto error;
+
+ rte_pktmbuf_chain(mbuf, m);
+
+ mbuf_data = (uint8_t *)rte_pktmbuf_append(mbuf, segment_sz);
+ if (mbuf_data == NULL)
+ goto error;
+
+ memcpy(mbuf_data, test_data, segment_sz);
+ test_data += segment_sz;
+ segments_nb--;
+ }
+
+ if (last_sz) {
+ mbuf_data = (uint8_t *)rte_pktmbuf_append(mbuf, last_sz);
+ if (mbuf_data == NULL)
+ goto error;
+
+ memcpy(mbuf_data, test_data, last_sz);
+ }
+
+ mbuf_data = (uint8_t *)rte_pktmbuf_append(mbuf,
+ options->auth_digest_sz);
+ if (mbuf_data == NULL)
+ goto error;
+
+ if (options->op_type == CPERF_AEAD) {
+ uint8_t *aead = (uint8_t *)rte_pktmbuf_prepend(mbuf,
+ RTE_ALIGN_CEIL(options->auth_aad_sz, 16));
+
+ if (aead == NULL)
+ goto error;
+
+ memcpy(aead, test_vector->aad.data, test_vector->aad.length);
+ }
+
+ return mbuf;
+error:
+ if (mbuf != NULL)
+ rte_pktmbuf_free(mbuf);
+
+ return NULL;
+}
+
+void *
+cperf_throughput_test_constructor(uint8_t dev_id, uint16_t qp_id,
+ const struct cperf_options *options,
+ const struct cperf_test_vector *test_vector,
+ const struct cperf_op_fns *op_fns)
+{
+ struct cperf_throughput_ctx *ctx = NULL;
+ unsigned int mbuf_idx;
+ char pool_name[32] = "";
+
+ ctx = rte_malloc(NULL, sizeof(struct cperf_throughput_ctx), 0);
+ if (ctx == NULL)
+ goto err;
+
+ ctx->dev_id = dev_id;
+ ctx->qp_id = qp_id;
+
+ ctx->populate_ops = op_fns->populate_ops;
+ ctx->options = options;
+ ctx->test_vector = test_vector;
+
+ ctx->sess = op_fns->sess_create(dev_id, options, test_vector);
+ if (ctx->sess == NULL)
+ goto err;
+
+ snprintf(pool_name, sizeof(pool_name), "cperf_pool_in_cdev_%d",
+ dev_id);
+
+ ctx->pkt_mbuf_pool_in = rte_pktmbuf_pool_create(pool_name,
+ options->pool_sz * options->segments_nb, 0, 0,
+ RTE_PKTMBUF_HEADROOM +
+ RTE_CACHE_LINE_ROUNDUP(
+ (options->buffer_sz / options->segments_nb) +
+ (options->buffer_sz % options->segments_nb) +
+ options->auth_digest_sz),
+ rte_socket_id());
+
+ if (ctx->pkt_mbuf_pool_in == NULL)
+ goto err;
+
+ /* Generate mbufs_in with plaintext populated for test */
+ if (ctx->options->pool_sz % ctx->options->burst_sz)
+ goto err;
+
+ ctx->mbufs_in = rte_malloc(NULL,
+ (sizeof(struct rte_mbuf *) * ctx->options->pool_sz), 0);
+
+ for (mbuf_idx = 0; mbuf_idx < options->pool_sz; mbuf_idx++) {
+ ctx->mbufs_in[mbuf_idx] = cperf_mbuf_create(
+ ctx->pkt_mbuf_pool_in, options->segments_nb,
+ options, test_vector);
+ if (ctx->mbufs_in[mbuf_idx] == NULL)
+ goto err;
+ }
+
+ if (options->out_of_place == 1) {
+
+ snprintf(pool_name, sizeof(pool_name), "cperf_pool_out_cdev_%d",
+ dev_id);
+
+ ctx->pkt_mbuf_pool_out = rte_pktmbuf_pool_create(
+ pool_name, options->pool_sz, 0, 0,
+ RTE_PKTMBUF_HEADROOM +
+ RTE_CACHE_LINE_ROUNDUP(
+ options->buffer_sz +
+ options->auth_digest_sz),
+ rte_socket_id());
+
+ if (ctx->pkt_mbuf_pool_out == NULL)
+ goto err;
+ }
+
+ ctx->mbufs_out = rte_malloc(NULL,
+ (sizeof(struct rte_mbuf *) *
+ ctx->options->pool_sz), 0);
+
+ for (mbuf_idx = 0; mbuf_idx < options->pool_sz; mbuf_idx++) {
+ if (options->out_of_place == 1) {
+ ctx->mbufs_out[mbuf_idx] = cperf_mbuf_create(
+ ctx->pkt_mbuf_pool_out, 1,
+ options, test_vector);
+ if (ctx->mbufs_out[mbuf_idx] == NULL)
+ goto err;
+ } else {
+ ctx->mbufs_out[mbuf_idx] = NULL;
+ }
+ }
+
+ snprintf(pool_name, sizeof(pool_name), "cperf_op_pool_cdev_%d",
+ dev_id);
+
+ ctx->crypto_op_pool = rte_crypto_op_pool_create(pool_name,
+ RTE_CRYPTO_OP_TYPE_SYMMETRIC, options->pool_sz, 0, 0,
+ rte_socket_id());
+ if (ctx->crypto_op_pool == NULL)
+ goto err;
+
+ return ctx;
+err:
+ cperf_throughput_test_free(ctx, mbuf_idx);
+
+ return NULL;
+}
+
+static int
+cperf_throughput_test_verifier(struct rte_mbuf *mbuf,
+ const struct cperf_options *options,
+ const struct cperf_test_vector *vector)
+{
+ const struct rte_mbuf *m;
+ uint32_t len;
+ uint16_t nb_segs;
+ uint8_t *data;
+ uint32_t cipher_offset, auth_offset;
+ uint8_t cipher, auth;
+ int res = 0;
+
+ m = mbuf;
+ nb_segs = m->nb_segs;
+ len = 0;
+ while (m && nb_segs != 0) {
+ len += m->data_len;
+ m = m->next;
+ nb_segs--;
+ }
+
+ data = rte_malloc(NULL, len, 0);
+ if (data == NULL)
+ return 1;
+
+ m = mbuf;
+ nb_segs = m->nb_segs;
+ len = 0;
+ while (m && nb_segs != 0) {
+ memcpy(data + len, rte_pktmbuf_mtod(m, uint8_t *),
+ m->data_len);
+ len += m->data_len;
+ m = m->next;
+ nb_segs--;
+ }
+
+ switch (options->op_type) {
+ case CPERF_CIPHER_ONLY:
+ cipher = 1;
+ cipher_offset = 0;
+ auth = 0;
+ auth_offset = 0;
+ break;
+ case CPERF_CIPHER_THEN_AUTH:
+ cipher = 1;
+ cipher_offset = 0;
+ auth = 1;
+ auth_offset = vector->plaintext.length;
+ break;
+ case CPERF_AUTH_ONLY:
+ cipher = 0;
+ cipher_offset = 0;
+ auth = 1;
+ auth_offset = vector->plaintext.length;
+ break;
+ case CPERF_AUTH_THEN_CIPHER:
+ cipher = 1;
+ cipher_offset = 0;
+ auth = 1;
+ auth_offset = vector->plaintext.length;
+ break;
+ case CPERF_AEAD:
+ cipher = 1;
+ cipher_offset = vector->aad.length;
+ auth = 1;
+ auth_offset = vector->aad.length + vector->plaintext.length;
+ break;
+ }
+
+ if (cipher == 1) {
+ if (options->cipher_op == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
+ res += memcmp(data + cipher_offset,
+ vector->ciphertext.data,
+ vector->ciphertext.length);
+ else
+ res += memcmp(data + cipher_offset,
+ vector->plaintext.data,
+ vector->plaintext.length);
+ }
+
+ if (auth == 1) {
+ if (options->auth_op == RTE_CRYPTO_AUTH_OP_GENERATE)
+ res += memcmp(data + auth_offset,
+ vector->digest.data,
+ vector->digest.length);
+ }
+
+ if (res != 0)
+ res = 1;
+
+ return res;
+}
+
+int
+cperf_throughput_test_runner(void *test_ctx)
+{
+ struct cperf_throughput_ctx *ctx = test_ctx;
+ struct cperf_op_result *res, *pres;
+
+ res = rte_malloc(NULL, sizeof(struct cperf_op_result) *
+ ctx->options->total_ops, 0);
+ if (res == NULL)
+ return 0;
+
+ uint64_t ops_enqd = 0, ops_enqd_total = 0, ops_enqd_failed = 0;
+ uint64_t ops_deqd = 0, ops_deqd_total = 0, ops_deqd_failed = 0;
+
+ uint64_t i, m_idx = 0, tsc_start, tsc_end, tsc_duration;
+
+ uint16_t ops_unused = 0;
+ uint64_t idx = 0;
+
+ struct rte_crypto_op *ops[ctx->options->burst_sz];
+ struct rte_crypto_op *ops_processed[ctx->options->burst_sz];
+
+ uint32_t lcore = rte_lcore_id();
+
+#ifdef CPERF_LINEARIZATION_ENABLE
+ struct rte_cryptodev_info dev_info;
+ int linearize = 0;
+
+ /* Check if source mbufs require coalescing */
+ if (ctx->options->segments_nb > 1) {
+ rte_cryptodev_info_get(ctx->dev_id, &dev_info);
+ if ((dev_info.feature_flags &
+ RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER) == 0)
+ linearize = 1;
+ }
+#endif /* CPERF_LINEARIZATION_ENABLE */
+
+ ctx->lcore_id = lcore;
+
+ if (!ctx->options->csv)
+ printf("\n# Running throughput test on device: %u, lcore: %u\n",
+ ctx->dev_id, lcore);
+
+ rte_cryptodev_enqueue_burst(ctx->dev_id, ctx->qp_id, NULL, 0);
+
+ for (i = 0; i < ctx->options->total_ops; i++)
+ rte_cryptodev_dequeue_burst(ctx->dev_id, ctx->qp_id,
+ ops_processed, ctx->options->burst_sz);
+
+ tsc_start = rte_rdtsc_precise();
+
+ while (ops_enqd_total < ctx->options->total_ops) {
+
+ uint16_t burst_size = ((ops_enqd_total + ctx->options->burst_sz)
+ <= ctx->options->total_ops) ?
+ ctx->options->burst_sz :
+ ctx->options->total_ops -
+ ops_enqd_total;
+
+ uint16_t ops_needed = burst_size - ops_unused;
+
+ /* Allocate crypto ops from pool */
+ if (ops_needed != rte_crypto_op_bulk_alloc(
+ ctx->crypto_op_pool,
+ RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+ ops, ops_needed))
+ return -1;
+
+ /* Setup crypto op, attach mbuf etc */
+ (ctx->populate_ops)(ops, &ctx->mbufs_in[m_idx],
+ &ctx->mbufs_out[m_idx],
+ ops_needed, ctx->sess, ctx->options,
+ ctx->test_vector);
+
+ for (i = 0; i < burst_size; i++) {
+ ops[i]->opaque_data = (void *)&res[idx];
+ idx++;
+ }
+
+#ifdef CPERF_LINEARIZATION_ENABLE
+ if (linearize) {
+ /* PMD doesn't support scatter-gather and source buffer
+ * is segmented.
+ * We need to linearize it before enqueuing.
+ */
+ for (i = 0; i < burst_size; i++)
+ rte_pktmbuf_linearize(ops[i]->sym->m_src);
+ }
+#endif /* CPERF_LINEARIZATION_ENABLE */
+
+ /* Enqueue burst of ops on crypto device */
+ ops_enqd = rte_cryptodev_enqueue_burst(ctx->dev_id, ctx->qp_id,
+ ops, burst_size);
+ if (ops_enqd < burst_size)
+ ops_enqd_failed++;
+
+ /**
+ * Calculate number of ops not enqueued (mainly for hw
+ * accelerators whose ingress queue can fill up).
+ */
+ ops_unused = burst_size - ops_enqd;
+ ops_enqd_total += ops_enqd;
+
+
+ /* Dequeue processed burst of ops from crypto device */
+ ops_deqd = rte_cryptodev_dequeue_burst(ctx->dev_id, ctx->qp_id,
+ ops_processed, ctx->options->burst_sz);
+ if (likely(ops_deqd)) {
+ /* free crypto ops so they can be reused. We don't free
+ * the mbufs here as we don't want to reuse them as
+ * the crypto operation will change the data and cause
+ * failures.
+ */
+ for (i = 0; i < ops_deqd; i++) {
+ pres = (struct cperf_op_result *)
+ (ops_processed[i]->opaque_data);
+ pres->status = ops_processed[i]->status;
+
+ rte_crypto_op_free(ops_processed[i]);
+ }
+
+ ops_deqd_total += ops_deqd;
+ } else {
+ /**
+ * Count dequeue polls which didn't return any
+ * processed operations. This statistic is mainly
+ * relevant to hw accelerators.
+ */
+ ops_deqd_failed++;
+ }
+
+ m_idx += ops_needed;
+ m_idx = m_idx + ctx->options->burst_sz > ctx->options->pool_sz ?
+ 0 : m_idx;
+ }
+
+ /* Dequeue any operations still in the crypto device */
+
+ while (ops_deqd_total < ctx->options->total_ops) {
+ /* Sending 0 length burst to flush sw crypto device */
+ rte_cryptodev_enqueue_burst(ctx->dev_id, ctx->qp_id, NULL, 0);
+
+ /* dequeue burst */
+ ops_deqd = rte_cryptodev_dequeue_burst(ctx->dev_id, ctx->qp_id,
+ ops_processed, ctx->options->burst_sz);
+ if (ops_deqd == 0)
+ ops_deqd_failed++;
+ else {
+ for (i = 0; i < ops_deqd; i++) {
+ pres = (struct cperf_op_result *)
+ (ops_processed[i]->opaque_data);
+ pres->status = ops_processed[i]->status;
+
+ rte_crypto_op_free(ops_processed[i]);
+ }
+
+ ops_deqd_total += ops_deqd;
+ }
+ }
+
+ tsc_end = rte_rdtsc_precise();
+ tsc_duration = (tsc_end - tsc_start);
+
+ if (ctx->options->verify) {
+ struct rte_mbuf **mbufs;
+
+ if (ctx->options->out_of_place == 1)
+ mbufs = ctx->mbufs_out;
+ else
+ mbufs = ctx->mbufs_in;
+
+ for (i = 0; i < ctx->options->total_ops; i++) {
+
+ if (res[i].status != RTE_CRYPTO_OP_STATUS_SUCCESS ||
+ cperf_throughput_test_verifier(
+ mbufs[i], ctx->options,
+ ctx->test_vector)) {
+
+ ctx->results.ops_failed++;
+ }
+ }
+ }
+
+ rte_free(res);
+
+ /* Calculate average operations processed per second */
+ ctx->results.ops_per_second = ((double)ctx->options->total_ops /
+ tsc_duration) * rte_get_tsc_hz();
+
+ /* Calculate average throughput (Gbps) in bits per second */
+ ctx->results.throughput_gbps = ((ctx->results.ops_per_second *
+ ctx->options->buffer_sz * 8) / 1000000000);
+
+
+ /* Calculate average cycles per byte */
+ ctx->results.cycles_per_byte = ((double)tsc_duration /
+ ctx->options->total_ops) / ctx->options->buffer_sz;
+
+ ctx->results.ops_enqueued = ops_enqd_total;
+ ctx->results.ops_dequeued = ops_deqd_total;
+
+ ctx->results.ops_enqueued_failed = ops_enqd_failed;
+ ctx->results.ops_dequeued_failed = ops_deqd_failed;
+
+ return 0;
+}
+
+
+
+void
+cperf_throughput_test_destructor(void *arg)
+{
+ struct cperf_throughput_ctx *ctx = arg;
+ struct cperf_throughput_results *results = &ctx->results;
+ static int only_once;
+
+ if (ctx == NULL)
+ return;
+
+ if (!ctx->options->csv) {
+ printf("\n# Device %d on lcore %u\n",
+ ctx->dev_id, ctx->lcore_id);
+ printf("# Buffer Size(B)\t Enqueued\t Dequeued\tFailed Enq"
+ "\tFailed Deq\tOps(Millions)\tThroughput(Gbps)"
+ "\tCycles Per Byte\n");
+
+ printf("\n%16u\t%10lu\t%10lu\t%10lu\t%10lu\t%13.0f\t%16.4f"
+ "\t%15.2f\n",
+ ctx->options->buffer_sz,
+ results->ops_enqueued,
+ results->ops_dequeued,
+ results->ops_enqueued_failed,
+ results->ops_dequeued_failed,
+ results->ops_per_second,
+ results->throughput_gbps,
+ results->cycles_per_byte);
+ } else {
+ if (!only_once)
+ printf("\n# CPU lcore id, Burst Size(B), "
+ "Buffer Size(B),Enqueued,Dequeued,Failed Enq,"
+ "Failed Deq,Ops(Millions),Throughput(Gbps),"
+ "Cycles Per Byte\n");
+ only_once = 1;
+ printf("%u;%u;%u;%lu;%lu;%lu;%lu;%.f3;%.f3;%.f3\n",
+ ctx->lcore_id,
+ ctx->options->burst_sz,
+ ctx->options->buffer_sz,
+ results->ops_enqueued,
+ results->ops_dequeued,
+ results->ops_enqueued_failed,
+ results->ops_dequeued_failed,
+ results->ops_per_second,
+ results->throughput_gbps,
+ results->cycles_per_byte);
+ }
+
+ cperf_throughput_test_free(ctx, ctx->options->pool_sz);
+}
diff --git a/app/test-crypto-perf/cperf_test_throughput.h b/app/test-crypto-perf/cperf_test_throughput.h
new file mode 100644
index 0000000..497a490
--- /dev/null
+++ b/app/test-crypto-perf/cperf_test_throughput.h
@@ -0,0 +1,58 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _CPERF_THROUGHPUT_
+#define _CPERF_THROUGHPUT_
+
+#include <stdint.h>
+
+#include <rte_mbuf.h>
+
+#include "cperf.h"
+#include "cperf_ops.h"
+#include "cperf_options.h"
+#include "cperf_test_vectors.h"
+
+
+void *
+cperf_throughput_test_constructor(uint8_t dev_id, uint16_t qp_id,
+ const struct cperf_options *options,
+ const struct cperf_test_vector *test_vector,
+ const struct cperf_op_fns *ops_fn);
+
+int
+cperf_throughput_test_runner(void *test_ctx);
+
+void
+cperf_throughput_test_destructor(void *test_ctx);
+
+#endif /* _CPERF_THROUGHPUT_ */
diff --git a/app/test-crypto-perf/cperf_test_vector_parsing.c b/app/test-crypto-perf/cperf_test_vector_parsing.c
new file mode 100644
index 0000000..e0bcb20
--- /dev/null
+++ b/app/test-crypto-perf/cperf_test_vector_parsing.c
@@ -0,0 +1,500 @@
+#include <stdio.h>
+
+#include <rte_malloc.h>
+
+#include "cperf_options.h"
+#include "cperf_test_vectors.h"
+#include "cperf_test_vector_parsing.h"
+
+int
+free_test_vector(struct cperf_test_vector *vector, struct cperf_options *opts)
+{
+ if (vector == NULL || opts == NULL)
+ return -1;
+
+ rte_free(vector->iv.data);
+ rte_free(vector->aad.data);
+ rte_free(vector->digest.data);
+
+ if (opts->test_file != NULL) {
+ rte_free(vector->plaintext.data);
+ rte_free(vector->cipher_key.data);
+ rte_free(vector->auth_key.data);
+ rte_free(vector->ciphertext.data);
+ }
+
+ rte_free(vector);
+
+ return 0;
+}
+
+void
+show_test_vector(struct cperf_test_vector *test_vector)
+{
+ const uint8_t wrap = 32;
+ uint32_t i;
+
+ if (test_vector == NULL)
+ return;
+
+ if (test_vector->plaintext.data) {
+ printf("\nplaintext =\n");
+ for (i = 0; i < test_vector->plaintext.length; ++i) {
+ if ((i % wrap == 0) && (i != 0))
+ printf("\n");
+ if (i == test_vector->plaintext.length - 1)
+ printf("0x%02x",
+ test_vector->plaintext.data[i]);
+ else
+ printf("0x%02x, ",
+ test_vector->plaintext.data[i]);
+ }
+ printf("\n");
+ }
+
+ if (test_vector->cipher_key.data) {
+ printf("\ncipher_key =\n");
+ for (i = 0; i < test_vector->cipher_key.length; ++i) {
+ if ((i % wrap == 0) && (i != 0))
+ printf("\n");
+ if (i == (uint32_t)(test_vector->cipher_key.length - 1))
+ printf("0x%02x",
+ test_vector->cipher_key.data[i]);
+ else
+ printf("0x%02x, ",
+ test_vector->cipher_key.data[i]);
+ }
+ printf("\n");
+ }
+
+ if (test_vector->auth_key.data) {
+ printf("\nauth_key =\n");
+ for (i = 0; i < test_vector->auth_key.length; ++i) {
+ if ((i % wrap == 0) && (i != 0))
+ printf("\n");
+ if (i == (uint32_t)(test_vector->auth_key.length - 1))
+ printf("0x%02x", test_vector->auth_key.data[i]);
+ else
+ printf("0x%02x, ",
+ test_vector->auth_key.data[i]);
+ }
+ printf("\n");
+ }
+
+ if (test_vector->iv.data) {
+ printf("\niv =\n");
+ for (i = 0; i < test_vector->iv.length; ++i) {
+ if ((i % wrap == 0) && (i != 0))
+ printf("\n");
+ if (i == (uint32_t)(test_vector->iv.length - 1))
+ printf("0x%02x", test_vector->iv.data[i]);
+ else
+ printf("0x%02x, ", test_vector->iv.data[i]);
+ }
+ printf("\n");
+ }
+
+ if (test_vector->ciphertext.data) {
+ printf("\nciphertext =\n");
+ for (i = 0; i < test_vector->ciphertext.length; ++i) {
+ if ((i % wrap == 0) && (i != 0))
+ printf("\n");
+ if (i == test_vector->ciphertext.length - 1)
+ printf("0x%02x",
+ test_vector->ciphertext.data[i]);
+ else
+ printf("0x%02x, ",
+ test_vector->ciphertext.data[i]);
+ }
+ printf("\n");
+ }
+
+ if (test_vector->aad.data) {
+ printf("\naad =\n");
+ for (i = 0; i < test_vector->aad.length; ++i) {
+ if ((i % wrap == 0) && (i != 0))
+ printf("\n");
+ if (i == (uint32_t)(test_vector->aad.length - 1))
+ printf("0x%02x", test_vector->aad.data[i]);
+ else
+ printf("0x%02x, ", test_vector->aad.data[i]);
+ }
+ printf("\n");
+ }
+
+ if (test_vector->digest.data) {
+ printf("\ndigest =\n");
+ for (i = 0; i < test_vector->digest.length; ++i) {
+ if ((i % wrap == 0) && (i != 0))
+ printf("\n");
+ if (i == (uint32_t)(test_vector->digest.length - 1))
+ printf("0x%02x", test_vector->digest.data[i]);
+ else
+ printf("0x%02x, ", test_vector->digest.data[i]);
+ }
+ printf("\n");
+ }
+}
+
+/* trim leading and trailing spaces */
+static char *
+trim_space(char *str)
+{
+ char *start, *end;
+
+ for (start = str; *start; start++) {
+ if (!isspace((unsigned char) start[0]))
+ break;
+ }
+
+ for (end = start + strlen(start); end > start + 1; end--) {
+ if (!isspace((unsigned char) end[-1]))
+ break;
+ }
+
+ *end = 0;
+
+ /* Shift from "start" to the beginning of the string */
+ if (start > str)
+ memmove(str, start, (end - start) + 1);
+
+ return str;
+}
+
+/* tokenization test values separated by a comma */
+static int
+parse_values(char *tokens, uint8_t **data, uint32_t *data_length)
+{
+ uint32_t n_tokens;
+ uint32_t data_size = 32;
+
+ uint8_t *values, *values_resized;
+ char *tok, *error = NULL;
+
+ tok = strtok(tokens, CPERF_VALUE_DELIMITER);
+ if (tok == NULL)
+ return -1;
+
+ values = (uint8_t *) rte_zmalloc(NULL, sizeof(uint8_t) * data_size, 0);
+ if (values == NULL)
+ return -1;
+
+ n_tokens = 0;
+ while (tok != NULL) {
+ values_resized = NULL;
+
+ if (n_tokens >= data_size) {
+ data_size *= 2;
+
+ values_resized = (uint8_t *) rte_realloc(values,
+ sizeof(uint8_t) * data_size, 0);
+ if (values_resized == NULL) {
+ rte_free(values);
+ return -1;
+ }
+ values = values_resized;
+ }
+
+ values[n_tokens] = (uint8_t) strtoul(tok, &error, 0);
+ if ((error == NULL) || (*error != '\0')) {
+ printf("Failed with convert '%s'\n", tok);
+ rte_free(values);
+ return -1;
+ }
+
+ tok = strtok(NULL, CPERF_VALUE_DELIMITER);
+ if (tok == NULL)
+ break;
+
+ n_tokens++;
+ }
+
+ values_resized = (uint8_t *) rte_realloc(values,
+ sizeof(uint8_t) * (n_tokens + 1), 0);
+
+ if (values_resized == NULL) {
+ rte_free(values);
+ return -1;
+ }
+
+ *data = values_resized;
+ *data_length = n_tokens + 1;
+
+ return 0;
+}
+
+/* checks the type of key and assigns data */
+static int
+parse_entry(char *entry, struct cperf_test_vector *vector,
+ struct cperf_options *opts, uint8_t tc_found)
+{
+ int status;
+ uint32_t data_length;
+
+ uint8_t *data = NULL;
+ char *token, *key_token;
+
+ /* get key */
+ token = strtok(entry, CPERF_ENTRY_DELIMITER);
+ key_token = token;
+
+ /* get values for key */
+ token = strtok(NULL, CPERF_ENTRY_DELIMITER);
+ if (token == NULL) {
+ printf("Expected 'key = values' but was '%.40s'..\n",
+ key_token);
+ return -1;
+ }
+
+ status = parse_values(token, &data, &data_length);
+ if (status)
+ return -1;
+
+ /* compare keys */
+ if (strstr(key_token, "plaintext")) {
+ rte_free(vector->plaintext.data);
+ vector->plaintext.data = data;
+ if (tc_found)
+ vector->plaintext.length = data_length;
+ else {
+ if (opts->buffer_sz > data_length) {
+ printf("Global plaintext shorter than "
+ "buffer_sz\n");
+ return -1;
+ }
+ vector->plaintext.length = opts->buffer_sz;
+ }
+
+ } else if (strstr(key_token, "cipher_key")) {
+ rte_free(vector->cipher_key.data);
+ vector->cipher_key.data = data;
+ if (tc_found)
+ vector->cipher_key.length = data_length;
+ else {
+ if (opts->cipher_key_sz > data_length) {
+ printf("Global cipher_key shorter than "
+ "cipher_key_sz\n");
+ return -1;
+ }
+ vector->cipher_key.length = opts->cipher_key_sz;
+ }
+
+ } else if (strstr(key_token, "auth_key")) {
+ rte_free(vector->auth_key.data);
+ vector->auth_key.data = data;
+ if (tc_found)
+ vector->auth_key.length = data_length;
+ else {
+ if (opts->auth_key_sz > data_length) {
+ printf("Global auth_key shorter than "
+ "auth_key_sz\n");
+ return -1;
+ }
+ vector->auth_key.length = opts->auth_key_sz;
+ }
+
+ } else if (strstr(key_token, "iv")) {
+ rte_free(vector->iv.data);
+ vector->iv.data = data;
+ vector->iv.phys_addr = rte_malloc_virt2phy(vector->iv.data);
+ if (tc_found)
+ vector->iv.length = data_length;
+ else {
+ if (opts->cipher_iv_sz > data_length) {
+ printf("Global iv shorter than "
+ "cipher_iv_sz\n");
+ return -1;
+ }
+ vector->iv.length = opts->cipher_iv_sz;
+ }
+
+ } else if (strstr(key_token, "ciphertext")) {
+ rte_free(vector->ciphertext.data);
+ vector->ciphertext.data = data;
+ if (tc_found)
+ vector->ciphertext.length = data_length;
+ else {
+ if (opts->buffer_sz > data_length) {
+ printf("Global ciphertext shorter than "
+ "buffer_sz\n");
+ return -1;
+ }
+ vector->ciphertext.length = opts->buffer_sz;
+ }
+
+ } else if (strstr(key_token, "aad")) {
+ rte_free(vector->aad.data);
+ vector->aad.data = data;
+ vector->aad.phys_addr = rte_malloc_virt2phy(vector->aad.data);
+ if (tc_found)
+ vector->aad.length = data_length;
+ else {
+ if (opts->auth_aad_sz > data_length) {
+ printf("Global aad shorter than "
+ "auth_aad_sz\n");
+ return -1;
+ }
+ vector->aad.length = opts->auth_aad_sz;
+ }
+
+ } else if (strstr(key_token, "digest")) {
+ rte_free(vector->digest.data);
+ vector->digest.data = data;
+ vector->digest.phys_addr = rte_malloc_virt2phy(
+ vector->digest.data);
+ if (tc_found)
+ vector->digest.length = data_length;
+ else {
+ if (opts->auth_digest_sz > data_length) {
+ printf("Global digest shorter than "
+ "auth_digest_sz\n");
+ return -1;
+ }
+ vector->digest.length = opts->auth_digest_sz;
+ }
+ } else {
+ printf("Not valid key: '%s'\n", trim_space(key_token));
+ return -1;
+ }
+
+ return 0;
+}
+
+/* searches in the file for test keys and values */
+static int
+parse_file(struct cperf_test_vector *vector, struct cperf_options *opts)
+{
+ uint8_t tc_found = 0;
+ uint8_t tc_data_start = 0;
+ ssize_t read;
+ size_t len = 0;
+ int status = 0;
+
+ FILE *fp;
+ char *line = NULL;
+ char *entry = NULL;
+
+ fp = fopen(opts->test_file, "r");
+ if (fp == NULL) {
+ printf("File %s does not exists\n", opts->test_file);
+ return -1;
+ }
+
+ while ((read = getline(&line, &len, fp)) != -1) {
+
+ /* ignore comments and new lines */
+ if (line[0] == '#' || line[0] == '/' || line[0] == '\n'
+ || line[0] == '\r' || line[0] == ' ')
+ continue;
+
+ trim_space(line);
+
+ /* next test case is started */
+ if (line[0] == '[' && line[strlen(line) - 1] == ']' && tc_found)
+ break;
+ /* test case section started, end of global data */
+ else if (line[0] == '[' && line[strlen(line) - 1] == ']')
+ tc_data_start = 1;
+
+ /* test name unspecified, end after global data */
+ if (tc_data_start && opts->test_name == NULL)
+ break;
+ /* searching for a suitable test */
+ else if (tc_data_start && tc_found == 0) {
+ if (!strcmp(line, opts->test_name)) {
+ tc_found = 1;
+ continue;
+ } else
+ continue;
+ }
+
+ /* buffer for multiline */
+ entry = (char *) rte_realloc(entry,
+ sizeof(char) * strlen(line) + 1, 0);
+ if (entry == NULL)
+ return -1;
+
+ memset(entry, 0, strlen(line) + 1);
+ strncpy(entry, line, strlen(line));
+
+ /* check if entry ends with , or = */
+ if (entry[strlen(entry) - 1] == ','
+ || entry[strlen(entry) - 1] == '=') {
+ while ((read = getline(&line, &len, fp)) != -1) {
+ trim_space(line);
+
+ /* extend entry about length of new line */
+ char *entry_extended = (char *) rte_realloc(
+ entry, sizeof(char)
+ * (strlen(line) + strlen(entry))
+ + 1, 0);
+
+ if (entry_extended == NULL)
+ goto err;
+ entry = entry_extended;
+
+ strncat(entry, line, strlen(line));
+
+ if (entry[strlen(entry) - 1] != ',')
+ break;
+ }
+ }
+ status = parse_entry(entry, vector, opts, tc_found);
+ if (status) {
+ printf("An error occurred while parsing!\n");
+ goto err;
+ }
+ }
+
+ if (tc_found == 0 && opts->test_name != NULL) {
+ printf("Not found '%s' case in test file\n", opts->test_name);
+ goto err;
+ }
+
+ fclose(fp);
+ free(line);
+ rte_free(entry);
+
+ return 0;
+
+err:
+ if (fp)
+ fclose(fp);
+ if (line)
+ free(line);
+ if (entry)
+ rte_free(entry);
+
+ return -1;
+}
+
+struct cperf_test_vector*
+cperf_test_vector_get_from_file(struct cperf_options *opts)
+{
+ int status;
+ struct cperf_test_vector *test_vector = NULL;
+
+ if (opts == NULL || opts->test_file == NULL)
+ return test_vector;
+
+ test_vector = (struct cperf_test_vector *) rte_zmalloc(NULL,
+ sizeof(struct cperf_test_vector), 0);
+ if (test_vector == NULL)
+ return test_vector;
+
+ /* filling the vector with data from a file */
+ status = parse_file(test_vector, opts);
+ if (status) {
+ free_test_vector(test_vector, opts);
+ return NULL;
+ }
+
+ /* other values not included in the file */
+ test_vector->data.cipher_offset = 0;
+ test_vector->data.cipher_length = opts->buffer_sz;
+
+ test_vector->data.auth_offset = 0;
+ test_vector->data.auth_length = opts->buffer_sz;
+
+ return test_vector;
+}
diff --git a/app/test-crypto-perf/cperf_test_vector_parsing.h b/app/test-crypto-perf/cperf_test_vector_parsing.h
new file mode 100644
index 0000000..5d0dcea
--- /dev/null
+++ b/app/test-crypto-perf/cperf_test_vector_parsing.h
@@ -0,0 +1,73 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef APP_CRYPTO_PERF_CPERF_TEST_VECTOR_PARSING_H_
+#define APP_CRYPTO_PERF_CPERF_TEST_VECTOR_PARSING_H_
+
+#define CPERF_VALUE_DELIMITER ","
+#define CPERF_ENTRY_DELIMITER "="
+
+/**
+ * Frees the allocated memory for test vector
+ *
+ * @param vector
+ * Destination vector test to release
+ * @param opts
+ * Test options
+ * @return
+ * 0 on success, (-1) on error.
+ */
+int
+free_test_vector(struct cperf_test_vector *vector, struct cperf_options *opts);
+
+/**
+ * Displays data in test vector
+ *
+ * @param vector
+ * Vector to display
+ */
+void
+show_test_vector(struct cperf_test_vector *test_vector);
+
+/**
+ * Completes test vector with data from file
+ *
+ * @param opts
+ * Test options
+ * @return
+ * NULL on error.
+ * Test vector pointer on successful.
+ */
+struct cperf_test_vector*
+cperf_test_vector_get_from_file(struct cperf_options *opts);
+
+#endif /* APP_CRYPTO_PERF_CPERF_TEST_VECTOR_PARSING_H_ */
diff --git a/app/test-crypto-perf/cperf_test_vectors.c b/app/test-crypto-perf/cperf_test_vectors.c
new file mode 100644
index 0000000..d38476e
--- /dev/null
+++ b/app/test-crypto-perf/cperf_test_vectors.c
@@ -0,0 +1,476 @@
+#include <rte_crypto.h>
+#include <rte_malloc.h>
+
+#include "cperf_test_vectors.h"
+
+uint8_t plaintext[2048] = {
+ 0x71, 0x75, 0x83, 0x98, 0x75, 0x42, 0x51, 0x09, 0x94, 0x02, 0x13, 0x20,
+ 0x15, 0x64, 0x46, 0x32, 0x08, 0x18, 0x91, 0x82, 0x86, 0x52, 0x23, 0x93,
+ 0x44, 0x54, 0x28, 0x68, 0x78, 0x78, 0x70, 0x06, 0x42, 0x74, 0x41, 0x27,
+ 0x73, 0x38, 0x53, 0x77, 0x51, 0x96, 0x53, 0x24, 0x03, 0x88, 0x74, 0x14,
+ 0x70, 0x23, 0x88, 0x30, 0x85, 0x18, 0x89, 0x27, 0x41, 0x71, 0x61, 0x23,
+ 0x04, 0x83, 0x30, 0x57, 0x26, 0x47, 0x23, 0x75, 0x25, 0x62, 0x53, 0x80,
+ 0x38, 0x34, 0x21, 0x33, 0x34, 0x51, 0x46, 0x29, 0x94, 0x64, 0x22, 0x67,
+ 0x25, 0x45, 0x70, 0x26, 0x74, 0x39, 0x46, 0x71, 0x08, 0x85, 0x27, 0x18,
+ 0x93, 0x39, 0x72, 0x11, 0x57, 0x26, 0x88, 0x46, 0x47, 0x49, 0x86, 0x92,
+ 0x03, 0x37, 0x96, 0x40, 0x84, 0x53, 0x67, 0x47, 0x60, 0x60, 0x37, 0x67,
+ 0x02, 0x68, 0x76, 0x62, 0x42, 0x01, 0x59, 0x11, 0x01, 0x89, 0x40, 0x87,
+ 0x58, 0x20, 0x51, 0x21, 0x66, 0x26, 0x26, 0x73, 0x03, 0x06, 0x14, 0x25,
+ 0x98, 0x42, 0x44, 0x67, 0x24, 0x78, 0x71, 0x45, 0x32, 0x61, 0x20, 0x26,
+ 0x08, 0x88, 0x44, 0x26, 0x40, 0x63, 0x76, 0x23, 0x78, 0x55, 0x81, 0x97,
+ 0x95, 0x89, 0x39, 0x07, 0x14, 0x50, 0x50, 0x73, 0x07, 0x20, 0x86, 0x83,
+ 0x74, 0x57, 0x72, 0x36, 0x68, 0x61, 0x14, 0x41, 0x56, 0x49, 0x64, 0x72,
+ 0x75, 0x81, 0x47, 0x91, 0x08, 0x76, 0x47, 0x06, 0x55, 0x77, 0x61, 0x45,
+ 0x50, 0x10, 0x07, 0x46, 0x46, 0x89, 0x80, 0x07, 0x24, 0x95, 0x39, 0x43,
+ 0x03, 0x75, 0x24, 0x35, 0x57, 0x82, 0x09, 0x64, 0x29, 0x24, 0x26, 0x66,
+ 0x67, 0x29, 0x05, 0x90, 0x82, 0x02, 0x45, 0x71, 0x21, 0x34, 0x25, 0x48,
+ 0x68, 0x26, 0x01, 0x18, 0x73, 0x18, 0x46, 0x15, 0x14, 0x33, 0x28, 0x44,
+ 0x24, 0x82, 0x20, 0x12, 0x99, 0x43, 0x68, 0x43, 0x25, 0x14, 0x34, 0x33,
+ 0x31, 0x13, 0x77, 0x44, 0x95, 0x22, 0x99, 0x02, 0x30, 0x50, 0x74, 0x43,
+ 0x81, 0x78, 0x32, 0x17, 0x09, 0x85, 0x04, 0x37, 0x31, 0x98, 0x76, 0x79,
+ 0x64, 0x10, 0x39, 0x89, 0x59, 0x90, 0x50, 0x15, 0x77, 0x39, 0x28, 0x14,
+ 0x30, 0x19, 0x68, 0x77, 0x89, 0x48, 0x86, 0x16, 0x11, 0x33, 0x84, 0x56,
+ 0x10, 0x20, 0x94, 0x72, 0x41, 0x69, 0x13, 0x00, 0x56, 0x27, 0x01, 0x57,
+ 0x46, 0x65, 0x65, 0x19, 0x33, 0x07, 0x62, 0x19, 0x91, 0x60, 0x29, 0x11,
+ 0x41, 0x25, 0x88, 0x21, 0x93, 0x85, 0x87, 0x40, 0x91, 0x25, 0x32, 0x86,
+ 0x76, 0x54, 0x92, 0x52, 0x72, 0x46, 0x61, 0x84, 0x20, 0x14, 0x65, 0x83,
+ 0x69, 0x90, 0x80, 0x11, 0x35, 0x70, 0x42, 0x64, 0x74, 0x85, 0x15, 0x23,
+ 0x06, 0x55, 0x67, 0x49, 0x76, 0x47, 0x11, 0x95, 0x00, 0x85, 0x05, 0x12,
+ 0x58, 0x53, 0x25, 0x73, 0x62, 0x81, 0x63, 0x82, 0x32, 0x75, 0x16, 0x48,
+ 0x04, 0x96, 0x75, 0x16, 0x43, 0x83, 0x41, 0x85, 0x95, 0x67, 0x27, 0x83,
+ 0x22, 0x43, 0x02, 0x27, 0x69, 0x62, 0x78, 0x50, 0x57, 0x66, 0x99, 0x89,
+ 0x05, 0x06, 0x35, 0x86, 0x37, 0x27, 0x48, 0x46, 0x50, 0x80, 0x96, 0x40,
+ 0x42, 0x36, 0x21, 0x54, 0x49, 0x18, 0x63, 0x38, 0x45, 0x76, 0x23, 0x20,
+ 0x28, 0x06, 0x17, 0x32, 0x58, 0x50, 0x49, 0x54, 0x29, 0x46, 0x18, 0x12,
+ 0x17, 0x50, 0x02, 0x80, 0x99, 0x53, 0x15, 0x02, 0x07, 0x14, 0x19, 0x60,
+ 0x56, 0x43, 0x76, 0x71, 0x49, 0x99, 0x54, 0x83, 0x28, 0x94, 0x30, 0x30,
+ 0x57, 0x05, 0x89, 0x80, 0x11, 0x03, 0x78, 0x35, 0x73, 0x52, 0x67, 0x39,
+ 0x67, 0x07, 0x04, 0x49, 0x23, 0x83, 0x86, 0x89, 0x57, 0x71, 0x08, 0x41,
+ 0x15, 0x97, 0x19, 0x72, 0x03, 0x27, 0x72, 0x52, 0x66, 0x67, 0x99, 0x15,
+ 0x33, 0x64, 0x69, 0x78, 0x07, 0x83, 0x53, 0x71, 0x21, 0x50, 0x05, 0x48,
+ 0x59, 0x85, 0x01, 0x36, 0x65, 0x02, 0x52, 0x01, 0x09, 0x49, 0x28, 0x77,
+ 0x25, 0x35, 0x67, 0x77, 0x81, 0x64, 0x24, 0x29, 0x42, 0x32, 0x59, 0x22,
+ 0x93, 0x48, 0x59, 0x03, 0x85, 0x87, 0x15, 0x55, 0x23, 0x42, 0x58, 0x17,
+ 0x18, 0x37, 0x70, 0x83, 0x80, 0x12, 0x44, 0x83, 0x45, 0x70, 0x55, 0x86,
+ 0x03, 0x23, 0x01, 0x56, 0x94, 0x12, 0x41, 0x34, 0x82, 0x90, 0x83, 0x46,
+ 0x17, 0x56, 0x66, 0x96, 0x75, 0x80, 0x59, 0x07, 0x15, 0x84, 0x19, 0x52,
+ 0x37, 0x44, 0x44, 0x83, 0x72, 0x43, 0x25, 0x42, 0x26, 0x86, 0x87, 0x86,
+ 0x91, 0x62, 0x14, 0x90, 0x34, 0x26, 0x14, 0x33, 0x59, 0x70, 0x73, 0x15,
+ 0x49, 0x40, 0x66, 0x88, 0x42, 0x66, 0x16, 0x42, 0x55, 0x92, 0x82, 0x06,
+ 0x20, 0x96, 0x36, 0x96, 0x13, 0x07, 0x84, 0x94, 0x37, 0x66, 0x62, 0x78,
+ 0x60, 0x58, 0x80, 0x50, 0x69, 0x03, 0x97, 0x16, 0x64, 0x45, 0x21, 0x39,
+ 0x79, 0x28, 0x52, 0x17, 0x14, 0x77, 0x31, 0x60, 0x86, 0x70, 0x09, 0x53,
+ 0x39, 0x32, 0x52, 0x31, 0x35, 0x79, 0x24, 0x70, 0x25, 0x48, 0x23, 0x49,
+ 0x10, 0x64, 0x54, 0x30, 0x82, 0x34, 0x51, 0x20, 0x46, 0x04, 0x29, 0x25,
+ 0x65, 0x09, 0x55, 0x30, 0x30, 0x52, 0x85, 0x32, 0x79, 0x19, 0x59, 0x07,
+ 0x05, 0x12, 0x11, 0x03, 0x21, 0x90, 0x36, 0x62, 0x23, 0x67, 0x36, 0x67,
+ 0x47, 0x39, 0x92, 0x88, 0x45, 0x43, 0x71, 0x16, 0x48, 0x27, 0x68, 0x39,
+ 0x98, 0x38, 0x03, 0x31, 0x85, 0x10, 0x06, 0x95, 0x54, 0x79, 0x28, 0x79,
+ 0x56, 0x16, 0x65, 0x69, 0x00, 0x54, 0x09, 0x91, 0x06, 0x10, 0x10, 0x86,
+ 0x75, 0x01, 0x02, 0x71, 0x01, 0x09, 0x32, 0x94, 0x66, 0x43, 0x68, 0x36,
+ 0x19, 0x52, 0x02, 0x04, 0x45, 0x49, 0x40, 0x94, 0x07, 0x87, 0x86, 0x79,
+ 0x84, 0x07, 0x75, 0x30, 0x73, 0x02, 0x57, 0x81, 0x65, 0x02, 0x28, 0x96,
+ 0x57, 0x07, 0x70, 0x34, 0x39, 0x35, 0x75, 0x19, 0x47, 0x57, 0x08, 0x75,
+ 0x86, 0x57, 0x11, 0x32, 0x09, 0x47, 0x83, 0x93, 0x20, 0x94, 0x90, 0x88,
+ 0x39, 0x63, 0x22, 0x88, 0x54, 0x54, 0x95, 0x75, 0x67, 0x26, 0x02, 0x49,
+ 0x26, 0x17, 0x35, 0x16, 0x27, 0x65, 0x64, 0x26, 0x93, 0x92, 0x77, 0x85,
+ 0x84, 0x40, 0x59, 0x29, 0x49, 0x69, 0x94, 0x71, 0x72, 0x21, 0x55, 0x03,
+ 0x19, 0x74, 0x09, 0x40, 0x57, 0x68, 0x41, 0x19, 0x11, 0x21, 0x63, 0x56,
+ 0x29, 0x77, 0x57, 0x81, 0x44, 0x40, 0x76, 0x77, 0x02, 0x71, 0x66, 0x35,
+ 0x89, 0x02, 0x64, 0x51, 0x61, 0x02, 0x46, 0x91, 0x38, 0x93, 0x62, 0x57,
+ 0x18, 0x98, 0x12, 0x87, 0x29, 0x48, 0x65, 0x39, 0x99, 0x45, 0x54, 0x69,
+ 0x51, 0x16, 0x25, 0x75, 0x60, 0x70, 0x33, 0x72, 0x01, 0x60, 0x26, 0x51,
+ 0x44, 0x14, 0x39, 0x12, 0x95, 0x48, 0x87, 0x33, 0x90, 0x16, 0x42, 0x78,
+ 0x48, 0x58, 0x96, 0x93, 0x75, 0x23, 0x07, 0x13, 0x86, 0x07, 0x96, 0x30,
+ 0x22, 0x82, 0x91, 0x36, 0x72, 0x16, 0x48, 0x77, 0x64, 0x99, 0x07, 0x34,
+ 0x78, 0x60, 0x61, 0x13, 0x48, 0x93, 0x46, 0x62, 0x48, 0x38, 0x37, 0x96,
+ 0x58, 0x64, 0x39, 0x90, 0x69, 0x46, 0x81, 0x98, 0x61, 0x89, 0x15, 0x59,
+ 0x78, 0x98, 0x21, 0x34, 0x00, 0x69, 0x97, 0x80, 0x28, 0x81, 0x53, 0x49,
+ 0x79, 0x53, 0x92, 0x20, 0x29, 0x40, 0x70, 0x06, 0x09, 0x55, 0x99, 0x41,
+ 0x51, 0x35, 0x55, 0x27, 0x39, 0x06, 0x29, 0x83, 0x66, 0x03, 0x68, 0x14,
+ 0x11, 0x69, 0x95, 0x51, 0x71, 0x55, 0x24, 0x60, 0x52, 0x58, 0x88, 0x11,
+ 0x88, 0x25, 0x37, 0x86, 0x01, 0x52, 0x93, 0x52, 0x02, 0x24, 0x91, 0x58,
+ 0x56, 0x37, 0x50, 0x88, 0x39, 0x09, 0x61, 0x19, 0x08, 0x86, 0x29, 0x51,
+ 0x63, 0x38, 0x81, 0x14, 0x75, 0x75, 0x39, 0x99, 0x22, 0x04, 0x32, 0x63,
+ 0x14, 0x68, 0x41, 0x79, 0x09, 0x57, 0x87, 0x29, 0x26, 0x94, 0x05, 0x71,
+ 0x82, 0x41, 0x26, 0x98, 0x68, 0x18, 0x55, 0x42, 0x78, 0x05, 0x74, 0x17,
+ 0x34, 0x34, 0x07, 0x62, 0x94, 0x72, 0x21, 0x08, 0x54, 0x72, 0x21, 0x08,
+ 0x31, 0x53, 0x82, 0x35, 0x27, 0x40, 0x85, 0x77, 0x08, 0x52, 0x58, 0x48,
+ 0x03, 0x86, 0x65, 0x51, 0x96, 0x43, 0x89, 0x19, 0x15, 0x08, 0x49, 0x62,
+ 0x57, 0x46, 0x17, 0x68, 0x56, 0x04, 0x70, 0x63, 0x75, 0x88, 0x13, 0x27,
+ 0x87, 0x44, 0x46, 0x27, 0x02, 0x97, 0x71, 0x07, 0x40, 0x17, 0x24, 0x61,
+ 0x16, 0x94, 0x86, 0x85, 0x67, 0x58, 0x87, 0x92, 0x02, 0x84, 0x75, 0x19,
+ 0x43, 0x60, 0x68, 0x03, 0x54, 0x75, 0x33, 0x17, 0x97, 0x75, 0x12, 0x62,
+ 0x43, 0x08, 0x35, 0x75, 0x32, 0x21, 0x08, 0x82, 0x78, 0x04, 0x74, 0x09,
+ 0x13, 0x48, 0x63, 0x68, 0x67, 0x09, 0x08, 0x50, 0x11, 0x71, 0x64, 0x72,
+ 0x63, 0x76, 0x21, 0x62, 0x80, 0x57, 0x19, 0x15, 0x26, 0x88, 0x02, 0x26,
+ 0x83, 0x17, 0x61, 0x76, 0x28, 0x10, 0x22, 0x37, 0x56, 0x71, 0x51, 0x60,
+ 0x12, 0x79, 0x24, 0x83, 0x78, 0x47, 0x78, 0x20, 0x52, 0x27, 0x19, 0x88,
+ 0x81, 0x04, 0x70, 0x20, 0x25, 0x10, 0x04, 0x01, 0x72, 0x57, 0x30, 0x93,
+ 0x96, 0x23, 0x02, 0x94, 0x61, 0x44, 0x17, 0x65, 0x77, 0x60, 0x27, 0x43,
+ 0x24, 0x59, 0x46, 0x76, 0x00, 0x11, 0x31, 0x99, 0x41, 0x48, 0x75, 0x32,
+ 0x05, 0x15, 0x45, 0x31, 0x57, 0x89, 0x10, 0x47, 0x53, 0x14, 0x66, 0x54,
+ 0x60, 0x55, 0x36, 0x93, 0x30, 0x03, 0x63, 0x80, 0x65, 0x43, 0x17, 0x36,
+ 0x18, 0x64, 0x21, 0x38, 0x16, 0x19, 0x19, 0x51, 0x73, 0x80, 0x38, 0x27,
+ 0x30, 0x89, 0x13, 0x43, 0x54, 0x11, 0x78, 0x05, 0x24, 0x38, 0x83, 0x56,
+ 0x50, 0x59, 0x12, 0x47, 0x69, 0x70, 0x70, 0x91, 0x28, 0x02, 0x08, 0x91,
+ 0x66, 0x09, 0x31, 0x65, 0x46, 0x20, 0x04, 0x85, 0x89, 0x53, 0x91, 0x42,
+ 0x34, 0x09, 0x36, 0x92, 0x42, 0x06, 0x87, 0x88, 0x23, 0x54, 0x87, 0x85,
+ 0x52, 0x98, 0x95, 0x76, 0x13, 0x50, 0x59, 0x89, 0x18, 0x14, 0x17, 0x47,
+ 0x10, 0x97, 0x39, 0x14, 0x33, 0x79, 0x83, 0x62, 0x55, 0x18, 0x30, 0x83,
+ 0x03, 0x45, 0x38, 0x37, 0x35, 0x20, 0x94, 0x84, 0x89, 0x80, 0x89, 0x10,
+ 0x48, 0x77, 0x33, 0x36, 0x50, 0x07, 0x93, 0x02, 0x45, 0x42, 0x91, 0x12,
+ 0x98, 0x09, 0x77, 0x20, 0x31, 0x95, 0x10, 0x29, 0x89, 0x02, 0x38, 0x92,
+ 0x90, 0x19, 0x51, 0x10, 0x19, 0x82, 0x23, 0x68, 0x06, 0x00, 0x67, 0x50,
+ 0x25, 0x03, 0x41, 0x69, 0x53, 0x42, 0x23, 0x99, 0x29, 0x21, 0x63, 0x22,
+ 0x72, 0x54, 0x72, 0x40, 0x23, 0x39, 0x74, 0x92, 0x53, 0x28, 0x67, 0x56,
+ 0x46, 0x84, 0x59, 0x85, 0x10, 0x92, 0x31, 0x20, 0x39, 0x95, 0x65, 0x15,
+ 0x76, 0x35, 0x37, 0x21, 0x98, 0x41, 0x68, 0x74, 0x94, 0x94, 0x86, 0x90,
+ 0x35, 0x07, 0x06, 0x38, 0x78, 0x32, 0x00, 0x60, 0x86, 0x12, 0x34, 0x65,
+ 0x67, 0x35, 0x76, 0x94, 0x78, 0x22, 0x99, 0x42, 0x82, 0x40, 0x05, 0x74,
+ 0x18, 0x59, 0x03, 0x83, 0x89, 0x05, 0x19, 0x28, 0x88, 0x35, 0x59, 0x10,
+ 0x12, 0x96, 0x48, 0x67, 0x59, 0x87, 0x26, 0x85, 0x74, 0x64, 0x78, 0x56,
+ 0x91, 0x81, 0x45, 0x90, 0x21, 0x80, 0x32, 0x19, 0x61, 0x38, 0x61, 0x70,
+ 0x35, 0x08, 0x93, 0x53, 0x21, 0x95, 0x08, 0x27, 0x90, 0x28, 0x94, 0x27,
+ 0x35, 0x78, 0x03, 0x57, 0x74, 0x84, 0x73, 0x63, 0x27, 0x98, 0x14, 0x21,
+ 0x22, 0x36, 0x75, 0x31, 0x81, 0x65, 0x85, 0x51, 0x02, 0x45, 0x18, 0x06,
+ 0x39, 0x13, 0x29, 0x29, 0x73, 0x26, 0x99, 0x51, 0x38, 0x43, 0x35, 0x58,
+ 0x70, 0x92, 0x32, 0x13, 0x80, 0x16, 0x26, 0x44, 0x22, 0x28, 0x05, 0x45,
+ 0x86, 0x90, 0x38, 0x19, 0x40, 0x06, 0x30, 0x56, 0x94, 0x09, 0x02, 0x02,
+ 0x96, 0x29, 0x22, 0x44, 0x87, 0x38, 0x09, 0x95, 0x58, 0x46, 0x42, 0x78,
+ 0x72, 0x77, 0x86, 0x31, 0x97, 0x19, 0x86, 0x51, 0x73, 0x76, 0x63, 0x98,
+ 0x39, 0x40, 0x20, 0x20, 0x67, 0x42, 0x55, 0x50, 0x63, 0x76, 0x81, 0x87,
+ 0x13, 0x81, 0x19, 0x54, 0x11, 0x77, 0x90, 0x26, 0x47, 0x25, 0x92, 0x88,
+ 0x18, 0x56, 0x23, 0x73, 0x91, 0x52, 0x39, 0x08, 0x59, 0x51, 0x81, 0x57,
+ 0x78, 0x17, 0x13, 0x90, 0x90, 0x50, 0x65, 0x59, 0x99, 0x77, 0x42, 0x28,
+ 0x21, 0x59, 0x97, 0x64, 0x25, 0x17, 0x92, 0x24, 0x50, 0x00, 0x28, 0x40,
+ 0x85, 0x33, 0x78, 0x86, 0x79, 0x40, 0x28, 0x30, 0x14, 0x12, 0x01, 0x72,
+ 0x41, 0x43, 0x06, 0x87, 0x67, 0x31, 0x66, 0x77, 0x07, 0x50, 0x55, 0x50,
+ 0x22, 0x80, 0x42, 0x06, 0x38, 0x01, 0x63, 0x66, 0x70, 0x12, 0x52, 0x91,
+ 0x90, 0x97, 0x21, 0x28, 0x22, 0x65, 0x02, 0x80, 0x72, 0x31, 0x17, 0x76,
+ 0x35, 0x16, 0x03, 0x56, 0x59, 0x93, 0x36, 0x37, 0x67, 0x54, 0x46, 0x87,
+ 0x29, 0x01, 0x30, 0x80, 0x47, 0x47, 0x31, 0x98, 0x34, 0x30, 0x23, 0x86,
+ 0x86, 0x14, 0x05, 0x75, 0x09, 0x88, 0x77, 0x92, 0x59, 0x43, 0x98, 0x72,
+ 0x55, 0x54, 0x25, 0x59, 0x22, 0x27, 0x21, 0x62, 0x97, 0x10, 0x61, 0x73,
+ 0x86, 0x95, 0x99, 0x10, 0x62, 0x35, 0x25, 0x16, 0x62, 0x60, 0x51, 0x48,
+ 0x69, 0x69, 0x92, 0x27, 0x19, 0x43, 0x40, 0x52, 0x70, 0x23, 0x37, 0x28,
+ 0x73, 0x10, 0x32, 0x55, 0x85, 0x46, 0x97, 0x59, 0x88, 0x48, 0x54, 0x06,
+ 0x58, 0x04, 0x82, 0x98, 0x88, 0x34, 0x05, 0x41, 0x94, 0x44, 0x35, 0x10,
+ 0x96, 0x48, 0x21, 0x17, 0x24, 0x40, 0x26, 0x15, 0x49, 0x28, 0x12, 0x17,
+ 0x10, 0x17, 0x91, 0x42, 0x84, 0x15, 0x83, 0x36, 0x29, 0x49, 0x92, 0x77,
+ 0x74, 0x11, 0x72, 0x97, 0x64, 0x53, 0x23, 0x29, 0x16, 0x35, 0x22, 0x10,
+ 0x87, 0x07, 0x44, 0x78, 0x18, 0x19, 0x79, 0x03, 0x58, 0x24, 0x15, 0x63,
+ 0x55, 0x75, 0x56, 0x14, 0x63, 0x65, 0x86, 0x61, 0x92, 0x94, 0x30, 0x92,
+ 0x69, 0x78, 0x40, 0x95, 0x19, 0x81, 0x41, 0x66, 0x97, 0x00, 0x17, 0x37,
+ 0x20, 0x82, 0x14, 0x26, 0x42, 0x63, 0x84, 0x20, 0x96, 0x11, 0x68, 0x37,
+ 0x60, 0x28, 0x69, 0x85, 0x45, 0x04, 0x62, 0x20, 0x49, 0x39, 0x74, 0x84,
+ 0x60, 0x23, 0x38, 0x33, 0x42, 0x49, 0x38, 0x82, 0x30, 0x63, 0x21, 0x51,
+ 0x69, 0x09, 0x05, 0x55, 0x78, 0x90, 0x68, 0x69, 0x22, 0x20, 0x17, 0x26,
+ 0x54, 0x01, 0x10, 0x04, 0x68, 0x19, 0x88, 0x40, 0x91, 0x74, 0x81, 0x29,
+ 0x07, 0x45, 0x33, 0x77, 0x12, 0x47, 0x08, 0x60, 0x09, 0x42, 0x84, 0x15,
+ 0x63, 0x92, 0x64, 0x77, 0x07, 0x44, 0x11, 0x07, 0x79, 0x81, 0x24, 0x05,
+ 0x21, 0x60, 0x81, 0x70, 0x66, 0x36, 0x69, 0x68, 0x45, 0x01, 0x11, 0x95,
+ 0x67, 0x95, 0x55, 0x07, 0x96, 0x63, 0x84, 0x04, 0x74, 0x72, 0x61, 0x91,
+ 0x60, 0x09, 0x90, 0x14, 0x34, 0x94, 0x06, 0x12, 0x01, 0x94, 0x40, 0x14,
+ 0x12, 0x53, 0x64, 0x81, 0x75, 0x99, 0x36, 0x99, 0x11, 0x69, 0x95, 0x51,
+ 0x71, 0x55, 0x24, 0x60, 0x52, 0x58, 0x88, 0x11, 0x88, 0x25, 0x37, 0x86,
+ 0x66, 0x36, 0x69, 0x68, 0x45, 0x01, 0x11, 0x95
+};
+
+/* cipher text */
+uint8_t ciphertext[2048] = {
+ 0xE2, 0x19, 0x24, 0x56, 0x13, 0x59, 0xA6, 0x5D, 0xDF, 0xD0, 0x72, 0xAA,
+ 0x23, 0xC7, 0x36, 0x3A, 0xBB, 0x3E, 0x8B, 0x64, 0xD5, 0xBF, 0xDE, 0x65,
+ 0xA2, 0x75, 0xD9, 0x45, 0x6C, 0x3C, 0xD2, 0x6A, 0xC7, 0xD0, 0x9A, 0xD0,
+ 0x87, 0xB8, 0xE4, 0x94, 0x11, 0x62, 0x5A, 0xC3, 0xC3, 0x01, 0xA3, 0x86,
+ 0xBC, 0xBC, 0x9C, 0xC0, 0x81, 0x9F, 0xBF, 0x5C, 0x6F, 0x3F, 0x13, 0xF1,
+ 0xAE, 0xCF, 0x26, 0xB3, 0xBC, 0x49, 0xD6, 0x3B, 0x7A, 0x2E, 0x99, 0x9E,
+ 0x1B, 0x04, 0x50, 0x6C, 0x48, 0x6B, 0x4E, 0x72, 0xFC, 0xC8, 0xA7, 0x0C,
+ 0x2C, 0xD9, 0xED, 0xE4, 0x82, 0xC4, 0x81, 0xA6, 0xB4, 0xCC, 0xAD, 0x10,
+ 0xF3, 0x1C, 0x39, 0x05, 0x41, 0x2D, 0x57, 0x32, 0xE7, 0x16, 0xF8, 0x4D,
+ 0xF0, 0xDE, 0x40, 0x5B, 0x5F, 0x80, 0xDC, 0xA7, 0xC3, 0x2D, 0x3D, 0x9E,
+ 0x27, 0xD4, 0xE8, 0x10, 0x8E, 0xEB, 0xA5, 0x68, 0x6F, 0x3D, 0xC0, 0x44,
+ 0xE7, 0x77, 0x73, 0xB9, 0x92, 0x8E, 0xA2, 0x26, 0x5C, 0x6F, 0x33, 0x4B,
+ 0x0B, 0xEF, 0x37, 0x55, 0xBE, 0xEC, 0x98, 0x83, 0x1E, 0xDF, 0xB2, 0x9E,
+ 0x5D, 0x1D, 0x78, 0x14, 0xD7, 0x85, 0x0E, 0xF8, 0x12, 0x30, 0x8E, 0x5D,
+ 0x08, 0x77, 0x0B, 0x2E, 0x9B, 0xF9, 0xA6, 0x72, 0xD2, 0x41, 0xC1, 0x8E,
+ 0x6B, 0x5E, 0x11, 0x85, 0x22, 0x6E, 0xE4, 0xA3, 0xEA, 0x4C, 0x91, 0xE1,
+ 0x7D, 0xD0, 0xEB, 0x9F, 0xD9, 0xD7, 0x05, 0x77, 0xD9, 0xA1, 0xC2, 0xFD,
+ 0x41, 0x63, 0x51, 0xB4, 0x7A, 0x1F, 0x21, 0xF0, 0xBF, 0x11, 0x4D, 0x9B,
+ 0x97, 0xAB, 0xB4, 0x94, 0x36, 0x34, 0xC9, 0x2D, 0x8B, 0xE2, 0x61, 0xCF,
+ 0xAF, 0x69, 0xD5, 0x5C, 0xE9, 0xED, 0xE3, 0xA0, 0x69, 0xD3, 0xE5, 0xAE,
+ 0x67, 0x6C, 0xC7, 0x11, 0xB1, 0x21, 0x96, 0xD6, 0xDB, 0xA8, 0x1D, 0xC9,
+ 0x83, 0x0B, 0xE2, 0xC6, 0x6E, 0x94, 0xE9, 0x50, 0x12, 0x9B, 0x01, 0x72,
+ 0xAA, 0xFD, 0x8B, 0x7C, 0xEC, 0x0D, 0x01, 0xA4, 0x5D, 0x00, 0xE9, 0x79,
+ 0x58, 0xF5, 0x67, 0xF9, 0x61, 0xC3, 0x11, 0xB4, 0x7E, 0x76, 0x0A, 0x4C,
+ 0x60, 0xD6, 0xBD, 0xC8, 0x31, 0xD3, 0x0C, 0xD0, 0x5B, 0xDF, 0x7B, 0x05,
+ 0x9A, 0xBB, 0xC6, 0x2E, 0x9F, 0xF8, 0x18, 0x80, 0x6D, 0x1B, 0x21, 0xE5,
+ 0xAC, 0x75, 0xBC, 0x0D, 0x72, 0x51, 0x61, 0xD7, 0xEA, 0xA2, 0xAC, 0x0E,
+ 0xC1, 0xE7, 0x49, 0x37, 0xE7, 0x7C, 0xDE, 0xBD, 0x56, 0x00, 0x44, 0x6D,
+ 0xAB, 0x81, 0x2B, 0x26, 0x4A, 0xAA, 0x60, 0xE6, 0x43, 0x8D, 0x88, 0x1C,
+ 0x48, 0x55, 0x53, 0x25, 0xE8, 0x3C, 0x46, 0xF0, 0xA6, 0x33, 0x2D, 0xA2,
+ 0xDC, 0x99, 0x57, 0x38, 0x59, 0xCF, 0x53, 0xFA, 0x3E, 0x78, 0x46, 0xA0,
+ 0xA9, 0x50, 0x12, 0x72, 0xAC, 0x15, 0xC6, 0xA7, 0x42, 0x0F, 0x59, 0x6E,
+ 0xEA, 0xB0, 0x3D, 0xB8, 0x94, 0x32, 0xD1, 0xB6, 0xE8, 0x90, 0x06, 0x66,
+ 0x0C, 0xDE, 0xA9, 0x35, 0xC7, 0xDD, 0x72, 0x42, 0x38, 0x33, 0x32, 0x2F,
+ 0x2C, 0x3F, 0xBD, 0x01, 0xD6, 0x47, 0xFC, 0x89, 0x31, 0x38, 0x2E, 0xB9,
+ 0x6B, 0xED, 0xDB, 0x85, 0x38, 0xB1, 0xA5, 0x50, 0xFA, 0xFB, 0xA7, 0x31,
+ 0xEC, 0xB6, 0xBB, 0x82, 0x50, 0xB4, 0x88, 0x5C, 0xED, 0xE5, 0x4B, 0x5B,
+ 0xBF, 0xB3, 0x18, 0xFB, 0xAD, 0x24, 0x41, 0x55, 0x80, 0xCD, 0xA3, 0xA1,
+ 0xD6, 0xD5, 0xB6, 0x06, 0xE9, 0x85, 0x12, 0x33, 0x52, 0x56, 0xF1, 0xB7,
+ 0xDC, 0x57, 0x9E, 0xB4, 0x00, 0x1E, 0xCB, 0x62, 0x13, 0x4C, 0x90, 0x9A,
+ 0x9D, 0x64, 0x80, 0xD1, 0x5E, 0xB3, 0xCB, 0x8A, 0x73, 0x4E, 0x7B, 0xBE,
+ 0x4D, 0xA7, 0xF7, 0xB7, 0x9C, 0x1C, 0x7F, 0x27, 0x1E, 0x7F, 0x58, 0xB2,
+ 0x74, 0xAF, 0x94, 0x0E, 0x19, 0x23, 0xE1, 0x6B, 0xD8, 0x20, 0x4F, 0x2C,
+ 0x13, 0xE8, 0x8C, 0x37, 0x46, 0x27, 0x55, 0x68, 0xDA, 0x3F, 0x7A, 0xC6,
+ 0xEF, 0x87, 0x1D, 0x3B, 0x95, 0x43, 0x5E, 0x75, 0xE0, 0x02, 0x22, 0x0E,
+ 0x11, 0x60, 0xAB, 0x1A, 0x91, 0x94, 0xC4, 0xFA, 0xD9, 0x92, 0x2B, 0xE5,
+ 0x03, 0xE0, 0x7A, 0x17, 0x5C, 0x67, 0x22, 0xB3, 0xCB, 0x77, 0x9E, 0x22,
+ 0x01, 0x5F, 0x5D, 0x64, 0xE4, 0x2F, 0xC4, 0x61, 0xCA, 0xC7, 0xFD, 0x20,
+ 0x24, 0x30, 0xAB, 0x3F, 0x1A, 0x08, 0x85, 0x08, 0x39, 0xDE, 0x19, 0x1C,
+ 0x1A, 0xEA, 0xB8, 0x7E, 0xE5, 0xBC, 0xD9, 0xB2, 0x59, 0xC8, 0x81, 0x02,
+ 0x1D, 0x5C, 0xC0, 0xDD, 0x8D, 0x56, 0xB6, 0x2E, 0x85, 0x26, 0xA8, 0x34,
+ 0x92, 0x36, 0x9A, 0x84, 0xBD, 0x27, 0xC1, 0x9D, 0x5E, 0x14, 0xC4, 0xB7,
+ 0x02, 0xA8, 0xC9, 0xC2, 0xAD, 0xDC, 0x98, 0x42, 0x51, 0xDE, 0x94, 0x28,
+ 0x39, 0xEF, 0xE9, 0x7F, 0x05, 0x3F, 0x1D, 0x67, 0x72, 0x04, 0xCF, 0x7D,
+ 0x38, 0x49, 0xC4, 0x59, 0xA5, 0xF6, 0xB6, 0x02, 0x31, 0xD0, 0x05, 0x74,
+ 0x4B, 0xD0, 0x89, 0xD1, 0x7F, 0xC6, 0xDB, 0x7E, 0x75, 0x62, 0xA3, 0xC2,
+ 0x2E, 0xB0, 0xCC, 0x9A, 0xD3, 0xA4, 0x14, 0xB6, 0xF2, 0x91, 0x44, 0x3F,
+ 0x84, 0xE0, 0x90, 0x4A, 0x6A, 0x34, 0x8C, 0x35, 0x3C, 0xB2, 0xA9, 0x35,
+ 0x88, 0xB0, 0x88, 0xF8, 0x7E, 0x5C, 0xD2, 0x08, 0x5E, 0x08, 0x15, 0x03,
+ 0xBC, 0xF5, 0x42, 0x6B, 0x28, 0xED, 0xDD, 0xAA, 0x4D, 0x78, 0x10, 0x31,
+ 0x32, 0xA2, 0xC5, 0xCA, 0xEE, 0x9A, 0x62, 0x52, 0x3E, 0x48, 0x83, 0xA4,
+ 0xCA, 0xD4, 0xC7, 0xA7, 0xA5, 0x3F, 0x44, 0x1C, 0x86, 0xAD, 0x52, 0x7D,
+ 0x80, 0x1D, 0x9E, 0x32, 0x3F, 0x2A, 0x2E, 0xD8, 0x89, 0xC1, 0xA4, 0xD6,
+ 0xC1, 0x90, 0x2E, 0x1A, 0x20, 0x4B, 0x87, 0x32, 0x35, 0x25, 0xD8, 0xB8,
+ 0x57, 0x15, 0x85, 0x1E, 0x3C, 0x8A, 0xDC, 0x1A, 0x49, 0x3D, 0x70, 0x35,
+ 0x99, 0xAA, 0xDE, 0x2C, 0xD4, 0xAF, 0x79, 0x72, 0xAB, 0x97, 0x84, 0x20,
+ 0xB6, 0x4F, 0x34, 0x3F, 0xEA, 0xAE, 0x5F, 0x8F, 0x3A, 0x42, 0xDB, 0x68,
+ 0xE5, 0x84, 0x63, 0x2E, 0x7A, 0x0E, 0xBD, 0x28, 0x6A, 0x24, 0xB6, 0xAB,
+ 0xE4, 0xAC, 0x20, 0x7C, 0x81, 0xD0, 0x69, 0x89, 0xF8, 0xDE, 0xA9, 0x02,
+ 0xFD, 0x1F, 0x08, 0xDA, 0x26, 0xC2, 0x24, 0xCA, 0xEB, 0x44, 0x16, 0x8D,
+ 0x55, 0x5F, 0xB9, 0xA9, 0x5A, 0x18, 0x50, 0xB1, 0x54, 0xF1, 0xBF, 0x06,
+ 0xC2, 0xB0, 0x95, 0xC2, 0xAE, 0xE5, 0xBF, 0xB3, 0xFD, 0xC9, 0xBF, 0x75,
+ 0x42, 0x7D, 0xA0, 0xA8, 0x95, 0xF9, 0x62, 0x3B, 0x9C, 0x0D, 0x81, 0xF3,
+ 0x9C, 0xFC, 0x19, 0x5B, 0xF7, 0xD1, 0x9C, 0xF0, 0xAA, 0xFE, 0xEF, 0x35,
+ 0x1E, 0x81, 0x9E, 0x02, 0x46, 0x52, 0x9B, 0x99, 0x0D, 0x12, 0x8B, 0x71,
+ 0x6C, 0x32, 0xB5, 0x23, 0x17, 0x03, 0xC5, 0xB0, 0xA1, 0xC3, 0x4B, 0x10,
+ 0x01, 0x4D, 0x4C, 0x4A, 0x46, 0x8F, 0xD9, 0x79, 0xBB, 0x10, 0x44, 0xB0,
+ 0x3C, 0x7D, 0x46, 0xFD, 0x38, 0xDF, 0xAF, 0x6E, 0x58, 0x7D, 0xE1, 0xEB,
+ 0xBB, 0x8C, 0xDC, 0x79, 0xDA, 0x41, 0xD1, 0x8B, 0x0B, 0x11, 0x4F, 0xE5,
+ 0x1C, 0xC1, 0x59, 0xA7, 0x1E, 0x5A, 0xC1, 0xEE, 0x27, 0x33, 0xC8, 0x55,
+ 0xA9, 0x32, 0xEA, 0xF7, 0x45, 0xB0, 0x08, 0xE9, 0x32, 0xDF, 0x70, 0x24,
+ 0x82, 0xD3, 0x2A, 0x3E, 0x4F, 0x42, 0xB9, 0x25, 0x10, 0xD1, 0x73, 0xFA,
+ 0xFD, 0xC1, 0x84, 0xF2, 0xF7, 0x0E, 0xBC, 0x9D, 0x90, 0x39, 0xD7, 0xFD,
+ 0x45, 0x77, 0xBA, 0x29, 0xF9, 0x87, 0x45, 0xC1, 0x32, 0x44, 0xB0, 0x27,
+ 0x6B, 0xFC, 0x8A, 0xFE, 0x00, 0x6F, 0x61, 0x98, 0xD0, 0x60, 0xC8, 0x10,
+ 0xE5, 0xBC, 0x88, 0x13, 0x45, 0x44, 0xA5, 0xEB, 0x6E, 0xCB, 0x11, 0xAF,
+ 0x30, 0xDC, 0x8B, 0xF8, 0x30, 0x46, 0xDA, 0x76, 0xF1, 0xE5, 0x14, 0x51,
+ 0x8A, 0x02, 0x5A, 0x5A, 0xAA, 0x7B, 0x2D, 0x57, 0x0A, 0x5C, 0x73, 0xD1,
+ 0x88, 0xCE, 0xBE, 0x3D, 0x06, 0x3F, 0x48, 0x1D, 0x44, 0x24, 0x6F, 0x4F,
+ 0x7F, 0x6A, 0xF2, 0x16, 0x34, 0x35, 0x38, 0x73, 0x8A, 0xE5, 0x25, 0xF4,
+ 0x34, 0x9E, 0x5B, 0x40, 0x90, 0x04, 0x57, 0x1B, 0x57, 0x75, 0x8F, 0xEA,
+ 0x1C, 0xF8, 0x7A, 0x68, 0x01, 0x1C, 0x8D, 0xBA, 0xF4, 0xE3, 0xD3, 0x8F,
+ 0x7F, 0xE4, 0x50, 0x35, 0x6B, 0x6B, 0xF6, 0xFC, 0x5F, 0x9B, 0x98, 0x78,
+ 0x16, 0x68, 0x72, 0x74, 0x71, 0x78, 0x25, 0x68, 0xE5, 0x1E, 0x66, 0xE2,
+ 0x4E, 0xC8, 0xDB, 0x92, 0x8E, 0x88, 0x64, 0x74, 0xDE, 0xDB, 0x85, 0x56,
+ 0x9F, 0xF9, 0xC4, 0x29, 0x54, 0xA8, 0xFB, 0xBA, 0xEA, 0xAB, 0xC7, 0x49,
+ 0x5C, 0x6C, 0xD7, 0x61, 0x8C, 0xE2, 0x2B, 0xF5, 0xA0, 0xA8, 0xD2, 0x41,
+ 0xC0, 0x54, 0xAB, 0xA7, 0x56, 0x5C, 0xE7, 0xA5, 0xEA, 0xBC, 0x47, 0xD1,
+ 0x0D, 0xD9, 0xC0, 0xA9, 0xC4, 0xA7, 0x3E, 0xD1, 0x2B, 0x1E, 0x34, 0x31,
+ 0x36, 0x9D, 0xB9, 0x51, 0xD3, 0xAD, 0x29, 0xE6, 0x9B, 0xD8, 0x4B, 0x93,
+ 0x33, 0x2F, 0x30, 0xEF, 0x18, 0x90, 0x69, 0x11, 0x09, 0xEA, 0xBA, 0xE0,
+ 0x10, 0x93, 0x63, 0x71, 0xA8, 0x83, 0x59, 0xDB, 0xFC, 0x12, 0x22, 0x84,
+ 0xC7, 0x01, 0x20, 0x99, 0xEC, 0x59, 0xA9, 0xE6, 0x9B, 0x5B, 0x8B, 0xB8,
+ 0x68, 0x52, 0x61, 0x8B, 0x4E, 0xF3, 0x50, 0x69, 0xF1, 0x49, 0x9B, 0xAF,
+ 0x53, 0xAD, 0xA0, 0x9D, 0x23, 0xE0, 0xE0, 0xC4, 0x31, 0xE4, 0x8E, 0x1C,
+ 0x51, 0x14, 0xFC, 0x95, 0x9C, 0xA6, 0x34, 0x85, 0xB0, 0x36, 0xFC, 0x7A,
+ 0x53, 0x03, 0x31, 0x0E, 0xCB, 0x34, 0x3E, 0xDF, 0xD1, 0x71, 0xBC, 0xDB,
+ 0xA1, 0xAF, 0x59, 0x4A, 0x03, 0x19, 0xA7, 0x8E, 0xB5, 0x82, 0x15, 0x24,
+ 0x69, 0x68, 0xBD, 0x9C, 0x2E, 0xFA, 0x06, 0xB5, 0x70, 0xC5, 0x70, 0xC4,
+ 0x14, 0x99, 0x01, 0x49, 0xBD, 0x6E, 0xAE, 0x10, 0xA1, 0xE4, 0xEF, 0xDD,
+ 0xE5, 0x51, 0x22, 0x9D, 0xF7, 0x93, 0xAB, 0x41, 0xBD, 0x86, 0x7A, 0xCC,
+ 0x51, 0x94, 0xEC, 0x22, 0xBE, 0x0D, 0x67, 0xFD, 0xA3, 0xFD, 0xCF, 0xF8,
+ 0x74, 0x0A, 0x5E, 0x1C, 0x71, 0xAD, 0xB6, 0xD0, 0xD7, 0xF8, 0x71, 0x34,
+ 0xAB, 0x62, 0xE7, 0xA8, 0x6B, 0x8F, 0x1E, 0x43, 0x46, 0xA5, 0xE4, 0xB4,
+ 0x52, 0x81, 0x66, 0xB3, 0xE5, 0x10, 0x23, 0x21, 0x2B, 0x31, 0x0F, 0xB8,
+ 0xB6, 0xC5, 0xA5, 0xC9, 0x90, 0x07, 0x83, 0xD0, 0xC3, 0x10, 0x7A, 0x04,
+ 0xBD, 0x8A, 0x3C, 0x7B, 0xF9, 0x0E, 0x51, 0x81, 0x96, 0xC8, 0xAE, 0xF9,
+ 0x27, 0xDE, 0x62, 0x7A, 0x41, 0x60, 0x35, 0x8F, 0x77, 0xBC, 0x95, 0x11,
+ 0x2C, 0xC4, 0x6C, 0x47, 0x7A, 0xEB, 0x29, 0xE5, 0x8E, 0xB5, 0xD6, 0xA5,
+ 0x54, 0x1B, 0xD0, 0xE0, 0x0F, 0x7D, 0x5C, 0x51, 0xD8, 0x6C, 0x92, 0x2F,
+ 0x13, 0x4E, 0x90, 0x77, 0xF8, 0x8D, 0x69, 0x78, 0x96, 0x96, 0x49, 0x9F,
+ 0x3C, 0x2E, 0x5C, 0xA6, 0x73, 0x27, 0x7D, 0xAD, 0x8D, 0xE3, 0x9B, 0x4A,
+ 0x2F, 0x50, 0x0A, 0x42, 0x7E, 0xF2, 0x3B, 0x50, 0x5C, 0x81, 0xC9, 0x49,
+ 0x01, 0x96, 0x83, 0x0A, 0xEC, 0x7F, 0xED, 0x1C, 0xA5, 0x7D, 0xF1, 0xE6,
+ 0xC4, 0xB3, 0x8F, 0xF9, 0x0F, 0xDB, 0x7B, 0xC1, 0x35, 0xF7, 0x63, 0x4A,
+ 0x39, 0xD4, 0x0E, 0x9E, 0x05, 0xD9, 0x42, 0xAA, 0xAB, 0x52, 0xCA, 0x4E,
+ 0x98, 0x3B, 0x43, 0x1A, 0x91, 0x25, 0xA9, 0x34, 0xD5, 0x66, 0xB2, 0xF4,
+ 0xFF, 0xDE, 0x64, 0x91, 0x90, 0xB9, 0x17, 0x70, 0xA0, 0xD6, 0xEA, 0xB6,
+ 0x36, 0xF4, 0x44, 0xCE, 0x86, 0x7B, 0x18, 0x74, 0x9C, 0x18, 0xAD, 0xB6,
+ 0xE0, 0x74, 0xC1, 0x0E, 0x29, 0x5D, 0x6A, 0x36, 0xD1, 0x3E, 0xB8, 0x2A,
+ 0xE4, 0x23, 0x1D, 0xB2, 0xAE, 0xF5, 0x5B, 0x8E, 0x2C, 0xD9, 0xD1, 0xE1,
+ 0x4F, 0x58, 0xA6, 0xE3, 0x88, 0x2E, 0xF9, 0xCF, 0x32, 0x3E, 0x8E, 0x37,
+ 0x95, 0xFF, 0xAD, 0x68, 0x11, 0x5E, 0x7F, 0x3D, 0x38, 0x06, 0x7C, 0x33,
+ 0x32, 0x78, 0x09, 0xEC, 0xCA, 0x3E, 0x08, 0xF1, 0xD0, 0x95, 0x19, 0xC9,
+ 0x7E, 0x62, 0xB2, 0x02, 0xA3, 0x5D, 0xF8, 0x3F, 0xA2, 0xB0, 0x8B, 0x38,
+ 0xB1, 0x8C, 0xEA, 0xB3, 0xE4, 0xBF, 0xD3, 0x6C, 0x6D, 0x3D, 0xD1, 0xC6,
+ 0xDA, 0x6B, 0x7A, 0xBA, 0x05, 0xEA, 0x9E, 0xA5, 0xE9, 0x00, 0xCC, 0x80,
+ 0x57, 0xAB, 0xD9, 0x0A, 0xD1, 0x00, 0x82, 0x2A, 0x51, 0x4B, 0xA2, 0x96,
+ 0xEB, 0x96, 0x14, 0xA8, 0x46, 0xDF, 0x1D, 0x48, 0xAE, 0xFA, 0x12, 0xA8,
+ 0x89, 0x8E, 0xEF, 0xBC, 0x3C, 0xA1, 0x6E, 0xDD, 0x90, 0x66, 0x2E, 0x56,
+ 0x6B, 0xF7, 0x1D, 0xF0, 0x46, 0x11, 0x4A, 0xA6, 0x07, 0x73, 0xC4, 0xE3,
+ 0x97, 0xFE, 0x7E, 0x22, 0x6F, 0x22, 0xB4, 0x6F, 0xB0, 0x32, 0x0A, 0x5E,
+ 0x85, 0x7E, 0x54, 0xB4, 0x24, 0xBD, 0x36, 0xA7, 0x94, 0xE7, 0x37, 0xFD,
+ 0x1A, 0xAF, 0xF4, 0x44, 0xB4, 0x35, 0x4F, 0xE0, 0x41, 0x0E, 0x7D, 0x73,
+ 0x29, 0x28, 0xDA, 0xAF, 0x69, 0xB2, 0xC5, 0xA7, 0x2A, 0x0A, 0xB5, 0x9C,
+ 0xC2, 0xAC, 0x5F, 0x59, 0x5C, 0xEE, 0x44, 0x49, 0x6F, 0x4F, 0x64, 0x43,
+ 0x6F, 0x43, 0x44, 0xAA, 0xA0, 0x4E, 0x94, 0x7C, 0x26, 0x5A, 0xF1, 0xD9,
+ 0xE6, 0x09, 0x80, 0x7A, 0x7D, 0x2E, 0xA2, 0xB9, 0x1A, 0x7A, 0x8F, 0x2A,
+ 0x97, 0x77, 0x23, 0xB4, 0x10, 0xAD, 0x20, 0x7B, 0xA3, 0x0F, 0xFD, 0x44,
+ 0x38, 0xAD, 0x94, 0x39, 0x88, 0x1C, 0xC4, 0xC8, 0xDF, 0xF1, 0x04, 0xA6,
+ 0x51, 0x5D, 0x54, 0x53, 0x60, 0xE4, 0x8A, 0x89, 0x4A, 0x9C, 0xE1, 0x68,
+ 0x4D, 0xFE, 0x69, 0x94, 0x0B, 0x8E, 0xED, 0x6C, 0xFE, 0x11, 0xA7, 0x77,
+ 0xBF, 0x08, 0x41, 0x67, 0x22, 0x59, 0x51, 0x48, 0xEE, 0x59, 0x02, 0x0E,
+ 0x60, 0x6D, 0xAE, 0x8C, 0xC6, 0x39, 0xB7, 0x55, 0xC5, 0x3B, 0x87, 0xA9,
+ 0xBD, 0xD8, 0xEA, 0x48, 0x21, 0xE4, 0x57, 0x51, 0x56, 0x03, 0xF4, 0xBE,
+ 0xBD, 0xBD, 0xC5, 0x26, 0x9B, 0x27, 0xE3, 0xAE, 0xD5, 0x1E, 0x30, 0xE9,
+ 0x7C, 0x9D, 0xDB, 0xE1, 0x09, 0x9D, 0x82, 0x49, 0x15, 0x38, 0x69, 0xFC,
+ 0x1D, 0x52, 0x1A, 0x75, 0xE6, 0xDD, 0x1D, 0xBE, 0x06, 0xC4, 0x9F, 0x14,
+ 0x4C, 0x12, 0xDE, 0xDF, 0x4A, 0xE1, 0x3B, 0xE7, 0xD1, 0xE3, 0x71, 0xD1,
+ 0xFA, 0xD8, 0x0E, 0x63, 0x27, 0xA9, 0xC7, 0x9D, 0xC0, 0x01, 0xC2, 0xDD,
+ 0xFC, 0xA6, 0x1F, 0x59, 0x87, 0xC5, 0x56, 0x99, 0x80, 0xEB, 0xF0, 0xB8,
+ 0xB3, 0x00, 0x9A, 0x61, 0xDB, 0x50, 0x79, 0x48, 0x37, 0x35, 0xDA, 0xD8,
+ 0xF2, 0x37, 0xA7, 0x43, 0xA7, 0xEB, 0x88, 0x2C, 0x68, 0xB4, 0xBB, 0x14,
+ 0x45, 0x31, 0x6B, 0x87, 0x65, 0xE7, 0x82, 0xB4, 0x74, 0xD2, 0xFF, 0x7F,
+ 0x60, 0x15, 0x94, 0x75, 0xEE, 0x30, 0x3C, 0x4E, 0xFC, 0x41, 0xD1, 0x5B,
+ 0xDD, 0x84, 0x6E, 0x13, 0x6C, 0xF8, 0x12, 0xE6, 0xB7, 0xA4, 0xB9, 0xC8,
+ 0x13, 0x89, 0x0C, 0x34, 0xA6, 0xAF, 0x09, 0xEB, 0xF2, 0xB3, 0x79, 0x77,
+ 0x80, 0xD8, 0x77, 0x64, 0xAD, 0x32, 0x3D, 0xD2, 0x06, 0xDF, 0x72, 0x11,
+ 0x4A, 0xA7, 0x70, 0xCE, 0xF9, 0xE6, 0x81, 0x35, 0xA4, 0xA7, 0x52, 0xB5,
+ 0x13, 0x68, 0x5C, 0x69, 0x45, 0xE2, 0x77, 0x2D, 0xBE, 0x2C, 0xE9, 0x38,
+ 0x25, 0x28, 0x7B, 0x63, 0x2C, 0x19, 0x8F, 0x59
+};
+
+/* aad */
+uint8_t aad[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B
+};
+
+/* iv */
+uint8_t iv[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
+ 0x0C, 0x0D, 0x0E, 0x0F
+};
+
+/* cipher key */
+uint8_t cipher_key[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
+ 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
+};
+
+/* auth key */
+uint8_t auth_key[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
+ 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23,
+ 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
+ 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53,
+ 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B,
+ 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F
+};
+
+/* Digests */
+uint8_t digest[2048] = { 0x00 };
+
+struct cperf_test_vector*
+cperf_test_vector_get_dummy(struct cperf_options *options)
+{
+ struct cperf_test_vector *t_vec;
+
+ t_vec = (struct cperf_test_vector *)rte_malloc(NULL,
+ sizeof(struct cperf_test_vector), 0);
+ if (t_vec == NULL)
+ return t_vec;
+
+ t_vec->plaintext.data = plaintext;
+ t_vec->plaintext.length = options->buffer_sz;
+
+ if (options->op_type == CPERF_CIPHER_ONLY ||
+ options->op_type == CPERF_CIPHER_THEN_AUTH ||
+ options->op_type == CPERF_AUTH_THEN_CIPHER ||
+ options->op_type == CPERF_AEAD) {
+ if (options->cipher_algo == RTE_CRYPTO_CIPHER_NULL) {
+ t_vec->cipher_key.length = -1;
+ t_vec->ciphertext.data = plaintext;
+ t_vec->cipher_key.data = NULL;
+ t_vec->iv.data = NULL;
+ } else {
+ t_vec->cipher_key.length = options->cipher_key_sz;
+ t_vec->ciphertext.data = ciphertext;
+ t_vec->cipher_key.data = cipher_key;
+ t_vec->iv.data = rte_malloc(NULL, options->cipher_iv_sz,
+ 16);
+ if (t_vec->iv.data == NULL) {
+ rte_free(t_vec);
+ return NULL;
+ }
+ memcpy(t_vec->iv.data, iv, options->cipher_iv_sz);
+ }
+ t_vec->ciphertext.length = options->buffer_sz;
+ t_vec->iv.phys_addr = rte_malloc_virt2phy(t_vec->iv.data);
+ t_vec->iv.length = options->cipher_iv_sz;
+ t_vec->data.cipher_offset = 0;
+ t_vec->data.cipher_length = options->buffer_sz;
+ }
+
+ if (options->op_type == CPERF_AUTH_ONLY ||
+ options->op_type == CPERF_CIPHER_THEN_AUTH ||
+ options->op_type == CPERF_AUTH_THEN_CIPHER ||
+ options->op_type == CPERF_AEAD) {
+ t_vec->auth_key.length = options->auth_key_sz;
+ if (options->auth_algo == RTE_CRYPTO_AUTH_NULL) {
+ t_vec->auth_key.data = NULL;
+ t_vec->aad.data = NULL;
+ } else if (options->auth_algo == RTE_CRYPTO_AUTH_AES_GCM) {
+ t_vec->auth_key.data = NULL;
+ t_vec->aad.data = rte_malloc(NULL, options->auth_aad_sz,
+ 16);
+ if (t_vec->aad.data == NULL) {
+ if (options->op_type != CPERF_AUTH_ONLY)
+ rte_free(t_vec->iv.data);
+ rte_free(t_vec);
+ return NULL;
+ }
+ memcpy(t_vec->aad.data, aad, options->auth_aad_sz);
+ } else {
+ t_vec->auth_key.data = auth_key;
+ t_vec->aad.data = NULL;
+ }
+
+ t_vec->aad.phys_addr = rte_malloc_virt2phy(t_vec->aad.data);
+ t_vec->aad.length = options->auth_aad_sz;
+ t_vec->digest.data = rte_malloc(NULL, options->auth_digest_sz,
+ 16);
+ if (t_vec->digest.data == NULL) {
+ if (options->op_type != CPERF_AUTH_ONLY)
+ rte_free(t_vec->iv.data);
+ rte_free(t_vec->aad.data);
+ rte_free(t_vec);
+ return NULL;
+ }
+ t_vec->digest.phys_addr =
+ rte_malloc_virt2phy(t_vec->digest.data);
+ t_vec->digest.length = options->auth_digest_sz;
+ memcpy(t_vec->digest.data, digest, options->auth_digest_sz);
+ t_vec->data.auth_offset = 0;
+ t_vec->data.auth_length = options->buffer_sz;
+ }
+
+ return t_vec;
+}
diff --git a/app/test-crypto-perf/cperf_test_vectors.h b/app/test-crypto-perf/cperf_test_vectors.h
new file mode 100644
index 0000000..c14c984
--- /dev/null
+++ b/app/test-crypto-perf/cperf_test_vectors.h
@@ -0,0 +1,98 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _CPERF_TEST_VECTRORS_
+#define _CPERF_TEST_VECTRORS_
+
+#include "cperf_options.h"
+
+struct cperf_test_vector {
+ struct {
+ uint8_t *data;
+ uint32_t length;
+ } plaintext;
+
+ struct {
+ uint8_t *data;
+ uint16_t length;
+ } cipher_key;
+
+ struct {
+ uint8_t *data;
+ uint16_t length;
+ } auth_key;
+
+ struct {
+ uint8_t *data;
+ phys_addr_t phys_addr;
+ uint16_t length;
+ } iv;
+
+ struct {
+ uint8_t *data;
+ uint32_t length;
+ } ciphertext;
+
+ struct {
+ uint8_t *data;
+ phys_addr_t phys_addr;
+ uint16_t length;
+ } aad;
+
+ struct {
+ uint8_t *data;
+ phys_addr_t phys_addr;
+ uint16_t length;
+ } digest;
+
+ struct {
+ uint32_t auth_offset;
+ uint32_t auth_length;
+ uint32_t cipher_offset;
+ uint32_t cipher_length;
+ } data;
+};
+
+struct cperf_test_vector*
+cperf_test_vector_get_dummy(struct cperf_options *options);
+
+extern uint8_t ciphertext[2048];
+
+extern uint8_t cipher_key[];
+extern uint8_t auth_key[];
+
+extern uint8_t iv[];
+extern uint8_t aad[];
+
+extern uint8_t digest[2048];
+
+#endif
diff --git a/app/test-crypto-perf/cperf_verify_parser.c b/app/test-crypto-perf/cperf_verify_parser.c
new file mode 100644
index 0000000..5640d84
--- /dev/null
+++ b/app/test-crypto-perf/cperf_verify_parser.c
@@ -0,0 +1,314 @@
+#include <stdio.h>
+
+#include <rte_malloc.h>
+#include "cperf_options.h"
+#include "cperf_test_vectors.h"
+#include "cperf_verify_parser.h"
+
+int
+free_test_vector(struct cperf_test_vector *vector, struct cperf_options *opts)
+{
+ if (vector == NULL || opts == NULL)
+ return -1;
+
+ if (opts->test_file == NULL) {
+ if (vector->iv.data)
+ rte_free(vector->iv.data);
+ if (vector->aad.data)
+ rte_free(vector->aad.data);
+ if (vector->digest.data)
+ rte_free(vector->digest.data);
+ rte_free(vector);
+
+ } else {
+ if (vector->plaintext.data)
+ rte_free(vector->plaintext.data);
+ if (vector->cipher_key.data)
+ rte_free(vector->cipher_key.data);
+ if (vector->auth_key.data)
+ rte_free(vector->auth_key.data);
+ if (vector->iv.data)
+ rte_free(vector->iv.data);
+ if (vector->ciphertext.data)
+ rte_free(vector->ciphertext.data);
+ if (vector->aad.data)
+ rte_free(vector->aad.data);
+ if (vector->digest.data)
+ rte_free(vector->digest.data);
+ rte_free(vector);
+ }
+
+ return 0;
+}
+
+/* trim leading and trailing spaces */
+static char *
+trim(char *str)
+{
+ char *start, *end;
+
+ for (start = str; *start; start++) {
+ if (!isspace((unsigned char) start[0]))
+ break;
+ }
+
+ for (end = start + strlen(start); end > start + 1; end--) {
+ if (!isspace((unsigned char) end[-1]))
+ break;
+ }
+
+ *end = 0;
+
+ /* Shift from "start" to the beginning of the string */
+ if (start > str)
+ memmove(str, start, (end - start) + 1);
+
+ return str;
+}
+
+/* tokenization test values separated by a comma */
+static int
+parse_values(char *tokens, uint8_t **data, uint32_t *data_length)
+{
+ uint8_t n_tokens;
+ uint32_t data_size = 32;
+ uint8_t *values;
+ char *tok, *error = NULL;
+
+ tok = strtok(tokens, VALUE_DELIMITER);
+ if (tok == NULL)
+ return -1;
+
+ values = (uint8_t *) rte_zmalloc(NULL, sizeof(uint8_t) * data_size, 0);
+ if (values == NULL)
+ return -1;
+
+ n_tokens = 0;
+ while (tok != NULL) {
+ uint8_t *values_extended = NULL;
+
+ if (n_tokens >= data_size) {
+
+ data_size *= 2;
+
+ values_extended = (uint8_t *) rte_realloc(values,
+ sizeof(uint8_t) * data_size, 0);
+ if (values_extended == NULL) {
+ rte_free(values);
+ return -1;
+ }
+
+ values = values_extended;
+ }
+
+ values[n_tokens] = (uint8_t) strtoul(tok, &error, 0);
+ if ((error == NULL) || (*error != '\0')) {
+ printf("Failed with convert '%s'\n", tok);
+ rte_free(values);
+ return -1;
+ }
+
+ tok = strtok(NULL, VALUE_DELIMITER);
+ if (tok == NULL)
+ break;
+
+ n_tokens++;
+ }
+
+ uint8_t *resize_values = (uint8_t *) rte_realloc(values,
+ sizeof(uint8_t) * (n_tokens + 1), 0);
+
+ if (resize_values == NULL) {
+ rte_free(values);
+ return -1;
+ }
+
+ *data = resize_values;
+ *data_length = n_tokens + 1;
+
+ return 0;
+}
+
+/* checks the type of key and assigns data */
+static int
+parse_entry(char *entry, struct cperf_test_vector *vector)
+{
+ char *token, *key_token;
+ uint8_t *data = NULL;
+ int status;
+ uint32_t data_length;
+
+ /* get key */
+ token = strtok(entry, ENTRY_DELIMITER);
+ key_token = token;
+
+ /* get values for key */
+ token = strtok(NULL, ENTRY_DELIMITER);
+
+ if (token == NULL) {
+ printf("Expected 'key = values' but was '%.40s'..\n",
+ key_token);
+ return -1;
+ }
+
+ status = parse_values(token, &data, &data_length);
+ if (status)
+ return -1;
+
+ /* compare keys */
+ if (strstr(key_token, "plaintext")) {
+ if (vector->plaintext.data)
+ rte_free(vector->plaintext.data);
+ vector->plaintext.data = data;
+ vector->plaintext.length = data_length;
+ } else if (strstr(key_token, "cipher_key")) {
+ if (vector->cipher_key.data)
+ rte_free(vector->cipher_key.data);
+ vector->cipher_key.data = data;
+ vector->cipher_key.length = data_length;
+ } else if (strstr(key_token, "auth_key")) {
+ if (vector->auth_key.data)
+ rte_free(vector->auth_key.data);
+ vector->auth_key.data = data;
+ vector->auth_key.length = data_length;
+ } else if (strstr(key_token, "iv")) {
+ if (vector->iv.data)
+ rte_free(vector->iv.data);
+ vector->iv.data = data;
+ vector->iv.phys_addr = rte_malloc_virt2phy(vector->iv.data);
+ vector->iv.length = data_length;
+ } else if (strstr(key_token, "ciphertext")) {
+ if (vector->ciphertext.data)
+ rte_free(vector->ciphertext.data);
+ vector->ciphertext.data = data;
+ vector->ciphertext.length = data_length;
+ } else if (strstr(key_token, "aad")) {
+ if (vector->aad.data)
+ rte_free(vector->aad.data);
+ vector->aad.data = data;
+ vector->aad.phys_addr = rte_malloc_virt2phy(vector->aad.data);
+ vector->aad.length = data_length;
+ } else if (strstr(key_token, "digest")) {
+ if (vector->digest.data)
+ rte_free(vector->digest.data);
+ vector->digest.data = data;
+ vector->digest.phys_addr = rte_malloc_virt2phy(
+ vector->digest.data);
+ vector->digest.length = data_length;
+ } else {
+ printf("Not valid key: '%s'\n", trim(key_token));
+ return -1;
+ }
+
+ return 0;
+}
+
+/* searches in the file for registry keys and values */
+static int
+parse_file(struct cperf_test_vector *v_vec, const char *path)
+{
+ FILE *fp;
+ char *line = NULL, *entry = NULL;
+ ssize_t read;
+ size_t len = 0;
+ int status = 0;
+
+ fp = fopen(path, "r");
+ if (fp == NULL) {
+ printf("File %s does not exists\n", path);
+ return -1;
+ }
+
+ while ((read = getline(&line, &len, fp)) != -1) {
+ /* ignore comments and new lines */
+ if (line[0] == '#' || line[0] == '/' || line[0] == '\n'
+ || line[0] == '\r' || line[0] == ' ')
+ continue;
+
+ trim(line);
+
+ /* buffer for multiline */
+ entry = (char *) rte_realloc(entry,
+ sizeof(char) * strlen(line) + 1, 0);
+ if (entry == NULL)
+ return -1;
+
+ memset(entry, 0, strlen(line) + 1);
+ strncpy(entry, line, strlen(line));
+
+ /* check if entry ends with , or = */
+ if (entry[strlen(entry) - 1] == ','
+ || entry[strlen(entry) - 1] == '=') {
+ while ((read = getline(&line, &len, fp)) != -1) {
+ trim(line);
+
+ /* extend entry about length of new line */
+ char *entry_extended = (char *) rte_realloc(
+ entry, sizeof(char)
+ * (strlen(line) + strlen(entry))
+ + 1, 0);
+
+ if (entry_extended == NULL)
+ goto err;
+ entry = entry_extended;
+
+ strncat(entry, line, strlen(line));
+
+ if (entry[strlen(entry) - 1] != ',')
+ break;
+ }
+ }
+ status = parse_entry(entry, v_vec);
+ if (status) {
+ printf("An error occurred while parsing!\n");
+ goto err;
+ }
+ }
+
+ fclose(fp);
+ free(line);
+ rte_free(entry);
+
+ return 0;
+
+err:
+ if (fp)
+ fclose(fp);
+ if (line)
+ free(line);
+ if (entry)
+ rte_free(entry);
+
+ return -1;
+}
+
+struct cperf_test_vector*
+cperf_test_vector_get_from_file(struct cperf_options *opts)
+{
+ int status;
+ struct cperf_test_vector *test_vector = NULL;
+
+ if (opts == NULL || opts->test_file == NULL)
+ return test_vector;
+
+ test_vector = (struct cperf_test_vector *) rte_zmalloc(NULL,
+ sizeof(struct cperf_test_vector), 0);
+ if (test_vector == NULL)
+ return test_vector;
+
+ /* filling the vector with data from a file */
+ status = parse_file(test_vector, opts->test_file);
+ if (status) {
+ free_test_vector(test_vector, opts);
+ return NULL;
+ }
+
+ /* other values not included in the file */
+ test_vector->data.cipher_offset = 0;
+ test_vector->data.cipher_length = opts->buffer_sz;
+
+ test_vector->data.auth_offset = 0;
+ test_vector->data.auth_length = opts->buffer_sz;
+
+ return test_vector;
+}
diff --git a/app/test-crypto-perf/data/aes_cbc_128_sha.data b/app/test-crypto-perf/data/aes_cbc_128_sha.data
new file mode 100644
index 0000000..42fa194
--- /dev/null
+++ b/app/test-crypto-perf/data/aes_cbc_128_sha.data
@@ -0,0 +1,503 @@
+# List of tests for AES-128 CBC:
+# 1) [sha1_hmac_buff_x]
+# 2) [sha224_hmac_buff_x]
+# 3) [sha256_hmac_buff_x]
+# 4) [sha384_hmac_buff_x]
+# 5) [sha512_hmac_buff_x]
+# where x is one of the values: 32, 64, 128, 256, 512, 1024, 2048
+
+##########
+# GLOBAL #
+##########
+plaintext =
+0xff, 0xca, 0xfb, 0xf1, 0x38, 0x20, 0x2f, 0x7b, 0x24, 0x98, 0x26, 0x7d, 0x1d, 0x9f, 0xb3, 0x93,
+0xd9, 0xef, 0xbd, 0xad, 0x4e, 0x40, 0xbd, 0x60, 0xe9, 0x48, 0x59, 0x90, 0x67, 0xd7, 0x2b, 0x7b,
+0x8a, 0xe0, 0x4d, 0xb0, 0x70, 0x38, 0xcc, 0x48, 0x61, 0x7d, 0xee, 0xd6, 0x35, 0x49, 0xae, 0xb4,
+0xaf, 0x6b, 0xdd, 0xe6, 0x21, 0xc0, 0x60, 0xce, 0x0a, 0xf4, 0x1c, 0x2e, 0x1c, 0x8d, 0xe8, 0x7b,
+0x59, 0xda, 0x19, 0x4f, 0xec, 0x07, 0x8e, 0xe2, 0xf0, 0x61, 0xf9, 0x27, 0x61, 0x6f, 0xf8, 0xdf,
+0x62, 0x4d, 0xaf, 0x06, 0xfe, 0x41, 0xa6, 0xa6, 0xf9, 0xa2, 0x06, 0x40, 0xb3, 0x04, 0xbd, 0xe6,
+0xc8, 0x17, 0xfb, 0x56, 0x6f, 0xa9, 0x3b, 0x8e, 0xa6, 0x58, 0xdc, 0x91, 0x17, 0x58, 0x42, 0x95,
+0xa3, 0x7c, 0x81, 0x78, 0xa6, 0x3d, 0x3f, 0x75, 0x74, 0x17, 0x1a, 0xd3, 0x6c, 0x2f, 0x48, 0x39,
+0x20, 0x20, 0xc1, 0x9a, 0x29, 0x84, 0x7d, 0x2d, 0x52, 0xa1, 0xf9, 0x5c, 0xf3, 0x4f, 0x91, 0xfc,
+0x75, 0xcf, 0xd6, 0x2d, 0xe7, 0x9a, 0x59, 0x6e, 0x00, 0x0e, 0x8d, 0x22, 0x17, 0xbd, 0xa0, 0xdd,
+0x79, 0x1f, 0x71, 0xe6, 0xcd, 0x2f, 0xb1, 0xb6, 0xbc, 0xc3, 0xdb, 0x02, 0x91, 0x41, 0x9b, 0x09,
+0xa9, 0xd2, 0x7e, 0xbd, 0x2c, 0x18, 0xae, 0xc0, 0x93, 0x0c, 0x02, 0x9a, 0xdb, 0x4e, 0xaa, 0xeb,
+0x84, 0x4b, 0x43, 0x5e, 0xf0, 0x98, 0xf2, 0x5f, 0x86, 0x70, 0x96, 0x90, 0x15, 0x30, 0xcf, 0x3a,
+0xc9, 0x33, 0x21, 0xec, 0x59, 0x86, 0xfc, 0x65, 0x7d, 0xbe, 0xb9, 0xf8, 0x97, 0xf9, 0x30, 0xa9,
+0x6d, 0xfc, 0x0c, 0x6e, 0x36, 0x67, 0xd5, 0xa6, 0x67, 0xd9, 0xbd, 0x9b, 0x34, 0x5d, 0xa7, 0xdd,
+0xda, 0x46, 0x33, 0x25, 0x60, 0x4a, 0x18, 0xf1, 0x55, 0x07, 0xb2, 0xb7, 0x26, 0x7b, 0xa6, 0x1e,
+0x77, 0xbe, 0x7f, 0x35, 0x46, 0xdf, 0x56, 0x9c, 0x22, 0x19, 0xc8, 0x85, 0xa2, 0x45, 0xb2, 0xad,
+0xf9, 0x26, 0x66, 0xab, 0xfc, 0x97, 0x4b, 0x51, 0x32, 0x36, 0xbc, 0xad, 0xcf, 0x54, 0x3a, 0x4f,
+0x94, 0xdb, 0xd2, 0xf9, 0x67, 0x1b, 0x3b, 0xe5, 0xb2, 0x1d, 0xc5, 0x52, 0x64, 0x2c, 0x06, 0x44,
+0xcf, 0x18, 0x83, 0xe0, 0xd8, 0x04, 0x92, 0xa9, 0xc4, 0x3c, 0x8b, 0xa3, 0x2b, 0xbc, 0x88, 0x7e,
+0xc0, 0x76, 0xa7, 0xe2, 0x7b, 0x47, 0x90, 0xf2, 0xaa, 0x0a, 0x34, 0x1b, 0x91, 0x12, 0xd2, 0xd0,
+0x82, 0x45, 0xf4, 0x57, 0xf1, 0xbd, 0x91, 0x5e, 0xab, 0x41, 0x4c, 0xdf, 0x91, 0x4c, 0xdd, 0x67,
+0x04, 0xa0, 0x98, 0x23, 0x8c, 0x24, 0xbe, 0xd6, 0x80, 0xb3, 0x6d, 0x04, 0xa1, 0x77, 0x43, 0xa5,
+0xee, 0xb7, 0xce, 0xb1, 0x48, 0x43, 0x94, 0x61, 0x15, 0x20, 0x9d, 0xce, 0xd0, 0x14, 0x95, 0x37,
+0xc8, 0x64, 0xa3, 0x2d, 0x3d, 0xe3, 0xff, 0xb4, 0x55, 0x83, 0x84, 0x41, 0x50, 0x57, 0xbd, 0x5a,
+0x0c, 0xe4, 0xda, 0x3b, 0x36, 0x4d, 0x21, 0xb5, 0x6f, 0x73, 0x2a, 0x8c, 0x78, 0x4f, 0x9b, 0x83,
+0xda, 0x11, 0x3c, 0xf0, 0xc9, 0x7e, 0xa6, 0x48, 0x34, 0x53, 0x62, 0xd3, 0x0c, 0xff, 0xb1, 0x74,
+0xd6, 0xea, 0xa5, 0xfc, 0x13, 0x1c, 0x05, 0xa8, 0xc0, 0xbc, 0x95, 0x9c, 0x8c, 0xf6, 0x8c, 0xc3,
+0xf3, 0x69, 0xab, 0x93, 0x65, 0xc0, 0xb7, 0x7e, 0xb0, 0x16, 0x7c, 0xb5, 0x5f, 0x05, 0x28, 0xc9,
+0x09, 0x4e, 0x2a, 0x32, 0x87, 0xb3, 0xab, 0xf8, 0x4c, 0xab, 0xeb, 0x3b, 0x6a, 0xa0, 0x1d, 0x7f,
+0xef, 0xe5, 0x9b, 0xa4, 0xb7, 0xd7, 0xc2, 0x5e, 0x03, 0x0f, 0x99, 0xeb, 0xb1, 0xb1, 0xa6, 0x9d,
+0x1c, 0x7c, 0x5c, 0x94, 0x8b, 0x6e, 0x11, 0x7a, 0xb3, 0x6d, 0x1e, 0x61, 0x64, 0xc3, 0x7d, 0x1c,
+0xb3, 0x54, 0x65, 0x08, 0x3b, 0xda, 0x97, 0xb9, 0x75, 0xc1, 0x2b, 0x3e, 0xa8, 0x5c, 0x3c, 0x2d,
+0x81, 0x5b, 0xbf, 0x5a, 0x13, 0x0e, 0xeb, 0x66, 0xc0, 0x0b, 0x8f, 0x04, 0x68, 0x68, 0x9b, 0xe3,
+0x0d, 0x84, 0xe0, 0xcf, 0x83, 0xd7, 0x62, 0x48, 0xc1, 0x31, 0xa5, 0xd5, 0xbc, 0xe3, 0xa3, 0xa5,
+0xb6, 0xd1, 0xfd, 0x81, 0x91, 0x4d, 0xbd, 0xc4, 0x62, 0x4f, 0xe3, 0xd5, 0x99, 0x14, 0xf1, 0xcd,
+0xf4, 0x7d, 0x13, 0xda, 0x68, 0x0a, 0xca, 0xd6, 0x82, 0x0b, 0xf6, 0xea, 0xad, 0x78, 0xa4, 0xc8,
+0x14, 0x7a, 0xec, 0x11, 0xd3, 0x16, 0x86, 0x9f, 0x17, 0x37, 0x6a, 0x06, 0x56, 0xaa, 0x1b, 0xd1,
+0xaf, 0x85, 0x95, 0x21, 0x36, 0x69, 0xec, 0x1b, 0x56, 0x84, 0x01, 0x3f, 0x4d, 0x34, 0x3d, 0x2d,
+0x38, 0x57, 0x2d, 0x7e, 0xd9, 0x7b, 0x2d, 0x81, 0x86, 0xd4, 0x7c, 0x83, 0x12, 0x1d, 0x9d, 0x27,
+0x72, 0x1b, 0x5e, 0xf4, 0x15, 0xa5, 0xcd, 0xb7, 0x5f, 0xbb, 0x49, 0xa1, 0xd9, 0xdd, 0x8d, 0xad,
+0xa9, 0x2c, 0x65, 0x18, 0x91, 0xfd, 0xd2, 0xd4, 0x09, 0x60, 0x0c, 0xfd, 0xa4, 0xe1, 0x25, 0x87,
+0x32, 0x64, 0x7b, 0x99, 0xd7, 0x61, 0x2f, 0xd4, 0x73, 0xdd, 0x85, 0x26, 0x08, 0x92, 0xc0, 0xe1,
+0x4f, 0x0c, 0x76, 0x5b, 0x26, 0x69, 0xdb, 0x78, 0x35, 0x65, 0xb9, 0x58, 0x1f, 0x9c, 0x0f, 0x18,
+0x95, 0xfe, 0x40, 0xfc, 0xf7, 0x93, 0x71, 0x70, 0x8b, 0x73, 0xdc, 0xb0, 0x88, 0x72, 0x19, 0x26,
+0x94, 0x26, 0xa7, 0xaa, 0x00, 0x72, 0x61, 0x53, 0xd2, 0x5d, 0x8f, 0x5e, 0x51, 0x88, 0x2d, 0xa4,
+0x28, 0xd5, 0xaf, 0x2d, 0xd2, 0x84, 0x39, 0x75, 0x1e, 0xe7, 0xf0, 0x23, 0xc0, 0x4f, 0x8d, 0xdd,
+0x5c, 0x90, 0xef, 0x6e, 0x53, 0xe0, 0x54, 0x67, 0xe1, 0x5b, 0x10, 0xf1, 0xf5, 0xf8, 0x64, 0x34,
+0x94, 0xeb, 0x37, 0xf7, 0xe9, 0xaa, 0x6c, 0xa4, 0xd8, 0x74, 0x6d, 0xca, 0x8d, 0x1a, 0x31, 0x73,
+0xca, 0xb4, 0xc7, 0x47, 0x34, 0x7f, 0xf8, 0x24, 0x9b, 0xfa, 0xc9, 0xcc, 0xa8, 0x61, 0xb4, 0x0e,
+0x4d, 0x68, 0xc7, 0xa0, 0xcb, 0xea, 0xf0, 0xcc, 0x0a, 0x6c, 0xf2, 0x33, 0x42, 0x99, 0x6c, 0xd8,
+0x74, 0x7f, 0x1e, 0x8a, 0xa3, 0x0a, 0x48, 0x4b, 0x7e, 0xbe, 0xdb, 0x7f, 0x56, 0x69, 0x43, 0xe8,
+0xbf, 0x12, 0xc4, 0x7b, 0xc2, 0xd9, 0xfa, 0x5c, 0xeb, 0x45, 0xca, 0x07, 0x3d, 0xc0, 0xcd, 0x68,
+0x8b, 0xd0, 0x79, 0xea, 0x0a, 0x78, 0x06, 0xdc, 0x81, 0xd7, 0x32, 0x18, 0xb3, 0x65, 0xbe, 0x47,
+0xbb, 0xfa, 0x17, 0x09, 0xe9, 0x31, 0x95, 0x30, 0xef, 0x07, 0x44, 0xec, 0xd0, 0x98, 0x98, 0xc0,
+0x6b, 0x71, 0x5b, 0x23, 0xb8, 0xb6, 0xd2, 0x21, 0xff, 0x51, 0xdd, 0xae, 0x48, 0x29, 0x75, 0x0c,
+0xc3, 0x3d, 0x91, 0xfe, 0x9d, 0xa8, 0x5e, 0xb2, 0x34, 0xb2, 0xd3, 0x81, 0xf6, 0x27, 0x9c, 0xac,
+0x6b, 0x20, 0x56, 0x86, 0xa5, 0x4f, 0x7a, 0xdb, 0xf9, 0xac, 0xa9, 0x8e, 0xe3, 0x73, 0x21, 0x99,
+0x71, 0x2d, 0xaf, 0x27, 0x92, 0x0c, 0xc7, 0xd3, 0x85, 0xb3, 0x40, 0xda, 0x13, 0x4a, 0x04, 0x41,
+0x54, 0xf8, 0xf2, 0x55, 0xb7, 0x80, 0xdd, 0x77, 0xba, 0x01, 0x7a, 0x31, 0xbd, 0x6b, 0xdc, 0x5c,
+0x59, 0xf4, 0x2b, 0xca, 0x25, 0xbb, 0x50, 0xba, 0xfa, 0x42, 0x38, 0xd2, 0x28, 0x10, 0x8b, 0x7b,
+0x96, 0x45, 0x30, 0xbb, 0x7f, 0xf4, 0x5a, 0xf7, 0x28, 0x6f, 0x47, 0xdc, 0xd2, 0x82, 0xf2, 0xf7,
+0xdd, 0x20, 0xb5, 0x0c, 0x7e, 0x53, 0x85, 0xa7, 0xfc, 0x3b, 0x1a, 0xc0, 0x07, 0x7b, 0xa1, 0x43,
+0x05, 0x18, 0x19, 0xd3, 0xfc, 0x41, 0xc2, 0xce, 0xd9, 0x5b, 0x4b, 0x63, 0xe2, 0x8f, 0x86, 0x3a,
+0xd1, 0xd0, 0x1d, 0x74, 0x2e, 0xbc, 0xd3, 0xce, 0x08, 0x0c, 0x10, 0x7a, 0x42, 0x60, 0xc5, 0x3a,
+0xa6, 0xd8, 0xb0, 0x52, 0xcf, 0x53, 0x28, 0x70, 0x45, 0xb7, 0x72, 0x7d, 0x77, 0x66, 0x54, 0x3d,
+0x38, 0x26, 0xcf, 0xd5, 0xbf, 0xe4, 0x80, 0x10, 0xba, 0x2b, 0xe8, 0xdc, 0xc3, 0xfe, 0x28, 0xa3,
+0x52, 0x58, 0x70, 0x4a, 0xde, 0x84, 0x33, 0x5e, 0x93, 0x04, 0xa4, 0x7c, 0xe7, 0xea, 0x8e, 0xba,
+0xeb, 0x8a, 0x19, 0x26, 0x6a, 0x7f, 0x7c, 0x4a, 0x5b, 0xb4, 0x0d, 0xfc, 0xc8, 0x11, 0x1b, 0x41,
+0x68, 0x5d, 0x2a, 0x25, 0x04, 0x4f, 0xc8, 0xf4, 0x65, 0xfc, 0xb9, 0x58, 0xeb, 0xb4, 0x67, 0x50,
+0x24, 0xf5, 0x43, 0xf6, 0x91, 0x4a, 0xb0, 0x0f, 0x32, 0xe0, 0x07, 0x75, 0x69, 0x1b, 0x3c, 0xeb,
+0xb2, 0x65, 0x26, 0x6f, 0xb8, 0x79, 0xe0, 0x78, 0x8c, 0xdc, 0x39, 0x24, 0x48, 0x76, 0x11, 0xd4,
+0x3a, 0xc5, 0xd2, 0x2b, 0xaa, 0x55, 0xfb, 0x92, 0x12, 0x2d, 0x88, 0x05, 0xd1, 0xb1, 0x31, 0x36,
+0x1f, 0xc2, 0x44, 0x1c, 0xab, 0x2e, 0xcd, 0x1c, 0x72, 0x86, 0xf6, 0x83, 0x87, 0x2e, 0x8b, 0xdb,
+0xaa, 0x16, 0x0e, 0x1b, 0xe6, 0x5c, 0x4d, 0x2f, 0x82, 0xbd, 0x49, 0x11, 0x60, 0x22, 0x0f, 0xde,
+0x3b, 0x2b, 0x20, 0x1d, 0x56, 0xb7, 0x21, 0xae, 0x0b, 0x26, 0x4f, 0xde, 0x3d, 0xa6, 0x3f, 0x61,
+0x81, 0xe2, 0x76, 0x60, 0x08, 0xc5, 0x4b, 0x18, 0x0b, 0xd1, 0xf5, 0xff, 0x8d, 0x1a, 0x96, 0x76,
+0x51, 0x15, 0x05, 0x4d, 0x8c, 0x6b, 0x12, 0x90, 0x47, 0xd4, 0xa4, 0x38, 0xb9, 0x48, 0xe4, 0x4c,
+0x05, 0x69, 0x6a, 0x8b, 0x9d, 0x7c, 0xa1, 0xbc, 0x77, 0xeb, 0x86, 0x93, 0x0a, 0x15, 0x84, 0xba,
+0x8f, 0xf5, 0x7c, 0x44, 0x75, 0x31, 0x79, 0x16, 0xc1, 0x81, 0x1a, 0xb6, 0xe6, 0x6c, 0x3d, 0xb8,
+0x15, 0x46, 0xf5, 0xbe, 0x46, 0x04, 0xa6, 0xec, 0xec, 0xd1, 0x74, 0x8b, 0x87, 0x2b, 0xdb, 0xd0,
+0x9f, 0xb3, 0x99, 0x9d, 0x87, 0x8c, 0xc6, 0xaa, 0xd4, 0x64, 0x45, 0xbd, 0xe8, 0xed, 0xa3, 0xc1,
+0x2a, 0x41, 0x1e, 0x26, 0xaf, 0x86, 0x16, 0xed, 0x80, 0x08, 0xca, 0x64, 0x21, 0x3a, 0xce, 0x21,
+0x4c, 0x41, 0xb9, 0x13, 0x2d, 0xf7, 0x1b, 0xdf, 0x2b, 0x33, 0x69, 0xe7, 0x5c, 0x8c, 0x7b, 0xfb,
+0xe3, 0x41, 0xe9, 0xce, 0xd7, 0xff, 0x0e, 0x54, 0xfe, 0xb0, 0x71, 0x78, 0xdc, 0xde, 0x7e, 0xdd,
+0x1f, 0x1c, 0x4a, 0x8f, 0x3e, 0x16, 0xfd, 0x91, 0x82, 0x94, 0xd4, 0xc2, 0xf7, 0xb2, 0x77, 0x89,
+0x16, 0x2c, 0xba, 0xb6, 0xbd, 0xed, 0x95, 0x43, 0x05, 0x9b, 0xf2, 0xc4, 0xbe, 0x46, 0x43, 0x90,
+0x1d, 0xd8, 0x24, 0x02, 0xd2, 0xea, 0xf4, 0x08, 0xd9, 0xf7, 0x84, 0x0e, 0xc6, 0xe7, 0x44, 0xdb,
+0xb8, 0xac, 0x0a, 0x53, 0x39, 0x61, 0x43, 0xdc, 0x22, 0x28, 0x8f, 0x22, 0x2f, 0x73, 0xbf, 0x59,
+0x2d, 0x3c, 0x8c, 0x0b, 0xcc, 0x2a, 0x67, 0xe0, 0x5b, 0x5c, 0x65, 0x5e, 0x6d, 0x98, 0x99, 0xaa,
+0x3b, 0x89, 0x12, 0xe2, 0x99, 0xf6, 0x15, 0xa7, 0xd2, 0x6a, 0x79, 0xb4, 0xf6, 0x0b, 0xf5, 0x0d,
+0x2d, 0x4c, 0xcb, 0x1b, 0x35, 0x93, 0x61, 0x32, 0xa1, 0x8a, 0xa8, 0x27, 0xe8, 0x95, 0x5a, 0x56,
+0x59, 0x04, 0xfe, 0xce, 0xc2, 0xd8, 0x92, 0x97, 0xb2, 0x54, 0x63, 0xd0, 0x3b, 0xde, 0x10, 0x34,
+0x32, 0x16, 0x05, 0x51, 0x1d, 0xfc, 0x96, 0x8e, 0xf1, 0xf6, 0x4b, 0xd7, 0x48, 0x22, 0xce, 0xca,
+0x1c, 0x6b, 0xab, 0x1f, 0x59, 0xa2, 0x74, 0xd6, 0xcd, 0x15, 0x07, 0xab, 0xa2, 0xd5, 0x22, 0x81,
+0xec, 0x20, 0x14, 0x36, 0xac, 0xe4, 0x25, 0x7d, 0xe6, 0x09, 0x00, 0x2c, 0x92, 0x4d, 0x4e, 0xbf,
+0xbf, 0xa1, 0xd4, 0xbe, 0x6b, 0xd4, 0x1f, 0x95, 0x9b, 0xf3, 0xda, 0x99, 0xad, 0xa4, 0x6c, 0x73,
+0x55, 0xd1, 0x9d, 0x4b, 0x16, 0xd4, 0x06, 0xec, 0x46, 0x3d, 0xb7, 0xe7, 0xce, 0xd0, 0x1d, 0x94,
+0x65, 0xde, 0x61, 0xb3, 0xc1, 0x10, 0x65, 0xe5, 0x68, 0x9b, 0xb0, 0xb4, 0x43, 0x0b, 0x92, 0xaf,
+0xb7, 0x40, 0xa2, 0xe5, 0x06, 0x3d, 0x72, 0x00, 0xc5, 0x39, 0xab, 0x35, 0x29, 0x22, 0x4c, 0xa5,
+0xa5, 0x3f, 0x22, 0x90, 0x53, 0xd2, 0x36, 0x63, 0x1e, 0xd3, 0x33, 0xa5, 0xbb, 0x3d, 0xa3, 0x0c,
+0x14, 0x9c, 0x2e, 0x6d, 0x9a, 0x7a, 0xf7, 0xf1, 0x56, 0x66, 0xe5, 0x8d, 0x53, 0x83, 0x34, 0x3f,
+0xa9, 0x83, 0x84, 0x68, 0x90, 0xc9, 0x51, 0xc2, 0xd4, 0x8e, 0x6c, 0xc7, 0x6d, 0xa7, 0x19, 0x61,
+0xa7, 0x2e, 0x36, 0xbc, 0xd2, 0x0f, 0x17, 0x49, 0xd4, 0x6b, 0x36, 0x63, 0xfb, 0x1d, 0xf4, 0xb0,
+0x6b, 0xcf, 0x34, 0x5f, 0xd2, 0x77, 0xae, 0x12, 0xaf, 0xb3, 0xdf, 0x52, 0xf7, 0xc2, 0xc8, 0xf2,
+0x63, 0x61, 0xb6, 0x3e, 0x39, 0xf2, 0xa7, 0x1a, 0x89, 0x9d, 0x0e, 0x8f, 0xaf, 0xe1, 0x01, 0x24,
+0xa6, 0x3a, 0xd5, 0x9a, 0x62, 0x67, 0xa3, 0x66, 0xee, 0xbc, 0xc5, 0x94, 0x4b, 0xc3, 0x15, 0xa1,
+0x7e, 0x07, 0x07, 0x2b, 0xb7, 0x43, 0x2a, 0xb4, 0xb8, 0x25, 0x88, 0x86, 0x23, 0xab, 0xdf, 0x05,
+0xbe, 0x46, 0x56, 0xd7, 0xda, 0xd6, 0x75, 0x53, 0xd9, 0xc8, 0x26, 0x8f, 0x39, 0x67, 0xed, 0x21,
+0x53, 0x1c, 0x9c, 0x89, 0x46, 0xd3, 0xfe, 0x54, 0xe6, 0x1d, 0x02, 0xb9, 0x25, 0x82, 0x66, 0xe6,
+0xf9, 0x45, 0xd9, 0x3f, 0xa5, 0x71, 0xc1, 0x46, 0x66, 0x7a, 0x27, 0x8a, 0x82, 0xc9, 0x21, 0xe9,
+0x17, 0xab, 0x6c, 0xef, 0x45, 0xe5, 0x88, 0x93, 0x87, 0x80, 0xb3, 0x85, 0x25, 0x96, 0x19, 0x41,
+0xab, 0xd6, 0xba, 0x92, 0x76, 0x21, 0x8a, 0x58, 0xbd, 0xe2, 0x4b, 0xec, 0x45, 0x59, 0x2c, 0x13,
+0x1a, 0xb5, 0x13, 0x25, 0x44, 0xe7, 0x71, 0x26, 0x0a, 0x34, 0x33, 0xb9, 0x57, 0x15, 0xa4, 0x90,
+0x60, 0x11, 0x05, 0x8e, 0xc8, 0x8e, 0x74, 0x52, 0x4b, 0x31, 0x71, 0xeb, 0x66, 0x7e, 0xee, 0xb1,
+0x0a, 0x21, 0x52, 0xc0, 0x1a, 0xe9, 0xa1, 0x5a, 0xe3, 0x3a, 0x24, 0xfb, 0xf3, 0x1e, 0xd6, 0x83,
+0x1d, 0xfb, 0x81, 0xa8, 0x91, 0x60, 0x9e, 0xbc, 0x59, 0x20, 0xc9, 0x9e, 0x71, 0x19, 0x83, 0x2b,
+0x6a, 0x48, 0x4e, 0x6b, 0x46, 0x82, 0x89, 0xda, 0x60, 0xff, 0x1a, 0x46, 0x94, 0x55, 0xda, 0xe5,
+0x99, 0xfa, 0x84, 0xd7, 0x3b, 0xb9, 0xa5, 0x34, 0x87, 0x86, 0x5e, 0x6d, 0x75, 0x9a, 0xe7, 0x09,
+0xb8, 0xe6, 0x71, 0x15, 0x10, 0x56, 0xd7, 0xc1, 0xc8, 0xb2, 0x62, 0xbc, 0xec, 0xe0, 0x94, 0xa0,
+0xcd, 0xb4, 0x04, 0xa9, 0xc3, 0x51, 0xee, 0xf8, 0x2e, 0x42, 0x9a, 0xaa, 0x34, 0xd3, 0xb9, 0xb0,
+0x36, 0xf9, 0x47, 0xc1, 0x07, 0x49, 0xde, 0xb8, 0x32, 0x8a, 0x87, 0x68, 0x56, 0x9a, 0x35, 0x79,
+0xd1, 0xac, 0x49, 0x38, 0xc6, 0xfe, 0xfd, 0xdf, 0x6f, 0x3c, 0xda, 0x48, 0xbd, 0x23, 0xfd, 0x85,
+0xf0, 0x96, 0xee, 0x1c, 0x27, 0x18, 0x86, 0xa6, 0xf0, 0x7b, 0xd8, 0x3c, 0xc7, 0x22, 0x3e, 0x2f,
+0xac, 0xb1, 0x37, 0xbd, 0x84, 0x4b, 0xe3, 0x92, 0x82, 0xd0, 0x25, 0x14, 0x22, 0x65, 0xed, 0xeb,
+0xef, 0xb9, 0xb6, 0xe4, 0x95, 0x18, 0x0d, 0x2b, 0x8d, 0x4f, 0xaf, 0xc0, 0xa0, 0x05, 0x8b, 0x35,
+0x5b, 0x94, 0xb2, 0x68, 0x26, 0x4f, 0x4a, 0x9e, 0x85, 0x0e, 0x46, 0xe0, 0x4f, 0x60, 0x66, 0x01,
+0xa4, 0x39, 0xe8, 0x8b, 0x2a, 0x50, 0xf5, 0x18, 0x70, 0xe2, 0xfc, 0xd6, 0xbe, 0xd3, 0x46, 0x4b
+
+ciphertext =
+0xd7, 0x0a, 0xed, 0x84, 0xf9, 0x13, 0x83, 0xd0, 0xbf, 0x57, 0xc2, 0x8b, 0xc9, 0x8c, 0x3a, 0x19,
+0x6a, 0x50, 0x01, 0xb7, 0xfe, 0xe2, 0x54, 0x0d, 0x94, 0x41, 0xcc, 0xcb, 0xe7, 0x41, 0x6f, 0x16,
+0xf7, 0x24, 0xd7, 0x01, 0x8d, 0xae, 0xc7, 0xa3, 0x4c, 0x36, 0xc2, 0x9c, 0x06, 0xba, 0xe2, 0x27,
+0x4f, 0xd2, 0xbb, 0x55, 0x65, 0xbb, 0xeb, 0x33, 0xe3, 0xaa, 0x6a, 0x47, 0x8c, 0xa4, 0xb4, 0x2f,
+0xe6, 0x20, 0xde, 0xde, 0x93, 0x59, 0x35, 0x79, 0x17, 0x84, 0x7d, 0x9b, 0xee, 0x72, 0x0a, 0x0f,
+0xb9, 0x59, 0xb3, 0xc5, 0xbc, 0x9c, 0xf1, 0xdb, 0x52, 0x5c, 0x90, 0xd2, 0x4d, 0x5a, 0x5e, 0xb9,
+0xdf, 0x27, 0x2c, 0xbd, 0xc2, 0xcf, 0x16, 0x30, 0xbe, 0xa4, 0x45, 0xeb, 0xc2, 0x6f, 0x01, 0x26,
+0x1a, 0xa6, 0xb1, 0x87, 0x4e, 0x6d, 0x95, 0x0c, 0xa6, 0x01, 0xca, 0x53, 0x5d, 0x0b, 0x35, 0x5c,
+0xa7, 0x42, 0x2f, 0x7a, 0x18, 0x4b, 0x18, 0x51, 0x0e, 0x80, 0xf0, 0x7e, 0xca, 0x0e, 0xec, 0x88,
+0x19, 0xa0, 0xce, 0x1f, 0xea, 0x61, 0x88, 0x26, 0xa9, 0xd1, 0xd0, 0xdf, 0x5c, 0x90, 0x87, 0x34,
+0xda, 0x68, 0x26, 0x49, 0xcf, 0xf7, 0x10, 0x7f, 0x09, 0x11, 0xde, 0x40, 0xd2, 0x17, 0x65, 0x6f,
+0x70, 0x3f, 0x43, 0xaa, 0x73, 0xbf, 0xb4, 0x4e, 0x07, 0x4e, 0x41, 0x89, 0xd3, 0xa7, 0xb3, 0x49,
+0x09, 0x05, 0xb5, 0x9d, 0x7d, 0x45, 0x11, 0x0b, 0x0f, 0x8a, 0x83, 0x2a, 0x94, 0x80, 0x4b, 0xcf,
+0xa3, 0x97, 0xb3, 0x93, 0x2f, 0xbc, 0x1f, 0xdf, 0xe7, 0xb7, 0xec, 0x3a, 0x39, 0xeb, 0xa9, 0x8d,
+0x7f, 0x9b, 0xf7, 0x12, 0xfc, 0x0c, 0x28, 0xe4, 0x82, 0x98, 0x88, 0xf7, 0x93, 0x4a, 0x0a, 0xdc,
+0x8d, 0x77, 0x2d, 0x7b, 0xd6, 0x6a, 0x6f, 0x0d, 0x54, 0x55, 0x0c, 0xe8, 0x6b, 0x71, 0xda, 0x7b,
+0x5a, 0xc5, 0x79, 0xa4, 0x2d, 0x61, 0xeb, 0x07, 0x95, 0x0a, 0x8a, 0x2c, 0x5c, 0xb0, 0xe2, 0x08,
+0xab, 0x07, 0x04, 0x3a, 0x00, 0xce, 0x6e, 0xc1, 0x7f, 0x0e, 0x65, 0x6a, 0xbe, 0x9c, 0xd5, 0xab,
+0x0f, 0x90, 0x6a, 0xfb, 0x45, 0x2f, 0x78, 0x80, 0xbe, 0x8a, 0x0c, 0xe1, 0x79, 0xf9, 0xfd, 0xbe,
+0x0d, 0xea, 0xfb, 0x57, 0x2b, 0x5f, 0xbf, 0x25, 0x8d, 0xa0, 0xd5, 0x4e, 0xac, 0x0d, 0x13, 0x66,
+0x75, 0xd0, 0xe3, 0x69, 0x2d, 0x1e, 0x85, 0xd1, 0x2b, 0xdb, 0xa0, 0xaa, 0x8d, 0x2c, 0x1d, 0xd2,
+0x69, 0x46, 0x4f, 0x3d, 0xe2, 0xd7, 0x80, 0xba, 0xa1, 0x53, 0x35, 0xb4, 0xd4, 0x4f, 0x33, 0x0e,
+0x03, 0xb8, 0xd0, 0xb8, 0x13, 0xc8, 0x12, 0xe6, 0x49, 0x0b, 0xe2, 0x0f, 0x2b, 0x09, 0xcf, 0x82,
+0x36, 0x9e, 0x87, 0x24, 0xc0, 0x66, 0xd8, 0xd2, 0x40, 0x33, 0xa4, 0x4b, 0x1f, 0x30, 0x9a, 0x1a,
+0x12, 0x65, 0x1e, 0xfc, 0x63, 0x3b, 0x31, 0x75, 0xc6, 0x85, 0xa4, 0xf0, 0x04, 0xb2, 0x56, 0x6c,
+0xeb, 0x0f, 0xae, 0xf4, 0x6a, 0x47, 0xae, 0x9c, 0xe1, 0x88, 0xc2, 0xf0, 0x7b, 0x28, 0xaa, 0xb8,
+0xb8, 0x23, 0x82, 0xec, 0xe1, 0xfa, 0x69, 0x71, 0xa9, 0x6c, 0x91, 0x05, 0x4e, 0x94, 0x41, 0x0c,
+0x53, 0x01, 0x35, 0x29, 0xc0, 0xc4, 0x75, 0x51, 0x0f, 0x61, 0x6a, 0x06, 0x02, 0x9b, 0x61, 0xd2,
+0x2a, 0xdd, 0xc8, 0x2b, 0x71, 0x2e, 0xcd, 0x94, 0xe6, 0x61, 0x88, 0xa5, 0xf9, 0xd5, 0xb8, 0x39,
+0xe6, 0x97, 0x4b, 0x1f, 0x8c, 0xf0, 0xfc, 0x2c, 0x9a, 0xd6, 0xc2, 0x4d, 0x56, 0x49, 0x2c, 0x7c,
+0x31, 0x00, 0x9c, 0x22, 0xf4, 0xad, 0xf0, 0x6d, 0x73, 0xe3, 0xda, 0x5a, 0x80, 0x8d, 0x25, 0xbd,
+0x6f, 0xe9, 0xb1, 0x39, 0x19, 0xd5, 0x5b, 0x4c, 0xc1, 0xb1, 0xa3, 0x57, 0xee, 0x41, 0xef, 0x23,
+0x7a, 0x47, 0xde, 0x56, 0x0c, 0x2d, 0x43, 0x77, 0xcc, 0x17, 0xc1, 0x6c, 0xf9, 0x90, 0xf2, 0xa0,
+0x1a, 0xb8, 0xab, 0x7a, 0x99, 0x90, 0xc8, 0x5b, 0x19, 0x20, 0x4e, 0xd9, 0x4b, 0xb4, 0x92, 0x71,
+0x27, 0x44, 0x30, 0x83, 0x6d, 0x39, 0x24, 0xa3, 0x0a, 0xa5, 0xf4, 0x5c, 0x31, 0x16, 0x26, 0xdb,
+0x62, 0xe1, 0x74, 0xf3, 0x89, 0xc6, 0x59, 0x6d, 0xcd, 0x10, 0xb9, 0xcc, 0x9a, 0x5b, 0x9a, 0x31,
+0xfa, 0xbb, 0x5b, 0x79, 0xc7, 0x05, 0x78, 0xcb, 0x15, 0x7f, 0x71, 0x51, 0x00, 0x95, 0xb0, 0x3b,
+0x82, 0x5d, 0xe2, 0x48, 0xfd, 0x19, 0xca, 0x87, 0xde, 0x16, 0x52, 0x61, 0xd0, 0x72, 0xbd, 0x00,
+0x7d, 0xae, 0x3f, 0x54, 0x2e, 0x36, 0xc8, 0x9d, 0xb9, 0x2b, 0xdf, 0x12, 0xe4, 0x46, 0x1b, 0x29,
+0xda, 0x6b, 0x8d, 0xa5, 0xfd, 0x28, 0xbc, 0x0f, 0x13, 0x27, 0x82, 0x06, 0x9f, 0xf2, 0xd3, 0x3e,
+0x80, 0x2b, 0x86, 0xf8, 0x2c, 0x4b, 0xd6, 0x82, 0x20, 0x9b, 0xa7, 0xa4, 0x7d, 0xd3, 0xf1, 0x9b,
+0xe3, 0x94, 0x6b, 0xd3, 0x12, 0x14, 0xd5, 0x70, 0x0e, 0x8e, 0x2c, 0xc2, 0x5f, 0x22, 0x37, 0x09,
+0x02, 0xbd, 0x03, 0x64, 0xd8, 0xc5, 0x61, 0xca, 0xe6, 0xea, 0x76, 0xf6, 0xce, 0x21, 0xb2, 0x00,
+0xef, 0x99, 0x4f, 0xd7, 0x9d, 0x8b, 0xaa, 0xa4, 0x2a, 0x37, 0x5a, 0x98, 0x71, 0x11, 0x1c, 0xf7,
+0xf1, 0x8e, 0x34, 0x80, 0x07, 0xfa, 0x8d, 0x5a, 0xb3, 0x84, 0xdf, 0xa6, 0xbe, 0x53, 0x87, 0x31,
+0xe3, 0xb1, 0xe1, 0xd0, 0x9e, 0x2e, 0xec, 0x5b, 0x46, 0xb9, 0x87, 0xa0, 0x45, 0xb4, 0x5b, 0x92,
+0x68, 0x98, 0x4c, 0x69, 0xa1, 0xf4, 0x49, 0x8e, 0xc9, 0x50, 0xf7, 0x9b, 0x99, 0x5b, 0x4e, 0x99,
+0xda, 0x8e, 0xa8, 0x39, 0x04, 0x21, 0x94, 0x06, 0x00, 0xdc, 0x45, 0xd8, 0xfe, 0x53, 0x0b, 0x7b,
+0xe5, 0x26, 0x27, 0x61, 0xaa, 0x37, 0x8f, 0x7d, 0x3f, 0xe7, 0xb4, 0xc7, 0x8d, 0x6f, 0xf6, 0x76,
+0x04, 0xed, 0x9f, 0x0d, 0x46, 0xf7, 0x4d, 0x3d, 0x2e, 0x9f, 0x92, 0x8c, 0x7a, 0x73, 0x82, 0x3b,
+0xfb, 0x04, 0x8e, 0xcb, 0xc2, 0xd9, 0xf3, 0x23, 0x35, 0x40, 0xde, 0xf0, 0x6f, 0xd2, 0xcd, 0xed,
+0xe2, 0xc7, 0xf6, 0x0b, 0x75, 0xbd, 0x33, 0x6f, 0x80, 0x23, 0x99, 0x07, 0xb8, 0x39, 0x47, 0x43,
+0x72, 0x55, 0xf1, 0xe6, 0xbf, 0x8e, 0xb9, 0x55, 0x75, 0x8b, 0xb0, 0x32, 0xdc, 0x60, 0xaa, 0xb8,
+0x66, 0xbe, 0xb2, 0xb8, 0xa3, 0x99, 0x9e, 0xef, 0xb5, 0x85, 0x1c, 0xe7, 0x6a, 0x8e, 0x07, 0x59,
+0x50, 0x65, 0xd2, 0x71, 0x0b, 0xc5, 0x6f, 0x4f, 0xa3, 0x45, 0xfc, 0xf2, 0x1d, 0x08, 0x85, 0x3e,
+0x50, 0x7c, 0xba, 0x16, 0x4c, 0xf5, 0x0d, 0x12, 0xe6, 0xe3, 0x87, 0x37, 0xd7, 0xe9, 0x2c, 0x7f,
+0xb5, 0x1a, 0xa2, 0x65, 0xdf, 0xfc, 0x32, 0x85, 0x0c, 0x12, 0x81, 0x49, 0xf4, 0x9b, 0xbb, 0xeb,
+0x69, 0xe4, 0x8a, 0x43, 0x56, 0x73, 0x32, 0xf5, 0xdf, 0x88, 0xba, 0xd7, 0xde, 0xfa, 0x1d, 0xfb,
+0xaa, 0xa3, 0xb6, 0x3b, 0x2d, 0xca, 0xe8, 0x9a, 0xb3, 0x21, 0x3c, 0xcf, 0x76, 0x72, 0x66, 0xe2,
+0x46, 0x74, 0xff, 0xae, 0x54, 0x52, 0x59, 0x55, 0x1c, 0x17, 0x1b, 0x82, 0x11, 0x6c, 0x1c, 0x42,
+0x3f, 0xbc, 0x1c, 0x81, 0x5a, 0x3f, 0x61, 0x82, 0xa3, 0xa7, 0x26, 0x1f, 0x4e, 0xd0, 0xaf, 0x0e,
+0xf9, 0xe0, 0x24, 0x8c, 0xe4, 0x3d, 0x3f, 0x2e, 0x73, 0x81, 0xaf, 0x25, 0xe3, 0xc6, 0x98, 0x4a,
+0x4c, 0xca, 0x65, 0x84, 0xd2, 0x64, 0xd1, 0xf4, 0x53, 0xe0, 0x6f, 0xac, 0x40, 0xea, 0x6e, 0x36,
+0xcf, 0x85, 0x4b, 0x94, 0x3e, 0x93, 0x8b, 0xb6, 0xe5, 0x0f, 0x7b, 0x3a, 0xe8, 0xf2, 0x78, 0xd0,
+0xc6, 0xb6, 0xdf, 0x66, 0xde, 0xc7, 0x7e, 0x1d, 0x10, 0x05, 0x60, 0x5d, 0xbd, 0x41, 0x5d, 0xfc,
+0x07, 0xd8, 0x9f, 0x6a, 0xf4, 0x65, 0xd2, 0x69, 0x88, 0x29, 0x72, 0x32, 0xe0, 0x53, 0x56, 0x04,
+0x20, 0x6d, 0x3c, 0x01, 0x7a, 0xd0, 0x63, 0x4a, 0x06, 0x9f, 0xe2, 0x88, 0x02, 0x39, 0xa1, 0xd7,
+0x81, 0x5e, 0x83, 0xcd, 0x09, 0x12, 0x56, 0xd4, 0x71, 0x85, 0x35, 0xe0, 0x0b, 0x55, 0x96, 0x6d,
+0x16, 0x88, 0xb5, 0x9d, 0x8f, 0xd6, 0x1e, 0xe6, 0x39, 0x47, 0x7f, 0xae, 0x47, 0x30, 0xb7, 0x28,
+0x72, 0x23, 0xfc, 0x10, 0xb8, 0xad, 0xf7, 0xd6, 0x57, 0x3c, 0xc5, 0xf7, 0xd5, 0x4f, 0xb8, 0xc1,
+0x02, 0xc2, 0xd5, 0x8c, 0xe5, 0x19, 0x0f, 0x69, 0xd3, 0x26, 0x9e, 0xb6, 0x6a, 0x43, 0xca, 0xf6,
+0x9f, 0x60, 0x7b, 0x4b, 0x34, 0x01, 0x00, 0x08, 0x51, 0xa4, 0x28, 0x6c, 0x10, 0x51, 0x18, 0x80,
+0x90, 0x0c, 0xd0, 0xb9, 0x0e, 0x29, 0xe4, 0x09, 0xd8, 0xd3, 0x74, 0x13, 0x4f, 0x28, 0x43, 0xc7,
+0xde, 0xec, 0xeb, 0xd7, 0xf9, 0xa2, 0xc4, 0x13, 0x94, 0x45, 0x37, 0x24, 0x6c, 0x33, 0x9c, 0xd3,
+0xb4, 0x38, 0x08, 0x9f, 0x9a, 0x8e, 0xf4, 0x40, 0xc5, 0x9a, 0xd3, 0x93, 0x6b, 0x45, 0xfa, 0x46,
+0xfd, 0xe0, 0x15, 0x38, 0xf0, 0xe7, 0xdc, 0x68, 0xcf, 0x35, 0x0f, 0x04, 0x6c, 0x1b, 0x50, 0xea,
+0x3a, 0xc4, 0x1c, 0x24, 0xf0, 0x5f, 0x9b, 0xf4, 0xcd, 0x05, 0x07, 0x88, 0xb6, 0x06, 0x94, 0x92,
+0xb9, 0xbd, 0x70, 0x74, 0x16, 0xea, 0x0b, 0x1e, 0xfd, 0x42, 0xe7, 0x03, 0x4a, 0xc1, 0x70, 0xef,
+0xdb, 0x3d, 0x87, 0x0b, 0x66, 0xf6, 0x2e, 0x9e, 0x77, 0x67, 0x2a, 0xc0, 0x4c, 0x43, 0xe7, 0xe0,
+0xa6, 0x01, 0xd5, 0xef, 0x00, 0xc4, 0xe3, 0x5b, 0x2e, 0x51, 0xeb, 0x73, 0x1d, 0x64, 0xa1, 0xcf,
+0x61, 0xf1, 0xdf, 0x5e, 0x21, 0x50, 0x71, 0x7e, 0xfe, 0x9c, 0x01, 0xc3, 0x34, 0x63, 0x61, 0x40,
+0x13, 0x51, 0x3e, 0x57, 0xb7, 0x74, 0x73, 0x8d, 0x93, 0x67, 0x87, 0x44, 0x6e, 0x8c, 0x35, 0x06,
+0x96, 0x3a, 0xe4, 0xa1, 0xa7, 0xe2, 0x36, 0x1b, 0x34, 0xc8, 0x28, 0xc2, 0x0d, 0x99, 0xf0, 0x6b,
+0x87, 0x7a, 0x11, 0xc6, 0x3c, 0xf1, 0x05, 0xf3, 0xde, 0x44, 0xdb, 0x80, 0x49, 0x40, 0x71, 0xaf,
+0x90, 0x21, 0xca, 0x49, 0x79, 0x35, 0xf7, 0xa0, 0x96, 0x91, 0x2b, 0x23, 0x84, 0x1b, 0x29, 0xaa,
+0x86, 0x8d, 0xa5, 0x47, 0x60, 0xdf, 0xc3, 0xf7, 0xd6, 0x07, 0x89, 0x8f, 0x40, 0xd5, 0x18, 0x12,
+0xba, 0x76, 0x86, 0x88, 0x9c, 0xe4, 0x05, 0x12, 0x2a, 0x95, 0x55, 0xab, 0x13, 0x0a, 0x43, 0x01,
+0xd5, 0x75, 0xde, 0x78, 0x75, 0xab, 0xf2, 0x34, 0x5d, 0x4b, 0x02, 0x31, 0x18, 0x3e, 0xb1, 0x69,
+0xff, 0xf9, 0x71, 0x0f, 0x69, 0x0f, 0xef, 0x69, 0xb4, 0xc6, 0x45, 0xd2, 0x1c, 0xca, 0xf0, 0xec,
+0x07, 0x07, 0x06, 0x97, 0xd1, 0xb5, 0xb7, 0xf3, 0x1d, 0x80, 0xef, 0x46, 0xc3, 0x23, 0xe5, 0x44,
+0x5b, 0x53, 0x96, 0xf1, 0x18, 0xda, 0xa7, 0xd5, 0x90, 0x72, 0x07, 0xac, 0x25, 0xde, 0x0a, 0x79,
+0x16, 0x8c, 0x4c, 0x7a, 0xe1, 0x35, 0x9d, 0xec, 0x0c, 0x39, 0xa8, 0xf4, 0xc2, 0xa1, 0xda, 0x7f,
+0x0b, 0x7c, 0x89, 0x5f, 0x5b, 0x53, 0x32, 0xd1, 0x80, 0xd1, 0x21, 0x82, 0x32, 0x5b, 0x5b, 0x87,
+0x98, 0x5a, 0x8f, 0x9f, 0xe1, 0x96, 0x7b, 0x43, 0xd9, 0x58, 0xd0, 0xe3, 0xd1, 0xfa, 0xa0, 0x7d,
+0x80, 0x00, 0xe1, 0x12, 0xc8, 0x13, 0xa7, 0xe1, 0xc5, 0x32, 0xc8, 0x0f, 0x03, 0x9c, 0xa2, 0x31,
+0xd8, 0x81, 0x07, 0x40, 0xc2, 0x0d, 0x2d, 0x25, 0xc0, 0x13, 0xa9, 0x57, 0x9d, 0x14, 0x78, 0x0e,
+0x3e, 0xab, 0x22, 0x5e, 0x29, 0x66, 0x3e, 0xea, 0x59, 0x1a, 0x6f, 0xa3, 0xbf, 0x29, 0x51, 0x3b,
+0x18, 0xe0, 0xab, 0x8c, 0xfb, 0xe6, 0x00, 0x57, 0x1c, 0x1d, 0xd2, 0x59, 0x7d, 0xa5, 0xf4, 0x8c,
+0xfa, 0xe6, 0x2a, 0x77, 0x09, 0x93, 0x3a, 0x7d, 0x9d, 0xa9, 0x3d, 0xf2, 0xae, 0xb7, 0xcc, 0x5c,
+0xa3, 0xf1, 0x00, 0x4b, 0x8c, 0xaf, 0xd7, 0xbc, 0x78, 0x35, 0x9b, 0x56, 0x64, 0xe9, 0x22, 0x60,
+0xd8, 0x67, 0x7e, 0x7d, 0x18, 0xc1, 0x44, 0x16, 0xcb, 0x9a, 0x79, 0x4d, 0x62, 0x31, 0x4d, 0xbe,
+0x07, 0x97, 0x0a, 0x7b, 0x46, 0x8a, 0x55, 0xcd, 0xbd, 0x3e, 0x06, 0x39, 0x55, 0x73, 0xac, 0x4d,
+0x2c, 0xc0, 0x35, 0x2c, 0x69, 0x99, 0xad, 0xfd, 0x47, 0x1e, 0xa8, 0xdc, 0x1c, 0xe2, 0x11, 0x1f,
+0x20, 0xe2, 0xda, 0x7d, 0x03, 0x48, 0xf4, 0x82, 0x22, 0xb5, 0x15, 0x21, 0xcc, 0xb2, 0xdb, 0x3a,
+0x8f, 0x30, 0xdf, 0xa6, 0x4d, 0x93, 0x6d, 0xd4, 0xd7, 0xf7, 0x38, 0xda, 0xa6, 0x38, 0x10, 0x81,
+0xdd, 0x70, 0xb0, 0x77, 0xa3, 0x7b, 0x4f, 0x6e, 0xb9, 0x62, 0xf2, 0x98, 0x32, 0x59, 0xd0, 0x4a,
+0xb3, 0x0a, 0x1a, 0x99, 0x0d, 0x4e, 0xd5, 0x06, 0xb0, 0xaa, 0xfe, 0x26, 0x86, 0x4d, 0xb1, 0xaf,
+0xd2, 0x0b, 0xc2, 0xf5, 0xee, 0x90, 0xf0, 0x72, 0xc0, 0x12, 0xe9, 0xa9, 0xdd, 0xc0, 0xe2, 0x77,
+0x4c, 0x74, 0x35, 0xa8, 0x8a, 0xc0, 0x72, 0x90, 0xb6, 0x1d, 0x97, 0xdd, 0xa3, 0x15, 0x7f, 0x5b,
+0x51, 0xe5, 0x35, 0x27, 0x56, 0x84, 0x42, 0x42, 0xc3, 0x8f, 0x8f, 0x86, 0x76, 0x0e, 0xd9, 0xac,
+0xea, 0xa5, 0xe3, 0x35, 0x42, 0x61, 0x4d, 0x74, 0xec, 0x67, 0x3e, 0x63, 0x05, 0x0e, 0xda, 0xcd,
+0xf7, 0x53, 0xe0, 0xa0, 0xd6, 0x16, 0xc1, 0x51, 0x8c, 0x02, 0xbc, 0xeb, 0x2f, 0xb6, 0xee, 0x6b,
+0x5f, 0x68, 0x48, 0x54, 0x5e, 0x0f, 0x97, 0x39, 0x26, 0xd9, 0x0c, 0xd4, 0xa0, 0xc0, 0xd3, 0x6f,
+0x06, 0x2c, 0x55, 0xb6, 0x96, 0x43, 0x8b, 0x70, 0x5c, 0x2e, 0xd1, 0xd7, 0x3e, 0x79, 0x21, 0xe3,
+0x09, 0x2c, 0x41, 0x5f, 0xcc, 0x95, 0xa1, 0x62, 0xcc, 0x28, 0x85, 0x09, 0xf7, 0x66, 0x82, 0x81,
+0xa6, 0x87, 0x22, 0xa1, 0xe5, 0x6b, 0x46, 0xfb, 0xeb, 0x3c, 0xb9, 0x29, 0xab, 0xab, 0x15, 0x96,
+0xa6, 0xb5, 0x34, 0x68, 0xd4, 0x94, 0xc8, 0xb2, 0xc9, 0x37, 0x15, 0x9a, 0xd2, 0xf7, 0xd9, 0xcf,
+0x07, 0x5b, 0xcf, 0xa4, 0x6a, 0x86, 0xcc, 0xfc, 0xf5, 0x10, 0xd1, 0x99, 0x5d, 0xf1, 0x90, 0xba,
+0x6a, 0xe6, 0x31, 0x2e, 0x92, 0xe9, 0x43, 0x7f, 0xf7, 0x83, 0x58, 0x9e, 0x17, 0x8b, 0xb6, 0x26,
+0xcc, 0x86, 0x12, 0x84, 0x74, 0x6c, 0x4c, 0xfb, 0xef, 0xb3, 0x90, 0xd9, 0x52, 0x6f, 0x2c, 0x56,
+0x42, 0x79, 0x52, 0xf6, 0xae, 0x0c, 0x55, 0x71, 0x9f, 0xf3, 0x80, 0xae, 0x97, 0x03, 0x2f, 0xab,
+0xee, 0x70, 0x9d, 0x06, 0x2c, 0x46, 0xca, 0x21, 0x03, 0x08, 0xef, 0x14, 0xdf, 0x77, 0x02, 0x89,
+0xd6, 0x46, 0x40, 0x3d, 0xb5, 0x95, 0xdb, 0x4b, 0x9c, 0x09, 0x23, 0xd4, 0x86, 0xe8, 0xe5, 0x0a,
+0xe1, 0xcc, 0x64, 0xd6, 0x11, 0x50, 0xb6, 0x2c, 0x8c, 0xc1, 0xd8, 0xeb, 0x8b, 0xbd, 0x65, 0x0a,
+0x22, 0x61, 0x0c, 0xe5, 0x16, 0x9a, 0xa6, 0x0f, 0xc3, 0x0d, 0xcf, 0x44, 0xa9, 0xe7, 0x26, 0x80,
+0x00, 0xef, 0x4d, 0x8a, 0xf1, 0x12, 0x73, 0x76, 0x8a, 0xdf, 0xf5, 0xc3, 0x60, 0x85, 0xd3, 0x19,
+0xc0, 0x81, 0x04, 0x92, 0xb1, 0x06, 0x6e, 0x1a, 0xf1, 0x3f, 0x27, 0x9a, 0xd3, 0x37, 0xa1, 0xb7,
+0x98, 0x13, 0x85, 0xa3, 0xc9, 0x51, 0x9a, 0x5e, 0x67, 0x50, 0xb1, 0x44, 0xa7, 0x90, 0xc4, 0x41
+
+cipher_key =
+0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A
+
+auth_key =
+0xaf, 0x96, 0x42, 0xf1, 0x8c, 0x50, 0xdc, 0x67, 0x1a, 0x43, 0x47, 0x62, 0xc7, 0x04, 0xab, 0x05,
+0xf5, 0x0c, 0xe7, 0xa2, 0xa6, 0x23, 0xd5, 0x3d, 0x95, 0xd8, 0xcd, 0x86, 0x79, 0xf5, 0x01, 0x47,
+0x4f, 0xf9, 0x1d, 0x9d, 0x36, 0xf7, 0x68, 0x1a, 0x64, 0x44, 0x58, 0x5d, 0xe5, 0x81, 0x15, 0x2a,
+0x41, 0xe4, 0x0e, 0xaa, 0x1f, 0x04, 0x21, 0xff, 0x2c, 0xf3, 0x73, 0x2b, 0x48, 0x1e, 0xd2, 0xf7,
+0xf6, 0xd9, 0xaf, 0xbf, 0x08, 0x3b, 0xbb, 0x19, 0x5f, 0xf6, 0x7d, 0x25, 0x85, 0xdf, 0x6b, 0x54,
+0xd0, 0xe7, 0x4b, 0x9e, 0xc7, 0xef, 0xca, 0x48, 0x6f, 0x21, 0xd7, 0x51, 0xc8, 0x21, 0xc1, 0x15,
+0xe8, 0x38, 0x36, 0x58, 0x39, 0xd9, 0x9a, 0xc5, 0xe7, 0x3b, 0xc4, 0x47, 0xe2, 0xbd, 0x80, 0x73,
+0xf8, 0xd1, 0x9a, 0x5e, 0x4b, 0xfb, 0x52, 0x6b, 0x50, 0xaf, 0x8b, 0xb7, 0xb5, 0x2c, 0x52, 0x84
+
+iv =
+0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+
+####################
+# sha_hmac_buff_32 #
+####################
+[sha1_hmac_buff_32]
+digest =
+0x8C, 0xD8, 0x0F, 0x6F, 0x32, 0xED, 0x11, 0xFF, 0x3B, 0xC3, 0x1C, 0xA7, 0x62, 0xE2, 0x2B, 0xCB,
+0x87, 0x65, 0x58, 0x92
+
+[sha224_hmac_buff_32]
+digest =
+0x2A, 0x97, 0xC8, 0xF8, 0x95, 0xAB, 0x35, 0x88, 0x88, 0x0F, 0x9B, 0x06, 0xEC ,0xE9, 0x27, 0xA3,
+0x17, 0x99, 0x28, 0xF8, 0xDF, 0xB4, 0xE1, 0x4E, 0x47, 0x0B, 0xDE, 0x8D
+
+[sha256_hmac_buff_32]
+digest =
+0x5C, 0x92, 0xD1, 0x03, 0x49, 0xA5, 0x20, 0x3E, 0x1B, 0x88, 0x6A, 0x30, 0xFB, 0x45, 0x1A, 0x4D,
+0xF7, 0xF2, 0xD0, 0x78, 0x20, 0x61, 0x7C, 0xD6, 0x4E, 0x0E, 0x7B, 0x3B, 0x35, 0xFE, 0xD8, 0x9A
+
+[sha384_hmac_buff_32]
+digest =
+0x8A, 0x39, 0x0D, 0x1C, 0x0C, 0x4A, 0x3C, 0x25, 0xA7, 0x43, 0x2C, 0x26, 0xF3, 0xCF, 0xB4, 0x92,
+0x41, 0x9C, 0x2C, 0xE2, 0x63, 0x40, 0x0B, 0x91, 0xD8, 0xB6, 0x30, 0xE4, 0x9F, 0x96, 0xDE, 0x3C,
+0xED, 0x66, 0x8B, 0x65, 0x5A, 0xA3, 0xB8, 0xD4, 0x01, 0xB3, 0xBC, 0xAA, 0x08, 0x92, 0x5C, 0x2F
+
+[sha512_hmac_buff_32]
+digest =
+0x1E, 0x27, 0xE8, 0xBD, 0xDA, 0x56, 0xC0, 0x5D, 0x04, 0xA0, 0xFC, 0x21, 0xCF, 0x52, 0x07, 0x45,
+0x28, 0xAD, 0x33, 0xC4, 0x3C, 0x07, 0x0B, 0x6B, 0xC9, 0x90, 0x2B, 0xE5, 0xCA, 0x11, 0x7C, 0x86,
+0x95, 0xF4, 0xC4, 0x56, 0xAC, 0x86, 0x0D, 0xF0, 0x62, 0xB8, 0x6C, 0xFC, 0x88, 0xC6, 0xBA, 0xF7,
+0x35, 0xDD, 0xB6, 0x2E, 0x34, 0x09, 0x27, 0x93, 0xB0, 0xF3, 0x0B, 0x7D, 0x9F, 0x74, 0x2D, 0x4F
+
+####################
+# sha_hmac_buff_64 #
+####################
+[sha1_hmac_buff_64]
+digest =
+0xAC, 0xD8, 0x84, 0x6B, 0x21, 0x20, 0xFE, 0x7D, 0x60, 0xA9, 0x6C, 0x0D, 0x64, 0xF9, 0x27, 0x5D,
+0x2F, 0xE9, 0xDF, 0x94
+
+[sha224_hmac_buff_64]
+digest =
+0xB2, 0x30, 0xEC, 0xC5, 0x3A, 0xA5, 0x77, 0x30, 0xDE, 0x64, 0xCE, 0x6D, 0x23, 0xF1, 0x07, 0xBF,
+0x96, 0x2A, 0xFE, 0x3A, 0xFD, 0xA1, 0x97, 0x3E, 0x73, 0x17, 0x42, 0x0B
+
+[sha256_hmac_buff_64]
+digest =
+0xB9, 0x48, 0x3B, 0x99, 0x56, 0x93, 0x0A, 0x4E, 0x11, 0xC8, 0x6D, 0x51, 0x56, 0xD6, 0xFB, 0xC4,
+0x2D, 0x36, 0x0C, 0x3B, 0x18, 0xF6, 0x3E, 0xF8, 0xD2, 0x5D, 0xA5, 0x9F, 0xFB, 0xE8, 0x58, 0x93
+
+[sha384_hmac_buff_64]
+digest =
+0x76, 0x45, 0x45, 0xB5, 0xE5, 0xDE, 0xC2, 0x7B, 0x01, 0xAA, 0x58, 0xB7, 0xD2, 0xCA, 0x0B, 0x6A,
+0xA1, 0x4E, 0x0D, 0xCC, 0xCF, 0x22, 0x9D, 0xBA, 0xA1, 0x6C, 0x54, 0x1A, 0x3B, 0x8B, 0xD9, 0x6F,
+0xB5, 0xA9, 0xC2, 0x80, 0xBF, 0x6C, 0xED, 0xED, 0xA1, 0xB0, 0x15, 0xA6, 0x91, 0x5A, 0xDD, 0x3F
+
+[sha512_hmac_buff_64]
+digest =
+0xED, 0xD9, 0xCA, 0xFE, 0x44, 0x12, 0x8F, 0xF1, 0xCD, 0x91, 0x58, 0x2A, 0x4D, 0xC7, 0x77, 0x50,
+0xD1, 0xBD, 0x9D, 0x33, 0xE3, 0x3A, 0xEA, 0xE1, 0x64, 0x18, 0x48, 0xE9, 0xF0, 0xEC, 0xE0, 0x0F,
+0x13, 0xFD, 0xB9, 0xB2, 0xCF, 0xBC, 0x43, 0x07, 0x66, 0x6E, 0x76, 0x18, 0x27, 0x0D, 0x15, 0x50,
+0x8A, 0x1C, 0x88, 0x8C, 0xC9, 0xDA, 0xD8, 0x30, 0x09, 0xE7, 0xD5, 0x25, 0xB8, 0x09, 0xFF, 0x20
+
+#####################
+# sha_hmac_buff_128 #
+#####################
+[sha1_hmac_buff_128]
+digest =
+0x09, 0x94, 0x8F, 0xD2, 0xE9, 0x08, 0x5B, 0x76, 0xAC, 0xCB, 0x07, 0x60, 0xE7, 0x41, 0xBD, 0x6C,
+0x91, 0x9E, 0xF4, 0x87
+
+[sha224_hmac_buff_128]
+digest =
+0x3A, 0x85, 0x01, 0x4C, 0xF7, 0xA8, 0xB0, 0xF7, 0x74, 0xAB, 0xB0, 0x89, 0x83, 0x2C, 0x3A, 0xA1,
+0x28, 0x87, 0xD7, 0xAB, 0xCF, 0x14, 0xE0, 0x73, 0xFB, 0x19, 0x85, 0xEF
+
+[sha256_hmac_buff_128]
+digest =
+0x7F, 0x79, 0xE4, 0x17, 0x6E, 0xE5, 0x78, 0xA0, 0x26, 0x65, 0x62, 0x7D, 0xB5, 0x69, 0x62, 0xC0,
+0x7B, 0x5C, 0xBA, 0x55, 0x06, 0xAD, 0x3D, 0xDE, 0xAA, 0xA7, 0xED, 0x82, 0x3A, 0xBD, 0xBA, 0xFB
+
+[sha384_hmac_buff_128]
+digest =
+0xEC, 0x68, 0xCB, 0x8E, 0x90, 0xCF, 0x8D, 0x04, 0xAF, 0x1F, 0x4C, 0x0B, 0xE9, 0x9B, 0x03, 0x05,
+0x19, 0x54, 0x4D, 0x28, 0x02, 0x8B, 0x19, 0x39, 0x1D, 0x59, 0xEF, 0x9C, 0xA1, 0xA5, 0x06, 0x89,
+0x7B, 0x81, 0xDB, 0xD2, 0xAC, 0x21, 0x79, 0xFF, 0xE9, 0x5A, 0x8A, 0xEE, 0x28, 0x12, 0x8D, 0xB1
+
+[sha512_hmac_buff_128]
+digest =
+0x98, 0xED, 0x87, 0x00, 0x0B, 0x2E, 0x5C, 0xFA, 0x56, 0x94, 0x86, 0x96, 0x6A, 0x45, 0x99, 0xC4,
+0xD8, 0x7E, 0x69, 0x6E, 0xD0, 0x47, 0x01, 0xA9, 0x03, 0xBE, 0x8A, 0x77, 0xDB, 0x19, 0x29, 0xFA,
+0xB8, 0xBF, 0x7E, 0x3B, 0xB1, 0x0F, 0xF8, 0xED, 0x63, 0xD4, 0x9B, 0x6F, 0xE5, 0xD6, 0xE3, 0xED,
+0x2B, 0x89, 0xB2, 0xBD, 0xF7, 0x36, 0x9C, 0xE8, 0x02, 0x88, 0x42, 0x4A, 0x15, 0x24, 0xBB, 0xAB
+
+#####################
+# sha_hmac_buff_256 #
+#####################
+[sha1_hmac_buff_256]
+digest =
+0x1E, 0x7E, 0x38, 0x4E, 0x76, 0x38, 0x75, 0xFE, 0x02, 0xAB, 0x1C, 0xA2, 0xAE, 0xBC, 0x4B, 0x57,
+0x16, 0xB2, 0xB2, 0x4D
+
+[sha224_hmac_buff_256]
+digest =
+0x49, 0xDA, 0x8E, 0xFB, 0xCD, 0xDF, 0xB8, 0x17, 0x3E, 0xF7, 0xF2, 0x73, 0x03, 0x23, 0x1F, 0x57,
+0x7C, 0x50, 0x89, 0x24, 0x56, 0xF0, 0x54, 0x5D, 0x6A, 0x30, 0xE1, 0x44
+
+[sha256_hmac_buff_256]
+digest =
+0xAB, 0x6D, 0xBF, 0x17, 0x2B, 0xE0, 0xD5, 0xF1, 0xB3, 0xC3, 0x25, 0xFA, 0x99, 0xEF, 0x38, 0x91,
+0x12, 0x3B, 0xDE, 0xD7, 0x48, 0xA3, 0x69, 0x2E, 0xAD, 0xA8, 0xAD, 0x08, 0x42, 0xBC, 0x78, 0xE3
+
+[sha384_hmac_buff_256]
+digest =
+0x4C, 0xF8, 0x22, 0x1B, 0x10, 0xBE, 0xD2, 0xEA, 0xBF, 0x27, 0x7C, 0x11, 0xBC, 0x53, 0x8B, 0xC1,
+0x3B, 0x13, 0xC9, 0xE0, 0xAA, 0x7E, 0x41, 0x17, 0xD0, 0x2C, 0x15, 0x6D, 0x23, 0x2E, 0x4E, 0xA0,
+0x44, 0x45, 0xBC, 0x7E, 0xD3, 0x6D, 0x68, 0xA1, 0xDD, 0xD5, 0xA7, 0x0B, 0x0E, 0x5A, 0x21, 0x41
+
+[sha512_hmac_buff_256]
+digest =
+0x25, 0x03, 0x50, 0xD1, 0x7C, 0x35, 0x33, 0x5C, 0xB5, 0x08, 0xBA, 0xFA, 0x9A, 0x86, 0x8E, 0x95,
+0x67, 0x62, 0xCB, 0x02, 0xEE, 0x3A, 0x1A, 0xD0, 0x0D, 0xD0, 0x3A, 0x79, 0xC9, 0x01, 0x1B, 0x78,
+0xF2, 0xCA, 0x57, 0xA5, 0x3C, 0x1B, 0x44, 0xFA, 0xC0, 0xEF, 0xF7, 0x68, 0xF3, 0xE3, 0x75, 0xFB,
+0x85, 0xFF, 0xD0, 0x8A, 0xE3, 0x43, 0xBE, 0x98, 0x1C, 0xCF, 0xBA, 0x01, 0x84, 0x30, 0xC3, 0xE9
+
+#####################
+# sha_hmac_buff_512 #
+#####################
+[sha1_hmac_buff_512]
+digest =
+0x55, 0x80, 0xC9, 0x15, 0xF4, 0x5D, 0x67, 0xF1, 0xDE, 0x07, 0xF2, 0x91, 0x88, 0x59, 0x95, 0x34,
+0x3A, 0xF5, 0x01, 0x61
+
+[sha224_hmac_buff_512]
+digest =
+0x98, 0x3D, 0x26, 0x3C, 0x62, 0x20, 0x69, 0x12, 0x0A, 0x01, 0x9B, 0x83, 0xC4, 0xD3, 0xE7, 0xAE,
+0xAD, 0xF3, 0x80, 0x35, 0xC7, 0x2A, 0xD7, 0x9B, 0xA9, 0x59, 0x6F, 0x23
+
+[sha256_hmac_buff_512]
+digest =
+0x3B, 0xD9, 0x0C, 0x74, 0x2F, 0x3B, 0xBA, 0xCA, 0x05, 0xA9, 0x17, 0x87, 0xB5, 0x38, 0x68, 0x63,
+0xC6, 0x0D, 0x3B, 0xFA, 0x32, 0x10, 0x29, 0x60, 0xDB, 0x2E, 0xBA, 0x73, 0x5D, 0xF3, 0x8F, 0x9F
+
+[sha384_hmac_buff_512]
+digest =
+0xE9, 0xA4, 0x1A, 0x3B, 0xE1, 0xDD, 0xD8, 0x47, 0x21, 0xDC, 0xEB, 0xB9, 0x22, 0xAA, 0x45, 0xD2,
+0x61, 0x47, 0x63, 0x88, 0x13, 0x6E, 0x1E, 0x8A, 0x7D, 0x37, 0xE0, 0x21, 0xC0, 0x08, 0x66, 0xE7,
+0x84, 0xCA, 0x7A, 0x09, 0x87, 0x84, 0x07, 0xCF, 0x8A, 0x22, 0x41, 0x68, 0x0E, 0x48, 0x11, 0x2A
+
+[sha512_hmac_buff_512]
+digest =
+0xD5, 0x41, 0x0A, 0x48, 0x68, 0x9B, 0xC1, 0x86, 0x16, 0x1A, 0x5D, 0x9E, 0x0E, 0x62, 0x0F, 0xB1,
+0xEE, 0x03, 0xE1, 0x23, 0xFE, 0xF0, 0x0F, 0x3F, 0xB0, 0xE1, 0x9C, 0xBC, 0x3E, 0x6D, 0x28, 0xD6,
+0x59, 0xB6, 0xC6, 0x17, 0x75, 0xD0, 0x2E, 0x7C, 0x1E, 0xCA, 0x40, 0x23, 0x16, 0x93, 0x94, 0xAC,
+0xD2, 0xDD, 0x5B, 0xB5, 0xAB, 0x69, 0x70, 0x84, 0xAB, 0xCF, 0x71, 0x53, 0x45, 0xFC, 0x01, 0x23
+
+######################
+# sha_hmac_buff_1024 #
+######################
+[sha1_hmac_buff_1024]
+digest =
+0x77, 0x5E, 0xFB, 0x4C, 0x35, 0x03, 0x85, 0x7D, 0xBA, 0xBE, 0x9D, 0xD5, 0xD7, 0xC3, 0x62, 0xFB,
+0xC0, 0x11, 0x54, 0xF9
+
+[sha224_hmac_buff_1024]
+digest =
+0x1D, 0xC5, 0xAB, 0xE5, 0xEA, 0xAD, 0x5C, 0x72, 0xB3, 0x3D, 0xF4, 0x21, 0x69, 0x1E, 0x9C, 0xBC,
+0xE1, 0x86, 0x91, 0x80, 0x7D, 0x52, 0x6E, 0x31, 0x14, 0xAE, 0x8A, 0xB7
+
+[sha256_hmac_buff_1024]
+digest =
+0x74, 0xC9, 0x7C, 0x21, 0xF8, 0xCC, 0x4C, 0xCB, 0xD6, 0xC3, 0xED, 0xA5, 0xF4, 0xAE, 0x75, 0x5F,
+0xE7, 0xAA, 0x49, 0x2E, 0x63, 0x7D, 0xF3, 0xD6, 0x9E, 0x46, 0x6F, 0x8A, 0x5C, 0x4B, 0xDF, 0x51
+
+[sha384_hmac_buff_1024]
+digest =
+0x6A, 0xCB, 0xD7, 0x77, 0xC1, 0xC8, 0xF5, 0xF3, 0x4C, 0x6A, 0xF5, 0xFC, 0xD0, 0xC2, 0x68, 0xF1,
+0x45, 0x3C, 0xBA, 0xFF, 0x83, 0x98, 0xB4, 0x0A, 0x29, 0x97, 0x27, 0xE8, 0x74, 0x2B, 0x66, 0xC0,
+0x5B, 0x45, 0x70, 0xA0, 0x8E, 0xD5, 0x16, 0x88, 0x0D, 0xB9, 0xBA, 0x3A, 0x70, 0x3F, 0x4B, 0xD0
+
+[sha512_hmac_buff_1024]
+digest =
+0x6A, 0x8D, 0x3F, 0x10, 0x56, 0xAF, 0xF0, 0xD4, 0x00, 0xE7, 0x4D, 0xBB, 0xCD, 0x3E, 0xD0, 0x39,
+0x21, 0xC4, 0xFD, 0x04, 0xC1, 0x91, 0xB7, 0xE5, 0xDF, 0x52, 0xED, 0xE5, 0xA0, 0x87, 0x76, 0x0E,
+0x44, 0x63, 0xED, 0xDD, 0xEA, 0xBF, 0x2E, 0xBF, 0x6B, 0x87, 0x9E, 0x5C, 0xD7, 0x55, 0x73, 0xD0,
+0xB2, 0xAC, 0x12, 0x87, 0xE1, 0x96, 0xD4, 0x1E, 0xD0, 0x5D, 0x83, 0x88, 0xC2, 0x00, 0xD0, 0xBE
+
+######################
+# sha_hmac_buff_2048 #
+######################
+[sha1_hmac_buff_2048]
+digest =
+0x02, 0xD4, 0x67, 0xF9, 0x41, 0x5C, 0x91, 0x62, 0x7E, 0x39, 0x4B, 0x3C, 0x2D, 0x77, 0x7A, 0x2C,
+0x2D, 0x47, 0x3E, 0x48
+
+[sha224_hmac_buff_2048]
+digest =
+0xF0, 0x8D, 0x1C, 0xF8, 0x7A, 0x5E, 0xA5, 0x48, 0x36, 0x7F, 0x96, 0x4A, 0x66, 0x66, 0x36, 0x32,
+0x5D, 0x68, 0xB8, 0x21, 0x5A, 0xE1, 0x95, 0x4F, 0x22, 0xF4, 0x44, 0x38
+
+[sha256_hmac_buff_2048]
+digest =
+0x82, 0xC2, 0x7C, 0x08, 0xE2, 0x94, 0xD8, 0xA9, 0x3C, 0xBB, 0x54, 0x20, 0xC2, 0x01, 0xBC, 0xF4,
+0xA2, 0xEE, 0x76, 0x06, 0x78, 0xE9, 0x51, 0x2F, 0x4D, 0x7D, 0x20, 0x20, 0x75, 0x1E, 0xB2, 0x8A
+
+[sha384_hmac_buff_2048]
+digest =
+0x59, 0xA5, 0xAA, 0xEE, 0xD8, 0x13, 0xB1, 0xBF, 0x28, 0x83, 0xB8, 0xB2, 0xBC, 0x91, 0x0F, 0x2E,
+0xCB, 0xC4, 0xCD, 0x8F, 0xE4, 0xB1, 0x28, 0xBE, 0xC4, 0x1A, 0xC4, 0x45, 0xF9, 0xCC, 0x6C, 0x6F,
+0x71, 0x59, 0x2C, 0xC4, 0x47, 0x61, 0xFE, 0xBB, 0xDD, 0x2B, 0x99, 0xDD, 0x6A, 0x49, 0x61, 0x33
+
+[sha512_hmac_buff_2048]
+digest =
+0x90, 0xAD, 0xA3, 0xFB, 0xC3, 0x88, 0x1F, 0xD9, 0x53, 0xE4, 0x9C, 0x71, 0x38, 0x3B, 0xFA, 0x99,
+0x82, 0x32, 0xC4, 0xFC, 0x61, 0x36, 0x65, 0x9E, 0xDF, 0x9C, 0xDB, 0xD5, 0xD2, 0xD0, 0xAE, 0x78,
+0x74, 0x08, 0xF0, 0x97, 0x7E, 0x1A, 0x0C, 0xC3, 0xDD, 0x8F, 0xB3, 0x1C, 0x55, 0xAC, 0xA7, 0xC9,
+0x49, 0x1C, 0xA7, 0xF7, 0xBA, 0xC0, 0x93, 0x54, 0xA3, 0x6B, 0xBF, 0xA7, 0x03, 0x40, 0xE0, 0x28
\ No newline at end of file
diff --git a/app/test-crypto-perf/data/aes_cbc_192_sha.data b/app/test-crypto-perf/data/aes_cbc_192_sha.data
new file mode 100644
index 0000000..7bfe3da
--- /dev/null
+++ b/app/test-crypto-perf/data/aes_cbc_192_sha.data
@@ -0,0 +1,504 @@
+# List of tests for AES-192 CBC:
+# 1) [sha1_hmac_buff_x]
+# 2) [sha224_hmac_buff_x]
+# 3) [sha256_hmac_buff_x]
+# 4) [sha384_hmac_buff_x]
+# 5) [sha512_hmac_buff_x]
+# where x is one of the values: 32, 64, 128, 256, 512, 1024, 2048
+
+##########
+# GLOBAL #
+##########
+plaintext =
+0xff, 0xca, 0xfb, 0xf1, 0x38, 0x20, 0x2f, 0x7b, 0x24, 0x98, 0x26, 0x7d, 0x1d, 0x9f, 0xb3, 0x93,
+0xd9, 0xef, 0xbd, 0xad, 0x4e, 0x40, 0xbd, 0x60, 0xe9, 0x48, 0x59, 0x90, 0x67, 0xd7, 0x2b, 0x7b,
+0x8a, 0xe0, 0x4d, 0xb0, 0x70, 0x38, 0xcc, 0x48, 0x61, 0x7d, 0xee, 0xd6, 0x35, 0x49, 0xae, 0xb4,
+0xaf, 0x6b, 0xdd, 0xe6, 0x21, 0xc0, 0x60, 0xce, 0x0a, 0xf4, 0x1c, 0x2e, 0x1c, 0x8d, 0xe8, 0x7b,
+0x59, 0xda, 0x19, 0x4f, 0xec, 0x07, 0x8e, 0xe2, 0xf0, 0x61, 0xf9, 0x27, 0x61, 0x6f, 0xf8, 0xdf,
+0x62, 0x4d, 0xaf, 0x06, 0xfe, 0x41, 0xa6, 0xa6, 0xf9, 0xa2, 0x06, 0x40, 0xb3, 0x04, 0xbd, 0xe6,
+0xc8, 0x17, 0xfb, 0x56, 0x6f, 0xa9, 0x3b, 0x8e, 0xa6, 0x58, 0xdc, 0x91, 0x17, 0x58, 0x42, 0x95,
+0xa3, 0x7c, 0x81, 0x78, 0xa6, 0x3d, 0x3f, 0x75, 0x74, 0x17, 0x1a, 0xd3, 0x6c, 0x2f, 0x48, 0x39,
+0x20, 0x20, 0xc1, 0x9a, 0x29, 0x84, 0x7d, 0x2d, 0x52, 0xa1, 0xf9, 0x5c, 0xf3, 0x4f, 0x91, 0xfc,
+0x75, 0xcf, 0xd6, 0x2d, 0xe7, 0x9a, 0x59, 0x6e, 0x00, 0x0e, 0x8d, 0x22, 0x17, 0xbd, 0xa0, 0xdd,
+0x79, 0x1f, 0x71, 0xe6, 0xcd, 0x2f, 0xb1, 0xb6, 0xbc, 0xc3, 0xdb, 0x02, 0x91, 0x41, 0x9b, 0x09,
+0xa9, 0xd2, 0x7e, 0xbd, 0x2c, 0x18, 0xae, 0xc0, 0x93, 0x0c, 0x02, 0x9a, 0xdb, 0x4e, 0xaa, 0xeb,
+0x84, 0x4b, 0x43, 0x5e, 0xf0, 0x98, 0xf2, 0x5f, 0x86, 0x70, 0x96, 0x90, 0x15, 0x30, 0xcf, 0x3a,
+0xc9, 0x33, 0x21, 0xec, 0x59, 0x86, 0xfc, 0x65, 0x7d, 0xbe, 0xb9, 0xf8, 0x97, 0xf9, 0x30, 0xa9,
+0x6d, 0xfc, 0x0c, 0x6e, 0x36, 0x67, 0xd5, 0xa6, 0x67, 0xd9, 0xbd, 0x9b, 0x34, 0x5d, 0xa7, 0xdd,
+0xda, 0x46, 0x33, 0x25, 0x60, 0x4a, 0x18, 0xf1, 0x55, 0x07, 0xb2, 0xb7, 0x26, 0x7b, 0xa6, 0x1e,
+0x77, 0xbe, 0x7f, 0x35, 0x46, 0xdf, 0x56, 0x9c, 0x22, 0x19, 0xc8, 0x85, 0xa2, 0x45, 0xb2, 0xad,
+0xf9, 0x26, 0x66, 0xab, 0xfc, 0x97, 0x4b, 0x51, 0x32, 0x36, 0xbc, 0xad, 0xcf, 0x54, 0x3a, 0x4f,
+0x94, 0xdb, 0xd2, 0xf9, 0x67, 0x1b, 0x3b, 0xe5, 0xb2, 0x1d, 0xc5, 0x52, 0x64, 0x2c, 0x06, 0x44,
+0xcf, 0x18, 0x83, 0xe0, 0xd8, 0x04, 0x92, 0xa9, 0xc4, 0x3c, 0x8b, 0xa3, 0x2b, 0xbc, 0x88, 0x7e,
+0xc0, 0x76, 0xa7, 0xe2, 0x7b, 0x47, 0x90, 0xf2, 0xaa, 0x0a, 0x34, 0x1b, 0x91, 0x12, 0xd2, 0xd0,
+0x82, 0x45, 0xf4, 0x57, 0xf1, 0xbd, 0x91, 0x5e, 0xab, 0x41, 0x4c, 0xdf, 0x91, 0x4c, 0xdd, 0x67,
+0x04, 0xa0, 0x98, 0x23, 0x8c, 0x24, 0xbe, 0xd6, 0x80, 0xb3, 0x6d, 0x04, 0xa1, 0x77, 0x43, 0xa5,
+0xee, 0xb7, 0xce, 0xb1, 0x48, 0x43, 0x94, 0x61, 0x15, 0x20, 0x9d, 0xce, 0xd0, 0x14, 0x95, 0x37,
+0xc8, 0x64, 0xa3, 0x2d, 0x3d, 0xe3, 0xff, 0xb4, 0x55, 0x83, 0x84, 0x41, 0x50, 0x57, 0xbd, 0x5a,
+0x0c, 0xe4, 0xda, 0x3b, 0x36, 0x4d, 0x21, 0xb5, 0x6f, 0x73, 0x2a, 0x8c, 0x78, 0x4f, 0x9b, 0x83,
+0xda, 0x11, 0x3c, 0xf0, 0xc9, 0x7e, 0xa6, 0x48, 0x34, 0x53, 0x62, 0xd3, 0x0c, 0xff, 0xb1, 0x74,
+0xd6, 0xea, 0xa5, 0xfc, 0x13, 0x1c, 0x05, 0xa8, 0xc0, 0xbc, 0x95, 0x9c, 0x8c, 0xf6, 0x8c, 0xc3,
+0xf3, 0x69, 0xab, 0x93, 0x65, 0xc0, 0xb7, 0x7e, 0xb0, 0x16, 0x7c, 0xb5, 0x5f, 0x05, 0x28, 0xc9,
+0x09, 0x4e, 0x2a, 0x32, 0x87, 0xb3, 0xab, 0xf8, 0x4c, 0xab, 0xeb, 0x3b, 0x6a, 0xa0, 0x1d, 0x7f,
+0xef, 0xe5, 0x9b, 0xa4, 0xb7, 0xd7, 0xc2, 0x5e, 0x03, 0x0f, 0x99, 0xeb, 0xb1, 0xb1, 0xa6, 0x9d,
+0x1c, 0x7c, 0x5c, 0x94, 0x8b, 0x6e, 0x11, 0x7a, 0xb3, 0x6d, 0x1e, 0x61, 0x64, 0xc3, 0x7d, 0x1c,
+0xb3, 0x54, 0x65, 0x08, 0x3b, 0xda, 0x97, 0xb9, 0x75, 0xc1, 0x2b, 0x3e, 0xa8, 0x5c, 0x3c, 0x2d,
+0x81, 0x5b, 0xbf, 0x5a, 0x13, 0x0e, 0xeb, 0x66, 0xc0, 0x0b, 0x8f, 0x04, 0x68, 0x68, 0x9b, 0xe3,
+0x0d, 0x84, 0xe0, 0xcf, 0x83, 0xd7, 0x62, 0x48, 0xc1, 0x31, 0xa5, 0xd5, 0xbc, 0xe3, 0xa3, 0xa5,
+0xb6, 0xd1, 0xfd, 0x81, 0x91, 0x4d, 0xbd, 0xc4, 0x62, 0x4f, 0xe3, 0xd5, 0x99, 0x14, 0xf1, 0xcd,
+0xf4, 0x7d, 0x13, 0xda, 0x68, 0x0a, 0xca, 0xd6, 0x82, 0x0b, 0xf6, 0xea, 0xad, 0x78, 0xa4, 0xc8,
+0x14, 0x7a, 0xec, 0x11, 0xd3, 0x16, 0x86, 0x9f, 0x17, 0x37, 0x6a, 0x06, 0x56, 0xaa, 0x1b, 0xd1,
+0xaf, 0x85, 0x95, 0x21, 0x36, 0x69, 0xec, 0x1b, 0x56, 0x84, 0x01, 0x3f, 0x4d, 0x34, 0x3d, 0x2d,
+0x38, 0x57, 0x2d, 0x7e, 0xd9, 0x7b, 0x2d, 0x81, 0x86, 0xd4, 0x7c, 0x83, 0x12, 0x1d, 0x9d, 0x27,
+0x72, 0x1b, 0x5e, 0xf4, 0x15, 0xa5, 0xcd, 0xb7, 0x5f, 0xbb, 0x49, 0xa1, 0xd9, 0xdd, 0x8d, 0xad,
+0xa9, 0x2c, 0x65, 0x18, 0x91, 0xfd, 0xd2, 0xd4, 0x09, 0x60, 0x0c, 0xfd, 0xa4, 0xe1, 0x25, 0x87,
+0x32, 0x64, 0x7b, 0x99, 0xd7, 0x61, 0x2f, 0xd4, 0x73, 0xdd, 0x85, 0x26, 0x08, 0x92, 0xc0, 0xe1,
+0x4f, 0x0c, 0x76, 0x5b, 0x26, 0x69, 0xdb, 0x78, 0x35, 0x65, 0xb9, 0x58, 0x1f, 0x9c, 0x0f, 0x18,
+0x95, 0xfe, 0x40, 0xfc, 0xf7, 0x93, 0x71, 0x70, 0x8b, 0x73, 0xdc, 0xb0, 0x88, 0x72, 0x19, 0x26,
+0x94, 0x26, 0xa7, 0xaa, 0x00, 0x72, 0x61, 0x53, 0xd2, 0x5d, 0x8f, 0x5e, 0x51, 0x88, 0x2d, 0xa4,
+0x28, 0xd5, 0xaf, 0x2d, 0xd2, 0x84, 0x39, 0x75, 0x1e, 0xe7, 0xf0, 0x23, 0xc0, 0x4f, 0x8d, 0xdd,
+0x5c, 0x90, 0xef, 0x6e, 0x53, 0xe0, 0x54, 0x67, 0xe1, 0x5b, 0x10, 0xf1, 0xf5, 0xf8, 0x64, 0x34,
+0x94, 0xeb, 0x37, 0xf7, 0xe9, 0xaa, 0x6c, 0xa4, 0xd8, 0x74, 0x6d, 0xca, 0x8d, 0x1a, 0x31, 0x73,
+0xca, 0xb4, 0xc7, 0x47, 0x34, 0x7f, 0xf8, 0x24, 0x9b, 0xfa, 0xc9, 0xcc, 0xa8, 0x61, 0xb4, 0x0e,
+0x4d, 0x68, 0xc7, 0xa0, 0xcb, 0xea, 0xf0, 0xcc, 0x0a, 0x6c, 0xf2, 0x33, 0x42, 0x99, 0x6c, 0xd8,
+0x74, 0x7f, 0x1e, 0x8a, 0xa3, 0x0a, 0x48, 0x4b, 0x7e, 0xbe, 0xdb, 0x7f, 0x56, 0x69, 0x43, 0xe8,
+0xbf, 0x12, 0xc4, 0x7b, 0xc2, 0xd9, 0xfa, 0x5c, 0xeb, 0x45, 0xca, 0x07, 0x3d, 0xc0, 0xcd, 0x68,
+0x8b, 0xd0, 0x79, 0xea, 0x0a, 0x78, 0x06, 0xdc, 0x81, 0xd7, 0x32, 0x18, 0xb3, 0x65, 0xbe, 0x47,
+0xbb, 0xfa, 0x17, 0x09, 0xe9, 0x31, 0x95, 0x30, 0xef, 0x07, 0x44, 0xec, 0xd0, 0x98, 0x98, 0xc0,
+0x6b, 0x71, 0x5b, 0x23, 0xb8, 0xb6, 0xd2, 0x21, 0xff, 0x51, 0xdd, 0xae, 0x48, 0x29, 0x75, 0x0c,
+0xc3, 0x3d, 0x91, 0xfe, 0x9d, 0xa8, 0x5e, 0xb2, 0x34, 0xb2, 0xd3, 0x81, 0xf6, 0x27, 0x9c, 0xac,
+0x6b, 0x20, 0x56, 0x86, 0xa5, 0x4f, 0x7a, 0xdb, 0xf9, 0xac, 0xa9, 0x8e, 0xe3, 0x73, 0x21, 0x99,
+0x71, 0x2d, 0xaf, 0x27, 0x92, 0x0c, 0xc7, 0xd3, 0x85, 0xb3, 0x40, 0xda, 0x13, 0x4a, 0x04, 0x41,
+0x54, 0xf8, 0xf2, 0x55, 0xb7, 0x80, 0xdd, 0x77, 0xba, 0x01, 0x7a, 0x31, 0xbd, 0x6b, 0xdc, 0x5c,
+0x59, 0xf4, 0x2b, 0xca, 0x25, 0xbb, 0x50, 0xba, 0xfa, 0x42, 0x38, 0xd2, 0x28, 0x10, 0x8b, 0x7b,
+0x96, 0x45, 0x30, 0xbb, 0x7f, 0xf4, 0x5a, 0xf7, 0x28, 0x6f, 0x47, 0xdc, 0xd2, 0x82, 0xf2, 0xf7,
+0xdd, 0x20, 0xb5, 0x0c, 0x7e, 0x53, 0x85, 0xa7, 0xfc, 0x3b, 0x1a, 0xc0, 0x07, 0x7b, 0xa1, 0x43,
+0x05, 0x18, 0x19, 0xd3, 0xfc, 0x41, 0xc2, 0xce, 0xd9, 0x5b, 0x4b, 0x63, 0xe2, 0x8f, 0x86, 0x3a,
+0xd1, 0xd0, 0x1d, 0x74, 0x2e, 0xbc, 0xd3, 0xce, 0x08, 0x0c, 0x10, 0x7a, 0x42, 0x60, 0xc5, 0x3a,
+0xa6, 0xd8, 0xb0, 0x52, 0xcf, 0x53, 0x28, 0x70, 0x45, 0xb7, 0x72, 0x7d, 0x77, 0x66, 0x54, 0x3d,
+0x38, 0x26, 0xcf, 0xd5, 0xbf, 0xe4, 0x80, 0x10, 0xba, 0x2b, 0xe8, 0xdc, 0xc3, 0xfe, 0x28, 0xa3,
+0x52, 0x58, 0x70, 0x4a, 0xde, 0x84, 0x33, 0x5e, 0x93, 0x04, 0xa4, 0x7c, 0xe7, 0xea, 0x8e, 0xba,
+0xeb, 0x8a, 0x19, 0x26, 0x6a, 0x7f, 0x7c, 0x4a, 0x5b, 0xb4, 0x0d, 0xfc, 0xc8, 0x11, 0x1b, 0x41,
+0x68, 0x5d, 0x2a, 0x25, 0x04, 0x4f, 0xc8, 0xf4, 0x65, 0xfc, 0xb9, 0x58, 0xeb, 0xb4, 0x67, 0x50,
+0x24, 0xf5, 0x43, 0xf6, 0x91, 0x4a, 0xb0, 0x0f, 0x32, 0xe0, 0x07, 0x75, 0x69, 0x1b, 0x3c, 0xeb,
+0xb2, 0x65, 0x26, 0x6f, 0xb8, 0x79, 0xe0, 0x78, 0x8c, 0xdc, 0x39, 0x24, 0x48, 0x76, 0x11, 0xd4,
+0x3a, 0xc5, 0xd2, 0x2b, 0xaa, 0x55, 0xfb, 0x92, 0x12, 0x2d, 0x88, 0x05, 0xd1, 0xb1, 0x31, 0x36,
+0x1f, 0xc2, 0x44, 0x1c, 0xab, 0x2e, 0xcd, 0x1c, 0x72, 0x86, 0xf6, 0x83, 0x87, 0x2e, 0x8b, 0xdb,
+0xaa, 0x16, 0x0e, 0x1b, 0xe6, 0x5c, 0x4d, 0x2f, 0x82, 0xbd, 0x49, 0x11, 0x60, 0x22, 0x0f, 0xde,
+0x3b, 0x2b, 0x20, 0x1d, 0x56, 0xb7, 0x21, 0xae, 0x0b, 0x26, 0x4f, 0xde, 0x3d, 0xa6, 0x3f, 0x61,
+0x81, 0xe2, 0x76, 0x60, 0x08, 0xc5, 0x4b, 0x18, 0x0b, 0xd1, 0xf5, 0xff, 0x8d, 0x1a, 0x96, 0x76,
+0x51, 0x15, 0x05, 0x4d, 0x8c, 0x6b, 0x12, 0x90, 0x47, 0xd4, 0xa4, 0x38, 0xb9, 0x48, 0xe4, 0x4c,
+0x05, 0x69, 0x6a, 0x8b, 0x9d, 0x7c, 0xa1, 0xbc, 0x77, 0xeb, 0x86, 0x93, 0x0a, 0x15, 0x84, 0xba,
+0x8f, 0xf5, 0x7c, 0x44, 0x75, 0x31, 0x79, 0x16, 0xc1, 0x81, 0x1a, 0xb6, 0xe6, 0x6c, 0x3d, 0xb8,
+0x15, 0x46, 0xf5, 0xbe, 0x46, 0x04, 0xa6, 0xec, 0xec, 0xd1, 0x74, 0x8b, 0x87, 0x2b, 0xdb, 0xd0,
+0x9f, 0xb3, 0x99, 0x9d, 0x87, 0x8c, 0xc6, 0xaa, 0xd4, 0x64, 0x45, 0xbd, 0xe8, 0xed, 0xa3, 0xc1,
+0x2a, 0x41, 0x1e, 0x26, 0xaf, 0x86, 0x16, 0xed, 0x80, 0x08, 0xca, 0x64, 0x21, 0x3a, 0xce, 0x21,
+0x4c, 0x41, 0xb9, 0x13, 0x2d, 0xf7, 0x1b, 0xdf, 0x2b, 0x33, 0x69, 0xe7, 0x5c, 0x8c, 0x7b, 0xfb,
+0xe3, 0x41, 0xe9, 0xce, 0xd7, 0xff, 0x0e, 0x54, 0xfe, 0xb0, 0x71, 0x78, 0xdc, 0xde, 0x7e, 0xdd,
+0x1f, 0x1c, 0x4a, 0x8f, 0x3e, 0x16, 0xfd, 0x91, 0x82, 0x94, 0xd4, 0xc2, 0xf7, 0xb2, 0x77, 0x89,
+0x16, 0x2c, 0xba, 0xb6, 0xbd, 0xed, 0x95, 0x43, 0x05, 0x9b, 0xf2, 0xc4, 0xbe, 0x46, 0x43, 0x90,
+0x1d, 0xd8, 0x24, 0x02, 0xd2, 0xea, 0xf4, 0x08, 0xd9, 0xf7, 0x84, 0x0e, 0xc6, 0xe7, 0x44, 0xdb,
+0xb8, 0xac, 0x0a, 0x53, 0x39, 0x61, 0x43, 0xdc, 0x22, 0x28, 0x8f, 0x22, 0x2f, 0x73, 0xbf, 0x59,
+0x2d, 0x3c, 0x8c, 0x0b, 0xcc, 0x2a, 0x67, 0xe0, 0x5b, 0x5c, 0x65, 0x5e, 0x6d, 0x98, 0x99, 0xaa,
+0x3b, 0x89, 0x12, 0xe2, 0x99, 0xf6, 0x15, 0xa7, 0xd2, 0x6a, 0x79, 0xb4, 0xf6, 0x0b, 0xf5, 0x0d,
+0x2d, 0x4c, 0xcb, 0x1b, 0x35, 0x93, 0x61, 0x32, 0xa1, 0x8a, 0xa8, 0x27, 0xe8, 0x95, 0x5a, 0x56,
+0x59, 0x04, 0xfe, 0xce, 0xc2, 0xd8, 0x92, 0x97, 0xb2, 0x54, 0x63, 0xd0, 0x3b, 0xde, 0x10, 0x34,
+0x32, 0x16, 0x05, 0x51, 0x1d, 0xfc, 0x96, 0x8e, 0xf1, 0xf6, 0x4b, 0xd7, 0x48, 0x22, 0xce, 0xca,
+0x1c, 0x6b, 0xab, 0x1f, 0x59, 0xa2, 0x74, 0xd6, 0xcd, 0x15, 0x07, 0xab, 0xa2, 0xd5, 0x22, 0x81,
+0xec, 0x20, 0x14, 0x36, 0xac, 0xe4, 0x25, 0x7d, 0xe6, 0x09, 0x00, 0x2c, 0x92, 0x4d, 0x4e, 0xbf,
+0xbf, 0xa1, 0xd4, 0xbe, 0x6b, 0xd4, 0x1f, 0x95, 0x9b, 0xf3, 0xda, 0x99, 0xad, 0xa4, 0x6c, 0x73,
+0x55, 0xd1, 0x9d, 0x4b, 0x16, 0xd4, 0x06, 0xec, 0x46, 0x3d, 0xb7, 0xe7, 0xce, 0xd0, 0x1d, 0x94,
+0x65, 0xde, 0x61, 0xb3, 0xc1, 0x10, 0x65, 0xe5, 0x68, 0x9b, 0xb0, 0xb4, 0x43, 0x0b, 0x92, 0xaf,
+0xb7, 0x40, 0xa2, 0xe5, 0x06, 0x3d, 0x72, 0x00, 0xc5, 0x39, 0xab, 0x35, 0x29, 0x22, 0x4c, 0xa5,
+0xa5, 0x3f, 0x22, 0x90, 0x53, 0xd2, 0x36, 0x63, 0x1e, 0xd3, 0x33, 0xa5, 0xbb, 0x3d, 0xa3, 0x0c,
+0x14, 0x9c, 0x2e, 0x6d, 0x9a, 0x7a, 0xf7, 0xf1, 0x56, 0x66, 0xe5, 0x8d, 0x53, 0x83, 0x34, 0x3f,
+0xa9, 0x83, 0x84, 0x68, 0x90, 0xc9, 0x51, 0xc2, 0xd4, 0x8e, 0x6c, 0xc7, 0x6d, 0xa7, 0x19, 0x61,
+0xa7, 0x2e, 0x36, 0xbc, 0xd2, 0x0f, 0x17, 0x49, 0xd4, 0x6b, 0x36, 0x63, 0xfb, 0x1d, 0xf4, 0xb0,
+0x6b, 0xcf, 0x34, 0x5f, 0xd2, 0x77, 0xae, 0x12, 0xaf, 0xb3, 0xdf, 0x52, 0xf7, 0xc2, 0xc8, 0xf2,
+0x63, 0x61, 0xb6, 0x3e, 0x39, 0xf2, 0xa7, 0x1a, 0x89, 0x9d, 0x0e, 0x8f, 0xaf, 0xe1, 0x01, 0x24,
+0xa6, 0x3a, 0xd5, 0x9a, 0x62, 0x67, 0xa3, 0x66, 0xee, 0xbc, 0xc5, 0x94, 0x4b, 0xc3, 0x15, 0xa1,
+0x7e, 0x07, 0x07, 0x2b, 0xb7, 0x43, 0x2a, 0xb4, 0xb8, 0x25, 0x88, 0x86, 0x23, 0xab, 0xdf, 0x05,
+0xbe, 0x46, 0x56, 0xd7, 0xda, 0xd6, 0x75, 0x53, 0xd9, 0xc8, 0x26, 0x8f, 0x39, 0x67, 0xed, 0x21,
+0x53, 0x1c, 0x9c, 0x89, 0x46, 0xd3, 0xfe, 0x54, 0xe6, 0x1d, 0x02, 0xb9, 0x25, 0x82, 0x66, 0xe6,
+0xf9, 0x45, 0xd9, 0x3f, 0xa5, 0x71, 0xc1, 0x46, 0x66, 0x7a, 0x27, 0x8a, 0x82, 0xc9, 0x21, 0xe9,
+0x17, 0xab, 0x6c, 0xef, 0x45, 0xe5, 0x88, 0x93, 0x87, 0x80, 0xb3, 0x85, 0x25, 0x96, 0x19, 0x41,
+0xab, 0xd6, 0xba, 0x92, 0x76, 0x21, 0x8a, 0x58, 0xbd, 0xe2, 0x4b, 0xec, 0x45, 0x59, 0x2c, 0x13,
+0x1a, 0xb5, 0x13, 0x25, 0x44, 0xe7, 0x71, 0x26, 0x0a, 0x34, 0x33, 0xb9, 0x57, 0x15, 0xa4, 0x90,
+0x60, 0x11, 0x05, 0x8e, 0xc8, 0x8e, 0x74, 0x52, 0x4b, 0x31, 0x71, 0xeb, 0x66, 0x7e, 0xee, 0xb1,
+0x0a, 0x21, 0x52, 0xc0, 0x1a, 0xe9, 0xa1, 0x5a, 0xe3, 0x3a, 0x24, 0xfb, 0xf3, 0x1e, 0xd6, 0x83,
+0x1d, 0xfb, 0x81, 0xa8, 0x91, 0x60, 0x9e, 0xbc, 0x59, 0x20, 0xc9, 0x9e, 0x71, 0x19, 0x83, 0x2b,
+0x6a, 0x48, 0x4e, 0x6b, 0x46, 0x82, 0x89, 0xda, 0x60, 0xff, 0x1a, 0x46, 0x94, 0x55, 0xda, 0xe5,
+0x99, 0xfa, 0x84, 0xd7, 0x3b, 0xb9, 0xa5, 0x34, 0x87, 0x86, 0x5e, 0x6d, 0x75, 0x9a, 0xe7, 0x09,
+0xb8, 0xe6, 0x71, 0x15, 0x10, 0x56, 0xd7, 0xc1, 0xc8, 0xb2, 0x62, 0xbc, 0xec, 0xe0, 0x94, 0xa0,
+0xcd, 0xb4, 0x04, 0xa9, 0xc3, 0x51, 0xee, 0xf8, 0x2e, 0x42, 0x9a, 0xaa, 0x34, 0xd3, 0xb9, 0xb0,
+0x36, 0xf9, 0x47, 0xc1, 0x07, 0x49, 0xde, 0xb8, 0x32, 0x8a, 0x87, 0x68, 0x56, 0x9a, 0x35, 0x79,
+0xd1, 0xac, 0x49, 0x38, 0xc6, 0xfe, 0xfd, 0xdf, 0x6f, 0x3c, 0xda, 0x48, 0xbd, 0x23, 0xfd, 0x85,
+0xf0, 0x96, 0xee, 0x1c, 0x27, 0x18, 0x86, 0xa6, 0xf0, 0x7b, 0xd8, 0x3c, 0xc7, 0x22, 0x3e, 0x2f,
+0xac, 0xb1, 0x37, 0xbd, 0x84, 0x4b, 0xe3, 0x92, 0x82, 0xd0, 0x25, 0x14, 0x22, 0x65, 0xed, 0xeb,
+0xef, 0xb9, 0xb6, 0xe4, 0x95, 0x18, 0x0d, 0x2b, 0x8d, 0x4f, 0xaf, 0xc0, 0xa0, 0x05, 0x8b, 0x35,
+0x5b, 0x94, 0xb2, 0x68, 0x26, 0x4f, 0x4a, 0x9e, 0x85, 0x0e, 0x46, 0xe0, 0x4f, 0x60, 0x66, 0x01,
+0xa4, 0x39, 0xe8, 0x8b, 0x2a, 0x50, 0xf5, 0x18, 0x70, 0xe2, 0xfc, 0xd6, 0xbe, 0xd3, 0x46, 0x4b
+
+ciphertext =
+0x0F, 0x9B, 0xF5, 0x9F, 0xE2, 0xB3, 0xD9, 0x12, 0x27, 0x51, 0x18, 0xD7, 0x4E, 0x1F, 0x40, 0x4C,
+0xC1, 0xDF, 0x66, 0xAB, 0x1A, 0xFA, 0xF8, 0xEE, 0xA4, 0x40, 0x63, 0x72, 0x58, 0xAE, 0x7E, 0x98,
+0x76, 0x63, 0x56, 0x1F, 0x71, 0xDB, 0x80, 0x07, 0xFE, 0x34, 0x23, 0x43, 0x1E, 0x3D, 0xDE, 0x7E,
+0xC0, 0x72, 0xEF, 0xAD, 0xF4, 0x30, 0xDF, 0x4E, 0x3B, 0x9F, 0xCA, 0x90, 0xC3, 0x95, 0x8A, 0x66,
+0x5C, 0xD6, 0xCA, 0xBD, 0x3C, 0xC9, 0xD2, 0xFE, 0x30, 0x02, 0xA9, 0x8E, 0xAA, 0x80, 0xF6, 0xFF,
+0xCD, 0x40, 0xBC, 0x99, 0xD2, 0x25, 0x7F, 0xBF, 0xC5, 0xF3, 0x50, 0x31, 0x69, 0xE1, 0xC8, 0x64,
+0xC5, 0x5F, 0x30, 0x30, 0xD9, 0xD7, 0xF9, 0xF0, 0xD3, 0x77, 0xE0, 0xD0, 0x11, 0xB8, 0xC9, 0x54,
+0xD9, 0x9C, 0x10, 0x74, 0xCA, 0x4A, 0xFE, 0xD2, 0x16, 0xA5, 0xD8, 0x2D, 0xC0, 0xDA, 0x39, 0x24,
+0xAF, 0x5E, 0xF2, 0xEB, 0xC7, 0x9D, 0xBC, 0xEF, 0x94, 0xA0, 0x49, 0x56, 0x39, 0xCE, 0x8A, 0x38,
+0x3B, 0x70, 0xC7, 0xB2, 0xE0, 0xD4, 0x43, 0xD7, 0xAC, 0xB4, 0xB3, 0xDB, 0xA2, 0x2B, 0x75, 0xE2,
+0x0E, 0x38, 0x2B, 0xE6, 0x42, 0x1A, 0x11, 0x08, 0x79, 0x9A, 0x32, 0xD2, 0x41, 0xCC, 0x28, 0xC3,
+0x4B, 0x3E, 0xD4, 0xB0, 0x10, 0x89, 0x7B, 0x0D, 0xB7, 0x95, 0xBE, 0x22, 0x01, 0xD0, 0x86, 0xA8,
+0xC6, 0xD0, 0xDD, 0xDF, 0x18, 0x2C, 0x1B, 0x49, 0xE3, 0x2B, 0x84, 0x53, 0x54, 0x14, 0xE6, 0x04,
+0xE1, 0xD6, 0x98, 0x91, 0x17, 0xE0, 0xD9, 0x39, 0xAF, 0xF9, 0x71, 0x35, 0x90, 0xCE, 0x4B, 0xD2,
+0x45, 0xB2, 0x4B, 0x68, 0x26, 0xBB, 0x8C, 0xBD, 0xA3, 0xF7, 0x60, 0xD4, 0x38, 0xAA, 0xDF, 0x5B,
+0x3B, 0x53, 0xF6, 0xA4, 0x45, 0x49, 0x4A, 0xEF, 0x6F, 0x04, 0x00, 0xFF, 0xE3, 0x3F, 0x7C, 0x7D,
+0xDC, 0xB0, 0x62, 0x9C, 0x6A, 0x99, 0x07, 0x85, 0xB3, 0x13, 0x2B, 0x40, 0x06, 0xAF, 0xE3, 0xA0,
+0x17, 0x97, 0x0D, 0x4E, 0xD7, 0xB0, 0x6B, 0xF8, 0x3C, 0x91, 0x0A, 0xF3, 0x17, 0x51, 0x30, 0xC8,
+0x58, 0x20, 0x20, 0xE2, 0xA3, 0xE6, 0x3B, 0x2F, 0x77, 0x7C, 0x52, 0x31, 0x4F, 0x4C, 0xA8, 0xD8,
+0x84, 0xB1, 0xE9, 0xB4, 0x86, 0xD8, 0x93, 0xBF, 0x2D, 0x6A, 0xDA, 0x5D, 0x39, 0x62, 0x5B, 0x52,
+0xFB, 0xBA, 0x9F, 0x83, 0x82, 0x3C, 0x40, 0x57, 0x02, 0x92, 0x6A, 0x97, 0x06, 0x39, 0x17, 0x0B,
+0xA7, 0xF5, 0x6A, 0x1A, 0x8E, 0x64, 0x74, 0x90, 0x33, 0xA6, 0xA3, 0x1E, 0x30, 0x1E, 0x67, 0x49,
+0x5A, 0x76, 0x43, 0x97, 0x71, 0xE0, 0x4E, 0xCC, 0x5A, 0xFD, 0x44, 0xFD, 0x5C, 0x41, 0x3A, 0x09,
+0x8E, 0x4E, 0xD2, 0xF0, 0x9A, 0x52, 0x39, 0x5B, 0x0E, 0xC4, 0xF2, 0xFE, 0xB4, 0x66, 0x6C, 0x60,
+0x47, 0x96, 0x80, 0x91, 0xBE, 0x6C, 0xA8, 0x33, 0x66, 0x4D, 0x08, 0x70, 0x27, 0x0C, 0x33, 0x50,
+0x8F, 0xEF, 0x05, 0xC9, 0x93, 0x21, 0x8D, 0xA4, 0x94, 0xF3, 0xBC, 0x4D, 0x96, 0x9A, 0x51, 0x29,
+0xDA, 0x8E, 0x32, 0xB4, 0xB3, 0xD8, 0x75, 0x20, 0x37, 0x9F, 0x33, 0xE2, 0xF9, 0xEB, 0xFA, 0xF2,
+0x6E, 0x3F, 0x71, 0x0C, 0x29, 0x8D, 0xFE, 0xE1, 0xF9, 0xC6, 0x49, 0xB6, 0x6E, 0x53, 0xBC, 0x24,
+0x1D, 0x0B, 0x24, 0x75, 0x54, 0x51, 0x0B, 0xEB, 0xDD, 0x67, 0x40, 0x61, 0xCA, 0x3F, 0xD2, 0x85,
+0x71, 0x16, 0xFC, 0x77, 0x9C, 0x56, 0xE5, 0xCA, 0x43, 0xC6, 0xC3, 0x2A, 0x47, 0xA8, 0x98, 0x40,
+0x02, 0x1D, 0x64, 0x47, 0x85, 0x99, 0x2F, 0x8F, 0x2D, 0xC2, 0x29, 0x7B, 0x8D, 0x64, 0xD9, 0x8F,
+0xF4, 0x91, 0x6F, 0x2A, 0xB0, 0x5C, 0xDC, 0xB0, 0xBE, 0xDE, 0x34, 0xA8, 0x99, 0x40, 0x23, 0x9F,
+0x8A, 0xF5, 0x0C, 0x32, 0xDE, 0x53, 0xA5, 0x55, 0xFE, 0x4C, 0xF8, 0x87, 0x83, 0xB6, 0xA1, 0x31,
+0x2C, 0xB4, 0xE9, 0x78, 0xB8, 0x45, 0xAA, 0x33, 0x6E, 0x8A, 0xBE, 0xDB, 0x76, 0x35, 0xDD, 0xDF,
+0xA1, 0x98, 0x21, 0x2B, 0x42, 0xF3, 0xA4, 0x3E, 0x2C, 0x38, 0xA9, 0xB1, 0x07, 0x38, 0xA1, 0x1D,
+0xA5, 0x85, 0x61, 0x87, 0xF1, 0xA1, 0x9D, 0x3D, 0x2C, 0xA6, 0x2F, 0x26, 0xFD, 0xE8, 0x46, 0x0D,
+0xBD, 0xDA, 0x44, 0xC4, 0xB5, 0xFF, 0x6F, 0xDB, 0xF7, 0xF4, 0xDB, 0x0A, 0x80, 0x7C, 0x81, 0x27,
+0xF4, 0x27, 0x41, 0x15, 0x9F, 0xEC, 0xA5, 0xAA, 0x79, 0x30, 0x9B, 0x0D, 0x84, 0xAC, 0x4D, 0x50,
+0x68, 0x56, 0x55, 0x32, 0xF9, 0x28, 0x06, 0xC3, 0x96, 0xD6, 0x57, 0x61, 0x04, 0xCF, 0xD8, 0xB9,
+0x36, 0x0D, 0x33, 0x11, 0xEE, 0x8A, 0x88, 0x5A, 0x11, 0x6C, 0x11, 0x71, 0x41, 0xFC, 0xD5, 0xF1,
+0xB7, 0xC2, 0x94, 0x98, 0x6F, 0xAB, 0x12, 0x5F, 0x34, 0x46, 0xDD, 0xBC, 0x65, 0x5C, 0x76, 0x3A,
+0x81, 0x42, 0xF8, 0x6D, 0xC2, 0x08, 0x93, 0x58, 0x30, 0x1B, 0x82, 0x28, 0xD7, 0xFB, 0x90, 0x61,
+0x24, 0x38, 0x12, 0xDC, 0xFB, 0x88, 0xFB, 0xC8, 0xB9, 0xB8, 0x23, 0xA5, 0xEB, 0x85, 0xB1, 0x92,
+0x55, 0x34, 0xA7, 0x8E, 0x2C, 0x3D, 0xD7, 0x07, 0xF6, 0x2C, 0xF5, 0x5A, 0x72, 0x38, 0x25, 0x5A,
+0x3F, 0x1F, 0xF5, 0x7B, 0x02, 0xFC, 0x70, 0xB1, 0x31, 0x01, 0xCA, 0xD6, 0x18, 0x7C, 0xF4, 0x0A,
+0x3A, 0xAE, 0x7B, 0x89, 0x0B, 0xE8, 0x5E, 0x7D, 0x64, 0x7A, 0x10, 0xE0, 0x8C, 0x8C, 0x02, 0xF7,
+0x2F, 0x52, 0x06, 0xE7, 0xD7, 0xFA, 0x56, 0xBB, 0xC4, 0x5A, 0x82, 0x14, 0x13, 0x7D, 0x41, 0xD0,
+0xCE, 0x57, 0xE6, 0x41, 0x3A, 0x08, 0xAD, 0x7C, 0x20, 0xDC, 0x15, 0xA8, 0xBA, 0xE6, 0xB8, 0x58,
+0xA6, 0xF4, 0x82, 0x70, 0xDE, 0x09, 0xE2, 0x8B, 0xFC, 0xAA, 0x7D, 0xD9, 0xFD, 0xCE, 0xBC, 0xAC,
+0xB8, 0xE8, 0xB2, 0x46, 0xC5, 0xC4, 0xF9, 0xFC, 0xE5, 0xFF, 0xF5, 0xCA, 0xB3, 0x51, 0x3C, 0xB8,
+0x25, 0xD7, 0x83, 0x3C, 0x91, 0xCD, 0xFB, 0x86, 0x94, 0x5E, 0x36, 0xCF, 0xDE, 0x8E, 0x37, 0x4F,
+0x9D, 0x54, 0xBB, 0x8D, 0x52, 0xE6, 0x86, 0x5C, 0x8B, 0x72, 0x23, 0xAF, 0x93, 0xF5, 0xFF, 0xB5,
+0xC5, 0xFE, 0xC1, 0x31, 0xCE, 0x72, 0xD7, 0x3A, 0x2E, 0x25, 0xBF, 0xC1, 0xEE, 0xD5, 0x28, 0xDB,
+0xB7, 0xD2, 0x4E, 0xC6, 0x2B, 0xE3, 0x6F, 0x87, 0x2D, 0xA5, 0xFB, 0xDB, 0x03, 0xB0, 0x13, 0x58,
+0x3F, 0x3B, 0xBD, 0x2E, 0x0B, 0x78, 0xC2, 0xDC, 0xF8, 0x30, 0x2F, 0x08, 0xA6, 0x6A, 0x00, 0x57,
+0x82, 0x79, 0x06, 0x11, 0xC2, 0x20, 0x49, 0xD1, 0xDD, 0x53, 0xF6, 0xA8, 0xB1, 0x0A, 0x1C, 0x97,
+0x11, 0x5C, 0xA4, 0x98, 0xBC, 0xE7, 0x10, 0x27, 0x73, 0x54, 0x3C, 0x91, 0x98, 0x58, 0x2F, 0xA8,
+0x96, 0xB2, 0xE8, 0x54, 0xC0, 0x6B, 0x4B, 0x69, 0x0E, 0x92, 0xFB, 0xF0, 0x5E, 0xDC, 0x45, 0xAE,
+0x6B, 0x12, 0x29, 0xBE, 0x59, 0xA2, 0x0B, 0xD6, 0xD2, 0x09, 0xE0, 0xBA, 0xE2, 0x1D, 0xD9, 0x8A,
+0x6D, 0x70, 0xD0, 0x62, 0x0C, 0x9D, 0xC4, 0x38, 0x3A, 0x11, 0xBA, 0xF8, 0x8B, 0x0A, 0xDF, 0xDF,
+0xD1, 0xBF, 0x87, 0x98, 0xC8, 0xFF, 0x42, 0x85, 0x13, 0xE7, 0x6C, 0xDE, 0xFE, 0x45, 0xFE, 0xF8,
+0x67, 0x28, 0x56, 0xF7, 0x3C, 0x12, 0x4E, 0x88, 0x05, 0x8B, 0x56, 0x53, 0x2E, 0xE8, 0x6F, 0x3B,
+0xEE, 0x40, 0x4D, 0x3C, 0x1B, 0x0C, 0xE7, 0xCA, 0xD1, 0x3A, 0xA3, 0x2A, 0xDB, 0xC0, 0xDB, 0x9D,
+0xA4, 0xC1, 0xDA, 0x50, 0x81, 0x59, 0x52, 0x87, 0x33, 0x10, 0xE6, 0x58, 0xC3, 0x3E, 0x08, 0x69,
+0xFF, 0x3B, 0x4C, 0x82, 0xBA, 0xC3, 0x81, 0x82, 0xB5, 0xF2, 0x9F, 0x0A, 0x20, 0xCF, 0x70, 0xFB,
+0x81, 0x63, 0xB7, 0x04, 0x95, 0xFE, 0x08, 0x33, 0x1A, 0xED, 0xB0, 0x0A, 0x86, 0xA6, 0x42, 0x8F,
+0xEB, 0x48, 0xD8, 0xF4, 0xFE, 0x50, 0xA2, 0xC6, 0x5E, 0xD8, 0x33, 0xAE, 0x44, 0x83, 0xE6, 0x7C,
+0x88, 0xA3, 0xEC, 0x74, 0xA4, 0x26, 0x58, 0xE6, 0x3C, 0xD4, 0x04, 0xAC, 0x71, 0xBD, 0xBE, 0xCC,
+0xC6, 0xE8, 0x55, 0xDE, 0x98, 0x7F, 0x6B, 0x4F, 0x62, 0xF6, 0x4E, 0x1C, 0x95, 0x44, 0xBE, 0xD7,
+0x77, 0x9C, 0xD2, 0x13, 0xD7, 0xF5, 0x2C, 0x8D, 0xC1, 0xC7, 0xCA, 0xF8, 0x68, 0x91, 0x06, 0x24,
+0x01, 0x5D, 0xD0, 0x9E, 0xC9, 0x24, 0x12, 0x83, 0xA1, 0xF4, 0x05, 0xE0, 0xB2, 0xA9, 0xAD, 0xFC,
+0xC3, 0x64, 0x08, 0x17, 0x58, 0xAB, 0xB7, 0x39, 0xA4, 0xB6, 0x77, 0x26, 0x37, 0x13, 0x24, 0x20,
+0xEB, 0xEE, 0x61, 0x28, 0x0E, 0x33, 0x7C, 0x4D, 0xD5, 0xEA, 0x42, 0x39, 0xB7, 0x20, 0xCB, 0x97,
+0x44, 0xBE, 0x6D, 0x67, 0x28, 0xF9, 0x99, 0xE1, 0xE7, 0x3A, 0x5D, 0x7D, 0xAA, 0xBB, 0x1D, 0xEC,
+0xA4, 0xF6, 0xAA, 0xED, 0xC5, 0x1F, 0xAD, 0xDF, 0x0E, 0xD3, 0x94, 0xA9, 0xD9, 0xFF, 0x29, 0x56,
+0x3C, 0x43, 0x5E, 0xC2, 0x3B, 0xB3, 0x2E, 0x4A, 0xB7, 0x9F, 0xF4, 0xA0, 0xF1, 0xD6, 0x93, 0xFF,
+0x4A, 0xC8, 0xF2, 0xDE, 0x1A, 0x96, 0xB1, 0x83, 0x37, 0x45, 0x0C, 0x79, 0x40, 0x51, 0xD1, 0x08,
+0xF2, 0xDC, 0xFA, 0xBF, 0xB4, 0x15, 0x9A, 0x60, 0x37, 0x81, 0x5F, 0x76, 0xB2, 0x87, 0x82, 0x2D,
+0xA8, 0x0A, 0x70, 0x1B, 0xA2, 0xD6, 0x7E, 0x65, 0xAC, 0x02, 0x36, 0xDA, 0x0F, 0xB4, 0xD5, 0x6E,
+0xEE, 0x60, 0x0B, 0xC8, 0xD6, 0x1B, 0x9C, 0xF1, 0xCF, 0x66, 0xCA, 0x1D, 0x9D, 0xE5, 0xC7, 0x0B,
+0x1A, 0xE1, 0x9E, 0x68, 0xFF, 0xCE, 0xCE, 0x1B, 0x0A, 0x1E, 0x8D, 0x25, 0x37, 0x40, 0x05, 0x20,
+0xE4, 0xA1, 0x4F, 0x4C, 0x33, 0x29, 0xB3, 0x7B, 0x47, 0xFA, 0x7E, 0xEF, 0x87, 0x89, 0x13, 0x10,
+0x1C, 0x0F, 0x15, 0x03, 0xFD, 0xD8, 0x81, 0xD7, 0xB9, 0xA7, 0xBA, 0xD0, 0x6F, 0x6F, 0x76, 0xF6,
+0xD1, 0xF3, 0xCE, 0x57, 0x21, 0x02, 0x12, 0xAA, 0x5E, 0x61, 0xD4, 0xCA, 0xF2, 0x84, 0x80, 0xF0,
+0x90, 0x37, 0x0B, 0xE5, 0xC9, 0xE4, 0xAD, 0xD5, 0x8C, 0x47, 0x6D, 0xFA, 0xE1, 0xE5, 0xC6, 0x3A,
+0xE4, 0x0A, 0x82, 0xCE, 0x05, 0xD6, 0x46, 0x39, 0xAE, 0xE9, 0xE4, 0x6A, 0xD7, 0xE5, 0x9E, 0x85,
+0x4A, 0x31, 0xFA, 0xA0, 0x86, 0x01, 0x4B, 0xC8, 0x77, 0xC2, 0x10, 0xED, 0x70, 0xD5, 0x7D, 0x0F,
+0xF4, 0xDC, 0x97, 0x93, 0xB2, 0x7D, 0x45, 0x7A, 0x24, 0x37, 0x2D, 0x39, 0xAC, 0xB6, 0x53, 0x6B,
+0xA5, 0x9B, 0xDC, 0xC1, 0xAC, 0x95, 0x01, 0x3E, 0x52, 0x53, 0x11, 0x0A, 0xB7, 0x1E, 0x1F, 0xCD,
+0x29, 0xC0, 0xE9, 0x0A, 0xDF, 0xE5, 0xF5, 0x54, 0xF7, 0xF7, 0x23, 0x7C, 0xC6, 0xB3, 0x18, 0xEA,
+0x0E, 0x08, 0xE3, 0x76, 0x8D, 0xDC, 0x01, 0x45, 0xB7, 0x45, 0xAF, 0x5C, 0x88, 0xEA, 0x74, 0xFE,
+0xE0, 0xC5, 0xA3, 0x73, 0x2D, 0x2E, 0x47, 0xF1, 0x2E, 0xC0, 0x01, 0x97, 0xE5, 0x64, 0x84, 0x59,
+0xC6, 0x83, 0xF5, 0xFC, 0x0D, 0x2D, 0x70, 0x46, 0x0E, 0x17, 0xE1, 0xC9, 0xE2, 0xBF, 0xF2, 0xF4,
+0x7B, 0x5C, 0xF1, 0xBE, 0xC3, 0xA7, 0x81, 0x96, 0xA1, 0x24, 0x67, 0x85, 0xF5, 0x6C, 0xD4, 0xA3,
+0x2A, 0xBE, 0xF5, 0x05, 0x2A, 0xBB, 0xF2, 0x18, 0xAF, 0xDC, 0x21, 0x8A, 0x76, 0x2E, 0xAC, 0x31,
+0xB7, 0x56, 0x55, 0xFD, 0x09, 0x48, 0x3A, 0xA6, 0x66, 0x1C, 0x2F, 0x92, 0x2C, 0x07, 0xDF, 0x09,
+0x3A, 0xD1, 0xEA, 0x7A, 0xFA, 0x87, 0xE3, 0xF6, 0x5D, 0x03, 0x45, 0xC9, 0x3F, 0x97, 0x60, 0x4F,
+0x9C, 0x6C, 0xCC, 0x55, 0x1F, 0xE1, 0xBD, 0x5E, 0xE5, 0x5D, 0x76, 0x0C, 0x00, 0xE0, 0xDA, 0xB9,
+0x60, 0xFC, 0xF4, 0xC5, 0xFC, 0x14, 0x3E, 0x2C, 0xF2, 0x18, 0xEC, 0x7D, 0x2B, 0x56, 0xFC, 0x6D,
+0xCE, 0x3D, 0x94, 0x5E, 0xA1, 0x00, 0xDC, 0x00, 0xA6, 0x73, 0xCE, 0xDE, 0x57, 0x87, 0xB3, 0x90,
+0xE5, 0x16, 0x82, 0x24, 0x62, 0xAD, 0x27, 0x8B, 0xFF, 0xDD, 0xD6, 0x7C, 0xFB, 0x45, 0x8A, 0x09,
+0xB0, 0x80, 0x15, 0x86, 0x90, 0xB9, 0xE9, 0x0F, 0x59, 0x86, 0x9E, 0xBA, 0xA2, 0x6A, 0xBA, 0x33,
+0xDD, 0xE5, 0xE8, 0x08, 0x6F, 0x3F, 0xF4, 0x2E, 0xF7, 0x25, 0x28, 0x23, 0x60, 0x51, 0x88, 0x50,
+0x66, 0x31, 0xEA, 0xEE, 0x83, 0x98, 0x62, 0x04, 0xBD, 0x48, 0x17, 0x34, 0x15, 0x2E, 0x9F, 0x33,
+0x8C, 0x96, 0x83, 0x71, 0x1C, 0x0F, 0x72, 0xEB, 0x5F, 0x1C, 0x1A, 0x79, 0x7C, 0x22, 0x4C, 0x84,
+0xC6, 0xA6, 0xD6, 0xDD, 0x29, 0x67, 0x78, 0xC5, 0xEC, 0x37, 0x3E, 0x00, 0xCF, 0xEF, 0x7E, 0x4B,
+0x6D, 0xB2, 0xBD, 0xD3, 0x70, 0x41, 0x2A, 0x89, 0x00, 0x0E, 0xCA, 0x89, 0xC6, 0x31, 0x9F, 0xCB,
+0x59, 0x0C, 0x9B, 0x47, 0x6A, 0x0C, 0x56, 0x6D, 0x03, 0xF7, 0xD4, 0x81, 0x15, 0x3E, 0x9F, 0x6F,
+0x15, 0x22, 0x10, 0x52, 0xCC, 0xD9, 0x2C, 0xA3, 0x85, 0xA5, 0x42, 0x04, 0x7E, 0xD2, 0xE2, 0x16,
+0x98, 0xB1, 0x40, 0x57, 0x8A, 0x5A, 0x54, 0xA1, 0xF8, 0x9B, 0x8C, 0x77, 0x7A, 0x5F, 0x26, 0x4B,
+0x85, 0xE0, 0x3C, 0xB2, 0xC2, 0xC2, 0x90, 0xDD, 0x8E, 0xD9, 0xF5, 0x94, 0xAC, 0x3E, 0x56, 0x20,
+0x63, 0x13, 0x08, 0x48, 0x69, 0x9C, 0xD7, 0xD7, 0x05, 0x1B, 0xB0, 0xF3, 0x8A, 0x81, 0x78, 0x43,
+0x62, 0x04, 0xAB, 0x8D, 0xA8, 0xD7, 0x51, 0x2C, 0xFE, 0x66, 0x80, 0x06, 0xC0, 0x10, 0x92, 0xF3,
+0xBA, 0xBF, 0x42, 0x95, 0x96, 0xB7, 0xDB, 0xA5, 0x73, 0x06, 0xB8, 0x0D, 0xAE, 0xDA, 0x00, 0xA7,
+0xD2, 0xF8, 0x63, 0xF0, 0x35, 0x15, 0x7D, 0x9B, 0x1C, 0x3D, 0x3F, 0x83, 0x9C, 0xAE, 0xC1, 0xFA,
+0xE3, 0x62, 0x9A, 0x8A, 0xF3, 0x86, 0x2F, 0xE4, 0xDB, 0x49, 0xDF, 0x2C, 0x17, 0xFE, 0x2C, 0x30,
+0xD1, 0x76, 0x88, 0x92, 0x60, 0x60, 0xB9, 0xF9, 0x35, 0x0F, 0xE2, 0xE8, 0x8E, 0x73, 0x9E, 0x7C,
+0xF6, 0xD0, 0x5F, 0x81, 0x22, 0x2A, 0x5D, 0x5F, 0x10, 0xFE, 0x7B, 0x06, 0xB5, 0x5F, 0xF3, 0x42,
+0x94, 0xC4, 0x3E, 0xE0, 0x0E, 0x11, 0xCC, 0x3B, 0x4F, 0xBD, 0x06, 0xD1, 0x15, 0xF5, 0x32, 0x76,
+0xE4, 0x97, 0xBF, 0xA7, 0xC5, 0xD0, 0x5E, 0x5A, 0x1C, 0x35, 0x18, 0x43, 0x6B, 0x10, 0xD2, 0xAB,
+0x8B, 0xF6, 0xE1, 0xBB, 0x8C, 0xE9, 0x9C, 0x6C, 0x27, 0x96, 0xF8, 0x19, 0x6F, 0x6E, 0x73, 0x28,
+0x8F, 0x51, 0x61, 0x0B, 0x4D, 0x4F, 0x22, 0x15, 0x1A, 0xCD, 0x88, 0x2C, 0x6F, 0x9C, 0xEC, 0x79,
+0x51, 0x70, 0x27, 0x8E, 0x58, 0xEF, 0xDE, 0x0B, 0xAA, 0x4D, 0xD2, 0x8F, 0x96, 0xE0, 0x71, 0x6A,
+0x8C, 0x41, 0xDB, 0x98, 0xF7, 0x2A, 0x09, 0x59, 0xD9, 0x48, 0x7B, 0x14, 0x87, 0x9B, 0x4A, 0xBB,
+0x88, 0xF2, 0x9D, 0x9D, 0x47, 0xF2, 0x80, 0x4B, 0xD9, 0x0E, 0xF3, 0xA9, 0x7E, 0xEF, 0xA1, 0x80,
+0x9D, 0x6F, 0x67, 0x6C, 0x14, 0x09, 0x2C, 0xB9, 0x03, 0xF3, 0x58, 0x37, 0xAE, 0x6B, 0xF7, 0x01,
+0x86, 0xDF, 0x43, 0xD5, 0xE4, 0xE2, 0x28, 0x8E, 0x8D, 0xA4, 0xF2, 0xC5, 0x7A, 0xA7, 0x89, 0x3A,
+0xE2, 0x7E, 0x77, 0xFD, 0x3A, 0x9A, 0x65, 0x5D, 0x87, 0xDC, 0x85, 0x70, 0xAB, 0xF3, 0x18, 0x0A
+
+cipher_key =
+0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A,
+0xd0, 0xe7, 0x4b, 0xfb, 0x5d, 0xe5, 0x0c, 0xe7
+
+auth_key =
+0xaf, 0x96, 0x42, 0xf1, 0x8c, 0x50, 0xdc, 0x67, 0x1a, 0x43, 0x47, 0x62, 0xc7, 0x04, 0xab, 0x05,
+0xf5, 0x0c, 0xe7, 0xa2, 0xa6, 0x23, 0xd5, 0x3d, 0x95, 0xd8, 0xcd, 0x86, 0x79, 0xf5, 0x01, 0x47,
+0x4f, 0xf9, 0x1d, 0x9d, 0x36, 0xf7, 0x68, 0x1a, 0x64, 0x44, 0x58, 0x5d, 0xe5, 0x81, 0x15, 0x2a,
+0x41, 0xe4, 0x0e, 0xaa, 0x1f, 0x04, 0x21, 0xff, 0x2c, 0xf3, 0x73, 0x2b, 0x48, 0x1e, 0xd2, 0xf7,
+0xf6, 0xd9, 0xaf, 0xbf, 0x08, 0x3b, 0xbb, 0x19, 0x5f, 0xf6, 0x7d, 0x25, 0x85, 0xdf, 0x6b, 0x54,
+0xd0, 0xe7, 0x4b, 0x9e, 0xc7, 0xef, 0xca, 0x48, 0x6f, 0x21, 0xd7, 0x51, 0xc8, 0x21, 0xc1, 0x15,
+0xe8, 0x38, 0x36, 0x58, 0x39, 0xd9, 0x9a, 0xc5, 0xe7, 0x3b, 0xc4, 0x47, 0xe2, 0xbd, 0x80, 0x73,
+0xf8, 0xd1, 0x9a, 0x5e, 0x4b, 0xfb, 0x52, 0x6b, 0x50, 0xaf, 0x8b, 0xb7, 0xb5, 0x2c, 0x52, 0x84
+
+iv =
+0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+
+####################
+# sha_hmac_buff_32 #
+####################
+[sha1_hmac_buff_32]
+digest =
+0x34, 0xCB, 0xFA, 0xE6, 0xBF, 0x60, 0x88, 0x82, 0x2C, 0x9F, 0x96, 0x4A, 0x5A, 0xD8, 0xAE, 0x48,
+0x1D, 0x2B, 0x0A, 0x22
+
+[sha224_hmac_buff_32]
+digest =
+0x17, 0xDD, 0xF3, 0xC0, 0xFC, 0xBC, 0x89, 0xE1, 0x02, 0x94, 0x51, 0x2B, 0xA0, 0x63, 0x4D, 0x1B,
+0x78, 0xCA, 0x0D, 0xD5, 0x99, 0xC0, 0xB8, 0x8E, 0x7F, 0x8A, 0xCB, 0x92
+
+[sha256_hmac_buff_32]
+digest =
+0xF7, 0xC0, 0xFD, 0x09, 0x94, 0x8F, 0x88, 0xF3, 0x26, 0xE1, 0xB1, 0xA6, 0x70, 0xFD, 0x57, 0xA2,
+0xB7, 0x63, 0x9C, 0x35, 0x97, 0x60, 0x27, 0x6A, 0xCC, 0xD8, 0x4A, 0xAE, 0xFD, 0xEC, 0x14, 0x56
+
+[sha384_hmac_buff_32]
+digest =
+0x01, 0x90, 0x96, 0x95, 0x8B, 0xE8, 0xF8, 0x30, 0xE0, 0xFE, 0xD4, 0x83, 0xE4, 0xE1, 0x48, 0xEB,
+0xEB, 0x3E, 0x6D, 0xBC, 0x72, 0xD8, 0xBF, 0x00, 0x86, 0x0B, 0x80, 0xCB, 0xCF, 0x0E, 0x83, 0x7E,
+0x77, 0x29, 0xA0, 0x71, 0xA9, 0x15, 0x8F, 0xE5, 0xC4, 0x32, 0xC8, 0xDB, 0x0A, 0xD1, 0xE3, 0x79
+
+[sha512_hmac_buff_32]
+digest =
+0x45, 0x72, 0x2B, 0xF4, 0x10, 0x82, 0xB6, 0xBC, 0xDB, 0x44, 0x34, 0x47, 0x55, 0xA7, 0x34, 0x4C,
+0x1C, 0x5D, 0x4D, 0x88, 0x58, 0x0B, 0xC2, 0x3E, 0xE7, 0x49, 0xF4, 0x6A, 0x99, 0x35, 0xE5, 0x2B,
+0xF4, 0x18, 0xD7, 0xD1, 0xAF, 0xC9, 0x81, 0xC5, 0x97, 0xE7, 0x94, 0xC4, 0xFD, 0x95, 0x7E, 0x1D,
+0x4E, 0xF4, 0x88, 0xC0, 0x10, 0x31, 0xB5, 0x1E, 0x39, 0x91, 0x1A, 0x48, 0xC2, 0x2F, 0xFE, 0xF6
+
+####################
+# sha_hmac_buff_64 #
+####################
+[sha1_hmac_buff_64]
+digest =
+0xD5, 0x0D, 0x9A, 0x30, 0xED, 0x71, 0x88, 0xF3, 0x72, 0x5D, 0x1C, 0xEF, 0x44, 0x36, 0xC1, 0x0C,
+0x66, 0x32, 0x15, 0xB5
+
+[sha224_hmac_buff_64]
+digest =
+0x59, 0xF0, 0x38, 0xA5, 0x7F, 0xDC, 0x55, 0xAF, 0x0A, 0x18, 0x0B, 0x34, 0xC1, 0x48, 0xFC, 0xB2,
+0xF8, 0x3B, 0xC2, 0x4A, 0x36, 0x0F, 0xEA, 0x4F, 0xD9, 0x46, 0x25, 0x1F
+
+[sha256_hmac_buff_64]
+digest =
+0x00, 0xD2, 0x5F, 0xAC, 0x89, 0x4B, 0x16, 0x08, 0x89, 0x8D, 0x4F, 0x8F, 0x56, 0xF5, 0xA2, 0x9B,
+0xDB, 0x91, 0x2F, 0xCE, 0x90, 0x0E, 0x4B, 0x17, 0x74, 0x8B, 0xC4, 0x8A, 0x47, 0xF0, 0x7C, 0x7A
+
+[sha384_hmac_buff_64]
+digest =
+0xFE, 0x79, 0x5C, 0x3D, 0xEA, 0x2C, 0x04, 0xB9, 0xE9, 0x37, 0x4E, 0x02, 0xE8, 0x56, 0xE8, 0x7E,
+0xB4, 0xA7, 0x3D, 0x37, 0xDD, 0x05, 0x58, 0x6A, 0x3D, 0x44, 0x0E, 0x84, 0xA9, 0xB4, 0x1F, 0x26,
+0xED, 0xAF, 0xA3, 0x4D, 0xA3, 0x6E, 0x30, 0x8F, 0xE3, 0x79, 0xB9, 0x58, 0x4E, 0xB3, 0x36, 0x1D
+
+[sha512_hmac_buff_64]
+digest =
+0x3A, 0xFE, 0x1E, 0xC8, 0x75, 0x0D, 0xF3, 0x15, 0x03, 0xCC, 0x7B, 0x50, 0xD1, 0x3E, 0x35, 0x97,
+0x4D, 0x80, 0xB8, 0x0B, 0x5E, 0x22, 0x4D, 0xB9, 0xD2, 0xC9, 0x0E, 0x24, 0xC4, 0xD9, 0xDD, 0x95,
+0xA1, 0x7D, 0xED, 0xE4, 0x28, 0x17, 0x7C, 0x50, 0x0B, 0x40, 0x81, 0x18, 0xEA, 0xFF, 0xBA, 0x1C,
+0x8C, 0x5D, 0x17, 0xB3, 0x5B, 0x39, 0x70, 0x93, 0x9A, 0xA0, 0x47, 0x59, 0x06, 0x01, 0xE5, 0xD0
+
+#####################
+# sha_hmac_buff_128 #
+#####################
+[sha1_hmac_buff_128]
+digest =
+0xF6, 0x21, 0x56, 0x15, 0xEC, 0xB6, 0xDE, 0x2B, 0x68, 0x79, 0x30, 0x69, 0x69, 0x82, 0x4B, 0x97,
+0x57, 0x61, 0xED, 0x01
+
+[sha224_hmac_buff_128]
+digest =
+0xC4, 0x5A, 0x48, 0x07, 0xCC, 0xFD, 0x68, 0x28, 0xCC, 0xDA, 0x13, 0x9C, 0xFE, 0x02, 0x22, 0x1C,
+0xD5, 0x2E, 0x9F, 0x0D, 0xED, 0x0B, 0x9B, 0x6D, 0xF3, 0x81, 0xD6, 0xDF
+
+[sha256_hmac_buff_128]
+digest =
+0x44, 0xA6, 0x70, 0x6C, 0xD2, 0xA6, 0x3F, 0xFB, 0x98, 0xB9, 0x6A, 0x71, 0x40, 0xCF, 0xD2, 0x40,
+0xA3, 0xC0, 0xC6, 0x4E, 0xF6, 0xD8, 0x4D, 0x87, 0xF5, 0x9B, 0xAC, 0xB0, 0x7B, 0xB7, 0x35, 0x5B
+
+[sha384_hmac_buff_128]
+digest =
+0xD7, 0xFA, 0xF1, 0xC5, 0xD6, 0xCE, 0xB9, 0x77, 0xD5, 0x6B, 0x4D, 0x7F, 0xFE, 0xAF, 0xDF, 0xCE,
+0x68, 0x1A, 0xB7, 0x3E, 0xA5, 0x9A, 0xF5, 0x79, 0x91, 0x96, 0x7C, 0xED, 0xC9, 0x02, 0x31, 0x67,
+0xC4, 0xD9, 0xD7, 0x5A, 0xD7, 0xF0, 0x82, 0x2C, 0xBD, 0x4A, 0xFF, 0x03, 0x25, 0xB6, 0x50, 0x17
+
+[sha512_hmac_buff_128]
+digest =
+0x78, 0xE1, 0x86, 0x74, 0xC1, 0x83, 0xDB, 0x3C, 0xAC, 0x2B, 0x17, 0xAC, 0x12, 0xAA, 0x30, 0xDE,
+0x2C, 0x86, 0xC4, 0x53, 0x4A, 0xC2, 0x78, 0x86, 0x3A, 0x8A, 0x96, 0x36, 0x2B, 0x09, 0xB1, 0x62,
+0xCA, 0xD0, 0x25, 0xB2, 0x5B, 0x3A, 0x76, 0xFA, 0xED, 0x5B, 0xFB, 0xF0, 0x8F, 0xF2, 0x06, 0x76,
+0x9B, 0xE0, 0x82, 0x25, 0x10, 0x5E, 0x8A, 0x13, 0xA1, 0x25, 0x3B, 0xB7, 0xFC, 0xC3, 0x15, 0xED
+
+#####################
+# sha_hmac_buff_256 #
+#####################
+[sha1_hmac_buff_256]
+digest =
+0x31, 0x36, 0xC8, 0xC7, 0x95, 0xDB, 0xF7, 0xF3, 0xA0, 0xFF, 0x89, 0x94, 0x8D, 0xB2, 0x3D, 0x5F,
+0x7A, 0xC1, 0x38, 0x97
+
+[sha224_hmac_buff_256]
+digest =
+0xAE, 0x1B, 0xA4, 0x42, 0xE6, 0x3C, 0x3D, 0xEE, 0xEE, 0xD1, 0x24, 0xD2, 0xFF, 0xD2, 0x1A, 0xF3,
+0x28, 0x87, 0x8F, 0x00, 0xE3, 0x74, 0xA1, 0xA2, 0xED, 0x70, 0x2D, 0x9D
+
+[sha256_hmac_buff_256]
+digest =
+0x73, 0x89, 0x54, 0x06, 0x65, 0x71, 0x1D, 0xA1, 0xAB, 0x4A, 0x0A, 0x36, 0x63, 0x92, 0xB8, 0x94,
+0x98, 0x98, 0xB5, 0x27, 0x9D, 0x9C, 0xF2, 0x91, 0x0C, 0x56, 0xC4, 0xEE, 0x99, 0xC6, 0xDE, 0xC7
+
+[sha384_hmac_buff_256]
+digest =
+0xFE, 0x6E, 0xA5, 0xDC, 0x82, 0x57, 0xBB, 0x4D, 0xA8, 0xF1, 0x2F, 0xD1, 0xA2, 0x05, 0x0A, 0xFE,
+0xF2, 0x64, 0x8A, 0xB3, 0x96, 0xBA, 0x06, 0x47, 0xA4, 0x40, 0x76, 0x8E, 0xB8, 0xE3, 0xAD, 0xD1,
+0xB2, 0x90, 0x9A, 0x02, 0xD1, 0x13, 0x4F, 0x74, 0x9B, 0xEB, 0x09, 0xFC, 0x7F, 0x99, 0xAC, 0xCD
+
+[sha512_hmac_buff_256]
+digest =
+0x9F, 0x71, 0xE0, 0x86, 0xF9, 0x76, 0x3F, 0xAB, 0x16, 0x4D, 0x9C, 0x28, 0x72, 0x3A, 0x17, 0x8F,
+0x35, 0xD1, 0x44, 0x18, 0xE0, 0x4A, 0xBD, 0x8B, 0x25, 0x9F, 0x6E, 0x5B, 0xE3, 0xF4, 0x1C, 0x40,
+0x2B, 0xF4, 0x61, 0x59, 0x60, 0x8D, 0x55, 0xD8, 0x18, 0x9B, 0x65, 0x8D, 0x9F, 0xAA, 0xB3, 0x71,
+0x3D, 0xB5, 0x70, 0xD2, 0x26, 0xF1, 0x55, 0xDC, 0xCE, 0x49, 0x40, 0xD7, 0x23, 0x6B, 0x20, 0x4A
+
+#####################
+# sha_hmac_buff_512 #
+#####################
+[sha1_hmac_buff_512]
+digest =
+0x0F, 0xF6, 0x33, 0x61, 0x16, 0x5C, 0xD1, 0x9E, 0xE0, 0x3D, 0x95, 0x93, 0xD2, 0x82, 0xDE, 0x2E,
+0xFA, 0x25, 0x56, 0xE4
+
+[sha224_hmac_buff_512]
+digest =
+0x85, 0x61, 0x57, 0x9F, 0x3E, 0x6A, 0xE1, 0x5C, 0x1D, 0xA3, 0x98, 0x9C, 0x28, 0x2C, 0x96, 0x8E,
+0xD0, 0x7D, 0x70, 0x7D, 0xF5, 0x98, 0xA4, 0x7C, 0x88, 0x1C, 0xA4, 0x5C
+
+[sha256_hmac_buff_512]
+digest =
+0xF4, 0x77, 0xB2, 0x2E, 0xAD, 0xBC, 0xA2, 0xCD, 0x49, 0xE0, 0xD2, 0xB0, 0xB3, 0xDE, 0x51, 0xD0,
+0xBC, 0xEF, 0x33, 0x50, 0x4F, 0x39, 0xBC, 0x94, 0x18, 0xF3, 0xDD, 0xFC, 0xB5, 0x8E, 0x44, 0x18
+
+[sha384_hmac_buff_512]
+digest =
+0x03, 0x4F, 0x86, 0xA0, 0xBC, 0x00, 0x44, 0xEB, 0x06, 0x75, 0x61, 0x13, 0x92, 0x60, 0x74, 0x44,
+0x1D, 0xCB, 0x2C, 0x8D, 0xEC, 0xE5, 0x5C, 0xBE, 0xA3, 0xAE, 0x5F, 0xE2, 0x71, 0xED, 0xAC, 0x69,
+0x9C, 0x6C, 0xE3, 0x20, 0x5C, 0x90, 0xC3, 0xF4, 0x36, 0x76, 0x70, 0xAE, 0x2A, 0x9C, 0xF5, 0x0B
+
+[sha512_hmac_buff_512]
+digest =
+0x3B, 0x83, 0x4B, 0x7F, 0x2A, 0x62, 0x9A, 0xF6, 0x42, 0x29, 0x7A, 0xF0, 0xCA, 0xE7, 0xBE, 0x1F,
+0x92, 0x5C, 0x66, 0x88, 0x58, 0xFA, 0xA4, 0xC7, 0xE7, 0xF0, 0xEA, 0x83, 0xB2, 0x0A, 0x2C, 0x3B,
+0xA7, 0xD4, 0xA4, 0x3E, 0x87, 0x00, 0x44, 0x2B, 0x3F, 0xB2, 0x4B, 0xFF, 0xAD, 0x9B, 0x07, 0x7D,
+0xA1, 0x09, 0x09, 0x60, 0x68, 0x2F, 0x7B, 0x16, 0x43, 0x0E, 0x22, 0xAF, 0x78, 0x8D, 0xC7, 0x16
+
+######################
+# sha_hmac_buff_1024 #
+######################
+[sha1_hmac_buff_1024]
+digest =
+0xCD, 0x04, 0x78, 0x4A, 0xD5, 0xFE, 0x95, 0xFB, 0x04, 0x85, 0xD5, 0x25, 0x58, 0xE6, 0x6C, 0x81,
+0xFA, 0x4B, 0xE7, 0x75
+
+[sha224_hmac_buff_1024]
+digest =
+0x10, 0xA5, 0x18, 0x56, 0x66, 0xDE, 0xE6, 0xF6, 0x71, 0xAF, 0x65, 0xEC, 0xE3, 0x77, 0x08, 0x58,
+0xD5, 0x45, 0xE6, 0x21, 0xF5, 0xCC, 0x2B, 0xE2, 0x76, 0x91, 0x51, 0xD9
+
+[sha256_hmac_buff_1024]
+digest =
+0xB4, 0x09, 0xF9, 0xA0, 0x5B, 0x80, 0xFF, 0xBA, 0x21, 0x5F, 0x57, 0xAB, 0x8B, 0x67, 0x89, 0x6D,
+0xB4, 0xE9, 0xEA, 0x5D, 0x77, 0x57, 0xBD, 0x0A, 0x60, 0xA4, 0x6B, 0xE8, 0xAA, 0x8A, 0x9B, 0xC7
+
+[sha384_hmac_buff_1024]
+digest =
+0x9D, 0xAE, 0x37, 0x87, 0x2C, 0x36, 0xFD, 0x51, 0xF1, 0xF2, 0x4C, 0x82, 0x27, 0xB5, 0x99, 0x63,
+0xAB, 0xD7, 0x62, 0x4A, 0x4E, 0xF1, 0xBF, 0xFB, 0xCA, 0x30, 0x55, 0x3F, 0x43, 0x85, 0xDE, 0x6B,
+0xA2, 0xB2, 0x8B, 0x45, 0x2A, 0x9D, 0x39, 0x29, 0x63, 0x1C, 0x04, 0x47, 0x58, 0x94, 0x5C, 0x91
+
+[sha512_hmac_buff_1024]
+digest =
+0xBF, 0x06, 0x94, 0xBB, 0x2E, 0x9C, 0x0A, 0xA4, 0xF3, 0x5F, 0x52, 0x4B, 0x42, 0x6E, 0xE1, 0x6C,
+0xA8, 0xAB, 0xB7, 0xE9, 0x6F, 0xAB, 0x77, 0xF8, 0x94, 0xD0, 0xA1, 0x81, 0xB8, 0x17, 0x21, 0xAC,
+0xB2, 0x3C, 0x73, 0x71, 0xDD, 0x76, 0xF8, 0x58, 0x84, 0xE7, 0xBB, 0xD4, 0x4A, 0x4F, 0x51, 0xF5,
+0x8C, 0x87, 0xAA, 0xAC, 0xCE, 0x5E, 0xFB, 0xD3, 0x1F, 0xA2, 0x49, 0xF2, 0x40, 0xAB, 0xB8, 0x76
+
+######################
+# sha_hmac_buff_2048 #
+######################
+[sha1_hmac_buff_2048]
+digest =
+0x56, 0xE7, 0x86, 0x23, 0x2C, 0x77, 0xBE, 0x2B, 0xE6, 0x76, 0xA1, 0xE9, 0xB1, 0x0F, 0x25, 0x15,
+0x1D, 0x59, 0x7F, 0x4A
+
+[sha224_hmac_buff_2048]
+digest =
+0xFD, 0xEB, 0x9E, 0x04, 0x53, 0xC7, 0xEA, 0x56, 0x21, 0x91, 0x6D, 0x8B, 0xDC, 0xA1, 0x0A, 0x2F,
+0x73, 0x4D, 0x05, 0x36, 0x43, 0x58, 0x71, 0xB2, 0x74, 0x6E, 0x7B, 0xAF
+
+[sha256_hmac_buff_2048]
+digest =
+0x25, 0x76, 0xA5, 0x64, 0x00, 0x13, 0xF7, 0xE7, 0x2D, 0x6D, 0x17, 0x36, 0x13, 0xF3, 0xC7, 0x57,
+0x70, 0x30, 0xB2, 0x76, 0x7A, 0xF4, 0x8F, 0xAF, 0x6B, 0x8C, 0x26, 0x88, 0x73, 0x2E, 0x49, 0xC0
+
+[sha384_hmac_buff_2048]
+digest =
+0xF0, 0x69, 0x78, 0x9A, 0x34, 0x88, 0x25, 0x3C, 0x3D, 0xF5, 0x42, 0x65, 0x25, 0x79, 0xB2, 0xFC,
+0x3B, 0x92, 0x46, 0xF9, 0x0D, 0x6D, 0xC1, 0x8E, 0x45, 0xBE, 0x8B, 0x70, 0x7D, 0x1B, 0x7E, 0xDE,
+0x93, 0x04, 0xC8, 0x59, 0x4B, 0x37, 0x2C, 0x20, 0x51, 0xB1, 0x91, 0x4F, 0xA4, 0x30, 0x09, 0xED
+
+[sha512_hmac_buff_2048]
+digest =
+0xAE, 0x8A, 0x42, 0x03, 0x11, 0x25, 0xE8, 0xC3, 0x4B, 0x4B, 0xC0, 0x29, 0x27, 0xE0, 0x0D, 0x27,
+0x13, 0x8F, 0x7D, 0x82, 0x72, 0x94, 0x4B, 0xF8, 0xC3, 0x1A, 0xE1, 0x5A, 0xF3, 0x8E, 0x23, 0x27,
+0x76, 0xE4, 0xF5, 0x3E, 0x24, 0x5B, 0xA3, 0xFA, 0x49, 0x8E, 0x57, 0xE3, 0x88, 0x15, 0x1D, 0xF6,
+0x27, 0xA5, 0xC8, 0xFB, 0x34, 0x44, 0x18, 0x6A, 0x64, 0xBE, 0xFB, 0x1E, 0x87, 0xA8, 0x36, 0x1E
diff --git a/app/test-crypto-perf/data/aes_cbc_256_sha.data b/app/test-crypto-perf/data/aes_cbc_256_sha.data
new file mode 100644
index 0000000..e46a21e
--- /dev/null
+++ b/app/test-crypto-perf/data/aes_cbc_256_sha.data
@@ -0,0 +1,504 @@
+# List of tests for AES-256 CBC:
+# 1) [sha1_hmac_buff_x]
+# 2) [sha224_hmac_buff_x]
+# 3) [sha256_hmac_buff_x]
+# 4) [sha384_hmac_buff_x]
+# 5) [sha512_hmac_buff_x]
+# where x is one of the values: 32, 64, 128, 256, 512, 1024, 2048
+
+##########
+# GLOBAL #
+##########
+plaintext =
+0xff, 0xca, 0xfb, 0xf1, 0x38, 0x20, 0x2f, 0x7b, 0x24, 0x98, 0x26, 0x7d, 0x1d, 0x9f, 0xb3, 0x93,
+0xd9, 0xef, 0xbd, 0xad, 0x4e, 0x40, 0xbd, 0x60, 0xe9, 0x48, 0x59, 0x90, 0x67, 0xd7, 0x2b, 0x7b,
+0x8a, 0xe0, 0x4d, 0xb0, 0x70, 0x38, 0xcc, 0x48, 0x61, 0x7d, 0xee, 0xd6, 0x35, 0x49, 0xae, 0xb4,
+0xaf, 0x6b, 0xdd, 0xe6, 0x21, 0xc0, 0x60, 0xce, 0x0a, 0xf4, 0x1c, 0x2e, 0x1c, 0x8d, 0xe8, 0x7b,
+0x59, 0xda, 0x19, 0x4f, 0xec, 0x07, 0x8e, 0xe2, 0xf0, 0x61, 0xf9, 0x27, 0x61, 0x6f, 0xf8, 0xdf,
+0x62, 0x4d, 0xaf, 0x06, 0xfe, 0x41, 0xa6, 0xa6, 0xf9, 0xa2, 0x06, 0x40, 0xb3, 0x04, 0xbd, 0xe6,
+0xc8, 0x17, 0xfb, 0x56, 0x6f, 0xa9, 0x3b, 0x8e, 0xa6, 0x58, 0xdc, 0x91, 0x17, 0x58, 0x42, 0x95,
+0xa3, 0x7c, 0x81, 0x78, 0xa6, 0x3d, 0x3f, 0x75, 0x74, 0x17, 0x1a, 0xd3, 0x6c, 0x2f, 0x48, 0x39,
+0x20, 0x20, 0xc1, 0x9a, 0x29, 0x84, 0x7d, 0x2d, 0x52, 0xa1, 0xf9, 0x5c, 0xf3, 0x4f, 0x91, 0xfc,
+0x75, 0xcf, 0xd6, 0x2d, 0xe7, 0x9a, 0x59, 0x6e, 0x00, 0x0e, 0x8d, 0x22, 0x17, 0xbd, 0xa0, 0xdd,
+0x79, 0x1f, 0x71, 0xe6, 0xcd, 0x2f, 0xb1, 0xb6, 0xbc, 0xc3, 0xdb, 0x02, 0x91, 0x41, 0x9b, 0x09,
+0xa9, 0xd2, 0x7e, 0xbd, 0x2c, 0x18, 0xae, 0xc0, 0x93, 0x0c, 0x02, 0x9a, 0xdb, 0x4e, 0xaa, 0xeb,
+0x84, 0x4b, 0x43, 0x5e, 0xf0, 0x98, 0xf2, 0x5f, 0x86, 0x70, 0x96, 0x90, 0x15, 0x30, 0xcf, 0x3a,
+0xc9, 0x33, 0x21, 0xec, 0x59, 0x86, 0xfc, 0x65, 0x7d, 0xbe, 0xb9, 0xf8, 0x97, 0xf9, 0x30, 0xa9,
+0x6d, 0xfc, 0x0c, 0x6e, 0x36, 0x67, 0xd5, 0xa6, 0x67, 0xd9, 0xbd, 0x9b, 0x34, 0x5d, 0xa7, 0xdd,
+0xda, 0x46, 0x33, 0x25, 0x60, 0x4a, 0x18, 0xf1, 0x55, 0x07, 0xb2, 0xb7, 0x26, 0x7b, 0xa6, 0x1e,
+0x77, 0xbe, 0x7f, 0x35, 0x46, 0xdf, 0x56, 0x9c, 0x22, 0x19, 0xc8, 0x85, 0xa2, 0x45, 0xb2, 0xad,
+0xf9, 0x26, 0x66, 0xab, 0xfc, 0x97, 0x4b, 0x51, 0x32, 0x36, 0xbc, 0xad, 0xcf, 0x54, 0x3a, 0x4f,
+0x94, 0xdb, 0xd2, 0xf9, 0x67, 0x1b, 0x3b, 0xe5, 0xb2, 0x1d, 0xc5, 0x52, 0x64, 0x2c, 0x06, 0x44,
+0xcf, 0x18, 0x83, 0xe0, 0xd8, 0x04, 0x92, 0xa9, 0xc4, 0x3c, 0x8b, 0xa3, 0x2b, 0xbc, 0x88, 0x7e,
+0xc0, 0x76, 0xa7, 0xe2, 0x7b, 0x47, 0x90, 0xf2, 0xaa, 0x0a, 0x34, 0x1b, 0x91, 0x12, 0xd2, 0xd0,
+0x82, 0x45, 0xf4, 0x57, 0xf1, 0xbd, 0x91, 0x5e, 0xab, 0x41, 0x4c, 0xdf, 0x91, 0x4c, 0xdd, 0x67,
+0x04, 0xa0, 0x98, 0x23, 0x8c, 0x24, 0xbe, 0xd6, 0x80, 0xb3, 0x6d, 0x04, 0xa1, 0x77, 0x43, 0xa5,
+0xee, 0xb7, 0xce, 0xb1, 0x48, 0x43, 0x94, 0x61, 0x15, 0x20, 0x9d, 0xce, 0xd0, 0x14, 0x95, 0x37,
+0xc8, 0x64, 0xa3, 0x2d, 0x3d, 0xe3, 0xff, 0xb4, 0x55, 0x83, 0x84, 0x41, 0x50, 0x57, 0xbd, 0x5a,
+0x0c, 0xe4, 0xda, 0x3b, 0x36, 0x4d, 0x21, 0xb5, 0x6f, 0x73, 0x2a, 0x8c, 0x78, 0x4f, 0x9b, 0x83,
+0xda, 0x11, 0x3c, 0xf0, 0xc9, 0x7e, 0xa6, 0x48, 0x34, 0x53, 0x62, 0xd3, 0x0c, 0xff, 0xb1, 0x74,
+0xd6, 0xea, 0xa5, 0xfc, 0x13, 0x1c, 0x05, 0xa8, 0xc0, 0xbc, 0x95, 0x9c, 0x8c, 0xf6, 0x8c, 0xc3,
+0xf3, 0x69, 0xab, 0x93, 0x65, 0xc0, 0xb7, 0x7e, 0xb0, 0x16, 0x7c, 0xb5, 0x5f, 0x05, 0x28, 0xc9,
+0x09, 0x4e, 0x2a, 0x32, 0x87, 0xb3, 0xab, 0xf8, 0x4c, 0xab, 0xeb, 0x3b, 0x6a, 0xa0, 0x1d, 0x7f,
+0xef, 0xe5, 0x9b, 0xa4, 0xb7, 0xd7, 0xc2, 0x5e, 0x03, 0x0f, 0x99, 0xeb, 0xb1, 0xb1, 0xa6, 0x9d,
+0x1c, 0x7c, 0x5c, 0x94, 0x8b, 0x6e, 0x11, 0x7a, 0xb3, 0x6d, 0x1e, 0x61, 0x64, 0xc3, 0x7d, 0x1c,
+0xb3, 0x54, 0x65, 0x08, 0x3b, 0xda, 0x97, 0xb9, 0x75, 0xc1, 0x2b, 0x3e, 0xa8, 0x5c, 0x3c, 0x2d,
+0x81, 0x5b, 0xbf, 0x5a, 0x13, 0x0e, 0xeb, 0x66, 0xc0, 0x0b, 0x8f, 0x04, 0x68, 0x68, 0x9b, 0xe3,
+0x0d, 0x84, 0xe0, 0xcf, 0x83, 0xd7, 0x62, 0x48, 0xc1, 0x31, 0xa5, 0xd5, 0xbc, 0xe3, 0xa3, 0xa5,
+0xb6, 0xd1, 0xfd, 0x81, 0x91, 0x4d, 0xbd, 0xc4, 0x62, 0x4f, 0xe3, 0xd5, 0x99, 0x14, 0xf1, 0xcd,
+0xf4, 0x7d, 0x13, 0xda, 0x68, 0x0a, 0xca, 0xd6, 0x82, 0x0b, 0xf6, 0xea, 0xad, 0x78, 0xa4, 0xc8,
+0x14, 0x7a, 0xec, 0x11, 0xd3, 0x16, 0x86, 0x9f, 0x17, 0x37, 0x6a, 0x06, 0x56, 0xaa, 0x1b, 0xd1,
+0xaf, 0x85, 0x95, 0x21, 0x36, 0x69, 0xec, 0x1b, 0x56, 0x84, 0x01, 0x3f, 0x4d, 0x34, 0x3d, 0x2d,
+0x38, 0x57, 0x2d, 0x7e, 0xd9, 0x7b, 0x2d, 0x81, 0x86, 0xd4, 0x7c, 0x83, 0x12, 0x1d, 0x9d, 0x27,
+0x72, 0x1b, 0x5e, 0xf4, 0x15, 0xa5, 0xcd, 0xb7, 0x5f, 0xbb, 0x49, 0xa1, 0xd9, 0xdd, 0x8d, 0xad,
+0xa9, 0x2c, 0x65, 0x18, 0x91, 0xfd, 0xd2, 0xd4, 0x09, 0x60, 0x0c, 0xfd, 0xa4, 0xe1, 0x25, 0x87,
+0x32, 0x64, 0x7b, 0x99, 0xd7, 0x61, 0x2f, 0xd4, 0x73, 0xdd, 0x85, 0x26, 0x08, 0x92, 0xc0, 0xe1,
+0x4f, 0x0c, 0x76, 0x5b, 0x26, 0x69, 0xdb, 0x78, 0x35, 0x65, 0xb9, 0x58, 0x1f, 0x9c, 0x0f, 0x18,
+0x95, 0xfe, 0x40, 0xfc, 0xf7, 0x93, 0x71, 0x70, 0x8b, 0x73, 0xdc, 0xb0, 0x88, 0x72, 0x19, 0x26,
+0x94, 0x26, 0xa7, 0xaa, 0x00, 0x72, 0x61, 0x53, 0xd2, 0x5d, 0x8f, 0x5e, 0x51, 0x88, 0x2d, 0xa4,
+0x28, 0xd5, 0xaf, 0x2d, 0xd2, 0x84, 0x39, 0x75, 0x1e, 0xe7, 0xf0, 0x23, 0xc0, 0x4f, 0x8d, 0xdd,
+0x5c, 0x90, 0xef, 0x6e, 0x53, 0xe0, 0x54, 0x67, 0xe1, 0x5b, 0x10, 0xf1, 0xf5, 0xf8, 0x64, 0x34,
+0x94, 0xeb, 0x37, 0xf7, 0xe9, 0xaa, 0x6c, 0xa4, 0xd8, 0x74, 0x6d, 0xca, 0x8d, 0x1a, 0x31, 0x73,
+0xca, 0xb4, 0xc7, 0x47, 0x34, 0x7f, 0xf8, 0x24, 0x9b, 0xfa, 0xc9, 0xcc, 0xa8, 0x61, 0xb4, 0x0e,
+0x4d, 0x68, 0xc7, 0xa0, 0xcb, 0xea, 0xf0, 0xcc, 0x0a, 0x6c, 0xf2, 0x33, 0x42, 0x99, 0x6c, 0xd8,
+0x74, 0x7f, 0x1e, 0x8a, 0xa3, 0x0a, 0x48, 0x4b, 0x7e, 0xbe, 0xdb, 0x7f, 0x56, 0x69, 0x43, 0xe8,
+0xbf, 0x12, 0xc4, 0x7b, 0xc2, 0xd9, 0xfa, 0x5c, 0xeb, 0x45, 0xca, 0x07, 0x3d, 0xc0, 0xcd, 0x68,
+0x8b, 0xd0, 0x79, 0xea, 0x0a, 0x78, 0x06, 0xdc, 0x81, 0xd7, 0x32, 0x18, 0xb3, 0x65, 0xbe, 0x47,
+0xbb, 0xfa, 0x17, 0x09, 0xe9, 0x31, 0x95, 0x30, 0xef, 0x07, 0x44, 0xec, 0xd0, 0x98, 0x98, 0xc0,
+0x6b, 0x71, 0x5b, 0x23, 0xb8, 0xb6, 0xd2, 0x21, 0xff, 0x51, 0xdd, 0xae, 0x48, 0x29, 0x75, 0x0c,
+0xc3, 0x3d, 0x91, 0xfe, 0x9d, 0xa8, 0x5e, 0xb2, 0x34, 0xb2, 0xd3, 0x81, 0xf6, 0x27, 0x9c, 0xac,
+0x6b, 0x20, 0x56, 0x86, 0xa5, 0x4f, 0x7a, 0xdb, 0xf9, 0xac, 0xa9, 0x8e, 0xe3, 0x73, 0x21, 0x99,
+0x71, 0x2d, 0xaf, 0x27, 0x92, 0x0c, 0xc7, 0xd3, 0x85, 0xb3, 0x40, 0xda, 0x13, 0x4a, 0x04, 0x41,
+0x54, 0xf8, 0xf2, 0x55, 0xb7, 0x80, 0xdd, 0x77, 0xba, 0x01, 0x7a, 0x31, 0xbd, 0x6b, 0xdc, 0x5c,
+0x59, 0xf4, 0x2b, 0xca, 0x25, 0xbb, 0x50, 0xba, 0xfa, 0x42, 0x38, 0xd2, 0x28, 0x10, 0x8b, 0x7b,
+0x96, 0x45, 0x30, 0xbb, 0x7f, 0xf4, 0x5a, 0xf7, 0x28, 0x6f, 0x47, 0xdc, 0xd2, 0x82, 0xf2, 0xf7,
+0xdd, 0x20, 0xb5, 0x0c, 0x7e, 0x53, 0x85, 0xa7, 0xfc, 0x3b, 0x1a, 0xc0, 0x07, 0x7b, 0xa1, 0x43,
+0x05, 0x18, 0x19, 0xd3, 0xfc, 0x41, 0xc2, 0xce, 0xd9, 0x5b, 0x4b, 0x63, 0xe2, 0x8f, 0x86, 0x3a,
+0xd1, 0xd0, 0x1d, 0x74, 0x2e, 0xbc, 0xd3, 0xce, 0x08, 0x0c, 0x10, 0x7a, 0x42, 0x60, 0xc5, 0x3a,
+0xa6, 0xd8, 0xb0, 0x52, 0xcf, 0x53, 0x28, 0x70, 0x45, 0xb7, 0x72, 0x7d, 0x77, 0x66, 0x54, 0x3d,
+0x38, 0x26, 0xcf, 0xd5, 0xbf, 0xe4, 0x80, 0x10, 0xba, 0x2b, 0xe8, 0xdc, 0xc3, 0xfe, 0x28, 0xa3,
+0x52, 0x58, 0x70, 0x4a, 0xde, 0x84, 0x33, 0x5e, 0x93, 0x04, 0xa4, 0x7c, 0xe7, 0xea, 0x8e, 0xba,
+0xeb, 0x8a, 0x19, 0x26, 0x6a, 0x7f, 0x7c, 0x4a, 0x5b, 0xb4, 0x0d, 0xfc, 0xc8, 0x11, 0x1b, 0x41,
+0x68, 0x5d, 0x2a, 0x25, 0x04, 0x4f, 0xc8, 0xf4, 0x65, 0xfc, 0xb9, 0x58, 0xeb, 0xb4, 0x67, 0x50,
+0x24, 0xf5, 0x43, 0xf6, 0x91, 0x4a, 0xb0, 0x0f, 0x32, 0xe0, 0x07, 0x75, 0x69, 0x1b, 0x3c, 0xeb,
+0xb2, 0x65, 0x26, 0x6f, 0xb8, 0x79, 0xe0, 0x78, 0x8c, 0xdc, 0x39, 0x24, 0x48, 0x76, 0x11, 0xd4,
+0x3a, 0xc5, 0xd2, 0x2b, 0xaa, 0x55, 0xfb, 0x92, 0x12, 0x2d, 0x88, 0x05, 0xd1, 0xb1, 0x31, 0x36,
+0x1f, 0xc2, 0x44, 0x1c, 0xab, 0x2e, 0xcd, 0x1c, 0x72, 0x86, 0xf6, 0x83, 0x87, 0x2e, 0x8b, 0xdb,
+0xaa, 0x16, 0x0e, 0x1b, 0xe6, 0x5c, 0x4d, 0x2f, 0x82, 0xbd, 0x49, 0x11, 0x60, 0x22, 0x0f, 0xde,
+0x3b, 0x2b, 0x20, 0x1d, 0x56, 0xb7, 0x21, 0xae, 0x0b, 0x26, 0x4f, 0xde, 0x3d, 0xa6, 0x3f, 0x61,
+0x81, 0xe2, 0x76, 0x60, 0x08, 0xc5, 0x4b, 0x18, 0x0b, 0xd1, 0xf5, 0xff, 0x8d, 0x1a, 0x96, 0x76,
+0x51, 0x15, 0x05, 0x4d, 0x8c, 0x6b, 0x12, 0x90, 0x47, 0xd4, 0xa4, 0x38, 0xb9, 0x48, 0xe4, 0x4c,
+0x05, 0x69, 0x6a, 0x8b, 0x9d, 0x7c, 0xa1, 0xbc, 0x77, 0xeb, 0x86, 0x93, 0x0a, 0x15, 0x84, 0xba,
+0x8f, 0xf5, 0x7c, 0x44, 0x75, 0x31, 0x79, 0x16, 0xc1, 0x81, 0x1a, 0xb6, 0xe6, 0x6c, 0x3d, 0xb8,
+0x15, 0x46, 0xf5, 0xbe, 0x46, 0x04, 0xa6, 0xec, 0xec, 0xd1, 0x74, 0x8b, 0x87, 0x2b, 0xdb, 0xd0,
+0x9f, 0xb3, 0x99, 0x9d, 0x87, 0x8c, 0xc6, 0xaa, 0xd4, 0x64, 0x45, 0xbd, 0xe8, 0xed, 0xa3, 0xc1,
+0x2a, 0x41, 0x1e, 0x26, 0xaf, 0x86, 0x16, 0xed, 0x80, 0x08, 0xca, 0x64, 0x21, 0x3a, 0xce, 0x21,
+0x4c, 0x41, 0xb9, 0x13, 0x2d, 0xf7, 0x1b, 0xdf, 0x2b, 0x33, 0x69, 0xe7, 0x5c, 0x8c, 0x7b, 0xfb,
+0xe3, 0x41, 0xe9, 0xce, 0xd7, 0xff, 0x0e, 0x54, 0xfe, 0xb0, 0x71, 0x78, 0xdc, 0xde, 0x7e, 0xdd,
+0x1f, 0x1c, 0x4a, 0x8f, 0x3e, 0x16, 0xfd, 0x91, 0x82, 0x94, 0xd4, 0xc2, 0xf7, 0xb2, 0x77, 0x89,
+0x16, 0x2c, 0xba, 0xb6, 0xbd, 0xed, 0x95, 0x43, 0x05, 0x9b, 0xf2, 0xc4, 0xbe, 0x46, 0x43, 0x90,
+0x1d, 0xd8, 0x24, 0x02, 0xd2, 0xea, 0xf4, 0x08, 0xd9, 0xf7, 0x84, 0x0e, 0xc6, 0xe7, 0x44, 0xdb,
+0xb8, 0xac, 0x0a, 0x53, 0x39, 0x61, 0x43, 0xdc, 0x22, 0x28, 0x8f, 0x22, 0x2f, 0x73, 0xbf, 0x59,
+0x2d, 0x3c, 0x8c, 0x0b, 0xcc, 0x2a, 0x67, 0xe0, 0x5b, 0x5c, 0x65, 0x5e, 0x6d, 0x98, 0x99, 0xaa,
+0x3b, 0x89, 0x12, 0xe2, 0x99, 0xf6, 0x15, 0xa7, 0xd2, 0x6a, 0x79, 0xb4, 0xf6, 0x0b, 0xf5, 0x0d,
+0x2d, 0x4c, 0xcb, 0x1b, 0x35, 0x93, 0x61, 0x32, 0xa1, 0x8a, 0xa8, 0x27, 0xe8, 0x95, 0x5a, 0x56,
+0x59, 0x04, 0xfe, 0xce, 0xc2, 0xd8, 0x92, 0x97, 0xb2, 0x54, 0x63, 0xd0, 0x3b, 0xde, 0x10, 0x34,
+0x32, 0x16, 0x05, 0x51, 0x1d, 0xfc, 0x96, 0x8e, 0xf1, 0xf6, 0x4b, 0xd7, 0x48, 0x22, 0xce, 0xca,
+0x1c, 0x6b, 0xab, 0x1f, 0x59, 0xa2, 0x74, 0xd6, 0xcd, 0x15, 0x07, 0xab, 0xa2, 0xd5, 0x22, 0x81,
+0xec, 0x20, 0x14, 0x36, 0xac, 0xe4, 0x25, 0x7d, 0xe6, 0x09, 0x00, 0x2c, 0x92, 0x4d, 0x4e, 0xbf,
+0xbf, 0xa1, 0xd4, 0xbe, 0x6b, 0xd4, 0x1f, 0x95, 0x9b, 0xf3, 0xda, 0x99, 0xad, 0xa4, 0x6c, 0x73,
+0x55, 0xd1, 0x9d, 0x4b, 0x16, 0xd4, 0x06, 0xec, 0x46, 0x3d, 0xb7, 0xe7, 0xce, 0xd0, 0x1d, 0x94,
+0x65, 0xde, 0x61, 0xb3, 0xc1, 0x10, 0x65, 0xe5, 0x68, 0x9b, 0xb0, 0xb4, 0x43, 0x0b, 0x92, 0xaf,
+0xb7, 0x40, 0xa2, 0xe5, 0x06, 0x3d, 0x72, 0x00, 0xc5, 0x39, 0xab, 0x35, 0x29, 0x22, 0x4c, 0xa5,
+0xa5, 0x3f, 0x22, 0x90, 0x53, 0xd2, 0x36, 0x63, 0x1e, 0xd3, 0x33, 0xa5, 0xbb, 0x3d, 0xa3, 0x0c,
+0x14, 0x9c, 0x2e, 0x6d, 0x9a, 0x7a, 0xf7, 0xf1, 0x56, 0x66, 0xe5, 0x8d, 0x53, 0x83, 0x34, 0x3f,
+0xa9, 0x83, 0x84, 0x68, 0x90, 0xc9, 0x51, 0xc2, 0xd4, 0x8e, 0x6c, 0xc7, 0x6d, 0xa7, 0x19, 0x61,
+0xa7, 0x2e, 0x36, 0xbc, 0xd2, 0x0f, 0x17, 0x49, 0xd4, 0x6b, 0x36, 0x63, 0xfb, 0x1d, 0xf4, 0xb0,
+0x6b, 0xcf, 0x34, 0x5f, 0xd2, 0x77, 0xae, 0x12, 0xaf, 0xb3, 0xdf, 0x52, 0xf7, 0xc2, 0xc8, 0xf2,
+0x63, 0x61, 0xb6, 0x3e, 0x39, 0xf2, 0xa7, 0x1a, 0x89, 0x9d, 0x0e, 0x8f, 0xaf, 0xe1, 0x01, 0x24,
+0xa6, 0x3a, 0xd5, 0x9a, 0x62, 0x67, 0xa3, 0x66, 0xee, 0xbc, 0xc5, 0x94, 0x4b, 0xc3, 0x15, 0xa1,
+0x7e, 0x07, 0x07, 0x2b, 0xb7, 0x43, 0x2a, 0xb4, 0xb8, 0x25, 0x88, 0x86, 0x23, 0xab, 0xdf, 0x05,
+0xbe, 0x46, 0x56, 0xd7, 0xda, 0xd6, 0x75, 0x53, 0xd9, 0xc8, 0x26, 0x8f, 0x39, 0x67, 0xed, 0x21,
+0x53, 0x1c, 0x9c, 0x89, 0x46, 0xd3, 0xfe, 0x54, 0xe6, 0x1d, 0x02, 0xb9, 0x25, 0x82, 0x66, 0xe6,
+0xf9, 0x45, 0xd9, 0x3f, 0xa5, 0x71, 0xc1, 0x46, 0x66, 0x7a, 0x27, 0x8a, 0x82, 0xc9, 0x21, 0xe9,
+0x17, 0xab, 0x6c, 0xef, 0x45, 0xe5, 0x88, 0x93, 0x87, 0x80, 0xb3, 0x85, 0x25, 0x96, 0x19, 0x41,
+0xab, 0xd6, 0xba, 0x92, 0x76, 0x21, 0x8a, 0x58, 0xbd, 0xe2, 0x4b, 0xec, 0x45, 0x59, 0x2c, 0x13,
+0x1a, 0xb5, 0x13, 0x25, 0x44, 0xe7, 0x71, 0x26, 0x0a, 0x34, 0x33, 0xb9, 0x57, 0x15, 0xa4, 0x90,
+0x60, 0x11, 0x05, 0x8e, 0xc8, 0x8e, 0x74, 0x52, 0x4b, 0x31, 0x71, 0xeb, 0x66, 0x7e, 0xee, 0xb1,
+0x0a, 0x21, 0x52, 0xc0, 0x1a, 0xe9, 0xa1, 0x5a, 0xe3, 0x3a, 0x24, 0xfb, 0xf3, 0x1e, 0xd6, 0x83,
+0x1d, 0xfb, 0x81, 0xa8, 0x91, 0x60, 0x9e, 0xbc, 0x59, 0x20, 0xc9, 0x9e, 0x71, 0x19, 0x83, 0x2b,
+0x6a, 0x48, 0x4e, 0x6b, 0x46, 0x82, 0x89, 0xda, 0x60, 0xff, 0x1a, 0x46, 0x94, 0x55, 0xda, 0xe5,
+0x99, 0xfa, 0x84, 0xd7, 0x3b, 0xb9, 0xa5, 0x34, 0x87, 0x86, 0x5e, 0x6d, 0x75, 0x9a, 0xe7, 0x09,
+0xb8, 0xe6, 0x71, 0x15, 0x10, 0x56, 0xd7, 0xc1, 0xc8, 0xb2, 0x62, 0xbc, 0xec, 0xe0, 0x94, 0xa0,
+0xcd, 0xb4, 0x04, 0xa9, 0xc3, 0x51, 0xee, 0xf8, 0x2e, 0x42, 0x9a, 0xaa, 0x34, 0xd3, 0xb9, 0xb0,
+0x36, 0xf9, 0x47, 0xc1, 0x07, 0x49, 0xde, 0xb8, 0x32, 0x8a, 0x87, 0x68, 0x56, 0x9a, 0x35, 0x79,
+0xd1, 0xac, 0x49, 0x38, 0xc6, 0xfe, 0xfd, 0xdf, 0x6f, 0x3c, 0xda, 0x48, 0xbd, 0x23, 0xfd, 0x85,
+0xf0, 0x96, 0xee, 0x1c, 0x27, 0x18, 0x86, 0xa6, 0xf0, 0x7b, 0xd8, 0x3c, 0xc7, 0x22, 0x3e, 0x2f,
+0xac, 0xb1, 0x37, 0xbd, 0x84, 0x4b, 0xe3, 0x92, 0x82, 0xd0, 0x25, 0x14, 0x22, 0x65, 0xed, 0xeb,
+0xef, 0xb9, 0xb6, 0xe4, 0x95, 0x18, 0x0d, 0x2b, 0x8d, 0x4f, 0xaf, 0xc0, 0xa0, 0x05, 0x8b, 0x35,
+0x5b, 0x94, 0xb2, 0x68, 0x26, 0x4f, 0x4a, 0x9e, 0x85, 0x0e, 0x46, 0xe0, 0x4f, 0x60, 0x66, 0x01,
+0xa4, 0x39, 0xe8, 0x8b, 0x2a, 0x50, 0xf5, 0x18, 0x70, 0xe2, 0xfc, 0xd6, 0xbe, 0xd3, 0x46, 0x4b
+
+ciphertext =
+0x77, 0xF9, 0xF7, 0x7A, 0xA3, 0xCB, 0x68, 0x1A, 0x11, 0x70, 0xD8, 0x7A, 0xB6, 0xE2, 0x37, 0x7E,
+0xD1, 0x57, 0x1C, 0x8E, 0x85, 0xD8, 0x08, 0xBF, 0x57, 0x1F, 0x21, 0x6C, 0xAD, 0xAD, 0x47, 0x1E,
+0x0D, 0x6B, 0x79, 0x39, 0x15, 0x4E, 0x5B, 0x59, 0x2D, 0x76, 0x87, 0xA6, 0xD6, 0x47, 0x8F, 0x82,
+0xB8, 0x51, 0x91, 0x32, 0x60, 0xCB, 0x97, 0xDE, 0xBE, 0xF0, 0xAD, 0xFC, 0x23, 0x2E, 0x22, 0x02,
+0x46, 0x17, 0x3F, 0x8F, 0x24, 0x0E, 0x31, 0x80, 0xEA, 0xD6, 0x85, 0x50, 0xA5, 0xEE, 0xB7, 0x15,
+0xD0, 0x2F, 0xA6, 0x92, 0xEF, 0xCD, 0x8B, 0x91, 0x4A, 0xEA, 0x03, 0x92, 0xB4, 0x65, 0x19, 0x66,
+0x9E, 0x73, 0x79, 0xCE, 0xA7, 0x4D, 0x8B, 0x77, 0x74, 0x44, 0x1C, 0x9F, 0xEE, 0x15, 0x91, 0xF2,
+0xF9, 0x50, 0x7D, 0x2A, 0xC2, 0x6B, 0x58, 0x36, 0xF7, 0x62, 0x25, 0x9C, 0x71, 0x34, 0x43, 0x14,
+0x9E, 0x17, 0xF7, 0xB7, 0x56, 0x1D, 0x91, 0x4C, 0xF6, 0x6C, 0xF2, 0x19, 0x39, 0xA2, 0x29, 0xA3,
+0x22, 0x4F, 0x14, 0x18, 0x76, 0x8A, 0x59, 0xAD, 0x3E, 0x5F, 0xDC, 0xC9, 0x80, 0x07, 0x51, 0xB2,
+0x90, 0x6A, 0xB9, 0x0C, 0xA4, 0x3F, 0x42, 0xBD, 0x40, 0xB7, 0xA7, 0xF5, 0x85, 0xBF, 0xEA, 0xD8,
+0x89, 0xA9, 0xE9, 0xC7, 0x25, 0xEC, 0xFF, 0x80, 0xE8, 0x94, 0x3B, 0xE7, 0xD1, 0x68, 0xDA, 0x1C,
+0xFA, 0x5D, 0xCD, 0x68, 0x09, 0x72, 0x63, 0xBA, 0x34, 0x56, 0xD4, 0x5F, 0xB0, 0xA7, 0xAE, 0xCF,
+0xFB, 0xA8, 0xBD, 0x52, 0x79, 0x98, 0xF6, 0x39, 0x52, 0xD3, 0xA7, 0xE1, 0xFB, 0x75, 0x76, 0x87,
+0xBC, 0x11, 0x18, 0x17, 0x47, 0x65, 0xDA, 0xE3, 0x25, 0x3E, 0x17, 0x43, 0x7B, 0x0D, 0x8B, 0x7F,
+0x20, 0xFF, 0x03, 0xFA, 0x28, 0xC7, 0xD3, 0xF8, 0xC2, 0xA8, 0xC1, 0xE5, 0xDA, 0x77, 0x41, 0x28,
+0x06, 0xC4, 0x20, 0xFC, 0x1B, 0xAA, 0x99, 0x78, 0x5C, 0x28, 0xDA, 0x9A, 0x2B, 0x6C, 0x56, 0x7E,
+0x63, 0x34, 0xCF, 0xCD, 0x5D, 0xB6, 0x13, 0xF5, 0x98, 0x08, 0x2E, 0x02, 0x2C, 0x63, 0xEC, 0xE3,
+0x43, 0xE8, 0x3B, 0xE6, 0x59, 0x8C, 0x61, 0x60, 0xDD, 0x33, 0x3F, 0x29, 0xA4, 0xA5, 0xD5, 0x33,
+0xEF, 0xAA, 0x7E, 0x8C, 0xAE, 0x9C, 0x1B, 0x0D, 0x74, 0xF6, 0x01, 0x8C, 0xF1, 0x04, 0xEB, 0x62,
+0x75, 0xC0, 0x98, 0x24, 0xB2, 0xDF, 0xB1, 0xBA, 0x50, 0xC3, 0x01, 0x5B, 0x13, 0x3A, 0xF9, 0x7A,
+0xF6, 0xF4, 0x75, 0xAF, 0x55, 0x54, 0x10, 0xBE, 0x11, 0x91, 0x7D, 0xF6, 0x66, 0x79, 0xE6, 0x4D,
+0x0E, 0x0B, 0x70, 0x3C, 0x00, 0x68, 0x2E, 0xA3, 0x84, 0xCE, 0xE1, 0x0A, 0xDC, 0xFE, 0xF9, 0xD2,
+0x59, 0x23, 0x05, 0xCA, 0x79, 0xF0, 0x89, 0xB9, 0x76, 0xD9, 0xAA, 0x04, 0x43, 0x30, 0x97, 0x15,
+0x59, 0x0B, 0x7C, 0x22, 0x0E, 0x72, 0xC6, 0x61, 0x19, 0x35, 0xC3, 0x6A, 0xF2, 0x6B, 0x39, 0xB6,
+0x1B, 0xD3, 0xE3, 0xF7, 0xCB, 0x46, 0x26, 0x97, 0x39, 0xBA, 0x41, 0xD8, 0xA4, 0x48, 0x96, 0xBC,
+0x22, 0x38, 0xCF, 0xE2, 0xCF, 0xD6, 0x36, 0x30, 0xD9, 0x96, 0x73, 0xAF, 0xA4, 0x0F, 0x52, 0x9D,
+0x64, 0x28, 0xAB, 0x3D, 0xF7, 0x1B, 0xA6, 0xDB, 0x47, 0x09, 0x45, 0x48, 0x30, 0x27, 0x4B, 0x37,
+0x38, 0x5B, 0xC5, 0x90, 0x8C, 0xCC, 0x82, 0x48, 0x7A, 0x98, 0x1C, 0x46, 0x24, 0xB1, 0xDA, 0xB9,
+0x6C, 0x30, 0x48, 0xF3, 0x6C, 0x84, 0xBD, 0x3F, 0x95, 0x3E, 0xC1, 0x27, 0x8B, 0x3C, 0x2F, 0xDA,
+0xD9, 0xF6, 0x54, 0x73, 0x04, 0x38, 0xD6, 0x45, 0xC5, 0x5C, 0x92, 0xDE, 0xB2, 0xE3, 0x62, 0x31,
+0xCE, 0x70, 0xD7, 0x11, 0x5E, 0x7A, 0x63, 0x0F, 0xA1, 0xD4, 0x8A, 0x2B, 0xDE, 0x38, 0xAA, 0x9F,
+0x33, 0x71, 0x67, 0x05, 0xDB, 0x48, 0xE4, 0x09, 0x73, 0x3A, 0x35, 0x1F, 0xC2, 0x0F, 0x44, 0x99,
+0x35, 0xBD, 0xBD, 0x7E, 0x85, 0x77, 0x46, 0x3A, 0x41, 0x79, 0xAB, 0x67, 0xA5, 0x87, 0xBD, 0x96,
+0xAE, 0xC2, 0x99, 0x35, 0xC3, 0xCA, 0x90, 0x36, 0xB1, 0x15, 0x9C, 0x37, 0x62, 0x54, 0xCA, 0x72,
+0x10, 0x07, 0x07, 0x6E, 0x1D, 0xD0, 0xFE, 0x4C, 0xE8, 0x48, 0x92, 0x7A, 0xA1, 0x7B, 0xA5, 0xAC,
+0xF7, 0xE1, 0x99, 0xC0, 0x99, 0x20, 0xD5, 0x07, 0x77, 0x1D, 0xE5, 0x14, 0x36, 0xA6, 0xF3, 0x77,
+0x9B, 0x61, 0x87, 0x98, 0xD6, 0xD6, 0xF8, 0xE6, 0x34, 0x37, 0x6F, 0x58, 0x29, 0x97, 0x2D, 0xE6,
+0xD1, 0x56, 0xB1, 0xBB, 0x35, 0xBD, 0x2B, 0x44, 0xAD, 0x30, 0x0F, 0x1D, 0x48, 0x5F, 0xDD, 0x58,
+0x7C, 0xB8, 0x2C, 0x2E, 0x26, 0x9B, 0xDA, 0x55, 0x01, 0x06, 0x66, 0xB0, 0x3C, 0xAB, 0xA0, 0x60,
+0x98, 0xF4, 0x72, 0xAF, 0xBC, 0x00, 0xAA, 0x57, 0x6A, 0xD8, 0x47, 0xC7, 0xC1, 0xCE, 0xB1, 0x05,
+0x45, 0x84, 0x63, 0x1E, 0x9C, 0x47, 0x11, 0xB4, 0xE6, 0x80, 0x8D, 0x3E, 0xFF, 0xE9, 0xD9, 0x3A,
+0x56, 0x3D, 0x41, 0x68, 0x2C, 0x6C, 0xA2, 0x23, 0x4C, 0xD6, 0x08, 0x91, 0x93, 0xCD, 0xAA, 0xF7,
+0xAA, 0x2B, 0x55, 0xEC, 0x53, 0xE8, 0xD9, 0x2E, 0xCB, 0xE0, 0x67, 0x1D, 0x9F, 0xFF, 0x94, 0xB8,
+0xBA, 0x82, 0xA7, 0x6A, 0x8C, 0x61, 0x7C, 0x58, 0x90, 0xA5, 0x11, 0x57, 0x21, 0xCF, 0x30, 0xB0,
+0x97, 0x44, 0x7D, 0x1D, 0xD3, 0x91, 0x3F, 0xC2, 0x4F, 0x0E, 0x3B, 0x57, 0x3A, 0x1F, 0x85, 0x82,
+0x79, 0x91, 0x03, 0xB4, 0x9B, 0x70, 0x2A, 0x5F, 0x8B, 0x20, 0x66, 0x6F, 0xF4, 0x10, 0x96, 0x52,
+0x4C, 0x77, 0xA2, 0x45, 0x28, 0xF8, 0xAD, 0xA3, 0x8C, 0x99, 0x3F, 0xD2, 0x39, 0x4A, 0x1A, 0x3A,
+0x72, 0x7E, 0x47, 0x49, 0x25, 0x63, 0x87, 0xCB, 0xEA, 0x89, 0x1D, 0x7F, 0x0C, 0x86, 0x9A, 0x8E,
+0xB1, 0x0C, 0xFF, 0xC6, 0xF2, 0xB1, 0x01, 0x99, 0xEA, 0xF1, 0x4A, 0xF1, 0xF3, 0x71, 0x4B, 0x92,
+0xC6, 0xD6, 0xD8, 0x26, 0xE8, 0x28, 0xF2, 0xF5, 0x5B, 0xE8, 0xF1, 0xE4, 0x4B, 0x36, 0x46, 0xD3,
+0x12, 0x2F, 0x98, 0x61, 0x12, 0xD9, 0x26, 0x58, 0x5C, 0x80, 0x7C, 0x71, 0x4E, 0x57, 0x9A, 0xAC,
+0x59, 0xE0, 0xC3, 0x70, 0x55, 0x57, 0xAE, 0x55, 0xF6, 0xCF, 0x6A, 0xF0, 0x10, 0xDC, 0xF4, 0xED,
+0xCC, 0x32, 0x4B, 0xAC, 0xC1, 0x4B, 0x2F, 0x62, 0x69, 0xD2, 0x15, 0x63, 0x39, 0xD5, 0x29, 0x09,
+0xA2, 0xB5, 0xC7, 0xBC, 0xFA, 0xC7, 0xC7, 0x8C, 0x64, 0xCF, 0x43, 0x9B, 0x4C, 0x60, 0x97, 0x33,
+0xA2, 0xB9, 0x0F, 0x70, 0x05, 0x89, 0x56, 0x62, 0xB1, 0x48, 0x08, 0xB5, 0x77, 0x4C, 0x60, 0x24,
+0x1D, 0x35, 0xEF, 0xD6, 0x53, 0xB0, 0x2E, 0x7F, 0xA6, 0x4B, 0x94, 0xE7, 0xCD, 0xC4, 0xFE, 0xC4,
+0x12, 0x7A, 0xAB, 0xD4, 0x05, 0xA5, 0x32, 0xD4, 0xA1, 0x8D, 0x9C, 0x22, 0x10, 0xDD, 0x39, 0x66,
+0x96, 0x79, 0x49, 0x19, 0x80, 0x1C, 0xE1, 0x1F, 0x01, 0x69, 0x37, 0x03, 0xB5, 0x22, 0x8F, 0x95,
+0xF7, 0xBD, 0x36, 0x89, 0x38, 0x37, 0x29, 0x6C, 0x0E, 0x89, 0x55, 0x4D, 0xC9, 0x64, 0xD3, 0xD5,
+0x9B, 0xB0, 0x51, 0x43, 0xBB, 0xA6, 0x6B, 0xFF, 0x13, 0xB6, 0x1A, 0x06, 0xF3, 0x86, 0x51, 0xFD,
+0xB9, 0xC8, 0x26, 0xA9, 0x8A, 0x4A, 0xC1, 0xE0, 0xD9, 0x3D, 0x31, 0x48, 0x39, 0xC8, 0x48, 0xC7,
+0xDE, 0xB1, 0x58, 0x0F, 0x4D, 0xEC, 0x5B, 0x32, 0x9C, 0x8B, 0xF4, 0x3A, 0x02, 0xE2, 0x92, 0x4A,
+0x7D, 0xCD, 0x38, 0x07, 0x4F, 0xBA, 0xD1, 0xD4, 0xE4, 0x3C, 0xB0, 0x4D, 0xB7, 0xEF, 0xFB, 0x06,
+0xA9, 0x83, 0x20, 0x0D, 0x7A, 0x1F, 0x15, 0x02, 0x70, 0x08, 0x8B, 0x91, 0xE6, 0xFD, 0x8C, 0x0B,
+0x3C, 0xEA, 0x1F, 0x94, 0xB6, 0x17, 0xC6, 0xB2, 0x07, 0x2C, 0x73, 0x7A, 0x4A, 0x76, 0x5F, 0x30,
+0x38, 0xE5, 0x22, 0xC6, 0xA3, 0xA7, 0x4D, 0x6A, 0x3A, 0xA7, 0x82, 0x90, 0xBE, 0xD1, 0xE9, 0x89,
+0x2F, 0xF0, 0xC9, 0x0A, 0xB6, 0xDA, 0x0D, 0x3E, 0x25, 0x8E, 0x99, 0xB2, 0x06, 0xE3, 0x65, 0x53,
+0x3F, 0x1A, 0xD9, 0x45, 0xCE, 0x10, 0xBE, 0x2E, 0xF4, 0x4F, 0x60, 0x25, 0xA7, 0x0A, 0xAE, 0x82,
+0x92, 0xAE, 0xC0, 0xFF, 0xAB, 0x49, 0x97, 0x5C, 0x53, 0x73, 0x4E, 0x78, 0x1A, 0x65, 0x42, 0xD5,
+0x6F, 0x1E, 0xE2, 0x25, 0x76, 0x3B, 0x6D, 0xF8, 0xBC, 0xBD, 0x3A, 0xDE, 0xB5, 0xFB, 0xBD, 0x90,
+0xDC, 0xC2, 0xB8, 0x90, 0xD4, 0x03, 0xD2, 0xDD, 0x35, 0x86, 0x48, 0x58, 0xB4, 0xCB, 0x10, 0xB2,
+0x31, 0xBD, 0x6C, 0x16, 0x92, 0x7A, 0x3D, 0x67, 0x45, 0x6B, 0x57, 0x26, 0xD2, 0xC2, 0xAF, 0xB1,
+0xAB, 0x82, 0x4B, 0x95, 0x08, 0x7D, 0x48, 0x1D, 0x17, 0x9D, 0x8B, 0x16, 0xCF, 0xE0, 0x16, 0x94,
+0xE1, 0xA6, 0xFC, 0x6C, 0xE1, 0x71, 0x3C, 0x57, 0x7F, 0x17, 0xC8, 0x4E, 0xFF, 0x16, 0x46, 0x1E,
+0x21, 0x27, 0x05, 0x41, 0xD3, 0x19, 0x28, 0x58, 0x86, 0xFB, 0x5A, 0xEF, 0xC3, 0x00, 0xE7, 0xA3,
+0x25, 0x1A, 0x94, 0x41, 0xE3, 0x50, 0x98, 0x94, 0x29, 0x42, 0x1F, 0x1C, 0x69, 0x46, 0xF4, 0x89,
+0x30, 0x4E, 0x5C, 0xCE, 0x2F, 0x65, 0xC5, 0x34, 0x71, 0xB7, 0xD9, 0x54, 0xB2, 0xC1, 0xCC, 0xED,
+0x14, 0x3E, 0xF1, 0x7B, 0x5F, 0xAE, 0xD3, 0x8F, 0xA2, 0x18, 0x12, 0x15, 0x23, 0x92, 0x75, 0x61,
+0xFF, 0xFA, 0x8F, 0xD1, 0x77, 0xC8, 0xC7, 0xA3, 0x44, 0x9F, 0x06, 0x2B, 0x1E, 0xA4, 0x4D, 0x4F,
+0x8E, 0x9A, 0x02, 0xA8, 0x4A, 0x67, 0x5D, 0x2D, 0x59, 0xFD, 0x1A, 0x8F, 0xE6, 0x52, 0x0C, 0xC7,
+0x4A, 0x95, 0xAF, 0xDD, 0x04, 0x76, 0x26, 0xCE, 0x4C, 0x97, 0x4E, 0x55, 0x9C, 0x28, 0xA4, 0x1D,
+0x92, 0xD6, 0x84, 0x87, 0x29, 0x28, 0x16, 0x1B, 0x34, 0xE3, 0xBD, 0x2F, 0x9B, 0xF8, 0x6F, 0xDC,
+0x9B, 0x6C, 0xF5, 0xEB, 0x26, 0x51, 0x47, 0x78, 0xA2, 0xB5, 0x4C, 0x24, 0x1E, 0x3D, 0xE5, 0x33,
+0xA3, 0xD9, 0x04, 0x20, 0x8E, 0xA7, 0x32, 0x88, 0xC6, 0x52, 0x0B, 0x71, 0x0D, 0x26, 0xC3, 0x3F,
+0xC4, 0xC8, 0x7F, 0x6F, 0x3A, 0xAD, 0xC7, 0x27, 0x3D, 0xB3, 0xE6, 0x6B, 0x68, 0x66, 0xB3, 0xEE,
+0x6D, 0xC7, 0xAB, 0xD4, 0xA2, 0x88, 0xAF, 0xEB, 0x1A, 0x51, 0x76, 0x19, 0xFC, 0xF7, 0x29, 0xF0,
+0x4D, 0xC5, 0xAB, 0x42, 0x81, 0x9F, 0x10, 0xD9, 0xB0, 0x5C, 0x9D, 0x1A, 0x5A, 0xFE, 0xB3, 0x71,
+0xBC, 0x13, 0x69, 0xDA, 0xCE, 0x15, 0x7C, 0x18, 0x2C, 0x81, 0xFC, 0xA9, 0x1E, 0x0B, 0x33, 0xBF,
+0x82, 0x0D, 0xD5, 0x58, 0xD0, 0xB6, 0x17, 0x34, 0xFE, 0x53, 0x45, 0xE7, 0x57, 0x9B, 0xFA, 0x3C,
+0x04, 0xCF, 0x89, 0x38, 0x73, 0xE9, 0x60, 0xEA, 0xF4, 0x0F, 0xB2, 0x2E, 0x90, 0x60, 0xAE, 0xFB,
+0x57, 0xCB, 0xA5, 0x9D, 0x60, 0x44, 0x46, 0x13, 0x3C, 0xB3, 0xB6, 0x0A, 0x09, 0x12, 0x2B, 0x27,
+0x95, 0x45, 0x29, 0x92, 0x86, 0x00, 0x2A, 0x93, 0x77, 0x8D, 0xAA, 0xC3, 0xF8, 0x46, 0xBE, 0x3A,
+0x6A, 0x0E, 0x51, 0x9D, 0x94, 0x60, 0x9A, 0x76, 0x93, 0xF4, 0x01, 0x19, 0xC3, 0xB1, 0x86, 0xA9,
+0x7E, 0xD1, 0xF6, 0xF1, 0x88, 0x59, 0x4E, 0x9F, 0xCC, 0xF2, 0xF7, 0xDD, 0x1B, 0x91, 0x98, 0xAC,
+0xCC, 0xC6, 0x81, 0x57, 0x3F, 0x07, 0xF2, 0x52, 0x5B, 0x79, 0x5D, 0xFB, 0x07, 0xF7, 0x6A, 0x62,
+0x30, 0xE5, 0x77, 0x81, 0x00, 0x6C, 0xB1, 0x11, 0x8A, 0x1D, 0x0C, 0x9C, 0x94, 0x1A, 0xAD, 0xB6,
+0x85, 0x29, 0x70, 0x19, 0xFB, 0xE1, 0xF5, 0x89, 0x6D, 0xB3, 0x84, 0xC5, 0x56, 0x14, 0x1E, 0x67,
+0x46, 0x57, 0xFE, 0x30, 0xD0, 0x81, 0x2B, 0x27, 0xD6, 0x4B, 0x41, 0x74, 0xF3, 0x51, 0xD0, 0x78,
+0xCE, 0x3A, 0x5C, 0x46, 0xCC, 0xCE, 0x19, 0xC9, 0xC3, 0x1A, 0x81, 0xF4, 0x62, 0x9A, 0x8B, 0xAD,
+0x71, 0x9C, 0x3E, 0x5B, 0x23, 0xA7, 0x9F, 0x7E, 0x26, 0xDD, 0x21, 0xCC, 0x36, 0x75, 0x90, 0x09,
+0x61, 0x0B, 0x85, 0xC1, 0x0A, 0xF4, 0x9D, 0x93, 0x9F, 0x5F, 0x73, 0x71, 0xAB, 0x2B, 0xFA, 0x5E,
+0xD9, 0xA1, 0xF8, 0x7F, 0x0F, 0xD5, 0x07, 0x59, 0xB2, 0x4F, 0xF9, 0x71, 0xD4, 0x35, 0x3E, 0x5D,
+0x85, 0x6A, 0x32, 0x76, 0xDB, 0xBE, 0xC5, 0xD4, 0x2B, 0xC5, 0x70, 0x95, 0x7C, 0x64, 0x04, 0x0E,
+0xC0, 0x4E, 0x59, 0x76, 0x10, 0xBF, 0x93, 0xBE, 0xEC, 0x40, 0x2C, 0xDE, 0x2D, 0xE6, 0xD1, 0x77,
+0xC7, 0x84, 0x4B, 0xD6, 0x1C, 0x9A, 0xA1, 0x93, 0xE4, 0x50, 0xA8, 0x1B, 0x73, 0x29, 0x92, 0xB0,
+0x37, 0x83, 0x15, 0xE3, 0xB5, 0xCD, 0xD1, 0x47, 0x38, 0xD1, 0xB6, 0xB6, 0x04, 0x3D, 0x58, 0x28,
+0xB1, 0xB5, 0x9E, 0xF3, 0x95, 0x12, 0x1A, 0xC2, 0xA1, 0x71, 0x72, 0x45, 0x35, 0x0F, 0xB8, 0xC4,
+0xEF, 0xF7, 0xAD, 0xD6, 0x82, 0x6A, 0x6A, 0x9E, 0x0E, 0xEF, 0xAB, 0xAD, 0x9D, 0x8D, 0xE4, 0x77,
+0xA1, 0x93, 0xAE, 0xE1, 0xBA, 0x0E, 0xAF, 0x83, 0xC4, 0x84, 0x19, 0x6E, 0x5B, 0x15, 0xD7, 0xAE,
+0x33, 0xA4, 0x37, 0xE2, 0xA1, 0x18, 0x2A, 0x4A, 0x9C, 0x5E, 0x7C, 0x61, 0x70, 0x76, 0xE9, 0xE6,
+0x0E, 0x11, 0xEE, 0x71, 0x45, 0xE0, 0x5E, 0x72, 0x3C, 0x88, 0x0C, 0x34, 0x34, 0x78, 0x39, 0xD7,
+0xFB, 0x26, 0x14, 0x1B, 0xCE, 0xEE, 0x15, 0x3C, 0xA4, 0x3F, 0xD3, 0x2A, 0x7C, 0x66, 0x58, 0xDD,
+0x56, 0x46, 0xAF, 0x14, 0x04, 0x35, 0x33, 0xD5, 0x83, 0xA0, 0x07, 0xE0, 0xC0, 0x4B, 0x9D, 0x36,
+0xF0, 0x72, 0x90, 0x7D, 0xFC, 0x4B, 0x3B, 0xDD, 0x07, 0x5E, 0xCD, 0xBE, 0x0B, 0x30, 0x78, 0x8C,
+0x9B, 0x4D, 0xFB, 0xB4, 0x95, 0xC4, 0xDE, 0x57, 0xB3, 0x07, 0xE6, 0x8F, 0x20, 0xE7, 0x54, 0x84,
+0xC8, 0x35, 0x3B, 0x68, 0x15, 0x74, 0x0F, 0x6A, 0xAB, 0xCC, 0x3E, 0x90, 0x6B, 0x38, 0x0A, 0xA8,
+0x5A, 0x3F, 0xF3, 0xAC, 0x27, 0x12, 0xFC, 0x04, 0xF6, 0x93, 0xB4, 0x84, 0xF2, 0x82, 0xED, 0xAE,
+0xF9, 0x64, 0x53, 0x1F, 0x9A, 0x2F, 0xAD, 0xB7, 0x2A, 0x17, 0x60, 0xFC, 0xDB, 0x07, 0xB1, 0x01,
+0xC9, 0xF8, 0x02, 0x5F, 0xF3, 0x5B, 0x5B, 0x90, 0xD4, 0x96, 0x92, 0x99, 0x36, 0x22, 0x53, 0xEA,
+0x62, 0xAE, 0xB0, 0x22, 0x6A, 0xAB, 0x24, 0xCD, 0x19, 0xBB, 0x86, 0x54, 0x17, 0x0F, 0x9D, 0x1A,
+0x4A, 0x3D, 0xE4, 0xF0, 0x0D, 0x03, 0xF2, 0x9A, 0x6D, 0x70, 0xEE, 0xA5, 0x51, 0x5F, 0xE8, 0x74,
+0xC1, 0xAC, 0x4B, 0xC6, 0x1C, 0x58, 0x26, 0x8F, 0xBF, 0xE1, 0x1D, 0xDB, 0x2D, 0xCA, 0x7E, 0x56,
+0xB9, 0x5E, 0x28, 0x4D, 0x63, 0x21, 0xDA, 0x20, 0xC5, 0xBB, 0xE3, 0x23, 0x92, 0x90, 0xB3, 0x2D,
+0xCE, 0x5B, 0x97, 0xF1, 0x66, 0x4A, 0x1D, 0xD0, 0xA4, 0x9E, 0x72, 0xD5, 0x3C, 0xC8, 0x7C, 0xCF,
+0x78, 0x1F, 0x5B, 0x34, 0x9B, 0xFF, 0x92, 0x71, 0xF5, 0x02, 0x0E, 0x01, 0xAC, 0x6A, 0x1E, 0xE0,
+0x2D, 0x15, 0x05, 0x40, 0x37, 0xF1, 0x7B, 0x24, 0xD8, 0x92, 0x5B, 0xE9, 0xEB, 0xD1, 0x7F, 0xC1,
+0xCE, 0x9C, 0xAA, 0x6A, 0x48, 0x38, 0x3A, 0xF5, 0x5A, 0x3F, 0x17, 0xFF, 0x45, 0x09, 0x1B, 0x40
+
+cipher_key =
+0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A,
+0xd0, 0xe7, 0x4b, 0xfb, 0x5d, 0xe5, 0x0c, 0xe7, 0x6f, 0x21, 0xb5, 0x52, 0x2a, 0xbb, 0xc7, 0xf7
+
+auth_key =
+0xaf, 0x96, 0x42, 0xf1, 0x8c, 0x50, 0xdc, 0x67, 0x1a, 0x43, 0x47, 0x62, 0xc7, 0x04, 0xab, 0x05,
+0xf5, 0x0c, 0xe7, 0xa2, 0xa6, 0x23, 0xd5, 0x3d, 0x95, 0xd8, 0xcd, 0x86, 0x79, 0xf5, 0x01, 0x47,
+0x4f, 0xf9, 0x1d, 0x9d, 0x36, 0xf7, 0x68, 0x1a, 0x64, 0x44, 0x58, 0x5d, 0xe5, 0x81, 0x15, 0x2a,
+0x41, 0xe4, 0x0e, 0xaa, 0x1f, 0x04, 0x21, 0xff, 0x2c, 0xf3, 0x73, 0x2b, 0x48, 0x1e, 0xd2, 0xf7,
+0xf6, 0xd9, 0xaf, 0xbf, 0x08, 0x3b, 0xbb, 0x19, 0x5f, 0xf6, 0x7d, 0x25, 0x85, 0xdf, 0x6b, 0x54,
+0xd0, 0xe7, 0x4b, 0x9e, 0xc7, 0xef, 0xca, 0x48, 0x6f, 0x21, 0xd7, 0x51, 0xc8, 0x21, 0xc1, 0x15,
+0xe8, 0x38, 0x36, 0x58, 0x39, 0xd9, 0x9a, 0xc5, 0xe7, 0x3b, 0xc4, 0x47, 0xe2, 0xbd, 0x80, 0x73,
+0xf8, 0xd1, 0x9a, 0x5e, 0x4b, 0xfb, 0x52, 0x6b, 0x50, 0xaf, 0x8b, 0xb7, 0xb5, 0x2c, 0x52, 0x84
+
+iv =
+0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+
+####################
+# sha_hmac_buff_32 #
+####################
+[sha1_hmac_buff_32]
+digest =
+0x36, 0xCA, 0x49, 0x6A, 0xE3, 0x54, 0xD8, 0x4F, 0x0B, 0x76, 0xD8, 0xAA, 0x78, 0xEB, 0x9D, 0x65,
+0x2C, 0xCA, 0x1F, 0x97
+
+[sha224_hmac_buff_32]
+digest =
+0x48, 0xC1, 0x45, 0x25, 0x29, 0xA0, 0x8B, 0x88, 0x72, 0x7A, 0xBC, 0x00, 0x94, 0x37, 0xE1, 0x22,
+0xEB, 0xFA, 0x1B, 0x7D, 0x89, 0x81, 0x31, 0xC8, 0x64, 0x76, 0x55, 0xA4
+
+[sha256_hmac_buff_32]
+digest =
+0x1C, 0xB2, 0x3D, 0xD1, 0xF9, 0xC7, 0x6C, 0x49, 0x2E, 0xDA, 0x94, 0x8B, 0xF1, 0xCF, 0x96, 0x43,
+0x67, 0x50, 0x39, 0x76, 0xB5, 0xA1, 0xCE, 0xA1, 0xD7, 0x77, 0x10, 0x07, 0x43, 0x37, 0x05, 0xB4
+
+[sha384_hmac_buff_32]
+digest =
+0x6C, 0xBD, 0x1E, 0x2E, 0x75, 0xA7, 0x2C, 0x98, 0xC4, 0x1E, 0x03, 0x4E, 0x39, 0x4B, 0x27, 0x41,
+0xFB, 0xC6, 0x56, 0x87, 0x84, 0xEB, 0xFA, 0xB1, 0x20, 0x1F, 0x11, 0x81, 0x8D, 0xDC, 0xB6, 0xA7,
+0xAD, 0x1F, 0xAC, 0xA9, 0x43, 0x1D, 0x2B, 0xEB, 0x5F, 0x27, 0xC6, 0x0F, 0x9E, 0xFB, 0x1E, 0xB1
+
+[sha512_hmac_buff_32]
+digest =
+0xA4, 0x60, 0x7E, 0xBE, 0x5F, 0x47, 0x58, 0x3B, 0x41, 0x5F, 0x29, 0xDF, 0xE4, 0xD2, 0xFB, 0x30,
+0xF0, 0x2B, 0x09, 0x4E, 0x09, 0x50, 0xEC, 0x1C, 0x0E, 0x34, 0x79, 0xAE, 0xD8, 0x6D, 0xAC, 0xB6,
+0x9B, 0x7C, 0xB9, 0x06, 0xC2, 0x4A, 0x4E, 0x22, 0x14, 0x4D, 0x42, 0x46, 0x20, 0xE0, 0x6C, 0xEE,
+0x2F, 0xE1, 0x23, 0xA2, 0x7A, 0x2F, 0xDB, 0xAF, 0x78, 0x75, 0x56, 0xF7, 0x3A, 0x5E, 0x74, 0xEF
+
+####################
+# sha_hmac_buff_64 #
+####################
+[sha1_hmac_buff_64]
+digest =
+0xFC, 0x17, 0x7E, 0x0E, 0x52, 0x94, 0xE3, 0x27, 0xC0, 0x9B, 0x72, 0xAD, 0xC0, 0x5B, 0xCF, 0xFF,
+0x65, 0x88, 0x43, 0xE7
+
+[sha224_hmac_buff_64]
+digest =
+0xD7, 0x55, 0x25, 0xC0, 0x26, 0xDD, 0x8E, 0x14, 0x17, 0x8B, 0x89, 0x59, 0x8A, 0xBB, 0xEA, 0xD6,
+0x7D, 0x85, 0x00, 0x9F, 0xC2, 0x8A, 0xCB, 0x01, 0x7F, 0x8C, 0x6E, 0x24
+
+[sha256_hmac_buff_64]
+digest =
+0x8F, 0x4B, 0x3B, 0x4C, 0x58, 0x25, 0x3B, 0x07, 0xEB, 0xF8, 0x20, 0x81, 0xD9, 0xD9, 0x92, 0x8F,
+0xF4, 0x32, 0x7C, 0x2A, 0xD9, 0xEC, 0x92, 0x60, 0x8F, 0xE3, 0x90, 0x7F, 0xC5, 0x75, 0x05, 0xB6
+
+[sha384_hmac_buff_64]
+digest =
+0xD1, 0xC7, 0x64, 0x27, 0xF0, 0x30, 0x43, 0x8E, 0xD6, 0xA6, 0x78, 0xF7, 0xE9, 0xCC, 0x8E, 0x69,
+0x6D, 0xB8, 0x3E, 0xFA, 0xA0, 0x81, 0x9C, 0x61, 0x78, 0x72, 0xF0, 0x1C, 0x29, 0x35, 0x51, 0x3E,
+0x4A, 0x95, 0xDE, 0x2C, 0x6A, 0x3F, 0x56, 0xA8, 0x12, 0xBA, 0x44, 0x39, 0x1E, 0xDB, 0xF7, 0xF5
+
+[sha512_hmac_buff_64]
+digest =
+0xE6, 0xE9, 0xD8, 0x1D, 0x90, 0xAE, 0x32, 0x0E, 0xBA, 0x55, 0x58, 0xD5, 0x55, 0x97, 0x40, 0xB3,
+0xE9, 0x12, 0xD3, 0x08, 0xEF, 0x21, 0xED, 0xA5, 0x94, 0x8D, 0xF2, 0x4C, 0x52, 0x2C, 0x50, 0xB2,
+0xD2, 0xEC, 0xB7, 0xE1, 0x95, 0x2D, 0x68, 0xDB, 0xAD, 0xB5, 0x94, 0x50, 0x67, 0xF3, 0x0A, 0x83,
+0x54, 0x03, 0x33, 0x1C, 0xD5, 0x42, 0x7D, 0xB4, 0x3E, 0x69, 0x7C, 0x36, 0x7E, 0x96, 0x0D, 0x3E
+
+#####################
+# sha_hmac_buff_128 #
+#####################
+[sha1_hmac_buff_128]
+digest =
+0xAA, 0x90, 0x55, 0xA5, 0x71, 0xC4, 0x2B, 0xA3, 0x02, 0xAA, 0xB1, 0x1C, 0xB3, 0x88, 0x38, 0x6E,
+0xAD, 0x26, 0x98, 0xA7
+
+[sha224_hmac_buff_128]
+digest =
+0xBE, 0xCC, 0x83, 0x48, 0x4C, 0x58, 0xF9, 0x86, 0xFA, 0x93, 0x5F, 0xD1, 0x3C, 0x11, 0x8A, 0x37,
+0xA6, 0xEE, 0x52, 0x4D, 0xA3, 0x98, 0x3E, 0x35, 0xF1, 0x4F, 0xD9, 0xDB
+
+[sha256_hmac_buff_128]
+digest =
+0xE2, 0x9C, 0xE1, 0xDF, 0xCD, 0xAE, 0x50, 0x4B, 0x9A, 0xA6, 0x41, 0xAC, 0x0C, 0xF1, 0x66, 0xED,
+0xA1, 0x22, 0x05, 0x72, 0x49, 0x97, 0xA1, 0x30, 0xB8, 0xF9, 0xED, 0x36, 0x0A, 0x19, 0xE4, 0x2A
+
+[sha384_hmac_buff_128]
+digest =
+0xD9, 0x3C, 0xEB, 0xF4, 0x20, 0xC6, 0x4F, 0xC7, 0xBD, 0x34, 0xBA, 0xFD, 0x7C, 0xA9, 0xCE, 0xFF,
+0x26, 0x2E, 0xB4, 0x4A, 0xB7, 0x47, 0x71, 0x2C, 0x9E, 0xCF, 0x44, 0x0B, 0xD9, 0xAF, 0x8D, 0x17,
+0x0A, 0x3A, 0x02, 0xD0, 0xE9, 0xDF, 0xCF, 0x52, 0x5F, 0xDA, 0xA7, 0xB6, 0x51, 0x7C, 0x59, 0x09
+
+[sha512_hmac_buff_128]
+digest =
+0xAD, 0x7E, 0xB7, 0x33, 0xFB, 0x8A, 0x17, 0xD0, 0x3C, 0xB0, 0x80, 0x19, 0xF3, 0x9A, 0x6F, 0x90,
+0xDE, 0xF3, 0x53, 0xEA, 0x48, 0x75, 0x0A, 0x1E, 0x49, 0x02, 0xA0, 0x94, 0xC4, 0xE8, 0xFB, 0x87,
+0x83, 0x80, 0xD3, 0xFF, 0x6B, 0x79, 0x73, 0x54, 0xF9, 0x2F, 0x2D, 0x59, 0x69, 0x0E, 0x50, 0x29,
+0x2A, 0xDA, 0x59, 0x38, 0xDD, 0x62, 0xF9, 0x1A, 0x18, 0xA9, 0x51, 0x5A, 0xFE, 0x8E, 0xFD, 0xBF
+
+#####################
+# sha_hmac_buff_256 #
+#####################
+[sha1_hmac_buff_256]
+digest =
+0xB1, 0x18, 0x31, 0xBF, 0xEE, 0x81, 0x7E, 0xFC, 0x68, 0xDA, 0xB6, 0x8A, 0x5D, 0xDE, 0x39, 0x65,
+0xC8, 0xF8, 0xC3, 0xE5
+
+[sha224_hmac_buff_256]
+digest =
+0xCD, 0xF6, 0xC2, 0x6D, 0xFD, 0x33, 0x1A, 0xD8, 0x2F, 0x07, 0x4F, 0x1A, 0xE8, 0x18, 0xBD, 0x04,
+0xB1, 0xE5, 0x8D, 0xC1, 0x21, 0x95, 0x87, 0x75, 0xC2, 0x27, 0x4B, 0xF2
+
+[sha256_hmac_buff_256]
+digest =
+0xC0, 0xFA, 0x8F, 0x6F, 0x55, 0xFC, 0xF3, 0xDF, 0x8E, 0x5D, 0x93, 0x5E, 0x6B, 0x20, 0x0A, 0x9A,
+0x84, 0x3D, 0xCD, 0x4B, 0x57, 0x63, 0x2D, 0x93, 0x51, 0x45, 0xF2, 0x1E, 0xC7, 0xA4, 0xD4, 0x69
+
+[sha384_hmac_buff_256]
+digest =
+0x2B, 0x92, 0x9E, 0x85, 0x5A, 0x89, 0xB5, 0x12, 0x4A, 0x9B, 0x2D, 0xD2, 0xB2, 0x3E, 0xAB, 0xC1,
+0x1E, 0x7F, 0x53, 0xD9, 0x88, 0xEB, 0xEE, 0xA2, 0x49, 0x14, 0xDE, 0x1A, 0x9E, 0x20, 0xCE, 0xEC,
+0x7A, 0x5D, 0x25, 0xD8, 0x8F, 0xFE, 0x8B, 0xB1, 0xB1, 0x04, 0x5F, 0x46, 0x2D, 0x34, 0x2D, 0x72
+
+[sha512_hmac_buff_256]
+digest =
+0x4F, 0x96, 0x89, 0x9E, 0x9D, 0x53, 0xAC, 0x05, 0xC7, 0xA0, 0x0F, 0x4D, 0xB6, 0x3E, 0x06, 0x03,
+0x19, 0x68, 0x41, 0x4F, 0x11, 0x57, 0x77, 0x21, 0xBD, 0x60, 0x3E, 0xB4, 0xFE, 0x6A, 0x0D, 0xBF,
+0xE0, 0x4F, 0x32, 0x5B, 0xF9, 0xDF, 0x13, 0xBD, 0x02, 0x73, 0xD4, 0x0C, 0xE9, 0x9D, 0xB7, 0xD5,
+0x38, 0xA0, 0x20, 0xD9, 0xD1, 0x66, 0x17, 0x19, 0x54, 0x36, 0x18, 0xE1, 0xF5, 0x34, 0x12, 0x9E
+
+#####################
+# sha_hmac_buff_512 #
+#####################
+[sha1_hmac_buff_512]
+digest =
+0x78, 0x14, 0x01, 0xED, 0x93, 0x6F, 0x22, 0xB6, 0x96, 0x5A, 0x32, 0x05, 0xA9, 0xD3, 0x49, 0x04,
+0x55, 0xB0, 0x00, 0x06
+
+[sha224_hmac_buff_512]
+digest =
+0x25, 0xD4, 0x8F, 0x92, 0xE1, 0xD0, 0x4E, 0x3F, 0x34, 0x38, 0x01, 0xB8, 0xFE, 0x57, 0x3D, 0x34,
+0x39, 0x98, 0x82, 0x8D, 0x68, 0x04, 0x5A, 0x74, 0x28, 0x4F, 0x18, 0xCE
+
+[sha256_hmac_buff_512]
+digest =
+0x90, 0x06, 0x97, 0x8A, 0x7A, 0xEF, 0x62, 0x14, 0x4C, 0x14, 0xAA, 0x25, 0x4C, 0xE3, 0x5D, 0xE4,
+0xAD, 0x6C, 0xD6, 0x82, 0x2B, 0x87, 0x53, 0x3E, 0xE9, 0xE4, 0x97, 0x82, 0x82, 0x76, 0xE7, 0xF1
+
+[sha384_hmac_buff_512]
+digest =
+0xD5, 0xDA, 0x7C, 0x8A, 0x0D, 0x1B, 0xBE, 0x3E, 0x25, 0x1E, 0x6C, 0xA4, 0x50, 0x32, 0x92, 0x13,
+0x91, 0x4F, 0xA2, 0x29, 0x2A, 0x0A, 0x57, 0x62, 0x3D, 0x93, 0xF2, 0x45, 0x96, 0x22, 0xF8, 0x0D,
+0xA9, 0xE9, 0xAB, 0xAC, 0x7B, 0x2E, 0x42, 0xC2, 0x3E, 0x75, 0x23, 0xD0, 0xD2, 0xAA, 0x1E, 0xEE
+
+[sha512_hmac_buff_512]
+digest =
+0x57, 0x34, 0x65, 0x3D, 0xDE, 0x8B, 0x7B, 0x99, 0x62, 0x24, 0xF3, 0xAF, 0xA6, 0xB1, 0xF0, 0x01,
+0x23, 0xD4, 0x94, 0xC2, 0x06, 0x70, 0xA5, 0x8C, 0x80, 0x93, 0x49, 0x88, 0xB4, 0xB6, 0x45, 0xE5,
+0x37, 0xC9, 0xE4, 0xA1, 0xAB, 0x6C, 0xA5, 0x23, 0xD2, 0x07, 0x9B, 0x10, 0x4D, 0xFD, 0x75, 0xC0,
+0x28, 0xA1, 0x8A, 0x84, 0x03, 0x35, 0x22, 0xCC, 0xAC, 0x6C, 0x97, 0x93, 0x57, 0x08, 0x48, 0x51
+
+######################
+# sha_hmac_buff_1024 #
+######################
+[sha1_hmac_buff_1024]
+digest =
+0x74, 0xF7, 0x91, 0x04, 0x06, 0xDB, 0xA9, 0xF0, 0x08, 0x0E, 0x93, 0xCE, 0x55, 0xA8, 0x54, 0xF0,
+0x4B, 0x5E, 0x3F, 0xC7
+
+[sha224_hmac_buff_1024]
+digest =
+0x45, 0xDA, 0x2E, 0x83, 0xBD, 0x35, 0xA4, 0x58, 0x14, 0x74, 0xCB, 0xA4, 0x48, 0xA6, 0xBA, 0xDC,
+0x7D, 0x56, 0x6A, 0x44, 0xA7, 0xE9, 0x2F, 0x75, 0x20, 0x47, 0x2A, 0x5A
+
+[sha256_hmac_buff_1024]
+digest =
+0xA2, 0x81, 0xFE, 0x1A, 0x5C, 0x4F, 0x02, 0x72, 0xEF, 0x4F, 0xC6, 0xEE, 0x54, 0x71, 0x69, 0xAF,
+0x5C, 0x71, 0x9F, 0xB0, 0xAC, 0x5B, 0x7F, 0x51, 0xD6, 0x0D, 0x64, 0xD2, 0x2E, 0x0E, 0x30, 0x55
+
+[sha384_hmac_buff_1024]
+digest =
+0x26, 0x44, 0x13, 0x01, 0x25, 0x6E, 0xC7, 0xC3, 0x88, 0x25, 0xD5, 0xDD, 0x1D, 0xCA, 0x0C, 0xB1,
+0xB8, 0x82, 0xB2, 0xB8, 0x15, 0x3F, 0xE5, 0x54, 0x43, 0x47, 0x32, 0x3B, 0xB2, 0xE0, 0xC8, 0x58,
+0x64, 0xE7, 0x78, 0xC9, 0x1F, 0x81, 0x7B, 0xBD, 0x0D, 0x6D, 0x37, 0x9C, 0x01, 0x20, 0x6A, 0x8E
+
+[sha512_hmac_buff_1024]
+digest =
+0xBE, 0xDA, 0x0D, 0x3B, 0x47, 0x24, 0xBA, 0x45, 0xBA, 0xCA, 0x84, 0x5F, 0xEA, 0xAC, 0x33, 0x84,
+0x00, 0x62, 0xA5, 0x29, 0xB6, 0x2F, 0xB7, 0x86, 0xD0, 0x94, 0xFF, 0xFF, 0xE4, 0x1E, 0x5C, 0xFD,
+0xC8, 0xD5, 0x3A, 0xD4, 0xFC, 0xA6, 0x1C, 0x66, 0x4A, 0x6D, 0xF9, 0x2B, 0x1D, 0x7F, 0xA0, 0xCF,
+0x3D, 0x0F, 0x1F, 0x5B, 0xDD, 0x21, 0x12, 0xA8, 0x76, 0xB0, 0xD7, 0x30, 0x66, 0xA6, 0xA0, 0x6C
+
+######################
+# sha_hmac_buff_2048 #
+######################
+[sha1_hmac_buff_2048]
+digest =
+0x99, 0x32, 0xCD, 0xC3, 0xC9, 0x7F, 0x98, 0x1A, 0x96, 0xF6, 0x52, 0xC8, 0xA2, 0x16, 0x9C, 0x29,
+0x9D, 0x6E, 0x96, 0xF5
+
+[sha224_hmac_buff_2048]
+digest =
+0x1A, 0xC4, 0xDC, 0x46, 0xE5, 0x87, 0xFE, 0xE0, 0x47, 0x64, 0x53, 0xA3, 0x6A, 0x1F, 0x78, 0xC0,
+0xC0, 0x02, 0x03, 0x64, 0xB1, 0x55, 0x50, 0x66, 0xDA, 0xD6, 0x9E, 0xBC
+
+[sha256_hmac_buff_2048]
+digest =
+0xA6, 0xC6, 0x4B, 0x0C, 0x95, 0xDE, 0xD5, 0xE2, 0x40, 0x7D, 0x44, 0xC5, 0xBF, 0x00, 0x5A, 0xFB,
+0x6F, 0x3F, 0x5E, 0x69, 0xB1, 0x32, 0x91, 0xAB, 0x6C, 0x90, 0x25, 0xAB, 0xD9, 0x1B, 0x8F, 0x80
+
+[sha384_hmac_buff_2048]
+digest =
+0x16, 0xF1, 0x1B, 0xC1, 0x22, 0xDB, 0x21, 0x90, 0x08, 0xE3, 0x42, 0x0C, 0x9A, 0xF1, 0x0F, 0xF8,
+0x7A, 0xE9, 0x50, 0x09, 0xC6, 0x0C, 0x71, 0x65, 0x3A, 0x40, 0xB3, 0x78, 0x11, 0xE8, 0xD2, 0xD4,
+0xB0, 0x6C, 0xA9, 0x6A, 0x0C, 0xCD, 0xE1, 0x70, 0x7E, 0x90, 0x86, 0x34, 0xC1, 0x08, 0x9E, 0xFC
+
+[sha512_hmac_buff_2048]
+digest =
+0xDF, 0x7F, 0xC3, 0x26, 0x3E, 0x55, 0x80, 0x7D, 0x02, 0x06, 0x5A, 0x4B, 0x8C, 0xFD, 0x2F, 0x33,
+0xF8, 0x0E, 0x9C, 0x59, 0xAE, 0x56, 0xAE, 0x86, 0xA9, 0x25, 0x3F, 0xB7, 0xF7, 0x4C, 0x7A, 0xB4,
+0xD8, 0x0E, 0x43, 0xC0, 0x86, 0xDF, 0xDB, 0xBA, 0xA8, 0xCB, 0x46, 0x2A, 0x92, 0x34, 0xF5, 0x3B,
+0xBD, 0x59, 0x64, 0xDF, 0x30, 0x20, 0xF5, 0x13, 0xD7, 0x78, 0xB9, 0x27, 0xE6, 0xB6, 0x56, 0x19
\ No newline at end of file
diff --git a/app/test-crypto-perf/main.c b/app/test-crypto-perf/main.c
new file mode 100644
index 0000000..4d75485
--- /dev/null
+++ b/app/test-crypto-perf/main.c
@@ -0,0 +1,411 @@
+#include <stdio.h>
+#include <unistd.h>
+
+#include <rte_eal.h>
+#include <rte_cryptodev.h>
+
+#include "cperf.h"
+#include "cperf_options.h"
+#include "cperf_test_vector_parsing.h"
+#include "cperf_test_throughput.h"
+#include "cperf_test_latency.h"
+
+const char *cperf_test_type_strs[] = {
+ [CPERF_TEST_TYPE_THROUGHPUT] = "throughput",
+ [CPERF_TEST_TYPE_CYCLECOUNT] = "cycle-count",
+ [CPERF_TEST_TYPE_LATENCY] = "latency"
+};
+
+const char *cperf_op_type_strs[] = {
+ [CPERF_CIPHER_ONLY] = "cipher-only",
+ [CPERF_AUTH_ONLY] = "auth-only",
+ [CPERF_CIPHER_THEN_AUTH] = "cipher-then-auth",
+ [CPERF_AUTH_THEN_CIPHER] = "auth-then-cipher",
+ [CPERF_AEAD] = "aead"
+};
+
+const struct cperf_test cperf_testmap[] = {
+ [CPERF_TEST_TYPE_THROUGHPUT] = {
+ cperf_throughput_test_constructor,
+ cperf_throughput_test_runner,
+ cperf_throughput_test_destructor
+ },
+ [CPERF_TEST_TYPE_CYCLECOUNT] = { NULL },
+ [CPERF_TEST_TYPE_LATENCY] = {
+ cperf_latency_test_constructor,
+ cperf_latency_test_runner,
+ cperf_latency_test_destructor
+ }
+};
+
+static int
+cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs)
+{
+ uint8_t cdev_id, enabled_cdev_count = 0, nb_lcores;
+ int ret;
+
+ enabled_cdev_count = rte_cryptodev_devices_get(opts->device_type,
+ enabled_cdevs, RTE_DIM(enabled_cdevs));
+ if (enabled_cdev_count == 0) {
+ printf("No crypto devices type %s available\n",
+ opts->device_type);
+ return -EINVAL;
+ }
+
+ nb_lcores = rte_lcore_count() - 1;
+
+ if (enabled_cdev_count > nb_lcores) {
+ printf("Number of capable crypto devices (%d) "
+ "has to be less or equal to number of slave "
+ "cores (%d)\n", enabled_cdev_count, nb_lcores);
+ return -EINVAL;
+ }
+
+ for (cdev_id = 0; cdev_id < enabled_cdev_count &&
+ cdev_id < RTE_CRYPTO_MAX_DEVS; cdev_id++) {
+
+ struct rte_cryptodev_config conf = {
+ .nb_queue_pairs = 1,
+ .socket_id = SOCKET_ID_ANY,
+ .session_mp = {
+ .nb_objs = 2048,
+ .cache_size = 64
+ }
+ };
+ struct rte_cryptodev_qp_conf qp_conf = {
+ .nb_descriptors = 2048
+ };
+
+ ret = rte_cryptodev_configure(enabled_cdevs[cdev_id], &conf);
+ if (ret < 0) {
+ printf("Failed to configure cryptodev %u",
+ enabled_cdevs[cdev_id]);
+ return -EINVAL;
+ }
+
+ ret = rte_cryptodev_queue_pair_setup(enabled_cdevs[cdev_id], 0,
+ &qp_conf, SOCKET_ID_ANY);
+ if (ret < 0) {
+ printf("Failed to setup queue pair %u on "
+ "cryptodev %u", 0, cdev_id);
+ return -EINVAL;
+ }
+
+ ret = rte_cryptodev_start(enabled_cdevs[cdev_id]);
+ if (ret < 0) {
+ printf("Failed to start device %u: error %d\n",
+ enabled_cdevs[cdev_id], ret);
+ return -EPERM;
+ }
+ }
+
+ return enabled_cdev_count;
+}
+
+static int
+cperf_verify_devices_capabilities(struct cperf_options *opts,
+ uint8_t *enabled_cdevs, uint8_t nb_cryptodevs)
+{
+ struct rte_cryptodev_capability_idx cap_idx;
+ const struct rte_cryptodev_symmetric_capability *capability;
+
+ uint8_t i, cdev_id;
+ int ret;
+
+ for (i = 0; i < nb_cryptodevs; i++) {
+
+ cdev_id = enabled_cdevs[i];
+
+ if (opts->op_type == CPERF_AUTH_ONLY ||
+ opts->op_type == CPERF_CIPHER_THEN_AUTH ||
+ opts->op_type == CPERF_AUTH_THEN_CIPHER) {
+
+ cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
+ cap_idx.algo.auth = opts->auth_algo;
+
+ capability = rte_cryptodev_capability_get(cdev_id,
+ &cap_idx);
+ if (capability == NULL)
+ return -1;
+
+ ret = rte_cryptodev_capability_check_auth(capability,
+ opts->auth_key_sz, opts->auth_digest_sz,
+ opts->auth_aad_sz);
+ if (ret != 0)
+ return ret;
+ }
+
+ if (opts->op_type == CPERF_CIPHER_ONLY ||
+ opts->op_type == CPERF_CIPHER_THEN_AUTH ||
+ opts->op_type == CPERF_AUTH_THEN_CIPHER) {
+
+ cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+ cap_idx.algo.cipher = opts->cipher_algo;
+
+ capability = rte_cryptodev_capability_get(cdev_id,
+ &cap_idx);
+ if (capability == NULL)
+ return -1;
+
+ ret = rte_cryptodev_capability_check_cipher(capability,
+ opts->cipher_key_sz,
+ opts->cipher_iv_sz);
+ if (ret != 0)
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int
+cperf_check_test_vector(struct cperf_options opts,
+ struct cperf_test_vector test_vec)
+{
+ if (opts.op_type == CPERF_CIPHER_ONLY) {
+ if (opts.cipher_algo == RTE_CRYPTO_CIPHER_NULL) {
+ if (test_vec.plaintext.data == NULL)
+ return -1;
+ } else if (opts.cipher_algo != RTE_CRYPTO_CIPHER_NULL) {
+ if (test_vec.plaintext.data == NULL)
+ return -1;
+ if (test_vec.plaintext.length != opts.buffer_sz)
+ return -1;
+ if (test_vec.ciphertext.data == NULL)
+ return -1;
+ if (test_vec.ciphertext.length != opts.buffer_sz)
+ return -1;
+ if (test_vec.iv.data == NULL)
+ return -1;
+ if (test_vec.iv.length != opts.cipher_iv_sz)
+ return -1;
+ if (test_vec.cipher_key.data == NULL)
+ return -1;
+ if (test_vec.cipher_key.length != opts.cipher_key_sz)
+ return -1;
+ }
+ } else if (opts.op_type == CPERF_AUTH_ONLY) {
+ if (opts.auth_algo != RTE_CRYPTO_AUTH_NULL) {
+ if (test_vec.plaintext.data == NULL)
+ return -1;
+ if (test_vec.plaintext.length != opts.buffer_sz)
+ return -1;
+ if (test_vec.auth_key.data == NULL)
+ return -1;
+ if (test_vec.auth_key.length != opts.auth_key_sz)
+ return -1;
+ if (test_vec.digest.data == NULL)
+ return -1;
+ if (test_vec.digest.length != opts.auth_digest_sz)
+ return -1;
+ }
+
+ } else if (opts.op_type == CPERF_CIPHER_THEN_AUTH ||
+ opts.op_type == CPERF_AUTH_THEN_CIPHER) {
+ if (opts.cipher_algo == RTE_CRYPTO_CIPHER_NULL) {
+ if (test_vec.plaintext.data == NULL)
+ return -1;
+ if (test_vec.plaintext.length != opts.buffer_sz)
+ return -1;
+ } else if (opts.cipher_algo != RTE_CRYPTO_CIPHER_NULL) {
+ if (test_vec.plaintext.data == NULL)
+ return -1;
+ if (test_vec.plaintext.length != opts.buffer_sz)
+ return -1;
+ if (test_vec.ciphertext.data == NULL)
+ return -1;
+ if (test_vec.ciphertext.length != opts.buffer_sz)
+ return -1;
+ if (test_vec.iv.data == NULL)
+ return -1;
+ if (test_vec.iv.length != opts.cipher_iv_sz)
+ return -1;
+ if (test_vec.cipher_key.data == NULL)
+ return -1;
+ if (test_vec.cipher_key.length != opts.cipher_key_sz)
+ return -1;
+ }
+ if (opts.auth_algo != RTE_CRYPTO_AUTH_NULL) {
+ if (test_vec.auth_key.data == NULL)
+ return -1;
+ if (test_vec.auth_key.length != opts.auth_key_sz)
+ return -1;
+ if (test_vec.digest.data == NULL)
+ return -1;
+ if (test_vec.digest.length != opts.auth_digest_sz)
+ return -1;
+ }
+ } else if (opts.op_type == CPERF_AEAD) {
+ if (test_vec.plaintext.data == NULL)
+ return -1;
+ if (test_vec.plaintext.length != opts.buffer_sz)
+ return -1;
+ if (test_vec.aad.data == NULL)
+ return -1;
+ if (test_vec.aad.length != opts.auth_aad_sz)
+ return -1;
+ if (test_vec.digest.data == NULL)
+ return -1;
+ if (test_vec.digest.length != opts.auth_digest_sz)
+ return -1;
+ }
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ struct cperf_options opts;
+ struct cperf_test_vector *t_vec = NULL;
+ const struct cperf_op_fns *op_fns;
+
+ void *ctx[RTE_MAX_LCORE] = { };
+
+ uint8_t nb_cryptodevs, cdev_id, i;
+ uint8_t enabled_cdevs[RTE_CRYPTO_MAX_DEVS] = { 0 };
+
+ int ret;
+ uint32_t lcore_id;
+
+ /* Initialise DPDK EAL */
+ ret = rte_eal_init(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Invalid EAL arguments!\n");
+ argc -= ret;
+ argv += ret;
+
+ cperf_options_default(&opts);
+
+ ret = cperf_options_parse(&opts, argc, argv);
+ if (ret) {
+ RTE_LOG(ERR, USER1, "Parsing on or more user options failed\n");
+ goto err;
+ }
+
+ ret = cperf_options_check(&opts);
+ if (ret) {
+ RTE_LOG(ERR, USER1,
+ "Checking on or more user options failed\n");
+ goto err;
+ }
+
+ if (!opts.silent)
+ cperf_options_dump(&opts);
+
+ nb_cryptodevs = cperf_initialize_cryptodev(&opts, enabled_cdevs);
+ if (nb_cryptodevs < 1) {
+ RTE_LOG(ERR, USER1, "Failed to initialise requested crypto "
+ "device type\n");
+ goto err;
+ }
+
+ ret = cperf_verify_devices_capabilities(&opts, enabled_cdevs,
+ nb_cryptodevs);
+ if (ret) {
+ RTE_LOG(ERR, USER1, "Crypto device type does not support "
+ "capabilities requested\n");
+ goto err;
+ }
+
+ if (opts.test_file != NULL) {
+ t_vec = cperf_test_vector_get_from_file(&opts);
+ if (t_vec == NULL) {
+ RTE_LOG(ERR, USER1,
+ "Failed to create test vector for"
+ " specified file\n");
+ goto err;
+ }
+
+ if (cperf_check_test_vector(opts, *t_vec)) {
+ RTE_LOG(ERR, USER1, "Incomplete necessary test vectors"
+ "\n");
+ goto err;
+ }
+ } else {
+ t_vec = cperf_test_vector_get_dummy(&opts);
+ if (t_vec == NULL) {
+ RTE_LOG(ERR, USER1,
+ "Failed to create test vector for"
+ " specified algorithms\n");
+ goto err;
+ }
+ }
+
+ op_fns = cperf_get_op_functions(&opts);
+ if (op_fns == NULL) {
+ RTE_LOG(ERR, USER1, "Failed to find function ops set for "
+ "specified algorithms combination\n");
+ goto err;
+ }
+
+ if (!opts.silent)
+ show_test_vector(t_vec);
+
+ i = 0;
+ RTE_LCORE_FOREACH_SLAVE(lcore_id) {
+
+ if (i == nb_cryptodevs)
+ break;
+
+ cdev_id = enabled_cdevs[i];
+
+ ctx[cdev_id] = cperf_testmap[opts.test].constructor(cdev_id, 0,
+ &opts, t_vec, op_fns);
+ if (ctx[cdev_id] == NULL) {
+ RTE_LOG(ERR, USER1, "Test run constructor failed\n");
+ goto err;
+ }
+ i++;
+ }
+
+ i = 0;
+ RTE_LCORE_FOREACH_SLAVE(lcore_id) {
+
+ if (i == nb_cryptodevs)
+ break;
+
+ cdev_id = enabled_cdevs[i];
+
+ rte_eal_remote_launch(cperf_testmap[opts.test].runner,
+ ctx[cdev_id], lcore_id);
+ i++;
+ }
+
+ rte_eal_mp_wait_lcore();
+
+ i = 0;
+ RTE_LCORE_FOREACH_SLAVE(lcore_id) {
+
+ if (i == nb_cryptodevs)
+ break;
+
+ cdev_id = enabled_cdevs[i];
+
+ cperf_testmap[opts.test].destructor(ctx[cdev_id]);
+ i++;
+ }
+
+ free_test_vector(t_vec, &opts);
+
+ printf("\n");
+ return EXIT_SUCCESS;
+
+err:
+ i = 0;
+ RTE_LCORE_FOREACH_SLAVE(lcore_id) {
+
+ if (i == nb_cryptodevs)
+ break;
+
+ cdev_id = enabled_cdevs[i];
+
+ if (ctx[cdev_id] && cperf_testmap[opts.test].destructor)
+ cperf_testmap[opts.test].destructor(ctx[cdev_id]);
+ i++;
+ }
+
+ free_test_vector(t_vec, &opts);
+
+ printf("\n");
+ return EXIT_FAILURE;
+}
diff --git a/config/common_base b/config/common_base
index edb6a54..96fd7bf 100644
--- a/config/common_base
+++ b/config/common_base
@@ -585,3 +585,9 @@ CONFIG_RTE_APP_TEST_RESOURCE_TAR=n
CONFIG_RTE_TEST_PMD=y
CONFIG_RTE_TEST_PMD_RECORD_CORE_CYCLES=n
CONFIG_RTE_TEST_PMD_RECORD_BURST_STATS=n
+
+#
+# Compile the crypto performance application
+#
+CONFIG_RTE_APP_CRYPTO_PERF=y
+
diff --git a/doc/guides/rel_notes/release_17_02.rst b/doc/guides/rel_notes/release_17_02.rst
index 3b982b2..3585664 100644
--- a/doc/guides/rel_notes/release_17_02.rst
+++ b/doc/guides/rel_notes/release_17_02.rst
@@ -79,6 +79,10 @@ New Features
* Scatter-gatter support for chained mbufs (only out-of place and destination
mbuf must be contiguous)
+* **Added performance test application.**
+
+ A new performance test application allows measuring performance parameters
+ of PMDs available in crypto tree.
Resolved Issues
---------------
diff --git a/doc/guides/tools/cryptoperf.rst b/doc/guides/tools/cryptoperf.rst
new file mode 100644
index 0000000..6832312
--- /dev/null
+++ b/doc/guides/tools/cryptoperf.rst
@@ -0,0 +1,397 @@
+.. BSD LICENSE
+ Copyright(c) 2016 Intel Corporation. All rights reserved.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name of Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+dpdk-test-crypto-perf Application
+=================================
+
+The ``dpdk-test-crypto-perf`` tool is a Data Plane Development Kit (DPDK)
+utility that allows measuring performance parameters of PMDs available in the
+crypto tree. There are available two measurement types: throughput and latency.
+User can use multiply cores to run tests on but only
+one type of crypto PMD can be measured during single application
+execution. Cipher parameters, type of device, type of operation and
+chain mode have to be specified in the command line as application
+parameters. These parameters are checked using device capabilities
+structure.
+
+Compiling the Application
+-------------------------
+
+**Step 1: PMD setting**
+
+The ``dpdk-test-crypto-perf`` tool depends on crypto device drivers PMD which
+are disabled by default in the build configuration file ``common_base``.
+The crypto device drivers PMD which should be tested can be enabled by setting::
+
+ CONFIG_RTE_LIBRTE_PMD_<name>=y
+
+Setting example for open ssl PMD::
+
+ CONFIG_RTE_LIBRTE_PMD_OPENSSL=y
+
+**Step 2: Linearization setting**
+
+It is possible linearized input segmented packets just before crypto operation
+for devices which doesn't support scatter-gather, and allows to measure
+performance also for this use case.
+
+To set on the linearization options add below definition to the
+``cperf_ops.h`` file::
+
+ #define CPERF_LINEARIZATION_ENABLE
+
+**Step 3: Build the application**
+
+Execute the ``dpdk-setup.sh`` script to build the DPDK library together with the
+``dpdk-test-crypto-perf`` applcation.
+
+Initially, the user must select a DPDK target to choose the correct target type
+and compiler options to use when building the libraries.
+The user must have all libraries, modules, updates and compilers installed
+in the system prior to this,
+as described in the earlier chapters in this Getting Started Guide.
+
+Running the Application
+-----------------------
+
+The tool application has a number of command line options:
+
+.. code-block:: console
+
+ dpdk-test-crypto-perf [EAL Options] -- [Application Options]
+
+EAL Options
+~~~~~~~~~~~
+
+The following are the EAL command-line options that can be used in conjunction
+with the ``dpdk-test-crypto-perf`` applcation.
+See the DPDK Getting Started Guides for more information on these options.
+
+* ``-c <COREMASK>``
+
+ Set the hexadecimal bitmask of the cores to run on.
+
+* ``-w <PCI>``
+
+ Add a PCI device in white list.
+
+* ``--vdev <driver><id>``
+
+ Add a virtual device.
+
+Appication Options
+~~~~~~~~~~~~~~~~~~
+
+The following are the appication command-line options:
+
+* ``--ptest type``
+
+ Set test type, where ``type`` is one of the following::
+
+ throughput
+ latency
+
+* ``--silent``
+
+ Disable options dump.
+
+* ``--pool-sz <n>``
+
+ Set the number of mbufs to be allocated in the mbuf pool.
+
+* ``--total-ops <n>``
+
+ Set the number of total operations performed.
+
+* ``--burst-sz <n>``
+
+ Set the number of packets per burst.
+
+* ``--buffer-sz <n>``
+
+ Set the size of single packet (plaintext or ciphertext in it).
+
+* ``--segments-nb <n>``
+
+ Set the number of segments per packet.
+
+* ``--devtype <name>``
+
+ Set device type, where ``name`` is one of the following::
+
+ crypto_null
+ crypto_aesni_mb
+ crypto_aesni_gcm
+ crypto_openssl
+ crypto_qat
+ crypto_snow3g
+ crypto_kasumi
+ crypto_zuc
+
+* ``--optype <name>``
+
+ Set operation type, where ``name`` is one of the following::
+
+ cipher-only
+ auth-only
+ cipher-then-auth
+ auth-then-cipher
+ aead
+
+* ``--sessionless``
+
+ Enable session-less crypto operations mode.
+
+* ``--out-of-place``
+
+ Enable out-of-place crypto operations mode.
+
+* ``--verify``
+
+ Enable verify that all crypto operations were successful.
+ The verification is done after the performance test.
+
+* ``--test-file <name>``
+
+ Set test vector file path. See the Test Vector File chapter.
+
+* ``--test-name <name>``
+
+ Set specific test name section in the test vector file.
+
+* ``--cipher-algo <name>``
+
+ Set cipher algorithm name, where ``name`` is one of the following::
+
+ 3des-cbc
+ 3des-ecb
+ 3des-ctr
+ aes-cbc
+ aes-ccm
+ aes-ctr
+ aes-ecb
+ aes-gcm
+ aes-f8
+ aes-xts
+ arc4
+ null
+ kasumi-f8
+ snow3g-uea2
+ zuc-eea3
+
+* ``--cipher-op <mode>``
+
+ Set cipher operation mode, where ``mode`` is one of the following::
+
+ encrypt
+ decrypt
+
+* ``--cipher-key-sz <n>``
+
+ Set the size of cipher key.
+
+* ``--cipher-iv-sz <n>``
+
+ Set the size of cipher iv.
+
+* ``--auth-algo <name>``
+
+ Set authentication algorithm name, where ``name`` is one
+ of the following::
+
+ 3des-cbc
+ aes-cbc-mac
+ aes-ccm
+ aes-cmac
+ aes-gcm
+ aes-gmac
+ aes-xcbc-mac
+ md5
+ md5-hmac
+ sha1
+ sha1-hmac
+ sha2-224
+ sha2-224-hmac
+ sha2-256
+ sha2-256-hmac
+ sha2-384
+ sha2-384-hmac
+ sha2-512
+ sha2-512-hmac
+ kasumi-f9
+ snow3g-uia2
+ zuc-eia3
+
+* ``--auth-op <mode>``
+
+ Set authentication operation mode, where ``mode`` is one of
+ the following::
+
+ verify
+ generate
+
+* ``--auth-key-sz <n>``
+
+ Set the size of authentication key.
+
+* ``--auth-digest-sz <n>``
+
+ Set the size of authentication digest.
+
+* ``--auth-aad-sz <n>``
+
+ Set the size of authentication aad.
+
+* ``--csv-friendly``
+
+ Enable test result output CSV friendly rather than human friendly.
+
+Test Vector File
+~~~~~~~~~~~~~~~~
+
+The test vector file is a text file contain information about test vectors.
+The file is made of the sections. The first section doesn't have header.
+It contain global information used in each test variant vectors -
+typicaly information about plaintext, ciphertext, cipher key, aut key,
+initial vector. All other sections begin header.
+The sections contain particular information typicaly digest.
+
+**Format of the file:**
+
+Each line beginig with sign '#' contain comment and it is ignored by parser::
+
+ # <comment>
+
+Header line is just name in square bracket::
+
+ [<section name>]
+
+Data line contain information tocken then sign '=' and
+a string of bytes in C byte array format::
+
+ <tocken> = <C byte array>
+
+**Tockens list:**
+
+* ``plaintext``
+
+ Original plaintext to be crypted.
+
+* ``ciphertext``
+
+ Encrypted plaintext string.
+
+* ``cipher_key``
+
+ Key used in cipher operation.
+
+* ``auth_key``
+
+ Key used in auth operation.
+
+* ``iv``
+
+ Initial vector.
+
+* ``aad``
+
+ Additional data.
+
+* ``digest``
+
+ Digest string.
+
+Examples
+--------
+
+Call application for performance throughput test of single Aesni MB PMD
+for cipher encryption aes-cbc and auth generation sha1-hmac,
+one milion operations, burst size 32, packet size 64::
+
+ dpdk-test-crypto-perf -c 0xc0 --vdev crypto_aesni_mb_pmd -w 0000:00:00.0 --
+ --ptest throughput --devtype crypto_aesni_mb --optype cipher-then-auth
+ --cipher-algo aes-cbc --cipher-op encrypt --cipher-key-sz 16 --auth-algo
+ sha1-hmac --auth-op generate --auth-key-sz 64 --auth-digest-sz 12
+ --total-ops 10000000 --burst-sz 32 --buffer-sz 64
+
+Call application for performance latency test of two Aesni MB PMD executed
+on two cores for cipher encryption aes-cbc, ten operations in silent mode::
+
+ dpdk-test-crypto-perf -c 0xf0 --vdev crypto_aesni_mb_pmd1
+ --vdev crypto_aesni_mb_pmd2 -w 0000:00:00.0 -- --devtype crypto_aesni_mb
+ --cipher-algo aes-cbc --cipher-key-sz 16 --cipher-iv-sz 16
+ --cipher-op encrypt --optype cipher-only --silent
+ --ptest latency --total-ops 10
+
+Call application for performance latency test of single open ssl PMD
+for cipher encryption aes-gcm and auth generation aes-gcm,ten operations
+in silent mode, test vector provide in file "test_aes_gcm.data"
+with packet verification::
+
+ dpdk-test-crypto-perf -c 0xf0 --vdev crypto_openssl -w 0000:00:00.0 --
+ --devtype crypto_openssl --cipher-algo aes-gcm --cipher-key-sz 16
+ --cipher-iv-sz 16 --cipher-op encrypt --auth-algo aes-gcm --auth-key-sz 16
+ --auth-digest-sz 16 --auth-aad-sz 16 --auth-op generate --optype aead
+ --silent --ptest latency --total-ops 10
+ --test-file test_aes_gcm.data --verify
+
+Test vector file for cipher algorithm aes cbc 256 with authorization sha::
+
+ # Global Section
+ plaintext =
+ 0xff, 0xca, 0xfb, 0xf1, 0x38, 0x20, 0x2f, 0x7b, 0x24, 0x98, 0x26, 0x7d, 0x1d, 0x9f, 0xb3, 0x93,
+ 0xd9, 0xef, 0xbd, 0xad, 0x4e, 0x40, 0xbd, 0x60, 0xe9, 0x48, 0x59, 0x90, 0x67, 0xd7, 0x2b, 0x7b,
+ 0x8a, 0xe0, 0x4d, 0xb0, 0x70, 0x38, 0xcc, 0x48, 0x61, 0x7d, 0xee, 0xd6, 0x35, 0x49, 0xae, 0xb4,
+ 0xaf, 0x6b, 0xdd, 0xe6, 0x21, 0xc0, 0x60, 0xce, 0x0a, 0xf4, 0x1c, 0x2e, 0x1c, 0x8d, 0xe8, 0x7b
+ ciphertext =
+ 0x77, 0xF9, 0xF7, 0x7A, 0xA3, 0xCB, 0x68, 0x1A, 0x11, 0x70, 0xD8, 0x7A, 0xB6, 0xE2, 0x37, 0x7E,
+ 0xD1, 0x57, 0x1C, 0x8E, 0x85, 0xD8, 0x08, 0xBF, 0x57, 0x1F, 0x21, 0x6C, 0xAD, 0xAD, 0x47, 0x1E,
+ 0x0D, 0x6B, 0x79, 0x39, 0x15, 0x4E, 0x5B, 0x59, 0x2D, 0x76, 0x87, 0xA6, 0xD6, 0x47, 0x8F, 0x82,
+ 0xB8, 0x51, 0x91, 0x32, 0x60, 0xCB, 0x97, 0xDE, 0xBE, 0xF0, 0xAD, 0xFC, 0x23, 0x2E, 0x22, 0x02
+ cipher_key =
+ 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A,
+ 0xd0, 0xe7, 0x4b, 0xfb, 0x5d, 0xe5, 0x0c, 0xe7, 0x6f, 0x21, 0xb5, 0x52, 0x2a, 0xbb, 0xc7, 0xf7
+ auth_key =
+ 0xaf, 0x96, 0x42, 0xf1, 0x8c, 0x50, 0xdc, 0x67, 0x1a, 0x43, 0x47, 0x62, 0xc7, 0x04, 0xab, 0x05,
+ 0xf5, 0x0c, 0xe7, 0xa2, 0xa6, 0x23, 0xd5, 0x3d, 0x95, 0xd8, 0xcd, 0x86, 0x79, 0xf5, 0x01, 0x47,
+ 0x4f, 0xf9, 0x1d, 0x9d, 0x36, 0xf7, 0x68, 0x1a, 0x64, 0x44, 0x58, 0x5d, 0xe5, 0x81, 0x15, 0x2a,
+ 0x41, 0xe4, 0x0e, 0xaa, 0x1f, 0x04, 0x21, 0xff, 0x2c, 0xf3, 0x73, 0x2b, 0x48, 0x1e, 0xd2, 0xf7
+ iv =
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+ # Section sha 1 hmac buff 32
+ [sha1_hmac_buff_32]
+ digest =
+ 0x36, 0xCA, 0x49, 0x6A, 0xE3, 0x54, 0xD8, 0x4F, 0x0B, 0x76, 0xD8, 0xAA, 0x78, 0xEB, 0x9D, 0x65,
+ 0x2C, 0xCA, 0x1F, 0x97
+ # Section sha 256 hmac buff 32
+ [sha256_hmac_buff_32]
+ digest =
+ 0x1C, 0xB2, 0x3D, 0xD1, 0xF9, 0xC7, 0x6C, 0x49, 0x2E, 0xDA, 0x94, 0x8B, 0xF1, 0xCF, 0x96, 0x43,
+ 0x67, 0x50, 0x39, 0x76, 0xB5, 0xA1, 0xCE, 0xA1, 0xD7, 0x77, 0x10, 0x07, 0x43, 0x37, 0x05, 0xB4
diff --git a/doc/guides/tools/index.rst b/doc/guides/tools/index.rst
index 513221c..6dc5d20 100644
--- a/doc/guides/tools/index.rst
+++ b/doc/guides/tools/index.rst
@@ -39,4 +39,5 @@ DPDK Tools User Guides
pdump
pmdinfo
devbind
+ cryptoperf
--
2.5.0
^ permalink raw reply related
* [PATCH v3 1/2] cryptodev: add functions to retrieve device info
From: Slawomir Mrozowicz @ 2017-01-11 16:07 UTC (permalink / raw)
To: dev; +Cc: Slawomir Mrozowicz, Declan Doherty, Marcin Kerlin
In-Reply-To: <1484150829-20734-1-git-send-email-slawomirx.mrozowicz@intel.com>
This patch adds helper functions for new performance application which
provide identifiers and number of crypto device and
provide and check capabilities available for defined device and algorithm.
The performance application can be used to measure throughput and latency
of cryptography operation performed by crypto device.
Signed-off-by: Declan Doherty <declan.doherty@intel.com>
Signed-off-by: Slawomir Mrozowicz <slawomirx.mrozowicz@intel.com>
Signed-off-by: Marcin Kerlin <marcinx.kerlin@intel.com>
---
To be applied on top of:
[dpdk-dev,v4] crypto/aesni_gcm: migration from MB library to ISA-L
v2 changes:
- code style fix
- add information in version.map about changes
v3 changes:
- title of the cryptodev patch
- supply information in version.map about changes
---
lib/librte_cryptodev/rte_crypto_sym.h | 16 +++
lib/librte_cryptodev/rte_cryptodev.c | 181 +++++++++++++++++++++++++
lib/librte_cryptodev/rte_cryptodev.h | 120 +++++++++-------
lib/librte_cryptodev/rte_cryptodev_version.map | 14 ++
4 files changed, 285 insertions(+), 46 deletions(-)
diff --git a/lib/librte_cryptodev/rte_crypto_sym.h b/lib/librte_cryptodev/rte_crypto_sym.h
index 0e20b30..c782588 100644
--- a/lib/librte_cryptodev/rte_crypto_sym.h
+++ b/lib/librte_cryptodev/rte_crypto_sym.h
@@ -112,6 +112,10 @@ enum rte_crypto_cipher_algorithm {
};
+/** Cipher algorithm name strings */
+extern const char *
+rte_crypto_cipher_algorithm_strings[];
+
/** Symmetric Cipher Direction */
enum rte_crypto_cipher_operation {
RTE_CRYPTO_CIPHER_OP_ENCRYPT,
@@ -120,6 +124,10 @@ enum rte_crypto_cipher_operation {
/**< Decrypt cipher operation */
};
+/** Cipher operation name strings */
+extern const char *
+rte_crypto_cipher_operation_strings[];
+
/**
* Symmetric Cipher Setup Data.
*
@@ -245,12 +253,20 @@ enum rte_crypto_auth_algorithm {
RTE_CRYPTO_AUTH_LIST_END
};
+/** Authentication algorithm name strings */
+extern const char *
+rte_crypto_auth_algorithm_strings[];
+
/** Symmetric Authentication / Hash Operations */
enum rte_crypto_auth_operation {
RTE_CRYPTO_AUTH_OP_VERIFY, /**< Verify authentication digest */
RTE_CRYPTO_AUTH_OP_GENERATE /**< Generate authentication digest */
};
+/** Authentication operation name strings */
+extern const char *
+rte_crypto_auth_operation_strings[];
+
/**
* Authentication / Hash transform data.
*
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index bbab4b3..c126b1b 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -111,6 +111,86 @@ static const char *cryptodev_vdev_valid_params[] = {
RTE_CRYPTODEV_VDEV_SOCKET_ID
};
+/**
+ * The crypto cipher algorithm strings identifiers.
+ * It could be used in application command line.
+ */
+const char *
+rte_crypto_cipher_algorithm_strings[] = {
+ [RTE_CRYPTO_CIPHER_3DES_CBC] = "3des-cbc",
+ [RTE_CRYPTO_CIPHER_3DES_ECB] = "3des-ecb",
+ [RTE_CRYPTO_CIPHER_3DES_CTR] = "3des-ctr",
+
+ [RTE_CRYPTO_CIPHER_AES_CBC] = "aes-cbc",
+ [RTE_CRYPTO_CIPHER_AES_CCM] = "aes-ccm",
+ [RTE_CRYPTO_CIPHER_AES_CTR] = "aes-ctr",
+ [RTE_CRYPTO_CIPHER_AES_ECB] = "aes-ecb",
+ [RTE_CRYPTO_CIPHER_AES_GCM] = "aes-gcm",
+ [RTE_CRYPTO_CIPHER_AES_F8] = "aes-f8",
+ [RTE_CRYPTO_CIPHER_AES_XTS] = "aes-xts",
+
+ [RTE_CRYPTO_CIPHER_ARC4] = "arc4",
+
+ [RTE_CRYPTO_CIPHER_NULL] = "null",
+
+ [RTE_CRYPTO_CIPHER_KASUMI_F8] = "kasumi-f8",
+ [RTE_CRYPTO_CIPHER_SNOW3G_UEA2] = "snow3g-uea2",
+ [RTE_CRYPTO_CIPHER_ZUC_EEA3] = "zuc-eea3"
+};
+
+/**
+ * The crypto cipher operation strings identifiers.
+ * It could be used in application command line.
+ */
+const char *
+rte_crypto_cipher_operation_strings[] = {
+ [RTE_CRYPTO_CIPHER_OP_ENCRYPT] = "encrypt",
+ [RTE_CRYPTO_CIPHER_OP_DECRYPT] = "decrypt"
+};
+
+/**
+ * The crypto auth algorithm strings identifiers.
+ * It could be used in application command line.
+ */
+const char *
+rte_crypto_auth_algorithm_strings[] = {
+ [RTE_CRYPTO_AUTH_AES_CBC_MAC] = "aes-cbc-mac",
+ [RTE_CRYPTO_AUTH_AES_CCM] = "aes-ccm",
+ [RTE_CRYPTO_AUTH_AES_CMAC] = "aes-cmac",
+ [RTE_CRYPTO_AUTH_AES_GCM] = "aes-gcm",
+ [RTE_CRYPTO_AUTH_AES_GMAC] = "aes-gmac",
+ [RTE_CRYPTO_AUTH_AES_XCBC_MAC] = "aes-xcbc-mac",
+
+ [RTE_CRYPTO_AUTH_MD5] = "md5",
+ [RTE_CRYPTO_AUTH_MD5_HMAC] = "md5-hmac",
+
+ [RTE_CRYPTO_AUTH_SHA1] = "sha1",
+ [RTE_CRYPTO_AUTH_SHA1_HMAC] = "sha1-hmac",
+
+ [RTE_CRYPTO_AUTH_SHA224] = "sha2-224",
+ [RTE_CRYPTO_AUTH_SHA224_HMAC] = "sha2-224-hmac",
+ [RTE_CRYPTO_AUTH_SHA256] = "sha2-256",
+ [RTE_CRYPTO_AUTH_SHA256_HMAC] = "sha2-256-hmac",
+ [RTE_CRYPTO_AUTH_SHA384] = "sha2-384",
+ [RTE_CRYPTO_AUTH_SHA384_HMAC] = "sha2-384-hmac",
+ [RTE_CRYPTO_AUTH_SHA512] = "sha2-512",
+ [RTE_CRYPTO_AUTH_SHA512_HMAC] = "sha2-512-hmac",
+
+ [RTE_CRYPTO_AUTH_KASUMI_F9] = "kasumi-f9",
+ [RTE_CRYPTO_AUTH_SNOW3G_UIA2] = "snow3g-uia2",
+ [RTE_CRYPTO_AUTH_ZUC_EIA3] = "zuc-eia3"
+};
+
+/**
+ * The crypto auth operation strings identifiers.
+ * It could be used in application command line.
+ */
+const char *
+rte_crypto_auth_operation_strings[] = {
+ [RTE_CRYPTO_AUTH_OP_VERIFY] = "verify",
+ [RTE_CRYPTO_AUTH_OP_GENERATE] = "generate"
+};
+
static uint8_t
number_of_sockets(void)
{
@@ -191,6 +271,73 @@ rte_cryptodev_parse_vdev_init_params(struct rte_crypto_vdev_init_params *params,
return ret;
}
+const struct rte_cryptodev_symmetric_capability *
+rte_cryptodev_capability_get(uint8_t dev_id,
+ const struct rte_cryptodev_capability_idx *idx)
+{
+ const struct rte_cryptodev_capabilities *capability;
+ struct rte_cryptodev_info dev_info;
+ int i = 0;
+
+ rte_cryptodev_info_get(dev_id, &dev_info);
+
+ while ((capability = &dev_info.capabilities[i++])->op !=
+ RTE_CRYPTO_OP_TYPE_UNDEFINED) {
+ if (capability->op != RTE_CRYPTO_OP_TYPE_SYMMETRIC)
+ continue;
+
+ if (capability->sym.xform_type != idx->type)
+ continue;
+
+ if (idx->type == RTE_CRYPTO_SYM_XFORM_AUTH &&
+ capability->sym.auth.algo == idx->algo.auth)
+ return &capability->sym;
+
+ if (idx->type == RTE_CRYPTO_SYM_XFORM_CIPHER &&
+ capability->sym.cipher.algo == idx->algo.cipher)
+ return &capability->sym;
+ }
+
+ return NULL;
+
+}
+
+#define param_range_check(x, y) \
+ (((x < y.min) || (x > y.max)) || \
+ (y.increment != 0 && (x % y.increment) != 0))
+
+int
+rte_cryptodev_capability_check_cipher(
+ const struct rte_cryptodev_symmetric_capability *capability,
+ uint16_t key_size, uint16_t iv_size)
+{
+ if (param_range_check(key_size, capability->cipher.key_size))
+ return -1;
+
+ if (param_range_check(iv_size, capability->cipher.iv_size))
+ return -1;
+
+ return 0;
+}
+
+int
+rte_cryptodev_capability_check_auth(
+ const struct rte_cryptodev_symmetric_capability *capability,
+ uint16_t key_size, uint16_t digest_size, uint16_t aad_size)
+{
+ if (param_range_check(key_size, capability->auth.key_size))
+ return -1;
+
+ if (param_range_check(digest_size, capability->auth.digest_size))
+ return -1;
+
+ if (param_range_check(aad_size, capability->auth.aad_size))
+ return -1;
+
+ return 0;
+}
+
+
const char *
rte_cryptodev_get_feature_name(uint64_t flag)
{
@@ -263,6 +410,40 @@ rte_cryptodev_count_devtype(enum rte_cryptodev_type type)
}
int
+rte_cryptodev_devices_get(const char *dev_name, uint8_t *devices,
+ uint8_t nb_devices)
+{
+ uint8_t i, cmp, count = 0;
+ struct rte_cryptodev **devs = &rte_cryptodev_globals->devs;
+ struct rte_pci_device *pci;
+
+ for (i = 0; i < rte_cryptodev_globals->max_devs && count < nb_devices;
+ i++) {
+
+ if ((*devs + i)
+ && (*devs + i)->attached ==
+ RTE_CRYPTODEV_ATTACHED) {
+
+ pci = (*devs + i)->pci_dev;
+
+ if (pci)
+ cmp = strncmp(pci->driver->driver.name,
+ dev_name,
+ strlen(dev_name));
+ else
+ cmp = strncmp((*devs + i)->data->name,
+ dev_name,
+ strlen(dev_name));
+
+ if (cmp == 0)
+ devices[count++] = (*devs + i)->data->dev_id;
+ }
+ }
+
+ return count;
+}
+
+int
rte_cryptodev_socket_id(uint8_t dev_id)
{
struct rte_cryptodev *dev;
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index fa311a9..97d1a86 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -76,7 +76,7 @@ enum rte_cryptodev_type {
RTE_CRYPTODEV_SNOW3G_PMD, /**< SNOW 3G PMD */
RTE_CRYPTODEV_KASUMI_PMD, /**< KASUMI PMD */
RTE_CRYPTODEV_ZUC_PMD, /**< ZUC PMD */
- RTE_CRYPTODEV_OPENSSL_PMD, /**< OpenSSL PMD */
+ RTE_CRYPTODEV_OPENSSL_PMD, /**< OpenSSL PMD */
};
extern const char **rte_cyptodev_names;
@@ -110,6 +110,20 @@ extern const char **rte_cyptodev_names;
#endif
/**
+ * Crypto parameters range description
+ */
+struct rte_crypto_param_range {
+ uint16_t min; /**< minimum size */
+ uint16_t max; /**< maximum size */
+ uint16_t increment;
+ /**< if a range of sizes are supported,
+ * this parameter is used to indicate
+ * increments in byte size that are supported
+ * between the minimum and maximum
+ */
+};
+
+/**
* Symmetric Crypto Capability
*/
struct rte_cryptodev_symmetric_capability {
@@ -122,35 +136,11 @@ struct rte_cryptodev_symmetric_capability {
/**< authentication algorithm */
uint16_t block_size;
/**< algorithm block size */
- struct {
- uint16_t min; /**< minimum key size */
- uint16_t max; /**< maximum key size */
- uint16_t increment;
- /**< if a range of sizes are supported,
- * this parameter is used to indicate
- * increments in byte size that are supported
- * between the minimum and maximum */
- } key_size;
+ struct rte_crypto_param_range key_size;
/**< auth key size range */
- struct {
- uint16_t min; /**< minimum digest size */
- uint16_t max; /**< maximum digest size */
- uint16_t increment;
- /**< if a range of sizes are supported,
- * this parameter is used to indicate
- * increments in byte size that are supported
- * between the minimum and maximum */
- } digest_size;
+ struct rte_crypto_param_range digest_size;
/**< digest size range */
- struct {
- uint16_t min; /**< minimum aad size */
- uint16_t max; /**< maximum aad size */
- uint16_t increment;
- /**< if a range of sizes are supported,
- * this parameter is used to indicate
- * increments in byte size that are supported
- * between the minimum and maximum */
- } aad_size;
+ struct rte_crypto_param_range aad_size;
/**< Additional authentication data size range */
} auth;
/**< Symmetric Authentication transform capabilities */
@@ -159,25 +149,9 @@ struct rte_cryptodev_symmetric_capability {
/**< cipher algorithm */
uint16_t block_size;
/**< algorithm block size */
- struct {
- uint16_t min; /**< minimum key size */
- uint16_t max; /**< maximum key size */
- uint16_t increment;
- /**< if a range of sizes are supported,
- * this parameter is used to indicate
- * increments in byte size that are supported
- * between the minimum and maximum */
- } key_size;
+ struct rte_crypto_param_range key_size;
/**< cipher key size range */
- struct {
- uint16_t min; /**< minimum iv size */
- uint16_t max; /**< maximum iv size */
- uint16_t increment;
- /**< if a range of sizes are supported,
- * this parameter is used to indicate
- * increments in byte size that are supported
- * between the minimum and maximum */
- } iv_size;
+ struct rte_crypto_param_range iv_size;
/**< Initialisation vector data size range */
} cipher;
/**< Symmetric Cipher transform capabilities */
@@ -196,6 +170,38 @@ struct rte_cryptodev_capabilities {
};
};
+/** Structure used to describe crypto algorithms */
+struct rte_cryptodev_capability_idx {
+ enum rte_crypto_sym_xform_type type;
+ union {
+ enum rte_crypto_cipher_algorithm cipher;
+ enum rte_crypto_auth_algorithm auth;
+ } algo;
+};
+
+/** Provide capabilities available for defined device and algorithm */
+const struct rte_cryptodev_symmetric_capability *
+rte_cryptodev_capability_get(uint8_t dev_id,
+ const struct rte_cryptodev_capability_idx *idx);
+
+/**
+ * Check if key size and initial vector are supported
+ * in crypto cipher capability
+ */
+int
+rte_cryptodev_capability_check_cipher(
+ const struct rte_cryptodev_symmetric_capability *capability,
+ uint16_t key_size, uint16_t iv_size);
+
+/**
+ * Check if key size and initial vector are supported
+ * in crypto auth capability
+ */
+int
+rte_cryptodev_capability_check_auth(
+ const struct rte_cryptodev_symmetric_capability *capability,
+ uint16_t key_size, uint16_t digest_size, uint16_t aad_size);
+
/** Macro used at end of crypto PMD list */
#define RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST() \
{ RTE_CRYPTO_OP_TYPE_UNDEFINED }
@@ -369,8 +375,30 @@ rte_cryptodev_get_dev_id(const char *name);
extern uint8_t
rte_cryptodev_count(void);
+/**
+ * Get number of crypto device defined type.
+ *
+ * @param type type of device.
+ *
+ * @return
+ * Returns number of crypto device.
+ */
extern uint8_t
rte_cryptodev_count_devtype(enum rte_cryptodev_type type);
+
+/**
+ * Get number and identifiers of attached crypto device.
+ *
+ * @param dev_name device name.
+ * @param devices output devices identifiers.
+ * @param nb_devices maximal number of devices.
+ *
+ * @return
+ * Returns number of attached crypto device.
+ */
+int
+rte_cryptodev_devices_get(const char *dev_name, uint8_t *devices,
+ uint8_t nb_devices);
/*
* Return the NUMA socket to which a device is connected
*
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index 9dde0e7..bdd5e5d 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -46,3 +46,17 @@ DPDK_16.11 {
rte_cryptodev_pci_remove;
} DPDK_16.07;
+
+DPDK_17.02 {
+ global:
+
+ rte_cryptodev_capability_check_auth;
+ rte_cryptodev_capability_check_cipher;
+ rte_cryptodev_capability_get;
+ rte_cryptodev_devices_get;
+ rte_crypto_auth_algorithm_strings;
+ rte_crypto_auth_operation_strings;
+ rte_crypto_cipher_algorithm_strings;
+ rte_crypto_cipher_operation_strings;
+
+} DPDK_16.11;
--
2.5.0
^ permalink raw reply related
* [PATCH] cryptodev: fix for loop in rte_cryptodev_pmd_get_named_dev
From: Fan Zhang @ 2017-01-11 14:09 UTC (permalink / raw)
To: dev; +Cc: pablo.de.lara.guarch
Fixes: d11b0f30 ("cryptodev: introduce API and framework for crypto devices")
This patch fixes the dev value update problem in
rte_cryptodev_pmd_get_named_dev, orginally, dev won't be updated
after the initiail step in the loop.
Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
lib/librte_cryptodev/rte_cryptodev_pmd.h | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h b/lib/librte_cryptodev/rte_cryptodev_pmd.h
index abfe2dc..c6a5794 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
@@ -183,8 +183,9 @@ rte_cryptodev_pmd_get_named_dev(const char *name)
if (name == NULL)
return NULL;
- for (i = 0, dev = &rte_cryptodev_globals->devs[i];
- i < rte_cryptodev_globals->max_devs; i++) {
+ for (i = 0; i < rte_cryptodev_globals->max_devs; i++) {
+ dev = &rte_cryptodev_globals->devs[i];
+
if ((dev->attached == RTE_CRYPTODEV_ATTACHED) &&
(strcmp(dev->data->name, name) == 0))
return dev;
--
2.7.4
^ permalink raw reply related
* [PATCH v3 0/2] Introduce new performance test application
From: Slawomir Mrozowicz @ 2017-01-11 16:07 UTC (permalink / raw)
To: dev; +Cc: Slawomir Mrozowicz
In-Reply-To: <1483635001-15473-1-git-send-email-slawomirx.mrozowicz@intel.com>
This patchset introduce new application which allows measuring
performance parameters of PMDs available in crypto tree. The goal of
this application is to replace existing performance tests in app/test.
Parameters available are: throughput (--ptest throughput) and latency
(--ptest latency). User can use multiply cores to run tests on but only
one type of crypto PMD can be measured during single application
execution. Cipher parameters, type of device, type of operation and
chain mode have to be specified in the command line as application
parameters. These parameters are checked using device capabilities
structure.
Couple of new library functions in librte_cryptodev are introduced for
application use.
There added also EAL option to suppresses all log output to stdout.
To build the application a CONFIG_RTE_APP_CRYPTO_PERF flag has to be set
(it is set by default).
Example of usage: -c 0xc0 --vdev crypto_aesni_mb_pmd -w 0000:00:00.0 --
--ptest throughput --devtype crypto_aesni_mb --optype cipher-then-auth
--cipher-algo aes-cbc --cipher-op encrypt --cipher-key-sz 16 --auth-algo
sha1-hmac --auth-op generate --auth-key-sz 64 --auth-digest-sz 12
--total-ops 10000000 --burst-sz 32 --buffer-sz 64
To be applied on top of:
[dpdk-dev,v4] crypto/aesni_gcm: migration from MB library to ISA-L
v2 changes:
- code style fix
- add information in version.map about changes
- add latency measurement by single operation instead of burst
- add processing of chained mbufs
- add handling of test vectors file and create example of the files
- add verify operation after performance measurement
- add check of input options
- simplify application output to allow output to be easily
- add processing out of place
- add coalescing functionality
- add documentation files
v3 changes:
- title of the cryptodev patch
- supply information in version.map about changes
- fix compile in dynamic mode
- fix logic in check option
- change application name and directory
Declan Doherty (2)
cryptodev: add functions to retrieve device info
app/crypto-perf: introduce new performance test application
Slawomir Mrozowicz (2):
cryptodev: add functions to retrieve device info
app/crypto-perf: introduce new performance test application
Marcin Kerlin (2)
cryptodev: add functions to retrieve device info
app/crypto-perf: introduce new performance test application
Piotr Azarewicz (1)
app/crypto-perf: introduce new performance test application
Michal Kobylinski (1)
app/crypto-perf: introduce new performance test application
MAINTAINERS | 4 +
app/Makefile | 1 +
app/test-crypto-perf/Makefile | 51 ++
app/test-crypto-perf/cperf.h | 58 ++
app/test-crypto-perf/cperf_ops.c | 474 ++++++++++++
app/test-crypto-perf/cperf_ops.h | 66 ++
app/test-crypto-perf/cperf_options.h | 104 +++
app/test-crypto-perf/cperf_options_parsing.c | 875 +++++++++++++++++++++++
app/test-crypto-perf/cperf_test_latency.c | 685 ++++++++++++++++++
app/test-crypto-perf/cperf_test_latency.h | 57 ++
app/test-crypto-perf/cperf_test_throughput.c | 651 +++++++++++++++++
app/test-crypto-perf/cperf_test_throughput.h | 58 ++
app/test-crypto-perf/cperf_test_vector_parsing.c | 500 +++++++++++++
app/test-crypto-perf/cperf_test_vector_parsing.h | 73 ++
app/test-crypto-perf/cperf_test_vectors.c | 476 ++++++++++++
app/test-crypto-perf/cperf_test_vectors.h | 98 +++
app/test-crypto-perf/cperf_verify_parser.c | 314 ++++++++
app/test-crypto-perf/data/aes_cbc_128_sha.data | 503 +++++++++++++
app/test-crypto-perf/data/aes_cbc_192_sha.data | 504 +++++++++++++
app/test-crypto-perf/data/aes_cbc_256_sha.data | 504 +++++++++++++
app/test-crypto-perf/main.c | 411 +++++++++++
config/common_base | 6 +
doc/guides/rel_notes/release_17_02.rst | 4 +
doc/guides/tools/cryptoperf.rst | 397 ++++++++++
doc/guides/tools/index.rst | 1 +
lib/librte_cryptodev/rte_crypto_sym.h | 16 +
lib/librte_cryptodev/rte_cryptodev.c | 181 +++++
lib/librte_cryptodev/rte_cryptodev.h | 120 ++--
lib/librte_cryptodev/rte_cryptodev_version.map | 14 +
29 files changed, 7160 insertions(+), 46 deletions(-)
create mode 100644 app/test-crypto-perf/Makefile
create mode 100644 app/test-crypto-perf/cperf.h
create mode 100644 app/test-crypto-perf/cperf_ops.c
create mode 100644 app/test-crypto-perf/cperf_ops.h
create mode 100644 app/test-crypto-perf/cperf_options.h
create mode 100644 app/test-crypto-perf/cperf_options_parsing.c
create mode 100644 app/test-crypto-perf/cperf_test_latency.c
create mode 100644 app/test-crypto-perf/cperf_test_latency.h
create mode 100644 app/test-crypto-perf/cperf_test_throughput.c
create mode 100644 app/test-crypto-perf/cperf_test_throughput.h
create mode 100644 app/test-crypto-perf/cperf_test_vector_parsing.c
create mode 100644 app/test-crypto-perf/cperf_test_vector_parsing.h
create mode 100644 app/test-crypto-perf/cperf_test_vectors.c
create mode 100644 app/test-crypto-perf/cperf_test_vectors.h
create mode 100644 app/test-crypto-perf/cperf_verify_parser.c
create mode 100644 app/test-crypto-perf/data/aes_cbc_128_sha.data
create mode 100644 app/test-crypto-perf/data/aes_cbc_192_sha.data
create mode 100644 app/test-crypto-perf/data/aes_cbc_256_sha.data
create mode 100644 app/test-crypto-perf/main.c
create mode 100644 doc/guides/tools/cryptoperf.rst
--
2.5.0
^ permalink raw reply
* Re: [RFC] ethdev: abstraction layer for QoS hierarchical scheduler
From: Jerin Jacob @ 2017-01-11 13:56 UTC (permalink / raw)
To: Cristian Dumitrescu; +Cc: dev, balasubramanian.manoharan
In-Reply-To: <1480529810-95280-1-git-send-email-cristian.dumitrescu@intel.com>
On Wed, Nov 30, 2016 at 06:16:50PM +0000, Cristian Dumitrescu wrote:
> This RFC proposes an ethdev-based abstraction layer for Quality of Service (QoS)
> hierarchical scheduler. The goal of the abstraction layer is to provide a simple
> generic API that is agnostic of the underlying HW, SW or mixed HW-SW complex
> implementation.
Thanks Cristian for bringing up this RFC.
This will help in integrating NPU's QoS hierarchical scheduler's into DPDK.
Overall the RFC looks very good as a generic traffic manager. However, as a
NPU HW vendor, we feel like we need to expose some of the HW constraints and
HW specific features in a generic way in this specification to effectively use
with HW based implementation.
I will try to describe HW constraints and HW features associated with HW based
hierarchical scheduler found in Cavium SoCs as inline. IMO, If other HW vendors
share the constraints on "hardware based hierarchical scheduler"
then we could have a realistic HW/SW abstraction for the hierarchical scheduler.
>
> Q1: What is the benefit for having an abstraction layer for QoS hierarchical
> layer?
> A1: There is growing interest in the industry for handling various HW-based,
> SW-based or mixed hierarchical scheduler implementations using a unified DPDK
> API.
Yes.
> Q4: Why have this abstraction layer into ethdev as opposed to a new type of
> device (e.g. scheddev) similar to ethdev, cryptodev, eventdev, etc?
> A4: Packets are sent to the Ethernet device using the ethdev API
> rte_eth_tx_burst() function, with the hierarchical scheduling taking place
> automatically (i.e. no SW intervention) in HW implementations. Basically, the
> hierarchical scheduler is done as part of packet TX operation.
> The hierarchical scheduler is typically the last stage before packet TX and it
> is tightly integrated with the TX stage. The hierarchical scheduler is just
> another offload feature of the Ethernet device, which needs to be accommodated
> by the ethdev API similar to any other offload feature (such as RSS, DCB,
> flow director, etc).
> Once the decision to schedule a specific packet has been taken, this packet
> cannot be dropped and it has to be sent over the wire as is, otherwise what
> takes place on the wire is not what was planned at scheduling time, so the
> scheduling is not accurate (Note: there are some devices which allow prepending
> headers to the packet after the scheduling stage at the expense of sending
> correction requests back to the scheduler, but this only strengthens the bond
> between scheduling and TX).
Makes sense.
>
> Q5: Given that the packet scheduling takes place automatically for pure HW
> implementations, how does packet scheduling take place for poll-mode SW
> implementations?
> A5: The API provided function rte_sched_run() is designed to take care of this.
> For HW implementations, this function typically does nothing. For SW
> implementations, this function is typically expected to perform dequeue of
> packets from the hierarchical scheduler and their write to Ethernet device TX
> queue, periodic flush of any buffers on enqueue-side into the hierarchical
> scheduler for burst-oriented implementations, etc.
>
Yes. In addition to that, if rte_sched_run() does nothing(for HW implementation)
then _application_ should not call the same. I think we need to introduce
"service core" concept in DPDK to make it very transparent from an application
perspective.
> Q6: Which are the scheduling algorithms supported?
> A6: The fundamental scheduling algorithms that are supported are Strict Priority
> (SP) and Weighted Fair Queuing (WFQ). The SP and WFQ algorithms are supported at
> the level of each node of the scheduling hierarchy, regardless of the node
> level/position in the tree. The SP algorithm is used to schedule between sibling
> nodes with different priority, while WFQ is used to schedule between groups of
> siblings that have the same priority.
> Algorithms such as Weighed Round Robin (WRR), byte-level WRR, Deficit WRR
> (DWRR), etc are considered approximations of the ideal WFQ and are therefore
> assimilated to WFQ, although an associated implementation-dependent accuracy,
> performance and resource usage trade-off might exist.
Makes sense.
>
> Q7: Which are the supported congestion management algorithms?
> A7: Tail drop, head drop and Weighted Random Early Detection (WRED). They are
> available for every leaf node in the hierarchy, subject to the specific
> implementation supporting them.
We don't support Tail drop, head drop or WRED for each leaf node in the hierarchy,
Instead, in some sense, it is integrated into the HW mempool block at the ingress.
So, maybe we can have some sort of capability or info API to get the capability of
the scheduler to the application to get the big picture instead of trying
individual resource APIs in the spec.
We do have support for querying available free entries in the leaf queue to
figure out the load. But it may not be worth to start a service core(rte_sched_run())
for implementing the spec due to multicore communication overhead.
Instead, using the HW base support(a means to get the
depth of leaf queue) application/library can do congestion management.
Thoughts ?
Does any other HW vendor support egress congestion management in HW ?
>
> Q8: Is traffic shaping supported?
> A8: Yes, there are a number of shapers (rate limiters) that can be supported for
> each node in the hierarchy (built-in limit is currently set to 4 per node). Each
> shaper can be private to a node (used only by that node) or shared between
> multiple nodes.
Makes sense. We have dual rate shapers(very similar to RFC-2697 and RFC-2698)
at all the nodes(obviously, an only single rate at the last node(the one close to
physical port)). Just to understand, When we say 4 shapers per node, Is it four
different rate limiters per node? Is there any RFC for four rate limiter like
single(RFC-2697) and dual(RFC-2698)?
>
> Q9: What is the purpose of having shaper profiles and WRED profiles?
> A9: In most implementations, many shapers typically share the same configuration
> parameters, so defining shaper profiles simplifies the configuration task. Same
> considerations apply to WRED contexts and profiles.
Makes sense.
> Q11: Are on-the-fly changes of the scheduling hierarchy allowed by the API?
> A11: Yes. The actual changes take place subject to the specific implementation
> supporting them, otherwise error code is returned.
On-the-fly scheduling hierarchy is tricky in HW implementation and it comes with
a lot of constraints. Returning the error code is fine, But we need to define what
it takes to reconfigure the hierarchy if on-the-fly reconfiguring is not supported.
The high-level constraints for reconfiguring hierarchy in our HW is:
1) Stop adding additional packets in leaf node
2) Wait for the packets to drain out from the nodes.
Point (2) is internal to implementation so we can manage.
I guess, For, Point (1), Application may need to know the constraint.
>
> Q13: Which are the possible options for the user when the Ethernet port does not
> support the scheduling hierarchy required by the user?
> A13: The following options are available to the user:
> i) abort
> ii) try out a new hierarchy (e.g. with less leaf nodes), if acceptable
As mentioned earlier, Additional API to get the capability will help here.
Some of the other capabilities, we believe it will be useful for the applications.
1) maximum number of levels,
2) maximum nodes per level,
3) Is congestion management supported?
4) maximum priority per node?
At least it will be useful for writing the example application
> iii) wrap the Ethernet device into a new type of Ethernet device that has a SW
> front-end implementing the hierarchical scheduler (e.g. existing DPDK library
> librte_sched); instantiate the new device type on-the-fly and check if the
> hierarchy requirements can be met by the new device.
Do we want to wrap to new ethernet device or let application to use software
library directly ? If it is former then,
Are we planning for a generic SW based driver for this? So that the NICs don't have
HW support can just reuse the SW driver.Instead of duplicating the code in
all the PMD drivers?
>
>
> Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> ---
> lib/librte_ether/rte_ethdev.h | 794 ++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 794 insertions(+)
> mode change 100644 => 100755 lib/librte_ether/rte_ethdev.h
>
> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> old mode 100644
> new mode 100755
> index 9678179..d4d8604
> --- a/lib/librte_ether/rte_ethdev.h
> +++ b/lib/librte_ether/rte_ethdev.h
> @@ -182,6 +182,8 @@ extern "C" {
> #include <rte_pci.h>
> #include <rte_dev.h>
> #include <rte_devargs.h>
> +#include <rte_meter.h>
> +#include <rte_red.h>
[snip]
> +
> +enum rte_eth_sched_stats_counter {
> + /**< Number of packets scheduled from current node. */
> + RTE_ETH_SCHED_STATS_COUNTER_N_PKTS = 1<< 0,
> + /**< Number of bytes scheduled from current node. */
> + RTE_ETH_SCHED_STATS_COUNTER_N_BYTES = 1 << 1,
> + RTE_ETH_SCHED_STATS_COUNTER_N_PKTS_DROPPED = 1 << 2,
> + RTE_ETH_SCHED_STATS_COUNTER_N_BYTES_DROPPED = 1 << 3,
> + /**< Number of packets currently waiting in the packet queue of current
> + leaf node. */
> + RTE_ETH_SCHED_STATS_COUNTER_N_PKTS_QUEUED = 1 << 4,
> + /**< Number of bytes currently waiting in the packet queue of current
> + leaf node. */
> + RTE_ETH_SCHED_STATS_COUNTER_N_BYTES_QUEUED = 1 << 5,
Some of the other counters seen in HW implementations from the shaper(rate limiter) are
RED_PACKETS,
RED_BYTES,
YELLOW_PACKETS,
YELLOW_BYTES,
GREEN_PACKETS,
GREEN_BYTES
> +};
> +
> +/**
> + * Node statistics counters
> + */
> +struct rte_eth_sched_node_stats {
> + /**< Number of packets scheduled from current node. */
> + uint64_t n_pkts;
> + /**< Number of bytes scheduled from current node. */
> + uint64_t n_bytes;
> + /**< Statistics counters for leaf nodes only */
We don't have support for the stats for the all nodes.Since you have the
rte_eth_sched_node_stats_get_enabled(), We are good.
> + struct {
> + /**< Number of packets dropped by current leaf node. */
> + uint64_t n_pkts_dropped;
> + /**< Number of bytes dropped by current leaf node. */
> + uint64_t n_bytes_dropped;
> + /**< Number of packets currently waiting in the packet queue of
> + current leaf node. */
> + uint64_t n_pkts_queued;
> + /**< Number of bytes currently waiting in the packet queue of
> + current leaf node. */
> + uint64_t n_bytes_queued;
> + } leaf;
leaf stats looks good to us.
> +};
> +
> /**
> + * Scheduler WRED profile add
> + *
> + * Create a new WRED profile with ID set to *wred_profile_id*. The new profile
> + * is used to create one or several WRED contexts.
> + *
> + * @param port_id
> + * The port identifier of the Ethernet device.
> + * @param wred_profile_id
> + * WRED profile ID for the new profile. Needs to be unused.
> + * @param profile
> + * WRED profile parameters. Needs to be pre-allocated and valid.
> + * @return
> + * 0 on success, non-zero error code otherwise.
> + */
> +int rte_eth_sched_wred_profile_add(uint8_t port_id,
> + uint32_t wred_profile_id,
> + struct rte_eth_sched_wred_params *profile);
How about returning wred_profile_id from the driver? looks like, that is the easy
way to manage from driver perspective(driver can pass the same handle for similar
profiles and have an opaque number for embedding some other information)
and it is kind of norm.
i.e
int rte_eth_sched_wred_profile_add(uint8_t port_id,
struct rte_eth_sched_wred_params *profile);
> +/**
> + * Scheduler node add or remap
> + *
> + * When *node_id* is not a valid node ID, a new node with this ID is created and
> + * connected as child to the existing node identified by *parent_node_id*.
> + *
> + * When *node_id* is a valid node ID, this node is disconnected from its current
> + * parent and connected as child to another existing node identified by
> + * *parent_node_id *.
> + *
> + * This function can be called during port initialization phase (before the
> + * Ethernet port is started) for building the scheduler start-up hierarchy.
> + * Subject to the specific Ethernet port supporting on-the-fly scheduler
> + * hierarchy updates, this function can also be called during run-time (after
> + * the Ethernet port is started).
> + *
> + * @param port_id
> + * The port identifier of the Ethernet device.
> + * @param node_id
> + * Node ID
> + * @param parent_node_id
> + * Parent node ID. Needs to be the valid.
> + * @param params
> + * Node parameters. Needs to be pre-allocated and valid.
> + * @return
> + * 0 on success, non-zero error code otherwise.
IMO, We need an explicit error number to differentiate the configuration
error due do Ethernet port has been started.
And on receiving on such error code, we need to define what is the procedure
to reconfigure the topology.
The recent rte_flow spec has own error codes to get more visibility on the failure,
so that application can choose better attributes for configuring.
For example, Some of those limitations in our HW are
1) priorities are from 0 to 9(error type: PRIORITY_NOT_SUPPORTED)
2) DDWR is applicable only for one set priorities per children to parent
connection. example, valid case: 0-1-1-1-2-3. Invalid case: 0-1-1-1-3-2-(2),
> + */
> +int rte_eth_sched_node_add(uint8_t port_id,
> + uint32_t node_id,
> + uint32_t parent_node_id,
> + struct rte_eth_sched_node_params *params);
> +
> +/**
> + *
> + * @param port_id
> + * The port identifier of the Ethernet device.
> + * @param node_id
> + * Node ID. Needs to be valid.
> + * @param queue_id
> + * Queue ID. Needs to be valid.
> + * @return
> + * 0 on success, non-zero error code otherwise.
> + */
> +int rte_eth_sched_node_queue_set(uint8_t port_id,
> + uint32_t node_id,
> + uint32_t queue_id);
> +
In HW based implementation leaf node id == tx_queue_id as hierarchical
scheduling is tightly coupled with tx_queues(ie leaf nodes), Do we need
such translation? like specifying "queue_id" in struct rte_eth_sched_node_params ?
since tx_queues are expressed in 0..n. How about making the leaf node id as
same. There is no such translation in HW so may be it will difficult to implement.
Do we really need this translation?
Other points:
HW can't understand any SW marking schemes applied at ingress classification
level. For us, at leaf node level all packets are in color unaware mode with
input color set as green(aka (color blind mode). On the subsequent levels,HW
adds color meta on the packet based on the shapers.
With above scheme, we have few features where we need figure out how to abstract in
the generic way based on SW implementation or other HW vendors constraints.
1) If last level color meta is YELLOW, HW can mark(write) 3 bits in the packet.
It will be useful for sharing the color info across two different systems.(like
updating IP diffserv bits)
2) The need for additional shaping param called _adjust_.
Typically the conditioning and scheduling algorithm is measured in bytes of
IP packets per second. We have a _signed_ adjust(-255 to 255) field
(looks like other HW implementations also) to express packet length with reference
to L2 length. Positive value to include L1 header
(typically 20B, Ethernet preamble and Inter Frame Gap)
and negative value to express to remove L2 + VLAN header and take only IP len etc
/Jerin
Cavium
^ permalink raw reply
* Re: Port stats zero when using MLX5 DPDK driver
From: Thomas Monjalon @ 2017-01-11 13:46 UTC (permalink / raw)
To: Shahaf Shuler; +Cc: dev, george.dit
In-Reply-To: <AM4PR05MB150547DF8FA5FCB6F28ED712C3670@AM4PR05MB1505.eurprd05.prod.outlook.com>
> > On Mon, Jan 9, 2017 at 2:32 PM, Shahaf Shuler wrote:
> > It is not support on Mellanox PMD to read the primary process counters
> > from a secondary process.
It is a pity that such a basic feature is not supported.
We should try to have this kind of feature better supported across
every drivers.
2017-01-10 08:43, Shahaf Shuler:
> supporting this functionality is not on the plans.
Please could you re-consider the plans? It should not be so difficult
to give access to the stats from a secondary process.
Thanks
> If you wish to read statistics of a running process you can use ethtool –S <device_name>.
> It will provide you the statistics of the port.
> Note that those statistics count the number of bytes/packet which were
> received/sent by the port. This number may not be equal to the number
> of packet/bytes which were send/received on the PMD.
^ permalink raw reply
* Re: [PATCH v4] ethdev: fix port data mismatched in multiple process model
From: Thomas Monjalon @ 2017-01-11 13:32 UTC (permalink / raw)
To: Yuanhan Liu; +Cc: dev, stable, Bruce Richardson, Ferruh Yigit
In-Reply-To: <20170110143339.GD2402@yliu-dev.sh.intel.com>
2017-01-10 22:33, Yuanhan Liu:
> On Mon, Jan 09, 2017 at 06:08:04PM +0100, Thomas Monjalon wrote:
> > Hi Yuanhan,
> >
> > Nit: the title should be "v4 1/6"
>
> Oops, my bad.
>
> > Except that, good patch :)
> >
> > > Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
> >
> > Acked-by: Thomas Monjalon <thomas.monjalon@6wind.com>
>
> Thanks for review! Mind if I apply it to the next-virtio tree?
Yes, please do.
^ permalink raw reply
* Re: [PATCH v8 00/25] Support VFD on i40e
From: Vincent JARDIN @ 2017-01-11 13:14 UTC (permalink / raw)
To: Ferruh Yigit, Zhang, Helin, Lu, Wenzhuo, dev
Cc: 'JOSHI, KAUSTUBH', 'DANIELS, EDWARD',
'ZELEZNIAK, ALEX'
In-Reply-To: <f5290bd1-e968-ae6b-d9c8-2104da11f84b@intel.com>
Le 10/01/2017 à 22:32, Ferruh Yigit a écrit :
> What do you think to continue high level DPDK PF discussion in mail
> thread for other pathset? So that we can continue to work on this one.
First, we need to assess or not if it makes sense to go toward Linux
kernel or DPDK based PF. If Linux kernel is used, then DPDK does not
need VFD related modifications.
VFD demonstrates that there are some needs of features, but it pushes
the new path of a fork of PF drivers.
^ permalink raw reply
* Re: [PATCH v4] null: fake PMD capabilities
From: Ferruh Yigit @ 2017-01-11 12:23 UTC (permalink / raw)
To: Michał Mirosław; +Cc: dev
In-Reply-To: <20170111101413.nwfapc4grnrbzvmv@rere.qmqm.pl>
On 1/11/2017 10:14 AM, Michał Mirosław wrote:
> On Mon, Jan 09, 2017 at 12:07:36PM +0000, Ferruh Yigit wrote:
>> On 12/14/2016 7:16 PM, Michał Mirosław wrote:
>>> From: Paweł Małachowski <pawel.malachowski@atendesoftware.pl>
>>>
>>> This allows for testing code which needs offloads to be supported.
>>>
>>> Signed-off-by: Michał Mirosław <michal.miroslaw@atendesoftware.pl>
>>> ---
>>> drivers/net/null/rte_eth_null.c | 23 ++++++++++++++++++++++-
>>> 1 file changed, 22 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
>>> index 836d982..e60516f 100644
>>> --- a/drivers/net/null/rte_eth_null.c
>>> +++ b/drivers/net/null/rte_eth_null.c
>>> @@ -284,6 +284,9 @@ eth_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,
>>> return 0;
>>> }
>>>
>>> +static void
>>> +eth_dev_void_ok(struct rte_eth_dev *dev __rte_unused) { return; }
>>> +
>>>
>>> static void
>>> eth_dev_info(struct rte_eth_dev *dev,
>>> @@ -304,6 +307,19 @@ eth_dev_info(struct rte_eth_dev *dev,
>>> dev_info->pci_dev = NULL;
>>> dev_info->reta_size = internals->reta_size;
>>> dev_info->flow_type_rss_offloads = internals->flow_type_rss_offloads;
>>> + /* We hereby declare we can RX offload VLAN-s out of thin air (they are not there)
>>> + */
>>> + dev_info->rx_offload_capa = DEV_RX_OFFLOAD_VLAN_STRIP |
>>> + DEV_RX_OFFLOAD_QINQ_STRIP;
>>> + /* We promise we will do any TX offloads before passing packets to /dev/null
>>> + */
>>> + dev_info->tx_offload_capa = DEV_TX_OFFLOAD_VLAN_INSERT |
>>> + DEV_TX_OFFLOAD_IPV4_CKSUM | DEV_TX_OFFLOAD_UDP_CKSUM |
>>> + DEV_TX_OFFLOAD_TCP_CKSUM | DEV_TX_OFFLOAD_SCTP_CKSUM |
>>> + DEV_TX_OFFLOAD_TCP_TSO | DEV_TX_OFFLOAD_UDP_TSO |
>>> + DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM | DEV_TX_OFFLOAD_QINQ_INSERT |
>>> + DEV_TX_OFFLOAD_VXLAN_TNL_TSO | DEV_TX_OFFLOAD_GRE_TNL_TSO |
>>> + DEV_TX_OFFLOAD_IPIP_TNL_TSO | DEV_TX_OFFLOAD_GENEVE_TNL_TSO;
>>
>> What do you think reporting offload capa based on user provided devargs,
>> as suggested by Konstantin?And by default not report any.
>
> I can see use of it for people that want to test software fallbacks for
> their app. For those who need only a /dev/null port, it doesn't add any value.
That would help if user want to test some combination of offload flags,
instead of having all.
>
> Best Regards,
> Michał Mirosław
>
^ permalink raw reply
* Re: [PATCH v8 00/25] Support VFD on i40e
From: Vincent Jardin @ 2017-01-11 11:03 UTC (permalink / raw)
To: JOSHI, KAUSTUBH (KAUSTUBH)
Cc: Zhang, Helin, Lu, Wenzhuo, dev, DANIELS, EDWARD S (EDWARD),
ZELEZNIAK, ALEX
In-Reply-To: <A7AD7EDA-482C-4B3C-A5E8-54C9CB7F66E7@research.att.com>
Please can you list the gaps of the Kernel API?
Thank you,
Vincent
Le 11 janvier 2017 3:59:45 AM "JOSHI, KAUSTUBH (KAUSTUBH)"
<kaustubh@research.att.com> a écrit :
> Hi Vincent,
>
> Greetings! Jumping into this debate a bit late, but let me share our point
> of view based on how we are using this code within AT&T for our NFV cloud.
>
> Actually, we first started with trying to do the configuration within the
> kernel drivers as you suggest, but quickly realized that besides the
> practical problem of kernel upstreaming being a much more arduous road
> (which can be overcome), the bigger problem was that there is no
> standardization in the configuration interfaces for the NICs in the kernel
> community. So different drivers do things differently and expose different
> settings, and no forum exists to drive towards such standardization. This
> was leading to vendors have to maintain patched versions of drivers for
> doing PF configuration, which is not a desirable situation.
>
> So, to build a portable (to multiple NICs) SRIOV VF manager like VFd, DPDK
> seemed like a good a forum with some hope for driving towards a standard
> set of interfaces and without having to worry about a lot of legacy baggage
> and old hardware. Especially since DPDK already takes on the role of
> configuring NICs for the data plane functions anyway - both PF and VF
> drivers will have to be included for data plane usage anyway - we viewed
> that adding VF config options will not cause any forking, but simply flush
> out the DPDK drivers and their interfaces to be more complete. These APIs
> could be optional, so new vendors aren’t obligated to add them.
>
> Furthermore, allowing VF config using the DPDK PF driver also has the side
> benefit of allowing a complete SRIOV system (both VF and PF) to be built
> entirely with DPDK, also making version alignment easier.
>
> We started with Niantic, which already had PF and VF drivers, and things
> have worked out very well with it. However, we would like VFd to be a
> multi-NIC vendor agnostic VF management tool, which is why we’ve been
> asking for making the PF config APIs richer.
>
> Regards
>
> KJ
>
>
>> On Jan 10, 2017, at 3:23 PM, Vincent Jardin <vincent.jardin@6wind.com> wrote:
>>
>> Nope. First one needs to assess if DPDK should be intensively used to
>> become a PF knowing Linux can do the jobs. Linux kernel community does not
>> like the forking of Kernel drivers, I tend to agree that we should not keep
>> duplicating options that can be solved with the Linux kernel.
>>
>> Best regards,
>> Vincent
>>
>>
>
^ permalink raw reply
* Re: [PATCH] kni: use bulk functions to allocate and free mbufs
From: Ananyev, Konstantin @ 2017-01-11 10:39 UTC (permalink / raw)
To: Sergey Vyazmitinov, olivier.matz@6wind.com; +Cc: Yigit, Ferruh, dev@dpdk.org
In-Reply-To: <1483048216-2936-1-git-send-email-s.vyazmitinov@brain4net.com>
Hi Sergey,
...
> diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
> index 4476d75..707c300 100644
> --- a/lib/librte_mbuf/rte_mbuf.h
> +++ b/lib/librte_mbuf/rte_mbuf.h
> @@ -1261,6 +1261,38 @@ static inline void rte_pktmbuf_free(struct rte_mbuf *m)
> }
>
> /**
> + * Free n packets mbuf back into its original mempool.
> + *
> + * Free each mbuf, and all its segments in case of chained buffers. Each
> + * segment is added back into its original mempool.
> + *
> + * @param mp
> + * The packets mempool.
> + * @param mbufs
> + * The packets mbufs array to be freed.
> + * @param n
> + * Number of packets.
> + */
> +static inline void rte_pktmbuf_free_bulk(struct rte_mempool *mp,
> + struct rte_mbuf **mbufs, unsigned n)
> +{
> + struct rte_mbuf *mbuf, *m_next;
> + unsigned i;
> + for (i = 0; i < n; ++i) {
> + mbuf = mbufs[i];
> + __rte_mbuf_sanity_check(mbuf, 1);
> +
> + mbuf = mbuf->next;
> + while (mbuf != NULL) {
> + m_next = mbuf->next;
> + rte_pktmbuf_free_seg(mbuf);
> + mbuf = m_next;
> + }
I think you forgot to call __rte_pktmbuf_prefree_seg(mbufs[i]); somewhere here.
Konstantin
> + }
> + rte_mempool_put_bulk(mp, (void * const *)mbufs, n);
> +}
> +
> +/**
> * Creates a "clone" of the given packet mbuf.
> *
> * Walks through all segments of the given packet mbuf, and for each of them:
> diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h
> index d315d42..e612a0a 100644
> --- a/lib/librte_mempool/rte_mempool.h
> +++ b/lib/librte_mempool/rte_mempool.h
> @@ -1497,6 +1497,12 @@ rte_mempool_get(struct rte_mempool *mp, void **obj_p)
> return rte_mempool_get_bulk(mp, obj_p, 1);
> }
>
> +static inline int __attribute__((always_inline))
> +rte_mempool_get_n(struct rte_mempool *mp, void **obj_p, int n)
> +{
> + return rte_mempool_get_bulk(mp, obj_p, n);
> +}
> +
> /**
> * Return the number of entries in the mempool.
> *
> --
> 2.7.4
^ permalink raw reply
* Re: [PATCH] app/testpmd: fix ixgbe private API calling
From: Iremonger, Bernard @ 2017-01-11 10:27 UTC (permalink / raw)
To: Lu, Wenzhuo, dev@dpdk.org; +Cc: Wu, Jingjing, stable@dpdk.org
In-Reply-To: <1484102853-53205-1-git-send-email-wenzhuo.lu@intel.com>
Hi Wenzhuo,
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Wenzhuo Lu
> Sent: Wednesday, January 11, 2017 2:48 AM
> To: dev@dpdk.org
> Cc: Wu, Jingjing <jingjing.wu@intel.com>; Lu, Wenzhuo
> <wenzhuo.lu@intel.com>; stable@dpdk.org
> Subject: [dpdk-dev] [PATCH] app/testpmd: fix ixgbe private API calling
>
> Some ixgbe private APIs are added to expose ixgbe specific functions.
> When they're used by testpmd, there's no check for if the NICs are ixgbe.
> Other NICs also have chance to call these APIs.
> This patch add the check and the feedback print.
I am not sure that testpmd is the right place to do this.
The rte_pmd_ixgbe_* functions are public API's which can be called by other applications.
The checks should be in the rte_pmd_ixgbe_* API's
> Fixes: 425781ff5afe ("app/testpmd: add ixgbe VF management")
>
> CC: stable@dpdk.org
> Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
> ---
> app/test-pmd/cmdline.c | 101
> +++++++++++++++++++++++++++++++++++++++----------
> 1 file changed, 81 insertions(+), 20 deletions(-)
>
> diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index
> f768b6b..172861a 100644
> --- a/app/test-pmd/cmdline.c
> +++ b/app/test-pmd/cmdline.c
> @@ -10883,11 +10883,16 @@ struct cmd_vf_vlan_anti_spoof_result {
> __attribute__((unused)) void *data)
> {
> struct cmd_vf_vlan_anti_spoof_result *res = parsed_result;
> - int ret = 0;
> + int ret = -ENOTSUP;
> int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
> + struct rte_eth_dev_info dev_info;
>
> - ret = rte_pmd_ixgbe_set_vf_vlan_anti_spoof(res->port_id, res-
> >vf_id,
> - is_on);
> + rte_eth_dev_info_get(res->port_id, &dev_info);
> +
> + if (strstr(dev_info.driver_name, "ixgbe") != NULL)
> + ret = rte_pmd_ixgbe_set_vf_vlan_anti_spoof(res->port_id,
> + res->vf_id,
> + is_on);
> switch (ret) {
> case 0:
> break;
> @@ -10897,6 +10902,9 @@ struct cmd_vf_vlan_anti_spoof_result {
> case -ENODEV:
> printf("invalid port_id %d\n", res->port_id);
> break;
> + case -ENOTSUP:
> + printf("function not implemented\n");
> + break;
> default:
> printf("programming error: (%s)\n", strerror(-ret));
> }
> @@ -10968,11 +10976,16 @@ struct cmd_vf_mac_anti_spoof_result {
> __attribute__((unused)) void *data)
> {
> struct cmd_vf_mac_anti_spoof_result *res = parsed_result;
> - int ret;
> + int ret = -ENOTSUP;
> int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
> + struct rte_eth_dev_info dev_info;
>
> - ret = rte_pmd_ixgbe_set_vf_mac_anti_spoof(res->port_id, res-
> >vf_id,
> - is_on);
> + rte_eth_dev_info_get(res->port_id, &dev_info);
> +
> + if (strstr(dev_info.driver_name, "ixgbe") != NULL)
> + ret = rte_pmd_ixgbe_set_vf_mac_anti_spoof(res->port_id,
> + res->vf_id,
> + is_on);
> switch (ret) {
> case 0:
> break;
> @@ -10982,6 +10995,9 @@ struct cmd_vf_mac_anti_spoof_result {
> case -ENODEV:
> printf("invalid port_id %d\n", res->port_id);
> break;
> + case -ENOTSUP:
> + printf("function not implemented\n");
> + break;
> default:
> printf("programming error: (%s)\n", strerror(-ret));
> }
> @@ -11053,10 +11069,15 @@ struct cmd_vf_vlan_stripq_result {
> __attribute__((unused)) void *data)
> {
> struct cmd_vf_vlan_stripq_result *res = parsed_result;
> - int ret = 0;
> + int ret = -ENOTSUP;
> int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
> + struct rte_eth_dev_info dev_info;
>
> - ret = rte_pmd_ixgbe_set_vf_vlan_stripq(res->port_id, res->vf_id,
> is_on);
> + rte_eth_dev_info_get(res->port_id, &dev_info);
> +
> + if (strstr(dev_info.driver_name, "ixgbe") != NULL)
> + ret = rte_pmd_ixgbe_set_vf_vlan_stripq(res->port_id, res-
> >vf_id,
> + is_on);
> switch (ret) {
> case 0:
> break;
> @@ -11066,6 +11087,9 @@ struct cmd_vf_vlan_stripq_result {
> case -ENODEV:
> printf("invalid port_id %d\n", res->port_id);
> break;
> + case -ENOTSUP:
> + printf("function not implemented\n");
> + break;
> default:
> printf("programming error: (%s)\n", strerror(-ret));
> }
> @@ -11137,9 +11161,14 @@ struct cmd_vf_vlan_insert_result {
> __attribute__((unused)) void *data)
> {
> struct cmd_vf_vlan_insert_result *res = parsed_result;
> - int ret;
> + int ret = -ENOTSUP;
> + struct rte_eth_dev_info dev_info;
>
> - ret = rte_pmd_ixgbe_set_vf_vlan_insert(res->port_id, res->vf_id,
> res->vlan_id);
> + rte_eth_dev_info_get(res->port_id, &dev_info);
> +
> + if (strstr(dev_info.driver_name, "ixgbe") != NULL)
> + ret = rte_pmd_ixgbe_set_vf_vlan_insert(res->port_id, res-
> >vf_id,
> + res->vlan_id);
> switch (ret) {
> case 0:
> break;
> @@ -11149,6 +11178,9 @@ struct cmd_vf_vlan_insert_result {
> case -ENODEV:
> printf("invalid port_id %d\n", res->port_id);
> break;
> + case -ENOTSUP:
> + printf("function not implemented\n");
> + break;
> default:
> printf("programming error: (%s)\n", strerror(-ret));
> }
> @@ -11210,10 +11242,14 @@ struct cmd_tx_loopback_result {
> __attribute__((unused)) void *data)
> {
> struct cmd_tx_loopback_result *res = parsed_result;
> - int ret;
> + int ret = -ENOTSUP;
> int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
> + struct rte_eth_dev_info dev_info;
>
> - ret = rte_pmd_ixgbe_set_tx_loopback(res->port_id, is_on);
> + rte_eth_dev_info_get(res->port_id, &dev_info);
> +
> + if (strstr(dev_info.driver_name, "ixgbe") != NULL)
> + ret = rte_pmd_ixgbe_set_tx_loopback(res->port_id, is_on);
> switch (ret) {
> case 0:
> break;
> @@ -11223,6 +11259,9 @@ struct cmd_tx_loopback_result {
> case -ENODEV:
> printf("invalid port_id %d\n", res->port_id);
> break;
> + case -ENOTSUP:
> + printf("function not implemented\n");
> + break;
> default:
> printf("programming error: (%s)\n", strerror(-ret));
> }
> @@ -11287,10 +11326,14 @@ struct cmd_all_queues_drop_en_result {
> __attribute__((unused)) void *data)
> {
> struct cmd_all_queues_drop_en_result *res = parsed_result;
> - int ret = 0;
> + int ret = -ENOTSUP;
> int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
> + struct rte_eth_dev_info dev_info;
>
> - ret = rte_pmd_ixgbe_set_all_queues_drop_en(res->port_id, is_on);
> + rte_eth_dev_info_get(res->port_id, &dev_info);
> +
> + if (strstr(dev_info.driver_name, "ixgbe") != NULL)
> + ret = rte_pmd_ixgbe_set_all_queues_drop_en(res-
> >port_id, is_on);
> switch (ret) {
> case 0:
> break;
> @@ -11300,6 +11343,9 @@ struct cmd_all_queues_drop_en_result {
> case -ENODEV:
> printf("invalid port_id %d\n", res->port_id);
> break;
> + case -ENOTSUP:
> + printf("function not implemented\n");
> + break;
> default:
> printf("programming error: (%s)\n", strerror(-ret));
> }
> @@ -11370,11 +11416,16 @@ struct cmd_vf_split_drop_en_result {
> __attribute__((unused)) void *data)
> {
> struct cmd_vf_split_drop_en_result *res = parsed_result;
> - int ret;
> + int ret = -ENOTSUP;
> int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
> + struct rte_eth_dev_info dev_info;
>
> - ret = rte_pmd_ixgbe_set_vf_split_drop_en(res->port_id, res-
> >vf_id,
> - is_on);
> + rte_eth_dev_info_get(res->port_id, &dev_info);
> +
> + if (strstr(dev_info.driver_name, "ixgbe") != NULL)
> + ret = rte_pmd_ixgbe_set_vf_split_drop_en(res->port_id,
> + res->vf_id,
> + is_on);
> switch (ret) {
> case 0:
> break;
> @@ -11384,6 +11435,9 @@ struct cmd_vf_split_drop_en_result {
> case -ENODEV:
> printf("invalid port_id %d\n", res->port_id);
> break;
> + case -ENOTSUP:
> + printf("function not implemented\n");
> + break;
> default:
> printf("programming error: (%s)\n", strerror(-ret));
> }
> @@ -11455,10 +11509,14 @@ struct cmd_set_vf_mac_addr_result {
> __attribute__((unused)) void *data)
> {
> struct cmd_set_vf_mac_addr_result *res = parsed_result;
> - int ret;
> + int ret = -ENOTSUP;
> + struct rte_eth_dev_info dev_info;
>
> - ret = rte_pmd_ixgbe_set_vf_mac_addr(res->port_id, res->vf_id,
> - &res->mac_addr);
> + rte_eth_dev_info_get(res->port_id, &dev_info);
> +
> + if (strstr(dev_info.driver_name, "ixgbe") != NULL)
> + ret = rte_pmd_ixgbe_set_vf_mac_addr(res->port_id, res-
> >vf_id,
> + &res->mac_addr);
> switch (ret) {
> case 0:
> break;
> @@ -11468,6 +11526,9 @@ struct cmd_set_vf_mac_addr_result {
> case -ENODEV:
> printf("invalid port_id %d\n", res->port_id);
> break;
> + case -ENOTSUP:
> + printf("function not implemented\n");
> + break;
> default:
> printf("programming error: (%s)\n", strerror(-ret));
> }
> --
> 1.9.3
Regards,
Bernard.
^ permalink raw reply
* Re: [PATCH v4] null: fake PMD capabilities
From: Michał Mirosław @ 2017-01-11 10:14 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: dev
In-Reply-To: <8d189949-27dc-b557-6fbc-f9d07fbd5296@intel.com>
On Mon, Jan 09, 2017 at 12:07:36PM +0000, Ferruh Yigit wrote:
> On 12/14/2016 7:16 PM, Michał Mirosław wrote:
> > From: Paweł Małachowski <pawel.malachowski@atendesoftware.pl>
> >
> > This allows for testing code which needs offloads to be supported.
> >
> > Signed-off-by: Michał Mirosław <michal.miroslaw@atendesoftware.pl>
> > ---
> > drivers/net/null/rte_eth_null.c | 23 ++++++++++++++++++++++-
> > 1 file changed, 22 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
> > index 836d982..e60516f 100644
> > --- a/drivers/net/null/rte_eth_null.c
> > +++ b/drivers/net/null/rte_eth_null.c
> > @@ -284,6 +284,9 @@ eth_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,
> > return 0;
> > }
> >
> > +static void
> > +eth_dev_void_ok(struct rte_eth_dev *dev __rte_unused) { return; }
> > +
> >
> > static void
> > eth_dev_info(struct rte_eth_dev *dev,
> > @@ -304,6 +307,19 @@ eth_dev_info(struct rte_eth_dev *dev,
> > dev_info->pci_dev = NULL;
> > dev_info->reta_size = internals->reta_size;
> > dev_info->flow_type_rss_offloads = internals->flow_type_rss_offloads;
> > + /* We hereby declare we can RX offload VLAN-s out of thin air (they are not there)
> > + */
> > + dev_info->rx_offload_capa = DEV_RX_OFFLOAD_VLAN_STRIP |
> > + DEV_RX_OFFLOAD_QINQ_STRIP;
> > + /* We promise we will do any TX offloads before passing packets to /dev/null
> > + */
> > + dev_info->tx_offload_capa = DEV_TX_OFFLOAD_VLAN_INSERT |
> > + DEV_TX_OFFLOAD_IPV4_CKSUM | DEV_TX_OFFLOAD_UDP_CKSUM |
> > + DEV_TX_OFFLOAD_TCP_CKSUM | DEV_TX_OFFLOAD_SCTP_CKSUM |
> > + DEV_TX_OFFLOAD_TCP_TSO | DEV_TX_OFFLOAD_UDP_TSO |
> > + DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM | DEV_TX_OFFLOAD_QINQ_INSERT |
> > + DEV_TX_OFFLOAD_VXLAN_TNL_TSO | DEV_TX_OFFLOAD_GRE_TNL_TSO |
> > + DEV_TX_OFFLOAD_IPIP_TNL_TSO | DEV_TX_OFFLOAD_GENEVE_TNL_TSO;
>
> What do you think reporting offload capa based on user provided devargs,
> as suggested by Konstantin?And by default not report any.
I can see use of it for people that want to test software fallbacks for
their app. For those who need only a /dev/null port, it doesn't add any value.
Best Regards,
Michał Mirosław
^ permalink raw reply
* [PATCH] i40e: improve message grepability
From: Michał Mirosław @ 2017-01-11 9:49 UTC (permalink / raw)
To: dev
In-Reply-To: <39ceb2bf1e5aa61e3957a8d8f9e5b2df28d6d2ad.1481590851.git.mirq-linux@rere.qmqm.pl>
Join message lines for easier grepping.
PRIxXX are left glued to strings as they are in other parts of the file.
Signed-off-by: Michał Mirosław <michal.miroslaw@atendesoftware.pl>
---
drivers/net/i40e/i40e_ethdev.c | 308 +++++++++++++++++++++--------------------
1 file changed, 160 insertions(+), 148 deletions(-)
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index db2aebdb..00c15f87 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -764,8 +764,8 @@ i40e_add_tx_flow_control_drop_filter(struct i40e_pf *pf)
pf->main_vsi_seid, 0,
TRUE, NULL, NULL);
if (ret)
- PMD_INIT_LOG(ERR, "Failed to add filter to drop flow control "
- " frames from VSIs.");
+ PMD_INIT_LOG(ERR,
+ "Failed to add filter to drop flow control frames from VSIs.");
}
static int
@@ -967,8 +967,8 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
hw->back = I40E_PF_TO_ADAPTER(pf);
hw->hw_addr = (uint8_t *)(pci_dev->mem_resource[0].addr);
if (!hw->hw_addr) {
- PMD_INIT_LOG(ERR, "Hardware is not available, "
- "as address is NULL");
+ PMD_INIT_LOG(ERR,
+ "Hardware is not available, as address is NULL");
return -ENODEV;
}
@@ -1104,8 +1104,8 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
/* Set the global registers with default ether type value */
ret = i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_OUTER, ETHER_TYPE_VLAN);
if (ret != I40E_SUCCESS) {
- PMD_INIT_LOG(ERR, "Failed to set the default outer "
- "VLAN ether type");
+ PMD_INIT_LOG(ERR,
+ "Failed to set the default outer VLAN ether type");
goto err_setup_pf_switch;
}
@@ -1141,8 +1141,8 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
/* Should be after VSI initialized */
dev->data->mac_addrs = rte_zmalloc("i40e", len, 0);
if (!dev->data->mac_addrs) {
- PMD_INIT_LOG(ERR, "Failed to allocated memory "
- "for storing mac address");
+ PMD_INIT_LOG(ERR,
+ "Failed to allocated memory for storing mac address");
goto err_mac_alloc;
}
ether_addr_copy((struct ether_addr *)hw->mac.perm_addr,
@@ -1714,8 +1714,9 @@ i40e_dev_start(struct rte_eth_dev *dev)
dev->data->nb_rx_queues * sizeof(int),
0);
if (!intr_handle->intr_vec) {
- PMD_INIT_LOG(ERR, "Failed to allocate %d rx_queues"
- " intr_vec\n", dev->data->nb_rx_queues);
+ PMD_INIT_LOG(ERR,
+ "Failed to allocate %d rx_queues intr_vec\n",
+ dev->data->nb_rx_queues);
return -ENOMEM;
}
}
@@ -1788,8 +1789,8 @@ i40e_dev_start(struct rte_eth_dev *dev)
i40e_pf_enable_irq0(hw);
if (dev->data->dev_conf.intr_conf.lsc != 0)
- PMD_INIT_LOG(INFO, "lsc won't enable because of"
- " no intr multiplex\n");
+ PMD_INIT_LOG(INFO,
+ "lsc won't enable because of no intr multiplex\n");
} else if (dev->data->dev_conf.intr_conf.lsc != 0) {
ret = i40e_aq_set_phy_int_mask(hw,
~(I40E_AQ_EVENT_LINK_UPDOWN |
@@ -2740,13 +2741,15 @@ i40e_vlan_tpid_set(struct rte_eth_dev *dev,
ret = i40e_aq_debug_read_register(hw, I40E_GL_SWT_L2TAGCTRL(reg_id),
®_r, NULL);
if (ret != I40E_SUCCESS) {
- PMD_DRV_LOG(ERR, "Fail to debug read from "
- "I40E_GL_SWT_L2TAGCTRL[%d]", reg_id);
+ PMD_DRV_LOG(ERR,
+ "Fail to debug read from I40E_GL_SWT_L2TAGCTRL[%d]",
+ reg_id);
ret = -EIO;
return ret;
}
- PMD_DRV_LOG(DEBUG, "Debug read from I40E_GL_SWT_L2TAGCTRL[%d]: "
- "0x%08"PRIx64"", reg_id, reg_r);
+ PMD_DRV_LOG(DEBUG,
+ "Debug read from I40E_GL_SWT_L2TAGCTRL[%d]: 0x%08"PRIx64,
+ reg_id, reg_r);
reg_w = reg_r & (~(I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_MASK));
reg_w |= ((uint64_t)tpid << I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_SHIFT);
@@ -2760,12 +2763,14 @@ i40e_vlan_tpid_set(struct rte_eth_dev *dev,
reg_w, NULL);
if (ret != I40E_SUCCESS) {
ret = -EIO;
- PMD_DRV_LOG(ERR, "Fail to debug write to "
- "I40E_GL_SWT_L2TAGCTRL[%d]", reg_id);
+ PMD_DRV_LOG(ERR,
+ "Fail to debug write to I40E_GL_SWT_L2TAGCTRL[%d]",
+ reg_id);
return ret;
}
- PMD_DRV_LOG(DEBUG, "Debug write 0x%08"PRIx64" to "
- "I40E_GL_SWT_L2TAGCTRL[%d]", reg_w, reg_id);
+ PMD_DRV_LOG(DEBUG,
+ "Debug write 0x%08"PRIx64" to I40E_GL_SWT_L2TAGCTRL[%d]",
+ reg_w, reg_id);
return ret;
}
@@ -2909,8 +2914,9 @@ i40e_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
max_high_water = I40E_RXPBSIZE >> I40E_KILOSHIFT;
if ((fc_conf->high_water > max_high_water) ||
(fc_conf->high_water < fc_conf->low_water)) {
- PMD_INIT_LOG(ERR, "Invalid high/low water setup value in KB, "
- "High_water must <= %d.", max_high_water);
+ PMD_INIT_LOG(ERR,
+ "Invalid high/low water setup value in KB, High_water must be <= %d.",
+ max_high_water);
return -EINVAL;
}
@@ -3082,8 +3088,8 @@ i40e_macaddr_remove(struct rte_eth_dev *dev, uint32_t index)
/* No VMDQ pool enabled or configured */
if (!(pf->flags & I40E_FLAG_VMDQ) ||
(i > pf->nb_cfg_vmdq_vsi)) {
- PMD_DRV_LOG(ERR, "No VMDQ pool enabled"
- "/configured");
+ PMD_DRV_LOG(ERR,
+ "No VMDQ pool enabled/configured");
return;
}
vsi = pf->vmdq[i - 1].vsi;
@@ -3284,9 +3290,9 @@ i40e_dev_rss_reta_update(struct rte_eth_dev *dev,
if (reta_size != lut_size ||
reta_size > ETH_RSS_RETA_SIZE_512) {
- PMD_DRV_LOG(ERR, "The size of hash lookup table configured "
- "(%d) doesn't match the number hardware can supported "
- "(%d)\n", reta_size, lut_size);
+ PMD_DRV_LOG(ERR,
+ "The size of hash lookup table configured (%d) doesn't match the number hardware can supported (%d)\n",
+ reta_size, lut_size);
return -EINVAL;
}
@@ -3325,9 +3331,9 @@ i40e_dev_rss_reta_query(struct rte_eth_dev *dev,
if (reta_size != lut_size ||
reta_size > ETH_RSS_RETA_SIZE_512) {
- PMD_DRV_LOG(ERR, "The size of hash lookup table configured "
- "(%d) doesn't match the number hardware can supported "
- "(%d)\n", reta_size, lut_size);
+ PMD_DRV_LOG(ERR,
+ "The size of hash lookup table configured (%d) doesn't match the number hardware can supported (%d)\n",
+ reta_size, lut_size);
return -EINVAL;
}
@@ -3382,8 +3388,9 @@ i40e_allocate_dma_mem_d(__attribute__((unused)) struct i40e_hw *hw,
mem->va = mz->addr;
mem->pa = rte_mem_phy2mch(mz->memseg_id, mz->phys_addr);
mem->zone = (const void *)mz;
- PMD_DRV_LOG(DEBUG, "memzone %s allocated with physical address: "
- "%"PRIu64, mz->name, mem->pa);
+ PMD_DRV_LOG(DEBUG,
+ "memzone %s allocated with physical address: %"PRIu64,
+ mz->name, mem->pa);
return I40E_SUCCESS;
}
@@ -3400,9 +3407,9 @@ i40e_free_dma_mem_d(__attribute__((unused)) struct i40e_hw *hw,
if (!mem)
return I40E_ERR_PARAM;
- PMD_DRV_LOG(DEBUG, "memzone %s to be freed with physical address: "
- "%"PRIu64, ((const struct rte_memzone *)mem->zone)->name,
- mem->pa);
+ PMD_DRV_LOG(DEBUG,
+ "memzone %s to be freed with physical address: %"PRIu64,
+ ((const struct rte_memzone *)mem->zone)->name, mem->pa);
rte_memzone_free((const struct rte_memzone *)mem->zone);
mem->zone = NULL;
mem->va = NULL;
@@ -3561,8 +3568,9 @@ i40e_pf_parameter_init(struct rte_eth_dev *dev)
pf->flags |= I40E_FLAG_SRIOV;
pf->vf_nb_qps = RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF;
pf->vf_num = pci_dev->max_vfs;
- PMD_DRV_LOG(DEBUG, "%u VF VSIs, %u queues per VF VSI, "
- "in total %u queues", pf->vf_num, pf->vf_nb_qps,
+ PMD_DRV_LOG(DEBUG,
+ "%u VF VSIs, %u queues per VF VSI, in total %u queues",
+ pf->vf_num, pf->vf_nb_qps,
pf->vf_nb_qps * pf->vf_num);
} else {
pf->vf_nb_qps = 0;
@@ -3591,14 +3599,14 @@ i40e_pf_parameter_init(struct rte_eth_dev *dev)
if (pf->max_nb_vmdq_vsi) {
pf->flags |= I40E_FLAG_VMDQ;
pf->vmdq_nb_qps = pf->vmdq_nb_qp_max;
- PMD_DRV_LOG(DEBUG, "%u VMDQ VSIs, %u queues "
- "per VMDQ VSI, in total %u queues",
+ PMD_DRV_LOG(DEBUG,
+ "%u VMDQ VSIs, %u queues per VMDQ VSI, in total %u queues",
pf->max_nb_vmdq_vsi,
pf->vmdq_nb_qps, pf->vmdq_nb_qps *
pf->max_nb_vmdq_vsi);
} else {
- PMD_DRV_LOG(INFO, "No enough queues left for "
- "VMDq");
+ PMD_DRV_LOG(INFO,
+ "No enough queues left for VMDq");
}
} else {
PMD_DRV_LOG(INFO, "No queue or VSI left for VMDq");
@@ -3611,15 +3619,15 @@ i40e_pf_parameter_init(struct rte_eth_dev *dev)
pf->flags |= I40E_FLAG_DCB;
if (qp_count > hw->func_caps.num_tx_qp) {
- PMD_DRV_LOG(ERR, "Failed to allocate %u queues, which exceeds "
- "the hardware maximum %u", qp_count,
- hw->func_caps.num_tx_qp);
+ PMD_DRV_LOG(ERR,
+ "Failed to allocate %u queues, which exceeds the hardware maximum %u",
+ qp_count, hw->func_caps.num_tx_qp);
return -EINVAL;
}
if (vsi_count > hw->func_caps.num_vsis) {
- PMD_DRV_LOG(ERR, "Failed to allocate %u VSIs, which exceeds "
- "the hardware maximum %u", vsi_count,
- hw->func_caps.num_vsis);
+ PMD_DRV_LOG(ERR,
+ "Failed to allocate %u VSIs, which exceeds the hardware maximum %u",
+ vsi_count, hw->func_caps.num_vsis);
return -EINVAL;
}
@@ -3865,8 +3873,8 @@ i40e_res_pool_alloc(struct i40e_res_pool_info *pool,
*/
entry = rte_zmalloc("res_pool", sizeof(*entry), 0);
if (entry == NULL) {
- PMD_DRV_LOG(ERR, "Failed to allocate memory for "
- "resource pool");
+ PMD_DRV_LOG(ERR,
+ "Failed to allocate memory for resource pool");
return -ENOMEM;
}
entry->base = valid_entry->base;
@@ -3906,9 +3914,9 @@ validate_tcmap_parameter(struct i40e_vsi *vsi, uint8_t enabled_tcmap)
}
if (!bitmap_is_subset(hw->func_caps.enabled_tcmap, enabled_tcmap)) {
- PMD_DRV_LOG(ERR, "Enabled TC map 0x%x not applicable to "
- "HW support 0x%x", hw->func_caps.enabled_tcmap,
- enabled_tcmap);
+ PMD_DRV_LOG(ERR,
+ "Enabled TC map 0x%x not applicable to HW support 0x%x",
+ hw->func_caps.enabled_tcmap, enabled_tcmap);
return I40E_NOT_SUPPORTED;
}
return I40E_SUCCESS;
@@ -4250,8 +4258,8 @@ i40e_update_default_filter_setting(struct i40e_vsi *vsi)
struct i40e_mac_filter *f;
struct ether_addr *mac;
- PMD_DRV_LOG(WARNING, "Cannot remove the default "
- "macvlan filter");
+ PMD_DRV_LOG(WARNING,
+ "Cannot remove the default macvlan filter");
/* It needs to add the permanent mac into mac list */
f = rte_zmalloc("macv_filter", sizeof(*f), 0);
if (f == NULL) {
@@ -4301,8 +4309,9 @@ i40e_vsi_get_bw_config(struct i40e_vsi *vsi)
ret = i40e_aq_query_vsi_ets_sla_config(hw, vsi->seid,
&ets_sla_config, NULL);
if (ret != I40E_SUCCESS) {
- PMD_DRV_LOG(ERR, "VSI failed to get TC bandwdith "
- "configuration %u", hw->aq.asq_last_status);
+ PMD_DRV_LOG(ERR,
+ "VSI failed to get TC bandwdith configuration %u",
+ hw->aq.asq_last_status);
return ret;
}
@@ -4390,14 +4399,14 @@ i40e_vsi_setup(struct i40e_pf *pf,
if (type != I40E_VSI_MAIN && type != I40E_VSI_SRIOV &&
uplink_vsi == NULL) {
- PMD_DRV_LOG(ERR, "VSI setup failed, "
- "VSI link shouldn't be NULL");
+ PMD_DRV_LOG(ERR,
+ "VSI setup failed, VSI link shouldn't be NULL");
return NULL;
}
if (type == I40E_VSI_MAIN && uplink_vsi != NULL) {
- PMD_DRV_LOG(ERR, "VSI setup failed, MAIN VSI "
- "uplink VSI should be NULL");
+ PMD_DRV_LOG(ERR,
+ "VSI setup failed, MAIN VSI uplink VSI should be NULL");
return NULL;
}
@@ -4548,8 +4557,8 @@ i40e_vsi_setup(struct i40e_pf *pf,
ret = i40e_vsi_config_tc_queue_mapping(vsi, &ctxt.info,
I40E_DEFAULT_TCMAP);
if (ret != I40E_SUCCESS) {
- PMD_DRV_LOG(ERR, "Failed to configure "
- "TC queue mapping");
+ PMD_DRV_LOG(ERR,
+ "Failed to configure TC queue mapping");
goto fail_msix_alloc;
}
ctxt.seid = vsi->seid;
@@ -4619,8 +4628,8 @@ i40e_vsi_setup(struct i40e_pf *pf,
ret = i40e_vsi_config_tc_queue_mapping(vsi, &ctxt.info,
I40E_DEFAULT_TCMAP);
if (ret != I40E_SUCCESS) {
- PMD_DRV_LOG(ERR, "Failed to configure "
- "TC queue mapping");
+ PMD_DRV_LOG(ERR,
+ "Failed to configure TC queue mapping");
goto fail_msix_alloc;
}
ctxt.info.up_enable_bits = I40E_DEFAULT_TCMAP;
@@ -4662,8 +4671,8 @@ i40e_vsi_setup(struct i40e_pf *pf,
ret = i40e_vsi_config_tc_queue_mapping(vsi, &ctxt.info,
I40E_DEFAULT_TCMAP);
if (ret != I40E_SUCCESS) {
- PMD_DRV_LOG(ERR, "Failed to configure "
- "TC queue mapping");
+ PMD_DRV_LOG(ERR,
+ "Failed to configure TC queue mapping");
goto fail_msix_alloc;
}
ctxt.info.up_enable_bits = I40E_DEFAULT_TCMAP;
@@ -4680,8 +4689,8 @@ i40e_vsi_setup(struct i40e_pf *pf,
ret = i40e_vsi_config_tc_queue_mapping(vsi, &ctxt.info,
I40E_DEFAULT_TCMAP);
if (ret != I40E_SUCCESS) {
- PMD_DRV_LOG(ERR, "Failed to configure "
- "TC queue mapping.");
+ PMD_DRV_LOG(ERR,
+ "Failed to configure TC queue mapping.");
goto fail_msix_alloc;
}
ctxt.info.up_enable_bits = I40E_DEFAULT_TCMAP;
@@ -4944,8 +4953,9 @@ i40e_pf_setup(struct i40e_pf *pf)
/* make queue allocated first, let FDIR use queue pair 0*/
ret = i40e_res_pool_alloc(&pf->qp_pool, I40E_DEFAULT_QP_NUM_FDIR);
if (ret != I40E_FDIR_QUEUE_ID) {
- PMD_DRV_LOG(ERR, "queue allocation fails for FDIR :"
- " ret =%d", ret);
+ PMD_DRV_LOG(ERR,
+ "queue allocation fails for FDIR: ret =%d",
+ ret);
pf->flags &= ~I40E_FLAG_FDIR;
}
}
@@ -4968,8 +4978,8 @@ i40e_pf_setup(struct i40e_pf *pf)
hw->func_caps.rss_table_size);
return I40E_ERR_PARAM;
}
- PMD_DRV_LOG(INFO, "Hardware capability of hash lookup table "
- "size: %u\n", hw->func_caps.rss_table_size);
+ PMD_DRV_LOG(INFO, "Hardware capability of hash lookup table size: %u\n",
+ hw->func_caps.rss_table_size);
pf->hash_lut_size = hw->func_caps.rss_table_size;
/* Enable ethtype and macvlan filters */
@@ -5219,8 +5229,8 @@ i40e_dev_rx_init(struct i40e_pf *pf)
ret = i40e_rx_queue_init(rxq);
if (ret != I40E_SUCCESS) {
- PMD_DRV_LOG(ERR, "Failed to do RX queue "
- "initialization");
+ PMD_DRV_LOG(ERR,
+ "Failed to do RX queue initialization");
break;
}
}
@@ -5504,8 +5514,9 @@ i40e_dev_handle_aq_msg(struct rte_eth_dev *dev)
ret = i40e_clean_arq_element(hw, &info, &pending);
if (ret != I40E_SUCCESS) {
- PMD_DRV_LOG(INFO, "Failed to read msg from AdminQ, "
- "aq_err: %u", hw->aq.asq_last_status);
+ PMD_DRV_LOG(INFO,
+ "Failed to read msg from AdminQ, aq_err: %u",
+ hw->aq.asq_last_status);
break;
}
opcode = rte_le_to_cpu_16(info.desc.opcode);
@@ -5822,8 +5833,8 @@ i40e_find_all_vlan_for_mac(struct i40e_vsi *vsi,
for (k = 0; k < I40E_UINT32_BIT_SIZE; k++) {
if (vsi->vfta[j] & (1 << k)) {
if (i > num - 1) {
- PMD_DRV_LOG(ERR, "vlan number "
- "not match");
+ PMD_DRV_LOG(ERR,
+ "vlan number doesn't match");
return I40E_ERR_PARAM;
}
(void)rte_memcpy(&mv_f[i].macaddr,
@@ -6304,8 +6315,7 @@ i40e_set_rss_key(struct i40e_vsi *vsi, uint8_t *key, uint8_t key_len)
ret = i40e_aq_set_rss_key(hw, vsi->vsi_id, key_dw);
if (ret)
- PMD_INIT_LOG(ERR, "Failed to configure RSS key "
- "via AQ");
+ PMD_INIT_LOG(ERR, "Failed to configure RSS key via AQ");
} else {
uint32_t *hash_key = (uint32_t *)key;
uint16_t i;
@@ -6569,8 +6579,9 @@ i40e_add_vxlan_port(struct i40e_pf *pf, uint16_t port)
/* Now check if there is space to add the new port */
idx = i40e_get_vxlan_port_idx(pf, 0);
if (idx < 0) {
- PMD_DRV_LOG(ERR, "Maximum number of UDP ports reached,"
- "not adding port %d", port);
+ PMD_DRV_LOG(ERR,
+ "Maximum number of UDP ports reached, not adding port %d",
+ port);
return -ENOSPC;
}
@@ -6941,15 +6952,15 @@ i40e_set_symmetric_hash_enable_per_port(struct i40e_hw *hw, uint8_t enable)
if (enable > 0) {
if (reg & I40E_PRTQF_CTL_0_HSYM_ENA_MASK) {
- PMD_DRV_LOG(INFO, "Symmetric hash has already "
- "been enabled");
+ PMD_DRV_LOG(INFO,
+ "Symmetric hash has already been enabled");
return;
}
reg |= I40E_PRTQF_CTL_0_HSYM_ENA_MASK;
} else {
if (!(reg & I40E_PRTQF_CTL_0_HSYM_ENA_MASK)) {
- PMD_DRV_LOG(INFO, "Symmetric hash has already "
- "been disabled");
+ PMD_DRV_LOG(INFO,
+ "Symmetric hash has already been disabled");
return;
}
reg &= ~I40E_PRTQF_CTL_0_HSYM_ENA_MASK;
@@ -7073,16 +7084,16 @@ i40e_set_hash_filter_global_config(struct i40e_hw *hw,
if (g_cfg->hash_func == RTE_ETH_HASH_FUNCTION_TOEPLITZ) {
/* Toeplitz */
if (reg & I40E_GLQF_CTL_HTOEP_MASK) {
- PMD_DRV_LOG(DEBUG, "Hash function already set to "
- "Toeplitz");
+ PMD_DRV_LOG(DEBUG,
+ "Hash function already set to Toeplitz");
goto out;
}
reg |= I40E_GLQF_CTL_HTOEP_MASK;
} else if (g_cfg->hash_func == RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) {
/* Simple XOR */
if (!(reg & I40E_GLQF_CTL_HTOEP_MASK)) {
- PMD_DRV_LOG(DEBUG, "Hash function already set to "
- "Simple XOR");
+ PMD_DRV_LOG(DEBUG,
+ "Hash function already set to Simple XOR");
goto out;
}
reg &= ~I40E_GLQF_CTL_HTOEP_MASK;
@@ -8030,13 +8041,14 @@ i40e_ethertype_filter_set(struct i40e_pf *pf,
}
if (filter->ether_type == ETHER_TYPE_IPv4 ||
filter->ether_type == ETHER_TYPE_IPv6) {
- PMD_DRV_LOG(ERR, "unsupported ether_type(0x%04x) in"
- " control packet filter.", filter->ether_type);
+ PMD_DRV_LOG(ERR,
+ "unsupported ether_type(0x%04x) in control packet filter.",
+ filter->ether_type);
return -EINVAL;
}
if (filter->ether_type == ETHER_TYPE_VLAN)
- PMD_DRV_LOG(WARNING, "filter vlan ether_type in first tag is"
- " not supported.");
+ PMD_DRV_LOG(WARNING,
+ "filter vlan ether_type in first tag is not supported.");
if (!(filter->flags & RTE_ETHTYPE_FLAGS_MAC))
flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC;
@@ -8051,11 +8063,10 @@ i40e_ethertype_filter_set(struct i40e_pf *pf,
pf->main_vsi->seid,
filter->queue, add, &stats, NULL);
- PMD_DRV_LOG(INFO, "add/rem control packet filter, return %d,"
- " mac_etype_used = %u, etype_used = %u,"
- " mac_etype_free = %u, etype_free = %u\n",
- ret, stats.mac_etype_used, stats.etype_used,
- stats.mac_etype_free, stats.etype_free);
+ PMD_DRV_LOG(INFO,
+ "add/rem control packet filter, return %d, mac_etype_used = %u, etype_used = %u, mac_etype_free = %u, etype_free = %u\n",
+ ret, stats.mac_etype_used, stats.etype_used,
+ stats.mac_etype_free, stats.etype_free);
if (ret < 0)
return -ENOSYS;
return 0;
@@ -8364,9 +8375,9 @@ i40e_configure_registers(struct i40e_hw *hw)
ret = i40e_aq_debug_write_register(hw, reg_table[i].addr,
reg_table[i].val, NULL);
if (ret < 0) {
- PMD_DRV_LOG(ERR, "Failed to write 0x%"PRIx64" to the "
- "address of 0x%"PRIx32, reg_table[i].val,
- reg_table[i].addr);
+ PMD_DRV_LOG(ERR,
+ "Failed to write 0x%"PRIx64" to the address of 0x%"PRIx32,
+ reg_table[i].val, reg_table[i].addr);
break;
}
PMD_DRV_LOG(DEBUG, "Write 0x%"PRIx64" to the address of "
@@ -8411,8 +8422,9 @@ i40e_config_qinq(struct i40e_hw *hw, struct i40e_vsi *vsi)
I40E_VSI_L2TAGSTXVALID(
vsi->vsi_id), reg, NULL);
if (ret < 0) {
- PMD_DRV_LOG(ERR, "Failed to update "
- "VSI_L2TAGSTXVALID[%d]", vsi->vsi_id);
+ PMD_DRV_LOG(ERR,
+ "Failed to update VSI_L2TAGSTXVALID[%d]",
+ vsi->vsi_id);
return I40E_ERR_CONFIG;
}
}
@@ -8463,11 +8475,10 @@ i40e_aq_add_mirror_rule(struct i40e_hw *hw,
rte_memcpy(&desc.params.raw, &cmd, sizeof(cmd));
status = i40e_asq_send_command(hw, &desc, entries, buff_len, NULL);
- PMD_DRV_LOG(INFO, "i40e_aq_add_mirror_rule, aq_status %d,"
- "rule_id = %u"
- " mirror_rules_used = %u, mirror_rules_free = %u,",
- hw->aq.asq_last_status, resp->rule_id,
- resp->mirror_rules_used, resp->mirror_rules_free);
+ PMD_DRV_LOG(INFO,
+ "i40e_aq_add_mirror_rule, aq_status %d, rule_id = %u mirror_rules_used = %u, mirror_rules_free = %u,",
+ hw->aq.asq_last_status, resp->rule_id,
+ resp->mirror_rules_used, resp->mirror_rules_free);
*rule_id = rte_le_to_cpu_16(resp->rule_id);
return status;
@@ -8545,8 +8556,8 @@ i40e_mirror_rule_set(struct rte_eth_dev *dev,
PMD_DRV_LOG(DEBUG, "i40e_mirror_rule_set: sw_id = %d.", sw_id);
if (pf->main_vsi->veb == NULL || pf->vfs == NULL) {
- PMD_DRV_LOG(ERR, "mirror rule can not be configured"
- " without veb or vfs.");
+ PMD_DRV_LOG(ERR,
+ "mirror rule can not be configured without veb or vfs.");
return -ENOSYS;
}
if (pf->nb_mirror_rule > I40E_MAX_MIRROR_RULES) {
@@ -8578,9 +8589,9 @@ i40e_mirror_rule_set(struct rte_eth_dev *dev,
mirr_rule->entries,
mirr_rule->num_entries, mirr_rule->id);
if (ret < 0) {
- PMD_DRV_LOG(ERR, "failed to remove mirror rule:"
- " ret = %d, aq_err = %d.",
- ret, hw->aq.asq_last_status);
+ PMD_DRV_LOG(ERR,
+ "failed to remove mirror rule: ret = %d, aq_err = %d.",
+ ret, hw->aq.asq_last_status);
return -ENOSYS;
}
TAILQ_REMOVE(&pf->mirror_list, mirr_rule, rules);
@@ -8669,9 +8680,9 @@ i40e_mirror_rule_set(struct rte_eth_dev *dev,
mirr_rule->rule_type, mirr_rule->entries,
j, &rule_id);
if (ret < 0) {
- PMD_DRV_LOG(ERR, "failed to add mirror rule:"
- " ret = %d, aq_err = %d.",
- ret, hw->aq.asq_last_status);
+ PMD_DRV_LOG(ERR,
+ "failed to add mirror rule: ret = %d, aq_err = %d.",
+ ret, hw->aq.asq_last_status);
rte_free(mirr_rule);
return -ENOSYS;
}
@@ -8723,9 +8734,9 @@ i40e_mirror_rule_reset(struct rte_eth_dev *dev, uint8_t sw_id)
mirr_rule->entries,
mirr_rule->num_entries, mirr_rule->id);
if (ret < 0) {
- PMD_DRV_LOG(ERR, "failed to remove mirror rule:"
- " status = %d, aq_err = %d.",
- ret, hw->aq.asq_last_status);
+ PMD_DRV_LOG(ERR,
+ "failed to remove mirror rule: status = %d, aq_err = %d.",
+ ret, hw->aq.asq_last_status);
return -ENOSYS;
}
TAILQ_REMOVE(&pf->mirror_list, mirr_rule, rules);
@@ -9157,9 +9168,9 @@ i40e_config_switch_comp_tc(struct i40e_veb *veb, uint8_t tc_map)
ret = i40e_aq_config_switch_comp_bw_config(hw, veb->seid,
&veb_bw, NULL);
if (ret) {
- PMD_INIT_LOG(ERR, "AQ command Config switch_comp BW allocation"
- " per TC failed = %d",
- hw->aq.asq_last_status);
+ PMD_INIT_LOG(ERR,
+ "AQ command Config switch_comp BW allocation per TC failed = %d",
+ hw->aq.asq_last_status);
return ret;
}
@@ -9167,16 +9178,18 @@ i40e_config_switch_comp_tc(struct i40e_veb *veb, uint8_t tc_map)
ret = i40e_aq_query_switch_comp_ets_config(hw, veb->seid,
&ets_query, NULL);
if (ret != I40E_SUCCESS) {
- PMD_DRV_LOG(ERR, "Failed to get switch_comp ETS"
- " configuration %u", hw->aq.asq_last_status);
+ PMD_DRV_LOG(ERR,
+ "Failed to get switch_comp ETS configuration %u",
+ hw->aq.asq_last_status);
return ret;
}
memset(&bw_query, 0, sizeof(bw_query));
ret = i40e_aq_query_switch_comp_bw_config(hw, veb->seid,
&bw_query, NULL);
if (ret != I40E_SUCCESS) {
- PMD_DRV_LOG(ERR, "Failed to get switch_comp bandwidth"
- " configuration %u", hw->aq.asq_last_status);
+ PMD_DRV_LOG(ERR,
+ "Failed to get switch_comp bandwidth configuration %u",
+ hw->aq.asq_last_status);
return ret;
}
@@ -9241,9 +9254,9 @@ i40e_vsi_config_tc(struct i40e_vsi *vsi, uint8_t tc_map)
}
ret = i40e_aq_config_vsi_tc_bw(hw, vsi->seid, &bw_data, NULL);
if (ret) {
- PMD_INIT_LOG(ERR, "AQ command Config VSI BW allocation"
- " per TC failed = %d",
- hw->aq.asq_last_status);
+ PMD_INIT_LOG(ERR,
+ "AQ command Config VSI BW allocation per TC failed = %d",
+ hw->aq.asq_last_status);
goto out;
}
for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
@@ -9263,9 +9276,8 @@ i40e_vsi_config_tc(struct i40e_vsi *vsi, uint8_t tc_map)
/* Update the VSI after updating the VSI queue-mapping information */
ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
if (ret) {
- PMD_INIT_LOG(ERR, "Failed to configure "
- "TC queue mapping = %d",
- hw->aq.asq_last_status);
+ PMD_INIT_LOG(ERR, "Failed to configure TC queue mapping = %d",
+ hw->aq.asq_last_status);
goto out;
}
/* update the local VSI info with updated queue map */
@@ -9317,8 +9329,8 @@ i40e_dcb_hw_configure(struct i40e_pf *pf,
/* Use the FW API if FW > v4.4*/
if (!(((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver >= 4)) ||
(hw->aq.fw_maj_ver >= 5))) {
- PMD_INIT_LOG(ERR, "FW < v4.4, can not use FW LLDP API"
- " to configure DCB");
+ PMD_INIT_LOG(ERR,
+ "FW < v4.4, can not use FW LLDP API to configure DCB");
return I40E_ERR_FIRMWARE_API_VERSION;
}
@@ -9384,8 +9396,8 @@ i40e_dcb_hw_configure(struct i40e_pf *pf,
I40E_DEFAULT_TCMAP);
if (ret)
PMD_INIT_LOG(WARNING,
- "Failed configuring TC for VSI seid=%d\n",
- vsi_list->vsi->seid);
+ "Failed configuring TC for VSI seid=%d\n",
+ vsi_list->vsi->seid);
/* continue */
}
}
@@ -9445,15 +9457,15 @@ i40e_dcb_init_configure(struct rte_eth_dev *dev, bool sw_dcb)
I40E_APP_PROTOID_FCOE;
ret = i40e_set_dcb_config(hw);
if (ret) {
- PMD_INIT_LOG(ERR, "default dcb config fails."
- " err = %d, aq_err = %d.", ret,
- hw->aq.asq_last_status);
+ PMD_INIT_LOG(ERR,
+ "default dcb config fails. err = %d, aq_err = %d.",
+ ret, hw->aq.asq_last_status);
return -ENOSYS;
}
} else {
- PMD_INIT_LOG(ERR, "DCB initialization in FW fails,"
- " err = %d, aq_err = %d.", ret,
- hw->aq.asq_last_status);
+ PMD_INIT_LOG(ERR,
+ "DCB initialization in FW fails, err = %d, aq_err = %d.",
+ ret, hw->aq.asq_last_status);
return -ENOTSUP;
}
} else {
@@ -9464,14 +9476,14 @@ i40e_dcb_init_configure(struct rte_eth_dev *dev, bool sw_dcb)
ret = i40e_init_dcb(hw);
if (!ret) {
if (hw->dcbx_status == I40E_DCBX_STATUS_DISABLED) {
- PMD_INIT_LOG(ERR, "HW doesn't support"
- " DCBX offload.");
+ PMD_INIT_LOG(ERR,
+ "HW doesn't support DCBX offload.");
return -ENOTSUP;
}
} else {
- PMD_INIT_LOG(ERR, "DCBX configuration failed, err = %d,"
- " aq_err = %d.", ret,
- hw->aq.asq_last_status);
+ PMD_INIT_LOG(ERR,
+ "DCBX configuration failed, err = %d, aq_err = %d.",
+ ret, hw->aq.asq_last_status);
return -ENOTSUP;
}
}
--
2.11.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox