* [dpdk-dev] [PATCH v2 0/4] new crypto software based device @ 2016-09-19 8:59 Michal Jastrzebski 2016-09-19 8:59 ` [dpdk-dev] [PATCH v2 1/4] libcrypto_pmd: initial implementation of SW crypto device Michal Jastrzebski ` (4 more replies) 0 siblings, 5 replies; 34+ messages in thread From: Michal Jastrzebski @ 2016-09-19 8:59 UTC (permalink / raw) To: dev; +Cc: pablo.de.lara.guarch, Marcin Kerlin From: Marcin Kerlin <marcinx.kerlin@intel.com> This code provides the initial implementation of the libcrypto poll mode driver. All cryptography operations are using Openssl library crypto API. Each algorithm uses EVP_ interface from openssl API which is recommended by Openssl maintainers. For more information about how to use this driver, go to: doc/guides/cryptodevs/libcrypto.rst Changes in V2: - add gcm/gmac algorithm correction - unit test rework This patch-set depends on the following patches: http://dpdk.org/dev/patchwork/patch/15326/ http://dpdk.org/dev/patchwork/patch/15327/ http://dpdk.org/dev/patchwork/patch/15328/ Slawomir Mrozowicz (2): libcrypto_pmd: initial implementation of SW crypto device lib/cryptodev: added support to libcrypto PMD Piotr Azarewicz (1) app/test: added tests for libcrypto PMD Daniel Mrzyglod (1) examples/l2fwd-crypto: updated example for libcrypto PMD MAINTAINERS | 4 + app/test/Makefile | 2 +- app/test/test_cryptodev.c | 690 +++++++++++- app/test/test_cryptodev.h | 1 + app/test/test_cryptodev_aes.c | 687 ------------ app/test/test_cryptodev_aes.h | 1124 -------------------- app/test/test_cryptodev_aes_test_vectors.h | 1095 +++++++++++++++++++ app/test/test_cryptodev_blockcipher.c | 531 +++++++++ app/test/test_cryptodev_blockcipher.h | 125 +++ app/test/test_cryptodev_des_test_vectors.h | 952 +++++++++++++++++ app/test/test_cryptodev_hash_test_vectors.h | 491 +++++++++ app/test/test_cryptodev_perf.c | 684 +++++++++++- config/common_base | 6 + doc/guides/cryptodevs/index.rst | 1 + doc/guides/cryptodevs/libcrypto.rst | 113 ++ doc/guides/rel_notes/release_16_11.rst | 5 +- drivers/crypto/Makefile | 1 + drivers/crypto/libcrypto/Makefile | 60 ++ drivers/crypto/libcrypto/rte_libcrypto_pmd.c | 1045 ++++++++++++++++++ drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c | 708 ++++++++++++ .../crypto/libcrypto/rte_libcrypto_pmd_private.h | 174 +++ .../crypto/libcrypto/rte_pmd_libcrypto_version.map | 3 + examples/l2fwd-crypto/main.c | 11 + lib/librte_cryptodev/rte_cryptodev.h | 3 + mk/rte.app.mk | 3 +- 25 files changed, 6666 insertions(+), 1853 deletions(-) delete mode 100644 app/test/test_cryptodev_aes.c delete mode 100644 app/test/test_cryptodev_aes.h create mode 100644 app/test/test_cryptodev_aes_test_vectors.h create mode 100644 app/test/test_cryptodev_blockcipher.c create mode 100644 app/test/test_cryptodev_blockcipher.h create mode 100644 app/test/test_cryptodev_des_test_vectors.h create mode 100644 app/test/test_cryptodev_hash_test_vectors.h create mode 100644 doc/guides/cryptodevs/libcrypto.rst create mode 100644 drivers/crypto/libcrypto/Makefile create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd.c create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h create mode 100644 drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map -- 1.9.1 ^ permalink raw reply [flat|nested] 34+ messages in thread
* [dpdk-dev] [PATCH v2 1/4] libcrypto_pmd: initial implementation of SW crypto device 2016-09-19 8:59 [dpdk-dev] [PATCH v2 0/4] new crypto software based device Michal Jastrzebski @ 2016-09-19 8:59 ` Michal Jastrzebski 2016-09-19 8:59 ` [dpdk-dev] [PATCH v2 2/4] lib/cryptodev: added support to libcrypto PMD Michal Jastrzebski ` (3 subsequent siblings) 4 siblings, 0 replies; 34+ messages in thread From: Michal Jastrzebski @ 2016-09-19 8:59 UTC (permalink / raw) To: dev Cc: pablo.de.lara.guarch, Slawomir Mrozowicz, Michal Kobylinski, Tomasz Kulasek, Daniel Mrzyglod From: Slawomir Mrozowicz <slawomirx.mrozowicz@intel.com> This code provides the initial implementation of the libcrypto poll mode driver. All cryptography operations are using Openssl library crypto API. Each algorithm uses EVP_ interface from openssl API - which is recommended by Openssl maintainers. LibCrypto PMD has support for: Supported cipher algorithms: RTE_CRYPTO_CIPHER_3DES_CBC RTE_CRYPTO_CIPHER_AES_CBC RTE_CRYPTO_CIPHER_AES_CTR RTE_CRYPTO_CIPHER_3DES_CTR RTE_CRYPTO_CIPHER_AES_GCM Supported authentication algorithms: RTE_CRYPTO_AUTH_AES_GMAC RTE_CRYPTO_AUTH_MD5 RTE_CRYPTO_AUTH_SHA1 RTE_CRYPTO_AUTH_SHA224 RTE_CRYPTO_AUTH_SHA256 RTE_CRYPTO_AUTH_SHA384 RTE_CRYPTO_AUTH_SHA512 RTE_CRYPTO_AUTH_MD5_HMAC RTE_CRYPTO_AUTH_SHA1_HMAC RTE_CRYPTO_AUTH_SHA224_HMAC RTE_CRYPTO_AUTH_SHA256_HMAC RTE_CRYPTO_AUTH_SHA384_HMAC RTE_CRYPTO_AUTH_SHA512_HMAC Installation ------------ To compile libcrypto PMD It has to be enabled in the config/common_base file and appropriate openssl packages have to be installed in the build environment. Signed-off-by: Slawomir Mrozowicz <slawomirx.mrozowicz@intel.com> Signed-off-by: Michal Kobylinski <michalx.kobylinski@intel.com> Signed-off-by: Tomasz Kulasek <tomaszx.kulasek@intel.com> Signed-off-by: Daniel Mrzyglod <danielx.t.mrzyglod@intel.com> --- v2: - add gcm crypto cipher and authentication algorithm - rework gmac crypto authentication algorithm --- MAINTAINERS | 4 + config/common_base | 6 + doc/guides/cryptodevs/index.rst | 1 + doc/guides/cryptodevs/libcrypto.rst | 113 +++ doc/guides/rel_notes/release_16_11.rst | 5 +- drivers/crypto/Makefile | 1 + drivers/crypto/libcrypto/Makefile | 60 ++ drivers/crypto/libcrypto/rte_libcrypto_pmd.c | 1045 ++++++++++++++++++++ drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c | 708 +++++++++++++ .../crypto/libcrypto/rte_libcrypto_pmd_private.h | 174 ++++ .../crypto/libcrypto/rte_pmd_libcrypto_version.map | 3 + mk/rte.app.mk | 3 +- 12 files changed, 2121 insertions(+), 2 deletions(-) create mode 100644 doc/guides/cryptodevs/libcrypto.rst create mode 100644 drivers/crypto/libcrypto/Makefile create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd.c create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h create mode 100644 drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map diff --git a/MAINTAINERS b/MAINTAINERS index 0e78941..6bd0889 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -432,6 +432,10 @@ M: Declan Doherty <declan.doherty@intel.com> F: drivers/crypto/null/ F: doc/guides/cryptodevs/null.rst +LibCrypto Crypto PMD +M: Declan Doherty <declan.doherty@intel.com> +F: drivers/crypto/libcrypto/ +F: doc/guides/cryptodevs/libcrypto.rst Packet processing ----------------- diff --git a/config/common_base b/config/common_base index 7830535..42d28dd 100644 --- a/config/common_base +++ b/config/common_base @@ -376,6 +376,12 @@ CONFIG_RTE_LIBRTE_PMD_AESNI_MB=n CONFIG_RTE_LIBRTE_PMD_AESNI_MB_DEBUG=n # +# Compile PMD for Software backed device +# +CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO=n +CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO_DEBUG=n + +# # Compile PMD for AESNI GCM device # CONFIG_RTE_LIBRTE_PMD_AESNI_GCM=n diff --git a/doc/guides/cryptodevs/index.rst b/doc/guides/cryptodevs/index.rst index 9616de1..adb6e98c 100644 --- a/doc/guides/cryptodevs/index.rst +++ b/doc/guides/cryptodevs/index.rst @@ -39,6 +39,7 @@ Crypto Device Drivers aesni_mb aesni_gcm kasumi + libcrypto null snow3g qat diff --git a/doc/guides/cryptodevs/libcrypto.rst b/doc/guides/cryptodevs/libcrypto.rst new file mode 100644 index 0000000..f9daa05 --- /dev/null +++ b/doc/guides/cryptodevs/libcrypto.rst @@ -0,0 +1,113 @@ +.. 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. + +LibCrypto Crypto Poll Mode Driver +============================================ + + +This code provides the initial implementation of the libcrypto poll mode +driver All cryptography operations are using Openssl library crypto API. +Each algorithm uses EVP_ interface from openssl API - which is recommended +by Openssl maintainers. + +For more details about openssl library please visit openssl webpage: +https://www.openssl.org/ + +Features +-------- + +LibCrypto PMD has support for: + +Supported cipher algorithms: +* ``RTE_CRYPTO_CIPHER_3DES_CBC`` +* ``RTE_CRYPTO_CIPHER_AES_CBC`` +* ``RTE_CRYPTO_CIPHER_AES_CTR`` +* ``RTE_CRYPTO_CIPHER_3DES_CTR`` +* ``RTE_CRYPTO_CIPHER_AES_GCM`` + +Supported authentication algorithms: +* ``RTE_CRYPTO_AUTH_AES_GMAC`` +* ``RTE_CRYPTO_AUTH_MD5`` +* ``RTE_CRYPTO_AUTH_SHA1`` +* ``RTE_CRYPTO_AUTH_SHA224`` +* ``RTE_CRYPTO_AUTH_SHA256`` +* ``RTE_CRYPTO_AUTH_SHA384`` +* ``RTE_CRYPTO_AUTH_SHA512`` +* ``RTE_CRYPTO_AUTH_MD5_HMAC`` +* ``RTE_CRYPTO_AUTH_SHA1_HMAC`` +* ``RTE_CRYPTO_AUTH_SHA224_HMAC`` +* ``RTE_CRYPTO_AUTH_SHA256_HMAC`` +* ``RTE_CRYPTO_AUTH_SHA384_HMAC`` +* ``RTE_CRYPTO_AUTH_SHA512_HMAC`` + + +Installation +------------ +To compile libcrypto PMD It has to be enabled in the config/common_base file +and appropriate openssl packages have to be installed in the build environment. + +The newest openssl library version is supported: +* 1.0.2h-fips 3 May 2016. +Older versions that were also verified: +* 1.0.1f 6 Jan 2014 +* 1.0.1 14 Mar 2012 + +For Ubuntu 14.04 LTS these packages have to be installed in the build system: +sudo apt-get install openssl +sudo apt-get install libc6-dev-i386 (for i686-native-linuxapp-gcc target) + +This code was also verified on Fedora 24. +This code was NOT yet verified on FreeBSD. + +Initialization +-------------- + +User can use app/test application to check how to use this pmd and to verify +crypto processing. + +Test name is cryptodev_libcrypto_autotest. +For performance test cryptodev_libcrypto_perftest can be used. + +To verify real traffic l2fwd-crypto example can be used with this command: +sudo ./build/l2fwd-crypto -c 0x3 -n 4 --vdev "cryptodev_libcrypto_pmd" +--vdev "cryptodev_libcrypto_pmd"-- -p 0x3 --chain CIPHER_HASH +--cipher_op ENCRYPT --cipher_algo AES_CBC +--cipher_key 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f +--iv 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:ff +--auth_op GENERATE --auth_algo SHA1_HMAC +--auth_key 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11 +:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11 +:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11 + +Limitations +----------- +* Maximum number of sessions is 2048. +* Chained mbufs are not supported. +* Hash only is not supported for GCM and GMAC. +* Cipher only is not supported for GCM and GMAC. diff --git a/doc/guides/rel_notes/release_16_11.rst b/doc/guides/rel_notes/release_16_11.rst index 1dd0e6a..fdd3e4f 100644 --- a/doc/guides/rel_notes/release_16_11.rst +++ b/doc/guides/rel_notes/release_16_11.rst @@ -34,7 +34,10 @@ New Features Refer to the previous release notes for examples. - This section is a comment. Make sure to start the actual text at the margin. +* **Added libcrypto PMD.** + + A new crypto PMD has been added, which provides several ciphering and hashing. + All cryptography operations are using Openssl library crypto API. * ** Added support of C3xxx Device in QAT PMD.** Support for Device c3xxx has been enabled in QAT PMD. diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index dc4ef7f..11b0863 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -33,6 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += aesni_gcm DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += aesni_mb +DIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += libcrypto DIRS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += qat DIRS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += snow3g DIRS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI) += kasumi diff --git a/drivers/crypto/libcrypto/Makefile b/drivers/crypto/libcrypto/Makefile new file mode 100644 index 0000000..c5f8cf2 --- /dev/null +++ b/drivers/crypto/libcrypto/Makefile @@ -0,0 +1,60 @@ +# 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 + +# library name +LIB = librte_pmd_libcrypto.a + +# build flags +CFLAGS += -O3 +CFLAGS += $(WERROR_FLAGS) + +# library version +LIBABIVER := 1 + +# versioning export map +EXPORT_MAP := rte_pmd_libcrypto_version.map + +# external library dependencies +LDLIBS += -lcrypto + +# library source files +SRCS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += rte_libcrypto_pmd.c +SRCS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += rte_libcrypto_pmd_ops.c + +# library dependencies +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_eal +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_mbuf +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_mempool +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_ring +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_cryptodev + +include $(RTE_SDK)/mk/rte.lib.mk diff --git a/drivers/crypto/libcrypto/rte_libcrypto_pmd.c b/drivers/crypto/libcrypto/rte_libcrypto_pmd.c new file mode 100644 index 0000000..0c7a8bd --- /dev/null +++ b/drivers/crypto/libcrypto/rte_libcrypto_pmd.c @@ -0,0 +1,1045 @@ +/*- + * 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_common.h> +#include <rte_hexdump.h> +#include <rte_cryptodev.h> +#include <rte_cryptodev_pmd.h> +#include <rte_dev.h> +#include <rte_malloc.h> +#include <rte_cpuflags.h> + +#include <openssl/evp.h> + +#include "rte_libcrypto_pmd_private.h" + +static int cryptodev_libcrypto_uninit(const char *name); + +/*----------------------------------------------------------------------------*/ + +/** + * Global static parameter used to create a unique name for each + * LIBCRYPTO crypto device. + */ +static unsigned int unique_name_id; + +static inline int +create_unique_device_name(char *name, size_t size) +{ + int ret; + + if (name == NULL) + return -EINVAL; + + ret = snprintf(name, size, "%s_%u", RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), + unique_name_id++); + if (ret < 0) + return ret; + return 0; +} + +/** + * Increment counter by 1 + * Counter is 64 bit array, big-endian + */ +static void +ctr_inc(uint8_t *ctr) +{ + uint64_t *ctr64 = (uint64_t *)ctr; + + *ctr64 = __builtin_bswap64(*ctr64); + (*ctr64)++; + *ctr64 = __builtin_bswap64(*ctr64); +} + +/* + *------------------------------------------------------------------------------ + * Session Prepare + *------------------------------------------------------------------------------ + */ + +/** Get xform chain order */ +static enum libcrypto_chain_order +libcrypto_get_chain_order(const struct rte_crypto_sym_xform *xform) +{ + enum libcrypto_chain_order res = LIBCRYPTO_CHAIN_NOT_SUPPORTED; + + if (xform != NULL) { + if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) { + if (xform->next == NULL) + res = LIBCRYPTO_CHAIN_ONLY_AUTH; + else if (xform->next->type == + RTE_CRYPTO_SYM_XFORM_CIPHER) + res = LIBCRYPTO_CHAIN_AUTH_CIPHER; + } + if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) { + if (xform->next == NULL) + res = LIBCRYPTO_CHAIN_ONLY_CIPHER; + else if (xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH) + res = LIBCRYPTO_CHAIN_CIPHER_AUTH; + } + } + + return res; +} + +/** Get session cipher key from input cipher key */ +static void +get_cipher_key(uint8_t *input_key, int keylen, uint8_t *session_key) +{ + memcpy(session_key, input_key, keylen); +} + +/** Get key ede 24 bytes standard from input key */ +static int +get_cipher_key_ede(uint8_t *key, int keylen, uint8_t *key_ede) +{ + int res = 0; + + /* Initialize keys - 24 bytes: [key1-key2-key3] */ + switch (keylen) { + case 24: + memcpy(key_ede, key, 24); + break; + case 16: + /* K3 = K1 */ + memcpy(key_ede, key, 16); + memcpy(key_ede + 16, key, 8); + break; + case 8: + /* K1 = K2 = K3 (DES compatibility) */ + memcpy(key_ede, key, 8); + memcpy(key_ede + 8, key, 8); + memcpy(key_ede + 16, key, 8); + break; + default: + LIBCRYPTO_LOG_ERR("Unsupported key size"); + res = -EINVAL; + } + + return res; +} + +/** Get adequate libcrypto function for input cipher algorithm */ +static uint8_t +get_cipher_algo(enum rte_crypto_cipher_algorithm sess_algo, size_t keylen, + const EVP_CIPHER **algo) +{ + int res = 0; + + if (algo != NULL) { + switch (sess_algo) { + case RTE_CRYPTO_CIPHER_3DES_CBC: + switch (keylen) { + case 16: + *algo = EVP_des_ede_cbc(); + break; + case 24: + *algo = EVP_des_ede3_cbc(); + break; + default: + res = -EINVAL; + } + break; + case RTE_CRYPTO_CIPHER_3DES_CTR: + break; + case RTE_CRYPTO_CIPHER_AES_CBC: + switch (keylen) { + case 16: + *algo = EVP_aes_128_cbc(); + break; + case 24: + *algo = EVP_aes_192_cbc(); + break; + case 32: + *algo = EVP_aes_256_cbc(); + break; + default: + res = -EINVAL; + } + break; + case RTE_CRYPTO_CIPHER_AES_CTR: + switch (keylen) { + case 16: + *algo = EVP_aes_128_ctr(); + break; + case 24: + *algo = EVP_aes_192_ctr(); + break; + case 32: + *algo = EVP_aes_256_ctr(); + break; + default: + res = -EINVAL; + } + break; + case RTE_CRYPTO_CIPHER_AES_GCM: + switch (keylen) { + case 16: + *algo = EVP_aes_128_gcm(); + break; + case 24: + *algo = EVP_aes_192_gcm(); + break; + case 32: + *algo = EVP_aes_256_gcm(); + break; + default: + res = -EINVAL; + } + break; + default: + res = -EINVAL; + break; + } + } else { + res = -EINVAL; + } + + return res; +} + +/** Get adequate libcrypto function for input auth algorithm */ +static uint8_t +get_auth_algo(enum rte_crypto_auth_algorithm sessalgo, + const EVP_MD **algo) +{ + int res = 0; + + if (algo != NULL) { + switch (sessalgo) { + case RTE_CRYPTO_AUTH_MD5: + case RTE_CRYPTO_AUTH_MD5_HMAC: + *algo = EVP_md5(); + break; + case RTE_CRYPTO_AUTH_SHA1: + case RTE_CRYPTO_AUTH_SHA1_HMAC: + *algo = EVP_sha1(); + break; + case RTE_CRYPTO_AUTH_SHA224: + case RTE_CRYPTO_AUTH_SHA224_HMAC: + *algo = EVP_sha224(); + break; + case RTE_CRYPTO_AUTH_SHA256: + case RTE_CRYPTO_AUTH_SHA256_HMAC: + *algo = EVP_sha256(); + break; + case RTE_CRYPTO_AUTH_SHA384: + case RTE_CRYPTO_AUTH_SHA384_HMAC: + *algo = EVP_sha384(); + break; + case RTE_CRYPTO_AUTH_SHA512: + case RTE_CRYPTO_AUTH_SHA512_HMAC: + *algo = EVP_sha512(); + break; + default: + res = -EINVAL; + break; + } + } else { + res = -EINVAL; + } + + return res; +} + +/** Set session cipher parameters */ +static int +libcrypto_set_session_cipher_parameters(struct libcrypto_session *sess, + const struct rte_crypto_sym_xform *xform) +{ + /* Select cipher direction */ + sess->cipher.direction = xform->cipher.op; + /* Select cipher key */ + sess->cipher.key.length = xform->cipher.key.length; + + /* Select cipher algo */ + switch (xform->cipher.algo) { + case RTE_CRYPTO_CIPHER_3DES_CBC: + case RTE_CRYPTO_CIPHER_AES_CBC: + case RTE_CRYPTO_CIPHER_AES_CTR: + case RTE_CRYPTO_CIPHER_AES_GCM: + sess->cipher.mode = LIBCRYPTO_CIPHER_LIB; + sess->cipher.algo = xform->cipher.algo; + sess->cipher.ctx = EVP_CIPHER_CTX_new(); + + if (get_cipher_algo(sess->cipher.algo, sess->cipher.key.length, + &sess->cipher.evp_algo) != 0) + return -EINVAL; + + get_cipher_key(xform->cipher.key.data, sess->cipher.key.length, + sess->cipher.key.data); + + break; + + case RTE_CRYPTO_CIPHER_3DES_CTR: + sess->cipher.mode = LIBCRYPTO_CIPHER_DES3CTR; + sess->cipher.ctx = EVP_CIPHER_CTX_new(); + + if (get_cipher_key_ede(xform->cipher.key.data, + sess->cipher.key.length, sess->cipher.key.data) != 0) + return -EINVAL; + break; + + default: + sess->cipher.algo = RTE_CRYPTO_CIPHER_NULL; + return -EINVAL; + } + + return 0; +} + +/* Set session auth parameters */ +static int +libcrypto_set_session_auth_parameters(struct libcrypto_session *sess, + const struct rte_crypto_sym_xform *xform) +{ + /* Select auth generate/verify */ + sess->auth.operation = xform->auth.op; + sess->auth.algo = xform->auth.algo; + + /* Select auth algo */ + switch (xform->auth.algo) { + case RTE_CRYPTO_AUTH_AES_GMAC: + case RTE_CRYPTO_AUTH_AES_GCM: + /* Check additional condition for AES_GMAC/GCM */ + if (sess->cipher.algo != RTE_CRYPTO_CIPHER_AES_GCM) + return -EINVAL; + sess->chain_order = LIBCRYPTO_CHAIN_COMBINED; + break; + + case RTE_CRYPTO_AUTH_MD5: + case RTE_CRYPTO_AUTH_SHA1: + case RTE_CRYPTO_AUTH_SHA224: + case RTE_CRYPTO_AUTH_SHA256: + case RTE_CRYPTO_AUTH_SHA384: + case RTE_CRYPTO_AUTH_SHA512: + sess->auth.mode = LIBCRYPTO_AUTH_AS_AUTH; + if (get_auth_algo(xform->auth.algo, &sess->auth.auth.evp_algo) != 0) + return -EINVAL; + sess->auth.auth.ctx = EVP_MD_CTX_create(); + break; + + case RTE_CRYPTO_AUTH_MD5_HMAC: + case RTE_CRYPTO_AUTH_SHA1_HMAC: + case RTE_CRYPTO_AUTH_SHA224_HMAC: + case RTE_CRYPTO_AUTH_SHA256_HMAC: + case RTE_CRYPTO_AUTH_SHA384_HMAC: + case RTE_CRYPTO_AUTH_SHA512_HMAC: + sess->auth.mode = LIBCRYPTO_AUTH_AS_HMAC; + sess->auth.hmac.ctx = EVP_MD_CTX_create(); + if (get_auth_algo(xform->auth.algo, &sess->auth.hmac.evp_algo) != 0) + return -EINVAL; + sess->auth.hmac.pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, + xform->auth.key.data, xform->auth.key.length); + break; + + default: + return -EINVAL; + } + + return 0; +} + +/** Parse crypto xform chain and set private session parameters */ +int +libcrypto_set_session_parameters(struct libcrypto_session *sess, + const struct rte_crypto_sym_xform *xform) +{ + const struct rte_crypto_sym_xform *cipher_xform = NULL; + const struct rte_crypto_sym_xform *auth_xform = NULL; + + sess->chain_order = libcrypto_get_chain_order(xform); + switch (sess->chain_order) { + case LIBCRYPTO_CHAIN_ONLY_CIPHER: + cipher_xform = xform; + break; + case LIBCRYPTO_CHAIN_ONLY_AUTH: + auth_xform = xform; + break; + case LIBCRYPTO_CHAIN_CIPHER_AUTH: + cipher_xform = xform; + auth_xform = xform->next; + break; + case LIBCRYPTO_CHAIN_AUTH_CIPHER: + auth_xform = xform; + cipher_xform = xform->next; + break; + default: + return -EINVAL; + } + + /* cipher_xform must be check before auth_xform */ + if (cipher_xform) { + if (libcrypto_set_session_cipher_parameters(sess, cipher_xform)) { + LIBCRYPTO_LOG_ERR( + "Invalid/unsupported cipher parameters"); + return -EINVAL; + } + } + + if (auth_xform) { + if (libcrypto_set_session_auth_parameters(sess, auth_xform)) { + LIBCRYPTO_LOG_ERR( + "Invalid/unsupported auth parameters"); + return -EINVAL; + } + } + + return 0; +} + +/** Reset private session parameters */ +void +libcrypto_reset_session(struct libcrypto_session *sess) +{ + EVP_CIPHER_CTX_free(sess->cipher.ctx); + + switch (sess->auth.mode) { + case LIBCRYPTO_AUTH_AS_AUTH: + EVP_MD_CTX_destroy(sess->auth.auth.ctx); + break; + case LIBCRYPTO_AUTH_AS_HMAC: + EVP_PKEY_free(sess->auth.hmac.pkey); + EVP_MD_CTX_destroy(sess->auth.hmac.ctx); + break; + default: + break; + } +} + +/** Provide session for operation */ +static struct libcrypto_session * +get_session(struct libcrypto_qp *qp, struct rte_crypto_op *op) +{ + struct libcrypto_session *sess = NULL; + + if (op->sym->sess_type == RTE_CRYPTO_SYM_OP_WITH_SESSION) { + /* get existing session */ + if (likely(op->sym->session != NULL && + op->sym->session->dev_type == + RTE_CRYPTODEV_LIBCRYPTO_PMD)) + sess = (struct libcrypto_session *) + op->sym->session->_private; + } else { + /* provide internal session */ + void *_sess = NULL; + + if (!rte_mempool_get(qp->sess_mp, (void **)&_sess)) { + sess = (struct libcrypto_session *) + ((struct rte_cryptodev_sym_session *)_sess) + ->_private; + + if (unlikely(libcrypto_set_session_parameters( + sess, op->sym->xform) != 0)) { + rte_mempool_put(qp->sess_mp, _sess); + sess = NULL; + } else + op->sym->session = _sess; + } + } + + if (sess == NULL) + op->status = RTE_CRYPTO_OP_STATUS_INVALID_SESSION; + + return sess; +} + +/* + *------------------------------------------------------------------------------ + * Process Operations + *------------------------------------------------------------------------------ + */ + +/** Process standard libcrypto cipher encryption */ +static int +process_libcrypto_cipher_encrypt(uint8_t *src, uint8_t *dst, + uint8_t *iv, uint8_t *key, int srclen, + EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo) +{ + int dstlen, totlen; + + if (EVP_EncryptInit_ex(ctx, algo, NULL, key, iv) <= 0) + goto process_cipher_encrypt_err; + + if (EVP_EncryptUpdate(ctx, dst, &dstlen, src, srclen) <= 0) + goto process_cipher_encrypt_err; + + if (EVP_EncryptFinal_ex(ctx, dst + dstlen, &totlen) <= 0) + goto process_cipher_encrypt_err; + + return 0; + +process_cipher_encrypt_err: + LIBCRYPTO_LOG_ERR("Process libcrypto cipher encrypt failed"); + return -EINVAL; +} + +/** Process standard libcrypto cipher decryption */ +static int +process_libcrypto_cipher_decrypt(uint8_t *src, uint8_t *dst, + uint8_t *iv, uint8_t *key, int srclen, + EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo) +{ + int dstlen, totlen; + + if (EVP_DecryptInit_ex(ctx, algo, NULL, key, iv) <= 0) + goto process_cipher_decrypt_err; + + if (EVP_CIPHER_CTX_set_padding(ctx, 0) <= 0) + goto process_cipher_decrypt_err; + + if (EVP_DecryptUpdate(ctx, dst, &dstlen, src, srclen) <= 0) + goto process_cipher_decrypt_err; + + if (EVP_DecryptFinal_ex(ctx, dst + dstlen, &totlen) <= 0) + goto process_cipher_decrypt_err; + + return 0; + +process_cipher_decrypt_err: + LIBCRYPTO_LOG_ERR("Process libcrypto cipher decrypt failed"); + return -EINVAL; +} + +/** Process cipher des 3 ctr encryption, decryption algorithm */ +static int +process_libcrypto_cipher_des3ctr(uint8_t *src, uint8_t *dst, + uint8_t *iv, uint8_t *key, int srclen, EVP_CIPHER_CTX *ctx) +{ + uint8_t ebuf[8], ctr[8]; + int unused, n; + + /* We use 3DES encryption also for decryption. + * IV is not important for 3DES ecb + */ + if (EVP_EncryptInit_ex(ctx, EVP_des_ede3_ecb(), NULL, key, NULL) <= 0) + goto process_cipher_des3ctr_err; + + memcpy(ctr, iv, 8); + n = 0; + + while (n < srclen) { + if (n % 8 == 0) { + if (EVP_EncryptUpdate(ctx, (unsigned char *)&ebuf, &unused, + (const unsigned char *)&ctr, 8) <= 0) + goto process_cipher_des3ctr_err; + ctr_inc(ctr); + } + dst[n] = src[n] ^ ebuf[n % 8]; + n++; + } + + return 0; + +process_cipher_des3ctr_err: + LIBCRYPTO_LOG_ERR("Process libcrypto cipher des 3 ede ctr failed"); + return -EINVAL; +} + +/** Process auth/encription aes-gcm algorithm */ +static int +process_libcrypto_auth_encryption_gcm(uint8_t *src, int srclen, + uint8_t *aad, int aadlen, uint8_t *iv, int ivlen, + uint8_t *key, uint8_t *dst, uint8_t *tag, + EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo) +{ + int len = 0, unused = 0; + uint8_t empty[] = {}; + + if (EVP_EncryptInit_ex(ctx, algo, NULL, NULL, NULL) <= 0) + goto process_auth_encryption_gcm_err; + + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, NULL) <= 0) + goto process_auth_encryption_gcm_err; + + if (EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv) <= 0) + goto process_auth_encryption_gcm_err; + + if (aadlen > 0) { + if (EVP_EncryptUpdate(ctx, NULL, &len, aad, aadlen) <= 0) + goto process_auth_encryption_gcm_err; + + /* Workaround open ssl bug in version less then 1.0.1f */ + if (EVP_EncryptUpdate(ctx, empty, &unused, empty, 0) <= 0) + goto process_auth_encryption_gcm_err; + } + + if (srclen > 0) + if (EVP_EncryptUpdate(ctx, dst, &len, src, srclen) <= 0) + goto process_auth_encryption_gcm_err; + + if (EVP_EncryptFinal_ex(ctx, dst + len, &len) <= 0) + goto process_auth_encryption_gcm_err; + + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag) <= 0) + goto process_auth_encryption_gcm_err; + + return 0; + +process_auth_encryption_gcm_err: + LIBCRYPTO_LOG_ERR("Process libcrypto auth encryption gcm failed"); + return -EINVAL; +} + +static int +process_libcrypto_auth_decryption_gcm(uint8_t *src, int srclen, + uint8_t *aad, int aadlen, uint8_t *iv, int ivlen, + uint8_t *key, uint8_t *dst, uint8_t *tag, + EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo) +{ + int len = 0, unused = 0; + uint8_t empty[] = {}; + + if (EVP_DecryptInit_ex(ctx, algo, NULL, NULL, NULL) <= 0) + goto process_auth_decryption_gcm_err; + + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, NULL) <= 0) + goto process_auth_decryption_gcm_err; + + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag) <= 0) + goto process_auth_decryption_gcm_err; + + if (EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv) <= 0) + goto process_auth_decryption_gcm_err; + + if (aadlen > 0) { + if (EVP_DecryptUpdate(ctx, NULL, &len, aad, aadlen) <= 0) + goto process_auth_decryption_gcm_err; + + /* Workaround open ssl bug in version less then 1.0.1f */ + if (EVP_DecryptUpdate(ctx, empty, &unused, empty, 0) <= 0) + goto process_auth_decryption_gcm_err; + } + + if (srclen > 0) + if (EVP_DecryptUpdate(ctx, dst, &len, src, srclen) <= 0) + goto process_auth_decryption_gcm_err; + + if (EVP_DecryptFinal_ex(ctx, dst + len, &len) <= 0) + goto process_auth_decryption_gcm_err; + + return 0; + +process_auth_decryption_gcm_err: + LIBCRYPTO_LOG_ERR("Process libcrypto auth decription gcm failed"); + return -EINVAL; +} + +/** Process standard libcrypto auth algorithms */ +static int +process_libcrypto_auth(uint8_t *src, uint8_t *dst, + __rte_unused uint8_t *iv, __rte_unused EVP_PKEY * pkey, + int srclen, EVP_MD_CTX *ctx, const EVP_MD *algo) +{ + size_t dstlen; + + if (EVP_DigestInit_ex(ctx, algo, NULL) <= 0) + goto process_auth_err; + + if (EVP_DigestUpdate(ctx, (char *)src, srclen) <= 0) + goto process_auth_err; + + if (EVP_DigestFinal_ex(ctx, dst, (unsigned int *)&dstlen) <= 0) + goto process_auth_err; + + return 0; + +process_auth_err: + LIBCRYPTO_LOG_ERR("Process libcrypto auth failed"); + return -EINVAL; +} + +/** Process standard libcrypto auth algorithms with hmac */ +static int +process_libcrypto_auth_hmac(uint8_t *src, uint8_t *dst, + __rte_unused uint8_t *iv, EVP_PKEY *pkey, + int srclen, EVP_MD_CTX *ctx, const EVP_MD *algo) +{ + size_t dstlen; + + if (EVP_DigestSignInit(ctx, NULL, algo, NULL, pkey) <= 0) + goto process_auth_err; + + if (EVP_DigestSignUpdate(ctx, (char *)src, srclen) <= 0) + goto process_auth_err; + + if (EVP_DigestSignFinal(ctx, dst, &dstlen) <= 0) + goto process_auth_err; + + return 0; + +process_auth_err: + LIBCRYPTO_LOG_ERR("Process libcrypto auth failed"); + return -EINVAL; +} + +/*----------------------------------------------------------------------------*/ + +/** Process auth/cipher operation */ +static int +process_libcrypto_combined_op + (struct rte_crypto_op *op, struct libcrypto_session *sess, + struct rte_mbuf *mbuf_src, struct rte_mbuf *mbuf_dst) +{ + /* cipher */ + uint8_t *src = NULL, *dst = NULL, *iv, *tag, *aad; + int srclen, ivlen, aadlen, status = -1; + + iv = op->sym->cipher.iv.data; + ivlen = op->sym->cipher.iv.length; + aad = op->sym->auth.aad.data; + aadlen = op->sym->auth.aad.length; + + tag = op->sym->auth.digest.data; + if (tag == NULL) + tag = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *, + op->sym->cipher.data.offset + + op->sym->cipher.data.length); + + if (sess->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) + srclen = 0; + else { + srclen = op->sym->cipher.data.length; + src = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *, + op->sym->cipher.data.offset); + dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *, + op->sym->cipher.data.offset); + } + + if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) + status = process_libcrypto_auth_encryption_gcm( + src, srclen, aad, aadlen, iv, ivlen, + sess->cipher.key.data, dst, tag, + sess->cipher.ctx, sess->cipher.evp_algo); + else + status = process_libcrypto_auth_decryption_gcm( + src, srclen, aad, aadlen, iv, ivlen, + sess->cipher.key.data, dst, tag, + sess->cipher.ctx, sess->cipher.evp_algo); + + if (status == 0) + op->status = RTE_CRYPTO_OP_STATUS_SUCCESS; + else + op->status = RTE_CRYPTO_OP_STATUS_ERROR; + + return status; +} + +/** Process cipher operation */ +static int +process_libcrypto_cipher_op + (struct rte_crypto_op *op, struct libcrypto_session *sess, + struct rte_mbuf *mbuf_src, struct rte_mbuf *mbuf_dst) +{ + uint8_t *src, *dst, *iv; + int srclen, status; + + srclen = op->sym->cipher.data.length; + src = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *, + op->sym->cipher.data.offset); + dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *, + op->sym->cipher.data.offset); + + iv = op->sym->cipher.iv.data; + + if (sess->cipher.mode == LIBCRYPTO_CIPHER_LIB) + if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) + status = process_libcrypto_cipher_encrypt(src, dst, iv, + sess->cipher.key.data, srclen, + sess->cipher.ctx, sess->cipher.evp_algo); + else + status = process_libcrypto_cipher_decrypt(src, dst, iv, + sess->cipher.key.data, srclen, + sess->cipher.ctx, sess->cipher.evp_algo); + else + status = process_libcrypto_cipher_des3ctr(src, dst, iv, + sess->cipher.key.data, srclen, sess->cipher.ctx); + + if (status == 0) + op->status = RTE_CRYPTO_OP_STATUS_SUCCESS; + else + op->status = RTE_CRYPTO_OP_STATUS_ERROR; + + return status; +} + +/** Process auth operation */ +static int +process_libcrypto_auth_op + (struct rte_crypto_op *op, struct libcrypto_session *sess, + struct rte_mbuf *mbuf_src, struct rte_mbuf *mbuf_dst) +{ + uint8_t *src, *dst; + int srclen, status = -1; + + srclen = op->sym->auth.data.length; + src = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *, + op->sym->auth.data.offset); + dst = op->sym->auth.digest.data; + if (dst == NULL) { + if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_GENERATE) + dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *, + op->sym->auth.data.offset + + op->sym->auth.data.length); + else + dst = (uint8_t *)rte_pktmbuf_append(mbuf_src, + op->sym->auth.digest.length); + } + + switch (sess->auth.mode) { + case LIBCRYPTO_AUTH_AS_AUTH: + status = process_libcrypto_auth(src, dst, + NULL, NULL, srclen, + sess->auth.auth.ctx, sess->auth.auth.evp_algo); + break; + case LIBCRYPTO_AUTH_AS_HMAC: + status = process_libcrypto_auth_hmac(src, dst, + NULL, sess->auth.hmac.pkey, srclen, + sess->auth.hmac.ctx, sess->auth.hmac.evp_algo); + break; + default: + break; + } + + if (status == 0) { + op->status = RTE_CRYPTO_OP_STATUS_SUCCESS; + + if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY) { + if (memcmp(dst, op->sym->auth.digest.data, + op->sym->auth.digest.length) != 0) { + op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED; + status = -EINVAL; + } + } + } else + op->status = RTE_CRYPTO_OP_STATUS_ERROR; + + return status; +} + +/** Process crypto operation for mbuf */ +static int +process_op(const struct libcrypto_qp *qp, struct rte_crypto_op *op, + struct libcrypto_session *sess) +{ + struct rte_mbuf *msrc, *mdst; + int status; + + msrc = op->sym->m_src; + mdst = op->sym->m_dst ? op->sym->m_dst : op->sym->m_src; + + switch (sess->chain_order) { + case LIBCRYPTO_CHAIN_ONLY_CIPHER: + status = process_libcrypto_cipher_op(op, sess, msrc, mdst); + break; + case LIBCRYPTO_CHAIN_ONLY_AUTH: + status = process_libcrypto_auth_op(op, sess, msrc, mdst); + break; + case LIBCRYPTO_CHAIN_CIPHER_AUTH: + status = process_libcrypto_cipher_op(op, sess, msrc, mdst); + if (status == 0) + status = process_libcrypto_auth_op(op, sess, mdst, mdst); + break; + case LIBCRYPTO_CHAIN_AUTH_CIPHER: + status = process_libcrypto_auth_op(op, sess, msrc, mdst); + if (status == 0) + status = process_libcrypto_cipher_op(op, sess, msrc, mdst); + break; + case LIBCRYPTO_CHAIN_COMBINED: + status = process_libcrypto_combined_op(op, sess, msrc, mdst); + break; + default: + status = -1; + break; + } + + /* Free session if a session-less crypto op */ + if (op->sym->sess_type == RTE_CRYPTO_SYM_OP_SESSIONLESS) { + libcrypto_reset_session(sess); + memset(sess, 0, sizeof(struct libcrypto_session)); + rte_mempool_put(qp->sess_mp, op->sym->session); + op->sym->session = NULL; + } + + if (status != 0) + return -1; + + return rte_ring_enqueue(qp->processed_ops, (void *)op); +} + +/* + *------------------------------------------------------------------------------ + * PMD Framework + *------------------------------------------------------------------------------ + */ + +/** Enqueue burst */ +static uint16_t +libcrypto_pmd_enqueue_burst(void *queue_pair, struct rte_crypto_op **ops, + uint16_t nb_ops) +{ + struct libcrypto_session *sess; + struct libcrypto_qp *qp = queue_pair; + int i, retval; + + for (i = 0; i < nb_ops; i++) { + sess = get_session(qp, ops[i]); + if (unlikely(sess == NULL)) + goto enqueue_err; + + retval = process_op(qp, ops[i], sess); + if (unlikely(retval < 0)) + goto enqueue_err; + } + + qp->stats.enqueued_count += i; + return i; + +enqueue_err: + qp->stats.enqueue_err_count++; + return i; +} + +/** Dequeue burst */ +static uint16_t +libcrypto_pmd_dequeue_burst(void *queue_pair, struct rte_crypto_op **ops, + uint16_t nb_ops) +{ + struct libcrypto_qp *qp = queue_pair; + + unsigned int nb_dequeued = 0; + + nb_dequeued = rte_ring_dequeue_burst(qp->processed_ops, + (void **)ops, nb_ops); + qp->stats.dequeued_count += nb_dequeued; + + return nb_dequeued; +} + +/** Create LIBCRYPTO crypto device */ +static int +cryptodev_libcrypto_create(const char *name, + struct rte_crypto_vdev_init_params *init_params) +{ + struct rte_cryptodev *dev; + char crypto_dev_name[RTE_CRYPTODEV_NAME_MAX_LEN]; + struct libcrypto_private *internals; + + /* create a unique device name */ + if (create_unique_device_name(crypto_dev_name, + RTE_CRYPTODEV_NAME_MAX_LEN) != 0) { + LIBCRYPTO_LOG_ERR("failed to create unique cryptodev name"); + return -EINVAL; + } + + dev = rte_cryptodev_pmd_virtual_dev_init(crypto_dev_name, + sizeof(struct libcrypto_private), init_params->socket_id); + if (dev == NULL) { + LIBCRYPTO_LOG_ERR("failed to create cryptodev vdev"); + goto init_error; + } + + dev->dev_type = RTE_CRYPTODEV_LIBCRYPTO_PMD; + dev->dev_ops = rte_libcrypto_pmd_ops; + + /* register rx/tx burst functions for data path */ + dev->dequeue_burst = libcrypto_pmd_dequeue_burst; + dev->enqueue_burst = libcrypto_pmd_enqueue_burst; + + dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO | + RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING | + RTE_CRYPTODEV_FF_CPU_AESNI; + + /* Set vector instructions mode supported */ + internals = dev->data->dev_private; + + internals->max_nb_qpairs = init_params->max_nb_queue_pairs; + internals->max_nb_sessions = init_params->max_nb_sessions; + + return 0; + +init_error: + LIBCRYPTO_LOG_ERR("driver %s: cryptodev_libcrypto_create failed", name); + + cryptodev_libcrypto_uninit(crypto_dev_name); + return -EFAULT; +} + +/** Initialise LIBCRYPTO crypto device */ +static int +cryptodev_libcrypto_init(const char *name, + const char *input_args) +{ + struct rte_crypto_vdev_init_params init_params = { + RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_QUEUE_PAIRS, + RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_SESSIONS, + rte_socket_id() + }; + + rte_cryptodev_parse_vdev_init_params(&init_params, input_args); + + RTE_LOG(INFO, PMD, "Initialising %s on NUMA node %d\n", name, + init_params.socket_id); + RTE_LOG(INFO, PMD, " Max number of queue pairs = %d\n", + init_params.max_nb_queue_pairs); + RTE_LOG(INFO, PMD, " Max number of sessions = %d\n", + init_params.max_nb_sessions); + + return cryptodev_libcrypto_create(name, &init_params); +} + +/** Uninitialise LIBCRYPTO crypto device */ +static int +cryptodev_libcrypto_uninit(const char *name) +{ + if (name == NULL) + return -EINVAL; + + RTE_LOG(INFO, PMD, + "Closing LIBCRYPTO crypto device %s on numa socket %u\n", + name, rte_socket_id()); + + return 0; +} + +static struct rte_driver cryptodev_libcrypto_pmd_drv = { + .type = PMD_VDEV, + .init = cryptodev_libcrypto_init, + .uninit = cryptodev_libcrypto_uninit +}; + +PMD_REGISTER_DRIVER(cryptodev_libcrypto_pmd_drv, CRYPTODEV_NAME_LIBCRYPTO_PMD); +DRIVER_REGISTER_PARAM_STRING(CRYPTODEV_NAME_LIBCRYPTO_PMD, + "max_nb_queue_pairs=<int> " + "max_nb_sessions=<int> " + "socket_id=<int>"); diff --git a/drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c b/drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c new file mode 100644 index 0000000..ae27359 --- /dev/null +++ b/drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c @@ -0,0 +1,708 @@ +/*- + * 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 <string.h> + +#include <rte_common.h> +#include <rte_malloc.h> +#include <rte_cryptodev_pmd.h> + +#include "rte_libcrypto_pmd_private.h" + + +static const struct rte_cryptodev_capabilities libcrypto_pmd_capabilities[] = { + { /* MD5 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_MD5_HMAC, + .block_size = 64, + .key_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .digest_size = { + .min = 16, + .max = 16, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* MD5 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_MD5, + .block_size = 64, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 16, + .max = 16, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA1 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .block_size = 64, + .key_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .digest_size = { + .min = 20, + .max = 20, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA1 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA1, + .block_size = 64, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 20, + .max = 20, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA224 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA224_HMAC, + .block_size = 64, + .key_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .digest_size = { + .min = 20, + .max = 20, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA224 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA224, + .block_size = 64, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 28, + .max = 28, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA256 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA256_HMAC, + .block_size = 64, + .key_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .digest_size = { + .min = 32, + .max = 32, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA256 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA256, + .block_size = 64, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 32, + .max = 32, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA384 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA384_HMAC, + .block_size = 128, + .key_size = { + .min = 128, + .max = 128, + .increment = 0 + }, + .digest_size = { + .min = 48, + .max = 48, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA384 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA384, + .block_size = 128, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 48, + .max = 48, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA512 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA512_HMAC, + .block_size = 128, + .key_size = { + .min = 128, + .max = 128, + .increment = 0 + }, + .digest_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA512 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA512, + .block_size = 128, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* AES CBC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, + {.cipher = { + .algo = RTE_CRYPTO_CIPHER_AES_CBC, + .block_size = 16, + .key_size = { + .min = 16, + .max = 32, + .increment = 8 + }, + .iv_size = { + .min = 16, + .max = 16, + .increment = 0 + } + }, } + }, } + }, + { /* AES CTR */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, + {.cipher = { + .algo = RTE_CRYPTO_CIPHER_AES_CTR, + .block_size = 16, + .key_size = { + .min = 16, + .max = 32, + .increment = 8 + }, + .iv_size = { + .min = 16, + .max = 16, + .increment = 0 + } + }, } + }, } + }, + { /* AES GCM (AUTH) */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_AES_GCM, + .block_size = 16, + .key_size = { + .min = 16, + .max = 32, + .increment = 8 + }, + .digest_size = { + .min = 16, + .max = 16, + .increment = 0 + }, + .aad_size = { + .min = 8, + .max = 12, + .increment = 4 + } + }, } + }, } + }, + { /* AES GCM (CIPHER) */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, + {.cipher = { + .algo = RTE_CRYPTO_CIPHER_AES_GCM, + .block_size = 16, + .key_size = { + .min = 16, + .max = 16, + .increment = 0 + }, + .iv_size = { + .min = 12, + .max = 16, + .increment = 4 + } + }, } + }, } + }, + { /* AES GMAC (AUTH) */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_AES_GMAC, + .block_size = 16, + .key_size = { + .min = 16, + .max = 32, + .increment = 8 + }, + .digest_size = { + .min = 16, + .max = 16, + .increment = 0 + }, + .aad_size = { + .min = 8, + .max = 12, + .increment = 4 + } + }, } + }, } + }, + { /* 3DES CBC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, + {.cipher = { + .algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .block_size = 8, + .key_size = { + .min = 16, + .max = 24, + .increment = 8 + }, + .iv_size = { + .min = 8, + .max = 8, + .increment = 0 + } + }, } + }, } + }, + { /* 3DES CTR */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, + {.cipher = { + .algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .block_size = 8, + .key_size = { + .min = 16, + .max = 24, + .increment = 8 + }, + .iv_size = { + .min = 8, + .max = 8, + .increment = 0 + } + }, } + }, } + }, + + RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST() +}; + + +/** Configure device */ +static int +libcrypto_pmd_config(__rte_unused struct rte_cryptodev *dev) +{ + return 0; +} + +/** Start device */ +static int +libcrypto_pmd_start(__rte_unused struct rte_cryptodev *dev) +{ + return 0; +} + +/** Stop device */ +static void +libcrypto_pmd_stop(__rte_unused struct rte_cryptodev *dev) +{ +} + +/** Close device */ +static int +libcrypto_pmd_close(__rte_unused struct rte_cryptodev *dev) +{ + return 0; +} + + +/** Get device statistics */ +static void +libcrypto_pmd_stats_get(struct rte_cryptodev *dev, + struct rte_cryptodev_stats *stats) +{ + int qp_id; + + for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) { + struct libcrypto_qp *qp = dev->data->queue_pairs[qp_id]; + + stats->enqueued_count += qp->stats.enqueued_count; + stats->dequeued_count += qp->stats.dequeued_count; + + stats->enqueue_err_count += qp->stats.enqueue_err_count; + stats->dequeue_err_count += qp->stats.dequeue_err_count; + } +} + +/** Reset device statistics */ +static void +libcrypto_pmd_stats_reset(struct rte_cryptodev *dev) +{ + int qp_id; + + for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) { + struct libcrypto_qp *qp = dev->data->queue_pairs[qp_id]; + + memset(&qp->stats, 0, sizeof(qp->stats)); + } +} + + +/** Get device info */ +static void +libcrypto_pmd_info_get(struct rte_cryptodev *dev, + struct rte_cryptodev_info *dev_info) +{ + struct libcrypto_private *internals = dev->data->dev_private; + + if (dev_info != NULL) { + dev_info->dev_type = dev->dev_type; + dev_info->feature_flags = dev->feature_flags; + dev_info->capabilities = libcrypto_pmd_capabilities; + dev_info->max_nb_queue_pairs = internals->max_nb_qpairs; + dev_info->sym.max_nb_sessions = internals->max_nb_sessions; + } +} + +/** Release queue pair */ +static int +libcrypto_pmd_qp_release(struct rte_cryptodev *dev, uint16_t qp_id) +{ + if (dev->data->queue_pairs[qp_id] != NULL) { + rte_free(dev->data->queue_pairs[qp_id]); + dev->data->queue_pairs[qp_id] = NULL; + } + return 0; +} + +/** set a unique name for the queue pair based on it's name, dev_id and qp_id */ +static int +libcrypto_pmd_qp_set_unique_name(struct rte_cryptodev *dev, + struct libcrypto_qp *qp) +{ + unsigned int n = snprintf(qp->name, sizeof(qp->name), + "libcrypto_pmd_%u_qp_%u", + dev->data->dev_id, qp->id); + + if (n > sizeof(qp->name)) + return -1; + + return 0; +} + + +/** Create a ring to place processed operations on */ +static struct rte_ring * +libcrypto_pmd_qp_create_processed_ops_ring(struct libcrypto_qp *qp, + unsigned int ring_size, int socket_id) +{ + struct rte_ring *r; + + r = rte_ring_lookup(qp->name); + if (r) { + if (r->prod.size >= ring_size) { + LIBCRYPTO_LOG_INFO( + "Reusing existing ring %s for processed ops", + qp->name); + return r; + } + + LIBCRYPTO_LOG_ERR( + "Unable to reuse existing ring %s for processed ops", + qp->name); + return NULL; + } + + return rte_ring_create(qp->name, ring_size, socket_id, + RING_F_SP_ENQ | RING_F_SC_DEQ); +} + + +/** Setup a queue pair */ +static int +libcrypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id, + const struct rte_cryptodev_qp_conf *qp_conf, + int socket_id) +{ + struct libcrypto_qp *qp = NULL; + + /* Free memory prior to re-allocation if needed. */ + if (dev->data->queue_pairs[qp_id] != NULL) + libcrypto_pmd_qp_release(dev, qp_id); + + /* Allocate the queue pair data structure. */ + qp = rte_zmalloc_socket("LIBCRYPTO PMD Queue Pair", sizeof(*qp), + RTE_CACHE_LINE_SIZE, socket_id); + if (qp == NULL) + return -ENOMEM; + + qp->id = qp_id; + dev->data->queue_pairs[qp_id] = qp; + + if (libcrypto_pmd_qp_set_unique_name(dev, qp)) + goto qp_setup_cleanup; + + qp->processed_ops = libcrypto_pmd_qp_create_processed_ops_ring(qp, + qp_conf->nb_descriptors, socket_id); + if (qp->processed_ops == NULL) + goto qp_setup_cleanup; + + qp->sess_mp = dev->data->session_pool; + + memset(&qp->stats, 0, sizeof(qp->stats)); + + return 0; + +qp_setup_cleanup: + if (qp) + rte_free(qp); + + return -1; +} + +/** Start queue pair */ +static int +libcrypto_pmd_qp_start(__rte_unused struct rte_cryptodev *dev, + __rte_unused uint16_t queue_pair_id) +{ + return -ENOTSUP; +} + +/** Stop queue pair */ +static int +libcrypto_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev, + __rte_unused uint16_t queue_pair_id) +{ + return -ENOTSUP; +} + +/** Return the number of allocated queue pairs */ +static uint32_t +libcrypto_pmd_qp_count(struct rte_cryptodev *dev) +{ + return dev->data->nb_queue_pairs; +} + +/** Returns the size of the session structure */ +static unsigned +libcrypto_pmd_session_get_size(struct rte_cryptodev *dev __rte_unused) +{ + return sizeof(struct libcrypto_session); +} + +/** Configure the session from a crypto xform chain */ +static void * +libcrypto_pmd_session_configure(struct rte_cryptodev *dev __rte_unused, + struct rte_crypto_sym_xform *xform, void *sess) +{ + if (unlikely(sess == NULL)) { + LIBCRYPTO_LOG_ERR("invalid session struct"); + return NULL; + } + + if (libcrypto_set_session_parameters( + sess, xform) != 0) { + LIBCRYPTO_LOG_ERR("failed configure session parameters"); + return NULL; + } + + return sess; +} + + +/** Clear the memory of session so it doesn't leave key material behind */ +static void +libcrypto_pmd_session_clear(struct rte_cryptodev *dev __rte_unused, void *sess) +{ + /* + * Current just resetting the whole data structure, need to investigate + * whether a more selective reset of key would be more performant + */ + if (sess) { + libcrypto_reset_session(sess); + memset(sess, 0, sizeof(struct libcrypto_session)); + } +} + +struct rte_cryptodev_ops libcrypto_pmd_ops = { + .dev_configure = libcrypto_pmd_config, + .dev_start = libcrypto_pmd_start, + .dev_stop = libcrypto_pmd_stop, + .dev_close = libcrypto_pmd_close, + + .stats_get = libcrypto_pmd_stats_get, + .stats_reset = libcrypto_pmd_stats_reset, + + .dev_infos_get = libcrypto_pmd_info_get, + + .queue_pair_setup = libcrypto_pmd_qp_setup, + .queue_pair_release = libcrypto_pmd_qp_release, + .queue_pair_start = libcrypto_pmd_qp_start, + .queue_pair_stop = libcrypto_pmd_qp_stop, + .queue_pair_count = libcrypto_pmd_qp_count, + + .session_get_size = libcrypto_pmd_session_get_size, + .session_configure = libcrypto_pmd_session_configure, + .session_clear = libcrypto_pmd_session_clear +}; + +struct rte_cryptodev_ops *rte_libcrypto_pmd_ops = &libcrypto_pmd_ops; diff --git a/drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h b/drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h new file mode 100644 index 0000000..dbef57f --- /dev/null +++ b/drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h @@ -0,0 +1,174 @@ +/*- + * 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 _LIBCRYPTO_PMD_PRIVATE_H_ +#define _LIBCRYPTO_PMD_PRIVATE_H_ + +#include <openssl/evp.h> +#include <openssl/des.h> + + +#define LIBCRYPTO_LOG_ERR(fmt, args...) \ + RTE_LOG(ERR, CRYPTODEV, "[%s] %s() line %u: " fmt "\n", \ + RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), \ + __func__, __LINE__, ## args) + +#ifdef RTE_LIBRTE_LIBCRYPTO_DEBUG +#define LIBCRYPTO_LOG_INFO(fmt, args...) \ + RTE_LOG(INFO, CRYPTODEV, "[%s] %s() line %u: " fmt "\n", \ + RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), \ + __func__, __LINE__, ## args) + +#define LIBCRYPTO_LOG_DBG(fmt, args...) \ + RTE_LOG(DEBUG, CRYPTODEV, "[%s] %s() line %u: " fmt "\n", \ + RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), \ + __func__, __LINE__, ## args) +#else +#define LIBCRYPTO_LOG_INFO(fmt, args...) +#define LIBCRYPTO_LOG_DBG(fmt, args...) +#endif + + +/** LIBCRYPTO operation order mode enumerator */ +enum libcrypto_chain_order { + LIBCRYPTO_CHAIN_ONLY_CIPHER, + LIBCRYPTO_CHAIN_ONLY_AUTH, + LIBCRYPTO_CHAIN_CIPHER_AUTH, + LIBCRYPTO_CHAIN_AUTH_CIPHER, + LIBCRYPTO_CHAIN_COMBINED, + LIBCRYPTO_CHAIN_NOT_SUPPORTED +}; + +/** LIBCRYPTO cipher mode enumerator */ +enum libcrypto_cipher_mode { + LIBCRYPTO_CIPHER_LIB, + LIBCRYPTO_CIPHER_DES3CTR, +}; + +/** LIBCRYPTO auth mode enumerator */ +enum libcrypto_auth_mode { + LIBCRYPTO_AUTH_AS_AUTH, + LIBCRYPTO_AUTH_AS_HMAC, +}; + +/** private data structure for each LIBCRYPTO crypto device */ +struct libcrypto_private { + unsigned int max_nb_qpairs; + /**< Max number of queue pairs */ + unsigned int max_nb_sessions; + /**< Max number of sessions */ +}; + +/** LIBCRYPTO crypto queue pair */ +struct libcrypto_qp { + uint16_t id; + /**< Queue Pair Identifier */ + char name[RTE_CRYPTODEV_NAME_LEN]; + /**< Unique Queue Pair Name */ + struct rte_ring *processed_ops; + /**< Ring for placing process packets */ + struct rte_mempool *sess_mp; + /**< Session Mempool */ + struct rte_cryptodev_stats stats; + /**< Queue pair statistics */ +} __rte_cache_aligned; + +/** LIBCRYPTO crypto private session structure */ +struct libcrypto_session { + enum libcrypto_chain_order chain_order; + /**< chain order mode */ + + /** Cipher Parameters */ + struct { + enum rte_crypto_cipher_operation direction; + /**< cipher operation direction */ + enum libcrypto_cipher_mode mode; + /**< cipher operation mode */ + enum rte_crypto_cipher_algorithm algo; + /**< cipher algorithm */ + + struct { + uint8_t data[32]; + /**< key data */ + size_t length; + /**< key length in bytes */ + } key; + + const EVP_CIPHER *evp_algo; + /**< pointer to EVP algorithm function */ + EVP_CIPHER_CTX *ctx; + /**< pointer to EVP context structure */ + } cipher; + + /** Authentication Parameters */ + struct { + enum rte_crypto_auth_operation operation; + /**< auth operation generate or verify */ + enum libcrypto_auth_mode mode; + /**< auth operation mode */ + enum rte_crypto_auth_algorithm algo; + /**< cipher algorithm */ + + union { + struct { + const EVP_MD *evp_algo; + /**< pointer to EVP algorithm function */ + EVP_MD_CTX *ctx; + /**< pointer to EVP context structure */ + } auth; + + struct { + EVP_PKEY *pkey; + /**< pointer to EVP key */ + const EVP_MD *evp_algo; + /**< pointer to EVP algorithm function */ + EVP_MD_CTX *ctx; + /**< pointer to EVP context structure */ + } hmac; + }; + } auth; + +} __rte_cache_aligned; + +/** Set and validate LIBCRYPTO crypto session parameters */ +extern int +libcrypto_set_session_parameters(struct libcrypto_session *sess, + const struct rte_crypto_sym_xform *xform); + +/** Reset LIBCRYPTO crypto session parameters */ +extern void +libcrypto_reset_session(struct libcrypto_session *sess); + +/** device specific operations function pointer structure */ +extern struct rte_cryptodev_ops *rte_libcrypto_pmd_ops; + +#endif /* _LIBCRYPTO_PMD_PRIVATE_H_ */ diff --git a/drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map b/drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map new file mode 100644 index 0000000..cc5829e --- /dev/null +++ b/drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map @@ -0,0 +1,3 @@ +DPDK_16.11 { + local: *; +}; diff --git a/mk/rte.app.mk b/mk/rte.app.mk index 1a0095b..67c0aa9 100644 --- a/mk/rte.app.mk +++ b/mk/rte.app.mk @@ -135,7 +135,8 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -lrte_pmd_aesni_mb _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += -lrte_pmd_aesni_gcm -lcrypto _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO) += -lrte_pmd_null_crypto +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += -lrte_pmd_libcrypto -lcrypto +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO)+= -lrte_pmd_null_crypto _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += -lrte_pmd_qat -lcrypto _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += -lrte_pmd_snow3g _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += -L$(LIBSSO_SNOW3G_PATH)/build -lsso_snow3g -- 1.9.1 ^ permalink raw reply [flat|nested] 34+ messages in thread
* [dpdk-dev] [PATCH v2 2/4] lib/cryptodev: added support to libcrypto PMD 2016-09-19 8:59 [dpdk-dev] [PATCH v2 0/4] new crypto software based device Michal Jastrzebski 2016-09-19 8:59 ` [dpdk-dev] [PATCH v2 1/4] libcrypto_pmd: initial implementation of SW crypto device Michal Jastrzebski @ 2016-09-19 8:59 ` Michal Jastrzebski 2016-09-19 22:59 ` De Lara Guarch, Pablo 2016-09-19 8:59 ` [dpdk-dev] [PATCH v2 3/4] app/test: added tests for " Michal Jastrzebski ` (2 subsequent siblings) 4 siblings, 1 reply; 34+ messages in thread From: Michal Jastrzebski @ 2016-09-19 8:59 UTC (permalink / raw) To: dev; +Cc: pablo.de.lara.guarch, Slawomir Mrozowicz From: Slawomir Mrozowicz <slawomirx.mrozowicz@intel.com> This patch adds libcrypto poll mode driver support to librte_cryptodev library. Signed-off-by: Slawomir Mrozowicz <slawomirx.mrozowicz@intel.com> --- lib/librte_cryptodev/rte_cryptodev.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h index d047ba8..3a91c44 100644 --- a/lib/librte_cryptodev/rte_cryptodev.h +++ b/lib/librte_cryptodev/rte_cryptodev.h @@ -56,6 +56,8 @@ extern "C" { /**< AES-NI Multi buffer PMD device name */ #define CRYPTODEV_NAME_AESNI_GCM_PMD cryptodev_aesni_gcm_pmd /**< AES-NI GCM PMD device name */ +#define CRYPTODEV_NAME_LIBCRYPTO_PMD cryptodev_libcrypto_pmd +/**< Open SSL Crypto PMD device name */ #define CRYPTODEV_NAME_QAT_SYM_PMD cryptodev_qat_sym_pmd /**< Intel QAT Symmetric Crypto PMD device name */ #define CRYPTODEV_NAME_SNOW3G_PMD cryptodev_snow3g_pmd @@ -71,6 +73,7 @@ enum rte_cryptodev_type { RTE_CRYPTODEV_QAT_SYM_PMD, /**< QAT PMD Symmetric Crypto */ RTE_CRYPTODEV_SNOW3G_PMD, /**< SNOW 3G PMD */ RTE_CRYPTODEV_KASUMI_PMD, /**< KASUMI PMD */ + RTE_CRYPTODEV_LIBCRYPTO_PMD, /**< LibCrypto PMD */ }; extern const char **rte_cyptodev_names; -- 1.9.1 ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dpdk-dev] [PATCH v2 2/4] lib/cryptodev: added support to libcrypto PMD 2016-09-19 8:59 ` [dpdk-dev] [PATCH v2 2/4] lib/cryptodev: added support to libcrypto PMD Michal Jastrzebski @ 2016-09-19 22:59 ` De Lara Guarch, Pablo 0 siblings, 0 replies; 34+ messages in thread From: De Lara Guarch, Pablo @ 2016-09-19 22:59 UTC (permalink / raw) To: Jastrzebski, MichalX K, dev; +Cc: Mrozowicz, SlawomirX > -----Original Message----- > From: Jastrzebski, MichalX K > Sent: Monday, September 19, 2016 2:00 AM > To: dev@dpdk.org > Cc: De Lara Guarch, Pablo; Mrozowicz, SlawomirX > Subject: [PATCH v2 2/4] lib/cryptodev: added support to libcrypto PMD > > From: Slawomir Mrozowicz <slawomirx.mrozowicz@intel.com> > > This patch adds libcrypto poll mode driver support to > librte_cryptodev library. > > Signed-off-by: Slawomir Mrozowicz <slawomirx.mrozowicz@intel.com> This patch can be merged to the previous patch, no need to have it separated, despite making a change in the lib folder. Doing this allows compilation of the PMD from the first patch. ^ permalink raw reply [flat|nested] 34+ messages in thread
* [dpdk-dev] [PATCH v2 3/4] app/test: added tests for libcrypto PMD 2016-09-19 8:59 [dpdk-dev] [PATCH v2 0/4] new crypto software based device Michal Jastrzebski 2016-09-19 8:59 ` [dpdk-dev] [PATCH v2 1/4] libcrypto_pmd: initial implementation of SW crypto device Michal Jastrzebski 2016-09-19 8:59 ` [dpdk-dev] [PATCH v2 2/4] lib/cryptodev: added support to libcrypto PMD Michal Jastrzebski @ 2016-09-19 8:59 ` Michal Jastrzebski 2016-09-19 8:59 ` [dpdk-dev] [PATCH v2 4/4] examples/l2fwd-crypto: updated example " Michal Jastrzebski 2016-09-29 14:14 ` [dpdk-dev] [PATCH v3 0/3] new crypto software based device Slawomir Mrozowicz 4 siblings, 0 replies; 34+ messages in thread From: Michal Jastrzebski @ 2016-09-19 8:59 UTC (permalink / raw) To: dev Cc: pablo.de.lara.guarch, Slawomir Mrozowicz, Piotr Azarewicz, Marcin Kerlin, Fiona Trahe From: Slawomir Mrozowicz <slawomirx.mrozowicz@intel.com> This patch containes unit tests for libcrypto PMD. User can use app/test application to check how to use this pmd and to verify crypto processing. Test name is cryptodev_libcrypto_autotest. For performance test cryptodev_libcrypto_perftest can be used. Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com> Signed-off-by: Marcin Kerlin <marcinx.kerlin@intel.com> Signed-off-by: Fiona Trahe <fiona.trahe@intel.com> --- v2 changes: - rename AES-named functions to blockcipher - replace different test cases with blockcipher functions pattern - add 3DES tests into QuickAssist PMD testsuite --- app/test/Makefile | 2 +- app/test/test_cryptodev.c | 690 +++++++++++++++- app/test/test_cryptodev.h | 1 + app/test/test_cryptodev_aes.c | 687 ---------------- app/test/test_cryptodev_aes.h | 1124 --------------------------- app/test/test_cryptodev_aes_test_vectors.h | 1095 ++++++++++++++++++++++++++ app/test/test_cryptodev_blockcipher.c | 531 +++++++++++++ app/test/test_cryptodev_blockcipher.h | 125 +++ app/test/test_cryptodev_des_test_vectors.h | 952 +++++++++++++++++++++++ app/test/test_cryptodev_hash_test_vectors.h | 491 ++++++++++++ app/test/test_cryptodev_perf.c | 684 +++++++++++++++- 11 files changed, 4531 insertions(+), 1851 deletions(-) delete mode 100644 app/test/test_cryptodev_aes.c delete mode 100644 app/test/test_cryptodev_aes.h create mode 100644 app/test/test_cryptodev_aes_test_vectors.h create mode 100644 app/test/test_cryptodev_blockcipher.c create mode 100644 app/test/test_cryptodev_blockcipher.h create mode 100644 app/test/test_cryptodev_des_test_vectors.h create mode 100644 app/test/test_cryptodev_hash_test_vectors.h diff --git a/app/test/Makefile b/app/test/Makefile index 611d77a..5be023a 100644 --- a/app/test/Makefile +++ b/app/test/Makefile @@ -193,7 +193,7 @@ endif SRCS-$(CONFIG_RTE_LIBRTE_PMD_RING) += test_pmd_ring.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_RING) += test_pmd_ring_perf.c -SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_aes.c +SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_blockcipher.c SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_perf.c SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev.c diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c index ee44ad6..ee71457 100644 --- a/app/test/test_cryptodev.c +++ b/app/test/test_cryptodev.c @@ -43,7 +43,10 @@ #include "test.h" #include "test_cryptodev.h" -#include "test_cryptodev_aes.h" +#include "test_cryptodev_blockcipher.h" +#include "test_cryptodev_aes_test_vectors.h" +#include "test_cryptodev_des_test_vectors.h" +#include "test_cryptodev_hash_test_vectors.h" #include "test_cryptodev_kasumi_test_vectors.h" #include "test_cryptodev_kasumi_hash_test_vectors.h" #include "test_cryptodev_snow3g_test_vectors.h" @@ -84,12 +87,16 @@ struct crypto_unittest_params { */ static int test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( - struct crypto_unittest_params *ut_params); + struct crypto_unittest_params *ut_params, uint8_t *cipher_key, + uint8_t *hmac_key); static int test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, struct crypto_unittest_params *ut_params, - struct crypto_testsuite_params *ts_param); + struct crypto_testsuite_params *ts_param, + const uint8_t *cipher, + const uint8_t *digest, + const uint8_t *iv); static struct rte_mbuf * setup_test_string(struct rte_mempool *mpool, @@ -197,6 +204,23 @@ testsuite_setup(void) } } + /* Create 2 LIBCRYPTO devices if required */ + if (gbl_cryptodev_type == RTE_CRYPTODEV_LIBCRYPTO_PMD) { + nb_devs = rte_cryptodev_count_devtype( + RTE_CRYPTODEV_LIBCRYPTO_PMD); + if (nb_devs < 2) { + for (i = nb_devs; i < 2; i++) { + ret = rte_eal_vdev_init( + RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), NULL); + + TEST_ASSERT(ret == 0, + "Failed to create instance %u of" + " pmd : %s", + i, RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD)); + } + } + } + /* Create 2 AESNI GCM devices if required */ if (gbl_cryptodev_type == RTE_CRYPTODEV_AESNI_GCM_PMD) { nb_devs = rte_cryptodev_count_devtype( @@ -822,6 +846,314 @@ static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA1_digest[] = { }; +/* Multisession Vector context Test */ +/*Begin Session 0 */ +static uint8_t ms_aes_cbc_key0[] = { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static uint8_t ms_aes_cbc_iv0[] = { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static const uint8_t ms_aes_cbc_cipher0[] = { + 0x3C, 0xE4, 0xEE, 0x42, 0xB6, 0x9B, 0xC3, 0x38, + 0x5F, 0xAD, 0x54, 0xDC, 0xA8, 0x32, 0x81, 0xDC, + 0x7A, 0x6F, 0x85, 0x58, 0x07, 0x35, 0xED, 0xEB, + 0xAD, 0x79, 0x79, 0x96, 0xD3, 0x0E, 0xA6, 0xD9, + 0xAA, 0x86, 0xA4, 0x8F, 0xB5, 0xD6, 0x6E, 0x6D, + 0x0C, 0x91, 0x2F, 0xC4, 0x67, 0x98, 0x0E, 0xC4, + 0x8D, 0x83, 0x68, 0x69, 0xC4, 0xD3, 0x94, 0x34, + 0xC4, 0x5D, 0x60, 0x55, 0x22, 0x87, 0x8F, 0x6F, + 0x17, 0x8E, 0x75, 0xE4, 0x02, 0xF5, 0x1B, 0x99, + 0xC8, 0x39, 0xA9, 0xAB, 0x23, 0x91, 0x12, 0xED, + 0x08, 0xE7, 0xD9, 0x25, 0x89, 0x24, 0x4F, 0x8D, + 0x68, 0xF3, 0x10, 0x39, 0x0A, 0xEE, 0x45, 0x24, + 0xDF, 0x7A, 0x9D, 0x00, 0x25, 0xE5, 0x35, 0x71, + 0x4E, 0x40, 0x59, 0x6F, 0x0A, 0x13, 0xB3, 0x72, + 0x1D, 0x98, 0x63, 0x94, 0x89, 0xA5, 0x39, 0x8E, + 0xD3, 0x9C, 0x8A, 0x7F, 0x71, 0x2F, 0xC7, 0xCD, + 0x81, 0x05, 0xDC, 0xC0, 0x8D, 0xCE, 0x6D, 0x18, + 0x30, 0xC4, 0x72, 0x51, 0xF0, 0x27, 0xC8, 0xF6, + 0x60, 0x5B, 0x7C, 0xB2, 0xE3, 0x49, 0x0C, 0x29, + 0xC6, 0x9F, 0x39, 0x57, 0x80, 0x55, 0x24, 0x2C, + 0x9B, 0x0F, 0x5A, 0xB3, 0x89, 0x55, 0x31, 0x96, + 0x0D, 0xCD, 0xF6, 0x51, 0x03, 0x2D, 0x89, 0x26, + 0x74, 0x44, 0xD6, 0xE8, 0xDC, 0xEA, 0x44, 0x55, + 0x64, 0x71, 0x9C, 0x9F, 0x5D, 0xBA, 0x39, 0x46, + 0xA8, 0x17, 0xA1, 0x9C, 0x52, 0x9D, 0xBC, 0x6B, + 0x4A, 0x98, 0xE6, 0xEA, 0x33, 0xEC, 0x58, 0xB4, + 0x43, 0xF0, 0x32, 0x45, 0xA4, 0xC1, 0x55, 0xB7, + 0x5D, 0xB5, 0x59, 0xB2, 0xE3, 0x96, 0xFF, 0xA5, + 0xAF, 0xE1, 0x86, 0x1B, 0x42, 0xE6, 0x3B, 0xA0, + 0x90, 0x4A, 0xE8, 0x8C, 0x21, 0x7F, 0x36, 0x1E, + 0x5B, 0x65, 0x25, 0xD1, 0xC1, 0x5A, 0xCA, 0x3D, + 0x10, 0xED, 0x2D, 0x79, 0xD0, 0x0F, 0x58, 0x44, + 0x69, 0x81, 0xF5, 0xD4, 0xC9, 0x0F, 0x90, 0x76, + 0x1F, 0x54, 0xD2, 0xD5, 0x97, 0xCE, 0x2C, 0xE3, + 0xEF, 0xF4, 0xB7, 0xC6, 0x3A, 0x87, 0x7F, 0x83, + 0x2A, 0xAF, 0xCD, 0x90, 0x12, 0xA7, 0x7D, 0x85, + 0x1D, 0x62, 0xD3, 0x85, 0x25, 0x05, 0xDB, 0x45, + 0x92, 0xA3, 0xF6, 0xA2, 0xA8, 0x41, 0xE4, 0x25, + 0x86, 0x87, 0x67, 0x24, 0xEC, 0x89, 0x23, 0x2A, + 0x9B, 0x20, 0x4D, 0x93, 0xEE, 0xE2, 0x2E, 0xC1, + 0x0B, 0x15, 0x33, 0xCF, 0x00, 0xD1, 0x1A, 0xDA, + 0x93, 0xFD, 0x28, 0x21, 0x5B, 0xCF, 0xD1, 0xF3, + 0x5A, 0x81, 0xBA, 0x82, 0x5E, 0x2F, 0x61, 0xB4, + 0x05, 0x71, 0xB5, 0xF4, 0x39, 0x3C, 0x1F, 0x60, + 0x00, 0x7A, 0xC4, 0xF8, 0x35, 0x20, 0x6C, 0x3A, + 0xCC, 0x03, 0x8F, 0x7B, 0xA2, 0xB6, 0x65, 0x8A, + 0xB6, 0x5F, 0xFD, 0x25, 0xD3, 0x5F, 0x92, 0xF9, + 0xAE, 0x17, 0x9B, 0x5E, 0x6E, 0x9A, 0xE4, 0x55, + 0x10, 0x25, 0x07, 0xA4, 0xAF, 0x21, 0x69, 0x13, + 0xD8, 0xFA, 0x31, 0xED, 0xF7, 0xA7, 0xA7, 0x3B, + 0xB8, 0x96, 0x8E, 0x10, 0x86, 0x74, 0xD8, 0xB1, + 0x34, 0x9E, 0x9B, 0x6A, 0x26, 0xA8, 0xD4, 0xD0, + 0xB5, 0xF6, 0xDE, 0xE7, 0xCA, 0x06, 0xDC, 0xA3, + 0x6F, 0xEE, 0x6B, 0x1E, 0xB5, 0x30, 0x99, 0x23, + 0xF9, 0x76, 0xF0, 0xA0, 0xCF, 0x3B, 0x94, 0x7B, + 0x19, 0x8D, 0xA5, 0x0C, 0x18, 0xA6, 0x1D, 0x07, + 0x89, 0xBE, 0x5B, 0x61, 0xE5, 0xF1, 0x42, 0xDB, + 0xD4, 0x2E, 0x02, 0x1F, 0xCE, 0xEF, 0x92, 0xB1, + 0x1B, 0x56, 0x50, 0xF2, 0x16, 0xE5, 0xE7, 0x4F, + 0xFD, 0xBB, 0x3E, 0xD2, 0xFC, 0x3C, 0xC6, 0x0F, + 0xF9, 0x12, 0x4E, 0xCB, 0x1E, 0x0C, 0x15, 0x84, + 0x2A, 0x14, 0x8A, 0x02, 0xE4, 0x7E, 0x95, 0x5B, + 0x86, 0xDB, 0x9B, 0x62, 0x5B, 0x19, 0xD2, 0x17, + 0xFA, 0x13, 0xBB, 0x6B, 0x3F, 0x45, 0x9F, 0xBF +}; + + +static uint8_t ms_hmac_key0[] = { + 0xFF, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 +}; + +static const uint8_t ms_hmac_digest0[] = { + 0x43, 0x52, 0xED, 0x34, 0xAB, 0x36, 0xB2, 0x51, + 0xFB, 0xA3, 0xA6, 0x7C, 0x38, 0xFC, 0x42, 0x8F, + 0x57, 0x64, 0xAB, 0x81, 0xA7, 0x89, 0xB7, 0x6C, + 0xA0, 0xDC, 0xB9, 0x4D, 0xC4, 0x30, 0xF9, 0xD4, + 0x10, 0x82, 0x55, 0xD0, 0xAB, 0x32, 0xFB, 0x56, + 0x0D, 0xE4, 0x68, 0x3D, 0x76, 0xD0, 0x7B, 0xE4, + 0xA6, 0x2C, 0x34, 0x9E, 0x8C, 0x41, 0xF8, 0x23, + 0x28, 0x1B, 0x3A, 0x90, 0x26, 0x34, 0x47, 0x90 + }; + +/* End Session 0 */ +/* Begin session 1 */ + +static uint8_t ms_aes_cbc_key1[] = { + 0xf1, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static uint8_t ms_aes_cbc_iv1[] = { + 0xf1, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static const uint8_t ms_aes_cbc_cipher1[] = { + 0x5A, 0x7A, 0x67, 0x5D, 0xB8, 0xE1, 0xDC, 0x71, + 0x39, 0xA8, 0x74, 0x93, 0x9C, 0x4C, 0xFE, 0x23, + 0x61, 0xCD, 0xA4, 0xB3, 0xD9, 0xCE, 0x99, 0x09, + 0x2A, 0x23, 0xF3, 0x29, 0xBF, 0x4C, 0xB4, 0x6A, + 0x1B, 0x6B, 0x73, 0x4D, 0x48, 0x0C, 0xCF, 0x6C, + 0x5E, 0x34, 0x9E, 0x7F, 0xBC, 0x8F, 0xCC, 0x8F, + 0x75, 0x1D, 0x3D, 0x77, 0x10, 0x76, 0xC8, 0xB9, + 0x99, 0x6F, 0xD6, 0x56, 0x75, 0xA9, 0xB2, 0x66, + 0xC2, 0x24, 0x2B, 0x9C, 0xFE, 0x40, 0x8E, 0x43, + 0x20, 0x97, 0x1B, 0xFA, 0xD0, 0xCF, 0x04, 0xAB, + 0xBB, 0xF6, 0x5D, 0xF5, 0xA0, 0x19, 0x7C, 0x23, + 0x5D, 0x80, 0x8C, 0x49, 0xF6, 0x76, 0x88, 0x29, + 0x27, 0x4C, 0x59, 0x2B, 0x43, 0xA6, 0xB2, 0x26, + 0x27, 0x78, 0xBE, 0x1B, 0xE1, 0x4F, 0x5A, 0x1F, + 0xFC, 0x68, 0x08, 0xE7, 0xC4, 0xD1, 0x34, 0x68, + 0xB7, 0x13, 0x14, 0x41, 0x62, 0x6B, 0x1F, 0x77, + 0x0C, 0x68, 0x1D, 0x0D, 0xED, 0x89, 0xAA, 0xD8, + 0x97, 0x02, 0xBA, 0x5E, 0xD4, 0x84, 0x25, 0x97, + 0x03, 0xA5, 0xA6, 0x13, 0x66, 0x02, 0xF4, 0xC3, + 0xF3, 0xD3, 0xCC, 0x95, 0xC3, 0x87, 0x46, 0x90, + 0x1F, 0x6E, 0x14, 0xA8, 0x00, 0xF2, 0x6F, 0xD5, + 0xA1, 0xAD, 0xD5, 0x40, 0xA2, 0x0F, 0x32, 0x7E, + 0x99, 0xA3, 0xF5, 0x53, 0xC3, 0x26, 0xA1, 0x45, + 0x01, 0x88, 0x57, 0x84, 0x3E, 0x7B, 0x4E, 0x0B, + 0x3C, 0xB5, 0x3E, 0x9E, 0xE9, 0x78, 0x77, 0xC5, + 0xC0, 0x89, 0xA8, 0xF8, 0xF1, 0xA5, 0x2D, 0x5D, + 0xF9, 0xC6, 0xFB, 0xCB, 0x05, 0x23, 0xBD, 0x6E, + 0x5E, 0x14, 0xC6, 0x57, 0x73, 0xCF, 0x98, 0xBD, + 0x10, 0x8B, 0x18, 0xA6, 0x01, 0x5B, 0x13, 0xAE, + 0x8E, 0xDE, 0x1F, 0xB5, 0xB7, 0x40, 0x6C, 0xC1, + 0x1E, 0xA1, 0x19, 0x20, 0x9E, 0x95, 0xE0, 0x2F, + 0x1C, 0xF5, 0xD9, 0xD0, 0x2B, 0x1E, 0x82, 0x25, + 0x62, 0xB4, 0xEB, 0xA1, 0x1F, 0xCE, 0x44, 0xA1, + 0xCB, 0x92, 0x01, 0x6B, 0xE4, 0x26, 0x23, 0xE3, + 0xC5, 0x67, 0x35, 0x55, 0xDA, 0xE5, 0x27, 0xEE, + 0x8D, 0x12, 0x84, 0xB7, 0xBA, 0xA7, 0x1C, 0xD6, + 0x32, 0x3F, 0x67, 0xED, 0xFB, 0x5B, 0x8B, 0x52, + 0x46, 0x8C, 0xF9, 0x69, 0xCD, 0xAE, 0x79, 0xAA, + 0x37, 0x78, 0x49, 0xEB, 0xC6, 0x8E, 0x76, 0x63, + 0x84, 0xFF, 0x9D, 0x22, 0x99, 0x51, 0xB7, 0x5E, + 0x83, 0x4C, 0x8B, 0xDF, 0x5A, 0x07, 0xCC, 0xBA, + 0x42, 0xA5, 0x98, 0xB6, 0x47, 0x0E, 0x66, 0xEB, + 0x23, 0x0E, 0xBA, 0x44, 0xA8, 0xAA, 0x20, 0x71, + 0x79, 0x9C, 0x77, 0x5F, 0xF5, 0xFE, 0xEC, 0xEF, + 0xC6, 0x64, 0x3D, 0x84, 0xD0, 0x2B, 0xA7, 0x0A, + 0xC3, 0x72, 0x5B, 0x9C, 0xFA, 0xA8, 0x87, 0x95, + 0x94, 0x11, 0x38, 0xA7, 0x1E, 0x58, 0xE3, 0x73, + 0xC6, 0xC9, 0xD1, 0x7B, 0x92, 0xDB, 0x0F, 0x49, + 0x74, 0xC2, 0xA2, 0x0E, 0x35, 0x57, 0xAC, 0xDB, + 0x9A, 0x1C, 0xCF, 0x5A, 0x32, 0x3E, 0x26, 0x9B, + 0xEC, 0xB3, 0xEF, 0x9C, 0xFE, 0xBE, 0x52, 0xAC, + 0xB1, 0x29, 0xDD, 0xFD, 0x07, 0xE2, 0xEE, 0xED, + 0xE4, 0x46, 0x37, 0xFE, 0xD1, 0xDC, 0xCD, 0x02, + 0xF9, 0x31, 0xB0, 0xFB, 0x36, 0xB7, 0x34, 0xA4, + 0x76, 0xE8, 0x57, 0xBF, 0x99, 0x92, 0xC7, 0xAF, + 0x98, 0x10, 0xE2, 0x70, 0xCA, 0xC9, 0x2B, 0x82, + 0x06, 0x96, 0x88, 0x0D, 0xB3, 0xAC, 0x9E, 0x6D, + 0x43, 0xBC, 0x5B, 0x31, 0xCF, 0x65, 0x8D, 0xA6, + 0xC7, 0xFE, 0x73, 0xE1, 0x54, 0xF7, 0x10, 0xF9, + 0x86, 0xF7, 0xDF, 0xA1, 0xA1, 0xD8, 0xAE, 0x35, + 0xB3, 0x90, 0xDC, 0x6F, 0x43, 0x7A, 0x8B, 0xE0, + 0xFE, 0x8F, 0x33, 0x4D, 0x29, 0x6C, 0x45, 0x53, + 0x73, 0xDD, 0x21, 0x0B, 0x85, 0x30, 0xB5, 0xA5, + 0xF3, 0x5D, 0xEC, 0x79, 0x61, 0x9D, 0x9E, 0xB3 + +}; + +static uint8_t ms_hmac_key1[] = { + 0xFE, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 +}; + +static const uint8_t ms_hmac_digest1[] = { + 0xCE, 0x6E, 0x5F, 0x77, 0x96, 0x9A, 0xB1, 0x69, + 0x2D, 0x5E, 0xF3, 0x2F, 0x32, 0x10, 0xCB, 0x50, + 0x0E, 0x09, 0x56, 0x25, 0x07, 0x34, 0xC9, 0x20, + 0xEC, 0x13, 0x43, 0x23, 0x5C, 0x08, 0x8B, 0xCD, + 0xDC, 0x86, 0x8C, 0xEE, 0x0A, 0x95, 0x2E, 0xB9, + 0x8C, 0x7B, 0x02, 0x7A, 0xD4, 0xE1, 0x49, 0xB4, + 0x45, 0xB5, 0x52, 0x37, 0xC6, 0xFF, 0xFE, 0xAA, + 0x0A, 0x87, 0xB8, 0x51, 0xF9, 0x2A, 0x01, 0x8F +}; +/* End Session 1 */ +/* Begin Session 2 */ +static uint8_t ms_aes_cbc_key2[] = { + 0xff, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static uint8_t ms_aes_cbc_iv2[] = { + 0xff, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static const uint8_t ms_aes_cbc_cipher2[] = { + 0xBB, 0x3C, 0x68, 0x25, 0xFD, 0xB6, 0xA2, 0x91, + 0x20, 0x56, 0xF6, 0x30, 0x35, 0xFC, 0x9E, 0x97, + 0xF2, 0x90, 0xFC, 0x7E, 0x3E, 0x0A, 0x75, 0xC8, + 0x4C, 0xF2, 0x2D, 0xAC, 0xD3, 0x93, 0xF0, 0xC5, + 0x14, 0x88, 0x8A, 0x23, 0xC2, 0x59, 0x9A, 0x98, + 0x4B, 0xD5, 0x2C, 0xDA, 0x43, 0xA9, 0x34, 0x69, + 0x7C, 0x6D, 0xDB, 0xDC, 0xCB, 0xC0, 0xA0, 0x09, + 0xA7, 0x86, 0x16, 0x4B, 0xBF, 0xA8, 0xB6, 0xCF, + 0x7F, 0x74, 0x1F, 0x22, 0xF0, 0xF6, 0xBB, 0x44, + 0x8B, 0x4C, 0x9E, 0x23, 0xF8, 0x9F, 0xFC, 0x5B, + 0x9E, 0x9C, 0x2A, 0x79, 0x30, 0x8F, 0xBF, 0xA9, + 0x68, 0xA1, 0x20, 0x71, 0x7C, 0x77, 0x22, 0x34, + 0x07, 0xCD, 0xC6, 0xF6, 0x50, 0x0A, 0x08, 0x99, + 0x17, 0x98, 0xE3, 0x93, 0x8A, 0xB0, 0xEE, 0xDF, + 0xC2, 0xBA, 0x3B, 0x44, 0x73, 0xDF, 0xDD, 0xDC, + 0x14, 0x4D, 0x3B, 0xBB, 0x5E, 0x58, 0xC1, 0x26, + 0xA7, 0xAE, 0x47, 0xF3, 0x24, 0x6D, 0x4F, 0xD3, + 0x6E, 0x3E, 0x33, 0xE6, 0x7F, 0xCA, 0x50, 0xAF, + 0x5D, 0x3D, 0xA0, 0xDD, 0xC9, 0xF3, 0x30, 0xD3, + 0x6E, 0x8B, 0x2E, 0x12, 0x24, 0x34, 0xF0, 0xD3, + 0xC7, 0x8D, 0x23, 0x29, 0xAA, 0x05, 0xE1, 0xFA, + 0x2E, 0xF6, 0x8D, 0x37, 0x86, 0xC0, 0x6D, 0x13, + 0x2D, 0x98, 0xF3, 0x52, 0x39, 0x22, 0xCE, 0x38, + 0xC2, 0x1A, 0x72, 0xED, 0xFB, 0xCC, 0xE4, 0x71, + 0x5A, 0x0C, 0x0D, 0x09, 0xF8, 0xE8, 0x1B, 0xBC, + 0x53, 0xC8, 0xD8, 0x8F, 0xE5, 0x98, 0x5A, 0xB1, + 0x06, 0xA6, 0x5B, 0xE6, 0xA2, 0x88, 0x21, 0x9E, + 0x36, 0xC0, 0x34, 0xF9, 0xFB, 0x3B, 0x0A, 0x22, + 0x00, 0x00, 0x39, 0x48, 0x8D, 0x23, 0x74, 0x62, + 0x72, 0x91, 0xE6, 0x36, 0xAA, 0x77, 0x9C, 0x72, + 0x9D, 0xA8, 0xC3, 0xA9, 0xD5, 0x44, 0x72, 0xA6, + 0xB9, 0x28, 0x8F, 0x64, 0x4C, 0x8A, 0x64, 0xE6, + 0x4E, 0xFA, 0xEF, 0x87, 0xDE, 0x7B, 0x22, 0x44, + 0xB0, 0xDF, 0x2E, 0x5F, 0x0B, 0xA5, 0xF2, 0x24, + 0x07, 0x5C, 0x2D, 0x39, 0xB7, 0x3D, 0x8A, 0xE5, + 0x0E, 0x9D, 0x4E, 0x50, 0xED, 0x03, 0x99, 0x8E, + 0xF0, 0x06, 0x55, 0x4E, 0xA2, 0x24, 0xE7, 0x17, + 0x46, 0xDF, 0x6C, 0xCD, 0xC6, 0x44, 0xE8, 0xF9, + 0xB9, 0x1B, 0x36, 0xF6, 0x7F, 0x10, 0xA4, 0x7D, + 0x90, 0xBD, 0xE4, 0xAA, 0xD6, 0x9E, 0x18, 0x9D, + 0x22, 0x35, 0xD6, 0x55, 0x54, 0xAA, 0xF7, 0x22, + 0xA3, 0x3E, 0xEF, 0xC8, 0xA2, 0x34, 0x8D, 0xA9, + 0x37, 0x63, 0xA6, 0xC3, 0x57, 0xCB, 0x0C, 0x49, + 0x7D, 0x02, 0xBE, 0xAA, 0x13, 0x75, 0xB7, 0x4E, + 0x52, 0x62, 0xA5, 0xC2, 0x33, 0xC7, 0x6C, 0x1B, + 0xF6, 0x34, 0xF6, 0x09, 0xA5, 0x0C, 0xC7, 0xA2, + 0x61, 0x48, 0x62, 0x7D, 0x17, 0x15, 0xE3, 0x95, + 0xC8, 0x63, 0xD2, 0xA4, 0x43, 0xA9, 0x49, 0x07, + 0xB2, 0x3B, 0x2B, 0x62, 0x7D, 0xCB, 0x51, 0xB3, + 0x25, 0x33, 0x47, 0x0E, 0x14, 0x67, 0xDC, 0x6A, + 0x9B, 0x51, 0xAC, 0x9D, 0x8F, 0xA2, 0x2B, 0x57, + 0x8C, 0x5C, 0x5F, 0x76, 0x23, 0x92, 0x0F, 0x84, + 0x46, 0x0E, 0x40, 0x85, 0x38, 0x60, 0xFA, 0x61, + 0x20, 0xC5, 0xE3, 0xF1, 0x70, 0xAC, 0x1B, 0xBF, + 0xC4, 0x2B, 0xC5, 0x67, 0xD1, 0x43, 0xC5, 0x17, + 0x74, 0x71, 0x69, 0x6F, 0x82, 0x89, 0x19, 0x8A, + 0x70, 0x43, 0x92, 0x01, 0xC4, 0x63, 0x7E, 0xB1, + 0x59, 0x4E, 0xCD, 0xEA, 0x93, 0xA4, 0x52, 0x53, + 0x9B, 0x61, 0x5B, 0xD2, 0x3E, 0x19, 0x39, 0xB7, + 0x32, 0xEA, 0x8E, 0xF8, 0x1D, 0x76, 0x5C, 0xB2, + 0x73, 0x2D, 0x91, 0xC0, 0x18, 0xED, 0x25, 0x2A, + 0x53, 0x64, 0xF0, 0x92, 0x31, 0x55, 0x21, 0xA8, + 0x24, 0xA9, 0xD1, 0x02, 0xF6, 0x6C, 0x2B, 0x70, + 0xA9, 0x59, 0xC1, 0xD6, 0xC3, 0x57, 0x5B, 0x92 +}; + +static uint8_t ms_hmac_key2[] = { + 0xFC, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 +}; + +static const uint8_t ms_hmac_digest2[] = { + 0xA5, 0x0F, 0x9C, 0xFB, 0x08, 0x62, 0x59, 0xFF, + 0x80, 0x2F, 0xEB, 0x4B, 0xE1, 0x46, 0x21, 0xD6, + 0x02, 0x98, 0xF2, 0x8E, 0xF4, 0xEC, 0xD4, 0x77, + 0x86, 0x4C, 0x31, 0x28, 0xC8, 0x25, 0x80, 0x27, + 0x3A, 0x72, 0x5D, 0x6A, 0x56, 0x8A, 0xD3, 0x82, + 0xB0, 0xEC, 0x31, 0x6D, 0x8B, 0x6B, 0xB4, 0x24, + 0xE7, 0x62, 0xC1, 0x52, 0xBC, 0x14, 0x1B, 0x8E, + 0xEC, 0x9A, 0xF1, 0x47, 0x80, 0xD2, 0xB0, 0x59 +}; + +/* End Session 2 */ + + static int test_AES_CBC_HMAC_SHA1_encrypt_digest(void) { @@ -952,17 +1284,24 @@ static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA512_digest[] = { static int test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( - struct crypto_unittest_params *ut_params); + struct crypto_unittest_params *ut_params, + uint8_t *cipher_key, + uint8_t *hmac_key); static int test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, struct crypto_unittest_params *ut_params, - struct crypto_testsuite_params *ts_params); + struct crypto_testsuite_params *ts_params, + const uint8_t *cipher, + const uint8_t *digest, + const uint8_t *iv); static int test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( - struct crypto_unittest_params *ut_params) + struct crypto_unittest_params *ut_params, + uint8_t *cipher_key, + uint8_t *hmac_key) { /* Setup Cipher Parameters */ @@ -971,7 +1310,7 @@ test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC; ut_params->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT; - ut_params->cipher_xform.cipher.key.data = aes_cbc_key; + ut_params->cipher_xform.cipher.key.data = cipher_key; ut_params->cipher_xform.cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC; /* Setup HMAC Parameters */ @@ -980,7 +1319,7 @@ test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SHA512_HMAC; - ut_params->auth_xform.auth.key.data = hmac_sha512_key; + ut_params->auth_xform.auth.key.data = hmac_key; ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA512; ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA512; @@ -991,12 +1330,15 @@ test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( static int test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, struct crypto_unittest_params *ut_params, - struct crypto_testsuite_params *ts_params) + struct crypto_testsuite_params *ts_params, + const uint8_t *cipher, + const uint8_t *digest, + const uint8_t *iv) { /* Generate test mbuf data and digest */ ut_params->ibuf = setup_test_string(ts_params->mbuf_pool, (const char *) - catch_22_quote_2_512_bytes_AES_CBC_ciphertext, + cipher, QUOTE_512_BYTES, 0); ut_params->digest = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, @@ -1004,7 +1346,7 @@ test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, TEST_ASSERT_NOT_NULL(ut_params->digest, "no room to append digest"); rte_memcpy(ut_params->digest, - catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA512_digest, + digest, DIGEST_BYTE_LENGTH_SHA512); /* Generate Crypto op data structure */ @@ -1034,7 +1376,7 @@ test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, ut_params->ibuf, 0); sym_op->cipher.iv.length = CIPHER_IV_LENGTH_AES_CBC; - rte_memcpy(sym_op->cipher.iv.data, aes_cbc_iv, + rte_memcpy(sym_op->cipher.iv.data, iv, CIPHER_IV_LENGTH_AES_CBC); sym_op->cipher.data.offset = CIPHER_IV_LENGTH_AES_CBC; @@ -1064,14 +1406,15 @@ test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, } static int -test_AES_mb_all(void) +test_AES_chain_mb_all(void) { struct crypto_testsuite_params *ts_params = &testsuite_params; int status; - status = test_AES_all_tests(ts_params->mbuf_pool, + status = test_blockcipher_all_tests(ts_params->mbuf_pool, ts_params->op_mpool, ts_params->valid_devs[0], - RTE_CRYPTODEV_AESNI_MB_PMD); + RTE_CRYPTODEV_AESNI_MB_PMD, + BLKCIPHER_AES_CHAIN_TYPE); TEST_ASSERT_EQUAL(status, 0, "Test failed"); @@ -1079,14 +1422,63 @@ test_AES_mb_all(void) } static int -test_AES_qat_all(void) +test_AES_chain_libcrypto_all(void) { struct crypto_testsuite_params *ts_params = &testsuite_params; int status; - status = test_AES_all_tests(ts_params->mbuf_pool, + status = test_blockcipher_all_tests(ts_params->mbuf_pool, ts_params->op_mpool, ts_params->valid_devs[0], - RTE_CRYPTODEV_QAT_SYM_PMD); + RTE_CRYPTODEV_LIBCRYPTO_PMD, + BLKCIPHER_AES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_cipheronly_libcrypto_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_LIBCRYPTO_PMD, + BLKCIPHER_AES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_chain_qat_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_QAT_SYM_PMD, + BLKCIPHER_AES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_authonly_libcrypto_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_LIBCRYPTO_PMD, + BLKCIPHER_AUTHONLY_TYPE); TEST_ASSERT_EQUAL(status, 0, "Test failed"); @@ -3160,6 +3552,69 @@ test_kasumi_cipher_auth_test_case_1(void) return test_kasumi_cipher_auth(&kasumi_test_case_6); } +static int +test_3DES_chain_qat_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_QAT_SYM_PMD, + BLKCIPHER_3DES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_cipheronly_qat_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_QAT_SYM_PMD, + BLKCIPHER_3DES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_chain_libcrypto_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_LIBCRYPTO_PMD, + BLKCIPHER_3DES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_cipheronly_libcrypto_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_LIBCRYPTO_PMD, + BLKCIPHER_3DES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} /* ***** AES-GCM Tests ***** */ @@ -3790,7 +4245,8 @@ test_multi_session(void) uint16_t i; - test_AES_CBC_HMAC_SHA512_decrypt_create_session_params(ut_params); + test_AES_CBC_HMAC_SHA512_decrypt_create_session_params(ut_params, + aes_cbc_key, hmac_sha512_key); rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info); @@ -3809,10 +4265,13 @@ test_multi_session(void) i); /* Attempt to send a request on each session */ - TEST_ASSERT_SUCCESS(test_AES_CBC_HMAC_SHA512_decrypt_perform( - sessions[i], ut_params, ts_params), - "Failed to perform decrypt on request " - "number %u.", i); + TEST_ASSERT_SUCCESS( + test_AES_CBC_HMAC_SHA512_decrypt_perform(sessions[i], ut_params, + ts_params, + catch_22_quote_2_512_bytes_AES_CBC_ciphertext, + catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA512_digest, + aes_cbc_iv), + "Failed to perform decrypt on request number %u.", i); /* free crypto operation structure */ if (ut_params->op) rte_crypto_op_free(ut_params->op); @@ -3849,6 +4308,113 @@ test_multi_session(void) return TEST_SUCCESS; } + +struct multi_session_params { + struct crypto_unittest_params ut_params; + uint8_t *cipher_key; + uint8_t *hmac_key; + const uint8_t *cipher; + const uint8_t *digest; + uint8_t *iv; +}; + +#define MB_SESSION_NUMBER 3 + +static int +test_multi_session_random_usage(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_cryptodev_info dev_info; + struct rte_cryptodev_sym_session **sessions; + uint32_t i, j; + struct multi_session_params ut_paramz[] = { + + { + .cipher_key = ms_aes_cbc_key0, + .hmac_key = ms_hmac_key0, + .cipher = ms_aes_cbc_cipher0, + .digest = ms_hmac_digest0, + .iv = ms_aes_cbc_iv0 + }, + { + .cipher_key = ms_aes_cbc_key1, + .hmac_key = ms_hmac_key1, + .cipher = ms_aes_cbc_cipher1, + .digest = ms_hmac_digest1, + .iv = ms_aes_cbc_iv1 + }, + { + .cipher_key = ms_aes_cbc_key2, + .hmac_key = ms_hmac_key2, + .cipher = ms_aes_cbc_cipher2, + .digest = ms_hmac_digest2, + .iv = ms_aes_cbc_iv2 + }, + + }; + + rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info); + + sessions = rte_malloc(NULL, + (sizeof(struct rte_cryptodev_sym_session *) + * dev_info.sym.max_nb_sessions) + 1, 0); + + for (i = 0; i < MB_SESSION_NUMBER; i++) { + rte_memcpy(&ut_paramz[i].ut_params, &testsuite_params, + sizeof(struct crypto_unittest_params)); + + test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( + &ut_paramz[i].ut_params, ut_paramz[i].cipher_key, + ut_paramz[i].hmac_key); + + /* Create multiple crypto sessions*/ + sessions[i] = rte_cryptodev_sym_session_create(ts_params->valid_devs[0], + &ut_paramz[i].ut_params.auth_xform); + + TEST_ASSERT_NOT_NULL(sessions[i], + "Session creation failed at session number %u", i); + + } + + srand(time(NULL)); + for (i = 0; i < 40000; i++) { + + j = rand() % MB_SESSION_NUMBER; + + TEST_ASSERT_SUCCESS( + test_AES_CBC_HMAC_SHA512_decrypt_perform(sessions[j], + &ut_paramz[j].ut_params, ts_params, ut_paramz[j].cipher, + ut_paramz[j].digest, ut_paramz[j].iv), + "Failed to perform decrypt on request number %u.", i); + + if (ut_paramz[j].ut_params.op) + rte_crypto_op_free(ut_paramz[j].ut_params.op); + + /* + * free mbuf - both obuf and ibuf are usually the same, + * so check if they point at the same address is necessary, + * to avoid freeing the mbuf twice. + */ + if (ut_paramz[j].ut_params.obuf) { + rte_pktmbuf_free(ut_paramz[j].ut_params.obuf); + if (ut_paramz[j].ut_params.ibuf == ut_paramz[j].ut_params.obuf) + ut_paramz[j].ut_params.ibuf = 0; + ut_paramz[j].ut_params.obuf = 0; + } + if (ut_paramz[j].ut_params.ibuf) { + rte_pktmbuf_free(ut_paramz[j].ut_params.ibuf); + ut_paramz[j].ut_params.ibuf = 0; + } + } + + for (i = 0; i < MB_SESSION_NUMBER; i++) + rte_cryptodev_sym_session_free(ts_params->valid_devs[0], sessions[i]); + + rte_free(sessions); + + return TEST_SUCCESS; +} + static int test_null_cipher_only_operation(void) { @@ -4470,7 +5036,9 @@ static struct unit_test_suite cryptodev_qat_testsuite = { TEST_CASE_ST(ut_setup, ut_teardown, test_multi_session), - TEST_CASE_ST(ut_setup, ut_teardown, test_AES_qat_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_qat_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_3DES_chain_qat_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_3DES_cipheronly_qat_all), TEST_CASE_ST(ut_setup, ut_teardown, test_stats), /** AES GCM Authenticated Encryption */ @@ -4608,7 +5176,70 @@ static struct unit_test_suite cryptodev_aesni_mb_testsuite = { .setup = testsuite_setup, .teardown = testsuite_teardown, .unit_test_cases = { - TEST_CASE_ST(ut_setup, ut_teardown, test_AES_mb_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_mb_all), + + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +static struct unit_test_suite cryptodev_libcrypto_testsuite = { + .suite_name = "Crypto Device LIBCRYPTO Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, test_multi_session), + TEST_CASE_ST(ut_setup, ut_teardown, test_multi_session_random_usage), + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_libcrypto_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_cipheronly_libcrypto_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_3DES_chain_libcrypto_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_3DES_cipheronly_libcrypto_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_authonly_libcrypto_all), + + /** AES GCM Authenticated Encryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_7), + + /** AES GCM Authenticated Decryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_7), + + /** AES GMAC Authentication */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_3), TEST_CASES_END() /**< NULL terminate unit test array */ } @@ -4827,6 +5458,14 @@ test_cryptodev_aesni_mb(void /*argv __rte_unused, int argc __rte_unused*/) } static int +test_cryptodev_libcrypto(void) +{ + gbl_cryptodev_type = RTE_CRYPTODEV_LIBCRYPTO_PMD; + + return unit_test_suite_runner(&cryptodev_libcrypto_testsuite); +} + +static int test_cryptodev_aesni_gcm(void) { gbl_cryptodev_type = RTE_CRYPTODEV_AESNI_GCM_PMD; @@ -4860,6 +5499,7 @@ test_cryptodev_sw_kasumi(void /*argv __rte_unused, int argc __rte_unused*/) REGISTER_TEST_COMMAND(cryptodev_qat_autotest, test_cryptodev_qat); REGISTER_TEST_COMMAND(cryptodev_aesni_mb_autotest, test_cryptodev_aesni_mb); +REGISTER_TEST_COMMAND(cryptodev_libcrypto_autotest, test_cryptodev_libcrypto); REGISTER_TEST_COMMAND(cryptodev_aesni_gcm_autotest, test_cryptodev_aesni_gcm); REGISTER_TEST_COMMAND(cryptodev_null_autotest, test_cryptodev_null); REGISTER_TEST_COMMAND(cryptodev_sw_snow3g_autotest, test_cryptodev_sw_snow3g); diff --git a/app/test/test_cryptodev.h b/app/test/test_cryptodev.h index 3c37c32..a9089aa 100644 --- a/app/test/test_cryptodev.h +++ b/app/test/test_cryptodev.h @@ -63,6 +63,7 @@ #define DIGEST_BYTE_LENGTH_SNOW3G_UIA2 (BYTE_LENGTH(32)) #define DIGEST_BYTE_LENGTH_KASUMI_F9 (BYTE_LENGTH(32)) #define AES_XCBC_MAC_KEY_SZ (16) +#define DIGEST_BYTE_LENGTH_AES_GCM (BYTE_LENGTH(128)) #define TRUNCATED_DIGEST_BYTE_LENGTH_SHA1 (12) #define TRUNCATED_DIGEST_BYTE_LENGTH_SHA224 (16) diff --git a/app/test/test_cryptodev_aes.c b/app/test/test_cryptodev_aes.c deleted file mode 100644 index e19c45b..0000000 --- a/app/test/test_cryptodev_aes.c +++ /dev/null @@ -1,687 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2015-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_common.h> -#include <rte_hexdump.h> -#include <rte_mbuf.h> -#include <rte_malloc.h> -#include <rte_memcpy.h> - -#include <rte_crypto.h> -#include <rte_cryptodev.h> -#include <rte_cryptodev_pmd.h> - -#include "test.h" -#include "test_cryptodev_aes.h" - -#ifndef AES_TEST_MSG_LEN -#define AES_TEST_MSG_LEN 256 -#endif - -#define AES_TEST_OP_ENCRYPT 0x01 -#define AES_TEST_OP_DECRYPT 0x02 -#define AES_TEST_OP_AUTH_GEN 0x04 -#define AES_TEST_OP_AUTH_VERIFY 0x08 - -#define AES_TEST_FEATURE_OOP 0x01 -#define AES_TEST_FEATURE_SESSIONLESS 0x02 -#define AES_TEST_FEATURE_STOPPER 0x04 /* stop upon failing */ - -#define AES_TEST_TARGET_PMD_MB 0x0001 /* Multi-buffer flag */ -#define AES_TEST_TARGET_PMD_QAT 0x0002 /* QAT flag */ - -#define AES_TEST_OP_CIPHER (AES_TEST_OP_ENCRYPT | \ - AES_TEST_OP_DECRYPT) - -#define AES_TEST_OP_AUTH (AES_TEST_OP_AUTH_GEN | \ - AES_TEST_OP_AUTH_VERIFY) - -#define AES_TEST_OP_ENC_AUTH_GEN (AES_TEST_OP_ENCRYPT | \ - AES_TEST_OP_AUTH_GEN) - -#define AES_TEST_OP_AUTH_VERIFY_DEC (AES_TEST_OP_DECRYPT | \ - AES_TEST_OP_AUTH_VERIFY) - -struct aes_test_case { - const char *test_descr; /* test description */ - const struct aes_test_data *test_data; - uint8_t op_mask; /* operation mask */ - uint8_t feature_mask; - uint32_t pmd_mask; -}; - -static const struct aes_test_case aes_test_cases[] = { - { - .test_descr = "AES-128-CTR HMAC-SHA1 Encryption Digest", - .test_data = &aes_test_data_1, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CTR HMAC-SHA1 Decryption Digest " - "Verify", - .test_data = &aes_test_data_1, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-192-CTR XCBC Encryption Digest", - .test_data = &aes_test_data_2, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-192-CTR XCBC Decryption Digest Verify", - .test_data = &aes_test_data_2, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-256-CTR HMAC-SHA1 Encryption Digest", - .test_data = &aes_test_data_3, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-256-CTR HMAC-SHA1 Decryption Digest " - "Verify", - .test_data = &aes_test_data_3, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest", - .test_data = &aes_test_data_4, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " - "Verify", - .test_data = &aes_test_data_4, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA256 Encryption Digest", - .test_data = &aes_test_data_5, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA256 Decryption Digest " - "Verify", - .test_data = &aes_test_data_5, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest", - .test_data = &aes_test_data_6, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest " - "Sessionless", - .test_data = &aes_test_data_6, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .feature_mask = AES_TEST_FEATURE_SESSIONLESS, - .pmd_mask = AES_TEST_TARGET_PMD_MB - }, - { - .test_descr = "AES-128-CBC HMAC-SHA512 Decryption Digest " - "Verify", - .test_data = &aes_test_data_6, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC XCBC Encryption Digest", - .test_data = &aes_test_data_7, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC XCBC Decryption Digest Verify", - .test_data = &aes_test_data_7, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest " - "OOP", - .test_data = &aes_test_data_4, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .feature_mask = AES_TEST_FEATURE_OOP, - .pmd_mask = AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " - "Verify OOP", - .test_data = &aes_test_data_4, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .feature_mask = AES_TEST_FEATURE_OOP, - .pmd_mask = AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA224 Encryption Digest", - .test_data = &aes_test_data_8, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA224 Decryption Digest " - "Verify", - .test_data = &aes_test_data_8, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA384 Encryption Digest", - .test_data = &aes_test_data_9, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA384 Decryption Digest " - "Verify", - .test_data = &aes_test_data_9, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, -}; - -static int -test_AES_one_case(const struct aes_test_case *t, - struct rte_mempool *mbuf_pool, - struct rte_mempool *op_mpool, - uint8_t dev_id, - enum rte_cryptodev_type cryptodev_type, - char *test_msg) -{ - struct rte_mbuf *ibuf = NULL; - struct rte_mbuf *obuf = NULL; - struct rte_mbuf *iobuf; - struct rte_crypto_sym_xform *cipher_xform = NULL; - struct rte_crypto_sym_xform *auth_xform = NULL; - struct rte_crypto_sym_xform *init_xform = NULL; - struct rte_crypto_sym_op *sym_op = NULL; - struct rte_crypto_op *op = NULL; - struct rte_cryptodev_sym_session *sess = NULL; - - int status = TEST_SUCCESS; - const struct aes_test_data *tdata = t->test_data; - uint8_t cipher_key[tdata->cipher_key.len]; - uint8_t auth_key[tdata->auth_key.len]; - uint32_t buf_len = tdata->ciphertext.len; - uint32_t digest_len = 0; - char *buf_p = NULL; - - if (tdata->cipher_key.len) - memcpy(cipher_key, tdata->cipher_key.data, - tdata->cipher_key.len); - if (tdata->auth_key.len) - memcpy(auth_key, tdata->auth_key.data, - tdata->auth_key.len); - - switch (cryptodev_type) { - case RTE_CRYPTODEV_QAT_SYM_PMD: - digest_len = tdata->digest.len; - break; - case RTE_CRYPTODEV_AESNI_MB_PMD: - digest_len = tdata->digest.truncated_len; - break; - default: - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Unsupported PMD type"); - status = TEST_FAILED; - goto error_exit; - } - - /* preparing data */ - ibuf = rte_pktmbuf_alloc(mbuf_pool); - if (!ibuf) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Allocation of rte_mbuf failed"); - status = TEST_FAILED; - goto error_exit; - } - - if (t->op_mask & AES_TEST_OP_CIPHER) - buf_len += tdata->iv.len; - if (t->op_mask & AES_TEST_OP_AUTH) - buf_len += digest_len; - - buf_p = rte_pktmbuf_append(ibuf, buf_len); - if (!buf_p) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "No room to append mbuf"); - status = TEST_FAILED; - goto error_exit; - } - - if (t->op_mask & AES_TEST_OP_CIPHER) { - rte_memcpy(buf_p, tdata->iv.data, tdata->iv.len); - buf_p += tdata->iv.len; - } - - /* only encryption requires plaintext.data input, - * decryption/(digest gen)/(digest verify) use ciphertext.data - * to be computed */ - if (t->op_mask & AES_TEST_OP_ENCRYPT) { - rte_memcpy(buf_p, tdata->plaintext.data, - tdata->plaintext.len); - buf_p += tdata->plaintext.len; - } else { - rte_memcpy(buf_p, tdata->ciphertext.data, - tdata->ciphertext.len); - buf_p += tdata->ciphertext.len; - } - - if (t->op_mask & AES_TEST_OP_AUTH_VERIFY) - rte_memcpy(buf_p, tdata->digest.data, digest_len); - else - memset(buf_p, 0, digest_len); - - if (t->feature_mask & AES_TEST_FEATURE_OOP) { - obuf = rte_pktmbuf_alloc(mbuf_pool); - if (!obuf) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, - "Allocation of rte_mbuf failed"); - status = TEST_FAILED; - goto error_exit; - } - - buf_p = rte_pktmbuf_append(obuf, buf_len); - if (!buf_p) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, - "No room to append mbuf"); - status = TEST_FAILED; - goto error_exit; - } - memset(buf_p, 0, buf_len); - } - - /* Generate Crypto op data structure */ - op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_SYMMETRIC); - if (!op) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Failed to allocate symmetric crypto " - "operation struct"); - status = TEST_FAILED; - goto error_exit; - } - - sym_op = op->sym; - - sym_op->m_src = ibuf; - - if (t->feature_mask & AES_TEST_FEATURE_OOP) { - sym_op->m_dst = obuf; - iobuf = obuf; - } else { - sym_op->m_dst = NULL; - iobuf = ibuf; - } - - /* sessionless op requires allocate xform using - * rte_crypto_op_sym_xforms_alloc(), otherwise rte_zmalloc() - * is used */ - if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) { - uint32_t n_xforms = 0; - - if (t->op_mask & AES_TEST_OP_CIPHER) - n_xforms++; - if (t->op_mask & AES_TEST_OP_AUTH) - n_xforms++; - - if (rte_crypto_op_sym_xforms_alloc(op, n_xforms) - == NULL) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, "Failed to " - "allocate space for crypto transforms"); - status = TEST_FAILED; - goto error_exit; - } - } else { - cipher_xform = rte_zmalloc(NULL, - sizeof(struct rte_crypto_sym_xform), 0); - - auth_xform = rte_zmalloc(NULL, - sizeof(struct rte_crypto_sym_xform), 0); - - if (!cipher_xform || !auth_xform) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, "Failed to " - "allocate memory for crypto transforms"); - status = TEST_FAILED; - goto error_exit; - } - } - - /* preparing xform, for sessioned op, init_xform is initialized - * here and later as param in rte_cryptodev_sym_session_create() - * call */ - if (t->op_mask == AES_TEST_OP_ENC_AUTH_GEN) { - if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) { - cipher_xform = op->sym->xform; - auth_xform = cipher_xform->next; - auth_xform->next = NULL; - } else { - cipher_xform->next = auth_xform; - auth_xform->next = NULL; - init_xform = cipher_xform; - } - } else if (t->op_mask == AES_TEST_OP_AUTH_VERIFY_DEC) { - if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) { - auth_xform = op->sym->xform; - cipher_xform = auth_xform->next; - cipher_xform->next = NULL; - } else { - auth_xform->next = cipher_xform; - cipher_xform->next = NULL; - init_xform = auth_xform; - } - } else if ((t->op_mask == AES_TEST_OP_ENCRYPT) || - (t->op_mask == AES_TEST_OP_DECRYPT)) { - if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) - cipher_xform = op->sym->xform; - else - init_xform = cipher_xform; - cipher_xform->next = NULL; - } else if ((t->op_mask == AES_TEST_OP_AUTH_GEN) || - (t->op_mask == AES_TEST_OP_AUTH_VERIFY)) { - if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) - auth_xform = op->sym->xform; - else - init_xform = auth_xform; - auth_xform->next = NULL; - } else { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Unrecognized operation"); - status = TEST_FAILED; - goto error_exit; - } - - /*configure xforms & sym_op cipher and auth data*/ - if (t->op_mask & AES_TEST_OP_CIPHER) { - cipher_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; - cipher_xform->cipher.algo = tdata->crypto_algo; - if (t->op_mask & AES_TEST_OP_ENCRYPT) - cipher_xform->cipher.op = - RTE_CRYPTO_CIPHER_OP_ENCRYPT; - else - cipher_xform->cipher.op = - RTE_CRYPTO_CIPHER_OP_DECRYPT; - cipher_xform->cipher.key.data = cipher_key; - cipher_xform->cipher.key.length = tdata->cipher_key.len; - - sym_op->cipher.data.offset = tdata->iv.len; - sym_op->cipher.data.length = tdata->ciphertext.len; - sym_op->cipher.iv.data = rte_pktmbuf_mtod(sym_op->m_src, - uint8_t *); - sym_op->cipher.iv.length = tdata->iv.len; - sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys( - sym_op->m_src); - } - - if (t->op_mask & AES_TEST_OP_AUTH) { - uint32_t auth_data_offset = 0; - uint32_t digest_offset = tdata->ciphertext.len; - - if (t->op_mask & AES_TEST_OP_CIPHER) { - digest_offset += tdata->iv.len; - auth_data_offset += tdata->iv.len; - } - - auth_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; - auth_xform->auth.algo = tdata->auth_algo; - auth_xform->auth.key.length = tdata->auth_key.len; - auth_xform->auth.key.data = auth_key; - auth_xform->auth.digest_length = digest_len; - - if (t->op_mask & AES_TEST_OP_AUTH_GEN) { - auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; - sym_op->auth.digest.data = rte_pktmbuf_mtod_offset - (iobuf, uint8_t *, digest_offset); - sym_op->auth.digest.phys_addr = - rte_pktmbuf_mtophys_offset(iobuf, - digest_offset); - } else { - auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; - sym_op->auth.digest.data = rte_pktmbuf_mtod_offset - (sym_op->m_src, uint8_t *, digest_offset); - sym_op->auth.digest.phys_addr = - rte_pktmbuf_mtophys_offset(sym_op->m_src, - digest_offset); - } - - sym_op->auth.data.offset = auth_data_offset; - sym_op->auth.data.length = tdata->ciphertext.len; - sym_op->auth.digest.length = digest_len; - } - - /* create session for sessioned op */ - if (!(t->feature_mask & AES_TEST_FEATURE_SESSIONLESS)) { - sess = rte_cryptodev_sym_session_create(dev_id, - init_xform); - if (!sess) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, - "Session creation failed"); - status = TEST_FAILED; - goto error_exit; - } - - /* attach symmetric crypto session to crypto operations */ - rte_crypto_op_attach_sym_session(op, sess); - } - - /* Process crypto operation */ - if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Error sending packet for encryption"); - status = TEST_FAILED; - goto error_exit; - } - - op = NULL; - - while (rte_cryptodev_dequeue_burst(dev_id, 0, &op, 1) == 0) - rte_pause(); - - if (!op) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Failed to process sym crypto op"); - status = TEST_FAILED; - goto error_exit; - } - - TEST_HEXDUMP(stdout, "m_src:", - rte_pktmbuf_mtod(sym_op->m_src, uint8_t *), buf_len); - if (t->feature_mask & AES_TEST_FEATURE_OOP) - TEST_HEXDUMP(stdout, "m_dst:", - rte_pktmbuf_mtod(sym_op->m_dst, uint8_t *), - buf_len); - - /* Verify results */ - if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) { - if (t->op_mask & AES_TEST_OP_AUTH_VERIFY) - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: Digest verification failed " - "(0x%X)", __LINE__, op->status); - else - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: Digest verification failed " - "(0x%X)", __LINE__, op->status); - status = TEST_FAILED; - goto error_exit; - } - - if (t->op_mask & AES_TEST_OP_CIPHER) { - uint8_t *crypto_res; - const uint8_t *compare_ref; - uint32_t compare_len; - - crypto_res = rte_pktmbuf_mtod_offset(iobuf, uint8_t *, - tdata->iv.len); - - if (t->op_mask & AES_TEST_OP_ENCRYPT) { - compare_ref = tdata->ciphertext.data; - compare_len = tdata->ciphertext.len; - } else { - compare_ref = tdata->plaintext.data; - compare_len = tdata->plaintext.len; - } - - if (memcmp(crypto_res, compare_ref, compare_len)) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, - "Crypto data not as expected"); - status = TEST_FAILED; - goto error_exit; - } - } - - if (t->op_mask & AES_TEST_OP_AUTH_GEN) { - uint8_t *auth_res; - - if (t->op_mask & AES_TEST_OP_CIPHER) - auth_res = rte_pktmbuf_mtod_offset(iobuf, - uint8_t *, - tdata->iv.len + tdata->ciphertext.len); - else - auth_res = rte_pktmbuf_mtod_offset(iobuf, - uint8_t *, tdata->ciphertext.len); - - if (memcmp(auth_res, tdata->digest.data, digest_len)) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, "Generated " - "digest data not as expected"); - status = TEST_FAILED; - goto error_exit; - } - } - - snprintf(test_msg, AES_TEST_MSG_LEN, "PASS"); - -error_exit: - if (!(t->feature_mask & AES_TEST_FEATURE_SESSIONLESS)) { - if (sess) - rte_cryptodev_sym_session_free(dev_id, sess); - if (cipher_xform) - rte_free(cipher_xform); - if (auth_xform) - rte_free(auth_xform); - } - - if (op) - rte_crypto_op_free(op); - - if (obuf) - rte_pktmbuf_free(obuf); - - if (ibuf) - rte_pktmbuf_free(ibuf); - - return status; -} - -int -test_AES_all_tests(struct rte_mempool *mbuf_pool, - struct rte_mempool *op_mpool, - uint8_t dev_id, - enum rte_cryptodev_type cryptodev_type) -{ - int status, overall_status = TEST_SUCCESS; - uint32_t i, test_index = 0; - char test_msg[AES_TEST_MSG_LEN + 1]; - uint32_t n_test_cases = sizeof(aes_test_cases) / - sizeof(aes_test_cases[0]); - uint32_t target_pmd_mask = 0; - - switch (cryptodev_type) { - case RTE_CRYPTODEV_AESNI_MB_PMD: - target_pmd_mask = AES_TEST_TARGET_PMD_MB; - break; - case RTE_CRYPTODEV_QAT_SYM_PMD: - target_pmd_mask = AES_TEST_TARGET_PMD_QAT; - break; - default: - TEST_ASSERT(-1, "Unrecognized cryptodev type"); - break; - } - - for (i = 0; i < n_test_cases; i++) { - const struct aes_test_case *tc = &aes_test_cases[i]; - - if (!(tc->pmd_mask & target_pmd_mask)) - continue; - - status = test_AES_one_case(tc, mbuf_pool, op_mpool, - dev_id, cryptodev_type, test_msg); - - printf(" %u) TestCase %s %s\n", test_index ++, - tc->test_descr, test_msg); - - if (status != TEST_SUCCESS) { - if (overall_status == TEST_SUCCESS) - overall_status = status; - - if (tc->feature_mask & AES_TEST_FEATURE_STOPPER) - break; - } - } - - return overall_status; -} diff --git a/app/test/test_cryptodev_aes.h b/app/test/test_cryptodev_aes.h deleted file mode 100644 index ef518e0..0000000 --- a/app/test/test_cryptodev_aes.h +++ /dev/null @@ -1,1124 +0,0 @@ -/*- - * 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 TEST_CRYPTODEV_AES_H_ -#define TEST_CRYPTODEV_AES_H_ - -struct aes_test_data { - enum rte_crypto_cipher_algorithm crypto_algo; - - struct { - uint8_t data[64]; - unsigned len; - } cipher_key; - - struct { - uint8_t data[64] __rte_aligned(16); - unsigned len; - } iv; - - struct { - uint8_t data[2048]; - unsigned len; - } plaintext; - - struct { - uint8_t data[2048]; - unsigned len; - } ciphertext; - - enum rte_crypto_auth_algorithm auth_algo; - - struct { - uint8_t data[128]; - unsigned len; - } auth_key; - - struct { - uint8_t data[128]; - unsigned len; /* for qat */ - unsigned truncated_len; /* for mb */ - } digest; -}; - -int -test_AES_all_tests(struct rte_mempool *mbuf_pool, - struct rte_mempool *op_mpool, - uint8_t dev_id, - enum rte_cryptodev_type cryptodev_type); - -/* test vectors */ -/* AES128-CTR-SHA1 test vector */ -static const struct aes_test_data aes_test_data_1 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, - .cipher_key = { - .data = { - 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, - 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C - }, - .len = 16 - }, - .iv = { - .data = { - 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, - 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF - }, - .len = 16 - }, - .plaintext = { - .data = { - 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, - 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, - 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, - 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, - 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, - 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, - 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, - 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 - }, - .len = 64 - }, - .ciphertext = { - .data = { - 0x87, 0x4D, 0x61, 0x91, 0xB6, 0x20, 0xE3, 0x26, - 0x1B, 0xEF, 0x68, 0x64, 0x99, 0x0D, 0xB6, 0xCE, - 0x98, 0x06, 0xF6, 0x6B, 0x79, 0x70, 0xFD, 0xFF, - 0x86, 0x17, 0x18, 0x7B, 0xB9, 0xFF, 0xFD, 0xFF, - 0x5A, 0xE4, 0xDF, 0x3E, 0xDB, 0xD5, 0xD3, 0x5E, - 0x5B, 0x4F, 0x09, 0x02, 0x0D, 0xB0, 0x3E, 0xAB, - 0x1E, 0x03, 0x1D, 0xDA, 0x2F, 0xBE, 0x03, 0xD1, - 0x79, 0x21, 0x70, 0xA0, 0xF3, 0x00, 0x9C, 0xEE - }, - .len = 64 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, - .auth_key = { - .data = { - 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, - 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, - 0xDE, 0xF4, 0xDE, 0xAD - }, - .len = 20 - }, - .digest = { - .data = { - 0x9B, 0x6F, 0x0C, 0x43, 0xF5, 0xC1, 0x3E, 0xB0, - 0xB1, 0x70, 0xB8, 0x2B, 0x33, 0x09, 0xD2, 0xB2, - 0x56, 0x20, 0xFB, 0xFE - }, - .len = 20, - .truncated_len = 12 - } -}; - -/** AES-192-CTR XCBC test vector */ -static const struct aes_test_data aes_test_data_2 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, - .cipher_key = { - .data = { - 0xCB, 0xC5, 0xED, 0x5B, 0xE7, 0x7C, 0xBD, 0x8C, - 0x50, 0xD9, 0x30, 0xF2, 0xB5, 0x6A, 0x0E, 0x5F, - 0xAA, 0xAE, 0xAD, 0xA2, 0x1F, 0x49, 0x52, 0xD4 - }, - .len = 24 - }, - .iv = { - .data = { - 0x3F, 0x69, 0xA8, 0xCD, 0xE8, 0xF0, 0xEF, 0x40, - 0xB8, 0x7A, 0x4B, 0xED, 0x2B, 0xAF, 0xBF, 0x57 - }, - .len = 16 - }, - .plaintext = { - .data = { - 0x01, 0x0F, 0x10, 0x1F, 0x20, 0x1C, 0x0E, 0xB8, - 0xFB, 0x5C, 0xCD, 0xCC, 0x1F, 0xF9, 0xAF, 0x0B, - 0x95, 0x03, 0x74, 0x99, 0x49, 0xE7, 0x62, 0x55, - 0xDA, 0xEA, 0x13, 0x20, 0x1D, 0xC6, 0xCC, 0xCC, - 0xD1, 0x70, 0x75, 0x47, 0x02, 0x2F, 0xFB, 0x86, - 0xBB, 0x6B, 0x23, 0xD2, 0xC9, 0x74, 0xD7, 0x7B, - 0x08, 0x03, 0x3B, 0x79, 0x39, 0xBB, 0x91, 0x29, - 0xDA, 0x14, 0x39, 0x8D, 0xFF, 0x81, 0x50, 0x96, - }, - .len = 64 - }, - .ciphertext = { - .data = { - 0x4A, 0x6C, 0xC8, 0xCC, 0x96, 0x2A, 0x13, 0x84, - 0x1C, 0x36, 0x88, 0xE9, 0xE5, 0x94, 0x70, 0xB2, - 0x14, 0x5B, 0x13, 0x80, 0xEA, 0xD8, 0x8D, 0x37, - 0xFD, 0x70, 0xA8, 0x83, 0xE8, 0x2B, 0x88, 0x1E, - 0xBA, 0x94, 0x3F, 0xF6, 0xB3, 0x1F, 0xDE, 0x34, - 0xF3, 0x5B, 0x80, 0xE9, 0xAB, 0xF5, 0x1C, 0x29, - 0xB6, 0xD9, 0x76, 0x2B, 0x06, 0xC6, 0x74, 0xF1, - 0x59, 0x5E, 0x9E, 0xA5, 0x7B, 0x2D, 0xD7, 0xF0 - }, - .len = 64 - }, - .auth_algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC, - .auth_key = { - .data = { - 0x87, 0x61, 0x54, 0x53, 0xC4, 0x6D, 0xDD, 0x51, - 0xE1, 0x9F, 0x86, 0x64, 0x39, 0x0A, 0xE6, 0x59 - }, - .len = 16 - }, - .digest = { - .data = { - 0xCA, 0x33, 0xB3, 0x3B, 0x16, 0x94, 0xAA, 0x55, - 0x36, 0x6B, 0x45, 0x46 - }, - .len = 12, - .truncated_len = 12 - } -}; - -/** AES-256-CTR SHA1 test vector */ -static const struct aes_test_data aes_test_data_3 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, - .cipher_key = { - .data = { - 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, - 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, - 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, - 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 - }, - .len = 32 - }, - .iv = { - .data = { - 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, - 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF - }, - .len = 16 - }, - .plaintext = { - .data = { - 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, - 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, - 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, - 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, - 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, - 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, - 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, - 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 - }, - .len = 64 - }, - .ciphertext = { - .data = { - 0x60, 0x1E, 0xC3, 0x13, 0x77, 0x57, 0x89, 0xA5, - 0xB7, 0xA7, 0xF5, 0x04, 0xBB, 0xF3, 0xD2, 0x28, - 0xF4, 0x43, 0xE3, 0xCA, 0x4D, 0x62, 0xB5, 0x9A, - 0xCA, 0x84, 0xE9, 0x90, 0xCA, 0xCA, 0xF5, 0xC5, - 0x2B, 0x09, 0x30, 0xDA, 0xA2, 0x3D, 0xE9, 0x4C, - 0xE8, 0x70, 0x17, 0xBA, 0x2D, 0x84, 0x98, 0x8D, - 0xDF, 0xC9, 0xC5, 0x8D, 0xB6, 0x7A, 0xAD, 0xA6, - 0x13, 0xC2, 0xDD, 0x08, 0x45, 0x79, 0x41, 0xA6 - }, - .len = 64 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, - .auth_key = { - .data = { - 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, - 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, - 0xDE, 0xF4, 0xDE, 0xAD - }, - .len = 20 - }, - .digest = { - .data = { - 0x3B, 0x1A, 0x9D, 0x82, 0x35, 0xD5, 0xDD, 0x64, - 0xCC, 0x1B, 0xA9, 0xC0, 0xEB, 0xE9, 0x42, 0x16, - 0xE7, 0x87, 0xA3, 0xEF - }, - .len = 20, - .truncated_len = 12 - } -}; - -/** AES-128-CBC SHA1 test vector */ -static const struct aes_test_data aes_test_data_4 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, - .auth_key = { - .data = { - 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, - 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, - 0xDE, 0xF4, 0xDE, 0xAD - }, - .len = 20 - }, - .digest = { - .data = { - 0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60, - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0x18, 0x8C, 0x1D, 0x32 - }, - .len = 20, - .truncated_len = 12 - } -}; - -/** AES-128-CBC SHA256 test vector */ -static const struct aes_test_data aes_test_data_5 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC, - .auth_key = { - .data = { - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60 - }, - .len = 32 - }, - .digest = { - .data = { - 0xC8, 0x57, 0x57, 0x31, 0x03, 0xE0, 0x03, 0x55, - 0x07, 0xC8, 0x9E, 0x7F, 0x48, 0x9A, 0x61, 0x9A, - 0x68, 0xEE, 0x03, 0x0E, 0x71, 0x75, 0xC7, 0xF4, - 0x2E, 0x45, 0x26, 0x32, 0x7C, 0x12, 0x15, 0x15 - }, - .len = 32, - .truncated_len = 16 - } -}; - -/** AES-128-CBC SHA512 test vector */ -static const struct aes_test_data aes_test_data_6 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA512_HMAC, - .auth_key = { - .data = { - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, - 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, - 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, - 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, - 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, - 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 - }, - .len = 64 - }, - .digest = { - .data = { - 0x5D, 0x54, 0x66, 0xC1, 0x6E, 0xBC, 0x04, 0xB8, - 0x46, 0xB8, 0x08, 0x6E, 0xE0, 0xF0, 0x43, 0x48, - 0x37, 0x96, 0x9C, 0xC6, 0x9C, 0xC2, 0x1E, 0xE8, - 0xF2, 0x0C, 0x0B, 0xEF, 0x86, 0xA2, 0xE3, 0x70, - 0x95, 0xC8, 0xB3, 0x06, 0x47, 0xA9, 0x90, 0xE8, - 0xA0, 0xC6, 0x72, 0x69, 0x05, 0xC0, 0x0D, 0x0E, - 0x21, 0x96, 0x65, 0x93, 0x74, 0x43, 0x2A, 0x1D, - 0x2E, 0xBF, 0xC2, 0xC2, 0xEE, 0xCC, 0x2F, 0x0A - }, - .len = 64, - .truncated_len = 32 - } -}; - -/** AES-128-CBC XCBC test vector */ -static const struct aes_test_data aes_test_data_7 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC, - .auth_key = { - .data = { - 0x87, 0x61, 0x54, 0x53, 0xC4, 0x6D, 0xDD, 0x51, - 0xE1, 0x9F, 0x86, 0x64, 0x39, 0x0A, 0xE6, 0x59 - }, - .len = 16 - }, - .digest = { - .data = { - 0xE0, 0xAC, 0x9A, 0xC4, 0x22, 0x64, 0x35, 0x89, - 0x77, 0x1D, 0x8B, 0x75 - }, - .len = 12, - .truncated_len = 12 - } -}; - -/** AES-128-CBC SHA224 test vector */ -static const struct aes_test_data aes_test_data_8 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA224_HMAC, - .auth_key = { - .data = { - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, - 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, - 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, - 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, - 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, - 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 - }, - .len = 64 - }, - .digest = { - .data = { - 0xA3, 0xCA, 0xC7, 0x1D, 0xA8, 0x61, 0x30, 0x98, - 0x3B, 0x8F, 0x01, 0x19, 0xAE, 0x8D, 0xBD, 0x34, - 0x40, 0x63, 0xA8, 0x2F, 0xDF, 0x85, 0x2B, 0x7F, - 0x63, 0x7C, 0xDD, 0xB7 - }, - .len = 28, - .truncated_len = 14 - } -}; - -/** AES-128-CBC SHA384 test vector */ -static const struct aes_test_data aes_test_data_9 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA384_HMAC, - .auth_key = { - .data = { - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, - 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, - 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, - 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, - 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, - 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60, - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, - 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, - 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, - 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, - 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, - 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 - }, - .len = 128 - }, - .digest = { - .data = { - 0x23, 0x60, 0xC8, 0xB1, 0x2D, 0x6C, 0x1E, 0x72, - 0x25, 0xAB, 0xF9, 0xC3, 0x9A, 0xA9, 0x4F, 0x8C, - 0x56, 0x38, 0x65, 0x0E, 0x74, 0xD5, 0x45, 0x9D, - 0xA3, 0xFD, 0x7E, 0x6D, 0x9E, 0x74, 0x88, 0x9D, - 0xA7, 0x12, 0x9D, 0xD8, 0x81, 0x3C, 0x86, 0x2F, - 0x4D, 0xF9, 0x6F, 0x0A, 0xB0, 0xC9, 0xEB, 0x0B - }, - .len = 48, - .truncated_len = 24 - } -}; - -#endif /* TEST_CRYPTODEV_AES_H_ */ diff --git a/app/test/test_cryptodev_aes_test_vectors.h b/app/test/test_cryptodev_aes_test_vectors.h new file mode 100644 index 0000000..ee46f9f --- /dev/null +++ b/app/test/test_cryptodev_aes_test_vectors.h @@ -0,0 +1,1095 @@ +/* + * 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 TEST_CRYPTODEV_AES_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_AES_TEST_VECTORS_H_ + +/* test vectors */ +static const uint8_t plaintext_aes128ctr[] = { + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, + 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, + 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, + 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, + 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, + 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, + 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 +}; + +static const uint8_t ciphertext64_aes128ctr[] = { + 0x87, 0x4D, 0x61, 0x91, 0xB6, 0x20, 0xE3, 0x26, + 0x1B, 0xEF, 0x68, 0x64, 0x99, 0x0D, 0xB6, 0xCE, + 0x98, 0x06, 0xF6, 0x6B, 0x79, 0x70, 0xFD, 0xFF, + 0x86, 0x17, 0x18, 0x7B, 0xB9, 0xFF, 0xFD, 0xFF, + 0x5A, 0xE4, 0xDF, 0x3E, 0xDB, 0xD5, 0xD3, 0x5E, + 0x5B, 0x4F, 0x09, 0x02, 0x0D, 0xB0, 0x3E, 0xAB, + 0x1E, 0x03, 0x1D, 0xDA, 0x2F, 0xBE, 0x03, 0xD1, + 0x79, 0x21, 0x70, 0xA0, 0xF3, 0x00, 0x9C, 0xEE +}; + +static const uint8_t plaintext_aes192ctr[] = { + 0x01, 0x0F, 0x10, 0x1F, 0x20, 0x1C, 0x0E, 0xB8, + 0xFB, 0x5C, 0xCD, 0xCC, 0x1F, 0xF9, 0xAF, 0x0B, + 0x95, 0x03, 0x74, 0x99, 0x49, 0xE7, 0x62, 0x55, + 0xDA, 0xEA, 0x13, 0x20, 0x1D, 0xC6, 0xCC, 0xCC, + 0xD1, 0x70, 0x75, 0x47, 0x02, 0x2F, 0xFB, 0x86, + 0xBB, 0x6B, 0x23, 0xD2, 0xC9, 0x74, 0xD7, 0x7B, + 0x08, 0x03, 0x3B, 0x79, 0x39, 0xBB, 0x91, 0x29, + 0xDA, 0x14, 0x39, 0x8D, 0xFF, 0x81, 0x50, 0x96, +}; + +static const uint8_t ciphertext64_aes192ctr[] = { + 0x4A, 0x6C, 0xC8, 0xCC, 0x96, 0x2A, 0x13, 0x84, + 0x1C, 0x36, 0x88, 0xE9, 0xE5, 0x94, 0x70, 0xB2, + 0x14, 0x5B, 0x13, 0x80, 0xEA, 0xD8, 0x8D, 0x37, + 0xFD, 0x70, 0xA8, 0x83, 0xE8, 0x2B, 0x88, 0x1E, + 0xBA, 0x94, 0x3F, 0xF6, 0xB3, 0x1F, 0xDE, 0x34, + 0xF3, 0x5B, 0x80, 0xE9, 0xAB, 0xF5, 0x1C, 0x29, + 0xB6, 0xD9, 0x76, 0x2B, 0x06, 0xC6, 0x74, 0xF1, + 0x59, 0x5E, 0x9E, 0xA5, 0x7B, 0x2D, 0xD7, 0xF0 +}; + +static const uint8_t plaintext_aes256ctr[] = { + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, + 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, + 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, + 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, + 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, + 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, + 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 +}; + +static const uint8_t ciphertext64_aes256ctr[] = { + 0x60, 0x1E, 0xC3, 0x13, 0x77, 0x57, 0x89, 0xA5, + 0xB7, 0xA7, 0xF5, 0x04, 0xBB, 0xF3, 0xD2, 0x28, + 0xF4, 0x43, 0xE3, 0xCA, 0x4D, 0x62, 0xB5, 0x9A, + 0xCA, 0x84, 0xE9, 0x90, 0xCA, 0xCA, 0xF5, 0xC5, + 0x2B, 0x09, 0x30, 0xDA, 0xA2, 0x3D, 0xE9, 0x4C, + 0xE8, 0x70, 0x17, 0xBA, 0x2D, 0x84, 0x98, 0x8D, + 0xDF, 0xC9, 0xC5, 0x8D, 0xB6, 0x7A, 0xAD, 0xA6, + 0x13, 0xC2, 0xDD, 0x08, 0x45, 0x79, 0x41, 0xA6 +}; + +static const uint8_t plaintext_aes_common[] = { + "What a lousy earth! He wondered how many people " + "were destitute that same night even in his own " + "prosperous country, how many homes were " + "shanties, how many husbands were drunk and " + "wives socked, and how many children were " + "bullied, abused, or abandoned. How many " + "families hungered for food they could not " + "afford to buy? How many hearts were broken? How " + "many suicides would take place that same night, " + "how many people would go insane? How many " + "cockroaches and landlords would triumph? How " + "many winners were losers, successes failures, " + "and rich men poor men? How many wise guys were " + "stupid? How many happy endings were unhappy " + "endings? How many honest men were liars, brave " + "men cowards, loyal men traitors, how many " + "sainted men were corrupt, how many people in " + "positions of trust had sold their souls to " + "bodyguards, how many had never had souls? How " + "many straight-and-narrow paths were crooked " + "paths? How many best families were worst " + "families and how many good people were bad " + "people? When you added them all up and then " + "subtracted, you might be left with only the " + "children, and perhaps with Albert Einstein and " + "an old violinist or sculptor somewhere." +}; + +static const uint8_t ciphertext512_aes128cbc[] = { + 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, + 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, + 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, + 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, + 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, + 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, + 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, + 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, + 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, + 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, + 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, + 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, + 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, + 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, + 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, + 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, + 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, + 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, + 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, + 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, + 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, + 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, + 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, + 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, + 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, + 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, + 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, + 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, + 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, + 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, + 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, + 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, + 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, + 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, + 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, + 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, + 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, + 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, + 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, + 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, + 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, + 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, + 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, + 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, + 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, + 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, + 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, + 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, + 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, + 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, + 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, + 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, + 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, + 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, + 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, + 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, + 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, + 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, + 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, + 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, + 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, + 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C +}; + +/* AES128-CTR-SHA1 test vector */ +static const struct blockcipher_test_data aes_test_data_1 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key = { + .data = { + 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C + }, + .len = 16 + }, + .iv = { + .data = { + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes128ctr, + .len = 64 + }, + .ciphertext = { + .data = ciphertext64_aes128ctr, + .len = 64 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x9B, 0x6F, 0x0C, 0x43, 0xF5, 0xC1, 0x3E, 0xB0, + 0xB1, 0x70, 0xB8, 0x2B, 0x33, 0x09, 0xD2, 0xB2, + 0x56, 0x20, 0xFB, 0xFE + }, + .len = 20, + .truncated_len = 12 + } +}; + +/** AES-192-CTR XCBC test vector */ +static const struct blockcipher_test_data aes_test_data_2 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key = { + .data = { + 0xCB, 0xC5, 0xED, 0x5B, 0xE7, 0x7C, 0xBD, 0x8C, + 0x50, 0xD9, 0x30, 0xF2, 0xB5, 0x6A, 0x0E, 0x5F, + 0xAA, 0xAE, 0xAD, 0xA2, 0x1F, 0x49, 0x52, 0xD4 + }, + .len = 24 + }, + .iv = { + .data = { + 0x3F, 0x69, 0xA8, 0xCD, 0xE8, 0xF0, 0xEF, 0x40, + 0xB8, 0x7A, 0x4B, 0xED, 0x2B, 0xAF, 0xBF, 0x57 + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes192ctr, + .len = 64 + }, + .ciphertext = { + .data = ciphertext64_aes192ctr, + .len = 64 + }, + .auth_algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC, + .auth_key = { + .data = { + 0x87, 0x61, 0x54, 0x53, 0xC4, 0x6D, 0xDD, 0x51, + 0xE1, 0x9F, 0x86, 0x64, 0x39, 0x0A, 0xE6, 0x59 + }, + .len = 16 + }, + .digest = { + .data = { + 0xCA, 0x33, 0xB3, 0x3B, 0x16, 0x94, 0xAA, 0x55, + 0x36, 0x6B, 0x45, 0x46 + }, + .len = 12, + .truncated_len = 12 + } +}; + +/** AES-256-CTR SHA1 test vector */ +static const struct blockcipher_test_data aes_test_data_3 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key = { + .data = { + 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, + 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, + 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, + 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 + }, + .len = 32 + }, + .iv = { + .data = { + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes256ctr, + .len = 64 + }, + .ciphertext = { + .data = ciphertext64_aes256ctr, + .len = 64 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x3B, 0x1A, 0x9D, 0x82, 0x35, 0xD5, 0xDD, 0x64, + 0xCC, 0x1B, 0xA9, 0xC0, 0xEB, 0xE9, 0x42, 0x16, + 0xE7, 0x87, 0xA3, 0xEF + }, + .len = 20, + .truncated_len = 12 + } +}; + +/** AES-128-CBC SHA1 test vector */ +static const struct blockcipher_test_data aes_test_data_4 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60, + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0x18, 0x8C, 0x1D, 0x32 + }, + .len = 20, + .truncated_len = 12 + } +}; + +/** AES-128-CBC SHA256 test vector */ +static const struct blockcipher_test_data aes_test_data_5 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC, + .auth_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, + 0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60 + }, + .len = 32 + }, + .digest = { + .data = { + 0xC8, 0x57, 0x57, 0x31, 0x03, 0xE0, 0x03, 0x55, + 0x07, 0xC8, 0x9E, 0x7F, 0x48, 0x9A, 0x61, 0x9A, + 0x68, 0xEE, 0x03, 0x0E, 0x71, 0x75, 0xC7, 0xF4, + 0x2E, 0x45, 0x26, 0x32, 0x7C, 0x12, 0x15, 0x15 + }, + .len = 32, + .truncated_len = 16 + } +}; + +/** AES-128-CBC SHA512 test vector */ +static const struct blockcipher_test_data aes_test_data_6 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA512_HMAC, + .auth_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 + }, + .len = 64 + }, + .digest = { + .data = { + 0x5D, 0x54, 0x66, 0xC1, 0x6E, 0xBC, 0x04, 0xB8, + 0x46, 0xB8, 0x08, 0x6E, 0xE0, 0xF0, 0x43, 0x48, + 0x37, 0x96, 0x9C, 0xC6, 0x9C, 0xC2, 0x1E, 0xE8, + 0xF2, 0x0C, 0x0B, 0xEF, 0x86, 0xA2, 0xE3, 0x70, + 0x95, 0xC8, 0xB3, 0x06, 0x47, 0xA9, 0x90, 0xE8, + 0xA0, 0xC6, 0x72, 0x69, 0x05, 0xC0, 0x0D, 0x0E, + 0x21, 0x96, 0x65, 0x93, 0x74, 0x43, 0x2A, 0x1D, + 0x2E, 0xBF, 0xC2, 0xC2, 0xEE, 0xCC, 0x2F, 0x0A + }, + .len = 64, + .truncated_len = 32 + } +}; + +/** AES-128-CBC XCBC test vector */ +static const struct blockcipher_test_data aes_test_data_7 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC, + .auth_key = { + .data = { + 0x87, 0x61, 0x54, 0x53, 0xC4, 0x6D, 0xDD, 0x51, + 0xE1, 0x9F, 0x86, 0x64, 0x39, 0x0A, 0xE6, 0x59 + }, + .len = 16 + }, + .digest = { + .data = { + 0xE0, 0xAC, 0x9A, 0xC4, 0x22, 0x64, 0x35, 0x89, + 0x77, 0x1D, 0x8B, 0x75 + }, + .len = 12, + .truncated_len = 12 + } +}; + +/** AES-128-CBC SHA224 test vector */ +static const struct blockcipher_test_data aes_test_data_8 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA224_HMAC, + .auth_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 + }, + .len = 64 + }, + .digest = { + .data = { + 0xA3, 0xCA, 0xC7, 0x1D, 0xA8, 0x61, 0x30, 0x98, + 0x3B, 0x8F, 0x01, 0x19, 0xAE, 0x8D, 0xBD, 0x34, + 0x40, 0x63, 0xA8, 0x2F, 0xDF, 0x85, 0x2B, 0x7F, + 0x63, 0x7C, 0xDD, 0xB7 + }, + .len = 28, + .truncated_len = 14 + } +}; + +/** AES-128-CBC SHA384 test vector */ +static const struct blockcipher_test_data aes_test_data_9 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA384_HMAC, + .auth_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60, + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 + }, + .len = 128 + }, + .digest = { + .data = { + 0x23, 0x60, 0xC8, 0xB1, 0x2D, 0x6C, 0x1E, 0x72, + 0x25, 0xAB, 0xF9, 0xC3, 0x9A, 0xA9, 0x4F, 0x8C, + 0x56, 0x38, 0x65, 0x0E, 0x74, 0xD5, 0x45, 0x9D, + 0xA3, 0xFD, 0x7E, 0x6D, 0x9E, 0x74, 0x88, 0x9D, + 0xA7, 0x12, 0x9D, 0xD8, 0x81, 0x3C, 0x86, 0x2F, + 0x4D, 0xF9, 0x6F, 0x0A, 0xB0, 0xC9, 0xEB, 0x0B + }, + .len = 48, + .truncated_len = 24 + } +}; + +static const uint8_t ciphertext512_aes192cbc[] = { + 0x45, 0xEE, 0x9A, 0xEA, 0x3C, 0x03, 0xFC, 0x4C, + 0x84, 0x36, 0xB0, 0xDA, 0xB0, 0xDC, 0xF3, 0x5B, + 0x75, 0xA7, 0xBE, 0x0E, 0xC0, 0x8D, 0x6C, 0xF8, + 0xC1, 0x0F, 0xD0, 0x35, 0x1D, 0x82, 0xAE, 0x7C, + 0x57, 0xC5, 0x7A, 0x55, 0x87, 0x1B, 0xD4, 0x03, + 0x0A, 0x64, 0xC9, 0xE0, 0xF4, 0xC7, 0x6F, 0x57, + 0x52, 0xC6, 0x73, 0xBA, 0x84, 0x0B, 0x5B, 0x89, + 0x21, 0xD2, 0x9B, 0x88, 0x68, 0xF5, 0xA9, 0x7F, + 0x3F, 0x49, 0xEB, 0xF4, 0xD4, 0x52, 0xD2, 0x64, + 0x80, 0xB2, 0x53, 0xDA, 0x19, 0xF6, 0x10, 0x24, + 0x23, 0x26, 0x7A, 0x7C, 0x07, 0x57, 0x4B, 0x0E, + 0x58, 0x49, 0x61, 0xD1, 0xDC, 0x9A, 0x32, 0x6B, + 0x0F, 0x43, 0x9E, 0x4D, 0xB4, 0x07, 0x4E, 0xB3, + 0x51, 0x74, 0xDE, 0x29, 0xBC, 0x98, 0xF9, 0xDF, + 0x78, 0x9A, 0x18, 0x9C, 0xD6, 0x7A, 0x55, 0x7C, + 0xE6, 0x1D, 0x5C, 0x1A, 0x99, 0xD2, 0xC3, 0x7B, + 0x9F, 0x96, 0x74, 0x2D, 0xE0, 0xEF, 0xD1, 0xE3, + 0x08, 0x9F, 0xAF, 0xE6, 0xED, 0xCA, 0xE1, 0xEA, + 0x23, 0x6F, 0x7C, 0x81, 0xA8, 0xC0, 0x5B, 0x8B, + 0x53, 0x90, 0x51, 0x2D, 0x0F, 0xF6, 0x7D, 0xA7, + 0x1C, 0xBD, 0x83, 0x84, 0x54, 0xA4, 0x15, 0xFB, + 0x3E, 0x25, 0xA7, 0x3A, 0x0A, 0x73, 0xD9, 0x88, + 0x6F, 0x80, 0x78, 0x95, 0x7F, 0x60, 0xAA, 0x86, + 0x8A, 0xFC, 0xDF, 0xC1, 0xCB, 0xDE, 0xBB, 0x25, + 0x52, 0x20, 0xC6, 0x79, 0xD4, 0x0F, 0x25, 0xE7, + 0xDB, 0xB2, 0x17, 0xA4, 0x6F, 0x3C, 0x6F, 0x91, + 0xF6, 0x44, 0x1E, 0xB6, 0x85, 0xBC, 0x7A, 0x14, + 0x10, 0x72, 0xBD, 0x16, 0x63, 0x39, 0x9E, 0x7B, + 0x84, 0x5B, 0x17, 0x61, 0xB1, 0x5D, 0x82, 0x0B, + 0x6D, 0x37, 0xD7, 0x79, 0xB8, 0x24, 0x91, 0x30, + 0x82, 0x91, 0x02, 0xB1, 0x18, 0x4B, 0xE0, 0xF4, + 0x13, 0x1B, 0xB2, 0x4C, 0xDA, 0xB8, 0x99, 0x96, + 0x83, 0x2F, 0xBE, 0x53, 0x8D, 0xDE, 0xFA, 0xAD, + 0xF6, 0x5C, 0xDB, 0xE5, 0x66, 0x26, 0x8F, 0x13, + 0x2B, 0x76, 0x47, 0x73, 0xDE, 0x1A, 0x74, 0xA6, + 0x30, 0xAF, 0x42, 0xA0, 0xE5, 0xD2, 0x8F, 0xC2, + 0xED, 0x3E, 0x9E, 0x29, 0x54, 0x3C, 0xDE, 0x9F, + 0x5D, 0x30, 0x2B, 0x63, 0xFB, 0xE3, 0xB1, 0x07, + 0xEE, 0x74, 0x4A, 0xAF, 0xB1, 0x20, 0x8D, 0xEC, + 0xE6, 0x78, 0x16, 0x8D, 0xA4, 0x6E, 0x34, 0x7D, + 0x47, 0xFB, 0x0B, 0xC1, 0x32, 0xD7, 0x0D, 0x6C, + 0x6F, 0x93, 0x9C, 0x5E, 0xEF, 0x1F, 0x9C, 0x45, + 0x80, 0x6B, 0x74, 0xA6, 0x81, 0xF2, 0xF6, 0xFA, + 0xAA, 0x9D, 0x4F, 0xCA, 0xB5, 0x90, 0x59, 0xB0, + 0x3B, 0xF2, 0xF0, 0x75, 0xFD, 0x8A, 0xD8, 0x97, + 0x65, 0x88, 0x56, 0x4C, 0x44, 0xDF, 0x73, 0xF7, + 0x56, 0x9C, 0x48, 0x7E, 0xB0, 0x1F, 0x1D, 0x7D, + 0x6A, 0x11, 0xF5, 0xC2, 0xF4, 0x17, 0xEF, 0x58, + 0xD8, 0x2A, 0xAF, 0x56, 0x2F, 0xCF, 0xEC, 0xA4, + 0x58, 0x8B, 0x60, 0xCE, 0xD4, 0x0F, 0x9C, 0x21, + 0xEC, 0x3E, 0x74, 0x7B, 0x81, 0x3D, 0x69, 0xC6, + 0x5E, 0x12, 0x83, 0xE9, 0xEF, 0x81, 0x58, 0x36, + 0x6A, 0x60, 0x0F, 0x54, 0x28, 0x11, 0xF9, 0x64, + 0x36, 0xAD, 0x79, 0xF5, 0x1C, 0x74, 0xD0, 0xC3, + 0x7B, 0x61, 0xE1, 0x92, 0xB0, 0x13, 0x91, 0x87, + 0x32, 0x1F, 0xF2, 0x5A, 0xDA, 0x25, 0x69, 0xEB, + 0xD7, 0x32, 0x7F, 0xF5, 0x23, 0x21, 0x54, 0x47, + 0x7B, 0x1B, 0x33, 0xB0, 0x3D, 0xF6, 0xE2, 0x7E, + 0x3E, 0xA2, 0x9E, 0xCA, 0x48, 0x0B, 0x4A, 0x29, + 0x81, 0xD4, 0x4E, 0xD5, 0x69, 0xFB, 0xCD, 0x37, + 0x8A, 0xC1, 0x5B, 0x50, 0xFF, 0xB5, 0x7D, 0x43, + 0x0F, 0xAE, 0xA6, 0xC2, 0xE5, 0x8F, 0x45, 0xB2, + 0x85, 0x99, 0x02, 0xA2, 0x9B, 0xBE, 0x90, 0x43, + 0x4F, 0x2F, 0x50, 0xE2, 0x77, 0x62, 0xD9, 0xCC +}; + +/** AES-192-CBC test vector */ +static const struct blockcipher_test_data aes_test_data_10 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes192cbc, + .len = 512 + } +}; + +static const uint8_t ciphertext512_aes256cbc[] = { + 0xF3, 0xDD, 0xF0, 0x0B, 0xFF, 0xA2, 0x6A, 0x04, + 0xBE, 0xDA, 0x52, 0xA6, 0xFE, 0x6B, 0xA6, 0xA7, + 0x48, 0x1D, 0x7D, 0x98, 0x65, 0xDB, 0xEF, 0x06, + 0x26, 0xB5, 0x8E, 0xEB, 0x05, 0x0E, 0x77, 0x98, + 0x17, 0x8E, 0xD0, 0xD4, 0x7B, 0x92, 0x8F, 0x5C, + 0xD0, 0x74, 0x5C, 0xA8, 0x4B, 0x54, 0xB6, 0x2F, + 0x83, 0x72, 0x2C, 0xFF, 0x72, 0xE9, 0xE4, 0x15, + 0x4C, 0x32, 0xAF, 0xC8, 0xC9, 0x89, 0x3C, 0x6E, + 0x31, 0xD5, 0xC0, 0x16, 0xC0, 0x31, 0x7D, 0x11, + 0xAB, 0xCB, 0xDE, 0xD2, 0xD6, 0xAA, 0x76, 0x5E, + 0xBA, 0xF6, 0xE2, 0x92, 0xCB, 0x86, 0x07, 0xFA, + 0xD4, 0x9E, 0x83, 0xED, 0xFD, 0xB8, 0x70, 0x54, + 0x6B, 0xBE, 0xEC, 0x72, 0xDD, 0x28, 0x5E, 0x95, + 0x78, 0xA5, 0x28, 0x43, 0x3D, 0x6D, 0xB1, 0xD9, + 0x69, 0x1F, 0xC9, 0x66, 0x0E, 0x32, 0x44, 0x08, + 0xD2, 0xAE, 0x2C, 0x43, 0xF2, 0xD0, 0x7D, 0x26, + 0x70, 0xE5, 0xA1, 0xCA, 0x37, 0xE9, 0x7D, 0xC7, + 0xA3, 0xFA, 0x81, 0x91, 0x64, 0xAA, 0x64, 0x91, + 0x9A, 0x95, 0x2D, 0xC9, 0xF9, 0xCE, 0xFE, 0x9F, + 0xC4, 0xD8, 0x81, 0xBE, 0x57, 0x84, 0xC5, 0x02, + 0xDB, 0x30, 0xC1, 0xD9, 0x0E, 0xA0, 0xA6, 0x00, + 0xD6, 0xF3, 0x52, 0x7E, 0x0D, 0x23, 0x6B, 0x2B, + 0x34, 0x99, 0x1F, 0x70, 0x27, 0x6D, 0x58, 0x84, + 0x93, 0x77, 0xB8, 0x3E, 0xF1, 0x71, 0x58, 0x42, + 0x8B, 0x2B, 0xC8, 0x6D, 0x05, 0x84, 0xFF, 0x4E, + 0x85, 0xEF, 0x4A, 0x9D, 0x91, 0x6A, 0xD5, 0xE1, + 0xAF, 0x01, 0xEB, 0x83, 0x8F, 0x23, 0x7C, 0x7F, + 0x12, 0x91, 0x05, 0xF0, 0x4E, 0xD9, 0x17, 0x62, + 0x75, 0xBB, 0xAC, 0x97, 0xEE, 0x3B, 0x4E, 0xC7, + 0xE5, 0x92, 0xF8, 0x9D, 0x4C, 0xF9, 0xEE, 0x55, + 0x18, 0xBB, 0xCC, 0xB4, 0xF2, 0x59, 0xB9, 0xFC, + 0x7A, 0x0F, 0x98, 0xD4, 0x8B, 0xFE, 0xF7, 0x83, + 0x46, 0xE2, 0x83, 0x33, 0x3E, 0x95, 0x8D, 0x17, + 0x1E, 0x85, 0xF8, 0x8C, 0x51, 0xB0, 0x6C, 0xB5, + 0x5E, 0x95, 0xBA, 0x4B, 0x69, 0x1B, 0x48, 0x69, + 0x0B, 0x8F, 0xA5, 0x18, 0x13, 0xB9, 0x77, 0xD1, + 0x80, 0x32, 0x32, 0x6D, 0x53, 0xA1, 0x95, 0x40, + 0x96, 0x8A, 0xCC, 0xA3, 0x69, 0xF8, 0x9F, 0xB5, + 0x8E, 0xD2, 0x68, 0x07, 0x4F, 0xA7, 0xEC, 0xF8, + 0x20, 0x21, 0x58, 0xF8, 0xD8, 0x9E, 0x5F, 0x40, + 0xBA, 0xB9, 0x76, 0x57, 0x3B, 0x17, 0xAD, 0xEE, + 0xCB, 0xDF, 0x07, 0xC1, 0xDF, 0x66, 0xA8, 0x0D, + 0xC2, 0xCE, 0x8F, 0x79, 0xC3, 0x32, 0xE0, 0x8C, + 0xFE, 0x5A, 0xF3, 0x55, 0x27, 0x73, 0x6F, 0xA1, + 0x54, 0xC6, 0xFC, 0x28, 0x9D, 0xBE, 0x97, 0xB9, + 0x54, 0x97, 0x72, 0x3A, 0x61, 0xAF, 0x6F, 0xDE, + 0xF8, 0x0E, 0xBB, 0x6B, 0x96, 0x84, 0xDD, 0x9B, + 0x62, 0xBA, 0x47, 0xB5, 0xC9, 0x3B, 0x4E, 0x8C, + 0x78, 0x2A, 0xCC, 0x0A, 0x69, 0x54, 0x25, 0x5E, + 0x8B, 0xAC, 0x56, 0xD9, 0xFE, 0x48, 0xBA, 0xCE, + 0xA9, 0xCE, 0xA6, 0x1D, 0xBF, 0x3E, 0x3C, 0x66, + 0x40, 0x71, 0x79, 0xAD, 0x5B, 0x26, 0xAD, 0xBE, + 0x58, 0x13, 0x64, 0x60, 0x7C, 0x05, 0xFC, 0xE3, + 0x51, 0x7A, 0xF2, 0xCC, 0x54, 0x16, 0x2C, 0xA4, + 0xCE, 0x5F, 0x59, 0x12, 0x77, 0xEB, 0xD9, 0x23, + 0xE3, 0x86, 0xFB, 0xD7, 0x48, 0x76, 0x9D, 0xE3, + 0x89, 0x87, 0x39, 0xFA, 0x7B, 0x21, 0x0B, 0x76, + 0xB2, 0xED, 0x1C, 0x27, 0x4B, 0xD5, 0x27, 0x05, + 0x8C, 0x7D, 0x58, 0x6C, 0xCA, 0xA5, 0x54, 0x9A, + 0x0F, 0xCB, 0xE9, 0x88, 0x31, 0xAD, 0x49, 0xEE, + 0x38, 0xFB, 0xC9, 0xFB, 0xB4, 0x7A, 0x00, 0x58, + 0x20, 0x32, 0xD3, 0x53, 0x5A, 0xDD, 0x74, 0x95, + 0x60, 0x59, 0x09, 0xAE, 0x7E, 0xEC, 0x74, 0xA3, + 0xB7, 0x1C, 0x6D, 0xF2, 0xAE, 0x79, 0xA4, 0x7C +}; + +/** AES-256-CBC test vector */ +static const struct blockcipher_test_data aes_test_data_11 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0, + 0x37, 0x07, 0xB8, 0x23, 0xA2, 0xA3, 0xB5, 0x8D + }, + .len = 32 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes256cbc, + .len = 512 + } +}; + +static const struct blockcipher_test_case aes_chain_test_cases[] = { + { + .test_descr = "AES-128-CTR HMAC-SHA1 Encryption Digest", + .test_data = &aes_test_data_1, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CTR HMAC-SHA1 Decryption Digest " + "Verify", + .test_data = &aes_test_data_1, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-192-CTR XCBC Encryption Digest", + .test_data = &aes_test_data_2, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-192-CTR XCBC Decryption Digest Verify", + .test_data = &aes_test_data_2, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-256-CTR HMAC-SHA1 Encryption Digest", + .test_data = &aes_test_data_3, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-256-CTR HMAC-SHA1 Decryption Digest " + "Verify", + .test_data = &aes_test_data_3, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " + "Verify", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA256 Encryption Digest", + .test_data = &aes_test_data_5, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA256 Decryption Digest " + "Verify", + .test_data = &aes_test_data_5, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest", + .test_data = &aes_test_data_6, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest " + "Sessionless", + .test_data = &aes_test_data_6, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-128-CBC HMAC-SHA512 Decryption Digest " + "Verify", + .test_data = &aes_test_data_6, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC XCBC Encryption Digest", + .test_data = &aes_test_data_7, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC XCBC Decryption Digest Verify", + .test_data = &aes_test_data_7, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest " + "OOP", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " + "Verify OOP", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-128-CBC HMAC-SHA224 Encryption Digest", + .test_data = &aes_test_data_8, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA224 Decryption Digest " + "Verify", + .test_data = &aes_test_data_8, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA384 Encryption Digest", + .test_data = &aes_test_data_9, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA384 Decryption Digest " + "Verify", + .test_data = &aes_test_data_9, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest Sessionless", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = + "AES-128-CBC HMAC-SHA1 Decryption Digest Verify Sessionless", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, +}; + +static const struct blockcipher_test_case aes_cipheronly_test_cases[] = { + { + .test_descr = "AES-128-CBC Encryption", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-128-CBC Decryption", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-192-CBC Encryption", + .test_data = &aes_test_data_10, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-192-CBC Decryption", + .test_data = &aes_test_data_10, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-256-CBC Encryption", + .test_data = &aes_test_data_11, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-256-CBC Decryption", + .test_data = &aes_test_data_11, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-128-CTR Encryption", + .test_data = &aes_test_data_1, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-128-CTR Decryption", + .test_data = &aes_test_data_1, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-192-CTR Encryption", + .test_data = &aes_test_data_2, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-192-CTR Decryption", + .test_data = &aes_test_data_2, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-256-CTR Encryption", + .test_data = &aes_test_data_3, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-256-CTR Decryption", + .test_data = &aes_test_data_3, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, +}; + +#endif /* TEST_CRYPTODEV_AES_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_blockcipher.c b/app/test/test_cryptodev_blockcipher.c new file mode 100644 index 0000000..6649080 --- /dev/null +++ b/app/test/test_cryptodev_blockcipher.c @@ -0,0 +1,531 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2015-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_common.h> +#include <rte_hexdump.h> +#include <rte_mbuf.h> +#include <rte_malloc.h> +#include <rte_memcpy.h> + +#include <rte_crypto.h> +#include <rte_cryptodev.h> +#include <rte_cryptodev_pmd.h> + +#include "test.h" +#include "test_cryptodev_blockcipher.h" +#include "test_cryptodev_aes_test_vectors.h" +#include "test_cryptodev_des_test_vectors.h" +#include "test_cryptodev_hash_test_vectors.h" + +static int +test_blockcipher_one_case(const struct blockcipher_test_case *t, + struct rte_mempool *mbuf_pool, + struct rte_mempool *op_mpool, + uint8_t dev_id, + enum rte_cryptodev_type cryptodev_type, + char *test_msg) +{ + struct rte_mbuf *ibuf = NULL; + struct rte_mbuf *obuf = NULL; + struct rte_mbuf *iobuf; + struct rte_crypto_sym_xform *cipher_xform = NULL; + struct rte_crypto_sym_xform *auth_xform = NULL; + struct rte_crypto_sym_xform *init_xform = NULL; + struct rte_crypto_sym_op *sym_op = NULL; + struct rte_crypto_op *op = NULL; + struct rte_cryptodev_sym_session *sess = NULL; + + int status = TEST_SUCCESS; + const struct blockcipher_test_data *tdata = t->test_data; + uint8_t cipher_key[tdata->cipher_key.len]; + uint8_t auth_key[tdata->auth_key.len]; + uint32_t buf_len = tdata->ciphertext.len; + uint32_t digest_len = 0; + char *buf_p = NULL; + + if (tdata->cipher_key.len) + memcpy(cipher_key, tdata->cipher_key.data, + tdata->cipher_key.len); + if (tdata->auth_key.len) + memcpy(auth_key, tdata->auth_key.data, + tdata->auth_key.len); + + switch (cryptodev_type) { + case RTE_CRYPTODEV_QAT_SYM_PMD: + case RTE_CRYPTODEV_LIBCRYPTO_PMD: + digest_len = tdata->digest.len; + break; + case RTE_CRYPTODEV_AESNI_MB_PMD: + digest_len = tdata->digest.truncated_len; + break; + default: + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Unsupported PMD type"); + status = TEST_FAILED; + goto error_exit; + } + + /* preparing data */ + ibuf = rte_pktmbuf_alloc(mbuf_pool); + if (!ibuf) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Allocation of rte_mbuf failed"); + status = TEST_FAILED; + goto error_exit; + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) + buf_len += tdata->iv.len; + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) + buf_len += digest_len; + + buf_p = rte_pktmbuf_append(ibuf, buf_len); + if (!buf_p) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "No room to append mbuf"); + status = TEST_FAILED; + goto error_exit; + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { + rte_memcpy(buf_p, tdata->iv.data, tdata->iv.len); + buf_p += tdata->iv.len; + } + + /* only encryption requires plaintext.data input, + * decryption/(digest gen)/(digest verify) use ciphertext.data + * to be computed + */ + if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) { + rte_memcpy(buf_p, tdata->plaintext.data, + tdata->plaintext.len); + buf_p += tdata->plaintext.len; + } else { + rte_memcpy(buf_p, tdata->ciphertext.data, + tdata->ciphertext.len); + buf_p += tdata->ciphertext.len; + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) + rte_memcpy(buf_p, tdata->digest.data, digest_len); + else + memset(buf_p, 0, digest_len); + + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) { + obuf = rte_pktmbuf_alloc(mbuf_pool); + if (!obuf) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "Allocation of rte_mbuf failed"); + status = TEST_FAILED; + goto error_exit; + } + + buf_p = rte_pktmbuf_append(obuf, buf_len); + if (!buf_p) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "No room to append mbuf"); + status = TEST_FAILED; + goto error_exit; + } + memset(buf_p, 0, buf_len); + } + + /* Generate Crypto op data structure */ + op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_SYMMETRIC); + if (!op) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Failed to allocate symmetric crypto " + "operation struct"); + status = TEST_FAILED; + goto error_exit; + } + + sym_op = op->sym; + + sym_op->m_src = ibuf; + + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) { + sym_op->m_dst = obuf; + iobuf = obuf; + } else { + sym_op->m_dst = NULL; + iobuf = ibuf; + } + + /* sessionless op requires allocate xform using + * rte_crypto_op_sym_xforms_alloc(), otherwise rte_zmalloc() + * is used + */ + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) { + uint32_t n_xforms = 0; + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) + n_xforms++; + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) + n_xforms++; + + if (rte_crypto_op_sym_xforms_alloc(op, n_xforms) + == NULL) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, "Failed to " + "allocate space for crypto transforms"); + status = TEST_FAILED; + goto error_exit; + } + } else { + cipher_xform = rte_zmalloc(NULL, + sizeof(struct rte_crypto_sym_xform), 0); + + auth_xform = rte_zmalloc(NULL, + sizeof(struct rte_crypto_sym_xform), 0); + + if (!cipher_xform || !auth_xform) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, "Failed to " + "allocate memory for crypto transforms"); + status = TEST_FAILED; + goto error_exit; + } + } + + /* preparing xform, for sessioned op, init_xform is initialized + * here and later as param in rte_cryptodev_sym_session_create() call + */ + if (t->op_mask == BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN) { + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) { + cipher_xform = op->sym->xform; + auth_xform = cipher_xform->next; + auth_xform->next = NULL; + } else { + cipher_xform->next = auth_xform; + auth_xform->next = NULL; + init_xform = cipher_xform; + } + } else if (t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC) { + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) { + auth_xform = op->sym->xform; + cipher_xform = auth_xform->next; + cipher_xform->next = NULL; + } else { + auth_xform->next = cipher_xform; + cipher_xform->next = NULL; + init_xform = auth_xform; + } + } else if ((t->op_mask == BLOCKCIPHER_TEST_OP_ENCRYPT) || + (t->op_mask == BLOCKCIPHER_TEST_OP_DECRYPT)) { + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) + cipher_xform = op->sym->xform; + else + init_xform = cipher_xform; + cipher_xform->next = NULL; + } else if ((t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_GEN) || + (t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_VERIFY)) { + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) + auth_xform = op->sym->xform; + else + init_xform = auth_xform; + auth_xform->next = NULL; + } else { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Unrecognized operation"); + status = TEST_FAILED; + goto error_exit; + } + + /*configure xforms & sym_op cipher and auth data*/ + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { + cipher_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; + cipher_xform->cipher.algo = tdata->crypto_algo; + if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) + cipher_xform->cipher.op = + RTE_CRYPTO_CIPHER_OP_ENCRYPT; + else + cipher_xform->cipher.op = + RTE_CRYPTO_CIPHER_OP_DECRYPT; + cipher_xform->cipher.key.data = cipher_key; + cipher_xform->cipher.key.length = tdata->cipher_key.len; + + sym_op->cipher.data.offset = tdata->iv.len; + sym_op->cipher.data.length = tdata->ciphertext.len; + sym_op->cipher.iv.data = rte_pktmbuf_mtod(sym_op->m_src, + uint8_t *); + sym_op->cipher.iv.length = tdata->iv.len; + sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys( + sym_op->m_src); + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) { + uint32_t auth_data_offset = 0; + uint32_t digest_offset = tdata->ciphertext.len; + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { + digest_offset += tdata->iv.len; + auth_data_offset += tdata->iv.len; + } + + auth_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; + auth_xform->auth.algo = tdata->auth_algo; + auth_xform->auth.key.length = tdata->auth_key.len; + auth_xform->auth.key.data = auth_key; + auth_xform->auth.digest_length = digest_len; + + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) { + auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; + sym_op->auth.digest.data = rte_pktmbuf_mtod_offset + (iobuf, uint8_t *, digest_offset); + sym_op->auth.digest.phys_addr = + rte_pktmbuf_mtophys_offset(iobuf, + digest_offset); + } else { + auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; + sym_op->auth.digest.data = rte_pktmbuf_mtod_offset + (sym_op->m_src, uint8_t *, digest_offset); + sym_op->auth.digest.phys_addr = + rte_pktmbuf_mtophys_offset(sym_op->m_src, + digest_offset); + } + + sym_op->auth.data.offset = auth_data_offset; + sym_op->auth.data.length = tdata->ciphertext.len; + sym_op->auth.digest.length = digest_len; + } + + /* create session for sessioned op */ + if (!(t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)) { + sess = rte_cryptodev_sym_session_create(dev_id, + init_xform); + if (!sess) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "Session creation failed"); + status = TEST_FAILED; + goto error_exit; + } + + /* attach symmetric crypto session to crypto operations */ + rte_crypto_op_attach_sym_session(op, sess); + } + + /* Process crypto operation */ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Error sending packet for encryption"); + status = TEST_FAILED; + goto error_exit; + } + + op = NULL; + + while (rte_cryptodev_dequeue_burst(dev_id, 0, &op, 1) == 0) + rte_pause(); + + if (!op) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Failed to process sym crypto op"); + status = TEST_FAILED; + goto error_exit; + } + + TEST_HEXDUMP(stdout, "m_src:", + rte_pktmbuf_mtod(sym_op->m_src, uint8_t *), buf_len); + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) + TEST_HEXDUMP(stdout, "m_dst:", + rte_pktmbuf_mtod(sym_op->m_dst, uint8_t *), + buf_len); + + /* Verify results */ + if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) { + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: Digest verification failed " + "(0x%X)", __LINE__, op->status); + else + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: Digest verification failed " + "(0x%X)", __LINE__, op->status); + status = TEST_FAILED; + goto error_exit; + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { + uint8_t *crypto_res; + const uint8_t *compare_ref; + uint32_t compare_len; + + crypto_res = rte_pktmbuf_mtod_offset(iobuf, uint8_t *, + tdata->iv.len); + + if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) { + compare_ref = tdata->ciphertext.data; + compare_len = tdata->ciphertext.len; + } else { + compare_ref = tdata->plaintext.data; + compare_len = tdata->plaintext.len; + } + + if (memcmp(crypto_res, compare_ref, compare_len)) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "Crypto data not as expected"); + status = TEST_FAILED; + goto error_exit; + } + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) { + uint8_t *auth_res; + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) + auth_res = rte_pktmbuf_mtod_offset(iobuf, + uint8_t *, + tdata->iv.len + tdata->ciphertext.len); + else + auth_res = rte_pktmbuf_mtod_offset(iobuf, + uint8_t *, tdata->ciphertext.len); + + if (memcmp(auth_res, tdata->digest.data, digest_len)) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, "Generated " + "digest data not as expected"); + status = TEST_FAILED; + goto error_exit; + } + } + + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "PASS"); + +error_exit: + if (!(t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)) { + if (sess) + rte_cryptodev_sym_session_free(dev_id, sess); + if (cipher_xform) + rte_free(cipher_xform); + if (auth_xform) + rte_free(auth_xform); + } + + if (op) + rte_crypto_op_free(op); + + if (obuf) + rte_pktmbuf_free(obuf); + + if (ibuf) + rte_pktmbuf_free(ibuf); + + return status; +} + +int +test_blockcipher_all_tests(struct rte_mempool *mbuf_pool, + struct rte_mempool *op_mpool, + uint8_t dev_id, + enum rte_cryptodev_type cryptodev_type, + enum blockcipher_test_type test_type) +{ + int status, overall_status = TEST_SUCCESS; + uint32_t i, test_index = 0; + char test_msg[BLOCKCIPHER_TEST_MSG_LEN + 1]; + uint32_t n_test_cases = 0; + uint32_t target_pmd_mask = 0; + const struct blockcipher_test_case *tcs = NULL; + + switch (test_type) { + case BLKCIPHER_AES_CHAIN_TYPE: + n_test_cases = sizeof(aes_chain_test_cases) / + sizeof(aes_chain_test_cases[0]); + tcs = aes_chain_test_cases; + break; + case BLKCIPHER_AES_CIPHERONLY_TYPE: + n_test_cases = sizeof(aes_cipheronly_test_cases) / + sizeof(aes_cipheronly_test_cases[0]); + tcs = aes_cipheronly_test_cases; + break; + case BLKCIPHER_3DES_CHAIN_TYPE: + n_test_cases = sizeof(triple_des_chain_test_cases) / + sizeof(triple_des_chain_test_cases[0]); + tcs = triple_des_chain_test_cases; + break; + case BLKCIPHER_3DES_CIPHERONLY_TYPE: + n_test_cases = sizeof(triple_des_cipheronly_test_cases) / + sizeof(triple_des_cipheronly_test_cases[0]); + tcs = triple_des_cipheronly_test_cases; + break; + case BLKCIPHER_AUTHONLY_TYPE: + n_test_cases = sizeof(hash_test_cases) / + sizeof(hash_test_cases[0]); + tcs = hash_test_cases; + break; + default: + break; + } + + switch (cryptodev_type) { + case RTE_CRYPTODEV_AESNI_MB_PMD: + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB; + break; + case RTE_CRYPTODEV_QAT_SYM_PMD: + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT; + break; + case RTE_CRYPTODEV_LIBCRYPTO_PMD: + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO; + break; + default: + TEST_ASSERT(0, "Unrecognized cryptodev type"); + break; + } + + for (i = 0; i < n_test_cases; i++) { + const struct blockcipher_test_case *tc = &tcs[i]; + + if (!(tc->pmd_mask & target_pmd_mask)) + continue; + + status = test_blockcipher_one_case(tc, mbuf_pool, op_mpool, + dev_id, cryptodev_type, test_msg); + + printf(" %u) TestCase %s %s\n", test_index ++, + tc->test_descr, test_msg); + + if (status != TEST_SUCCESS) { + if (overall_status == TEST_SUCCESS) + overall_status = status; + + if (tc->feature_mask & BLOCKCIPHER_TEST_FEATURE_STOPPER) + break; + } + } + + return overall_status; +} diff --git a/app/test/test_cryptodev_blockcipher.h b/app/test/test_cryptodev_blockcipher.h new file mode 100644 index 0000000..3232a86 --- /dev/null +++ b/app/test/test_cryptodev_blockcipher.h @@ -0,0 +1,125 @@ +/*- + * 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 TEST_CRYPTODEV_BLOCKCIPHER_H_ +#define TEST_CRYPTODEV_BLOCKCIPHER_H_ + +#ifndef BLOCKCIPHER_TEST_MSG_LEN +#define BLOCKCIPHER_TEST_MSG_LEN 256 +#endif + +#define BLOCKCIPHER_TEST_OP_ENCRYPT 0x01 +#define BLOCKCIPHER_TEST_OP_DECRYPT 0x02 +#define BLOCKCIPHER_TEST_OP_AUTH_GEN 0x04 +#define BLOCKCIPHER_TEST_OP_AUTH_VERIFY 0x08 + +#define BLOCKCIPHER_TEST_FEATURE_OOP 0x01 +#define BLOCKCIPHER_TEST_FEATURE_SESSIONLESS 0x02 +#define BLOCKCIPHER_TEST_FEATURE_STOPPER 0x04 /* stop upon failing */ + +#define BLOCKCIPHER_TEST_TARGET_PMD_MB 0x0001 /* Multi-buffer flag */ +#define BLOCKCIPHER_TEST_TARGET_PMD_QAT 0x0002 /* QAT flag */ +#define BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO 0x0004 /* SW LIBCRYPTO flag */ + +#define BLOCKCIPHER_TEST_OP_CIPHER (BLOCKCIPHER_TEST_OP_ENCRYPT | \ + BLOCKCIPHER_TEST_OP_DECRYPT) + +#define BLOCKCIPHER_TEST_OP_AUTH (BLOCKCIPHER_TEST_OP_AUTH_GEN | \ + BLOCKCIPHER_TEST_OP_AUTH_VERIFY) + +#define BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN (BLOCKCIPHER_TEST_OP_ENCRYPT | \ + BLOCKCIPHER_TEST_OP_AUTH_GEN) + +#define BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC (BLOCKCIPHER_TEST_OP_DECRYPT | \ + BLOCKCIPHER_TEST_OP_AUTH_VERIFY) + +enum blockcipher_test_type { + BLKCIPHER_AES_CHAIN_TYPE, /* use aes_chain_test_cases[] */ + BLKCIPHER_AES_CIPHERONLY_TYPE, /* use aes_cipheronly_test_cases[] */ + BLKCIPHER_3DES_CHAIN_TYPE, /* use triple_des_chain_test_cases[] */ + BLKCIPHER_3DES_CIPHERONLY_TYPE, /* triple_des_cipheronly_test_cases[] */ + BLKCIPHER_AUTHONLY_TYPE /* use hash_test_cases[] */ +}; + +struct blockcipher_test_case { + const char *test_descr; /* test description */ + const struct blockcipher_test_data *test_data; + uint8_t op_mask; /* operation mask */ + uint8_t feature_mask; + uint32_t pmd_mask; +}; + +struct blockcipher_test_data { + enum rte_crypto_cipher_algorithm crypto_algo; + + struct { + uint8_t data[64]; + unsigned int len; + } cipher_key; + + struct { + uint8_t data[64] __rte_aligned(16); + unsigned int len; + } iv; + + struct { + const uint8_t *data; + unsigned int len; + } plaintext; + + struct { + const uint8_t *data; + unsigned int len; + } ciphertext; + + enum rte_crypto_auth_algorithm auth_algo; + + struct { + uint8_t data[128]; + unsigned int len; + } auth_key; + + struct { + uint8_t data[128]; + unsigned int len; /* for qat */ + unsigned int truncated_len; /* for mb */ + } digest; +}; + +int +test_blockcipher_all_tests(struct rte_mempool *mbuf_pool, + struct rte_mempool *op_mpool, + uint8_t dev_id, + enum rte_cryptodev_type cryptodev_type, + enum blockcipher_test_type test_type); + +#endif /* TEST_CRYPTODEV_BLOCKCIPHER_H_ */ diff --git a/app/test/test_cryptodev_des_test_vectors.h b/app/test/test_cryptodev_des_test_vectors.h new file mode 100644 index 0000000..f3144fe --- /dev/null +++ b/app/test/test_cryptodev_des_test_vectors.h @@ -0,0 +1,952 @@ +/* + * 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 TEST_CRYPTODEV_DES_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_DES_TEST_VECTORS_H_ + +static const uint8_t plaintext_des[] = { + "What a lousy earth! He wondered how many people " + "were destitute that same night even in his own " + "prosperous country, how many homes were " + "shanties, how many husbands were drunk and " + "wives socked, and how many children were " + "bullied, abused, or abandoned. How many " + "families hungered for food they could not " + "afford to buy? How many hearts were broken? How " + "many suicides would take place that same night, " + "how many people would go insane? How many " + "cockroaches and landlords would triumph? How " + "many winners were losers, successes failures, " + "and rich men poor men? How many wise guys were " + "stupid? How many happy endings were unhappy " + "endings? How many honest men were liars, brave " + "men cowards, loyal men traitors, how many " + "sainted men were corrupt, how many people in " + "positions of trust had sold their souls to " + "bodyguards, how many had never had souls? How " + "many straight-and-narrow paths were crooked " + "paths? How many best families were worst " + "families and how many good people were bad " + "people? When you added them all up and then " + "subtracted, you might be left with only the " + "children, and perhaps with Albert Einstein and " + "an old violinist or sculptor somewhere." +}; + +static const uint8_t ciphertext512_des128ctr[] = { + 0x13, 0x39, 0x3B, 0xBC, 0x1D, 0xE3, 0x23, 0x09, + 0x9B, 0x08, 0xD1, 0x09, 0x52, 0x93, 0x78, 0x29, + 0x11, 0x21, 0xBA, 0x01, 0x15, 0xCD, 0xEC, 0xAA, + 0x79, 0x77, 0x58, 0xAE, 0xAE, 0xBC, 0x97, 0x33, + 0x94, 0xA9, 0x2D, 0xC0, 0x0A, 0xA9, 0xA4, 0x4B, + 0x19, 0x07, 0x88, 0x06, 0x7E, 0x81, 0x0F, 0xB5, + 0x60, 0xCF, 0xA7, 0xC3, 0x2A, 0x43, 0xFF, 0x16, + 0x3A, 0x5F, 0x11, 0x2D, 0x11, 0x38, 0x37, 0x94, + 0x2A, 0xC8, 0x3D, 0x20, 0xBB, 0x93, 0x95, 0x54, + 0x12, 0xFF, 0x0C, 0x47, 0x89, 0x7D, 0x73, 0xD1, + 0x2E, 0x3A, 0x80, 0x52, 0xA8, 0x92, 0x93, 0x99, + 0x16, 0xB8, 0x12, 0x1B, 0x8B, 0xA8, 0xC1, 0x81, + 0x95, 0x18, 0x82, 0xD6, 0x5A, 0xA7, 0xFE, 0xCF, + 0xC4, 0xAC, 0x85, 0x91, 0x0C, 0x2F, 0x1D, 0x10, + 0x9A, 0x65, 0x07, 0xB0, 0x2E, 0x5A, 0x2D, 0x48, + 0x26, 0xF8, 0x17, 0x7A, 0x53, 0xD6, 0xB8, 0xDF, + 0xB1, 0x10, 0x48, 0x7E, 0x8F, 0xBE, 0x2E, 0xA1, + 0x0D, 0x9E, 0xA9, 0xF1, 0x3B, 0x3B, 0x33, 0xCD, + 0xDC, 0x52, 0x7E, 0xC0, 0x0E, 0xA0, 0xD8, 0xA7, + 0xC6, 0x34, 0x5A, 0xAA, 0x29, 0x8B, 0xA9, 0xAC, + 0x1F, 0x78, 0xAD, 0xEE, 0x34, 0x59, 0x30, 0xFB, + 0x2A, 0x20, 0x3D, 0x4D, 0x30, 0xA7, 0x7D, 0xD8, + 0xA0, 0xC6, 0xA2, 0xD3, 0x9A, 0xFB, 0x50, 0x97, + 0x4D, 0x25, 0xA2, 0x37, 0x51, 0x54, 0xB7, 0xEB, + 0xED, 0x77, 0xDB, 0x94, 0x35, 0x8B, 0x70, 0x95, + 0x4A, 0x00, 0xA7, 0xF1, 0x8A, 0x66, 0x0E, 0xC6, + 0x05, 0x7B, 0x69, 0x05, 0x42, 0x03, 0x96, 0x2C, + 0x55, 0x00, 0x1B, 0xC0, 0x19, 0x4D, 0x0D, 0x2E, + 0xF5, 0x81, 0x11, 0x64, 0xCA, 0xBB, 0xF2, 0x0F, + 0x9C, 0x60, 0xE2, 0xCC, 0x02, 0x6E, 0x83, 0xD5, + 0x24, 0xF4, 0x12, 0x0E, 0x6A, 0xEA, 0x4F, 0x6C, + 0x79, 0x69, 0x65, 0x67, 0xDB, 0xF7, 0xEA, 0x98, + 0x5D, 0x56, 0x98, 0xB7, 0x88, 0xE7, 0x23, 0xC9, + 0x17, 0x32, 0x92, 0x33, 0x5A, 0x0C, 0x15, 0x20, + 0x3B, 0x1C, 0xF9, 0x0F, 0x4D, 0xD1, 0xE8, 0xE6, + 0x9E, 0x5E, 0x24, 0x1B, 0xA4, 0xB8, 0xB9, 0xE9, + 0x2F, 0xFC, 0x89, 0xB4, 0xB9, 0xF4, 0xA6, 0xAD, + 0x55, 0xF4, 0xDF, 0x58, 0x63, 0x25, 0xE3, 0x41, + 0x70, 0xDF, 0x10, 0xE7, 0x13, 0x87, 0x8D, 0xB3, + 0x62, 0x4F, 0xF5, 0x86, 0x85, 0x8F, 0x59, 0xF0, + 0x21, 0x0E, 0x8F, 0x11, 0xAD, 0xBF, 0xDD, 0x61, + 0x68, 0x3F, 0x54, 0x57, 0x49, 0x38, 0xC8, 0x24, + 0x8E, 0x0A, 0xAC, 0xCA, 0x2C, 0x36, 0x3E, 0x5F, + 0x0A, 0xCE, 0xFD, 0x1A, 0x60, 0x63, 0x5A, 0xE6, + 0x06, 0x64, 0xB5, 0x94, 0x3C, 0xC9, 0xAF, 0x7C, + 0xCD, 0x49, 0x10, 0xCF, 0xAF, 0x0E, 0x2E, 0x79, + 0x27, 0xB2, 0x67, 0x02, 0xED, 0xEE, 0x80, 0x77, + 0x7C, 0x6D, 0x4B, 0xDB, 0xCF, 0x8D, 0x68, 0x00, + 0x2E, 0xD9, 0xF0, 0x8E, 0x08, 0xBF, 0xA6, 0x9B, + 0xFE, 0xA4, 0xFB, 0x19, 0x46, 0xAF, 0x1B, 0xA9, + 0xF8, 0x22, 0x81, 0x21, 0x97, 0xFC, 0xC0, 0x8A, + 0x26, 0x58, 0x13, 0x29, 0xB6, 0x69, 0x94, 0x4B, + 0xAB, 0xB3, 0x88, 0x0D, 0xA9, 0x48, 0x0E, 0xE8, + 0x70, 0xFC, 0xA1, 0x21, 0xC4, 0x2C, 0xE5, 0x99, + 0xB4, 0xF1, 0x6F, 0xB2, 0x4B, 0x4B, 0xCD, 0x48, + 0x15, 0x47, 0x2D, 0x72, 0x39, 0x99, 0x9D, 0x24, + 0x0C, 0x8B, 0xDC, 0xA1, 0xEE, 0xF6, 0xF4, 0x73, + 0xC3, 0xB8, 0x0C, 0x23, 0x0D, 0xA7, 0xC4, 0x7D, + 0x27, 0xE2, 0x14, 0x11, 0x53, 0x19, 0xE7, 0xCA, + 0x94, 0x4E, 0x0D, 0x2C, 0xF7, 0x36, 0x47, 0xDB, + 0x77, 0x3C, 0x22, 0xAC, 0xBE, 0xE1, 0x06, 0x55, + 0xE5, 0xDD, 0x8B, 0x65, 0xE8, 0xE9, 0x91, 0x52, + 0x59, 0x97, 0xFC, 0x8C, 0xEE, 0x96, 0x22, 0x60, + 0xEE, 0xBF, 0x82, 0xF0, 0xCA, 0x14, 0xF9, 0xD3 +}; + +static const struct blockcipher_test_data +triple_des128ctr_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128ctr, + .len = 512 + } +}; + +static const struct blockcipher_test_data +triple_des128ctr_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128ctr, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .digest = { + .data = { + 0xC3, 0x40, 0xD5, 0xD9, 0x8F, 0x8A, 0xC0, 0xF0, + 0x46, 0x28, 0x02, 0x01, 0xB5, 0xC1, 0x87, 0x4D, + 0xAC, 0xFE, 0x48, 0x76 + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +triple_des128ctr_hmac_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128ctr, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0xF1, 0xC1, 0xDB, 0x4D, 0xFA, 0x7F, 0x2F, 0xE5, + 0xF8, 0x49, 0xEA, 0x1D, 0x7F, 0xCB, 0x42, 0x59, + 0xC4, 0x1E, 0xB1, 0x18 + }, + .len = 20 + } +}; + +static const uint8_t ciphertext512_des192ctr[] = { + 0xFF, 0x32, 0x52, 0x97, 0x10, 0xBF, 0x0B, 0x10, + 0x68, 0x0F, 0x4F, 0x56, 0x8B, 0x2C, 0x7B, 0x8E, + 0x39, 0x1E, 0x1A, 0x2F, 0x83, 0xDE, 0x5E, 0x35, + 0xC8, 0x4B, 0xDF, 0xD5, 0xBC, 0x84, 0x50, 0x1A, + 0x02, 0xDF, 0xB3, 0x11, 0xE4, 0xDA, 0xB8, 0x0E, + 0x47, 0xC6, 0x0C, 0x51, 0x09, 0x62, 0x9C, 0x5D, + 0x71, 0x40, 0x49, 0xD8, 0x55, 0xBD, 0x7D, 0x90, + 0x71, 0xC5, 0xF7, 0x07, 0x6F, 0x08, 0x71, 0x2A, + 0xB1, 0x77, 0x9B, 0x0F, 0xA1, 0xB0, 0xD6, 0x10, + 0xB2, 0xE5, 0x31, 0xEC, 0x21, 0x13, 0x89, 0x2A, + 0x09, 0x7E, 0x30, 0xDB, 0xA0, 0xF0, 0xDC, 0xE4, + 0x74, 0x64, 0x39, 0xA3, 0xB0, 0xB1, 0x80, 0x66, + 0x52, 0xD4, 0x4E, 0xC9, 0x5A, 0x52, 0x6A, 0xC7, + 0xB5, 0x2B, 0x61, 0xD5, 0x17, 0xD5, 0xF3, 0xCC, + 0x41, 0x61, 0xD2, 0xA6, 0xF4, 0x51, 0x24, 0x3A, + 0x63, 0x5D, 0x23, 0xB1, 0xF0, 0x22, 0xE7, 0x45, + 0xFA, 0x5F, 0x7E, 0x99, 0x00, 0x11, 0x28, 0x35, + 0xA3, 0xF4, 0x61, 0x94, 0x0E, 0x98, 0xCE, 0x35, + 0xDD, 0x91, 0x1B, 0x0B, 0x4D, 0xEE, 0xFF, 0xFF, + 0x0B, 0xD4, 0xDC, 0x56, 0xFC, 0x71, 0xE9, 0xEC, + 0xE8, 0x36, 0x51, 0xF8, 0x8B, 0x6A, 0xE1, 0x8C, + 0x2B, 0x25, 0x91, 0x91, 0x9B, 0x92, 0x76, 0xB5, + 0x3D, 0x26, 0xA8, 0x53, 0xEA, 0x30, 0x5B, 0x4D, + 0xDA, 0x16, 0xDA, 0x7D, 0x04, 0x88, 0xF5, 0x22, + 0xA8, 0x0C, 0xB9, 0x41, 0xC7, 0x91, 0x64, 0x86, + 0x99, 0x7D, 0x18, 0xB9, 0x67, 0xA2, 0x6E, 0x05, + 0x1A, 0x82, 0x8F, 0xA2, 0xEB, 0x4D, 0x0B, 0x8C, + 0x88, 0x2D, 0xBA, 0x77, 0x87, 0x32, 0x50, 0x3C, + 0x4C, 0xD8, 0xD3, 0x50, 0x39, 0xFA, 0xDF, 0x48, + 0x3E, 0x30, 0xF5, 0x76, 0x06, 0xB0, 0x1A, 0x05, + 0x60, 0x2C, 0xD3, 0xA0, 0x63, 0x1A, 0x19, 0x2D, + 0x6B, 0x76, 0xF2, 0x31, 0x4C, 0xA7, 0xE6, 0x5C, + 0x1B, 0x23, 0x20, 0x41, 0x32, 0xE5, 0x83, 0x47, + 0x04, 0xB6, 0x3E, 0xE0, 0xFD, 0x49, 0x1E, 0x1B, + 0x75, 0x10, 0x11, 0x46, 0xE9, 0xF9, 0x96, 0x9A, + 0xD7, 0x59, 0xFE, 0x38, 0x31, 0xFE, 0x79, 0xC4, + 0xC8, 0x46, 0x88, 0xDE, 0x2E, 0xAE, 0x20, 0xED, + 0x77, 0x50, 0x40, 0x38, 0x26, 0xD3, 0x35, 0xF6, + 0x29, 0x55, 0x6A, 0x6B, 0x38, 0x69, 0xFE, 0x90, + 0x5B, 0xA7, 0xFA, 0x6B, 0x73, 0x4F, 0xB9, 0x5D, + 0xDC, 0x6F, 0x98, 0xC3, 0x6A, 0xC4, 0xB5, 0x09, + 0xC5, 0x84, 0xA5, 0x6A, 0x84, 0xA4, 0xB3, 0x8A, + 0x5F, 0xCA, 0x92, 0x64, 0x9E, 0xC3, 0x0F, 0x84, + 0x8B, 0x2D, 0x48, 0xC6, 0x67, 0xAE, 0x07, 0xE0, + 0x28, 0x38, 0x6D, 0xC4, 0x4D, 0x13, 0x87, 0xE0, + 0xB2, 0x2F, 0xAA, 0xC0, 0xCF, 0x68, 0xD7, 0x9C, + 0xB8, 0x07, 0xE4, 0x51, 0xD7, 0x75, 0x86, 0xFA, + 0x0C, 0x50, 0x74, 0x68, 0x00, 0x64, 0x2A, 0x27, + 0x59, 0xE9, 0x80, 0xEB, 0xC2, 0xA3, 0xFA, 0x58, + 0xCC, 0x03, 0xE7, 0x7B, 0x66, 0x53, 0xFF, 0x90, + 0xA0, 0x85, 0xE2, 0xF8, 0x82, 0xFE, 0xC6, 0x2B, + 0xFF, 0x5E, 0x70, 0x85, 0x34, 0xB7, 0x22, 0x38, + 0xDB, 0xBC, 0x15, 0x30, 0x59, 0xC1, 0x48, 0x42, + 0xE5, 0x38, 0x8D, 0x37, 0x59, 0xDB, 0xA3, 0x20, + 0x17, 0x36, 0x1D, 0x4B, 0xBF, 0x4E, 0xA4, 0x35, + 0xCC, 0xFE, 0xF5, 0x7A, 0x73, 0xB4, 0x6D, 0x20, + 0x1D, 0xC0, 0xE5, 0x21, 0x5C, 0xD2, 0x8A, 0x65, + 0x08, 0xB6, 0x63, 0xAC, 0x9A, 0x1E, 0x3F, 0x3C, + 0xAB, 0xB6, 0x6D, 0x34, 0xB2, 0x3A, 0x08, 0xDA, + 0x29, 0x63, 0xD1, 0xA4, 0x83, 0x52, 0xB0, 0x63, + 0x1B, 0x89, 0x35, 0x57, 0x59, 0x2C, 0x0F, 0x72, + 0x72, 0xFD, 0xA0, 0xAC, 0xDB, 0xB4, 0xA3, 0xA1, + 0x18, 0x10, 0x12, 0x97, 0x99, 0x63, 0x38, 0x98, + 0x96, 0xB5, 0x16, 0x07, 0x4E, 0xE9, 0x2C, 0x97 +}; + +static const struct blockcipher_test_data +triple_des192ctr_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192ctr, + .len = 512 + } +}; + +static const struct blockcipher_test_data +triple_des192ctr_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192ctr, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .digest = { + .data = { + 0xEA, 0x62, 0xB9, 0xB2, 0x78, 0x6C, 0x8E, 0xDB, + 0xA3, 0xB6, 0xFF, 0x23, 0x3A, 0x47, 0xD8, 0xC8, + 0xED, 0x5E, 0x20, 0x1D + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +triple_des192ctr_hmac_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192ctr, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x32, 0xD5, 0x19, 0x8F, 0x79, 0x3A, 0xAA, 0x7B, + 0x70, 0x67, 0x4E, 0x63, 0x88, 0xA3, 0x9A, 0x82, + 0x07, 0x33, 0x12, 0x94 + }, + .len = 20 + } +}; + +static const uint8_t ciphertext512_des128cbc[] = { + 0x28, 0x2a, 0xff, 0x15, 0x5c, 0xdf, 0xd9, 0x6b, + 0x54, 0xbc, 0x7b, 0xfb, 0xc5, 0x64, 0x4d, 0xdd, + 0x3e, 0xf2, 0x9e, 0xb7, 0x53, 0x65, 0x37, 0x05, + 0xe0, 0xdf, 0xae, 0xf7, 0xc9, 0x27, 0xe4, 0xec, + 0x11, 0x27, 0xc2, 0x9e, 0x02, 0x4e, 0x03, 0x3b, + 0x33, 0xf2, 0x66, 0x08, 0x24, 0x5f, 0xab, 0xc2, + 0x7e, 0x21, 0x19, 0x5d, 0x51, 0xc3, 0xe2, 0x97, + 0x6f, 0x2e, 0xb4, 0xaa, 0x34, 0x70, 0x88, 0x78, + 0x4e, 0xe7, 0x3d, 0xe1, 0x9f, 0x87, 0x1c, 0x8b, + 0xac, 0x8d, 0xa1, 0x1a, 0xcd, 0xb0, 0xf8, 0xb6, + 0x24, 0x36, 0xe3, 0x8c, 0x07, 0xe7, 0xe4, 0x92, + 0x13, 0x86, 0x6f, 0x13, 0xec, 0x04, 0x5c, 0xe9, + 0xb9, 0xca, 0x45, 0x8a, 0x2c, 0x46, 0xda, 0x54, + 0x1d, 0xb5, 0x81, 0xb1, 0xcd, 0xf3, 0x7d, 0x11, + 0x6b, 0xb3, 0x0a, 0x45, 0xe5, 0x6e, 0x51, 0x3e, + 0x2c, 0xac, 0x7c, 0xbc, 0xa7, 0x7e, 0x22, 0x4d, + 0xe6, 0x02, 0xe3, 0x3f, 0x77, 0xd7, 0x73, 0x72, + 0x0e, 0xfb, 0x42, 0x85, 0x80, 0xdf, 0xa8, 0x91, + 0x60, 0x40, 0x48, 0xcd, 0x1b, 0xd9, 0xbf, 0x2f, + 0xf2, 0xdf, 0xd0, 0xbd, 0x3f, 0x82, 0xce, 0x15, + 0x9d, 0x6e, 0xc6, 0x59, 0x6f, 0x27, 0x0d, 0xf9, + 0x26, 0xe2, 0x11, 0x29, 0x50, 0xc3, 0x0a, 0xb7, + 0xde, 0x9d, 0xe9, 0x55, 0xa1, 0xe9, 0x01, 0x33, + 0x56, 0x51, 0xa7, 0x3a, 0x9e, 0x63, 0xc5, 0x08, + 0x01, 0x3b, 0x03, 0x4b, 0xc6, 0xc4, 0xa1, 0xc0, + 0xc0, 0xd0, 0x0e, 0x48, 0xe5, 0x4c, 0x55, 0x6b, + 0x4a, 0xc1, 0x0a, 0x24, 0x4b, 0xd0, 0x02, 0xf4, + 0x31, 0x63, 0x11, 0xbd, 0xa6, 0x1f, 0xf4, 0xae, + 0x23, 0x5a, 0x40, 0x7e, 0x0e, 0x4e, 0x63, 0x8b, + 0x66, 0x3d, 0x55, 0x46, 0x6e, 0x5c, 0x76, 0xa7, + 0x68, 0x31, 0xce, 0x5d, 0xca, 0xe2, 0xb4, 0xb0, + 0xc1, 0x1f, 0x66, 0x18, 0x75, 0x64, 0x73, 0xa9, + 0x9e, 0xd5, 0x0e, 0x0e, 0xf7, 0x77, 0x61, 0xf8, + 0x89, 0xc6, 0xcf, 0x0c, 0x41, 0xd3, 0x8f, 0xfd, + 0x22, 0x52, 0x4f, 0x94, 0x5c, 0x19, 0x11, 0x3a, + 0xb5, 0x63, 0xe8, 0x81, 0x33, 0x13, 0x54, 0x3c, + 0x93, 0x36, 0xb5, 0x5b, 0x51, 0xaf, 0x51, 0xa2, + 0x08, 0xae, 0x83, 0x15, 0x77, 0x07, 0x28, 0x0d, + 0x98, 0xe1, 0x2f, 0x69, 0x0e, 0xfb, 0x9a, 0x2e, + 0x27, 0x27, 0xb0, 0xd5, 0xce, 0xf8, 0x16, 0x55, + 0xfd, 0xaa, 0xd7, 0x1a, 0x1b, 0x2e, 0x4c, 0x86, + 0x7a, 0x6a, 0x90, 0xf7, 0x0a, 0x07, 0xd3, 0x81, + 0x4b, 0x75, 0x6a, 0x79, 0xdb, 0x63, 0x45, 0x0f, + 0x31, 0x7e, 0xd0, 0x2a, 0x14, 0xff, 0xee, 0xcc, + 0x97, 0x8a, 0x7d, 0x74, 0xbd, 0x9d, 0xaf, 0x00, + 0xdb, 0x7e, 0xf3, 0xe6, 0x22, 0x76, 0x77, 0x58, + 0xba, 0x1c, 0x06, 0x96, 0xfb, 0x6f, 0x41, 0x71, + 0x66, 0x98, 0xae, 0x31, 0x7d, 0x29, 0x18, 0x71, + 0x0e, 0xe4, 0x98, 0x7e, 0x59, 0x5a, 0xc9, 0x78, + 0x9c, 0xfb, 0x6c, 0x81, 0x44, 0xb4, 0x0f, 0x5e, + 0x18, 0x53, 0xb8, 0x6f, 0xbc, 0x3b, 0x15, 0xf0, + 0x10, 0xdd, 0x0d, 0x4b, 0x0a, 0x36, 0x0e, 0xb4, + 0x76, 0x0f, 0x16, 0xa7, 0x5c, 0x9d, 0xcf, 0xb0, + 0x6d, 0x38, 0x02, 0x07, 0x05, 0xe9, 0xe9, 0x46, + 0x08, 0xb8, 0x52, 0xd6, 0xd9, 0x4c, 0x81, 0x63, + 0x1d, 0xe2, 0x5b, 0xd0, 0xf6, 0x5e, 0x1e, 0x81, + 0x48, 0x08, 0x66, 0x3a, 0x85, 0xed, 0x65, 0xfe, + 0xe8, 0x05, 0x7a, 0xe1, 0xe6, 0x12, 0xf2, 0x52, + 0x83, 0xdd, 0x82, 0xbe, 0xf6, 0x34, 0x8a, 0x6f, + 0xc5, 0x83, 0xcd, 0x3f, 0xbe, 0x58, 0x8b, 0x11, + 0x78, 0xdc, 0x0c, 0x83, 0x72, 0x5d, 0x05, 0x2a, + 0x01, 0x29, 0xee, 0x48, 0x9a, 0x67, 0x00, 0x6e, + 0x14, 0x60, 0x2d, 0x00, 0x52, 0x87, 0x98, 0x5e, + 0x43, 0xfe, 0xf1, 0x10, 0x14, 0xf1, 0x91, 0xcc +}; + +static const struct blockcipher_test_data +triple_des128cbc_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128cbc, + .len = 512 + } +}; + +static const struct blockcipher_test_data +triple_des128cbc_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .digest = { + .data = { + 0x94, 0x45, 0x7B, 0xDF, 0xFE, 0x80, 0xB9, 0xA6, + 0xA0, 0x7A, 0xE8, 0x93, 0x40, 0x7B, 0x85, 0x02, + 0x1C, 0xD7, 0xE8, 0x87 + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +triple_des128cbc_hmac_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x7E, 0xBA, 0xFF, 0x86, 0x8D, 0x65, 0xCD, 0x08, + 0x76, 0x34, 0x94, 0xE9, 0x9A, 0xCD, 0xB2, 0xBB, + 0xBF, 0x65, 0xF5, 0x42 + }, + .len = 20 + } +}; + +static const uint8_t ciphertext512_des192cbc[] = { + 0xd0, 0xc9, 0xdc, 0x51, 0x29, 0x97, 0x03, 0x64, + 0xcd, 0x22, 0xba, 0x3d, 0x2b, 0xbc, 0x21, 0x37, + 0x7b, 0x1e, 0x29, 0x23, 0xeb, 0x51, 0x6e, 0xac, + 0xbe, 0x5b, 0xd3, 0x67, 0xe0, 0x3f, 0xc3, 0xb5, + 0xe3, 0x04, 0x17, 0x42, 0x2b, 0xaa, 0xdd, 0xd6, + 0x0e, 0x69, 0xd0, 0x8f, 0x8a, 0xfc, 0xb4, 0x55, + 0x67, 0x06, 0x51, 0xbb, 0x00, 0x57, 0xee, 0x95, + 0x28, 0x79, 0x3f, 0xd9, 0x97, 0x2b, 0xb0, 0x02, + 0x35, 0x08, 0xce, 0x7a, 0xc3, 0x43, 0x2c, 0x87, + 0xaa, 0x97, 0x6a, 0xad, 0xf0, 0x26, 0xea, 0x1d, + 0xbb, 0x08, 0xe9, 0x52, 0x11, 0xd3, 0xaf, 0x36, + 0x17, 0x14, 0x21, 0xb2, 0xbc, 0x42, 0x51, 0x33, + 0x27, 0x8c, 0xd8, 0x45, 0xb9, 0x76, 0xa0, 0x11, + 0x24, 0x34, 0xde, 0x4d, 0x13, 0x67, 0x1b, 0xc3, + 0x31, 0x12, 0x66, 0x56, 0x59, 0xd2, 0xb1, 0x8f, + 0xec, 0x1e, 0xc0, 0x10, 0x7a, 0x86, 0xb1, 0x60, + 0xc3, 0x01, 0xd6, 0xa8, 0x55, 0xad, 0x58, 0x63, + 0xca, 0x68, 0xa9, 0x33, 0xe3, 0x93, 0x90, 0x7d, + 0x8f, 0xca, 0xf8, 0x1c, 0xc2, 0x9e, 0xfb, 0xde, + 0x9c, 0xc7, 0xf2, 0x6c, 0xff, 0xcc, 0x39, 0x17, + 0x49, 0x33, 0x0d, 0x7c, 0xed, 0x07, 0x99, 0x91, + 0x91, 0x6c, 0x5f, 0x3f, 0x02, 0x09, 0xdc, 0x70, + 0xf9, 0x3b, 0x8d, 0xaa, 0xf4, 0xbc, 0x0e, 0xec, + 0xf2, 0x26, 0xfb, 0xb2, 0x1c, 0x31, 0xae, 0xc6, + 0x72, 0xe8, 0x0b, 0x75, 0x05, 0x57, 0x58, 0x98, + 0x92, 0x37, 0x27, 0x8e, 0x3b, 0x0c, 0x25, 0xfb, + 0xcf, 0x82, 0x02, 0xd5, 0x0b, 0x1f, 0x89, 0x49, + 0xcd, 0x0f, 0xa1, 0xa7, 0x08, 0x63, 0x56, 0xa7, + 0x1f, 0x80, 0x3a, 0xef, 0x24, 0x89, 0x57, 0x1a, + 0x02, 0xdc, 0x2e, 0x51, 0xbd, 0x4a, 0x10, 0x23, + 0xfc, 0x02, 0x1a, 0x3f, 0x34, 0xbf, 0x1c, 0x98, + 0x1a, 0x40, 0x0a, 0x96, 0x8e, 0x41, 0xd5, 0x09, + 0x55, 0x37, 0xe9, 0x25, 0x11, 0x83, 0xf8, 0xf3, + 0xd4, 0xb0, 0xdb, 0x16, 0xd7, 0x51, 0x7e, 0x94, + 0xf7, 0xb4, 0x26, 0xe0, 0xf4, 0x80, 0x01, 0x65, + 0x51, 0xeb, 0xbc, 0xb0, 0x65, 0x8f, 0xdd, 0xb5, + 0xf7, 0x00, 0xec, 0x40, 0xab, 0x7d, 0x96, 0xcc, + 0x8d, 0xec, 0x89, 0x80, 0x31, 0x39, 0xa2, 0x5c, + 0xb0, 0x55, 0x4c, 0xee, 0xdd, 0x15, 0x2b, 0xa9, + 0x86, 0x4e, 0x23, 0x14, 0x36, 0xc5, 0x57, 0xf5, + 0xe3, 0xe8, 0x89, 0xc9, 0xb7, 0xf8, 0xeb, 0x08, + 0xe5, 0x93, 0x12, 0x5c, 0x0f, 0x79, 0xa1, 0x86, + 0xe4, 0xc2, 0xeb, 0xa6, 0xa0, 0x50, 0x6a, 0xec, + 0xd3, 0xce, 0x50, 0x78, 0x4e, 0x4f, 0x93, 0xd8, + 0xdc, 0xb4, 0xec, 0x02, 0xe9, 0xbd, 0x17, 0x99, + 0x1e, 0x16, 0x4e, 0xd7, 0xb0, 0x07, 0x02, 0x55, + 0x63, 0x24, 0x4f, 0x7b, 0x8f, 0xc5, 0x7a, 0x12, + 0x29, 0xff, 0x5d, 0xc1, 0xe7, 0xae, 0x48, 0xc8, + 0x57, 0x53, 0xe7, 0xcd, 0x10, 0x6c, 0x19, 0xfc, + 0xcc, 0xb9, 0xb1, 0xbe, 0x48, 0x9f, 0x2d, 0x3f, + 0x39, 0x2e, 0xdd, 0x71, 0xde, 0x1b, 0x54, 0xee, + 0x7d, 0x94, 0x8f, 0x27, 0x23, 0xe9, 0x74, 0x92, + 0x14, 0x93, 0x84, 0x65, 0xc9, 0x22, 0x7c, 0xa8, + 0x1b, 0x72, 0x73, 0xb1, 0x23, 0xa0, 0x6b, 0xcc, + 0xb5, 0x22, 0x06, 0x15, 0xe5, 0x96, 0x03, 0x4a, + 0x52, 0x8d, 0x1d, 0xbf, 0x3e, 0x82, 0x45, 0x9c, + 0x75, 0x9e, 0xa9, 0x3a, 0x97, 0xb6, 0x5d, 0xc4, + 0x75, 0x67, 0xa1, 0xf3, 0x0f, 0x7a, 0xfd, 0x71, + 0x58, 0x04, 0xf9, 0xa7, 0xc2, 0x56, 0x74, 0x04, + 0x74, 0x68, 0x6d, 0x8a, 0xf6, 0x6c, 0x5d, 0xd8, + 0xb5, 0xed, 0x70, 0x23, 0x32, 0x4d, 0x75, 0x92, + 0x88, 0x7b, 0x39, 0x37, 0x02, 0x4b, 0xb2, 0x1c, + 0x1f, 0x7e, 0x5b, 0x1b, 0x10, 0xfc, 0x17, 0x21, + 0x66, 0x62, 0x63, 0xc2, 0xcd, 0x16, 0x96, 0x3e +}; + +static const struct blockcipher_test_data +triple_des192cbc_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192cbc, + .len = 512 + } +}; + +static const struct blockcipher_test_data +triple_des192cbc_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .digest = { + .data = { + 0x53, 0x27, 0xC0, 0xE6, 0xD6, 0x1B, 0xD6, 0x45, + 0x94, 0x2D, 0xCE, 0x8B, 0x29, 0xA3, 0x52, 0x14, + 0xC1, 0x6B, 0x87, 0x99 + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +triple_des192cbc_hmac_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0xBA, 0xAC, 0x74, 0x19, 0x43, 0xB0, 0x72, 0xB8, + 0x08, 0xF5, 0x24, 0xC4, 0x09, 0xBD, 0x48, 0xC1, + 0x3C, 0x50, 0x1C, 0xDD + }, + .len = 20 + } +}; + +static const struct blockcipher_test_case triple_des_chain_test_cases[] = { + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Encryption Digest", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Decryption Digest Verify", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC SHA1 Encryption Digest", + .test_data = &triple_des128cbc_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-128-CBC SHA1 Decryption Digest Verify", + .test_data = &triple_des128cbc_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-192-CBC HMAC-SHA1 Encryption Digest", + .test_data = &triple_des192cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CBC HMAC-SHA1 Decryption Digest Verify", + .test_data = &triple_des192cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CBC SHA1 Encryption Digest", + .test_data = &triple_des192cbc_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-192-CBC SHA1 Decryption Digest Verify", + .test_data = &triple_des192cbc_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-128-CTR HMAC-SHA1 Encryption Digest", + .test_data = &triple_des128ctr_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CTR HMAC-SHA1 Decryption Digest Verify", + .test_data = &triple_des128ctr_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CTR SHA1 Encryption Digest", + .test_data = &triple_des128ctr_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-128-CTR SHA1 Decryption Digest Verify", + .test_data = &triple_des128ctr_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-192-CTR HMAC-SHA1 Encryption Digest", + .test_data = &triple_des192ctr_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CTR HMAC-SHA1 Decryption Digest Verify", + .test_data = &triple_des192ctr_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CTR SHA1 Encryption Digest", + .test_data = &triple_des192ctr_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-192-CTR SHA1 Decryption Digest Verify", + .test_data = &triple_des192ctr_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Encryption Digest OOP", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Decryption Digest Verify OOP", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Encryption Digest Sessionless", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = + "3DES-128-CBC HMAC-SHA1 Decryption Digest Verify Sessionless", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, +}; + +static const struct blockcipher_test_case triple_des_cipheronly_test_cases[] = { + { + .test_descr = "3DES-128-CBC Encryption", + .test_data = &triple_des128cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC Decryption", + .test_data = &triple_des128cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CBC Encryption", + .test_data = &triple_des192cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CBC Decryption", + .test_data = &triple_des192cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CTR Encryption", + .test_data = &triple_des128ctr_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CTR Decryption", + .test_data = &triple_des128ctr_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CTR Encryption", + .test_data = &triple_des192ctr_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CTR Decryption", + .test_data = &triple_des192ctr_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + } +}; + +#endif /* TEST_CRYPTODEV_DES_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_hash_test_vectors.h b/app/test/test_cryptodev_hash_test_vectors.h new file mode 100644 index 0000000..dfc84db --- /dev/null +++ b/app/test/test_cryptodev_hash_test_vectors.h @@ -0,0 +1,491 @@ +/* + * 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 TEST_CRYPTODEV_HASH_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_HASH_TEST_VECTORS_H_ + +static const uint8_t plaintext_hash[] = { + "What a lousy earth! He wondered how many people " + "were destitute that same night even in his own " + "prosperous country, how many homes were " + "shanties, how many husbands were drunk and " + "wives socked, and how many children were " + "bullied, abused, or abandoned. How many " + "families hungered for food they could not " + "afford to buy? How many hearts were broken? How " + "many suicides would take place that same night, " + "how many people would go insane? How many " + "cockroaches and landlords would triumph? How " + "many winners were losers, successes failures, " + "and rich men poor men? How many wise guys were " + "stupid? How many happy endings were unhappy " + "endings? How many honest men were liars, brave " + "men cowards, loyal men traitors, how many " + "sainted men were corrupt, how many people in " + "positions of trust had sold their souls to " + "bodyguards, how many had never had souls? How " + "many straight-and-narrow paths were crooked " + "paths? How many best families were worst " + "families and how many good people were bad " + "people? When you added them all up and then " + "subtracted, you might be left with only the " + "children, and perhaps with Albert Einstein and " + "an old violinist or sculptor somewhere." +}; + +static const struct blockcipher_test_data +md5_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_MD5, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0xB3, 0xE6, 0xBB, 0x50, 0x41, 0x35, 0x3C, 0x6B, + 0x7A, 0xFF, 0xD2, 0x64, 0xAF, 0xD5, 0x1C, 0xB2 + }, + .len = 16 + } +}; + +static const struct blockcipher_test_data +hmac_md5_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_MD5_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD + }, + .len = 16 + }, + .digest = { + .data = { + 0x50, 0xE8, 0xDE, 0xC5, 0xC1, 0x76, 0xAC, 0xAE, + 0x15, 0x4A, 0xF1, 0x7F, 0x7E, 0x04, 0x42, 0x9B + }, + .len = 16 + } +}; + +static const struct blockcipher_test_data +sha1_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0xA2, 0x8D, 0x40, 0x78, 0xDD, 0x9F, 0xBB, 0xD5, + 0x35, 0x62, 0xFB, 0xFA, 0x93, 0xFD, 0x7D, 0x70, + 0xA6, 0x7D, 0x45, 0xCA + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +hmac_sha1_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0xC4, 0xB7, 0x0E, 0x6B, 0xDE, 0xD1, 0xE7, 0x77, + 0x7E, 0x2E, 0x8F, 0xFC, 0x48, 0x39, 0x46, 0x17, + 0x3F, 0x91, 0x64, 0x59 + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +sha224_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA224, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0x91, 0xE7, 0xCD, 0x75, 0x14, 0x9C, 0xA9, 0xE9, + 0x2E, 0x46, 0x12, 0x20, 0x22, 0xF9, 0x68, 0x28, + 0x39, 0x26, 0xDF, 0xB5, 0x78, 0x62, 0xB2, 0x6E, + 0x5E, 0x8F, 0x25, 0x84 + }, + .len = 28 + } +}; + +static const struct blockcipher_test_data +hmac_sha224_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA224_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92, + 0xFB, 0xBF, 0xB0, 0x8C + }, + .len = 28 + }, + .digest = { + .data = { + 0x70, 0x0F, 0x04, 0x4D, 0x22, 0x02, 0x7D, 0x31, + 0x36, 0xDA, 0x77, 0x19, 0xB9, 0x66, 0x37, 0x7B, + 0xF1, 0x8A, 0x63, 0xBB, 0x5D, 0x1D, 0xE3, 0x9F, + 0x92, 0xF6, 0xAA, 0x19 + }, + .len = 28 + } +}; + +static const struct blockcipher_test_data +sha256_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA256, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0x7F, 0xF1, 0x0C, 0xF5, 0x90, 0x97, 0x19, 0x0F, + 0x00, 0xE4, 0x83, 0x01, 0xCA, 0x59, 0x00, 0x2E, + 0x1F, 0xC7, 0x84, 0xEE, 0x76, 0xA6, 0x39, 0x15, + 0x76, 0x2F, 0x87, 0xF9, 0x01, 0x06, 0xF3, 0xB7 + }, + .len = 32 + } +}; + +static const struct blockcipher_test_data +hmac_sha256_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92, + 0xFB, 0xBF, 0xB0, 0x8C, 0x29, 0x87, 0x90, 0xAC + }, + .len = 32 + }, + .digest = { + .data = { + 0xAF, 0x8F, 0x70, 0x1B, 0x4B, 0xAF, 0x34, 0xCB, + 0x02, 0x24, 0x48, 0x45, 0x83, 0x52, 0x8F, 0x22, + 0x06, 0x4D, 0x64, 0x09, 0x0A, 0xCC, 0x02, 0x77, + 0x71, 0x83, 0x48, 0x71, 0x07, 0x02, 0x25, 0x17 + }, + .len = 32 + } +}; + +static const struct blockcipher_test_data +sha384_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA384, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0x1D, 0xE7, 0x3F, 0x55, 0x86, 0xFE, 0x48, 0x9F, + 0xAC, 0xC6, 0x85, 0x32, 0xFA, 0x8E, 0xA6, 0x77, + 0x25, 0x84, 0xA5, 0x98, 0x8D, 0x0B, 0x80, 0xF4, + 0xEB, 0x2C, 0xFB, 0x6C, 0xEA, 0x7B, 0xFD, 0xD5, + 0xAD, 0x41, 0xAB, 0x15, 0xB0, 0x03, 0x15, 0xEC, + 0x9E, 0x3D, 0xED, 0xCB, 0x80, 0x7B, 0xF4, 0xB6 + }, + .len = 48 + } +}; + +static const struct blockcipher_test_data +hmac_sha384_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA384_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92, + 0xFB, 0xBF, 0xB0, 0x8C, 0x29, 0x87, 0x90, 0xAC, + 0x39, 0x8B, 0x5C, 0x49, 0x68, 0x1E, 0x3A, 0x05, + 0xCC, 0x68, 0x5C, 0x76, 0xCB, 0x3C, 0x71, 0x89 + }, + .len = 48 + }, + .digest = { + .data = { + 0xE2, 0x83, 0x18, 0x55, 0xB5, 0x8D, 0x94, 0x9B, + 0x01, 0xB6, 0xE2, 0x57, 0x7A, 0x62, 0xF5, 0xF4, + 0xAB, 0x39, 0xF3, 0x3C, 0x28, 0xA0, 0x0F, 0xCC, + 0xEE, 0x1C, 0xF1, 0xF8, 0x69, 0xF1, 0x24, 0x3B, + 0x10, 0x90, 0x0A, 0xE3, 0xF0, 0x59, 0xDD, 0xC0, + 0x6F, 0xE6, 0x8C, 0x84, 0xD5, 0x03, 0xF8, 0x9E + }, + .len = 48 + } +}; + +static const struct blockcipher_test_data +sha512_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA512, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0xB9, 0xBA, 0x28, 0x48, 0x3C, 0xC2, 0xD3, 0x65, + 0x4A, 0xD6, 0x00, 0x1D, 0xCE, 0x61, 0x64, 0x54, + 0x45, 0x8C, 0x64, 0x0E, 0xED, 0x0E, 0xD8, 0x1C, + 0x72, 0xCE, 0xD2, 0x44, 0x91, 0xC8, 0xEB, 0xC7, + 0x99, 0xC5, 0xCA, 0x89, 0x72, 0x64, 0x96, 0x41, + 0xC8, 0xEA, 0xB2, 0x4E, 0xD1, 0x21, 0x13, 0x49, + 0x64, 0x4E, 0x15, 0x68, 0x12, 0x67, 0x26, 0x0F, + 0x2C, 0x3C, 0x83, 0x25, 0x27, 0x86, 0xF0, 0xDB + }, + .len = 64 + } +}; + +static const struct blockcipher_test_data +hmac_sha512_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA512_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92, + 0xFB, 0xBF, 0xB0, 0x8C, 0x29, 0x87, 0x90, 0xAC, + 0x39, 0x8B, 0x5C, 0x49, 0x68, 0x1E, 0x3A, 0x05, + 0xCC, 0x68, 0x5C, 0x76, 0xCB, 0x3C, 0x71, 0x89, + 0xDE, 0xAA, 0x36, 0x44, 0x98, 0x93, 0x97, 0x1E, + 0x6D, 0x53, 0x83, 0x87, 0xB3, 0xB7, 0x56, 0x41 + }, + .len = 64 + }, + .digest = { + .data = { + 0xB8, 0x0B, 0x35, 0x97, 0x3F, 0x24, 0x3F, 0x05, + 0x2A, 0x7F, 0x2F, 0xD8, 0xD7, 0x56, 0x58, 0xAD, + 0x6F, 0x8D, 0x1F, 0x4C, 0x30, 0xF9, 0xA8, 0x29, + 0x7A, 0xE0, 0x8D, 0x88, 0xF5, 0x2E, 0x94, 0xF5, + 0x06, 0xF7, 0x5D, 0x57, 0x32, 0xA8, 0x49, 0x29, + 0xEA, 0x6B, 0x6D, 0x95, 0xBD, 0x76, 0xF5, 0x79, + 0x97, 0x37, 0x0F, 0xBE, 0xC2, 0x45, 0xA0, 0x87, + 0xAF, 0x24, 0x27, 0x0C, 0x78, 0xBA, 0xBE, 0x20 + }, + .len = 64 + } +}; + +static const struct blockcipher_test_case hash_test_cases[] = { + { + .test_descr = "MD5 Digest", + .test_data = &md5_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "MD5 Digest Verify", + .test_data = &md5_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-MD5 Digest", + .test_data = &hmac_md5_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-MD5 Digest Verify", + .test_data = &hmac_md5_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA1 Digest", + .test_data = &sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA1 Digest Verify", + .test_data = &sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA1 Digest", + .test_data = &hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA1 Digest Verify", + .test_data = &hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA224 Digest", + .test_data = &sha224_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA224 Digest Verify", + .test_data = &sha224_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA224 Digest", + .test_data = &hmac_sha224_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA224 Digest Verify", + .test_data = &hmac_sha224_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA256 Digest", + .test_data = &sha256_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA256 Digest Verify", + .test_data = &sha256_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA256 Digest", + .test_data = &hmac_sha256_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA256 Digest Verify", + .test_data = &hmac_sha256_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA384 Digest", + .test_data = &sha384_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA384 Digest Verify", + .test_data = &sha384_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA384 Digest", + .test_data = &hmac_sha384_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA384 Digest Verify", + .test_data = &hmac_sha384_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA512 Digest", + .test_data = &sha512_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA512 Digest Verify", + .test_data = &sha512_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA512 Digest", + .test_data = &hmac_sha512_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA512 Digest Verify", + .test_data = &hmac_sha512_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, +}; + +#endif /* TEST_CRYPTODEV_HASH_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_perf.c b/app/test/test_cryptodev_perf.c index 2398d84..0a0085d 100644 --- a/app/test/test_cryptodev_perf.c +++ b/app/test/test_cryptodev_perf.c @@ -97,12 +97,28 @@ static struct rte_cryptodev_sym_session * test_perf_create_snow3g_session(uint8_t dev_id, enum chain_mode chain, enum rte_crypto_cipher_algorithm cipher_algo, unsigned cipher_key_len, enum rte_crypto_auth_algorithm auth_algo); +static struct rte_cryptodev_sym_session * +test_perf_create_libcrypto_session(uint8_t dev_id, enum chain_mode chain, + enum rte_crypto_cipher_algorithm cipher_algo, + unsigned int cipher_key_len, enum rte_crypto_auth_algorithm auth_algo); static struct rte_mbuf * test_perf_create_pktmbuf(struct rte_mempool *mpool, unsigned buf_sz); static inline struct rte_crypto_op * test_perf_set_crypto_op_snow3g(struct rte_crypto_op *op, struct rte_mbuf *m, struct rte_cryptodev_sym_session *sess, unsigned data_len, unsigned digest_len); +static inline struct rte_crypto_op * +test_perf_set_crypto_op_aes(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len); +static inline struct rte_crypto_op * +test_perf_set_crypto_op_aes_gcm(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len); +static inline struct rte_crypto_op * +test_perf_set_crypto_op_3des(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len); static uint32_t get_auth_digest_length(enum rte_crypto_auth_algorithm algo); @@ -273,9 +289,24 @@ testsuite_setup(void) } } + /* Create 2 LIBCRYPTO devices if required */ + if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_LIBCRYPTO_PMD) { + nb_devs = rte_cryptodev_count_devtype(RTE_CRYPTODEV_LIBCRYPTO_PMD); + if (nb_devs < 2) { + for (i = nb_devs; i < 2; i++) { + ret = rte_eal_vdev_init( + RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), NULL); + + TEST_ASSERT(ret == 0, + "Failed to create instance %u of pmd : %s", + i, RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD)); + } + } + } + nb_devs = rte_cryptodev_count(); if (nb_devs < 1) { - RTE_LOG(ERR, USER1, "No crypto devices found?"); + RTE_LOG(ERR, USER1, "No crypto devices found?\n"); return TEST_FAILED; } @@ -2149,6 +2180,151 @@ test_perf_snow3G_vary_burst_size(void) return 0; } +static int +test_perf_libcrypto_optimise_cyclecount(struct perf_test_params *pparams) +{ + uint32_t num_to_submit = pparams->total_operations; + struct rte_crypto_op *c_ops[num_to_submit]; + struct rte_crypto_op *proc_ops[num_to_submit]; + uint64_t failed_polls, retries, start_cycles, end_cycles, total_cycles = 0; + uint32_t burst_sent = 0, burst_received = 0; + uint32_t i, burst_size, num_sent, num_ops_received; + + struct crypto_testsuite_params *ts_params = &testsuite_params; + + static struct rte_cryptodev_sym_session *sess; + + static struct rte_crypto_op *(*test_perf_set_crypto_op) + (struct rte_crypto_op *, struct rte_mbuf *, + struct rte_cryptodev_sym_session *, unsigned int, + unsigned int); + + unsigned int digest_length = get_auth_digest_length(pparams->auth_algo); + + if (rte_cryptodev_count() == 0) { + printf("\nNo crypto devices found. Is PMD build configured?\n"); + return TEST_FAILED; + } + + /* Create Crypto session*/ + sess = test_perf_create_libcrypto_session(ts_params->dev_id, + pparams->chain, pparams->cipher_algo, + pparams->cipher_key_length, pparams->auth_algo); + TEST_ASSERT_NOT_NULL(sess, "Session creation failed"); + + /* Generate Crypto op data structure(s)*/ + for (i = 0; i < num_to_submit ; i++) { + struct rte_mbuf *m = test_perf_create_pktmbuf( + ts_params->mbuf_mp, + pparams->buf_size); + TEST_ASSERT_NOT_NULL(m, "Failed to allocate tx_buf"); + + struct rte_crypto_op *op = + rte_crypto_op_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC); + TEST_ASSERT_NOT_NULL(op, "Failed to allocate op"); + + switch (pparams->cipher_algo) { + case RTE_CRYPTO_CIPHER_3DES_CBC: + case RTE_CRYPTO_CIPHER_3DES_CTR: + test_perf_set_crypto_op = test_perf_set_crypto_op_3des; + break; + case RTE_CRYPTO_CIPHER_AES_CBC: + case RTE_CRYPTO_CIPHER_AES_CTR: + test_perf_set_crypto_op = test_perf_set_crypto_op_aes; + break; + case RTE_CRYPTO_CIPHER_AES_GCM: + test_perf_set_crypto_op = test_perf_set_crypto_op_aes_gcm; + break; + default: + return TEST_FAILED; + } + + op = test_perf_set_crypto_op(op, m, sess, pparams->buf_size, + digest_length); + TEST_ASSERT_NOT_NULL(op, "Failed to attach op to session"); + + c_ops[i] = op; + } + + printf("\nOn %s dev%u qp%u, %s, cipher algo:%s, cipher key length:%u, " + "auth_algo:%s, Packet Size %u bytes", + pmd_name(gbl_cryptodev_perftest_devtype), + ts_params->dev_id, 0, + chain_mode_name(pparams->chain), + cipher_algo_name(pparams->cipher_algo), + pparams->cipher_key_length, + auth_algo_name(pparams->auth_algo), + pparams->buf_size); + printf("\nOps Tx\tOps Rx\tOps/burst "); + printf("Retries EmptyPolls\tIACycles/CyOp\tIACycles/Burst\tIACycles/Byte"); + + for (i = 2; i <= 128 ; i *= 2) { + num_sent = 0; + num_ops_received = 0; + retries = 0; + failed_polls = 0; + burst_size = i; + total_cycles = 0; + while (num_sent < num_to_submit) { + start_cycles = rte_rdtsc_precise(); + burst_sent = rte_cryptodev_enqueue_burst(ts_params->dev_id, + 0, &c_ops[num_sent], + ((num_to_submit - num_sent) < burst_size) ? + num_to_submit - num_sent : burst_size); + end_cycles = rte_rdtsc_precise(); + if (burst_sent == 0) + retries++; + num_sent += burst_sent; + total_cycles += (end_cycles - start_cycles); + + /* Wait until requests have been sent. */ + rte_delay_ms(1); + + start_cycles = rte_rdtsc_precise(); + burst_received = rte_cryptodev_dequeue_burst( + ts_params->dev_id, 0, proc_ops, burst_size); + end_cycles = rte_rdtsc_precise(); + if (burst_received < burst_sent) + failed_polls++; + num_ops_received += burst_received; + + total_cycles += end_cycles - start_cycles; + } + + while (num_ops_received != num_to_submit) { + /* Sending 0 length burst to flush sw crypto device */ + rte_cryptodev_enqueue_burst(ts_params->dev_id, 0, NULL, 0); + + start_cycles = rte_rdtsc_precise(); + burst_received = rte_cryptodev_dequeue_burst( + ts_params->dev_id, 0, proc_ops, burst_size); + end_cycles = rte_rdtsc_precise(); + + total_cycles += end_cycles - start_cycles; + if (burst_received == 0) + failed_polls++; + num_ops_received += burst_received; + } + + printf("\n%u\t%u\t%u", num_sent, num_ops_received, burst_size); + printf("\t\t%"PRIu64, retries); + printf("\t%"PRIu64, failed_polls); + printf("\t\t%"PRIu64, total_cycles/num_ops_received); + printf("\t\t%"PRIu64, (total_cycles/num_ops_received)*burst_size); + printf("\t\t%"PRIu64, + total_cycles/(num_ops_received*pparams->buf_size)); + } + printf("\n"); + + for (i = 0; i < num_to_submit ; i++) { + rte_pktmbuf_free(c_ops[i]->sym->m_src); + rte_crypto_op_free(c_ops[i]); + } + + return TEST_SUCCESS; +} + static uint32_t get_auth_key_max_length(enum rte_crypto_auth_algorithm algo) { switch (algo) { @@ -2164,6 +2340,8 @@ static uint32_t get_auth_key_max_length(enum rte_crypto_auth_algorithm algo) return 128; case RTE_CRYPTO_AUTH_SHA512_HMAC: return 128; + case RTE_CRYPTO_AUTH_AES_GCM: + return 0; default: return 0; } @@ -2184,23 +2362,35 @@ static uint32_t get_auth_digest_length(enum rte_crypto_auth_algorithm algo) return TRUNCATED_DIGEST_BYTE_LENGTH_SHA384; case RTE_CRYPTO_AUTH_SHA512_HMAC: return TRUNCATED_DIGEST_BYTE_LENGTH_SHA512; + case RTE_CRYPTO_AUTH_AES_GCM: + return DIGEST_BYTE_LENGTH_AES_GCM; default: return 0; } } -static uint8_t aes_cbc_key[] = { +static uint8_t aes_key[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static uint8_t aes_cbc_iv[] = { +static uint8_t aes_iv[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static uint8_t triple_des_key[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static uint8_t triple_des_iv[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + static uint8_t hmac_sha_key[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -2250,7 +2440,7 @@ test_perf_create_aes_sha_session(uint8_t dev_id, enum chain_mode chain, cipher_xform.cipher.algo = cipher_algo; cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; - cipher_xform.cipher.key.data = aes_cbc_key; + cipher_xform.cipher.key.data = aes_key; cipher_xform.cipher.key.length = cipher_key_len; /* Setup HMAC Parameters */ @@ -2328,8 +2518,77 @@ test_perf_create_snow3g_session(uint8_t dev_id, enum chain_mode chain, } } -#define AES_CBC_BLOCK_SIZE 16 -#define AES_CBC_CIPHER_IV_LENGTH 16 +static struct rte_cryptodev_sym_session * +test_perf_create_libcrypto_session(uint8_t dev_id, enum chain_mode chain, + enum rte_crypto_cipher_algorithm cipher_algo, + unsigned int cipher_key_len, + enum rte_crypto_auth_algorithm auth_algo) +{ + struct rte_crypto_sym_xform cipher_xform = { 0 }; + struct rte_crypto_sym_xform auth_xform = { 0 }; + + /* Setup Cipher Parameters */ + cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; + cipher_xform.cipher.algo = cipher_algo; + cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; + + switch (cipher_algo) { + case RTE_CRYPTO_CIPHER_3DES_CBC: + case RTE_CRYPTO_CIPHER_3DES_CTR: + cipher_xform.cipher.key.data = triple_des_key; + break; + case RTE_CRYPTO_CIPHER_AES_CBC: + case RTE_CRYPTO_CIPHER_AES_CTR: + case RTE_CRYPTO_CIPHER_AES_GCM: + cipher_xform.cipher.key.data = aes_key; + break; + default: + return NULL; + } + + cipher_xform.cipher.key.length = cipher_key_len; + + /* Setup Auth Parameters */ + auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; + auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; + auth_xform.auth.algo = auth_algo; + + switch (auth_algo) { + case RTE_CRYPTO_AUTH_SHA1_HMAC: + auth_xform.auth.key.data = hmac_sha_key; + break; + case RTE_CRYPTO_AUTH_AES_GCM: + auth_xform.auth.key.data = NULL; + break; + default: + return NULL; + } + + auth_xform.auth.key.length = get_auth_key_max_length(auth_algo); + auth_xform.auth.digest_length = get_auth_digest_length(auth_algo); + + switch (chain) { + case CIPHER_HASH: + cipher_xform.next = &auth_xform; + auth_xform.next = NULL; + /* Create Crypto session*/ + return rte_cryptodev_sym_session_create(dev_id, &cipher_xform); + case HASH_CIPHER: + auth_xform.next = &cipher_xform; + cipher_xform.next = NULL; + /* Create Crypto session*/ + return rte_cryptodev_sym_session_create(dev_id, &auth_xform); + default: + return NULL; + } +} + +#define AES_BLOCK_SIZE 16 +#define AES_CIPHER_IV_LENGTH 16 + +#define TRIPLE_DES_BLOCK_SIZE 8 +#define TRIPLE_DES_CIPHER_IV_LENGTH 8 + #define SNOW3G_CIPHER_IV_LENGTH 16 static struct rte_mbuf * @@ -2348,7 +2607,7 @@ test_perf_create_pktmbuf(struct rte_mempool *mpool, unsigned buf_sz) } static inline struct rte_crypto_op * -test_perf_set_crypto_op(struct rte_crypto_op *op, struct rte_mbuf *m, +test_perf_set_crypto_op_aes(struct rte_crypto_op *op, struct rte_mbuf *m, struct rte_cryptodev_sym_session *sess, unsigned data_len, unsigned digest_len) { @@ -2362,19 +2621,53 @@ test_perf_set_crypto_op(struct rte_crypto_op *op, struct rte_mbuf *m, (m->data_off + data_len); op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, data_len); op->sym->auth.digest.length = digest_len; - op->sym->auth.aad.data = aes_cbc_iv; - op->sym->auth.aad.length = AES_CBC_CIPHER_IV_LENGTH; + op->sym->auth.aad.data = aes_iv; + op->sym->auth.aad.length = AES_CIPHER_IV_LENGTH; /* Cipher Parameters */ - op->sym->cipher.iv.data = aes_cbc_iv; - op->sym->cipher.iv.length = AES_CBC_CIPHER_IV_LENGTH; + op->sym->cipher.iv.data = aes_iv; + op->sym->cipher.iv.length = AES_CIPHER_IV_LENGTH; /* Data lengths/offsets Parameters */ op->sym->auth.data.offset = 0; op->sym->auth.data.length = data_len; - op->sym->cipher.data.offset = AES_CBC_BLOCK_SIZE; - op->sym->cipher.data.length = data_len - AES_CBC_BLOCK_SIZE; + op->sym->cipher.data.offset = AES_BLOCK_SIZE; + op->sym->cipher.data.length = data_len - AES_BLOCK_SIZE; + + op->sym->m_src = m; + + return op; +} + +static inline struct rte_crypto_op * +test_perf_set_crypto_op_aes_gcm(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len) +{ + if (rte_crypto_op_attach_sym_session(op, sess) != 0) { + rte_crypto_op_free(op); + return NULL; + } + + /* Authentication Parameters */ + op->sym->auth.digest.data = (uint8_t *)m->buf_addr + + (m->data_off + data_len); + op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, data_len); + op->sym->auth.digest.length = digest_len; + op->sym->auth.aad.data = aes_iv; + op->sym->auth.aad.length = AES_CIPHER_IV_LENGTH; + + /* Cipher Parameters */ + op->sym->cipher.iv.data = aes_iv; + op->sym->cipher.iv.length = AES_CIPHER_IV_LENGTH; + + /* Data lengths/offsets Parameters */ + op->sym->auth.data.offset = AES_BLOCK_SIZE; + op->sym->auth.data.length = data_len - AES_BLOCK_SIZE; + + op->sym->cipher.data.offset = AES_BLOCK_SIZE; + op->sym->cipher.data.length = data_len - AES_BLOCK_SIZE; op->sym->m_src = m; @@ -2415,7 +2708,39 @@ test_perf_set_crypto_op_snow3g(struct rte_crypto_op *op, struct rte_mbuf *m, return op; } +static inline struct rte_crypto_op * +test_perf_set_crypto_op_3des(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len) +{ + if (rte_crypto_op_attach_sym_session(op, sess) != 0) { + rte_crypto_op_free(op); + return NULL; + } + + /* Authentication Parameters */ + op->sym->auth.digest.data = (uint8_t *)m->buf_addr + + (m->data_off + data_len); + op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, data_len); + op->sym->auth.digest.length = digest_len; + op->sym->auth.aad.data = triple_des_iv; + op->sym->auth.aad.length = TRIPLE_DES_CIPHER_IV_LENGTH; + + /* Cipher Parameters */ + op->sym->cipher.iv.data = triple_des_iv; + op->sym->cipher.iv.length = TRIPLE_DES_CIPHER_IV_LENGTH; + + /* Data lengths/offsets Parameters */ + op->sym->auth.data.offset = 0; + op->sym->auth.data.length = data_len; + op->sym->cipher.data.offset = TRIPLE_DES_BLOCK_SIZE; + op->sym->cipher.data.length = data_len - TRIPLE_DES_BLOCK_SIZE; + + op->sym->m_src = m; + + return op; +} /* An mbuf set is used in each burst. An mbuf can be used by multiple bursts at * same time, i.e. as they're not dereferenced there's no need to wait until @@ -2486,7 +2811,7 @@ test_perf_aes_sha(uint8_t dev_id, uint16_t queue_id, "and free ops below."); } else { for (i = 0; i < ops_needed; i++) - ops[i] = test_perf_set_crypto_op(ops[i], + ops[i] = test_perf_set_crypto_op_aes(ops[i], mbufs[i + (pparams->burst_size * (j % NUM_MBUF_SETS))], sess, pparams->buf_size, digest_length); @@ -2697,6 +3022,154 @@ test_perf_snow3g(uint8_t dev_id, uint16_t queue_id, return TEST_SUCCESS; } +static int +test_perf_libcrypto(uint8_t dev_id, uint16_t queue_id, + struct perf_test_params *pparams) +{ + uint16_t i, k, l, m; + uint16_t j = 0; + uint16_t ops_unused = 0; + + uint64_t burst_enqueued = 0, total_enqueued = 0, burst_dequeued = 0; + uint64_t processed = 0, failed_polls = 0, retries = 0; + uint64_t tsc_start = 0, tsc_end = 0; + + unsigned int digest_length = get_auth_digest_length(pparams->auth_algo); + + struct rte_crypto_op *ops[pparams->burst_size]; + struct rte_crypto_op *proc_ops[pparams->burst_size]; + + struct rte_mbuf *mbufs[pparams->burst_size * NUM_MBUF_SETS]; + + struct crypto_testsuite_params *ts_params = &testsuite_params; + + static struct rte_cryptodev_sym_session *sess; + + static struct rte_crypto_op *(*test_perf_set_crypto_op) + (struct rte_crypto_op *, struct rte_mbuf *, + struct rte_cryptodev_sym_session *, unsigned int, + unsigned int); + + switch (pparams->cipher_algo) { + case RTE_CRYPTO_CIPHER_3DES_CBC: + case RTE_CRYPTO_CIPHER_3DES_CTR: + test_perf_set_crypto_op = test_perf_set_crypto_op_3des; + break; + case RTE_CRYPTO_CIPHER_AES_CBC: + case RTE_CRYPTO_CIPHER_AES_CTR: + test_perf_set_crypto_op = test_perf_set_crypto_op_aes; + break; + case RTE_CRYPTO_CIPHER_AES_GCM: + test_perf_set_crypto_op = test_perf_set_crypto_op_aes_gcm; + break; + default: + return TEST_FAILED; + } + + if (rte_cryptodev_count() == 0) { + printf("\nNo crypto devices found. Is PMD build configured?\n"); + return TEST_FAILED; + } + + /* Create Crypto session*/ + sess = test_perf_create_libcrypto_session(ts_params->dev_id, + pparams->chain, pparams->cipher_algo, + pparams->cipher_key_length, pparams->auth_algo); + TEST_ASSERT_NOT_NULL(sess, "Session creation failed"); + + /* Generate a burst of crypto operations */ + for (i = 0; i < (pparams->burst_size * NUM_MBUF_SETS); i++) { + mbufs[i] = test_perf_create_pktmbuf( + ts_params->mbuf_mp, + pparams->buf_size); + + if (mbufs[i] == NULL) { + printf("\nFailed to get mbuf - freeing the rest.\n"); + for (k = 0; k < i; k++) + rte_pktmbuf_free(mbufs[k]); + return -1; + } + } + + tsc_start = rte_rdtsc_precise(); + + while (total_enqueued < pparams->total_operations) { + uint16_t burst_size = + total_enqueued + pparams->burst_size <= pparams->total_operations ? + pparams->burst_size : pparams->total_operations - total_enqueued; + uint16_t ops_needed = burst_size - ops_unused; + + if (ops_needed != rte_crypto_op_bulk_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC, ops, ops_needed)){ + printf("\nFailed to alloc enough ops, finish dequeuing " + "and free ops below."); + } else { + for (i = 0; i < ops_needed; i++) + ops[i] = test_perf_set_crypto_op(ops[i], + mbufs[i + (pparams->burst_size * + (j % NUM_MBUF_SETS))], + sess, pparams->buf_size, digest_length); + + /* enqueue burst */ + burst_enqueued = rte_cryptodev_enqueue_burst(dev_id, + queue_id, ops, burst_size); + + if (burst_enqueued < burst_size) + retries++; + + ops_unused = burst_size - burst_enqueued; + total_enqueued += burst_enqueued; + } + + /* dequeue burst */ + burst_dequeued = rte_cryptodev_dequeue_burst(dev_id, queue_id, + proc_ops, pparams->burst_size); + if (burst_dequeued == 0) + failed_polls++; + else { + processed += burst_dequeued; + + for (l = 0; l < burst_dequeued; l++) + rte_crypto_op_free(proc_ops[l]); + } + j++; + } + + /* Dequeue any operations still in the crypto device */ + while (processed < pparams->total_operations) { + /* Sending 0 length burst to flush sw crypto device */ + rte_cryptodev_enqueue_burst(dev_id, queue_id, NULL, 0); + + /* dequeue burst */ + burst_dequeued = rte_cryptodev_dequeue_burst(dev_id, queue_id, + proc_ops, pparams->burst_size); + if (burst_dequeued == 0) + failed_polls++; + else { + processed += burst_dequeued; + + for (m = 0; m < burst_dequeued; m++) + rte_crypto_op_free(proc_ops[m]); + } + } + + tsc_end = rte_rdtsc_precise(); + + double ops_s = ((double)processed / (tsc_end - tsc_start)) + * rte_get_tsc_hz(); + double throughput = (ops_s * pparams->buf_size * NUM_MBUF_SETS) + / 1000000000; + + printf("\t%u\t%6.2f\t%10.2f\t%8"PRIu64"\t%8"PRIu64, pparams->buf_size, + ops_s / 1000000, throughput, retries, failed_polls); + + for (i = 0; i < pparams->burst_size * NUM_MBUF_SETS; i++) + rte_pktmbuf_free(mbufs[i]); + + printf("\n"); + return TEST_SUCCESS; +} + /* perf_test_aes_sha("avx2", HASH_CIPHER, 16, CBC, SHA1); @@ -2844,6 +3317,166 @@ test_perf_snow3G_vary_pkt_size(void) } static int +test_perf_libcrypto_vary_pkt_size(void) +{ + unsigned int total_operations = 1000000; + unsigned int burst_size = { 64 }; + unsigned int buf_lengths[] = { 64, 128, 256, 512, 768, 1024, 1280, 1536, + 1792, 2048 }; + uint8_t i, j; + + struct perf_test_params params_set[] = { + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key_length = 24, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key_length = 32, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key_length = 24, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_GCM, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_AES_GCM + }, + }; + + for (i = 0; i < RTE_DIM(params_set); i++) { + params_set[i].total_operations = total_operations; + params_set[i].burst_size = burst_size; + printf("\n%s. cipher algo: %s auth algo: %s cipher key size=%u." + " burst_size: %d ops\n", + chain_mode_name(params_set[i].chain), + cipher_algo_name(params_set[i].cipher_algo), + auth_algo_name(params_set[i].auth_algo), + params_set[i].cipher_key_length, + burst_size); + printf("\nBuffer Size(B)\tOPS(M)\tThroughput(Gbps)\tRetries\t" + "EmptyPolls\n"); + for (j = 0; j < RTE_DIM(buf_lengths); j++) { + params_set[i].buf_size = buf_lengths[j]; + test_perf_libcrypto(testsuite_params.dev_id, 0, ¶ms_set[i]); + } + } + + return 0; +} + +static int +test_perf_libcrypto_vary_burst_size(void) +{ + unsigned int total_operations = 4096; + uint16_t buf_lengths[] = { 40 }; + uint8_t i, j; + + struct perf_test_params params_set[] = { + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key_length = 24, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key_length = 32, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key_length = 24, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_GCM, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_AES_GCM + }, + }; + + printf("\n\nStart %s.", __func__); + printf("\nThis Test measures the average IA cycle cost using a " + "constant request(packet) size. "); + printf("Cycle cost is only valid when indicators show device is not busy," + " i.e. Retries and EmptyPolls = 0"); + + for (i = 0; i < RTE_DIM(params_set); i++) { + printf("\n"); + params_set[i].total_operations = total_operations; + + for (j = 0; j < RTE_DIM(buf_lengths); j++) { + params_set[i].buf_size = buf_lengths[j]; + test_perf_libcrypto_optimise_cyclecount(¶ms_set[i]); + } + } + + return 0; +} + +static int test_perf_aes_cbc_vary_burst_size(void) { return test_perf_crypto_qp_vary_burst_size(testsuite_params.dev_id); @@ -2887,6 +3520,19 @@ static struct unit_test_suite cryptodev_snow3g_testsuite = { } }; +static struct unit_test_suite cryptodev_libcrypto_testsuite = { + .suite_name = "Crypto Device LIBCRYPTO Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, + test_perf_libcrypto_vary_pkt_size), + TEST_CASE_ST(ut_setup, ut_teardown, + test_perf_libcrypto_vary_burst_size), + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + static int perftest_aesni_mb_cryptodev(void /*argv __rte_unused, int argc __rte_unused*/) { @@ -2919,7 +3565,17 @@ perftest_qat_snow3g_cryptodev(void /*argv __rte_unused, int argc __rte_unused*/) return unit_test_suite_runner(&cryptodev_snow3g_testsuite); } +static int +perftest_libcrypto_cryptodev(void /*argv __rte_unused, int argc __rte_unused*/) +{ + gbl_cryptodev_perftest_devtype = RTE_CRYPTODEV_LIBCRYPTO_PMD; + + return unit_test_suite_runner(&cryptodev_libcrypto_testsuite); +} + REGISTER_TEST_COMMAND(cryptodev_aesni_mb_perftest, perftest_aesni_mb_cryptodev); REGISTER_TEST_COMMAND(cryptodev_qat_perftest, perftest_qat_cryptodev); REGISTER_TEST_COMMAND(cryptodev_sw_snow3g_perftest, perftest_sw_snow3g_cryptodev); REGISTER_TEST_COMMAND(cryptodev_qat_snow3g_perftest, perftest_qat_snow3g_cryptodev); +REGISTER_TEST_COMMAND(cryptodev_libcrypto_perftest, + perftest_libcrypto_cryptodev); -- 1.9.1 ^ permalink raw reply [flat|nested] 34+ messages in thread
* [dpdk-dev] [PATCH v2 4/4] examples/l2fwd-crypto: updated example for libcrypto PMD 2016-09-19 8:59 [dpdk-dev] [PATCH v2 0/4] new crypto software based device Michal Jastrzebski ` (2 preceding siblings ...) 2016-09-19 8:59 ` [dpdk-dev] [PATCH v2 3/4] app/test: added tests for " Michal Jastrzebski @ 2016-09-19 8:59 ` Michal Jastrzebski 2016-09-19 23:58 ` De Lara Guarch, Pablo 2016-09-29 14:14 ` [dpdk-dev] [PATCH v3 0/3] new crypto software based device Slawomir Mrozowicz 4 siblings, 1 reply; 34+ messages in thread From: Michal Jastrzebski @ 2016-09-19 8:59 UTC (permalink / raw) To: dev; +Cc: pablo.de.lara.guarch, Slawomir Mrozowicz, Daniel Mrzyglod From: Slawomir Mrozowicz <slawomirx.mrozowicz@intel.com> To verify real traffic l2fwd-crypto example can be used with this command: sudo ./build/l2fwd-crypto -c 0x3 -n 4 --vdev "cryptodev_libcrypto_pmd" --vdev "cryptodev_libcrypto_pmd" -- -p 0x3 --chain CIPHER_HASH --cipher_op ENCRYPT --cipher_algo AES_CBC --cipher_key 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f --iv 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:ff --auth_op GENERATE --auth_algo SHA1_HMAC --auth_key 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11: 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11: 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11: 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11 Limitations ----------- Maximum number of sessions is 2048. Signed-off-by: Daniel Mrzyglod <danielx.t.mrzyglod@intel.com> --- examples/l2fwd-crypto/main.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/examples/l2fwd-crypto/main.c b/examples/l2fwd-crypto/main.c index 66397a0..d912c23 100644 --- a/examples/l2fwd-crypto/main.c +++ b/examples/l2fwd-crypto/main.c @@ -341,18 +341,27 @@ fill_supported_algorithm_tables(void) strcpy(supported_auth_algo[i], "NOT_SUPPORTED"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_AES_GCM], "AES_GCM"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_AES_GMAC], "AES_GMAC"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_MD5_HMAC], "MD5_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_MD5], "MD5"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_NULL], "NULL"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_AES_XCBC_MAC], "AES_XCBC_MAC"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA1_HMAC], "SHA1_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA1], "SHA1"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA224_HMAC], "SHA224_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA224], "SHA224"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA256_HMAC], "SHA256_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA256], "SHA256"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA384_HMAC], "SHA384_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA384], "SHA384"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA512_HMAC], "SHA512_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA512], "SHA512"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SNOW3G_UIA2], "SNOW3G_UIA2"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_KASUMI_F9], "KASUMI_F9"); + + for (i = 0; i < RTE_CRYPTO_CIPHER_LIST_END; i++) strcpy(supported_cipher_algo[i], "NOT_SUPPORTED"); @@ -362,6 +371,8 @@ fill_supported_algorithm_tables(void) strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_NULL], "NULL"); strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_SNOW3G_UEA2], "SNOW3G_UEA2"); strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_KASUMI_F8], "KASUMI_F8"); + strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_3DES_CTR], "3DES_CTR"); + strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_3DES_CBC], "3DES_CBC"); } -- 1.9.1 ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dpdk-dev] [PATCH v2 4/4] examples/l2fwd-crypto: updated example for libcrypto PMD 2016-09-19 8:59 ` [dpdk-dev] [PATCH v2 4/4] examples/l2fwd-crypto: updated example " Michal Jastrzebski @ 2016-09-19 23:58 ` De Lara Guarch, Pablo 0 siblings, 0 replies; 34+ messages in thread From: De Lara Guarch, Pablo @ 2016-09-19 23:58 UTC (permalink / raw) To: Jastrzebski, MichalX K, dev; +Cc: Mrozowicz, SlawomirX, Mrzyglod, DanielX T Hi, > -----Original Message----- > From: Jastrzebski, MichalX K > Sent: Monday, September 19, 2016 2:00 AM > To: dev@dpdk.org > Cc: De Lara Guarch, Pablo; Mrozowicz, SlawomirX; Mrzyglod, DanielX T > Subject: [PATCH v2 4/4] examples/l2fwd-crypto: updated example for > libcrypto PMD > > From: Slawomir Mrozowicz <slawomirx.mrozowicz@intel.com> > > To verify real traffic l2fwd-crypto example can be used with this command: > sudo ./build/l2fwd-crypto -c 0x3 -n 4 --vdev "cryptodev_libcrypto_pmd" > --vdev "cryptodev_libcrypto_pmd" > -- -p 0x3 --chain CIPHER_HASH --cipher_op ENCRYPT --cipher_algo AES_CBC > --cipher_key 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f > --iv 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:ff > --auth_op GENERATE --auth_algo SHA1_HMAC > --auth_key > 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11: > 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11: > 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11: > 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11 > > Limitations > ----------- > Maximum number of sessions is 2048. I think it would be more valuable to include here the extra algorithms that can be used in this app with this patch, instead of including an example of the command line. Also, the maximum number of sessions is an arbitrary maximum number for all vdevs, so I think it is not necessary to include it in here. > > Signed-off-by: Daniel Mrzyglod <danielx.t.mrzyglod@intel.com> Thanks, Pablo ^ permalink raw reply [flat|nested] 34+ messages in thread
* [dpdk-dev] [PATCH v3 0/3] new crypto software based device 2016-09-19 8:59 [dpdk-dev] [PATCH v2 0/4] new crypto software based device Michal Jastrzebski ` (3 preceding siblings ...) 2016-09-19 8:59 ` [dpdk-dev] [PATCH v2 4/4] examples/l2fwd-crypto: updated example " Michal Jastrzebski @ 2016-09-29 14:14 ` Slawomir Mrozowicz 2016-09-29 14:14 ` [dpdk-dev] [PATCH v3 1/3] libcrypto_pmd: initial implementation of SW crypto device Slawomir Mrozowicz ` (3 more replies) 4 siblings, 4 replies; 34+ messages in thread From: Slawomir Mrozowicz @ 2016-09-29 14:14 UTC (permalink / raw) To: dev; +Cc: Slawomir Mrozowicz This code provides the initial implementation of the libcrypto poll mode driver. All cryptography operations are using Openssl library crypto API. Each algorithm uses EVP_ interface from openssl API - which is recommended by Openssl maintainers. For more information about how to use this driver, go to: doc/guides/cryptodevs/libcrypto.rst Changes in V3: - add nagative verification tests - add big data test - fix pmd according to negative verification tests - change gmac aad max size - update documentation and commits comments Changes in V2: - add gcm/gmac algorithm correction - unit test rework This patch-set depends on the following patches: http://dpdk.org/dev/patchwork/patch/15166/ http://dpdk.org/dev/patchwork/patch/15227/ http://dpdk.org/dev/patchwork/patch/15229/ http://dpdk.org/dev/patchwork/patch/15231/ http://dpdk.org/dev/patchwork/patch/15321/ http://dpdk.org/dev/patchwork/patch/15323/ http://dpdk.org/dev/patchwork/patch/15317/ http://dpdk.org/dev/patchwork/patch/15318/ http://dpdk.org/dev/patchwork/patch/15327/ Slawomir Mrozowicz (1): libcrypto_pmd: initial implementation of SW crypto device Piotr Azarewicz (1) app/test: added tests for libcrypto PMD Daniel Mrzyglod (1) examples/l2fwd-crypto: updated example for libcrypto PMD MAINTAINERS | 4 + app/test/Makefile | 2 +- app/test/test_cryptodev.c | 1579 +++- app/test/test_cryptodev.h | 1 + app/test/test_cryptodev_aes.c | 687 -- app/test/test_cryptodev_aes.h | 1124 --- app/test/test_cryptodev_aes_test_vectors.h | 1095 +++ app/test/test_cryptodev_blockcipher.c | 531 ++ app/test/test_cryptodev_blockcipher.h | 125 + app/test/test_cryptodev_des_test_vectors.h | 952 +++ app/test/test_cryptodev_gcm_test_vectors.h | 8247 +++++++++++++++++++- app/test/test_cryptodev_hash_test_vectors.h | 491 ++ app/test/test_cryptodev_perf.c | 684 +- config/common_base | 6 + doc/guides/cryptodevs/index.rst | 1 + doc/guides/cryptodevs/libcrypto.rst | 116 + doc/guides/rel_notes/release_16_11.rst | 23 +- drivers/crypto/Makefile | 1 + drivers/crypto/libcrypto/Makefile | 60 + drivers/crypto/libcrypto/rte_libcrypto_pmd.c | 1051 +++ drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c | 708 ++ .../crypto/libcrypto/rte_libcrypto_pmd_private.h | 174 + .../crypto/libcrypto/rte_pmd_libcrypto_version.map | 3 + examples/l2fwd-crypto/main.c | 11 + lib/librte_cryptodev/rte_cryptodev.h | 3 + mk/rte.app.mk | 19 +- 26 files changed, 15738 insertions(+), 1960 deletions(-) delete mode 100644 app/test/test_cryptodev_aes.c delete mode 100644 app/test/test_cryptodev_aes.h create mode 100644 app/test/test_cryptodev_aes_test_vectors.h create mode 100644 app/test/test_cryptodev_blockcipher.c create mode 100644 app/test/test_cryptodev_blockcipher.h create mode 100644 app/test/test_cryptodev_des_test_vectors.h create mode 100644 app/test/test_cryptodev_hash_test_vectors.h create mode 100644 doc/guides/cryptodevs/libcrypto.rst create mode 100644 drivers/crypto/libcrypto/Makefile create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd.c create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h create mode 100644 drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map -- 2.5.0 ^ permalink raw reply [flat|nested] 34+ messages in thread
* [dpdk-dev] [PATCH v3 1/3] libcrypto_pmd: initial implementation of SW crypto device 2016-09-29 14:14 ` [dpdk-dev] [PATCH v3 0/3] new crypto software based device Slawomir Mrozowicz @ 2016-09-29 14:14 ` Slawomir Mrozowicz 2016-09-29 14:14 ` [dpdk-dev] [PATCH v3 2/3] app/test: added tests for libcrypto PMD Slawomir Mrozowicz ` (2 subsequent siblings) 3 siblings, 0 replies; 34+ messages in thread From: Slawomir Mrozowicz @ 2016-09-29 14:14 UTC (permalink / raw) To: dev Cc: Slawomir Mrozowicz, Michal Kobylinski, Tomasz Kulasek, Daniel Mrzyglod This code provides the initial implementation of the libcrypto poll mode driver. All cryptography operations are using Openssl library crypto API. Each algorithm uses EVP_ interface from openssl API - which is recommended by Openssl maintainers. This patch adds libcrypto poll mode driver support to librte_cryptodev library. Signed-off-by: Slawomir Mrozowicz <slawomirx.mrozowicz@intel.com> Signed-off-by: Michal Kobylinski <michalx.kobylinski@intel.com> Signed-off-by: Tomasz Kulasek <tomaszx.kulasek@intel.com> Signed-off-by: Daniel Mrzyglod <danielx.t.mrzyglod@intel.com> --- v2: - add gcm crypto cipher and authentication algorithm - rework gmac crypto authentication algorithm v3: - fix pmd according to negative verification tests - change gmac aad max size - update documentation --- MAINTAINERS | 4 + config/common_base | 6 + doc/guides/cryptodevs/index.rst | 1 + doc/guides/cryptodevs/libcrypto.rst | 116 +++ doc/guides/rel_notes/release_16_11.rst | 23 +- drivers/crypto/Makefile | 1 + drivers/crypto/libcrypto/Makefile | 60 ++ drivers/crypto/libcrypto/rte_libcrypto_pmd.c | 1051 ++++++++++++++++++++ drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c | 708 +++++++++++++ .../crypto/libcrypto/rte_libcrypto_pmd_private.h | 174 ++++ .../crypto/libcrypto/rte_pmd_libcrypto_version.map | 3 + lib/librte_cryptodev/rte_cryptodev.h | 3 + mk/rte.app.mk | 19 +- 13 files changed, 2159 insertions(+), 10 deletions(-) create mode 100644 doc/guides/cryptodevs/libcrypto.rst create mode 100644 drivers/crypto/libcrypto/Makefile create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd.c create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h create mode 100644 drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map diff --git a/MAINTAINERS b/MAINTAINERS index 7c33ad4..0982aef 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -434,6 +434,10 @@ M: Declan Doherty <declan.doherty@intel.com> F: drivers/crypto/null/ F: doc/guides/cryptodevs/null.rst +LibCrypto Crypto PMD +M: Declan Doherty <declan.doherty@intel.com> +F: drivers/crypto/libcrypto/ +F: doc/guides/cryptodevs/libcrypto.rst Packet processing ----------------- diff --git a/config/common_base b/config/common_base index 7830535..42d28dd 100644 --- a/config/common_base +++ b/config/common_base @@ -376,6 +376,12 @@ CONFIG_RTE_LIBRTE_PMD_AESNI_MB=n CONFIG_RTE_LIBRTE_PMD_AESNI_MB_DEBUG=n # +# Compile PMD for Software backed device +# +CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO=n +CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO_DEBUG=n + +# # Compile PMD for AESNI GCM device # CONFIG_RTE_LIBRTE_PMD_AESNI_GCM=n diff --git a/doc/guides/cryptodevs/index.rst b/doc/guides/cryptodevs/index.rst index 9616de1..adb6e98c 100644 --- a/doc/guides/cryptodevs/index.rst +++ b/doc/guides/cryptodevs/index.rst @@ -39,6 +39,7 @@ Crypto Device Drivers aesni_mb aesni_gcm kasumi + libcrypto null snow3g qat diff --git a/doc/guides/cryptodevs/libcrypto.rst b/doc/guides/cryptodevs/libcrypto.rst new file mode 100644 index 0000000..77eff95 --- /dev/null +++ b/doc/guides/cryptodevs/libcrypto.rst @@ -0,0 +1,116 @@ +.. 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. + +LibCrypto Crypto Poll Mode Driver + +This code provides the initial implementation of the libcrypto poll mode +driver. All cryptography operations are using Openssl library crypto API. +Each algorithm uses EVP_ interface from openssl API - which is recommended +by Openssl maintainers. + +For more details about openssl library please visit openssl webpage: +https://www.openssl.org/ + +Features +-------- + +LibCrypto PMD has support for: + +Supported cipher algorithms: +* ``RTE_CRYPTO_CIPHER_3DES_CBC`` +* ``RTE_CRYPTO_CIPHER_AES_CBC`` +* ``RTE_CRYPTO_CIPHER_AES_CTR`` +* ``RTE_CRYPTO_CIPHER_3DES_CTR`` +* ``RTE_CRYPTO_CIPHER_AES_GCM`` + +Supported authentication algorithms: +* ``RTE_CRYPTO_AUTH_AES_GMAC`` +* ``RTE_CRYPTO_AUTH_MD5`` +* ``RTE_CRYPTO_AUTH_SHA1`` +* ``RTE_CRYPTO_AUTH_SHA224`` +* ``RTE_CRYPTO_AUTH_SHA256`` +* ``RTE_CRYPTO_AUTH_SHA384`` +* ``RTE_CRYPTO_AUTH_SHA512`` +* ``RTE_CRYPTO_AUTH_MD5_HMAC`` +* ``RTE_CRYPTO_AUTH_SHA1_HMAC`` +* ``RTE_CRYPTO_AUTH_SHA224_HMAC`` +* ``RTE_CRYPTO_AUTH_SHA256_HMAC`` +* ``RTE_CRYPTO_AUTH_SHA384_HMAC`` +* ``RTE_CRYPTO_AUTH_SHA512_HMAC`` + + +Installation +------------ + +To compile libcrypto PMD, it has to be enabled in the config/common_base file +and appropriate openssl packages have to be installed in the build environment. + +The newest openssl library version is supported: +* 1.0.2h-fips 3 May 2016. +Older versions that were also verified: +* 1.0.1f 6 Jan 2014 +* 1.0.1 14 Mar 2012 + +For Ubuntu 14.04 LTS these packages have to be installed in the build system: +sudo apt-get install openssl +sudo apt-get install libc6-dev-i386 (for i686-native-linuxapp-gcc target) + +This code was also verified on Fedora 24. +This code was NOT yet verified on FreeBSD. + +Initialization +-------------- + +User can use app/test application to check how to use this pmd and to verify +crypto processing. + +Test name is cryptodev_libcrypto_autotest. +For performance test cryptodev_libcrypto_perftest can be used. + +To verify real traffic l2fwd-crypto example can be used with this command: + +.. code-block:: console + +sudo ./build/l2fwd-crypto -c 0x3 -n 4 --vdev "cryptodev_libcrypto_pmd" +--vdev "cryptodev_libcrypto_pmd"-- -p 0x3 --chain CIPHER_HASH +--cipher_op ENCRYPT --cipher_algo AES_CBC +--cipher_key 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f +--iv 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:ff +--auth_op GENERATE --auth_algo SHA1_HMAC +--auth_key 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11 +:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11 +:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11 + +Limitations +----------- + +* Maximum number of sessions is 2048. +* Chained mbufs are not supported. +* Hash only is not supported for GCM and GMAC. +* Cipher only is not supported for GCM and GMAC. diff --git a/doc/guides/rel_notes/release_16_11.rst b/doc/guides/rel_notes/release_16_11.rst index cc507a9..6e92966 100644 --- a/doc/guides/rel_notes/release_16_11.rst +++ b/doc/guides/rel_notes/release_16_11.rst @@ -34,7 +34,28 @@ New Features Refer to the previous release notes for examples. - This section is a comment. Make sure to start the actual text at the margin. +* **Added libcrypto PMD.** + + A new crypto PMD has been added, which provides several ciphering and hashing. + All cryptography operations are using Openssl library crypto API. + +* ** Added support of C3xxx Device in QAT PMD.** + Support for Device c3xxx has been enabled in QAT PMD. + +* ** Added support of C62XX Device in QAT PMD.** + Support for Device c62xx has been enabled in QAT PMD. + + +* **Updated the QAT PMD.** + The QAT PMD was updated with changes including the following: + + * Added support for MD5_HMAC algorithm. + * Added support for SHA224-HMAC algorithm. + * Added support for SHA384-HMAC algorithm. + * Added support for NULL algorithm. + * Added support for KASUMI (F8 and F9) algorithm. + * Added support for GMAC algorithm. + * Added support for 3DES block cipher algorithm. * ** Added support of C3xxx Device in QAT PMD.** Support for Device c3xxx has been enabled in QAT PMD. diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index dc4ef7f..11b0863 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -33,6 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += aesni_gcm DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += aesni_mb +DIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += libcrypto DIRS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += qat DIRS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += snow3g DIRS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI) += kasumi diff --git a/drivers/crypto/libcrypto/Makefile b/drivers/crypto/libcrypto/Makefile new file mode 100644 index 0000000..c5f8cf2 --- /dev/null +++ b/drivers/crypto/libcrypto/Makefile @@ -0,0 +1,60 @@ +# 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 + +# library name +LIB = librte_pmd_libcrypto.a + +# build flags +CFLAGS += -O3 +CFLAGS += $(WERROR_FLAGS) + +# library version +LIBABIVER := 1 + +# versioning export map +EXPORT_MAP := rte_pmd_libcrypto_version.map + +# external library dependencies +LDLIBS += -lcrypto + +# library source files +SRCS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += rte_libcrypto_pmd.c +SRCS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += rte_libcrypto_pmd_ops.c + +# library dependencies +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_eal +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_mbuf +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_mempool +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_ring +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_cryptodev + +include $(RTE_SDK)/mk/rte.lib.mk diff --git a/drivers/crypto/libcrypto/rte_libcrypto_pmd.c b/drivers/crypto/libcrypto/rte_libcrypto_pmd.c new file mode 100644 index 0000000..d9a60d0 --- /dev/null +++ b/drivers/crypto/libcrypto/rte_libcrypto_pmd.c @@ -0,0 +1,1051 @@ +/*- + * 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_common.h> +#include <rte_hexdump.h> +#include <rte_cryptodev.h> +#include <rte_cryptodev_pmd.h> +#include <rte_dev.h> +#include <rte_malloc.h> +#include <rte_cpuflags.h> + +#include <openssl/evp.h> + +#include "rte_libcrypto_pmd_private.h" + +static int cryptodev_libcrypto_uninit(const char *name); + +/*----------------------------------------------------------------------------*/ + +/** + * Global static parameter used to create a unique name for each + * LIBCRYPTO crypto device. + */ +static unsigned int unique_name_id; + +static inline int +create_unique_device_name(char *name, size_t size) +{ + int ret; + + if (name == NULL) + return -EINVAL; + + ret = snprintf(name, size, "%s_%u", RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), + unique_name_id++); + if (ret < 0) + return ret; + return 0; +} + +/** + * Increment counter by 1 + * Counter is 64 bit array, big-endian + */ +static void +ctr_inc(uint8_t *ctr) +{ + uint64_t *ctr64 = (uint64_t *)ctr; + + *ctr64 = __builtin_bswap64(*ctr64); + (*ctr64)++; + *ctr64 = __builtin_bswap64(*ctr64); +} + +/* + *------------------------------------------------------------------------------ + * Session Prepare + *------------------------------------------------------------------------------ + */ + +/** Get xform chain order */ +static enum libcrypto_chain_order +libcrypto_get_chain_order(const struct rte_crypto_sym_xform *xform) +{ + enum libcrypto_chain_order res = LIBCRYPTO_CHAIN_NOT_SUPPORTED; + + if (xform != NULL) { + if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) { + if (xform->next == NULL) + res = LIBCRYPTO_CHAIN_ONLY_AUTH; + else if (xform->next->type == + RTE_CRYPTO_SYM_XFORM_CIPHER) + res = LIBCRYPTO_CHAIN_AUTH_CIPHER; + } + if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) { + if (xform->next == NULL) + res = LIBCRYPTO_CHAIN_ONLY_CIPHER; + else if (xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH) + res = LIBCRYPTO_CHAIN_CIPHER_AUTH; + } + } + + return res; +} + +/** Get session cipher key from input cipher key */ +static void +get_cipher_key(uint8_t *input_key, int keylen, uint8_t *session_key) +{ + memcpy(session_key, input_key, keylen); +} + +/** Get key ede 24 bytes standard from input key */ +static int +get_cipher_key_ede(uint8_t *key, int keylen, uint8_t *key_ede) +{ + int res = 0; + + /* Initialize keys - 24 bytes: [key1-key2-key3] */ + switch (keylen) { + case 24: + memcpy(key_ede, key, 24); + break; + case 16: + /* K3 = K1 */ + memcpy(key_ede, key, 16); + memcpy(key_ede + 16, key, 8); + break; + case 8: + /* K1 = K2 = K3 (DES compatibility) */ + memcpy(key_ede, key, 8); + memcpy(key_ede + 8, key, 8); + memcpy(key_ede + 16, key, 8); + break; + default: + LIBCRYPTO_LOG_ERR("Unsupported key size"); + res = -EINVAL; + } + + return res; +} + +/** Get adequate libcrypto function for input cipher algorithm */ +static uint8_t +get_cipher_algo(enum rte_crypto_cipher_algorithm sess_algo, size_t keylen, + const EVP_CIPHER **algo) +{ + int res = 0; + + if (algo != NULL) { + switch (sess_algo) { + case RTE_CRYPTO_CIPHER_3DES_CBC: + switch (keylen) { + case 16: + *algo = EVP_des_ede_cbc(); + break; + case 24: + *algo = EVP_des_ede3_cbc(); + break; + default: + res = -EINVAL; + } + break; + case RTE_CRYPTO_CIPHER_3DES_CTR: + break; + case RTE_CRYPTO_CIPHER_AES_CBC: + switch (keylen) { + case 16: + *algo = EVP_aes_128_cbc(); + break; + case 24: + *algo = EVP_aes_192_cbc(); + break; + case 32: + *algo = EVP_aes_256_cbc(); + break; + default: + res = -EINVAL; + } + break; + case RTE_CRYPTO_CIPHER_AES_CTR: + switch (keylen) { + case 16: + *algo = EVP_aes_128_ctr(); + break; + case 24: + *algo = EVP_aes_192_ctr(); + break; + case 32: + *algo = EVP_aes_256_ctr(); + break; + default: + res = -EINVAL; + } + break; + case RTE_CRYPTO_CIPHER_AES_GCM: + switch (keylen) { + case 16: + *algo = EVP_aes_128_gcm(); + break; + case 24: + *algo = EVP_aes_192_gcm(); + break; + case 32: + *algo = EVP_aes_256_gcm(); + break; + default: + res = -EINVAL; + } + break; + default: + res = -EINVAL; + break; + } + } else { + res = -EINVAL; + } + + return res; +} + +/** Get adequate libcrypto function for input auth algorithm */ +static uint8_t +get_auth_algo(enum rte_crypto_auth_algorithm sessalgo, + const EVP_MD **algo) +{ + int res = 0; + + if (algo != NULL) { + switch (sessalgo) { + case RTE_CRYPTO_AUTH_MD5: + case RTE_CRYPTO_AUTH_MD5_HMAC: + *algo = EVP_md5(); + break; + case RTE_CRYPTO_AUTH_SHA1: + case RTE_CRYPTO_AUTH_SHA1_HMAC: + *algo = EVP_sha1(); + break; + case RTE_CRYPTO_AUTH_SHA224: + case RTE_CRYPTO_AUTH_SHA224_HMAC: + *algo = EVP_sha224(); + break; + case RTE_CRYPTO_AUTH_SHA256: + case RTE_CRYPTO_AUTH_SHA256_HMAC: + *algo = EVP_sha256(); + break; + case RTE_CRYPTO_AUTH_SHA384: + case RTE_CRYPTO_AUTH_SHA384_HMAC: + *algo = EVP_sha384(); + break; + case RTE_CRYPTO_AUTH_SHA512: + case RTE_CRYPTO_AUTH_SHA512_HMAC: + *algo = EVP_sha512(); + break; + default: + res = -EINVAL; + break; + } + } else { + res = -EINVAL; + } + + return res; +} + +/** Set session cipher parameters */ +static int +libcrypto_set_session_cipher_parameters(struct libcrypto_session *sess, + const struct rte_crypto_sym_xform *xform) +{ + /* Select cipher direction */ + sess->cipher.direction = xform->cipher.op; + /* Select cipher key */ + sess->cipher.key.length = xform->cipher.key.length; + + /* Select cipher algo */ + switch (xform->cipher.algo) { + case RTE_CRYPTO_CIPHER_3DES_CBC: + case RTE_CRYPTO_CIPHER_AES_CBC: + case RTE_CRYPTO_CIPHER_AES_CTR: + case RTE_CRYPTO_CIPHER_AES_GCM: + sess->cipher.mode = LIBCRYPTO_CIPHER_LIB; + sess->cipher.algo = xform->cipher.algo; + sess->cipher.ctx = EVP_CIPHER_CTX_new(); + + if (get_cipher_algo(sess->cipher.algo, sess->cipher.key.length, + &sess->cipher.evp_algo) != 0) + return -EINVAL; + + get_cipher_key(xform->cipher.key.data, sess->cipher.key.length, + sess->cipher.key.data); + + break; + + case RTE_CRYPTO_CIPHER_3DES_CTR: + sess->cipher.mode = LIBCRYPTO_CIPHER_DES3CTR; + sess->cipher.ctx = EVP_CIPHER_CTX_new(); + + if (get_cipher_key_ede(xform->cipher.key.data, + sess->cipher.key.length, sess->cipher.key.data) != 0) + return -EINVAL; + break; + + default: + sess->cipher.algo = RTE_CRYPTO_CIPHER_NULL; + return -EINVAL; + } + + return 0; +} + +/* Set session auth parameters */ +static int +libcrypto_set_session_auth_parameters(struct libcrypto_session *sess, + const struct rte_crypto_sym_xform *xform) +{ + /* Select auth generate/verify */ + sess->auth.operation = xform->auth.op; + sess->auth.algo = xform->auth.algo; + + /* Select auth algo */ + switch (xform->auth.algo) { + case RTE_CRYPTO_AUTH_AES_GMAC: + case RTE_CRYPTO_AUTH_AES_GCM: + /* Check additional condition for AES_GMAC/GCM */ + if (sess->cipher.algo != RTE_CRYPTO_CIPHER_AES_GCM) + return -EINVAL; + sess->chain_order = LIBCRYPTO_CHAIN_COMBINED; + break; + + case RTE_CRYPTO_AUTH_MD5: + case RTE_CRYPTO_AUTH_SHA1: + case RTE_CRYPTO_AUTH_SHA224: + case RTE_CRYPTO_AUTH_SHA256: + case RTE_CRYPTO_AUTH_SHA384: + case RTE_CRYPTO_AUTH_SHA512: + sess->auth.mode = LIBCRYPTO_AUTH_AS_AUTH; + if (get_auth_algo(xform->auth.algo, &sess->auth.auth.evp_algo) != 0) + return -EINVAL; + sess->auth.auth.ctx = EVP_MD_CTX_create(); + break; + + case RTE_CRYPTO_AUTH_MD5_HMAC: + case RTE_CRYPTO_AUTH_SHA1_HMAC: + case RTE_CRYPTO_AUTH_SHA224_HMAC: + case RTE_CRYPTO_AUTH_SHA256_HMAC: + case RTE_CRYPTO_AUTH_SHA384_HMAC: + case RTE_CRYPTO_AUTH_SHA512_HMAC: + sess->auth.mode = LIBCRYPTO_AUTH_AS_HMAC; + sess->auth.hmac.ctx = EVP_MD_CTX_create(); + if (get_auth_algo(xform->auth.algo, &sess->auth.hmac.evp_algo) != 0) + return -EINVAL; + sess->auth.hmac.pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, + xform->auth.key.data, xform->auth.key.length); + break; + + default: + return -EINVAL; + } + + return 0; +} + +/** Parse crypto xform chain and set private session parameters */ +int +libcrypto_set_session_parameters(struct libcrypto_session *sess, + const struct rte_crypto_sym_xform *xform) +{ + const struct rte_crypto_sym_xform *cipher_xform = NULL; + const struct rte_crypto_sym_xform *auth_xform = NULL; + + sess->chain_order = libcrypto_get_chain_order(xform); + switch (sess->chain_order) { + case LIBCRYPTO_CHAIN_ONLY_CIPHER: + cipher_xform = xform; + break; + case LIBCRYPTO_CHAIN_ONLY_AUTH: + auth_xform = xform; + break; + case LIBCRYPTO_CHAIN_CIPHER_AUTH: + cipher_xform = xform; + auth_xform = xform->next; + break; + case LIBCRYPTO_CHAIN_AUTH_CIPHER: + auth_xform = xform; + cipher_xform = xform->next; + break; + default: + return -EINVAL; + } + + /* cipher_xform must be check before auth_xform */ + if (cipher_xform) { + if (libcrypto_set_session_cipher_parameters(sess, cipher_xform)) { + LIBCRYPTO_LOG_ERR( + "Invalid/unsupported cipher parameters"); + return -EINVAL; + } + } + + if (auth_xform) { + if (libcrypto_set_session_auth_parameters(sess, auth_xform)) { + LIBCRYPTO_LOG_ERR( + "Invalid/unsupported auth parameters"); + return -EINVAL; + } + } + + return 0; +} + +/** Reset private session parameters */ +void +libcrypto_reset_session(struct libcrypto_session *sess) +{ + EVP_CIPHER_CTX_free(sess->cipher.ctx); + + switch (sess->auth.mode) { + case LIBCRYPTO_AUTH_AS_AUTH: + EVP_MD_CTX_destroy(sess->auth.auth.ctx); + break; + case LIBCRYPTO_AUTH_AS_HMAC: + EVP_PKEY_free(sess->auth.hmac.pkey); + EVP_MD_CTX_destroy(sess->auth.hmac.ctx); + break; + default: + break; + } +} + +/** Provide session for operation */ +static struct libcrypto_session * +get_session(struct libcrypto_qp *qp, struct rte_crypto_op *op) +{ + struct libcrypto_session *sess = NULL; + + if (op->sym->sess_type == RTE_CRYPTO_SYM_OP_WITH_SESSION) { + /* get existing session */ + if (likely(op->sym->session != NULL && + op->sym->session->dev_type == + RTE_CRYPTODEV_LIBCRYPTO_PMD)) + sess = (struct libcrypto_session *) + op->sym->session->_private; + } else { + /* provide internal session */ + void *_sess = NULL; + + if (!rte_mempool_get(qp->sess_mp, (void **)&_sess)) { + sess = (struct libcrypto_session *) + ((struct rte_cryptodev_sym_session *)_sess) + ->_private; + + if (unlikely(libcrypto_set_session_parameters( + sess, op->sym->xform) != 0)) { + rte_mempool_put(qp->sess_mp, _sess); + sess = NULL; + } else + op->sym->session = _sess; + } + } + + if (sess == NULL) + op->status = RTE_CRYPTO_OP_STATUS_INVALID_SESSION; + + return sess; +} + +/* + *------------------------------------------------------------------------------ + * Process Operations + *------------------------------------------------------------------------------ + */ + +/** Process standard libcrypto cipher encryption */ +static int +process_libcrypto_cipher_encrypt(uint8_t *src, uint8_t *dst, + uint8_t *iv, uint8_t *key, int srclen, + EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo) +{ + int dstlen, totlen; + + if (EVP_EncryptInit_ex(ctx, algo, NULL, key, iv) <= 0) + goto process_cipher_encrypt_err; + + if (EVP_EncryptUpdate(ctx, dst, &dstlen, src, srclen) <= 0) + goto process_cipher_encrypt_err; + + if (EVP_EncryptFinal_ex(ctx, dst + dstlen, &totlen) <= 0) + goto process_cipher_encrypt_err; + + return 0; + +process_cipher_encrypt_err: + LIBCRYPTO_LOG_ERR("Process libcrypto cipher encrypt failed"); + return -EINVAL; +} + +/** Process standard libcrypto cipher decryption */ +static int +process_libcrypto_cipher_decrypt(uint8_t *src, uint8_t *dst, + uint8_t *iv, uint8_t *key, int srclen, + EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo) +{ + int dstlen, totlen; + + if (EVP_DecryptInit_ex(ctx, algo, NULL, key, iv) <= 0) + goto process_cipher_decrypt_err; + + if (EVP_CIPHER_CTX_set_padding(ctx, 0) <= 0) + goto process_cipher_decrypt_err; + + if (EVP_DecryptUpdate(ctx, dst, &dstlen, src, srclen) <= 0) + goto process_cipher_decrypt_err; + + if (EVP_DecryptFinal_ex(ctx, dst + dstlen, &totlen) <= 0) + goto process_cipher_decrypt_err; + + return 0; + +process_cipher_decrypt_err: + LIBCRYPTO_LOG_ERR("Process libcrypto cipher decrypt failed"); + return -EINVAL; +} + +/** Process cipher des 3 ctr encryption, decryption algorithm */ +static int +process_libcrypto_cipher_des3ctr(uint8_t *src, uint8_t *dst, + uint8_t *iv, uint8_t *key, int srclen, EVP_CIPHER_CTX *ctx) +{ + uint8_t ebuf[8], ctr[8]; + int unused, n; + + /* We use 3DES encryption also for decryption. + * IV is not important for 3DES ecb + */ + if (EVP_EncryptInit_ex(ctx, EVP_des_ede3_ecb(), NULL, key, NULL) <= 0) + goto process_cipher_des3ctr_err; + + memcpy(ctr, iv, 8); + n = 0; + + while (n < srclen) { + if (n % 8 == 0) { + if (EVP_EncryptUpdate(ctx, (unsigned char *)&ebuf, &unused, + (const unsigned char *)&ctr, 8) <= 0) + goto process_cipher_des3ctr_err; + ctr_inc(ctr); + } + dst[n] = src[n] ^ ebuf[n % 8]; + n++; + } + + return 0; + +process_cipher_des3ctr_err: + LIBCRYPTO_LOG_ERR("Process libcrypto cipher des 3 ede ctr failed"); + return -EINVAL; +} + +/** Process auth/encription aes-gcm algorithm */ +static int +process_libcrypto_auth_encryption_gcm(uint8_t *src, int srclen, + uint8_t *aad, int aadlen, uint8_t *iv, int ivlen, + uint8_t *key, uint8_t *dst, uint8_t *tag, + EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo) +{ + int len = 0, unused = 0; + uint8_t empty[] = {}; + + if (EVP_EncryptInit_ex(ctx, algo, NULL, NULL, NULL) <= 0) + goto process_auth_encryption_gcm_err; + + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, NULL) <= 0) + goto process_auth_encryption_gcm_err; + + if (EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv) <= 0) + goto process_auth_encryption_gcm_err; + + if (aadlen > 0) { + if (EVP_EncryptUpdate(ctx, NULL, &len, aad, aadlen) <= 0) + goto process_auth_encryption_gcm_err; + + /* Workaround open ssl bug in version less then 1.0.1f */ + if (EVP_EncryptUpdate(ctx, empty, &unused, empty, 0) <= 0) + goto process_auth_encryption_gcm_err; + } + + if (srclen > 0) + if (EVP_EncryptUpdate(ctx, dst, &len, src, srclen) <= 0) + goto process_auth_encryption_gcm_err; + + if (EVP_EncryptFinal_ex(ctx, dst + len, &len) <= 0) + goto process_auth_encryption_gcm_err; + + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag) <= 0) + goto process_auth_encryption_gcm_err; + + return 0; + +process_auth_encryption_gcm_err: + LIBCRYPTO_LOG_ERR("Process libcrypto auth encryption gcm failed"); + return -EINVAL; +} + +static int +process_libcrypto_auth_decryption_gcm(uint8_t *src, int srclen, + uint8_t *aad, int aadlen, uint8_t *iv, int ivlen, + uint8_t *key, uint8_t *dst, uint8_t *tag, + EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo) +{ + int len = 0, unused = 0; + uint8_t empty[] = {}; + + if (EVP_DecryptInit_ex(ctx, algo, NULL, NULL, NULL) <= 0) + goto process_auth_decryption_gcm_err; + + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, NULL) <= 0) + goto process_auth_decryption_gcm_err; + + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag) <= 0) + goto process_auth_decryption_gcm_err; + + if (EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv) <= 0) + goto process_auth_decryption_gcm_err; + + if (aadlen > 0) { + if (EVP_DecryptUpdate(ctx, NULL, &len, aad, aadlen) <= 0) + goto process_auth_decryption_gcm_err; + + /* Workaround open ssl bug in version less then 1.0.1f */ + if (EVP_DecryptUpdate(ctx, empty, &unused, empty, 0) <= 0) + goto process_auth_decryption_gcm_err; + } + + if (srclen > 0) + if (EVP_DecryptUpdate(ctx, dst, &len, src, srclen) <= 0) + goto process_auth_decryption_gcm_err; + + if (EVP_DecryptFinal_ex(ctx, dst + len, &len) <= 0) + goto process_auth_decryption_gcm_final_err; + + return 0; + +process_auth_decryption_gcm_err: + LIBCRYPTO_LOG_ERR("Process libcrypto auth decription gcm failed"); + return -EINVAL; + +process_auth_decryption_gcm_final_err: + return -EFAULT; +} + +/** Process standard libcrypto auth algorithms */ +static int +process_libcrypto_auth(uint8_t *src, uint8_t *dst, + __rte_unused uint8_t *iv, __rte_unused EVP_PKEY * pkey, + int srclen, EVP_MD_CTX *ctx, const EVP_MD *algo) +{ + size_t dstlen; + + if (EVP_DigestInit_ex(ctx, algo, NULL) <= 0) + goto process_auth_err; + + if (EVP_DigestUpdate(ctx, (char *)src, srclen) <= 0) + goto process_auth_err; + + if (EVP_DigestFinal_ex(ctx, dst, (unsigned int *)&dstlen) <= 0) + goto process_auth_err; + + return 0; + +process_auth_err: + LIBCRYPTO_LOG_ERR("Process libcrypto auth failed"); + return -EINVAL; +} + +/** Process standard libcrypto auth algorithms with hmac */ +static int +process_libcrypto_auth_hmac(uint8_t *src, uint8_t *dst, + __rte_unused uint8_t *iv, EVP_PKEY *pkey, + int srclen, EVP_MD_CTX *ctx, const EVP_MD *algo) +{ + size_t dstlen; + + if (EVP_DigestSignInit(ctx, NULL, algo, NULL, pkey) <= 0) + goto process_auth_err; + + if (EVP_DigestSignUpdate(ctx, (char *)src, srclen) <= 0) + goto process_auth_err; + + if (EVP_DigestSignFinal(ctx, dst, &dstlen) <= 0) + goto process_auth_err; + + return 0; + +process_auth_err: + LIBCRYPTO_LOG_ERR("Process libcrypto auth failed"); + return -EINVAL; +} + +/*----------------------------------------------------------------------------*/ + +/** Process auth/cipher combined operation */ +static void +process_libcrypto_combined_op + (struct rte_crypto_op *op, struct libcrypto_session *sess, + struct rte_mbuf *mbuf_src, struct rte_mbuf *mbuf_dst) +{ + /* cipher */ + uint8_t *src = NULL, *dst = NULL, *iv, *tag, *aad; + int srclen, ivlen, aadlen, status = -1; + + iv = op->sym->cipher.iv.data; + ivlen = op->sym->cipher.iv.length; + aad = op->sym->auth.aad.data; + aadlen = op->sym->auth.aad.length; + + tag = op->sym->auth.digest.data; + if (tag == NULL) + tag = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *, + op->sym->cipher.data.offset + + op->sym->cipher.data.length); + + if (sess->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) + srclen = 0; + else { + srclen = op->sym->cipher.data.length; + src = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *, + op->sym->cipher.data.offset); + dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *, + op->sym->cipher.data.offset); + } + + if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) + status = process_libcrypto_auth_encryption_gcm( + src, srclen, aad, aadlen, iv, ivlen, + sess->cipher.key.data, dst, tag, + sess->cipher.ctx, sess->cipher.evp_algo); + else + status = process_libcrypto_auth_decryption_gcm( + src, srclen, aad, aadlen, iv, ivlen, + sess->cipher.key.data, dst, tag, + sess->cipher.ctx, sess->cipher.evp_algo); + + if (status != 0) { + if (status == (-EFAULT) && + sess->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY) + op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED; + else + op->status = RTE_CRYPTO_OP_STATUS_ERROR; + } +} + +/** Process cipher operation */ +static void +process_libcrypto_cipher_op + (struct rte_crypto_op *op, struct libcrypto_session *sess, + struct rte_mbuf *mbuf_src, struct rte_mbuf *mbuf_dst) +{ + uint8_t *src, *dst, *iv; + int srclen, status; + + srclen = op->sym->cipher.data.length; + src = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *, + op->sym->cipher.data.offset); + dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *, + op->sym->cipher.data.offset); + + iv = op->sym->cipher.iv.data; + + if (sess->cipher.mode == LIBCRYPTO_CIPHER_LIB) + if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) + status = process_libcrypto_cipher_encrypt(src, dst, iv, + sess->cipher.key.data, srclen, + sess->cipher.ctx, sess->cipher.evp_algo); + else + status = process_libcrypto_cipher_decrypt(src, dst, iv, + sess->cipher.key.data, srclen, + sess->cipher.ctx, sess->cipher.evp_algo); + else + status = process_libcrypto_cipher_des3ctr(src, dst, iv, + sess->cipher.key.data, srclen, sess->cipher.ctx); + + if (status != 0) + op->status = RTE_CRYPTO_OP_STATUS_ERROR; +} + +/** Process auth operation */ +static void +process_libcrypto_auth_op + (struct rte_crypto_op *op, struct libcrypto_session *sess, + struct rte_mbuf *mbuf_src, struct rte_mbuf *mbuf_dst) +{ + uint8_t *src, *dst; + int srclen, status; + + srclen = op->sym->auth.data.length; + src = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *, + op->sym->auth.data.offset); + + if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY) + dst = (uint8_t *)rte_pktmbuf_append(mbuf_src, + op->sym->auth.digest.length); + else { + dst = op->sym->auth.digest.data; + if (dst == NULL) + dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *, + op->sym->auth.data.offset + + op->sym->auth.data.length); + } + + switch (sess->auth.mode) { + case LIBCRYPTO_AUTH_AS_AUTH: + status = process_libcrypto_auth(src, dst, + NULL, NULL, srclen, + sess->auth.auth.ctx, sess->auth.auth.evp_algo); + break; + case LIBCRYPTO_AUTH_AS_HMAC: + status = process_libcrypto_auth_hmac(src, dst, + NULL, sess->auth.hmac.pkey, srclen, + sess->auth.hmac.ctx, sess->auth.hmac.evp_algo); + break; + default: + status = -1; + break; + } + + if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY) { + if (memcmp(dst, op->sym->auth.digest.data, + op->sym->auth.digest.length) != 0) { + op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED; + } + /* Trim area used for digest from mbuf. */ + rte_pktmbuf_trim(mbuf_src, + op->sym->auth.digest.length); + } + + if (status != 0) + op->status = RTE_CRYPTO_OP_STATUS_ERROR; +} + +/** Process crypto operation for mbuf */ +static int +process_op(const struct libcrypto_qp *qp, struct rte_crypto_op *op, + struct libcrypto_session *sess) +{ + struct rte_mbuf *msrc, *mdst; + int retval; + + msrc = op->sym->m_src; + mdst = op->sym->m_dst ? op->sym->m_dst : op->sym->m_src; + + op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED; + + switch (sess->chain_order) { + case LIBCRYPTO_CHAIN_ONLY_CIPHER: + process_libcrypto_cipher_op(op, sess, msrc, mdst); + break; + case LIBCRYPTO_CHAIN_ONLY_AUTH: + process_libcrypto_auth_op(op, sess, msrc, mdst); + break; + case LIBCRYPTO_CHAIN_CIPHER_AUTH: + process_libcrypto_cipher_op(op, sess, msrc, mdst); + process_libcrypto_auth_op(op, sess, mdst, mdst); + break; + case LIBCRYPTO_CHAIN_AUTH_CIPHER: + process_libcrypto_auth_op(op, sess, msrc, mdst); + process_libcrypto_cipher_op(op, sess, msrc, mdst); + break; + case LIBCRYPTO_CHAIN_COMBINED: + process_libcrypto_combined_op(op, sess, msrc, mdst); + break; + default: + op->status = RTE_CRYPTO_OP_STATUS_ERROR; + break; + } + + /* Free session if a session-less crypto op */ + if (op->sym->sess_type == RTE_CRYPTO_SYM_OP_SESSIONLESS) { + libcrypto_reset_session(sess); + memset(sess, 0, sizeof(struct libcrypto_session)); + rte_mempool_put(qp->sess_mp, op->sym->session); + op->sym->session = NULL; + } + + + if (op->status == RTE_CRYPTO_OP_STATUS_NOT_PROCESSED) + op->status = RTE_CRYPTO_OP_STATUS_SUCCESS; + + if (op->status != RTE_CRYPTO_OP_STATUS_ERROR) + retval = rte_ring_enqueue(qp->processed_ops, (void *)op); + else + retval = -1; + + return retval; +} + +/* + *------------------------------------------------------------------------------ + * PMD Framework + *------------------------------------------------------------------------------ + */ + +/** Enqueue burst */ +static uint16_t +libcrypto_pmd_enqueue_burst(void *queue_pair, struct rte_crypto_op **ops, + uint16_t nb_ops) +{ + struct libcrypto_session *sess; + struct libcrypto_qp *qp = queue_pair; + int i, retval; + + for (i = 0; i < nb_ops; i++) { + sess = get_session(qp, ops[i]); + if (unlikely(sess == NULL)) + goto enqueue_err; + + retval = process_op(qp, ops[i], sess); + if (unlikely(retval < 0)) + goto enqueue_err; + } + + qp->stats.enqueued_count += i; + return i; + +enqueue_err: + qp->stats.enqueue_err_count++; + return i; +} + +/** Dequeue burst */ +static uint16_t +libcrypto_pmd_dequeue_burst(void *queue_pair, struct rte_crypto_op **ops, + uint16_t nb_ops) +{ + struct libcrypto_qp *qp = queue_pair; + + unsigned int nb_dequeued = 0; + + nb_dequeued = rte_ring_dequeue_burst(qp->processed_ops, + (void **)ops, nb_ops); + qp->stats.dequeued_count += nb_dequeued; + + return nb_dequeued; +} + +/** Create LIBCRYPTO crypto device */ +static int +cryptodev_libcrypto_create(const char *name, + struct rte_crypto_vdev_init_params *init_params) +{ + struct rte_cryptodev *dev; + char crypto_dev_name[RTE_CRYPTODEV_NAME_MAX_LEN]; + struct libcrypto_private *internals; + + /* create a unique device name */ + if (create_unique_device_name(crypto_dev_name, + RTE_CRYPTODEV_NAME_MAX_LEN) != 0) { + LIBCRYPTO_LOG_ERR("failed to create unique cryptodev name"); + return -EINVAL; + } + + dev = rte_cryptodev_pmd_virtual_dev_init(crypto_dev_name, + sizeof(struct libcrypto_private), init_params->socket_id); + if (dev == NULL) { + LIBCRYPTO_LOG_ERR("failed to create cryptodev vdev"); + goto init_error; + } + + dev->dev_type = RTE_CRYPTODEV_LIBCRYPTO_PMD; + dev->dev_ops = rte_libcrypto_pmd_ops; + + /* register rx/tx burst functions for data path */ + dev->dequeue_burst = libcrypto_pmd_dequeue_burst; + dev->enqueue_burst = libcrypto_pmd_enqueue_burst; + + dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO | + RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING | + RTE_CRYPTODEV_FF_CPU_AESNI; + + /* Set vector instructions mode supported */ + internals = dev->data->dev_private; + + internals->max_nb_qpairs = init_params->max_nb_queue_pairs; + internals->max_nb_sessions = init_params->max_nb_sessions; + + return 0; + +init_error: + LIBCRYPTO_LOG_ERR("driver %s: cryptodev_libcrypto_create failed", name); + + cryptodev_libcrypto_uninit(crypto_dev_name); + return -EFAULT; +} + +/** Initialise LIBCRYPTO crypto device */ +static int +cryptodev_libcrypto_init(const char *name, + const char *input_args) +{ + struct rte_crypto_vdev_init_params init_params = { + RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_QUEUE_PAIRS, + RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_SESSIONS, + rte_socket_id() + }; + + rte_cryptodev_parse_vdev_init_params(&init_params, input_args); + + RTE_LOG(INFO, PMD, "Initialising %s on NUMA node %d\n", name, + init_params.socket_id); + RTE_LOG(INFO, PMD, " Max number of queue pairs = %d\n", + init_params.max_nb_queue_pairs); + RTE_LOG(INFO, PMD, " Max number of sessions = %d\n", + init_params.max_nb_sessions); + + return cryptodev_libcrypto_create(name, &init_params); +} + +/** Uninitialise LIBCRYPTO crypto device */ +static int +cryptodev_libcrypto_uninit(const char *name) +{ + if (name == NULL) + return -EINVAL; + + RTE_LOG(INFO, PMD, + "Closing LIBCRYPTO crypto device %s on numa socket %u\n", + name, rte_socket_id()); + + return 0; +} + +static struct rte_driver cryptodev_libcrypto_pmd_drv = { + .type = PMD_VDEV, + .init = cryptodev_libcrypto_init, + .uninit = cryptodev_libcrypto_uninit +}; + +PMD_REGISTER_DRIVER(cryptodev_libcrypto_pmd_drv, CRYPTODEV_NAME_LIBCRYPTO_PMD); +DRIVER_REGISTER_PARAM_STRING(CRYPTODEV_NAME_LIBCRYPTO_PMD, + "max_nb_queue_pairs=<int> " + "max_nb_sessions=<int> " + "socket_id=<int>"); diff --git a/drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c b/drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c new file mode 100644 index 0000000..b5d7bd5 --- /dev/null +++ b/drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c @@ -0,0 +1,708 @@ +/*- + * 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 <string.h> + +#include <rte_common.h> +#include <rte_malloc.h> +#include <rte_cryptodev_pmd.h> + +#include "rte_libcrypto_pmd_private.h" + + +static const struct rte_cryptodev_capabilities libcrypto_pmd_capabilities[] = { + { /* MD5 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_MD5_HMAC, + .block_size = 64, + .key_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .digest_size = { + .min = 16, + .max = 16, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* MD5 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_MD5, + .block_size = 64, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 16, + .max = 16, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA1 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .block_size = 64, + .key_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .digest_size = { + .min = 20, + .max = 20, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA1 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA1, + .block_size = 64, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 20, + .max = 20, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA224 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA224_HMAC, + .block_size = 64, + .key_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .digest_size = { + .min = 28, + .max = 28, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA224 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA224, + .block_size = 64, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 28, + .max = 28, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA256 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA256_HMAC, + .block_size = 64, + .key_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .digest_size = { + .min = 32, + .max = 32, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA256 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA256, + .block_size = 64, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 32, + .max = 32, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA384 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA384_HMAC, + .block_size = 128, + .key_size = { + .min = 128, + .max = 128, + .increment = 0 + }, + .digest_size = { + .min = 48, + .max = 48, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA384 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA384, + .block_size = 128, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 48, + .max = 48, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA512 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA512_HMAC, + .block_size = 128, + .key_size = { + .min = 128, + .max = 128, + .increment = 0 + }, + .digest_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA512 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA512, + .block_size = 128, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* AES CBC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, + {.cipher = { + .algo = RTE_CRYPTO_CIPHER_AES_CBC, + .block_size = 16, + .key_size = { + .min = 16, + .max = 32, + .increment = 8 + }, + .iv_size = { + .min = 16, + .max = 16, + .increment = 0 + } + }, } + }, } + }, + { /* AES CTR */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, + {.cipher = { + .algo = RTE_CRYPTO_CIPHER_AES_CTR, + .block_size = 16, + .key_size = { + .min = 16, + .max = 32, + .increment = 8 + }, + .iv_size = { + .min = 16, + .max = 16, + .increment = 0 + } + }, } + }, } + }, + { /* AES GCM (AUTH) */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_AES_GCM, + .block_size = 16, + .key_size = { + .min = 16, + .max = 32, + .increment = 8 + }, + .digest_size = { + .min = 16, + .max = 16, + .increment = 0 + }, + .aad_size = { + .min = 8, + .max = 12, + .increment = 4 + } + }, } + }, } + }, + { /* AES GCM (CIPHER) */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, + {.cipher = { + .algo = RTE_CRYPTO_CIPHER_AES_GCM, + .block_size = 16, + .key_size = { + .min = 16, + .max = 16, + .increment = 0 + }, + .iv_size = { + .min = 12, + .max = 16, + .increment = 4 + } + }, } + }, } + }, + { /* AES GMAC (AUTH) */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_AES_GMAC, + .block_size = 16, + .key_size = { + .min = 16, + .max = 32, + .increment = 8 + }, + .digest_size = { + .min = 16, + .max = 16, + .increment = 0 + }, + .aad_size = { + .min = 8, + .max = 65532, + .increment = 4 + } + }, } + }, } + }, + { /* 3DES CBC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, + {.cipher = { + .algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .block_size = 8, + .key_size = { + .min = 16, + .max = 24, + .increment = 8 + }, + .iv_size = { + .min = 8, + .max = 8, + .increment = 0 + } + }, } + }, } + }, + { /* 3DES CTR */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, + {.cipher = { + .algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .block_size = 8, + .key_size = { + .min = 16, + .max = 24, + .increment = 8 + }, + .iv_size = { + .min = 8, + .max = 8, + .increment = 0 + } + }, } + }, } + }, + + RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST() +}; + + +/** Configure device */ +static int +libcrypto_pmd_config(__rte_unused struct rte_cryptodev *dev) +{ + return 0; +} + +/** Start device */ +static int +libcrypto_pmd_start(__rte_unused struct rte_cryptodev *dev) +{ + return 0; +} + +/** Stop device */ +static void +libcrypto_pmd_stop(__rte_unused struct rte_cryptodev *dev) +{ +} + +/** Close device */ +static int +libcrypto_pmd_close(__rte_unused struct rte_cryptodev *dev) +{ + return 0; +} + + +/** Get device statistics */ +static void +libcrypto_pmd_stats_get(struct rte_cryptodev *dev, + struct rte_cryptodev_stats *stats) +{ + int qp_id; + + for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) { + struct libcrypto_qp *qp = dev->data->queue_pairs[qp_id]; + + stats->enqueued_count += qp->stats.enqueued_count; + stats->dequeued_count += qp->stats.dequeued_count; + + stats->enqueue_err_count += qp->stats.enqueue_err_count; + stats->dequeue_err_count += qp->stats.dequeue_err_count; + } +} + +/** Reset device statistics */ +static void +libcrypto_pmd_stats_reset(struct rte_cryptodev *dev) +{ + int qp_id; + + for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) { + struct libcrypto_qp *qp = dev->data->queue_pairs[qp_id]; + + memset(&qp->stats, 0, sizeof(qp->stats)); + } +} + + +/** Get device info */ +static void +libcrypto_pmd_info_get(struct rte_cryptodev *dev, + struct rte_cryptodev_info *dev_info) +{ + struct libcrypto_private *internals = dev->data->dev_private; + + if (dev_info != NULL) { + dev_info->dev_type = dev->dev_type; + dev_info->feature_flags = dev->feature_flags; + dev_info->capabilities = libcrypto_pmd_capabilities; + dev_info->max_nb_queue_pairs = internals->max_nb_qpairs; + dev_info->sym.max_nb_sessions = internals->max_nb_sessions; + } +} + +/** Release queue pair */ +static int +libcrypto_pmd_qp_release(struct rte_cryptodev *dev, uint16_t qp_id) +{ + if (dev->data->queue_pairs[qp_id] != NULL) { + rte_free(dev->data->queue_pairs[qp_id]); + dev->data->queue_pairs[qp_id] = NULL; + } + return 0; +} + +/** set a unique name for the queue pair based on it's name, dev_id and qp_id */ +static int +libcrypto_pmd_qp_set_unique_name(struct rte_cryptodev *dev, + struct libcrypto_qp *qp) +{ + unsigned int n = snprintf(qp->name, sizeof(qp->name), + "libcrypto_pmd_%u_qp_%u", + dev->data->dev_id, qp->id); + + if (n > sizeof(qp->name)) + return -1; + + return 0; +} + + +/** Create a ring to place processed operations on */ +static struct rte_ring * +libcrypto_pmd_qp_create_processed_ops_ring(struct libcrypto_qp *qp, + unsigned int ring_size, int socket_id) +{ + struct rte_ring *r; + + r = rte_ring_lookup(qp->name); + if (r) { + if (r->prod.size >= ring_size) { + LIBCRYPTO_LOG_INFO( + "Reusing existing ring %s for processed ops", + qp->name); + return r; + } + + LIBCRYPTO_LOG_ERR( + "Unable to reuse existing ring %s for processed ops", + qp->name); + return NULL; + } + + return rte_ring_create(qp->name, ring_size, socket_id, + RING_F_SP_ENQ | RING_F_SC_DEQ); +} + + +/** Setup a queue pair */ +static int +libcrypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id, + const struct rte_cryptodev_qp_conf *qp_conf, + int socket_id) +{ + struct libcrypto_qp *qp = NULL; + + /* Free memory prior to re-allocation if needed. */ + if (dev->data->queue_pairs[qp_id] != NULL) + libcrypto_pmd_qp_release(dev, qp_id); + + /* Allocate the queue pair data structure. */ + qp = rte_zmalloc_socket("LIBCRYPTO PMD Queue Pair", sizeof(*qp), + RTE_CACHE_LINE_SIZE, socket_id); + if (qp == NULL) + return -ENOMEM; + + qp->id = qp_id; + dev->data->queue_pairs[qp_id] = qp; + + if (libcrypto_pmd_qp_set_unique_name(dev, qp)) + goto qp_setup_cleanup; + + qp->processed_ops = libcrypto_pmd_qp_create_processed_ops_ring(qp, + qp_conf->nb_descriptors, socket_id); + if (qp->processed_ops == NULL) + goto qp_setup_cleanup; + + qp->sess_mp = dev->data->session_pool; + + memset(&qp->stats, 0, sizeof(qp->stats)); + + return 0; + +qp_setup_cleanup: + if (qp) + rte_free(qp); + + return -1; +} + +/** Start queue pair */ +static int +libcrypto_pmd_qp_start(__rte_unused struct rte_cryptodev *dev, + __rte_unused uint16_t queue_pair_id) +{ + return -ENOTSUP; +} + +/** Stop queue pair */ +static int +libcrypto_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev, + __rte_unused uint16_t queue_pair_id) +{ + return -ENOTSUP; +} + +/** Return the number of allocated queue pairs */ +static uint32_t +libcrypto_pmd_qp_count(struct rte_cryptodev *dev) +{ + return dev->data->nb_queue_pairs; +} + +/** Returns the size of the session structure */ +static unsigned +libcrypto_pmd_session_get_size(struct rte_cryptodev *dev __rte_unused) +{ + return sizeof(struct libcrypto_session); +} + +/** Configure the session from a crypto xform chain */ +static void * +libcrypto_pmd_session_configure(struct rte_cryptodev *dev __rte_unused, + struct rte_crypto_sym_xform *xform, void *sess) +{ + if (unlikely(sess == NULL)) { + LIBCRYPTO_LOG_ERR("invalid session struct"); + return NULL; + } + + if (libcrypto_set_session_parameters( + sess, xform) != 0) { + LIBCRYPTO_LOG_ERR("failed configure session parameters"); + return NULL; + } + + return sess; +} + + +/** Clear the memory of session so it doesn't leave key material behind */ +static void +libcrypto_pmd_session_clear(struct rte_cryptodev *dev __rte_unused, void *sess) +{ + /* + * Current just resetting the whole data structure, need to investigate + * whether a more selective reset of key would be more performant + */ + if (sess) { + libcrypto_reset_session(sess); + memset(sess, 0, sizeof(struct libcrypto_session)); + } +} + +struct rte_cryptodev_ops libcrypto_pmd_ops = { + .dev_configure = libcrypto_pmd_config, + .dev_start = libcrypto_pmd_start, + .dev_stop = libcrypto_pmd_stop, + .dev_close = libcrypto_pmd_close, + + .stats_get = libcrypto_pmd_stats_get, + .stats_reset = libcrypto_pmd_stats_reset, + + .dev_infos_get = libcrypto_pmd_info_get, + + .queue_pair_setup = libcrypto_pmd_qp_setup, + .queue_pair_release = libcrypto_pmd_qp_release, + .queue_pair_start = libcrypto_pmd_qp_start, + .queue_pair_stop = libcrypto_pmd_qp_stop, + .queue_pair_count = libcrypto_pmd_qp_count, + + .session_get_size = libcrypto_pmd_session_get_size, + .session_configure = libcrypto_pmd_session_configure, + .session_clear = libcrypto_pmd_session_clear +}; + +struct rte_cryptodev_ops *rte_libcrypto_pmd_ops = &libcrypto_pmd_ops; diff --git a/drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h b/drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h new file mode 100644 index 0000000..dbef57f --- /dev/null +++ b/drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h @@ -0,0 +1,174 @@ +/*- + * 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 _LIBCRYPTO_PMD_PRIVATE_H_ +#define _LIBCRYPTO_PMD_PRIVATE_H_ + +#include <openssl/evp.h> +#include <openssl/des.h> + + +#define LIBCRYPTO_LOG_ERR(fmt, args...) \ + RTE_LOG(ERR, CRYPTODEV, "[%s] %s() line %u: " fmt "\n", \ + RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), \ + __func__, __LINE__, ## args) + +#ifdef RTE_LIBRTE_LIBCRYPTO_DEBUG +#define LIBCRYPTO_LOG_INFO(fmt, args...) \ + RTE_LOG(INFO, CRYPTODEV, "[%s] %s() line %u: " fmt "\n", \ + RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), \ + __func__, __LINE__, ## args) + +#define LIBCRYPTO_LOG_DBG(fmt, args...) \ + RTE_LOG(DEBUG, CRYPTODEV, "[%s] %s() line %u: " fmt "\n", \ + RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), \ + __func__, __LINE__, ## args) +#else +#define LIBCRYPTO_LOG_INFO(fmt, args...) +#define LIBCRYPTO_LOG_DBG(fmt, args...) +#endif + + +/** LIBCRYPTO operation order mode enumerator */ +enum libcrypto_chain_order { + LIBCRYPTO_CHAIN_ONLY_CIPHER, + LIBCRYPTO_CHAIN_ONLY_AUTH, + LIBCRYPTO_CHAIN_CIPHER_AUTH, + LIBCRYPTO_CHAIN_AUTH_CIPHER, + LIBCRYPTO_CHAIN_COMBINED, + LIBCRYPTO_CHAIN_NOT_SUPPORTED +}; + +/** LIBCRYPTO cipher mode enumerator */ +enum libcrypto_cipher_mode { + LIBCRYPTO_CIPHER_LIB, + LIBCRYPTO_CIPHER_DES3CTR, +}; + +/** LIBCRYPTO auth mode enumerator */ +enum libcrypto_auth_mode { + LIBCRYPTO_AUTH_AS_AUTH, + LIBCRYPTO_AUTH_AS_HMAC, +}; + +/** private data structure for each LIBCRYPTO crypto device */ +struct libcrypto_private { + unsigned int max_nb_qpairs; + /**< Max number of queue pairs */ + unsigned int max_nb_sessions; + /**< Max number of sessions */ +}; + +/** LIBCRYPTO crypto queue pair */ +struct libcrypto_qp { + uint16_t id; + /**< Queue Pair Identifier */ + char name[RTE_CRYPTODEV_NAME_LEN]; + /**< Unique Queue Pair Name */ + struct rte_ring *processed_ops; + /**< Ring for placing process packets */ + struct rte_mempool *sess_mp; + /**< Session Mempool */ + struct rte_cryptodev_stats stats; + /**< Queue pair statistics */ +} __rte_cache_aligned; + +/** LIBCRYPTO crypto private session structure */ +struct libcrypto_session { + enum libcrypto_chain_order chain_order; + /**< chain order mode */ + + /** Cipher Parameters */ + struct { + enum rte_crypto_cipher_operation direction; + /**< cipher operation direction */ + enum libcrypto_cipher_mode mode; + /**< cipher operation mode */ + enum rte_crypto_cipher_algorithm algo; + /**< cipher algorithm */ + + struct { + uint8_t data[32]; + /**< key data */ + size_t length; + /**< key length in bytes */ + } key; + + const EVP_CIPHER *evp_algo; + /**< pointer to EVP algorithm function */ + EVP_CIPHER_CTX *ctx; + /**< pointer to EVP context structure */ + } cipher; + + /** Authentication Parameters */ + struct { + enum rte_crypto_auth_operation operation; + /**< auth operation generate or verify */ + enum libcrypto_auth_mode mode; + /**< auth operation mode */ + enum rte_crypto_auth_algorithm algo; + /**< cipher algorithm */ + + union { + struct { + const EVP_MD *evp_algo; + /**< pointer to EVP algorithm function */ + EVP_MD_CTX *ctx; + /**< pointer to EVP context structure */ + } auth; + + struct { + EVP_PKEY *pkey; + /**< pointer to EVP key */ + const EVP_MD *evp_algo; + /**< pointer to EVP algorithm function */ + EVP_MD_CTX *ctx; + /**< pointer to EVP context structure */ + } hmac; + }; + } auth; + +} __rte_cache_aligned; + +/** Set and validate LIBCRYPTO crypto session parameters */ +extern int +libcrypto_set_session_parameters(struct libcrypto_session *sess, + const struct rte_crypto_sym_xform *xform); + +/** Reset LIBCRYPTO crypto session parameters */ +extern void +libcrypto_reset_session(struct libcrypto_session *sess); + +/** device specific operations function pointer structure */ +extern struct rte_cryptodev_ops *rte_libcrypto_pmd_ops; + +#endif /* _LIBCRYPTO_PMD_PRIVATE_H_ */ diff --git a/drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map b/drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map new file mode 100644 index 0000000..cc5829e --- /dev/null +++ b/drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map @@ -0,0 +1,3 @@ +DPDK_16.11 { + local: *; +}; diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h index 7fb5f6e..3f0fc2e 100644 --- a/lib/librte_cryptodev/rte_cryptodev.h +++ b/lib/librte_cryptodev/rte_cryptodev.h @@ -56,6 +56,8 @@ extern "C" { /**< AES-NI Multi buffer PMD device name */ #define CRYPTODEV_NAME_AESNI_GCM_PMD crypto_aesni_gcm /**< AES-NI GCM PMD device name */ +#define CRYPTODEV_NAME_LIBCRYPTO_PMD cryptodev_libcrypto +/**< Open SSL Crypto PMD device name */ #define CRYPTODEV_NAME_QAT_SYM_PMD crypto_qat /**< Intel QAT Symmetric Crypto PMD device name */ #define CRYPTODEV_NAME_SNOW3G_PMD crypto_snow3g @@ -71,6 +73,7 @@ enum rte_cryptodev_type { RTE_CRYPTODEV_QAT_SYM_PMD, /**< QAT PMD Symmetric Crypto */ RTE_CRYPTODEV_SNOW3G_PMD, /**< SNOW 3G PMD */ RTE_CRYPTODEV_KASUMI_PMD, /**< KASUMI PMD */ + RTE_CRYPTODEV_LIBCRYPTO_PMD, /**< LibCrypto PMD */ }; extern const char **rte_cyptodev_names; diff --git a/mk/rte.app.mk b/mk/rte.app.mk index 1a0095b..e1b9e64 100644 --- a/mk/rte.app.mk +++ b/mk/rte.app.mk @@ -131,16 +131,17 @@ endif # $(CONFIG_RTE_LIBRTE_VHOST) _LDLIBS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += -lrte_pmd_vmxnet3_uio ifeq ($(CONFIG_RTE_LIBRTE_CRYPTODEV),y) -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -lrte_pmd_aesni_mb -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += -lrte_pmd_aesni_gcm -lcrypto -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -lrte_pmd_aesni_mb +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += -lrte_pmd_aesni_gcm -lcrypto +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += -lrte_pmd_libcrypto -lcrypto _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO) += -lrte_pmd_null_crypto -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += -lrte_pmd_qat -lcrypto -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += -lrte_pmd_snow3g -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += -L$(LIBSSO_SNOW3G_PATH)/build -lsso_snow3g -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI) += -lrte_pmd_kasumi -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI) += -L$(LIBSSO_KASUMI_PATH)/build -lsso_kasumi +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += -lrte_pmd_qat -lcrypto +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += -lrte_pmd_snow3g +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += -L$(LIBSSO_SNOW3G_PATH)/build -lsso_snow3g +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI) += -lrte_pmd_kasumi +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI) += -L$(LIBSSO_KASUMI_PATH)/build -lsso_kasumi endif # CONFIG_RTE_LIBRTE_CRYPTODEV endif # !CONFIG_RTE_BUILD_SHARED_LIBS -- 2.5.0 ^ permalink raw reply [flat|nested] 34+ messages in thread
* [dpdk-dev] [PATCH v3 2/3] app/test: added tests for libcrypto PMD 2016-09-29 14:14 ` [dpdk-dev] [PATCH v3 0/3] new crypto software based device Slawomir Mrozowicz 2016-09-29 14:14 ` [dpdk-dev] [PATCH v3 1/3] libcrypto_pmd: initial implementation of SW crypto device Slawomir Mrozowicz @ 2016-09-29 14:14 ` Slawomir Mrozowicz 2016-09-29 14:39 ` [dpdk-dev] [PATCH v3 3/3] examples/l2fwd-crypto: updated example " Slawomir Mrozowicz 2016-09-30 16:17 ` [dpdk-dev] [PATCH v4 0/5] new crypto software based device Slawomir Mrozowicz 3 siblings, 0 replies; 34+ messages in thread From: Slawomir Mrozowicz @ 2016-09-29 14:14 UTC (permalink / raw) To: dev; +Cc: Slawomir Mrozowicz, Piotr Azarewicz, Marcin Kerlin, Fiona Trahe This patch containes unit tests for libcrypto PMD. User can use app/test application to check how to use this pmd and to verify crypto processing. Test name is cryptodev_libcrypto_autotest. For performance test cryptodev_libcrypto_perftest can be used. Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com> Signed-off-by: Marcin Kerlin <marcinx.kerlin@intel.com> Signed-off-by: Fiona Trahe <fiona.trahe@intel.com> --- v2: - rename AES-named functions to blockcipher - replace different test cases with blockcipher functions pattern - add 3DES tests into QuickAssist PMD testsuite v3: - add nagative verification tests - add big data test - change gmac aad max size --- app/test/Makefile | 2 +- app/test/test_cryptodev.c | 1579 ++++- app/test/test_cryptodev.h | 1 + app/test/test_cryptodev_aes.c | 687 --- app/test/test_cryptodev_aes.h | 1124 ---- app/test/test_cryptodev_aes_test_vectors.h | 1095 ++++ app/test/test_cryptodev_blockcipher.c | 531 ++ app/test/test_cryptodev_blockcipher.h | 125 + app/test/test_cryptodev_des_test_vectors.h | 952 ++++ app/test/test_cryptodev_gcm_test_vectors.h | 8247 ++++++++++++++++++++++++++- app/test/test_cryptodev_hash_test_vectors.h | 491 ++ app/test/test_cryptodev_perf.c | 684 ++- 12 files changed, 13568 insertions(+), 1950 deletions(-) delete mode 100644 app/test/test_cryptodev_aes.c delete mode 100644 app/test/test_cryptodev_aes.h create mode 100644 app/test/test_cryptodev_aes_test_vectors.h create mode 100644 app/test/test_cryptodev_blockcipher.c create mode 100644 app/test/test_cryptodev_blockcipher.h create mode 100644 app/test/test_cryptodev_des_test_vectors.h create mode 100644 app/test/test_cryptodev_hash_test_vectors.h diff --git a/app/test/Makefile b/app/test/Makefile index 611d77a..5be023a 100644 --- a/app/test/Makefile +++ b/app/test/Makefile @@ -193,7 +193,7 @@ endif SRCS-$(CONFIG_RTE_LIBRTE_PMD_RING) += test_pmd_ring.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_RING) += test_pmd_ring_perf.c -SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_aes.c +SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_blockcipher.c SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_perf.c SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev.c diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c index d744b37..4f37403 100644 --- a/app/test/test_cryptodev.c +++ b/app/test/test_cryptodev.c @@ -43,7 +43,10 @@ #include "test.h" #include "test_cryptodev.h" -#include "test_cryptodev_aes.h" +#include "test_cryptodev_blockcipher.h" +#include "test_cryptodev_aes_test_vectors.h" +#include "test_cryptodev_des_test_vectors.h" +#include "test_cryptodev_hash_test_vectors.h" #include "test_cryptodev_kasumi_test_vectors.h" #include "test_cryptodev_kasumi_hash_test_vectors.h" #include "test_cryptodev_snow3g_test_vectors.h" @@ -84,12 +87,16 @@ struct crypto_unittest_params { */ static int test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( - struct crypto_unittest_params *ut_params); + struct crypto_unittest_params *ut_params, uint8_t *cipher_key, + uint8_t *hmac_key); static int test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, struct crypto_unittest_params *ut_params, - struct crypto_testsuite_params *ts_param); + struct crypto_testsuite_params *ts_param, + const uint8_t *cipher, + const uint8_t *digest, + const uint8_t *iv); static struct rte_mbuf * setup_test_string(struct rte_mempool *mpool, @@ -160,7 +167,7 @@ testsuite_setup(void) /* Not already created so create */ ts_params->mbuf_pool = rte_pktmbuf_pool_create( "CRYPTO_MBUFPOOL", - NUM_MBUFS, MBUF_CACHE_SIZE, 0, MBUF_SIZE, + NUM_MBUFS, MBUF_CACHE_SIZE, 0, UINT16_MAX, rte_socket_id()); if (ts_params->mbuf_pool == NULL) { RTE_LOG(ERR, USER1, "Can't create CRYPTO_MBUFPOOL\n"); @@ -197,6 +204,23 @@ testsuite_setup(void) } } + /* Create 2 LIBCRYPTO devices if required */ + if (gbl_cryptodev_type == RTE_CRYPTODEV_LIBCRYPTO_PMD) { + nb_devs = rte_cryptodev_count_devtype( + RTE_CRYPTODEV_LIBCRYPTO_PMD); + if (nb_devs < 2) { + for (i = nb_devs; i < 2; i++) { + ret = rte_eal_vdev_init( + RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), NULL); + + TEST_ASSERT(ret == 0, + "Failed to create instance %u of" + " pmd : %s", + i, RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD)); + } + } + } + /* Create 2 AESNI GCM devices if required */ if (gbl_cryptodev_type == RTE_CRYPTODEV_AESNI_GCM_PMD) { nb_devs = rte_cryptodev_count_devtype( @@ -822,6 +846,314 @@ static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA1_digest[] = { }; +/* Multisession Vector context Test */ +/*Begin Session 0 */ +static uint8_t ms_aes_cbc_key0[] = { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static uint8_t ms_aes_cbc_iv0[] = { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static const uint8_t ms_aes_cbc_cipher0[] = { + 0x3C, 0xE4, 0xEE, 0x42, 0xB6, 0x9B, 0xC3, 0x38, + 0x5F, 0xAD, 0x54, 0xDC, 0xA8, 0x32, 0x81, 0xDC, + 0x7A, 0x6F, 0x85, 0x58, 0x07, 0x35, 0xED, 0xEB, + 0xAD, 0x79, 0x79, 0x96, 0xD3, 0x0E, 0xA6, 0xD9, + 0xAA, 0x86, 0xA4, 0x8F, 0xB5, 0xD6, 0x6E, 0x6D, + 0x0C, 0x91, 0x2F, 0xC4, 0x67, 0x98, 0x0E, 0xC4, + 0x8D, 0x83, 0x68, 0x69, 0xC4, 0xD3, 0x94, 0x34, + 0xC4, 0x5D, 0x60, 0x55, 0x22, 0x87, 0x8F, 0x6F, + 0x17, 0x8E, 0x75, 0xE4, 0x02, 0xF5, 0x1B, 0x99, + 0xC8, 0x39, 0xA9, 0xAB, 0x23, 0x91, 0x12, 0xED, + 0x08, 0xE7, 0xD9, 0x25, 0x89, 0x24, 0x4F, 0x8D, + 0x68, 0xF3, 0x10, 0x39, 0x0A, 0xEE, 0x45, 0x24, + 0xDF, 0x7A, 0x9D, 0x00, 0x25, 0xE5, 0x35, 0x71, + 0x4E, 0x40, 0x59, 0x6F, 0x0A, 0x13, 0xB3, 0x72, + 0x1D, 0x98, 0x63, 0x94, 0x89, 0xA5, 0x39, 0x8E, + 0xD3, 0x9C, 0x8A, 0x7F, 0x71, 0x2F, 0xC7, 0xCD, + 0x81, 0x05, 0xDC, 0xC0, 0x8D, 0xCE, 0x6D, 0x18, + 0x30, 0xC4, 0x72, 0x51, 0xF0, 0x27, 0xC8, 0xF6, + 0x60, 0x5B, 0x7C, 0xB2, 0xE3, 0x49, 0x0C, 0x29, + 0xC6, 0x9F, 0x39, 0x57, 0x80, 0x55, 0x24, 0x2C, + 0x9B, 0x0F, 0x5A, 0xB3, 0x89, 0x55, 0x31, 0x96, + 0x0D, 0xCD, 0xF6, 0x51, 0x03, 0x2D, 0x89, 0x26, + 0x74, 0x44, 0xD6, 0xE8, 0xDC, 0xEA, 0x44, 0x55, + 0x64, 0x71, 0x9C, 0x9F, 0x5D, 0xBA, 0x39, 0x46, + 0xA8, 0x17, 0xA1, 0x9C, 0x52, 0x9D, 0xBC, 0x6B, + 0x4A, 0x98, 0xE6, 0xEA, 0x33, 0xEC, 0x58, 0xB4, + 0x43, 0xF0, 0x32, 0x45, 0xA4, 0xC1, 0x55, 0xB7, + 0x5D, 0xB5, 0x59, 0xB2, 0xE3, 0x96, 0xFF, 0xA5, + 0xAF, 0xE1, 0x86, 0x1B, 0x42, 0xE6, 0x3B, 0xA0, + 0x90, 0x4A, 0xE8, 0x8C, 0x21, 0x7F, 0x36, 0x1E, + 0x5B, 0x65, 0x25, 0xD1, 0xC1, 0x5A, 0xCA, 0x3D, + 0x10, 0xED, 0x2D, 0x79, 0xD0, 0x0F, 0x58, 0x44, + 0x69, 0x81, 0xF5, 0xD4, 0xC9, 0x0F, 0x90, 0x76, + 0x1F, 0x54, 0xD2, 0xD5, 0x97, 0xCE, 0x2C, 0xE3, + 0xEF, 0xF4, 0xB7, 0xC6, 0x3A, 0x87, 0x7F, 0x83, + 0x2A, 0xAF, 0xCD, 0x90, 0x12, 0xA7, 0x7D, 0x85, + 0x1D, 0x62, 0xD3, 0x85, 0x25, 0x05, 0xDB, 0x45, + 0x92, 0xA3, 0xF6, 0xA2, 0xA8, 0x41, 0xE4, 0x25, + 0x86, 0x87, 0x67, 0x24, 0xEC, 0x89, 0x23, 0x2A, + 0x9B, 0x20, 0x4D, 0x93, 0xEE, 0xE2, 0x2E, 0xC1, + 0x0B, 0x15, 0x33, 0xCF, 0x00, 0xD1, 0x1A, 0xDA, + 0x93, 0xFD, 0x28, 0x21, 0x5B, 0xCF, 0xD1, 0xF3, + 0x5A, 0x81, 0xBA, 0x82, 0x5E, 0x2F, 0x61, 0xB4, + 0x05, 0x71, 0xB5, 0xF4, 0x39, 0x3C, 0x1F, 0x60, + 0x00, 0x7A, 0xC4, 0xF8, 0x35, 0x20, 0x6C, 0x3A, + 0xCC, 0x03, 0x8F, 0x7B, 0xA2, 0xB6, 0x65, 0x8A, + 0xB6, 0x5F, 0xFD, 0x25, 0xD3, 0x5F, 0x92, 0xF9, + 0xAE, 0x17, 0x9B, 0x5E, 0x6E, 0x9A, 0xE4, 0x55, + 0x10, 0x25, 0x07, 0xA4, 0xAF, 0x21, 0x69, 0x13, + 0xD8, 0xFA, 0x31, 0xED, 0xF7, 0xA7, 0xA7, 0x3B, + 0xB8, 0x96, 0x8E, 0x10, 0x86, 0x74, 0xD8, 0xB1, + 0x34, 0x9E, 0x9B, 0x6A, 0x26, 0xA8, 0xD4, 0xD0, + 0xB5, 0xF6, 0xDE, 0xE7, 0xCA, 0x06, 0xDC, 0xA3, + 0x6F, 0xEE, 0x6B, 0x1E, 0xB5, 0x30, 0x99, 0x23, + 0xF9, 0x76, 0xF0, 0xA0, 0xCF, 0x3B, 0x94, 0x7B, + 0x19, 0x8D, 0xA5, 0x0C, 0x18, 0xA6, 0x1D, 0x07, + 0x89, 0xBE, 0x5B, 0x61, 0xE5, 0xF1, 0x42, 0xDB, + 0xD4, 0x2E, 0x02, 0x1F, 0xCE, 0xEF, 0x92, 0xB1, + 0x1B, 0x56, 0x50, 0xF2, 0x16, 0xE5, 0xE7, 0x4F, + 0xFD, 0xBB, 0x3E, 0xD2, 0xFC, 0x3C, 0xC6, 0x0F, + 0xF9, 0x12, 0x4E, 0xCB, 0x1E, 0x0C, 0x15, 0x84, + 0x2A, 0x14, 0x8A, 0x02, 0xE4, 0x7E, 0x95, 0x5B, + 0x86, 0xDB, 0x9B, 0x62, 0x5B, 0x19, 0xD2, 0x17, + 0xFA, 0x13, 0xBB, 0x6B, 0x3F, 0x45, 0x9F, 0xBF +}; + + +static uint8_t ms_hmac_key0[] = { + 0xFF, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 +}; + +static const uint8_t ms_hmac_digest0[] = { + 0x43, 0x52, 0xED, 0x34, 0xAB, 0x36, 0xB2, 0x51, + 0xFB, 0xA3, 0xA6, 0x7C, 0x38, 0xFC, 0x42, 0x8F, + 0x57, 0x64, 0xAB, 0x81, 0xA7, 0x89, 0xB7, 0x6C, + 0xA0, 0xDC, 0xB9, 0x4D, 0xC4, 0x30, 0xF9, 0xD4, + 0x10, 0x82, 0x55, 0xD0, 0xAB, 0x32, 0xFB, 0x56, + 0x0D, 0xE4, 0x68, 0x3D, 0x76, 0xD0, 0x7B, 0xE4, + 0xA6, 0x2C, 0x34, 0x9E, 0x8C, 0x41, 0xF8, 0x23, + 0x28, 0x1B, 0x3A, 0x90, 0x26, 0x34, 0x47, 0x90 + }; + +/* End Session 0 */ +/* Begin session 1 */ + +static uint8_t ms_aes_cbc_key1[] = { + 0xf1, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static uint8_t ms_aes_cbc_iv1[] = { + 0xf1, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static const uint8_t ms_aes_cbc_cipher1[] = { + 0x5A, 0x7A, 0x67, 0x5D, 0xB8, 0xE1, 0xDC, 0x71, + 0x39, 0xA8, 0x74, 0x93, 0x9C, 0x4C, 0xFE, 0x23, + 0x61, 0xCD, 0xA4, 0xB3, 0xD9, 0xCE, 0x99, 0x09, + 0x2A, 0x23, 0xF3, 0x29, 0xBF, 0x4C, 0xB4, 0x6A, + 0x1B, 0x6B, 0x73, 0x4D, 0x48, 0x0C, 0xCF, 0x6C, + 0x5E, 0x34, 0x9E, 0x7F, 0xBC, 0x8F, 0xCC, 0x8F, + 0x75, 0x1D, 0x3D, 0x77, 0x10, 0x76, 0xC8, 0xB9, + 0x99, 0x6F, 0xD6, 0x56, 0x75, 0xA9, 0xB2, 0x66, + 0xC2, 0x24, 0x2B, 0x9C, 0xFE, 0x40, 0x8E, 0x43, + 0x20, 0x97, 0x1B, 0xFA, 0xD0, 0xCF, 0x04, 0xAB, + 0xBB, 0xF6, 0x5D, 0xF5, 0xA0, 0x19, 0x7C, 0x23, + 0x5D, 0x80, 0x8C, 0x49, 0xF6, 0x76, 0x88, 0x29, + 0x27, 0x4C, 0x59, 0x2B, 0x43, 0xA6, 0xB2, 0x26, + 0x27, 0x78, 0xBE, 0x1B, 0xE1, 0x4F, 0x5A, 0x1F, + 0xFC, 0x68, 0x08, 0xE7, 0xC4, 0xD1, 0x34, 0x68, + 0xB7, 0x13, 0x14, 0x41, 0x62, 0x6B, 0x1F, 0x77, + 0x0C, 0x68, 0x1D, 0x0D, 0xED, 0x89, 0xAA, 0xD8, + 0x97, 0x02, 0xBA, 0x5E, 0xD4, 0x84, 0x25, 0x97, + 0x03, 0xA5, 0xA6, 0x13, 0x66, 0x02, 0xF4, 0xC3, + 0xF3, 0xD3, 0xCC, 0x95, 0xC3, 0x87, 0x46, 0x90, + 0x1F, 0x6E, 0x14, 0xA8, 0x00, 0xF2, 0x6F, 0xD5, + 0xA1, 0xAD, 0xD5, 0x40, 0xA2, 0x0F, 0x32, 0x7E, + 0x99, 0xA3, 0xF5, 0x53, 0xC3, 0x26, 0xA1, 0x45, + 0x01, 0x88, 0x57, 0x84, 0x3E, 0x7B, 0x4E, 0x0B, + 0x3C, 0xB5, 0x3E, 0x9E, 0xE9, 0x78, 0x77, 0xC5, + 0xC0, 0x89, 0xA8, 0xF8, 0xF1, 0xA5, 0x2D, 0x5D, + 0xF9, 0xC6, 0xFB, 0xCB, 0x05, 0x23, 0xBD, 0x6E, + 0x5E, 0x14, 0xC6, 0x57, 0x73, 0xCF, 0x98, 0xBD, + 0x10, 0x8B, 0x18, 0xA6, 0x01, 0x5B, 0x13, 0xAE, + 0x8E, 0xDE, 0x1F, 0xB5, 0xB7, 0x40, 0x6C, 0xC1, + 0x1E, 0xA1, 0x19, 0x20, 0x9E, 0x95, 0xE0, 0x2F, + 0x1C, 0xF5, 0xD9, 0xD0, 0x2B, 0x1E, 0x82, 0x25, + 0x62, 0xB4, 0xEB, 0xA1, 0x1F, 0xCE, 0x44, 0xA1, + 0xCB, 0x92, 0x01, 0x6B, 0xE4, 0x26, 0x23, 0xE3, + 0xC5, 0x67, 0x35, 0x55, 0xDA, 0xE5, 0x27, 0xEE, + 0x8D, 0x12, 0x84, 0xB7, 0xBA, 0xA7, 0x1C, 0xD6, + 0x32, 0x3F, 0x67, 0xED, 0xFB, 0x5B, 0x8B, 0x52, + 0x46, 0x8C, 0xF9, 0x69, 0xCD, 0xAE, 0x79, 0xAA, + 0x37, 0x78, 0x49, 0xEB, 0xC6, 0x8E, 0x76, 0x63, + 0x84, 0xFF, 0x9D, 0x22, 0x99, 0x51, 0xB7, 0x5E, + 0x83, 0x4C, 0x8B, 0xDF, 0x5A, 0x07, 0xCC, 0xBA, + 0x42, 0xA5, 0x98, 0xB6, 0x47, 0x0E, 0x66, 0xEB, + 0x23, 0x0E, 0xBA, 0x44, 0xA8, 0xAA, 0x20, 0x71, + 0x79, 0x9C, 0x77, 0x5F, 0xF5, 0xFE, 0xEC, 0xEF, + 0xC6, 0x64, 0x3D, 0x84, 0xD0, 0x2B, 0xA7, 0x0A, + 0xC3, 0x72, 0x5B, 0x9C, 0xFA, 0xA8, 0x87, 0x95, + 0x94, 0x11, 0x38, 0xA7, 0x1E, 0x58, 0xE3, 0x73, + 0xC6, 0xC9, 0xD1, 0x7B, 0x92, 0xDB, 0x0F, 0x49, + 0x74, 0xC2, 0xA2, 0x0E, 0x35, 0x57, 0xAC, 0xDB, + 0x9A, 0x1C, 0xCF, 0x5A, 0x32, 0x3E, 0x26, 0x9B, + 0xEC, 0xB3, 0xEF, 0x9C, 0xFE, 0xBE, 0x52, 0xAC, + 0xB1, 0x29, 0xDD, 0xFD, 0x07, 0xE2, 0xEE, 0xED, + 0xE4, 0x46, 0x37, 0xFE, 0xD1, 0xDC, 0xCD, 0x02, + 0xF9, 0x31, 0xB0, 0xFB, 0x36, 0xB7, 0x34, 0xA4, + 0x76, 0xE8, 0x57, 0xBF, 0x99, 0x92, 0xC7, 0xAF, + 0x98, 0x10, 0xE2, 0x70, 0xCA, 0xC9, 0x2B, 0x82, + 0x06, 0x96, 0x88, 0x0D, 0xB3, 0xAC, 0x9E, 0x6D, + 0x43, 0xBC, 0x5B, 0x31, 0xCF, 0x65, 0x8D, 0xA6, + 0xC7, 0xFE, 0x73, 0xE1, 0x54, 0xF7, 0x10, 0xF9, + 0x86, 0xF7, 0xDF, 0xA1, 0xA1, 0xD8, 0xAE, 0x35, + 0xB3, 0x90, 0xDC, 0x6F, 0x43, 0x7A, 0x8B, 0xE0, + 0xFE, 0x8F, 0x33, 0x4D, 0x29, 0x6C, 0x45, 0x53, + 0x73, 0xDD, 0x21, 0x0B, 0x85, 0x30, 0xB5, 0xA5, + 0xF3, 0x5D, 0xEC, 0x79, 0x61, 0x9D, 0x9E, 0xB3 + +}; + +static uint8_t ms_hmac_key1[] = { + 0xFE, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 +}; + +static const uint8_t ms_hmac_digest1[] = { + 0xCE, 0x6E, 0x5F, 0x77, 0x96, 0x9A, 0xB1, 0x69, + 0x2D, 0x5E, 0xF3, 0x2F, 0x32, 0x10, 0xCB, 0x50, + 0x0E, 0x09, 0x56, 0x25, 0x07, 0x34, 0xC9, 0x20, + 0xEC, 0x13, 0x43, 0x23, 0x5C, 0x08, 0x8B, 0xCD, + 0xDC, 0x86, 0x8C, 0xEE, 0x0A, 0x95, 0x2E, 0xB9, + 0x8C, 0x7B, 0x02, 0x7A, 0xD4, 0xE1, 0x49, 0xB4, + 0x45, 0xB5, 0x52, 0x37, 0xC6, 0xFF, 0xFE, 0xAA, + 0x0A, 0x87, 0xB8, 0x51, 0xF9, 0x2A, 0x01, 0x8F +}; +/* End Session 1 */ +/* Begin Session 2 */ +static uint8_t ms_aes_cbc_key2[] = { + 0xff, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static uint8_t ms_aes_cbc_iv2[] = { + 0xff, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static const uint8_t ms_aes_cbc_cipher2[] = { + 0xBB, 0x3C, 0x68, 0x25, 0xFD, 0xB6, 0xA2, 0x91, + 0x20, 0x56, 0xF6, 0x30, 0x35, 0xFC, 0x9E, 0x97, + 0xF2, 0x90, 0xFC, 0x7E, 0x3E, 0x0A, 0x75, 0xC8, + 0x4C, 0xF2, 0x2D, 0xAC, 0xD3, 0x93, 0xF0, 0xC5, + 0x14, 0x88, 0x8A, 0x23, 0xC2, 0x59, 0x9A, 0x98, + 0x4B, 0xD5, 0x2C, 0xDA, 0x43, 0xA9, 0x34, 0x69, + 0x7C, 0x6D, 0xDB, 0xDC, 0xCB, 0xC0, 0xA0, 0x09, + 0xA7, 0x86, 0x16, 0x4B, 0xBF, 0xA8, 0xB6, 0xCF, + 0x7F, 0x74, 0x1F, 0x22, 0xF0, 0xF6, 0xBB, 0x44, + 0x8B, 0x4C, 0x9E, 0x23, 0xF8, 0x9F, 0xFC, 0x5B, + 0x9E, 0x9C, 0x2A, 0x79, 0x30, 0x8F, 0xBF, 0xA9, + 0x68, 0xA1, 0x20, 0x71, 0x7C, 0x77, 0x22, 0x34, + 0x07, 0xCD, 0xC6, 0xF6, 0x50, 0x0A, 0x08, 0x99, + 0x17, 0x98, 0xE3, 0x93, 0x8A, 0xB0, 0xEE, 0xDF, + 0xC2, 0xBA, 0x3B, 0x44, 0x73, 0xDF, 0xDD, 0xDC, + 0x14, 0x4D, 0x3B, 0xBB, 0x5E, 0x58, 0xC1, 0x26, + 0xA7, 0xAE, 0x47, 0xF3, 0x24, 0x6D, 0x4F, 0xD3, + 0x6E, 0x3E, 0x33, 0xE6, 0x7F, 0xCA, 0x50, 0xAF, + 0x5D, 0x3D, 0xA0, 0xDD, 0xC9, 0xF3, 0x30, 0xD3, + 0x6E, 0x8B, 0x2E, 0x12, 0x24, 0x34, 0xF0, 0xD3, + 0xC7, 0x8D, 0x23, 0x29, 0xAA, 0x05, 0xE1, 0xFA, + 0x2E, 0xF6, 0x8D, 0x37, 0x86, 0xC0, 0x6D, 0x13, + 0x2D, 0x98, 0xF3, 0x52, 0x39, 0x22, 0xCE, 0x38, + 0xC2, 0x1A, 0x72, 0xED, 0xFB, 0xCC, 0xE4, 0x71, + 0x5A, 0x0C, 0x0D, 0x09, 0xF8, 0xE8, 0x1B, 0xBC, + 0x53, 0xC8, 0xD8, 0x8F, 0xE5, 0x98, 0x5A, 0xB1, + 0x06, 0xA6, 0x5B, 0xE6, 0xA2, 0x88, 0x21, 0x9E, + 0x36, 0xC0, 0x34, 0xF9, 0xFB, 0x3B, 0x0A, 0x22, + 0x00, 0x00, 0x39, 0x48, 0x8D, 0x23, 0x74, 0x62, + 0x72, 0x91, 0xE6, 0x36, 0xAA, 0x77, 0x9C, 0x72, + 0x9D, 0xA8, 0xC3, 0xA9, 0xD5, 0x44, 0x72, 0xA6, + 0xB9, 0x28, 0x8F, 0x64, 0x4C, 0x8A, 0x64, 0xE6, + 0x4E, 0xFA, 0xEF, 0x87, 0xDE, 0x7B, 0x22, 0x44, + 0xB0, 0xDF, 0x2E, 0x5F, 0x0B, 0xA5, 0xF2, 0x24, + 0x07, 0x5C, 0x2D, 0x39, 0xB7, 0x3D, 0x8A, 0xE5, + 0x0E, 0x9D, 0x4E, 0x50, 0xED, 0x03, 0x99, 0x8E, + 0xF0, 0x06, 0x55, 0x4E, 0xA2, 0x24, 0xE7, 0x17, + 0x46, 0xDF, 0x6C, 0xCD, 0xC6, 0x44, 0xE8, 0xF9, + 0xB9, 0x1B, 0x36, 0xF6, 0x7F, 0x10, 0xA4, 0x7D, + 0x90, 0xBD, 0xE4, 0xAA, 0xD6, 0x9E, 0x18, 0x9D, + 0x22, 0x35, 0xD6, 0x55, 0x54, 0xAA, 0xF7, 0x22, + 0xA3, 0x3E, 0xEF, 0xC8, 0xA2, 0x34, 0x8D, 0xA9, + 0x37, 0x63, 0xA6, 0xC3, 0x57, 0xCB, 0x0C, 0x49, + 0x7D, 0x02, 0xBE, 0xAA, 0x13, 0x75, 0xB7, 0x4E, + 0x52, 0x62, 0xA5, 0xC2, 0x33, 0xC7, 0x6C, 0x1B, + 0xF6, 0x34, 0xF6, 0x09, 0xA5, 0x0C, 0xC7, 0xA2, + 0x61, 0x48, 0x62, 0x7D, 0x17, 0x15, 0xE3, 0x95, + 0xC8, 0x63, 0xD2, 0xA4, 0x43, 0xA9, 0x49, 0x07, + 0xB2, 0x3B, 0x2B, 0x62, 0x7D, 0xCB, 0x51, 0xB3, + 0x25, 0x33, 0x47, 0x0E, 0x14, 0x67, 0xDC, 0x6A, + 0x9B, 0x51, 0xAC, 0x9D, 0x8F, 0xA2, 0x2B, 0x57, + 0x8C, 0x5C, 0x5F, 0x76, 0x23, 0x92, 0x0F, 0x84, + 0x46, 0x0E, 0x40, 0x85, 0x38, 0x60, 0xFA, 0x61, + 0x20, 0xC5, 0xE3, 0xF1, 0x70, 0xAC, 0x1B, 0xBF, + 0xC4, 0x2B, 0xC5, 0x67, 0xD1, 0x43, 0xC5, 0x17, + 0x74, 0x71, 0x69, 0x6F, 0x82, 0x89, 0x19, 0x8A, + 0x70, 0x43, 0x92, 0x01, 0xC4, 0x63, 0x7E, 0xB1, + 0x59, 0x4E, 0xCD, 0xEA, 0x93, 0xA4, 0x52, 0x53, + 0x9B, 0x61, 0x5B, 0xD2, 0x3E, 0x19, 0x39, 0xB7, + 0x32, 0xEA, 0x8E, 0xF8, 0x1D, 0x76, 0x5C, 0xB2, + 0x73, 0x2D, 0x91, 0xC0, 0x18, 0xED, 0x25, 0x2A, + 0x53, 0x64, 0xF0, 0x92, 0x31, 0x55, 0x21, 0xA8, + 0x24, 0xA9, 0xD1, 0x02, 0xF6, 0x6C, 0x2B, 0x70, + 0xA9, 0x59, 0xC1, 0xD6, 0xC3, 0x57, 0x5B, 0x92 +}; + +static uint8_t ms_hmac_key2[] = { + 0xFC, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 +}; + +static const uint8_t ms_hmac_digest2[] = { + 0xA5, 0x0F, 0x9C, 0xFB, 0x08, 0x62, 0x59, 0xFF, + 0x80, 0x2F, 0xEB, 0x4B, 0xE1, 0x46, 0x21, 0xD6, + 0x02, 0x98, 0xF2, 0x8E, 0xF4, 0xEC, 0xD4, 0x77, + 0x86, 0x4C, 0x31, 0x28, 0xC8, 0x25, 0x80, 0x27, + 0x3A, 0x72, 0x5D, 0x6A, 0x56, 0x8A, 0xD3, 0x82, + 0xB0, 0xEC, 0x31, 0x6D, 0x8B, 0x6B, 0xB4, 0x24, + 0xE7, 0x62, 0xC1, 0x52, 0xBC, 0x14, 0x1B, 0x8E, + 0xEC, 0x9A, 0xF1, 0x47, 0x80, 0xD2, 0xB0, 0x59 +}; + +/* End Session 2 */ + + static int test_AES_CBC_HMAC_SHA1_encrypt_digest(void) { @@ -952,17 +1284,24 @@ static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA512_digest[] = { static int test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( - struct crypto_unittest_params *ut_params); + struct crypto_unittest_params *ut_params, + uint8_t *cipher_key, + uint8_t *hmac_key); static int test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, struct crypto_unittest_params *ut_params, - struct crypto_testsuite_params *ts_params); + struct crypto_testsuite_params *ts_params, + const uint8_t *cipher, + const uint8_t *digest, + const uint8_t *iv); static int test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( - struct crypto_unittest_params *ut_params) + struct crypto_unittest_params *ut_params, + uint8_t *cipher_key, + uint8_t *hmac_key) { /* Setup Cipher Parameters */ @@ -971,7 +1310,7 @@ test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC; ut_params->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT; - ut_params->cipher_xform.cipher.key.data = aes_cbc_key; + ut_params->cipher_xform.cipher.key.data = cipher_key; ut_params->cipher_xform.cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC; /* Setup HMAC Parameters */ @@ -980,7 +1319,7 @@ test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SHA512_HMAC; - ut_params->auth_xform.auth.key.data = hmac_sha512_key; + ut_params->auth_xform.auth.key.data = hmac_key; ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA512; ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA512; @@ -991,12 +1330,15 @@ test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( static int test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, struct crypto_unittest_params *ut_params, - struct crypto_testsuite_params *ts_params) + struct crypto_testsuite_params *ts_params, + const uint8_t *cipher, + const uint8_t *digest, + const uint8_t *iv) { /* Generate test mbuf data and digest */ ut_params->ibuf = setup_test_string(ts_params->mbuf_pool, (const char *) - catch_22_quote_2_512_bytes_AES_CBC_ciphertext, + cipher, QUOTE_512_BYTES, 0); ut_params->digest = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, @@ -1004,7 +1346,7 @@ test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, TEST_ASSERT_NOT_NULL(ut_params->digest, "no room to append digest"); rte_memcpy(ut_params->digest, - catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA512_digest, + digest, DIGEST_BYTE_LENGTH_SHA512); /* Generate Crypto op data structure */ @@ -1034,7 +1376,7 @@ test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, ut_params->ibuf, 0); sym_op->cipher.iv.length = CIPHER_IV_LENGTH_AES_CBC; - rte_memcpy(sym_op->cipher.iv.data, aes_cbc_iv, + rte_memcpy(sym_op->cipher.iv.data, iv, CIPHER_IV_LENGTH_AES_CBC); sym_op->cipher.data.offset = CIPHER_IV_LENGTH_AES_CBC; @@ -1064,14 +1406,63 @@ test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, } static int -test_AES_mb_all(void) +test_AES_chain_mb_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_AESNI_MB_PMD, + BLKCIPHER_AES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_chain_libcrypto_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_LIBCRYPTO_PMD, + BLKCIPHER_AES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_cipheronly_libcrypto_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_LIBCRYPTO_PMD, + BLKCIPHER_AES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_chain_qat_all(void) { struct crypto_testsuite_params *ts_params = &testsuite_params; int status; - status = test_AES_all_tests(ts_params->mbuf_pool, + status = test_blockcipher_all_tests(ts_params->mbuf_pool, ts_params->op_mpool, ts_params->valid_devs[0], - RTE_CRYPTODEV_AESNI_MB_PMD); + RTE_CRYPTODEV_QAT_SYM_PMD, + BLKCIPHER_AES_CHAIN_TYPE); TEST_ASSERT_EQUAL(status, 0, "Test failed"); @@ -1079,14 +1470,15 @@ test_AES_mb_all(void) } static int -test_AES_qat_all(void) +test_authonly_libcrypto_all(void) { struct crypto_testsuite_params *ts_params = &testsuite_params; int status; - status = test_AES_all_tests(ts_params->mbuf_pool, + status = test_blockcipher_all_tests(ts_params->mbuf_pool, ts_params->op_mpool, ts_params->valid_devs[0], - RTE_CRYPTODEV_QAT_SYM_PMD); + RTE_CRYPTODEV_LIBCRYPTO_PMD, + BLKCIPHER_AUTHONLY_TYPE); TEST_ASSERT_EQUAL(status, 0, "Test failed"); @@ -3158,19 +3550,82 @@ test_kasumi_cipher_auth_test_case_1(void) return test_kasumi_cipher_auth(&kasumi_test_case_6); } +static int +test_3DES_chain_qat_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_QAT_SYM_PMD, + BLKCIPHER_3DES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_cipheronly_qat_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_QAT_SYM_PMD, + BLKCIPHER_3DES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_chain_libcrypto_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_LIBCRYPTO_PMD, + BLKCIPHER_3DES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_cipheronly_libcrypto_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_LIBCRYPTO_PMD, + BLKCIPHER_3DES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} /* ***** AES-GCM Tests ***** */ static int create_gcm_session(uint8_t dev_id, enum rte_crypto_cipher_operation op, const uint8_t *key, const uint8_t key_len, - const uint8_t aad_len, const uint8_t auth_len, - enum rte_crypto_auth_operation auth_op) + const uint8_t aad_len, const uint8_t auth_len) { uint8_t cipher_key[key_len]; struct crypto_unittest_params *ut_params = &unittest_params; + memcpy(cipher_key, key, key_len); /* Setup Cipher Parameters */ @@ -3178,7 +3633,7 @@ create_gcm_session(uint8_t dev_id, enum rte_crypto_cipher_operation op, ut_params->cipher_xform.next = NULL; ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_GCM; - ut_params->auth_xform.auth.op = auth_op; + ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; ut_params->cipher_xform.cipher.op = op; ut_params->cipher_xform.cipher.key.data = cipher_key; ut_params->cipher_xform.cipher.key.length = key_len; @@ -3309,8 +3764,7 @@ test_mb_AES_GCM_authenticated_encryption(const struct gcm_test_data *tdata) retval = create_gcm_session(ts_params->valid_devs[0], RTE_CRYPTO_CIPHER_OP_ENCRYPT, tdata->key.data, tdata->key.len, - tdata->aad.len, tdata->auth_tag.len, - RTE_CRYPTO_AUTH_OP_GENERATE); + tdata->aad.len, tdata->auth_tag.len); if (retval < 0) return retval; @@ -3440,8 +3894,7 @@ test_mb_AES_GCM_authenticated_decryption(const struct gcm_test_data *tdata) retval = create_gcm_session(ts_params->valid_devs[0], RTE_CRYPTO_CIPHER_OP_DECRYPT, tdata->key.data, tdata->key.len, - tdata->aad.len, tdata->auth_tag.len, - RTE_CRYPTO_AUTH_OP_VERIFY); + tdata->aad.len, tdata->auth_tag.len); if (retval < 0) return retval; @@ -3788,7 +4241,8 @@ test_multi_session(void) uint16_t i; - test_AES_CBC_HMAC_SHA512_decrypt_create_session_params(ut_params); + test_AES_CBC_HMAC_SHA512_decrypt_create_session_params(ut_params, + aes_cbc_key, hmac_sha512_key); rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info); @@ -3807,10 +4261,13 @@ test_multi_session(void) i); /* Attempt to send a request on each session */ - TEST_ASSERT_SUCCESS(test_AES_CBC_HMAC_SHA512_decrypt_perform( - sessions[i], ut_params, ts_params), - "Failed to perform decrypt on request " - "number %u.", i); + TEST_ASSERT_SUCCESS( + test_AES_CBC_HMAC_SHA512_decrypt_perform(sessions[i], ut_params, + ts_params, + catch_22_quote_2_512_bytes_AES_CBC_ciphertext, + catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA512_digest, + aes_cbc_iv), + "Failed to perform decrypt on request number %u.", i); /* free crypto operation structure */ if (ut_params->op) rte_crypto_op_free(ut_params->op); @@ -3847,6 +4304,112 @@ test_multi_session(void) return TEST_SUCCESS; } +struct multi_session_params { + struct crypto_unittest_params ut_params; + uint8_t *cipher_key; + uint8_t *hmac_key; + const uint8_t *cipher; + const uint8_t *digest; + uint8_t *iv; +}; + +#define MB_SESSION_NUMBER 3 + +static int +test_multi_session_random_usage(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_cryptodev_info dev_info; + struct rte_cryptodev_sym_session **sessions; + uint32_t i, j; + struct multi_session_params ut_paramz[] = { + + { + .cipher_key = ms_aes_cbc_key0, + .hmac_key = ms_hmac_key0, + .cipher = ms_aes_cbc_cipher0, + .digest = ms_hmac_digest0, + .iv = ms_aes_cbc_iv0 + }, + { + .cipher_key = ms_aes_cbc_key1, + .hmac_key = ms_hmac_key1, + .cipher = ms_aes_cbc_cipher1, + .digest = ms_hmac_digest1, + .iv = ms_aes_cbc_iv1 + }, + { + .cipher_key = ms_aes_cbc_key2, + .hmac_key = ms_hmac_key2, + .cipher = ms_aes_cbc_cipher2, + .digest = ms_hmac_digest2, + .iv = ms_aes_cbc_iv2 + }, + + }; + + rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info); + + sessions = rte_malloc(NULL, + (sizeof(struct rte_cryptodev_sym_session *) + * dev_info.sym.max_nb_sessions) + 1, 0); + + for (i = 0; i < MB_SESSION_NUMBER; i++) { + rte_memcpy(&ut_paramz[i].ut_params, &testsuite_params, + sizeof(struct crypto_unittest_params)); + + test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( + &ut_paramz[i].ut_params, ut_paramz[i].cipher_key, + ut_paramz[i].hmac_key); + + /* Create multiple crypto sessions*/ + sessions[i] = rte_cryptodev_sym_session_create(ts_params->valid_devs[0], + &ut_paramz[i].ut_params.auth_xform); + + TEST_ASSERT_NOT_NULL(sessions[i], + "Session creation failed at session number %u", i); + + } + + srand(time(NULL)); + for (i = 0; i < 40000; i++) { + + j = rand() % MB_SESSION_NUMBER; + + TEST_ASSERT_SUCCESS( + test_AES_CBC_HMAC_SHA512_decrypt_perform(sessions[j], + &ut_paramz[j].ut_params, ts_params, ut_paramz[j].cipher, + ut_paramz[j].digest, ut_paramz[j].iv), + "Failed to perform decrypt on request number %u.", i); + + if (ut_paramz[j].ut_params.op) + rte_crypto_op_free(ut_paramz[j].ut_params.op); + + /* + * free mbuf - both obuf and ibuf are usually the same, + * so check if they point at the same address is necessary, + * to avoid freeing the mbuf twice. + */ + if (ut_paramz[j].ut_params.obuf) { + rte_pktmbuf_free(ut_paramz[j].ut_params.obuf); + if (ut_paramz[j].ut_params.ibuf == ut_paramz[j].ut_params.obuf) + ut_paramz[j].ut_params.ibuf = 0; + ut_paramz[j].ut_params.obuf = 0; + } + if (ut_paramz[j].ut_params.ibuf) { + rte_pktmbuf_free(ut_paramz[j].ut_params.ibuf); + ut_paramz[j].ut_params.ibuf = 0; + } + } + + for (i = 0; i < MB_SESSION_NUMBER; i++) + rte_cryptodev_sym_session_free(ts_params->valid_devs[0], sessions[i]); + + rte_free(sessions); + + return TEST_SUCCESS; +} + static int test_null_cipher_only_operation(void) { @@ -4393,6 +4956,12 @@ test_AES_GMAC_authentication_test_case_3(void) } static int +test_AES_GMAC_authentication_test_case_4(void) +{ + return test_AES_GMAC_authentication(&gmac_test_case_4); +} + +static int test_AES_GMAC_authentication_verify(const struct gmac_test_data *tdata) { struct crypto_testsuite_params *ts_params = &testsuite_params; @@ -4454,83 +5023,797 @@ test_AES_GMAC_authentication_verify_test_case_3(void) return test_AES_GMAC_authentication_verify(&gmac_test_case_3); } -static struct unit_test_suite cryptodev_qat_testsuite = { - .suite_name = "Crypto QAT Unit Test Suite", - .setup = testsuite_setup, - .teardown = testsuite_teardown, - .unit_test_cases = { - TEST_CASE_ST(ut_setup, ut_teardown, - test_device_configure_invalid_dev_id), - TEST_CASE_ST(ut_setup, ut_teardown, - test_device_configure_invalid_queue_pair_ids), - TEST_CASE_ST(ut_setup, ut_teardown, - test_queue_pair_descriptor_setup), - TEST_CASE_ST(ut_setup, ut_teardown, - test_multi_session), +static int +test_AES_GMAC_authentication_verify_test_case_4(void) +{ + return test_AES_GMAC_authentication_verify(&gmac_test_case_4); +} - TEST_CASE_ST(ut_setup, ut_teardown, test_AES_qat_all), - TEST_CASE_ST(ut_setup, ut_teardown, test_stats), +struct test_crypto_vector { + enum rte_crypto_cipher_algorithm crypto_algo; - /** AES GCM Authenticated Encryption */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_7), + struct { + uint8_t data[64]; + unsigned int len; + } cipher_key; - /** AES GCM Authenticated Decryption */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_7), + struct { + uint8_t data[64]; + unsigned int len; + } iv; - /** AES GMAC Authentication */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_verify_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_verify_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_verify_test_case_3), + struct { + const uint8_t *data; + unsigned int len; + } plaintext; - /** SNOW 3G encrypt only (UEA2) */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_encryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_encryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_encryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_encryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_encryption_test_case_5), + struct { + const uint8_t *data; + unsigned int len; + } ciphertext; - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_encryption_test_case_1_oop), + enum rte_crypto_auth_algorithm auth_algo; + + struct { + uint8_t data[128]; + unsigned int len; + } auth_key; + + struct { + const uint8_t *data; + unsigned int len; + } aad; + + struct { + uint8_t data[128]; + unsigned int len; + } digest; +}; + +static const struct test_crypto_vector +hmac_sha1_test_crypto_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .plaintext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0xC4, 0xB7, 0x0E, 0x6B, 0xDE, 0xD1, 0xE7, 0x77, + 0x7E, 0x2E, 0x8F, 0xFC, 0x48, 0x39, 0x46, 0x17, + 0x3F, 0x91, 0x64, 0x59 + }, + .len = 20 + } +}; + +static const struct test_crypto_vector +aes128_gmac_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_AES_GMAC, + .crypto_algo = RTE_CRYPTO_CIPHER_AES_GCM, + .aad = { + .data = plaintext_hash, + .len = 512 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B + }, + .len = 12 + }, + .cipher_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA + }, + .len = 16 + }, + .digest = { + .data = { + 0xCA, 0x00, 0x99, 0x8B, 0x30, 0x7E, 0x74, 0x56, + 0x32, 0xA7, 0x87, 0xB5, 0xE9, 0xB2, 0x34, 0x5A + }, + .len = 16 + } +}; + +static const struct test_crypto_vector +aes128cbc_hmac_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_hash, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60, + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0x18, 0x8C, 0x1D, 0x32 + }, + .len = 20 + } +}; + +static void +data_corruption(uint8_t *data) +{ + data[0] += 1; +} + +static void +tag_corruption(uint8_t *data, unsigned int tag_offset) +{ + data[tag_offset] += 1; +} + +static int +create_auth_session(struct crypto_unittest_params *ut_params, + uint8_t dev_id, + const struct test_crypto_vector *reference, + enum rte_crypto_auth_operation auth_op) +{ + uint8_t auth_key[reference->auth_key.len + 1]; + + memcpy(auth_key, reference->auth_key.data, reference->auth_key.len); + + /* Setup Authentication Parameters */ + ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; + ut_params->auth_xform.auth.op = auth_op; + ut_params->auth_xform.next = NULL; + ut_params->auth_xform.auth.algo = reference->auth_algo; + ut_params->auth_xform.auth.key.length = reference->auth_key.len; + ut_params->auth_xform.auth.key.data = auth_key; + ut_params->auth_xform.auth.digest_length = reference->digest.len; + ut_params->auth_xform.auth.add_auth_data_length = reference->aad.len; + + /* Create Crypto session*/ + ut_params->sess = rte_cryptodev_sym_session_create(dev_id, + &ut_params->auth_xform); + + TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); + + return 0; +} + +static int +create_auth_cipher_session(struct crypto_unittest_params *ut_params, + uint8_t dev_id, + const struct test_crypto_vector *reference, + enum rte_crypto_auth_operation auth_op, + enum rte_crypto_cipher_operation cipher_op) +{ + uint8_t cipher_key[reference->cipher_key.len + 1]; + uint8_t auth_key[reference->auth_key.len + 1]; + + memcpy(cipher_key, reference->cipher_key.data, reference->cipher_key.len); + memcpy(auth_key, reference->auth_key.data, reference->auth_key.len); + + /* Setup Authentication Parameters */ + ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; + ut_params->auth_xform.auth.op = auth_op; + ut_params->auth_xform.next = &ut_params->cipher_xform; + ut_params->auth_xform.auth.algo = reference->auth_algo; + ut_params->auth_xform.auth.key.length = reference->auth_key.len; + ut_params->auth_xform.auth.key.data = auth_key; + ut_params->auth_xform.auth.digest_length = reference->digest.len; + ut_params->auth_xform.auth.add_auth_data_length = reference->aad.len; + + /* Setup Cipher Parameters */ + ut_params->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; + ut_params->cipher_xform.next = NULL; + ut_params->cipher_xform.cipher.algo = reference->crypto_algo; + ut_params->cipher_xform.cipher.op = cipher_op; + ut_params->cipher_xform.cipher.key.data = cipher_key; + ut_params->cipher_xform.cipher.key.length = reference->cipher_key.len; + + /* Create Crypto session*/ + ut_params->sess = rte_cryptodev_sym_session_create(dev_id, + &ut_params->auth_xform); + + TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); + + return 0; +} + +static int +create_auth_operation(struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int auth_generate) +{ + /* Generate Crypto op data structure */ + ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC); + TEST_ASSERT_NOT_NULL(ut_params->op, + "Failed to allocate pktmbuf offload"); + + /* Set crypto operation data parameters */ + rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); + + struct rte_crypto_sym_op *sym_op = ut_params->op->sym; + + /* set crypto operation source mbuf */ + sym_op->m_src = ut_params->ibuf; + + /* digest */ + sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( + ut_params->ibuf, reference->digest.len); + + TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, + "no room to append auth tag"); + + sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( + ut_params->ibuf, reference->plaintext.len); + sym_op->auth.digest.length = reference->digest.len; + + if (auth_generate) + memset(sym_op->auth.digest.data, 0, reference->digest.len); + else + memcpy(sym_op->auth.digest.data, + reference->digest.data, + reference->digest.len); + + TEST_HEXDUMP(stdout, "digest:", + sym_op->auth.digest.data, + sym_op->auth.digest.length); + + sym_op->auth.data.length = reference->plaintext.len; + sym_op->auth.data.offset = 0; + + return 0; +} + +static int +create_auth_GMAC_operation(struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int auth_generate) +{ + /* Generate Crypto op data structure */ + ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC); + TEST_ASSERT_NOT_NULL(ut_params->op, + "Failed to allocate pktmbuf offload"); + + /* Set crypto operation data parameters */ + rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); + + struct rte_crypto_sym_op *sym_op = ut_params->op->sym; + + /* set crypto operation source mbuf */ + sym_op->m_src = ut_params->ibuf; + + /* aad */ + sym_op->auth.aad.data = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + reference->aad.len); + TEST_ASSERT_NOT_NULL(sym_op->auth.aad.data, "no room to append AAD"); + memcpy(sym_op->auth.aad.data, reference->aad.data, reference->aad.len); + + TEST_HEXDUMP(stdout, "AAD:", sym_op->auth.aad.data, reference->aad.len); + + sym_op->auth.aad.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); + sym_op->auth.aad.length = reference->aad.len; + + /* digest */ + sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( + ut_params->ibuf, reference->digest.len); + + TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, + "no room to append auth tag"); + + sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( + ut_params->ibuf, reference->ciphertext.len); + sym_op->auth.digest.length = reference->digest.len; + + if (auth_generate) + memset(sym_op->auth.digest.data, 0, reference->digest.len); + else + memcpy(sym_op->auth.digest.data, + reference->digest.data, + reference->digest.len); + + TEST_HEXDUMP(stdout, "digest:", + sym_op->auth.digest.data, + sym_op->auth.digest.length); + + sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend( + ut_params->ibuf, reference->iv.len); + TEST_ASSERT_NOT_NULL(sym_op->cipher.iv.data, "no room to prepend iv"); + + sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); + sym_op->cipher.iv.length = reference->iv.len; + + memcpy(sym_op->cipher.iv.data, reference->iv.data, reference->iv.len); + + sym_op->cipher.data.length = 0; + sym_op->cipher.data.offset = 0; + + sym_op->auth.data.length = 0; + sym_op->auth.data.offset = 0; + + return 0; +} + +static int +create_cipher_auth_operation(struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int auth_generate) +{ + /* Generate Crypto op data structure */ + ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC); + TEST_ASSERT_NOT_NULL(ut_params->op, + "Failed to allocate pktmbuf offload"); + + /* Set crypto operation data parameters */ + rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); + + struct rte_crypto_sym_op *sym_op = ut_params->op->sym; + + /* set crypto operation source mbuf */ + sym_op->m_src = ut_params->ibuf; + + /* digest */ + sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( + ut_params->ibuf, reference->digest.len); + + TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, + "no room to append auth tag"); + + sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( + ut_params->ibuf, reference->ciphertext.len); + sym_op->auth.digest.length = reference->digest.len; + + if (auth_generate) + memset(sym_op->auth.digest.data, 0, reference->digest.len); + else + memcpy(sym_op->auth.digest.data, + reference->digest.data, + reference->digest.len); + + TEST_HEXDUMP(stdout, "digest:", + sym_op->auth.digest.data, + sym_op->auth.digest.length); + + sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend( + ut_params->ibuf, reference->iv.len); + TEST_ASSERT_NOT_NULL(sym_op->cipher.iv.data, "no room to prepend iv"); + + sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); + sym_op->cipher.iv.length = reference->iv.len; + + memcpy(sym_op->cipher.iv.data, reference->iv.data, reference->iv.len); + + sym_op->cipher.data.length = reference->ciphertext.len; + sym_op->cipher.data.offset = reference->iv.len; + + sym_op->auth.data.length = reference->ciphertext.len; + sym_op->auth.data.offset = reference->iv.len; + + return 0; +} + +static int +create_auth_verify_operation(struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return create_auth_operation(ts_params, ut_params, reference, 0); +} + +static int +create_auth_verify_GMAC_operation( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return create_auth_GMAC_operation(ts_params, ut_params, reference, 0); +} + +static int +create_cipher_auth_verify_operation(struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return create_cipher_auth_operation(ts_params, ut_params, reference, 0); +} + +static int +test_authentication_verify_fail_when_data_corruption( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int data_corrupted) +{ + int retval; + + uint8_t *plaintext; + + /* Create session */ + retval = create_auth_session(ut_params, + ts_params->valid_devs[0], + reference, + RTE_CRYPTO_AUTH_OP_VERIFY); + if (retval < 0) + return retval; + + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + TEST_ASSERT_NOT_NULL(ut_params->ibuf, + "Failed to allocate input buffer in mempool"); + + /* clear mbuf payload */ + memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->ibuf)); + + plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + reference->plaintext.len); + TEST_ASSERT_NOT_NULL(plaintext, "no room to append plaintext"); + memcpy(plaintext, reference->plaintext.data, reference->plaintext.len); + + TEST_HEXDUMP(stdout, "plaintext:", plaintext, reference->plaintext.len); + + /* Create operation */ + retval = create_auth_verify_operation(ts_params, ut_params, reference); + + if (retval < 0) + return retval; + + if (data_corrupted) + data_corruption(plaintext); + else + tag_corruption(plaintext, reference->plaintext.len); + + ut_params->op = process_crypto_request(ts_params->valid_devs[0], + ut_params->op); + TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process"); + TEST_ASSERT_EQUAL(ut_params->op->status, + RTE_CRYPTO_OP_STATUS_AUTH_FAILED, + "authentication not failed"); + + ut_params->obuf = ut_params->op->sym->m_src; + TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf"); + + return 0; +} + +static int +test_authentication_verify_GMAC_fail_when_corruption( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int data_corrupted) +{ + int retval; + + /* Create session */ + retval = create_auth_cipher_session(ut_params, + ts_params->valid_devs[0], + reference, + RTE_CRYPTO_AUTH_OP_VERIFY, + RTE_CRYPTO_CIPHER_OP_DECRYPT); + if (retval < 0) + return retval; + + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + TEST_ASSERT_NOT_NULL(ut_params->ibuf, + "Failed to allocate input buffer in mempool"); + + /* clear mbuf payload */ + memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->ibuf)); + + /* Create operation */ + retval = create_auth_verify_GMAC_operation(ts_params, + ut_params, + reference); + + if (retval < 0) + return retval; + + if (data_corrupted) + data_corruption(ut_params->op->sym->auth.aad.data); + else + tag_corruption(ut_params->op->sym->auth.aad.data, reference->aad.len); + + ut_params->op = process_crypto_request(ts_params->valid_devs[0], + ut_params->op); + TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process"); + TEST_ASSERT_EQUAL(ut_params->op->status, + RTE_CRYPTO_OP_STATUS_AUTH_FAILED, + "authentication not failed"); + + ut_params->obuf = ut_params->op->sym->m_src; + TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf"); + + return 0; +} + +static int +test_authenticated_decryption_fail_when_corruption( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int data_corrupted) +{ + int retval; + + uint8_t *ciphertext; + + /* Create session */ + retval = create_auth_cipher_session(ut_params, + ts_params->valid_devs[0], + reference, + RTE_CRYPTO_AUTH_OP_VERIFY, + RTE_CRYPTO_CIPHER_OP_DECRYPT); + if (retval < 0) + return retval; + + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + TEST_ASSERT_NOT_NULL(ut_params->ibuf, + "Failed to allocate input buffer in mempool"); + + /* clear mbuf payload */ + memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->ibuf)); + + ciphertext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + reference->ciphertext.len); + TEST_ASSERT_NOT_NULL(ciphertext, "no room to append ciphertext"); + memcpy(ciphertext, reference->ciphertext.data, reference->ciphertext.len); + + /* Create operation */ + retval = create_cipher_auth_verify_operation(ts_params, + ut_params, + reference); + + if (retval < 0) + return retval; + + if (data_corrupted) + data_corruption(ciphertext); + else + tag_corruption(ciphertext, reference->ciphertext.len); + + ut_params->op = process_crypto_request(ts_params->valid_devs[0], + ut_params->op); + + TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process"); + TEST_ASSERT_EQUAL(ut_params->op->status, + RTE_CRYPTO_OP_STATUS_AUTH_FAILED, + "authentication not failed"); + + ut_params->obuf = ut_params->op->sym->m_src; + TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf"); + + return 0; +} + +static int +test_authentication_verify_fail_when_data_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authentication_verify_fail_when_data_corruption( + ts_params, ut_params, reference, 1); +} + +static int +test_authentication_verify_fail_when_tag_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authentication_verify_fail_when_data_corruption( + ts_params, ut_params, reference, 0); +} + +static int +test_authentication_verify_GMAC_fail_when_data_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authentication_verify_GMAC_fail_when_corruption( + ts_params, ut_params, reference, 1); +} + +static int +test_authentication_verify_GMAC_fail_when_tag_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authentication_verify_GMAC_fail_when_corruption( + ts_params, ut_params, reference, 0); +} + +static int +test_authenticated_decryption_fail_when_data_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authenticated_decryption_fail_when_corruption( + ts_params, ut_params, reference, 1); +} + +static int +test_authenticated_decryption_fail_when_tag_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authenticated_decryption_fail_when_corruption( + ts_params, ut_params, reference, 0); +} + +static int +authentication_verify_HMAC_SHA1_fail_when_data_corrupted(void) +{ + return test_authentication_verify_fail_when_data_corrupted( + &testsuite_params, &unittest_params, + &hmac_sha1_test_crypto_vector); +} + +static int +authentication_verify_HMAC_SHA1_fail_when_tag_corrupted(void) +{ + return test_authentication_verify_fail_when_tag_corrupted( + &testsuite_params, &unittest_params, + &hmac_sha1_test_crypto_vector); +} + +static int +authentication_verify_AES128_GMAC_fail_when_data_corrupted(void) +{ + return test_authentication_verify_GMAC_fail_when_data_corrupted( + &testsuite_params, &unittest_params, + &aes128_gmac_test_vector); +} + +static int +authentication_verify_AES128_GMAC_fail_when_tag_corrupted(void) +{ + return test_authentication_verify_GMAC_fail_when_tag_corrupted( + &testsuite_params, &unittest_params, + &aes128_gmac_test_vector); +} + +static int +auth_decryption_AES128CBC_HMAC_SHA1_fail_when_data_corrupted(void) +{ + return test_authenticated_decryption_fail_when_data_corrupted( + &testsuite_params, + &unittest_params, + &aes128cbc_hmac_sha1_test_vector); +} + +static int +auth_decryption_AES128CBC_HMAC_SHA1_fail_when_tag_corrupted(void) +{ + return test_authenticated_decryption_fail_when_tag_corrupted( + &testsuite_params, + &unittest_params, + &aes128cbc_hmac_sha1_test_vector); +} + +static struct unit_test_suite cryptodev_qat_testsuite = { + .suite_name = "Crypto QAT Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, + test_device_configure_invalid_dev_id), + TEST_CASE_ST(ut_setup, ut_teardown, + test_device_configure_invalid_queue_pair_ids), + TEST_CASE_ST(ut_setup, ut_teardown, + test_queue_pair_descriptor_setup), + TEST_CASE_ST(ut_setup, ut_teardown, + test_multi_session), + + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_qat_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_3DES_chain_qat_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_3DES_cipheronly_qat_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_stats), + + /** AES GCM Authenticated Encryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_7), + + /** AES GCM Authenticated Decryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_7), + + /** AES GMAC Authentication */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_3), + + /** SNOW 3G encrypt only (UEA2) */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_encryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_encryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_encryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_encryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_encryption_test_case_5), + + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_encryption_test_case_1_oop), TEST_CASE_ST(ut_setup, ut_teardown, test_snow3g_decryption_test_case_1_oop), @@ -4604,7 +5887,88 @@ static struct unit_test_suite cryptodev_aesni_mb_testsuite = { .setup = testsuite_setup, .teardown = testsuite_teardown, .unit_test_cases = { - TEST_CASE_ST(ut_setup, ut_teardown, test_AES_mb_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_mb_all), + + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +static struct unit_test_suite cryptodev_libcrypto_testsuite = { + .suite_name = "Crypto Device LIBCRYPTO Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, test_multi_session), + TEST_CASE_ST(ut_setup, ut_teardown, test_multi_session_random_usage), + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_libcrypto_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_cipheronly_libcrypto_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_3DES_chain_libcrypto_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_3DES_cipheronly_libcrypto_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_authonly_libcrypto_all), + + /** AES GCM Authenticated Encryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_7), + + /** AES GCM Authenticated Decryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_7), + + /** AES GMAC Authentication */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_4), + + /** Negative tests */ + TEST_CASE_ST(ut_setup, ut_teardown, + authentication_verify_HMAC_SHA1_fail_when_data_corrupted), + TEST_CASE_ST(ut_setup, ut_teardown, + authentication_verify_HMAC_SHA1_fail_when_tag_corrupted), + TEST_CASE_ST(ut_setup, ut_teardown, + authentication_verify_AES128_GMAC_fail_when_data_corrupted), + TEST_CASE_ST(ut_setup, ut_teardown, + authentication_verify_AES128_GMAC_fail_when_tag_corrupted), + TEST_CASE_ST(ut_setup, ut_teardown, + auth_decryption_AES128CBC_HMAC_SHA1_fail_when_data_corrupted), + TEST_CASE_ST(ut_setup, ut_teardown, + auth_decryption_AES128CBC_HMAC_SHA1_fail_when_tag_corrupted), TEST_CASES_END() /**< NULL terminate unit test array */ } @@ -4823,6 +6187,14 @@ test_cryptodev_aesni_mb(void /*argv __rte_unused, int argc __rte_unused*/) } static int +test_cryptodev_libcrypto(void) +{ + gbl_cryptodev_type = RTE_CRYPTODEV_LIBCRYPTO_PMD; + + return unit_test_suite_runner(&cryptodev_libcrypto_testsuite); +} + +static int test_cryptodev_aesni_gcm(void) { gbl_cryptodev_type = RTE_CRYPTODEV_AESNI_GCM_PMD; @@ -4856,6 +6228,7 @@ test_cryptodev_sw_kasumi(void /*argv __rte_unused, int argc __rte_unused*/) REGISTER_TEST_COMMAND(cryptodev_qat_autotest, test_cryptodev_qat); REGISTER_TEST_COMMAND(cryptodev_aesni_mb_autotest, test_cryptodev_aesni_mb); +REGISTER_TEST_COMMAND(cryptodev_libcrypto_autotest, test_cryptodev_libcrypto); REGISTER_TEST_COMMAND(cryptodev_aesni_gcm_autotest, test_cryptodev_aesni_gcm); REGISTER_TEST_COMMAND(cryptodev_null_autotest, test_cryptodev_null); REGISTER_TEST_COMMAND(cryptodev_sw_snow3g_autotest, test_cryptodev_sw_snow3g); diff --git a/app/test/test_cryptodev.h b/app/test/test_cryptodev.h index 3c37c32..a9089aa 100644 --- a/app/test/test_cryptodev.h +++ b/app/test/test_cryptodev.h @@ -63,6 +63,7 @@ #define DIGEST_BYTE_LENGTH_SNOW3G_UIA2 (BYTE_LENGTH(32)) #define DIGEST_BYTE_LENGTH_KASUMI_F9 (BYTE_LENGTH(32)) #define AES_XCBC_MAC_KEY_SZ (16) +#define DIGEST_BYTE_LENGTH_AES_GCM (BYTE_LENGTH(128)) #define TRUNCATED_DIGEST_BYTE_LENGTH_SHA1 (12) #define TRUNCATED_DIGEST_BYTE_LENGTH_SHA224 (16) diff --git a/app/test/test_cryptodev_aes.c b/app/test/test_cryptodev_aes.c deleted file mode 100644 index e19c45b..0000000 --- a/app/test/test_cryptodev_aes.c +++ /dev/null @@ -1,687 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2015-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_common.h> -#include <rte_hexdump.h> -#include <rte_mbuf.h> -#include <rte_malloc.h> -#include <rte_memcpy.h> - -#include <rte_crypto.h> -#include <rte_cryptodev.h> -#include <rte_cryptodev_pmd.h> - -#include "test.h" -#include "test_cryptodev_aes.h" - -#ifndef AES_TEST_MSG_LEN -#define AES_TEST_MSG_LEN 256 -#endif - -#define AES_TEST_OP_ENCRYPT 0x01 -#define AES_TEST_OP_DECRYPT 0x02 -#define AES_TEST_OP_AUTH_GEN 0x04 -#define AES_TEST_OP_AUTH_VERIFY 0x08 - -#define AES_TEST_FEATURE_OOP 0x01 -#define AES_TEST_FEATURE_SESSIONLESS 0x02 -#define AES_TEST_FEATURE_STOPPER 0x04 /* stop upon failing */ - -#define AES_TEST_TARGET_PMD_MB 0x0001 /* Multi-buffer flag */ -#define AES_TEST_TARGET_PMD_QAT 0x0002 /* QAT flag */ - -#define AES_TEST_OP_CIPHER (AES_TEST_OP_ENCRYPT | \ - AES_TEST_OP_DECRYPT) - -#define AES_TEST_OP_AUTH (AES_TEST_OP_AUTH_GEN | \ - AES_TEST_OP_AUTH_VERIFY) - -#define AES_TEST_OP_ENC_AUTH_GEN (AES_TEST_OP_ENCRYPT | \ - AES_TEST_OP_AUTH_GEN) - -#define AES_TEST_OP_AUTH_VERIFY_DEC (AES_TEST_OP_DECRYPT | \ - AES_TEST_OP_AUTH_VERIFY) - -struct aes_test_case { - const char *test_descr; /* test description */ - const struct aes_test_data *test_data; - uint8_t op_mask; /* operation mask */ - uint8_t feature_mask; - uint32_t pmd_mask; -}; - -static const struct aes_test_case aes_test_cases[] = { - { - .test_descr = "AES-128-CTR HMAC-SHA1 Encryption Digest", - .test_data = &aes_test_data_1, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CTR HMAC-SHA1 Decryption Digest " - "Verify", - .test_data = &aes_test_data_1, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-192-CTR XCBC Encryption Digest", - .test_data = &aes_test_data_2, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-192-CTR XCBC Decryption Digest Verify", - .test_data = &aes_test_data_2, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-256-CTR HMAC-SHA1 Encryption Digest", - .test_data = &aes_test_data_3, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-256-CTR HMAC-SHA1 Decryption Digest " - "Verify", - .test_data = &aes_test_data_3, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest", - .test_data = &aes_test_data_4, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " - "Verify", - .test_data = &aes_test_data_4, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA256 Encryption Digest", - .test_data = &aes_test_data_5, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA256 Decryption Digest " - "Verify", - .test_data = &aes_test_data_5, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest", - .test_data = &aes_test_data_6, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest " - "Sessionless", - .test_data = &aes_test_data_6, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .feature_mask = AES_TEST_FEATURE_SESSIONLESS, - .pmd_mask = AES_TEST_TARGET_PMD_MB - }, - { - .test_descr = "AES-128-CBC HMAC-SHA512 Decryption Digest " - "Verify", - .test_data = &aes_test_data_6, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC XCBC Encryption Digest", - .test_data = &aes_test_data_7, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC XCBC Decryption Digest Verify", - .test_data = &aes_test_data_7, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest " - "OOP", - .test_data = &aes_test_data_4, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .feature_mask = AES_TEST_FEATURE_OOP, - .pmd_mask = AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " - "Verify OOP", - .test_data = &aes_test_data_4, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .feature_mask = AES_TEST_FEATURE_OOP, - .pmd_mask = AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA224 Encryption Digest", - .test_data = &aes_test_data_8, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA224 Decryption Digest " - "Verify", - .test_data = &aes_test_data_8, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA384 Encryption Digest", - .test_data = &aes_test_data_9, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA384 Decryption Digest " - "Verify", - .test_data = &aes_test_data_9, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, -}; - -static int -test_AES_one_case(const struct aes_test_case *t, - struct rte_mempool *mbuf_pool, - struct rte_mempool *op_mpool, - uint8_t dev_id, - enum rte_cryptodev_type cryptodev_type, - char *test_msg) -{ - struct rte_mbuf *ibuf = NULL; - struct rte_mbuf *obuf = NULL; - struct rte_mbuf *iobuf; - struct rte_crypto_sym_xform *cipher_xform = NULL; - struct rte_crypto_sym_xform *auth_xform = NULL; - struct rte_crypto_sym_xform *init_xform = NULL; - struct rte_crypto_sym_op *sym_op = NULL; - struct rte_crypto_op *op = NULL; - struct rte_cryptodev_sym_session *sess = NULL; - - int status = TEST_SUCCESS; - const struct aes_test_data *tdata = t->test_data; - uint8_t cipher_key[tdata->cipher_key.len]; - uint8_t auth_key[tdata->auth_key.len]; - uint32_t buf_len = tdata->ciphertext.len; - uint32_t digest_len = 0; - char *buf_p = NULL; - - if (tdata->cipher_key.len) - memcpy(cipher_key, tdata->cipher_key.data, - tdata->cipher_key.len); - if (tdata->auth_key.len) - memcpy(auth_key, tdata->auth_key.data, - tdata->auth_key.len); - - switch (cryptodev_type) { - case RTE_CRYPTODEV_QAT_SYM_PMD: - digest_len = tdata->digest.len; - break; - case RTE_CRYPTODEV_AESNI_MB_PMD: - digest_len = tdata->digest.truncated_len; - break; - default: - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Unsupported PMD type"); - status = TEST_FAILED; - goto error_exit; - } - - /* preparing data */ - ibuf = rte_pktmbuf_alloc(mbuf_pool); - if (!ibuf) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Allocation of rte_mbuf failed"); - status = TEST_FAILED; - goto error_exit; - } - - if (t->op_mask & AES_TEST_OP_CIPHER) - buf_len += tdata->iv.len; - if (t->op_mask & AES_TEST_OP_AUTH) - buf_len += digest_len; - - buf_p = rte_pktmbuf_append(ibuf, buf_len); - if (!buf_p) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "No room to append mbuf"); - status = TEST_FAILED; - goto error_exit; - } - - if (t->op_mask & AES_TEST_OP_CIPHER) { - rte_memcpy(buf_p, tdata->iv.data, tdata->iv.len); - buf_p += tdata->iv.len; - } - - /* only encryption requires plaintext.data input, - * decryption/(digest gen)/(digest verify) use ciphertext.data - * to be computed */ - if (t->op_mask & AES_TEST_OP_ENCRYPT) { - rte_memcpy(buf_p, tdata->plaintext.data, - tdata->plaintext.len); - buf_p += tdata->plaintext.len; - } else { - rte_memcpy(buf_p, tdata->ciphertext.data, - tdata->ciphertext.len); - buf_p += tdata->ciphertext.len; - } - - if (t->op_mask & AES_TEST_OP_AUTH_VERIFY) - rte_memcpy(buf_p, tdata->digest.data, digest_len); - else - memset(buf_p, 0, digest_len); - - if (t->feature_mask & AES_TEST_FEATURE_OOP) { - obuf = rte_pktmbuf_alloc(mbuf_pool); - if (!obuf) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, - "Allocation of rte_mbuf failed"); - status = TEST_FAILED; - goto error_exit; - } - - buf_p = rte_pktmbuf_append(obuf, buf_len); - if (!buf_p) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, - "No room to append mbuf"); - status = TEST_FAILED; - goto error_exit; - } - memset(buf_p, 0, buf_len); - } - - /* Generate Crypto op data structure */ - op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_SYMMETRIC); - if (!op) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Failed to allocate symmetric crypto " - "operation struct"); - status = TEST_FAILED; - goto error_exit; - } - - sym_op = op->sym; - - sym_op->m_src = ibuf; - - if (t->feature_mask & AES_TEST_FEATURE_OOP) { - sym_op->m_dst = obuf; - iobuf = obuf; - } else { - sym_op->m_dst = NULL; - iobuf = ibuf; - } - - /* sessionless op requires allocate xform using - * rte_crypto_op_sym_xforms_alloc(), otherwise rte_zmalloc() - * is used */ - if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) { - uint32_t n_xforms = 0; - - if (t->op_mask & AES_TEST_OP_CIPHER) - n_xforms++; - if (t->op_mask & AES_TEST_OP_AUTH) - n_xforms++; - - if (rte_crypto_op_sym_xforms_alloc(op, n_xforms) - == NULL) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, "Failed to " - "allocate space for crypto transforms"); - status = TEST_FAILED; - goto error_exit; - } - } else { - cipher_xform = rte_zmalloc(NULL, - sizeof(struct rte_crypto_sym_xform), 0); - - auth_xform = rte_zmalloc(NULL, - sizeof(struct rte_crypto_sym_xform), 0); - - if (!cipher_xform || !auth_xform) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, "Failed to " - "allocate memory for crypto transforms"); - status = TEST_FAILED; - goto error_exit; - } - } - - /* preparing xform, for sessioned op, init_xform is initialized - * here and later as param in rte_cryptodev_sym_session_create() - * call */ - if (t->op_mask == AES_TEST_OP_ENC_AUTH_GEN) { - if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) { - cipher_xform = op->sym->xform; - auth_xform = cipher_xform->next; - auth_xform->next = NULL; - } else { - cipher_xform->next = auth_xform; - auth_xform->next = NULL; - init_xform = cipher_xform; - } - } else if (t->op_mask == AES_TEST_OP_AUTH_VERIFY_DEC) { - if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) { - auth_xform = op->sym->xform; - cipher_xform = auth_xform->next; - cipher_xform->next = NULL; - } else { - auth_xform->next = cipher_xform; - cipher_xform->next = NULL; - init_xform = auth_xform; - } - } else if ((t->op_mask == AES_TEST_OP_ENCRYPT) || - (t->op_mask == AES_TEST_OP_DECRYPT)) { - if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) - cipher_xform = op->sym->xform; - else - init_xform = cipher_xform; - cipher_xform->next = NULL; - } else if ((t->op_mask == AES_TEST_OP_AUTH_GEN) || - (t->op_mask == AES_TEST_OP_AUTH_VERIFY)) { - if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) - auth_xform = op->sym->xform; - else - init_xform = auth_xform; - auth_xform->next = NULL; - } else { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Unrecognized operation"); - status = TEST_FAILED; - goto error_exit; - } - - /*configure xforms & sym_op cipher and auth data*/ - if (t->op_mask & AES_TEST_OP_CIPHER) { - cipher_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; - cipher_xform->cipher.algo = tdata->crypto_algo; - if (t->op_mask & AES_TEST_OP_ENCRYPT) - cipher_xform->cipher.op = - RTE_CRYPTO_CIPHER_OP_ENCRYPT; - else - cipher_xform->cipher.op = - RTE_CRYPTO_CIPHER_OP_DECRYPT; - cipher_xform->cipher.key.data = cipher_key; - cipher_xform->cipher.key.length = tdata->cipher_key.len; - - sym_op->cipher.data.offset = tdata->iv.len; - sym_op->cipher.data.length = tdata->ciphertext.len; - sym_op->cipher.iv.data = rte_pktmbuf_mtod(sym_op->m_src, - uint8_t *); - sym_op->cipher.iv.length = tdata->iv.len; - sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys( - sym_op->m_src); - } - - if (t->op_mask & AES_TEST_OP_AUTH) { - uint32_t auth_data_offset = 0; - uint32_t digest_offset = tdata->ciphertext.len; - - if (t->op_mask & AES_TEST_OP_CIPHER) { - digest_offset += tdata->iv.len; - auth_data_offset += tdata->iv.len; - } - - auth_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; - auth_xform->auth.algo = tdata->auth_algo; - auth_xform->auth.key.length = tdata->auth_key.len; - auth_xform->auth.key.data = auth_key; - auth_xform->auth.digest_length = digest_len; - - if (t->op_mask & AES_TEST_OP_AUTH_GEN) { - auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; - sym_op->auth.digest.data = rte_pktmbuf_mtod_offset - (iobuf, uint8_t *, digest_offset); - sym_op->auth.digest.phys_addr = - rte_pktmbuf_mtophys_offset(iobuf, - digest_offset); - } else { - auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; - sym_op->auth.digest.data = rte_pktmbuf_mtod_offset - (sym_op->m_src, uint8_t *, digest_offset); - sym_op->auth.digest.phys_addr = - rte_pktmbuf_mtophys_offset(sym_op->m_src, - digest_offset); - } - - sym_op->auth.data.offset = auth_data_offset; - sym_op->auth.data.length = tdata->ciphertext.len; - sym_op->auth.digest.length = digest_len; - } - - /* create session for sessioned op */ - if (!(t->feature_mask & AES_TEST_FEATURE_SESSIONLESS)) { - sess = rte_cryptodev_sym_session_create(dev_id, - init_xform); - if (!sess) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, - "Session creation failed"); - status = TEST_FAILED; - goto error_exit; - } - - /* attach symmetric crypto session to crypto operations */ - rte_crypto_op_attach_sym_session(op, sess); - } - - /* Process crypto operation */ - if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Error sending packet for encryption"); - status = TEST_FAILED; - goto error_exit; - } - - op = NULL; - - while (rte_cryptodev_dequeue_burst(dev_id, 0, &op, 1) == 0) - rte_pause(); - - if (!op) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Failed to process sym crypto op"); - status = TEST_FAILED; - goto error_exit; - } - - TEST_HEXDUMP(stdout, "m_src:", - rte_pktmbuf_mtod(sym_op->m_src, uint8_t *), buf_len); - if (t->feature_mask & AES_TEST_FEATURE_OOP) - TEST_HEXDUMP(stdout, "m_dst:", - rte_pktmbuf_mtod(sym_op->m_dst, uint8_t *), - buf_len); - - /* Verify results */ - if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) { - if (t->op_mask & AES_TEST_OP_AUTH_VERIFY) - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: Digest verification failed " - "(0x%X)", __LINE__, op->status); - else - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: Digest verification failed " - "(0x%X)", __LINE__, op->status); - status = TEST_FAILED; - goto error_exit; - } - - if (t->op_mask & AES_TEST_OP_CIPHER) { - uint8_t *crypto_res; - const uint8_t *compare_ref; - uint32_t compare_len; - - crypto_res = rte_pktmbuf_mtod_offset(iobuf, uint8_t *, - tdata->iv.len); - - if (t->op_mask & AES_TEST_OP_ENCRYPT) { - compare_ref = tdata->ciphertext.data; - compare_len = tdata->ciphertext.len; - } else { - compare_ref = tdata->plaintext.data; - compare_len = tdata->plaintext.len; - } - - if (memcmp(crypto_res, compare_ref, compare_len)) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, - "Crypto data not as expected"); - status = TEST_FAILED; - goto error_exit; - } - } - - if (t->op_mask & AES_TEST_OP_AUTH_GEN) { - uint8_t *auth_res; - - if (t->op_mask & AES_TEST_OP_CIPHER) - auth_res = rte_pktmbuf_mtod_offset(iobuf, - uint8_t *, - tdata->iv.len + tdata->ciphertext.len); - else - auth_res = rte_pktmbuf_mtod_offset(iobuf, - uint8_t *, tdata->ciphertext.len); - - if (memcmp(auth_res, tdata->digest.data, digest_len)) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, "Generated " - "digest data not as expected"); - status = TEST_FAILED; - goto error_exit; - } - } - - snprintf(test_msg, AES_TEST_MSG_LEN, "PASS"); - -error_exit: - if (!(t->feature_mask & AES_TEST_FEATURE_SESSIONLESS)) { - if (sess) - rte_cryptodev_sym_session_free(dev_id, sess); - if (cipher_xform) - rte_free(cipher_xform); - if (auth_xform) - rte_free(auth_xform); - } - - if (op) - rte_crypto_op_free(op); - - if (obuf) - rte_pktmbuf_free(obuf); - - if (ibuf) - rte_pktmbuf_free(ibuf); - - return status; -} - -int -test_AES_all_tests(struct rte_mempool *mbuf_pool, - struct rte_mempool *op_mpool, - uint8_t dev_id, - enum rte_cryptodev_type cryptodev_type) -{ - int status, overall_status = TEST_SUCCESS; - uint32_t i, test_index = 0; - char test_msg[AES_TEST_MSG_LEN + 1]; - uint32_t n_test_cases = sizeof(aes_test_cases) / - sizeof(aes_test_cases[0]); - uint32_t target_pmd_mask = 0; - - switch (cryptodev_type) { - case RTE_CRYPTODEV_AESNI_MB_PMD: - target_pmd_mask = AES_TEST_TARGET_PMD_MB; - break; - case RTE_CRYPTODEV_QAT_SYM_PMD: - target_pmd_mask = AES_TEST_TARGET_PMD_QAT; - break; - default: - TEST_ASSERT(-1, "Unrecognized cryptodev type"); - break; - } - - for (i = 0; i < n_test_cases; i++) { - const struct aes_test_case *tc = &aes_test_cases[i]; - - if (!(tc->pmd_mask & target_pmd_mask)) - continue; - - status = test_AES_one_case(tc, mbuf_pool, op_mpool, - dev_id, cryptodev_type, test_msg); - - printf(" %u) TestCase %s %s\n", test_index ++, - tc->test_descr, test_msg); - - if (status != TEST_SUCCESS) { - if (overall_status == TEST_SUCCESS) - overall_status = status; - - if (tc->feature_mask & AES_TEST_FEATURE_STOPPER) - break; - } - } - - return overall_status; -} diff --git a/app/test/test_cryptodev_aes.h b/app/test/test_cryptodev_aes.h deleted file mode 100644 index ef518e0..0000000 --- a/app/test/test_cryptodev_aes.h +++ /dev/null @@ -1,1124 +0,0 @@ -/*- - * 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 TEST_CRYPTODEV_AES_H_ -#define TEST_CRYPTODEV_AES_H_ - -struct aes_test_data { - enum rte_crypto_cipher_algorithm crypto_algo; - - struct { - uint8_t data[64]; - unsigned len; - } cipher_key; - - struct { - uint8_t data[64] __rte_aligned(16); - unsigned len; - } iv; - - struct { - uint8_t data[2048]; - unsigned len; - } plaintext; - - struct { - uint8_t data[2048]; - unsigned len; - } ciphertext; - - enum rte_crypto_auth_algorithm auth_algo; - - struct { - uint8_t data[128]; - unsigned len; - } auth_key; - - struct { - uint8_t data[128]; - unsigned len; /* for qat */ - unsigned truncated_len; /* for mb */ - } digest; -}; - -int -test_AES_all_tests(struct rte_mempool *mbuf_pool, - struct rte_mempool *op_mpool, - uint8_t dev_id, - enum rte_cryptodev_type cryptodev_type); - -/* test vectors */ -/* AES128-CTR-SHA1 test vector */ -static const struct aes_test_data aes_test_data_1 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, - .cipher_key = { - .data = { - 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, - 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C - }, - .len = 16 - }, - .iv = { - .data = { - 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, - 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF - }, - .len = 16 - }, - .plaintext = { - .data = { - 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, - 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, - 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, - 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, - 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, - 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, - 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, - 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 - }, - .len = 64 - }, - .ciphertext = { - .data = { - 0x87, 0x4D, 0x61, 0x91, 0xB6, 0x20, 0xE3, 0x26, - 0x1B, 0xEF, 0x68, 0x64, 0x99, 0x0D, 0xB6, 0xCE, - 0x98, 0x06, 0xF6, 0x6B, 0x79, 0x70, 0xFD, 0xFF, - 0x86, 0x17, 0x18, 0x7B, 0xB9, 0xFF, 0xFD, 0xFF, - 0x5A, 0xE4, 0xDF, 0x3E, 0xDB, 0xD5, 0xD3, 0x5E, - 0x5B, 0x4F, 0x09, 0x02, 0x0D, 0xB0, 0x3E, 0xAB, - 0x1E, 0x03, 0x1D, 0xDA, 0x2F, 0xBE, 0x03, 0xD1, - 0x79, 0x21, 0x70, 0xA0, 0xF3, 0x00, 0x9C, 0xEE - }, - .len = 64 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, - .auth_key = { - .data = { - 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, - 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, - 0xDE, 0xF4, 0xDE, 0xAD - }, - .len = 20 - }, - .digest = { - .data = { - 0x9B, 0x6F, 0x0C, 0x43, 0xF5, 0xC1, 0x3E, 0xB0, - 0xB1, 0x70, 0xB8, 0x2B, 0x33, 0x09, 0xD2, 0xB2, - 0x56, 0x20, 0xFB, 0xFE - }, - .len = 20, - .truncated_len = 12 - } -}; - -/** AES-192-CTR XCBC test vector */ -static const struct aes_test_data aes_test_data_2 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, - .cipher_key = { - .data = { - 0xCB, 0xC5, 0xED, 0x5B, 0xE7, 0x7C, 0xBD, 0x8C, - 0x50, 0xD9, 0x30, 0xF2, 0xB5, 0x6A, 0x0E, 0x5F, - 0xAA, 0xAE, 0xAD, 0xA2, 0x1F, 0x49, 0x52, 0xD4 - }, - .len = 24 - }, - .iv = { - .data = { - 0x3F, 0x69, 0xA8, 0xCD, 0xE8, 0xF0, 0xEF, 0x40, - 0xB8, 0x7A, 0x4B, 0xED, 0x2B, 0xAF, 0xBF, 0x57 - }, - .len = 16 - }, - .plaintext = { - .data = { - 0x01, 0x0F, 0x10, 0x1F, 0x20, 0x1C, 0x0E, 0xB8, - 0xFB, 0x5C, 0xCD, 0xCC, 0x1F, 0xF9, 0xAF, 0x0B, - 0x95, 0x03, 0x74, 0x99, 0x49, 0xE7, 0x62, 0x55, - 0xDA, 0xEA, 0x13, 0x20, 0x1D, 0xC6, 0xCC, 0xCC, - 0xD1, 0x70, 0x75, 0x47, 0x02, 0x2F, 0xFB, 0x86, - 0xBB, 0x6B, 0x23, 0xD2, 0xC9, 0x74, 0xD7, 0x7B, - 0x08, 0x03, 0x3B, 0x79, 0x39, 0xBB, 0x91, 0x29, - 0xDA, 0x14, 0x39, 0x8D, 0xFF, 0x81, 0x50, 0x96, - }, - .len = 64 - }, - .ciphertext = { - .data = { - 0x4A, 0x6C, 0xC8, 0xCC, 0x96, 0x2A, 0x13, 0x84, - 0x1C, 0x36, 0x88, 0xE9, 0xE5, 0x94, 0x70, 0xB2, - 0x14, 0x5B, 0x13, 0x80, 0xEA, 0xD8, 0x8D, 0x37, - 0xFD, 0x70, 0xA8, 0x83, 0xE8, 0x2B, 0x88, 0x1E, - 0xBA, 0x94, 0x3F, 0xF6, 0xB3, 0x1F, 0xDE, 0x34, - 0xF3, 0x5B, 0x80, 0xE9, 0xAB, 0xF5, 0x1C, 0x29, - 0xB6, 0xD9, 0x76, 0x2B, 0x06, 0xC6, 0x74, 0xF1, - 0x59, 0x5E, 0x9E, 0xA5, 0x7B, 0x2D, 0xD7, 0xF0 - }, - .len = 64 - }, - .auth_algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC, - .auth_key = { - .data = { - 0x87, 0x61, 0x54, 0x53, 0xC4, 0x6D, 0xDD, 0x51, - 0xE1, 0x9F, 0x86, 0x64, 0x39, 0x0A, 0xE6, 0x59 - }, - .len = 16 - }, - .digest = { - .data = { - 0xCA, 0x33, 0xB3, 0x3B, 0x16, 0x94, 0xAA, 0x55, - 0x36, 0x6B, 0x45, 0x46 - }, - .len = 12, - .truncated_len = 12 - } -}; - -/** AES-256-CTR SHA1 test vector */ -static const struct aes_test_data aes_test_data_3 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, - .cipher_key = { - .data = { - 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, - 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, - 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, - 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 - }, - .len = 32 - }, - .iv = { - .data = { - 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, - 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF - }, - .len = 16 - }, - .plaintext = { - .data = { - 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, - 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, - 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, - 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, - 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, - 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, - 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, - 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 - }, - .len = 64 - }, - .ciphertext = { - .data = { - 0x60, 0x1E, 0xC3, 0x13, 0x77, 0x57, 0x89, 0xA5, - 0xB7, 0xA7, 0xF5, 0x04, 0xBB, 0xF3, 0xD2, 0x28, - 0xF4, 0x43, 0xE3, 0xCA, 0x4D, 0x62, 0xB5, 0x9A, - 0xCA, 0x84, 0xE9, 0x90, 0xCA, 0xCA, 0xF5, 0xC5, - 0x2B, 0x09, 0x30, 0xDA, 0xA2, 0x3D, 0xE9, 0x4C, - 0xE8, 0x70, 0x17, 0xBA, 0x2D, 0x84, 0x98, 0x8D, - 0xDF, 0xC9, 0xC5, 0x8D, 0xB6, 0x7A, 0xAD, 0xA6, - 0x13, 0xC2, 0xDD, 0x08, 0x45, 0x79, 0x41, 0xA6 - }, - .len = 64 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, - .auth_key = { - .data = { - 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, - 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, - 0xDE, 0xF4, 0xDE, 0xAD - }, - .len = 20 - }, - .digest = { - .data = { - 0x3B, 0x1A, 0x9D, 0x82, 0x35, 0xD5, 0xDD, 0x64, - 0xCC, 0x1B, 0xA9, 0xC0, 0xEB, 0xE9, 0x42, 0x16, - 0xE7, 0x87, 0xA3, 0xEF - }, - .len = 20, - .truncated_len = 12 - } -}; - -/** AES-128-CBC SHA1 test vector */ -static const struct aes_test_data aes_test_data_4 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, - .auth_key = { - .data = { - 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, - 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, - 0xDE, 0xF4, 0xDE, 0xAD - }, - .len = 20 - }, - .digest = { - .data = { - 0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60, - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0x18, 0x8C, 0x1D, 0x32 - }, - .len = 20, - .truncated_len = 12 - } -}; - -/** AES-128-CBC SHA256 test vector */ -static const struct aes_test_data aes_test_data_5 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC, - .auth_key = { - .data = { - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60 - }, - .len = 32 - }, - .digest = { - .data = { - 0xC8, 0x57, 0x57, 0x31, 0x03, 0xE0, 0x03, 0x55, - 0x07, 0xC8, 0x9E, 0x7F, 0x48, 0x9A, 0x61, 0x9A, - 0x68, 0xEE, 0x03, 0x0E, 0x71, 0x75, 0xC7, 0xF4, - 0x2E, 0x45, 0x26, 0x32, 0x7C, 0x12, 0x15, 0x15 - }, - .len = 32, - .truncated_len = 16 - } -}; - -/** AES-128-CBC SHA512 test vector */ -static const struct aes_test_data aes_test_data_6 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA512_HMAC, - .auth_key = { - .data = { - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, - 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, - 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, - 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, - 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, - 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 - }, - .len = 64 - }, - .digest = { - .data = { - 0x5D, 0x54, 0x66, 0xC1, 0x6E, 0xBC, 0x04, 0xB8, - 0x46, 0xB8, 0x08, 0x6E, 0xE0, 0xF0, 0x43, 0x48, - 0x37, 0x96, 0x9C, 0xC6, 0x9C, 0xC2, 0x1E, 0xE8, - 0xF2, 0x0C, 0x0B, 0xEF, 0x86, 0xA2, 0xE3, 0x70, - 0x95, 0xC8, 0xB3, 0x06, 0x47, 0xA9, 0x90, 0xE8, - 0xA0, 0xC6, 0x72, 0x69, 0x05, 0xC0, 0x0D, 0x0E, - 0x21, 0x96, 0x65, 0x93, 0x74, 0x43, 0x2A, 0x1D, - 0x2E, 0xBF, 0xC2, 0xC2, 0xEE, 0xCC, 0x2F, 0x0A - }, - .len = 64, - .truncated_len = 32 - } -}; - -/** AES-128-CBC XCBC test vector */ -static const struct aes_test_data aes_test_data_7 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC, - .auth_key = { - .data = { - 0x87, 0x61, 0x54, 0x53, 0xC4, 0x6D, 0xDD, 0x51, - 0xE1, 0x9F, 0x86, 0x64, 0x39, 0x0A, 0xE6, 0x59 - }, - .len = 16 - }, - .digest = { - .data = { - 0xE0, 0xAC, 0x9A, 0xC4, 0x22, 0x64, 0x35, 0x89, - 0x77, 0x1D, 0x8B, 0x75 - }, - .len = 12, - .truncated_len = 12 - } -}; - -/** AES-128-CBC SHA224 test vector */ -static const struct aes_test_data aes_test_data_8 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA224_HMAC, - .auth_key = { - .data = { - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, - 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, - 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, - 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, - 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, - 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 - }, - .len = 64 - }, - .digest = { - .data = { - 0xA3, 0xCA, 0xC7, 0x1D, 0xA8, 0x61, 0x30, 0x98, - 0x3B, 0x8F, 0x01, 0x19, 0xAE, 0x8D, 0xBD, 0x34, - 0x40, 0x63, 0xA8, 0x2F, 0xDF, 0x85, 0x2B, 0x7F, - 0x63, 0x7C, 0xDD, 0xB7 - }, - .len = 28, - .truncated_len = 14 - } -}; - -/** AES-128-CBC SHA384 test vector */ -static const struct aes_test_data aes_test_data_9 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA384_HMAC, - .auth_key = { - .data = { - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, - 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, - 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, - 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, - 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, - 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60, - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, - 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, - 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, - 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, - 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, - 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 - }, - .len = 128 - }, - .digest = { - .data = { - 0x23, 0x60, 0xC8, 0xB1, 0x2D, 0x6C, 0x1E, 0x72, - 0x25, 0xAB, 0xF9, 0xC3, 0x9A, 0xA9, 0x4F, 0x8C, - 0x56, 0x38, 0x65, 0x0E, 0x74, 0xD5, 0x45, 0x9D, - 0xA3, 0xFD, 0x7E, 0x6D, 0x9E, 0x74, 0x88, 0x9D, - 0xA7, 0x12, 0x9D, 0xD8, 0x81, 0x3C, 0x86, 0x2F, - 0x4D, 0xF9, 0x6F, 0x0A, 0xB0, 0xC9, 0xEB, 0x0B - }, - .len = 48, - .truncated_len = 24 - } -}; - -#endif /* TEST_CRYPTODEV_AES_H_ */ diff --git a/app/test/test_cryptodev_aes_test_vectors.h b/app/test/test_cryptodev_aes_test_vectors.h new file mode 100644 index 0000000..ee46f9f --- /dev/null +++ b/app/test/test_cryptodev_aes_test_vectors.h @@ -0,0 +1,1095 @@ +/* + * 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 TEST_CRYPTODEV_AES_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_AES_TEST_VECTORS_H_ + +/* test vectors */ +static const uint8_t plaintext_aes128ctr[] = { + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, + 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, + 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, + 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, + 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, + 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, + 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 +}; + +static const uint8_t ciphertext64_aes128ctr[] = { + 0x87, 0x4D, 0x61, 0x91, 0xB6, 0x20, 0xE3, 0x26, + 0x1B, 0xEF, 0x68, 0x64, 0x99, 0x0D, 0xB6, 0xCE, + 0x98, 0x06, 0xF6, 0x6B, 0x79, 0x70, 0xFD, 0xFF, + 0x86, 0x17, 0x18, 0x7B, 0xB9, 0xFF, 0xFD, 0xFF, + 0x5A, 0xE4, 0xDF, 0x3E, 0xDB, 0xD5, 0xD3, 0x5E, + 0x5B, 0x4F, 0x09, 0x02, 0x0D, 0xB0, 0x3E, 0xAB, + 0x1E, 0x03, 0x1D, 0xDA, 0x2F, 0xBE, 0x03, 0xD1, + 0x79, 0x21, 0x70, 0xA0, 0xF3, 0x00, 0x9C, 0xEE +}; + +static const uint8_t plaintext_aes192ctr[] = { + 0x01, 0x0F, 0x10, 0x1F, 0x20, 0x1C, 0x0E, 0xB8, + 0xFB, 0x5C, 0xCD, 0xCC, 0x1F, 0xF9, 0xAF, 0x0B, + 0x95, 0x03, 0x74, 0x99, 0x49, 0xE7, 0x62, 0x55, + 0xDA, 0xEA, 0x13, 0x20, 0x1D, 0xC6, 0xCC, 0xCC, + 0xD1, 0x70, 0x75, 0x47, 0x02, 0x2F, 0xFB, 0x86, + 0xBB, 0x6B, 0x23, 0xD2, 0xC9, 0x74, 0xD7, 0x7B, + 0x08, 0x03, 0x3B, 0x79, 0x39, 0xBB, 0x91, 0x29, + 0xDA, 0x14, 0x39, 0x8D, 0xFF, 0x81, 0x50, 0x96, +}; + +static const uint8_t ciphertext64_aes192ctr[] = { + 0x4A, 0x6C, 0xC8, 0xCC, 0x96, 0x2A, 0x13, 0x84, + 0x1C, 0x36, 0x88, 0xE9, 0xE5, 0x94, 0x70, 0xB2, + 0x14, 0x5B, 0x13, 0x80, 0xEA, 0xD8, 0x8D, 0x37, + 0xFD, 0x70, 0xA8, 0x83, 0xE8, 0x2B, 0x88, 0x1E, + 0xBA, 0x94, 0x3F, 0xF6, 0xB3, 0x1F, 0xDE, 0x34, + 0xF3, 0x5B, 0x80, 0xE9, 0xAB, 0xF5, 0x1C, 0x29, + 0xB6, 0xD9, 0x76, 0x2B, 0x06, 0xC6, 0x74, 0xF1, + 0x59, 0x5E, 0x9E, 0xA5, 0x7B, 0x2D, 0xD7, 0xF0 +}; + +static const uint8_t plaintext_aes256ctr[] = { + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, + 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, + 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, + 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, + 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, + 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, + 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 +}; + +static const uint8_t ciphertext64_aes256ctr[] = { + 0x60, 0x1E, 0xC3, 0x13, 0x77, 0x57, 0x89, 0xA5, + 0xB7, 0xA7, 0xF5, 0x04, 0xBB, 0xF3, 0xD2, 0x28, + 0xF4, 0x43, 0xE3, 0xCA, 0x4D, 0x62, 0xB5, 0x9A, + 0xCA, 0x84, 0xE9, 0x90, 0xCA, 0xCA, 0xF5, 0xC5, + 0x2B, 0x09, 0x30, 0xDA, 0xA2, 0x3D, 0xE9, 0x4C, + 0xE8, 0x70, 0x17, 0xBA, 0x2D, 0x84, 0x98, 0x8D, + 0xDF, 0xC9, 0xC5, 0x8D, 0xB6, 0x7A, 0xAD, 0xA6, + 0x13, 0xC2, 0xDD, 0x08, 0x45, 0x79, 0x41, 0xA6 +}; + +static const uint8_t plaintext_aes_common[] = { + "What a lousy earth! He wondered how many people " + "were destitute that same night even in his own " + "prosperous country, how many homes were " + "shanties, how many husbands were drunk and " + "wives socked, and how many children were " + "bullied, abused, or abandoned. How many " + "families hungered for food they could not " + "afford to buy? How many hearts were broken? How " + "many suicides would take place that same night, " + "how many people would go insane? How many " + "cockroaches and landlords would triumph? How " + "many winners were losers, successes failures, " + "and rich men poor men? How many wise guys were " + "stupid? How many happy endings were unhappy " + "endings? How many honest men were liars, brave " + "men cowards, loyal men traitors, how many " + "sainted men were corrupt, how many people in " + "positions of trust had sold their souls to " + "bodyguards, how many had never had souls? How " + "many straight-and-narrow paths were crooked " + "paths? How many best families were worst " + "families and how many good people were bad " + "people? When you added them all up and then " + "subtracted, you might be left with only the " + "children, and perhaps with Albert Einstein and " + "an old violinist or sculptor somewhere." +}; + +static const uint8_t ciphertext512_aes128cbc[] = { + 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, + 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, + 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, + 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, + 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, + 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, + 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, + 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, + 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, + 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, + 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, + 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, + 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, + 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, + 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, + 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, + 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, + 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, + 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, + 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, + 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, + 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, + 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, + 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, + 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, + 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, + 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, + 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, + 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, + 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, + 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, + 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, + 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, + 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, + 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, + 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, + 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, + 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, + 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, + 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, + 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, + 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, + 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, + 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, + 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, + 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, + 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, + 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, + 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, + 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, + 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, + 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, + 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, + 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, + 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, + 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, + 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, + 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, + 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, + 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, + 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, + 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C +}; + +/* AES128-CTR-SHA1 test vector */ +static const struct blockcipher_test_data aes_test_data_1 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key = { + .data = { + 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C + }, + .len = 16 + }, + .iv = { + .data = { + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes128ctr, + .len = 64 + }, + .ciphertext = { + .data = ciphertext64_aes128ctr, + .len = 64 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x9B, 0x6F, 0x0C, 0x43, 0xF5, 0xC1, 0x3E, 0xB0, + 0xB1, 0x70, 0xB8, 0x2B, 0x33, 0x09, 0xD2, 0xB2, + 0x56, 0x20, 0xFB, 0xFE + }, + .len = 20, + .truncated_len = 12 + } +}; + +/** AES-192-CTR XCBC test vector */ +static const struct blockcipher_test_data aes_test_data_2 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key = { + .data = { + 0xCB, 0xC5, 0xED, 0x5B, 0xE7, 0x7C, 0xBD, 0x8C, + 0x50, 0xD9, 0x30, 0xF2, 0xB5, 0x6A, 0x0E, 0x5F, + 0xAA, 0xAE, 0xAD, 0xA2, 0x1F, 0x49, 0x52, 0xD4 + }, + .len = 24 + }, + .iv = { + .data = { + 0x3F, 0x69, 0xA8, 0xCD, 0xE8, 0xF0, 0xEF, 0x40, + 0xB8, 0x7A, 0x4B, 0xED, 0x2B, 0xAF, 0xBF, 0x57 + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes192ctr, + .len = 64 + }, + .ciphertext = { + .data = ciphertext64_aes192ctr, + .len = 64 + }, + .auth_algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC, + .auth_key = { + .data = { + 0x87, 0x61, 0x54, 0x53, 0xC4, 0x6D, 0xDD, 0x51, + 0xE1, 0x9F, 0x86, 0x64, 0x39, 0x0A, 0xE6, 0x59 + }, + .len = 16 + }, + .digest = { + .data = { + 0xCA, 0x33, 0xB3, 0x3B, 0x16, 0x94, 0xAA, 0x55, + 0x36, 0x6B, 0x45, 0x46 + }, + .len = 12, + .truncated_len = 12 + } +}; + +/** AES-256-CTR SHA1 test vector */ +static const struct blockcipher_test_data aes_test_data_3 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key = { + .data = { + 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, + 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, + 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, + 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 + }, + .len = 32 + }, + .iv = { + .data = { + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes256ctr, + .len = 64 + }, + .ciphertext = { + .data = ciphertext64_aes256ctr, + .len = 64 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x3B, 0x1A, 0x9D, 0x82, 0x35, 0xD5, 0xDD, 0x64, + 0xCC, 0x1B, 0xA9, 0xC0, 0xEB, 0xE9, 0x42, 0x16, + 0xE7, 0x87, 0xA3, 0xEF + }, + .len = 20, + .truncated_len = 12 + } +}; + +/** AES-128-CBC SHA1 test vector */ +static const struct blockcipher_test_data aes_test_data_4 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60, + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0x18, 0x8C, 0x1D, 0x32 + }, + .len = 20, + .truncated_len = 12 + } +}; + +/** AES-128-CBC SHA256 test vector */ +static const struct blockcipher_test_data aes_test_data_5 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC, + .auth_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, + 0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60 + }, + .len = 32 + }, + .digest = { + .data = { + 0xC8, 0x57, 0x57, 0x31, 0x03, 0xE0, 0x03, 0x55, + 0x07, 0xC8, 0x9E, 0x7F, 0x48, 0x9A, 0x61, 0x9A, + 0x68, 0xEE, 0x03, 0x0E, 0x71, 0x75, 0xC7, 0xF4, + 0x2E, 0x45, 0x26, 0x32, 0x7C, 0x12, 0x15, 0x15 + }, + .len = 32, + .truncated_len = 16 + } +}; + +/** AES-128-CBC SHA512 test vector */ +static const struct blockcipher_test_data aes_test_data_6 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA512_HMAC, + .auth_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 + }, + .len = 64 + }, + .digest = { + .data = { + 0x5D, 0x54, 0x66, 0xC1, 0x6E, 0xBC, 0x04, 0xB8, + 0x46, 0xB8, 0x08, 0x6E, 0xE0, 0xF0, 0x43, 0x48, + 0x37, 0x96, 0x9C, 0xC6, 0x9C, 0xC2, 0x1E, 0xE8, + 0xF2, 0x0C, 0x0B, 0xEF, 0x86, 0xA2, 0xE3, 0x70, + 0x95, 0xC8, 0xB3, 0x06, 0x47, 0xA9, 0x90, 0xE8, + 0xA0, 0xC6, 0x72, 0x69, 0x05, 0xC0, 0x0D, 0x0E, + 0x21, 0x96, 0x65, 0x93, 0x74, 0x43, 0x2A, 0x1D, + 0x2E, 0xBF, 0xC2, 0xC2, 0xEE, 0xCC, 0x2F, 0x0A + }, + .len = 64, + .truncated_len = 32 + } +}; + +/** AES-128-CBC XCBC test vector */ +static const struct blockcipher_test_data aes_test_data_7 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC, + .auth_key = { + .data = { + 0x87, 0x61, 0x54, 0x53, 0xC4, 0x6D, 0xDD, 0x51, + 0xE1, 0x9F, 0x86, 0x64, 0x39, 0x0A, 0xE6, 0x59 + }, + .len = 16 + }, + .digest = { + .data = { + 0xE0, 0xAC, 0x9A, 0xC4, 0x22, 0x64, 0x35, 0x89, + 0x77, 0x1D, 0x8B, 0x75 + }, + .len = 12, + .truncated_len = 12 + } +}; + +/** AES-128-CBC SHA224 test vector */ +static const struct blockcipher_test_data aes_test_data_8 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA224_HMAC, + .auth_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 + }, + .len = 64 + }, + .digest = { + .data = { + 0xA3, 0xCA, 0xC7, 0x1D, 0xA8, 0x61, 0x30, 0x98, + 0x3B, 0x8F, 0x01, 0x19, 0xAE, 0x8D, 0xBD, 0x34, + 0x40, 0x63, 0xA8, 0x2F, 0xDF, 0x85, 0x2B, 0x7F, + 0x63, 0x7C, 0xDD, 0xB7 + }, + .len = 28, + .truncated_len = 14 + } +}; + +/** AES-128-CBC SHA384 test vector */ +static const struct blockcipher_test_data aes_test_data_9 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA384_HMAC, + .auth_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60, + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 + }, + .len = 128 + }, + .digest = { + .data = { + 0x23, 0x60, 0xC8, 0xB1, 0x2D, 0x6C, 0x1E, 0x72, + 0x25, 0xAB, 0xF9, 0xC3, 0x9A, 0xA9, 0x4F, 0x8C, + 0x56, 0x38, 0x65, 0x0E, 0x74, 0xD5, 0x45, 0x9D, + 0xA3, 0xFD, 0x7E, 0x6D, 0x9E, 0x74, 0x88, 0x9D, + 0xA7, 0x12, 0x9D, 0xD8, 0x81, 0x3C, 0x86, 0x2F, + 0x4D, 0xF9, 0x6F, 0x0A, 0xB0, 0xC9, 0xEB, 0x0B + }, + .len = 48, + .truncated_len = 24 + } +}; + +static const uint8_t ciphertext512_aes192cbc[] = { + 0x45, 0xEE, 0x9A, 0xEA, 0x3C, 0x03, 0xFC, 0x4C, + 0x84, 0x36, 0xB0, 0xDA, 0xB0, 0xDC, 0xF3, 0x5B, + 0x75, 0xA7, 0xBE, 0x0E, 0xC0, 0x8D, 0x6C, 0xF8, + 0xC1, 0x0F, 0xD0, 0x35, 0x1D, 0x82, 0xAE, 0x7C, + 0x57, 0xC5, 0x7A, 0x55, 0x87, 0x1B, 0xD4, 0x03, + 0x0A, 0x64, 0xC9, 0xE0, 0xF4, 0xC7, 0x6F, 0x57, + 0x52, 0xC6, 0x73, 0xBA, 0x84, 0x0B, 0x5B, 0x89, + 0x21, 0xD2, 0x9B, 0x88, 0x68, 0xF5, 0xA9, 0x7F, + 0x3F, 0x49, 0xEB, 0xF4, 0xD4, 0x52, 0xD2, 0x64, + 0x80, 0xB2, 0x53, 0xDA, 0x19, 0xF6, 0x10, 0x24, + 0x23, 0x26, 0x7A, 0x7C, 0x07, 0x57, 0x4B, 0x0E, + 0x58, 0x49, 0x61, 0xD1, 0xDC, 0x9A, 0x32, 0x6B, + 0x0F, 0x43, 0x9E, 0x4D, 0xB4, 0x07, 0x4E, 0xB3, + 0x51, 0x74, 0xDE, 0x29, 0xBC, 0x98, 0xF9, 0xDF, + 0x78, 0x9A, 0x18, 0x9C, 0xD6, 0x7A, 0x55, 0x7C, + 0xE6, 0x1D, 0x5C, 0x1A, 0x99, 0xD2, 0xC3, 0x7B, + 0x9F, 0x96, 0x74, 0x2D, 0xE0, 0xEF, 0xD1, 0xE3, + 0x08, 0x9F, 0xAF, 0xE6, 0xED, 0xCA, 0xE1, 0xEA, + 0x23, 0x6F, 0x7C, 0x81, 0xA8, 0xC0, 0x5B, 0x8B, + 0x53, 0x90, 0x51, 0x2D, 0x0F, 0xF6, 0x7D, 0xA7, + 0x1C, 0xBD, 0x83, 0x84, 0x54, 0xA4, 0x15, 0xFB, + 0x3E, 0x25, 0xA7, 0x3A, 0x0A, 0x73, 0xD9, 0x88, + 0x6F, 0x80, 0x78, 0x95, 0x7F, 0x60, 0xAA, 0x86, + 0x8A, 0xFC, 0xDF, 0xC1, 0xCB, 0xDE, 0xBB, 0x25, + 0x52, 0x20, 0xC6, 0x79, 0xD4, 0x0F, 0x25, 0xE7, + 0xDB, 0xB2, 0x17, 0xA4, 0x6F, 0x3C, 0x6F, 0x91, + 0xF6, 0x44, 0x1E, 0xB6, 0x85, 0xBC, 0x7A, 0x14, + 0x10, 0x72, 0xBD, 0x16, 0x63, 0x39, 0x9E, 0x7B, + 0x84, 0x5B, 0x17, 0x61, 0xB1, 0x5D, 0x82, 0x0B, + 0x6D, 0x37, 0xD7, 0x79, 0xB8, 0x24, 0x91, 0x30, + 0x82, 0x91, 0x02, 0xB1, 0x18, 0x4B, 0xE0, 0xF4, + 0x13, 0x1B, 0xB2, 0x4C, 0xDA, 0xB8, 0x99, 0x96, + 0x83, 0x2F, 0xBE, 0x53, 0x8D, 0xDE, 0xFA, 0xAD, + 0xF6, 0x5C, 0xDB, 0xE5, 0x66, 0x26, 0x8F, 0x13, + 0x2B, 0x76, 0x47, 0x73, 0xDE, 0x1A, 0x74, 0xA6, + 0x30, 0xAF, 0x42, 0xA0, 0xE5, 0xD2, 0x8F, 0xC2, + 0xED, 0x3E, 0x9E, 0x29, 0x54, 0x3C, 0xDE, 0x9F, + 0x5D, 0x30, 0x2B, 0x63, 0xFB, 0xE3, 0xB1, 0x07, + 0xEE, 0x74, 0x4A, 0xAF, 0xB1, 0x20, 0x8D, 0xEC, + 0xE6, 0x78, 0x16, 0x8D, 0xA4, 0x6E, 0x34, 0x7D, + 0x47, 0xFB, 0x0B, 0xC1, 0x32, 0xD7, 0x0D, 0x6C, + 0x6F, 0x93, 0x9C, 0x5E, 0xEF, 0x1F, 0x9C, 0x45, + 0x80, 0x6B, 0x74, 0xA6, 0x81, 0xF2, 0xF6, 0xFA, + 0xAA, 0x9D, 0x4F, 0xCA, 0xB5, 0x90, 0x59, 0xB0, + 0x3B, 0xF2, 0xF0, 0x75, 0xFD, 0x8A, 0xD8, 0x97, + 0x65, 0x88, 0x56, 0x4C, 0x44, 0xDF, 0x73, 0xF7, + 0x56, 0x9C, 0x48, 0x7E, 0xB0, 0x1F, 0x1D, 0x7D, + 0x6A, 0x11, 0xF5, 0xC2, 0xF4, 0x17, 0xEF, 0x58, + 0xD8, 0x2A, 0xAF, 0x56, 0x2F, 0xCF, 0xEC, 0xA4, + 0x58, 0x8B, 0x60, 0xCE, 0xD4, 0x0F, 0x9C, 0x21, + 0xEC, 0x3E, 0x74, 0x7B, 0x81, 0x3D, 0x69, 0xC6, + 0x5E, 0x12, 0x83, 0xE9, 0xEF, 0x81, 0x58, 0x36, + 0x6A, 0x60, 0x0F, 0x54, 0x28, 0x11, 0xF9, 0x64, + 0x36, 0xAD, 0x79, 0xF5, 0x1C, 0x74, 0xD0, 0xC3, + 0x7B, 0x61, 0xE1, 0x92, 0xB0, 0x13, 0x91, 0x87, + 0x32, 0x1F, 0xF2, 0x5A, 0xDA, 0x25, 0x69, 0xEB, + 0xD7, 0x32, 0x7F, 0xF5, 0x23, 0x21, 0x54, 0x47, + 0x7B, 0x1B, 0x33, 0xB0, 0x3D, 0xF6, 0xE2, 0x7E, + 0x3E, 0xA2, 0x9E, 0xCA, 0x48, 0x0B, 0x4A, 0x29, + 0x81, 0xD4, 0x4E, 0xD5, 0x69, 0xFB, 0xCD, 0x37, + 0x8A, 0xC1, 0x5B, 0x50, 0xFF, 0xB5, 0x7D, 0x43, + 0x0F, 0xAE, 0xA6, 0xC2, 0xE5, 0x8F, 0x45, 0xB2, + 0x85, 0x99, 0x02, 0xA2, 0x9B, 0xBE, 0x90, 0x43, + 0x4F, 0x2F, 0x50, 0xE2, 0x77, 0x62, 0xD9, 0xCC +}; + +/** AES-192-CBC test vector */ +static const struct blockcipher_test_data aes_test_data_10 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes192cbc, + .len = 512 + } +}; + +static const uint8_t ciphertext512_aes256cbc[] = { + 0xF3, 0xDD, 0xF0, 0x0B, 0xFF, 0xA2, 0x6A, 0x04, + 0xBE, 0xDA, 0x52, 0xA6, 0xFE, 0x6B, 0xA6, 0xA7, + 0x48, 0x1D, 0x7D, 0x98, 0x65, 0xDB, 0xEF, 0x06, + 0x26, 0xB5, 0x8E, 0xEB, 0x05, 0x0E, 0x77, 0x98, + 0x17, 0x8E, 0xD0, 0xD4, 0x7B, 0x92, 0x8F, 0x5C, + 0xD0, 0x74, 0x5C, 0xA8, 0x4B, 0x54, 0xB6, 0x2F, + 0x83, 0x72, 0x2C, 0xFF, 0x72, 0xE9, 0xE4, 0x15, + 0x4C, 0x32, 0xAF, 0xC8, 0xC9, 0x89, 0x3C, 0x6E, + 0x31, 0xD5, 0xC0, 0x16, 0xC0, 0x31, 0x7D, 0x11, + 0xAB, 0xCB, 0xDE, 0xD2, 0xD6, 0xAA, 0x76, 0x5E, + 0xBA, 0xF6, 0xE2, 0x92, 0xCB, 0x86, 0x07, 0xFA, + 0xD4, 0x9E, 0x83, 0xED, 0xFD, 0xB8, 0x70, 0x54, + 0x6B, 0xBE, 0xEC, 0x72, 0xDD, 0x28, 0x5E, 0x95, + 0x78, 0xA5, 0x28, 0x43, 0x3D, 0x6D, 0xB1, 0xD9, + 0x69, 0x1F, 0xC9, 0x66, 0x0E, 0x32, 0x44, 0x08, + 0xD2, 0xAE, 0x2C, 0x43, 0xF2, 0xD0, 0x7D, 0x26, + 0x70, 0xE5, 0xA1, 0xCA, 0x37, 0xE9, 0x7D, 0xC7, + 0xA3, 0xFA, 0x81, 0x91, 0x64, 0xAA, 0x64, 0x91, + 0x9A, 0x95, 0x2D, 0xC9, 0xF9, 0xCE, 0xFE, 0x9F, + 0xC4, 0xD8, 0x81, 0xBE, 0x57, 0x84, 0xC5, 0x02, + 0xDB, 0x30, 0xC1, 0xD9, 0x0E, 0xA0, 0xA6, 0x00, + 0xD6, 0xF3, 0x52, 0x7E, 0x0D, 0x23, 0x6B, 0x2B, + 0x34, 0x99, 0x1F, 0x70, 0x27, 0x6D, 0x58, 0x84, + 0x93, 0x77, 0xB8, 0x3E, 0xF1, 0x71, 0x58, 0x42, + 0x8B, 0x2B, 0xC8, 0x6D, 0x05, 0x84, 0xFF, 0x4E, + 0x85, 0xEF, 0x4A, 0x9D, 0x91, 0x6A, 0xD5, 0xE1, + 0xAF, 0x01, 0xEB, 0x83, 0x8F, 0x23, 0x7C, 0x7F, + 0x12, 0x91, 0x05, 0xF0, 0x4E, 0xD9, 0x17, 0x62, + 0x75, 0xBB, 0xAC, 0x97, 0xEE, 0x3B, 0x4E, 0xC7, + 0xE5, 0x92, 0xF8, 0x9D, 0x4C, 0xF9, 0xEE, 0x55, + 0x18, 0xBB, 0xCC, 0xB4, 0xF2, 0x59, 0xB9, 0xFC, + 0x7A, 0x0F, 0x98, 0xD4, 0x8B, 0xFE, 0xF7, 0x83, + 0x46, 0xE2, 0x83, 0x33, 0x3E, 0x95, 0x8D, 0x17, + 0x1E, 0x85, 0xF8, 0x8C, 0x51, 0xB0, 0x6C, 0xB5, + 0x5E, 0x95, 0xBA, 0x4B, 0x69, 0x1B, 0x48, 0x69, + 0x0B, 0x8F, 0xA5, 0x18, 0x13, 0xB9, 0x77, 0xD1, + 0x80, 0x32, 0x32, 0x6D, 0x53, 0xA1, 0x95, 0x40, + 0x96, 0x8A, 0xCC, 0xA3, 0x69, 0xF8, 0x9F, 0xB5, + 0x8E, 0xD2, 0x68, 0x07, 0x4F, 0xA7, 0xEC, 0xF8, + 0x20, 0x21, 0x58, 0xF8, 0xD8, 0x9E, 0x5F, 0x40, + 0xBA, 0xB9, 0x76, 0x57, 0x3B, 0x17, 0xAD, 0xEE, + 0xCB, 0xDF, 0x07, 0xC1, 0xDF, 0x66, 0xA8, 0x0D, + 0xC2, 0xCE, 0x8F, 0x79, 0xC3, 0x32, 0xE0, 0x8C, + 0xFE, 0x5A, 0xF3, 0x55, 0x27, 0x73, 0x6F, 0xA1, + 0x54, 0xC6, 0xFC, 0x28, 0x9D, 0xBE, 0x97, 0xB9, + 0x54, 0x97, 0x72, 0x3A, 0x61, 0xAF, 0x6F, 0xDE, + 0xF8, 0x0E, 0xBB, 0x6B, 0x96, 0x84, 0xDD, 0x9B, + 0x62, 0xBA, 0x47, 0xB5, 0xC9, 0x3B, 0x4E, 0x8C, + 0x78, 0x2A, 0xCC, 0x0A, 0x69, 0x54, 0x25, 0x5E, + 0x8B, 0xAC, 0x56, 0xD9, 0xFE, 0x48, 0xBA, 0xCE, + 0xA9, 0xCE, 0xA6, 0x1D, 0xBF, 0x3E, 0x3C, 0x66, + 0x40, 0x71, 0x79, 0xAD, 0x5B, 0x26, 0xAD, 0xBE, + 0x58, 0x13, 0x64, 0x60, 0x7C, 0x05, 0xFC, 0xE3, + 0x51, 0x7A, 0xF2, 0xCC, 0x54, 0x16, 0x2C, 0xA4, + 0xCE, 0x5F, 0x59, 0x12, 0x77, 0xEB, 0xD9, 0x23, + 0xE3, 0x86, 0xFB, 0xD7, 0x48, 0x76, 0x9D, 0xE3, + 0x89, 0x87, 0x39, 0xFA, 0x7B, 0x21, 0x0B, 0x76, + 0xB2, 0xED, 0x1C, 0x27, 0x4B, 0xD5, 0x27, 0x05, + 0x8C, 0x7D, 0x58, 0x6C, 0xCA, 0xA5, 0x54, 0x9A, + 0x0F, 0xCB, 0xE9, 0x88, 0x31, 0xAD, 0x49, 0xEE, + 0x38, 0xFB, 0xC9, 0xFB, 0xB4, 0x7A, 0x00, 0x58, + 0x20, 0x32, 0xD3, 0x53, 0x5A, 0xDD, 0x74, 0x95, + 0x60, 0x59, 0x09, 0xAE, 0x7E, 0xEC, 0x74, 0xA3, + 0xB7, 0x1C, 0x6D, 0xF2, 0xAE, 0x79, 0xA4, 0x7C +}; + +/** AES-256-CBC test vector */ +static const struct blockcipher_test_data aes_test_data_11 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0, + 0x37, 0x07, 0xB8, 0x23, 0xA2, 0xA3, 0xB5, 0x8D + }, + .len = 32 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes256cbc, + .len = 512 + } +}; + +static const struct blockcipher_test_case aes_chain_test_cases[] = { + { + .test_descr = "AES-128-CTR HMAC-SHA1 Encryption Digest", + .test_data = &aes_test_data_1, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CTR HMAC-SHA1 Decryption Digest " + "Verify", + .test_data = &aes_test_data_1, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-192-CTR XCBC Encryption Digest", + .test_data = &aes_test_data_2, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-192-CTR XCBC Decryption Digest Verify", + .test_data = &aes_test_data_2, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-256-CTR HMAC-SHA1 Encryption Digest", + .test_data = &aes_test_data_3, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-256-CTR HMAC-SHA1 Decryption Digest " + "Verify", + .test_data = &aes_test_data_3, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " + "Verify", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA256 Encryption Digest", + .test_data = &aes_test_data_5, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA256 Decryption Digest " + "Verify", + .test_data = &aes_test_data_5, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest", + .test_data = &aes_test_data_6, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest " + "Sessionless", + .test_data = &aes_test_data_6, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-128-CBC HMAC-SHA512 Decryption Digest " + "Verify", + .test_data = &aes_test_data_6, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC XCBC Encryption Digest", + .test_data = &aes_test_data_7, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC XCBC Decryption Digest Verify", + .test_data = &aes_test_data_7, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest " + "OOP", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " + "Verify OOP", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-128-CBC HMAC-SHA224 Encryption Digest", + .test_data = &aes_test_data_8, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA224 Decryption Digest " + "Verify", + .test_data = &aes_test_data_8, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA384 Encryption Digest", + .test_data = &aes_test_data_9, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA384 Decryption Digest " + "Verify", + .test_data = &aes_test_data_9, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest Sessionless", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = + "AES-128-CBC HMAC-SHA1 Decryption Digest Verify Sessionless", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, +}; + +static const struct blockcipher_test_case aes_cipheronly_test_cases[] = { + { + .test_descr = "AES-128-CBC Encryption", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-128-CBC Decryption", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-192-CBC Encryption", + .test_data = &aes_test_data_10, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-192-CBC Decryption", + .test_data = &aes_test_data_10, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-256-CBC Encryption", + .test_data = &aes_test_data_11, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-256-CBC Decryption", + .test_data = &aes_test_data_11, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-128-CTR Encryption", + .test_data = &aes_test_data_1, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-128-CTR Decryption", + .test_data = &aes_test_data_1, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-192-CTR Encryption", + .test_data = &aes_test_data_2, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-192-CTR Decryption", + .test_data = &aes_test_data_2, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-256-CTR Encryption", + .test_data = &aes_test_data_3, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-256-CTR Decryption", + .test_data = &aes_test_data_3, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, +}; + +#endif /* TEST_CRYPTODEV_AES_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_blockcipher.c b/app/test/test_cryptodev_blockcipher.c new file mode 100644 index 0000000..6649080 --- /dev/null +++ b/app/test/test_cryptodev_blockcipher.c @@ -0,0 +1,531 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2015-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_common.h> +#include <rte_hexdump.h> +#include <rte_mbuf.h> +#include <rte_malloc.h> +#include <rte_memcpy.h> + +#include <rte_crypto.h> +#include <rte_cryptodev.h> +#include <rte_cryptodev_pmd.h> + +#include "test.h" +#include "test_cryptodev_blockcipher.h" +#include "test_cryptodev_aes_test_vectors.h" +#include "test_cryptodev_des_test_vectors.h" +#include "test_cryptodev_hash_test_vectors.h" + +static int +test_blockcipher_one_case(const struct blockcipher_test_case *t, + struct rte_mempool *mbuf_pool, + struct rte_mempool *op_mpool, + uint8_t dev_id, + enum rte_cryptodev_type cryptodev_type, + char *test_msg) +{ + struct rte_mbuf *ibuf = NULL; + struct rte_mbuf *obuf = NULL; + struct rte_mbuf *iobuf; + struct rte_crypto_sym_xform *cipher_xform = NULL; + struct rte_crypto_sym_xform *auth_xform = NULL; + struct rte_crypto_sym_xform *init_xform = NULL; + struct rte_crypto_sym_op *sym_op = NULL; + struct rte_crypto_op *op = NULL; + struct rte_cryptodev_sym_session *sess = NULL; + + int status = TEST_SUCCESS; + const struct blockcipher_test_data *tdata = t->test_data; + uint8_t cipher_key[tdata->cipher_key.len]; + uint8_t auth_key[tdata->auth_key.len]; + uint32_t buf_len = tdata->ciphertext.len; + uint32_t digest_len = 0; + char *buf_p = NULL; + + if (tdata->cipher_key.len) + memcpy(cipher_key, tdata->cipher_key.data, + tdata->cipher_key.len); + if (tdata->auth_key.len) + memcpy(auth_key, tdata->auth_key.data, + tdata->auth_key.len); + + switch (cryptodev_type) { + case RTE_CRYPTODEV_QAT_SYM_PMD: + case RTE_CRYPTODEV_LIBCRYPTO_PMD: + digest_len = tdata->digest.len; + break; + case RTE_CRYPTODEV_AESNI_MB_PMD: + digest_len = tdata->digest.truncated_len; + break; + default: + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Unsupported PMD type"); + status = TEST_FAILED; + goto error_exit; + } + + /* preparing data */ + ibuf = rte_pktmbuf_alloc(mbuf_pool); + if (!ibuf) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Allocation of rte_mbuf failed"); + status = TEST_FAILED; + goto error_exit; + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) + buf_len += tdata->iv.len; + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) + buf_len += digest_len; + + buf_p = rte_pktmbuf_append(ibuf, buf_len); + if (!buf_p) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "No room to append mbuf"); + status = TEST_FAILED; + goto error_exit; + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { + rte_memcpy(buf_p, tdata->iv.data, tdata->iv.len); + buf_p += tdata->iv.len; + } + + /* only encryption requires plaintext.data input, + * decryption/(digest gen)/(digest verify) use ciphertext.data + * to be computed + */ + if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) { + rte_memcpy(buf_p, tdata->plaintext.data, + tdata->plaintext.len); + buf_p += tdata->plaintext.len; + } else { + rte_memcpy(buf_p, tdata->ciphertext.data, + tdata->ciphertext.len); + buf_p += tdata->ciphertext.len; + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) + rte_memcpy(buf_p, tdata->digest.data, digest_len); + else + memset(buf_p, 0, digest_len); + + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) { + obuf = rte_pktmbuf_alloc(mbuf_pool); + if (!obuf) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "Allocation of rte_mbuf failed"); + status = TEST_FAILED; + goto error_exit; + } + + buf_p = rte_pktmbuf_append(obuf, buf_len); + if (!buf_p) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "No room to append mbuf"); + status = TEST_FAILED; + goto error_exit; + } + memset(buf_p, 0, buf_len); + } + + /* Generate Crypto op data structure */ + op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_SYMMETRIC); + if (!op) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Failed to allocate symmetric crypto " + "operation struct"); + status = TEST_FAILED; + goto error_exit; + } + + sym_op = op->sym; + + sym_op->m_src = ibuf; + + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) { + sym_op->m_dst = obuf; + iobuf = obuf; + } else { + sym_op->m_dst = NULL; + iobuf = ibuf; + } + + /* sessionless op requires allocate xform using + * rte_crypto_op_sym_xforms_alloc(), otherwise rte_zmalloc() + * is used + */ + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) { + uint32_t n_xforms = 0; + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) + n_xforms++; + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) + n_xforms++; + + if (rte_crypto_op_sym_xforms_alloc(op, n_xforms) + == NULL) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, "Failed to " + "allocate space for crypto transforms"); + status = TEST_FAILED; + goto error_exit; + } + } else { + cipher_xform = rte_zmalloc(NULL, + sizeof(struct rte_crypto_sym_xform), 0); + + auth_xform = rte_zmalloc(NULL, + sizeof(struct rte_crypto_sym_xform), 0); + + if (!cipher_xform || !auth_xform) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, "Failed to " + "allocate memory for crypto transforms"); + status = TEST_FAILED; + goto error_exit; + } + } + + /* preparing xform, for sessioned op, init_xform is initialized + * here and later as param in rte_cryptodev_sym_session_create() call + */ + if (t->op_mask == BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN) { + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) { + cipher_xform = op->sym->xform; + auth_xform = cipher_xform->next; + auth_xform->next = NULL; + } else { + cipher_xform->next = auth_xform; + auth_xform->next = NULL; + init_xform = cipher_xform; + } + } else if (t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC) { + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) { + auth_xform = op->sym->xform; + cipher_xform = auth_xform->next; + cipher_xform->next = NULL; + } else { + auth_xform->next = cipher_xform; + cipher_xform->next = NULL; + init_xform = auth_xform; + } + } else if ((t->op_mask == BLOCKCIPHER_TEST_OP_ENCRYPT) || + (t->op_mask == BLOCKCIPHER_TEST_OP_DECRYPT)) { + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) + cipher_xform = op->sym->xform; + else + init_xform = cipher_xform; + cipher_xform->next = NULL; + } else if ((t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_GEN) || + (t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_VERIFY)) { + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) + auth_xform = op->sym->xform; + else + init_xform = auth_xform; + auth_xform->next = NULL; + } else { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Unrecognized operation"); + status = TEST_FAILED; + goto error_exit; + } + + /*configure xforms & sym_op cipher and auth data*/ + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { + cipher_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; + cipher_xform->cipher.algo = tdata->crypto_algo; + if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) + cipher_xform->cipher.op = + RTE_CRYPTO_CIPHER_OP_ENCRYPT; + else + cipher_xform->cipher.op = + RTE_CRYPTO_CIPHER_OP_DECRYPT; + cipher_xform->cipher.key.data = cipher_key; + cipher_xform->cipher.key.length = tdata->cipher_key.len; + + sym_op->cipher.data.offset = tdata->iv.len; + sym_op->cipher.data.length = tdata->ciphertext.len; + sym_op->cipher.iv.data = rte_pktmbuf_mtod(sym_op->m_src, + uint8_t *); + sym_op->cipher.iv.length = tdata->iv.len; + sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys( + sym_op->m_src); + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) { + uint32_t auth_data_offset = 0; + uint32_t digest_offset = tdata->ciphertext.len; + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { + digest_offset += tdata->iv.len; + auth_data_offset += tdata->iv.len; + } + + auth_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; + auth_xform->auth.algo = tdata->auth_algo; + auth_xform->auth.key.length = tdata->auth_key.len; + auth_xform->auth.key.data = auth_key; + auth_xform->auth.digest_length = digest_len; + + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) { + auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; + sym_op->auth.digest.data = rte_pktmbuf_mtod_offset + (iobuf, uint8_t *, digest_offset); + sym_op->auth.digest.phys_addr = + rte_pktmbuf_mtophys_offset(iobuf, + digest_offset); + } else { + auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; + sym_op->auth.digest.data = rte_pktmbuf_mtod_offset + (sym_op->m_src, uint8_t *, digest_offset); + sym_op->auth.digest.phys_addr = + rte_pktmbuf_mtophys_offset(sym_op->m_src, + digest_offset); + } + + sym_op->auth.data.offset = auth_data_offset; + sym_op->auth.data.length = tdata->ciphertext.len; + sym_op->auth.digest.length = digest_len; + } + + /* create session for sessioned op */ + if (!(t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)) { + sess = rte_cryptodev_sym_session_create(dev_id, + init_xform); + if (!sess) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "Session creation failed"); + status = TEST_FAILED; + goto error_exit; + } + + /* attach symmetric crypto session to crypto operations */ + rte_crypto_op_attach_sym_session(op, sess); + } + + /* Process crypto operation */ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Error sending packet for encryption"); + status = TEST_FAILED; + goto error_exit; + } + + op = NULL; + + while (rte_cryptodev_dequeue_burst(dev_id, 0, &op, 1) == 0) + rte_pause(); + + if (!op) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Failed to process sym crypto op"); + status = TEST_FAILED; + goto error_exit; + } + + TEST_HEXDUMP(stdout, "m_src:", + rte_pktmbuf_mtod(sym_op->m_src, uint8_t *), buf_len); + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) + TEST_HEXDUMP(stdout, "m_dst:", + rte_pktmbuf_mtod(sym_op->m_dst, uint8_t *), + buf_len); + + /* Verify results */ + if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) { + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: Digest verification failed " + "(0x%X)", __LINE__, op->status); + else + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: Digest verification failed " + "(0x%X)", __LINE__, op->status); + status = TEST_FAILED; + goto error_exit; + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { + uint8_t *crypto_res; + const uint8_t *compare_ref; + uint32_t compare_len; + + crypto_res = rte_pktmbuf_mtod_offset(iobuf, uint8_t *, + tdata->iv.len); + + if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) { + compare_ref = tdata->ciphertext.data; + compare_len = tdata->ciphertext.len; + } else { + compare_ref = tdata->plaintext.data; + compare_len = tdata->plaintext.len; + } + + if (memcmp(crypto_res, compare_ref, compare_len)) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "Crypto data not as expected"); + status = TEST_FAILED; + goto error_exit; + } + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) { + uint8_t *auth_res; + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) + auth_res = rte_pktmbuf_mtod_offset(iobuf, + uint8_t *, + tdata->iv.len + tdata->ciphertext.len); + else + auth_res = rte_pktmbuf_mtod_offset(iobuf, + uint8_t *, tdata->ciphertext.len); + + if (memcmp(auth_res, tdata->digest.data, digest_len)) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, "Generated " + "digest data not as expected"); + status = TEST_FAILED; + goto error_exit; + } + } + + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "PASS"); + +error_exit: + if (!(t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)) { + if (sess) + rte_cryptodev_sym_session_free(dev_id, sess); + if (cipher_xform) + rte_free(cipher_xform); + if (auth_xform) + rte_free(auth_xform); + } + + if (op) + rte_crypto_op_free(op); + + if (obuf) + rte_pktmbuf_free(obuf); + + if (ibuf) + rte_pktmbuf_free(ibuf); + + return status; +} + +int +test_blockcipher_all_tests(struct rte_mempool *mbuf_pool, + struct rte_mempool *op_mpool, + uint8_t dev_id, + enum rte_cryptodev_type cryptodev_type, + enum blockcipher_test_type test_type) +{ + int status, overall_status = TEST_SUCCESS; + uint32_t i, test_index = 0; + char test_msg[BLOCKCIPHER_TEST_MSG_LEN + 1]; + uint32_t n_test_cases = 0; + uint32_t target_pmd_mask = 0; + const struct blockcipher_test_case *tcs = NULL; + + switch (test_type) { + case BLKCIPHER_AES_CHAIN_TYPE: + n_test_cases = sizeof(aes_chain_test_cases) / + sizeof(aes_chain_test_cases[0]); + tcs = aes_chain_test_cases; + break; + case BLKCIPHER_AES_CIPHERONLY_TYPE: + n_test_cases = sizeof(aes_cipheronly_test_cases) / + sizeof(aes_cipheronly_test_cases[0]); + tcs = aes_cipheronly_test_cases; + break; + case BLKCIPHER_3DES_CHAIN_TYPE: + n_test_cases = sizeof(triple_des_chain_test_cases) / + sizeof(triple_des_chain_test_cases[0]); + tcs = triple_des_chain_test_cases; + break; + case BLKCIPHER_3DES_CIPHERONLY_TYPE: + n_test_cases = sizeof(triple_des_cipheronly_test_cases) / + sizeof(triple_des_cipheronly_test_cases[0]); + tcs = triple_des_cipheronly_test_cases; + break; + case BLKCIPHER_AUTHONLY_TYPE: + n_test_cases = sizeof(hash_test_cases) / + sizeof(hash_test_cases[0]); + tcs = hash_test_cases; + break; + default: + break; + } + + switch (cryptodev_type) { + case RTE_CRYPTODEV_AESNI_MB_PMD: + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB; + break; + case RTE_CRYPTODEV_QAT_SYM_PMD: + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT; + break; + case RTE_CRYPTODEV_LIBCRYPTO_PMD: + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO; + break; + default: + TEST_ASSERT(0, "Unrecognized cryptodev type"); + break; + } + + for (i = 0; i < n_test_cases; i++) { + const struct blockcipher_test_case *tc = &tcs[i]; + + if (!(tc->pmd_mask & target_pmd_mask)) + continue; + + status = test_blockcipher_one_case(tc, mbuf_pool, op_mpool, + dev_id, cryptodev_type, test_msg); + + printf(" %u) TestCase %s %s\n", test_index ++, + tc->test_descr, test_msg); + + if (status != TEST_SUCCESS) { + if (overall_status == TEST_SUCCESS) + overall_status = status; + + if (tc->feature_mask & BLOCKCIPHER_TEST_FEATURE_STOPPER) + break; + } + } + + return overall_status; +} diff --git a/app/test/test_cryptodev_blockcipher.h b/app/test/test_cryptodev_blockcipher.h new file mode 100644 index 0000000..3232a86 --- /dev/null +++ b/app/test/test_cryptodev_blockcipher.h @@ -0,0 +1,125 @@ +/*- + * 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 TEST_CRYPTODEV_BLOCKCIPHER_H_ +#define TEST_CRYPTODEV_BLOCKCIPHER_H_ + +#ifndef BLOCKCIPHER_TEST_MSG_LEN +#define BLOCKCIPHER_TEST_MSG_LEN 256 +#endif + +#define BLOCKCIPHER_TEST_OP_ENCRYPT 0x01 +#define BLOCKCIPHER_TEST_OP_DECRYPT 0x02 +#define BLOCKCIPHER_TEST_OP_AUTH_GEN 0x04 +#define BLOCKCIPHER_TEST_OP_AUTH_VERIFY 0x08 + +#define BLOCKCIPHER_TEST_FEATURE_OOP 0x01 +#define BLOCKCIPHER_TEST_FEATURE_SESSIONLESS 0x02 +#define BLOCKCIPHER_TEST_FEATURE_STOPPER 0x04 /* stop upon failing */ + +#define BLOCKCIPHER_TEST_TARGET_PMD_MB 0x0001 /* Multi-buffer flag */ +#define BLOCKCIPHER_TEST_TARGET_PMD_QAT 0x0002 /* QAT flag */ +#define BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO 0x0004 /* SW LIBCRYPTO flag */ + +#define BLOCKCIPHER_TEST_OP_CIPHER (BLOCKCIPHER_TEST_OP_ENCRYPT | \ + BLOCKCIPHER_TEST_OP_DECRYPT) + +#define BLOCKCIPHER_TEST_OP_AUTH (BLOCKCIPHER_TEST_OP_AUTH_GEN | \ + BLOCKCIPHER_TEST_OP_AUTH_VERIFY) + +#define BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN (BLOCKCIPHER_TEST_OP_ENCRYPT | \ + BLOCKCIPHER_TEST_OP_AUTH_GEN) + +#define BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC (BLOCKCIPHER_TEST_OP_DECRYPT | \ + BLOCKCIPHER_TEST_OP_AUTH_VERIFY) + +enum blockcipher_test_type { + BLKCIPHER_AES_CHAIN_TYPE, /* use aes_chain_test_cases[] */ + BLKCIPHER_AES_CIPHERONLY_TYPE, /* use aes_cipheronly_test_cases[] */ + BLKCIPHER_3DES_CHAIN_TYPE, /* use triple_des_chain_test_cases[] */ + BLKCIPHER_3DES_CIPHERONLY_TYPE, /* triple_des_cipheronly_test_cases[] */ + BLKCIPHER_AUTHONLY_TYPE /* use hash_test_cases[] */ +}; + +struct blockcipher_test_case { + const char *test_descr; /* test description */ + const struct blockcipher_test_data *test_data; + uint8_t op_mask; /* operation mask */ + uint8_t feature_mask; + uint32_t pmd_mask; +}; + +struct blockcipher_test_data { + enum rte_crypto_cipher_algorithm crypto_algo; + + struct { + uint8_t data[64]; + unsigned int len; + } cipher_key; + + struct { + uint8_t data[64] __rte_aligned(16); + unsigned int len; + } iv; + + struct { + const uint8_t *data; + unsigned int len; + } plaintext; + + struct { + const uint8_t *data; + unsigned int len; + } ciphertext; + + enum rte_crypto_auth_algorithm auth_algo; + + struct { + uint8_t data[128]; + unsigned int len; + } auth_key; + + struct { + uint8_t data[128]; + unsigned int len; /* for qat */ + unsigned int truncated_len; /* for mb */ + } digest; +}; + +int +test_blockcipher_all_tests(struct rte_mempool *mbuf_pool, + struct rte_mempool *op_mpool, + uint8_t dev_id, + enum rte_cryptodev_type cryptodev_type, + enum blockcipher_test_type test_type); + +#endif /* TEST_CRYPTODEV_BLOCKCIPHER_H_ */ diff --git a/app/test/test_cryptodev_des_test_vectors.h b/app/test/test_cryptodev_des_test_vectors.h new file mode 100644 index 0000000..f3144fe --- /dev/null +++ b/app/test/test_cryptodev_des_test_vectors.h @@ -0,0 +1,952 @@ +/* + * 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 TEST_CRYPTODEV_DES_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_DES_TEST_VECTORS_H_ + +static const uint8_t plaintext_des[] = { + "What a lousy earth! He wondered how many people " + "were destitute that same night even in his own " + "prosperous country, how many homes were " + "shanties, how many husbands were drunk and " + "wives socked, and how many children were " + "bullied, abused, or abandoned. How many " + "families hungered for food they could not " + "afford to buy? How many hearts were broken? How " + "many suicides would take place that same night, " + "how many people would go insane? How many " + "cockroaches and landlords would triumph? How " + "many winners were losers, successes failures, " + "and rich men poor men? How many wise guys were " + "stupid? How many happy endings were unhappy " + "endings? How many honest men were liars, brave " + "men cowards, loyal men traitors, how many " + "sainted men were corrupt, how many people in " + "positions of trust had sold their souls to " + "bodyguards, how many had never had souls? How " + "many straight-and-narrow paths were crooked " + "paths? How many best families were worst " + "families and how many good people were bad " + "people? When you added them all up and then " + "subtracted, you might be left with only the " + "children, and perhaps with Albert Einstein and " + "an old violinist or sculptor somewhere." +}; + +static const uint8_t ciphertext512_des128ctr[] = { + 0x13, 0x39, 0x3B, 0xBC, 0x1D, 0xE3, 0x23, 0x09, + 0x9B, 0x08, 0xD1, 0x09, 0x52, 0x93, 0x78, 0x29, + 0x11, 0x21, 0xBA, 0x01, 0x15, 0xCD, 0xEC, 0xAA, + 0x79, 0x77, 0x58, 0xAE, 0xAE, 0xBC, 0x97, 0x33, + 0x94, 0xA9, 0x2D, 0xC0, 0x0A, 0xA9, 0xA4, 0x4B, + 0x19, 0x07, 0x88, 0x06, 0x7E, 0x81, 0x0F, 0xB5, + 0x60, 0xCF, 0xA7, 0xC3, 0x2A, 0x43, 0xFF, 0x16, + 0x3A, 0x5F, 0x11, 0x2D, 0x11, 0x38, 0x37, 0x94, + 0x2A, 0xC8, 0x3D, 0x20, 0xBB, 0x93, 0x95, 0x54, + 0x12, 0xFF, 0x0C, 0x47, 0x89, 0x7D, 0x73, 0xD1, + 0x2E, 0x3A, 0x80, 0x52, 0xA8, 0x92, 0x93, 0x99, + 0x16, 0xB8, 0x12, 0x1B, 0x8B, 0xA8, 0xC1, 0x81, + 0x95, 0x18, 0x82, 0xD6, 0x5A, 0xA7, 0xFE, 0xCF, + 0xC4, 0xAC, 0x85, 0x91, 0x0C, 0x2F, 0x1D, 0x10, + 0x9A, 0x65, 0x07, 0xB0, 0x2E, 0x5A, 0x2D, 0x48, + 0x26, 0xF8, 0x17, 0x7A, 0x53, 0xD6, 0xB8, 0xDF, + 0xB1, 0x10, 0x48, 0x7E, 0x8F, 0xBE, 0x2E, 0xA1, + 0x0D, 0x9E, 0xA9, 0xF1, 0x3B, 0x3B, 0x33, 0xCD, + 0xDC, 0x52, 0x7E, 0xC0, 0x0E, 0xA0, 0xD8, 0xA7, + 0xC6, 0x34, 0x5A, 0xAA, 0x29, 0x8B, 0xA9, 0xAC, + 0x1F, 0x78, 0xAD, 0xEE, 0x34, 0x59, 0x30, 0xFB, + 0x2A, 0x20, 0x3D, 0x4D, 0x30, 0xA7, 0x7D, 0xD8, + 0xA0, 0xC6, 0xA2, 0xD3, 0x9A, 0xFB, 0x50, 0x97, + 0x4D, 0x25, 0xA2, 0x37, 0x51, 0x54, 0xB7, 0xEB, + 0xED, 0x77, 0xDB, 0x94, 0x35, 0x8B, 0x70, 0x95, + 0x4A, 0x00, 0xA7, 0xF1, 0x8A, 0x66, 0x0E, 0xC6, + 0x05, 0x7B, 0x69, 0x05, 0x42, 0x03, 0x96, 0x2C, + 0x55, 0x00, 0x1B, 0xC0, 0x19, 0x4D, 0x0D, 0x2E, + 0xF5, 0x81, 0x11, 0x64, 0xCA, 0xBB, 0xF2, 0x0F, + 0x9C, 0x60, 0xE2, 0xCC, 0x02, 0x6E, 0x83, 0xD5, + 0x24, 0xF4, 0x12, 0x0E, 0x6A, 0xEA, 0x4F, 0x6C, + 0x79, 0x69, 0x65, 0x67, 0xDB, 0xF7, 0xEA, 0x98, + 0x5D, 0x56, 0x98, 0xB7, 0x88, 0xE7, 0x23, 0xC9, + 0x17, 0x32, 0x92, 0x33, 0x5A, 0x0C, 0x15, 0x20, + 0x3B, 0x1C, 0xF9, 0x0F, 0x4D, 0xD1, 0xE8, 0xE6, + 0x9E, 0x5E, 0x24, 0x1B, 0xA4, 0xB8, 0xB9, 0xE9, + 0x2F, 0xFC, 0x89, 0xB4, 0xB9, 0xF4, 0xA6, 0xAD, + 0x55, 0xF4, 0xDF, 0x58, 0x63, 0x25, 0xE3, 0x41, + 0x70, 0xDF, 0x10, 0xE7, 0x13, 0x87, 0x8D, 0xB3, + 0x62, 0x4F, 0xF5, 0x86, 0x85, 0x8F, 0x59, 0xF0, + 0x21, 0x0E, 0x8F, 0x11, 0xAD, 0xBF, 0xDD, 0x61, + 0x68, 0x3F, 0x54, 0x57, 0x49, 0x38, 0xC8, 0x24, + 0x8E, 0x0A, 0xAC, 0xCA, 0x2C, 0x36, 0x3E, 0x5F, + 0x0A, 0xCE, 0xFD, 0x1A, 0x60, 0x63, 0x5A, 0xE6, + 0x06, 0x64, 0xB5, 0x94, 0x3C, 0xC9, 0xAF, 0x7C, + 0xCD, 0x49, 0x10, 0xCF, 0xAF, 0x0E, 0x2E, 0x79, + 0x27, 0xB2, 0x67, 0x02, 0xED, 0xEE, 0x80, 0x77, + 0x7C, 0x6D, 0x4B, 0xDB, 0xCF, 0x8D, 0x68, 0x00, + 0x2E, 0xD9, 0xF0, 0x8E, 0x08, 0xBF, 0xA6, 0x9B, + 0xFE, 0xA4, 0xFB, 0x19, 0x46, 0xAF, 0x1B, 0xA9, + 0xF8, 0x22, 0x81, 0x21, 0x97, 0xFC, 0xC0, 0x8A, + 0x26, 0x58, 0x13, 0x29, 0xB6, 0x69, 0x94, 0x4B, + 0xAB, 0xB3, 0x88, 0x0D, 0xA9, 0x48, 0x0E, 0xE8, + 0x70, 0xFC, 0xA1, 0x21, 0xC4, 0x2C, 0xE5, 0x99, + 0xB4, 0xF1, 0x6F, 0xB2, 0x4B, 0x4B, 0xCD, 0x48, + 0x15, 0x47, 0x2D, 0x72, 0x39, 0x99, 0x9D, 0x24, + 0x0C, 0x8B, 0xDC, 0xA1, 0xEE, 0xF6, 0xF4, 0x73, + 0xC3, 0xB8, 0x0C, 0x23, 0x0D, 0xA7, 0xC4, 0x7D, + 0x27, 0xE2, 0x14, 0x11, 0x53, 0x19, 0xE7, 0xCA, + 0x94, 0x4E, 0x0D, 0x2C, 0xF7, 0x36, 0x47, 0xDB, + 0x77, 0x3C, 0x22, 0xAC, 0xBE, 0xE1, 0x06, 0x55, + 0xE5, 0xDD, 0x8B, 0x65, 0xE8, 0xE9, 0x91, 0x52, + 0x59, 0x97, 0xFC, 0x8C, 0xEE, 0x96, 0x22, 0x60, + 0xEE, 0xBF, 0x82, 0xF0, 0xCA, 0x14, 0xF9, 0xD3 +}; + +static const struct blockcipher_test_data +triple_des128ctr_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128ctr, + .len = 512 + } +}; + +static const struct blockcipher_test_data +triple_des128ctr_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128ctr, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .digest = { + .data = { + 0xC3, 0x40, 0xD5, 0xD9, 0x8F, 0x8A, 0xC0, 0xF0, + 0x46, 0x28, 0x02, 0x01, 0xB5, 0xC1, 0x87, 0x4D, + 0xAC, 0xFE, 0x48, 0x76 + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +triple_des128ctr_hmac_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128ctr, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0xF1, 0xC1, 0xDB, 0x4D, 0xFA, 0x7F, 0x2F, 0xE5, + 0xF8, 0x49, 0xEA, 0x1D, 0x7F, 0xCB, 0x42, 0x59, + 0xC4, 0x1E, 0xB1, 0x18 + }, + .len = 20 + } +}; + +static const uint8_t ciphertext512_des192ctr[] = { + 0xFF, 0x32, 0x52, 0x97, 0x10, 0xBF, 0x0B, 0x10, + 0x68, 0x0F, 0x4F, 0x56, 0x8B, 0x2C, 0x7B, 0x8E, + 0x39, 0x1E, 0x1A, 0x2F, 0x83, 0xDE, 0x5E, 0x35, + 0xC8, 0x4B, 0xDF, 0xD5, 0xBC, 0x84, 0x50, 0x1A, + 0x02, 0xDF, 0xB3, 0x11, 0xE4, 0xDA, 0xB8, 0x0E, + 0x47, 0xC6, 0x0C, 0x51, 0x09, 0x62, 0x9C, 0x5D, + 0x71, 0x40, 0x49, 0xD8, 0x55, 0xBD, 0x7D, 0x90, + 0x71, 0xC5, 0xF7, 0x07, 0x6F, 0x08, 0x71, 0x2A, + 0xB1, 0x77, 0x9B, 0x0F, 0xA1, 0xB0, 0xD6, 0x10, + 0xB2, 0xE5, 0x31, 0xEC, 0x21, 0x13, 0x89, 0x2A, + 0x09, 0x7E, 0x30, 0xDB, 0xA0, 0xF0, 0xDC, 0xE4, + 0x74, 0x64, 0x39, 0xA3, 0xB0, 0xB1, 0x80, 0x66, + 0x52, 0xD4, 0x4E, 0xC9, 0x5A, 0x52, 0x6A, 0xC7, + 0xB5, 0x2B, 0x61, 0xD5, 0x17, 0xD5, 0xF3, 0xCC, + 0x41, 0x61, 0xD2, 0xA6, 0xF4, 0x51, 0x24, 0x3A, + 0x63, 0x5D, 0x23, 0xB1, 0xF0, 0x22, 0xE7, 0x45, + 0xFA, 0x5F, 0x7E, 0x99, 0x00, 0x11, 0x28, 0x35, + 0xA3, 0xF4, 0x61, 0x94, 0x0E, 0x98, 0xCE, 0x35, + 0xDD, 0x91, 0x1B, 0x0B, 0x4D, 0xEE, 0xFF, 0xFF, + 0x0B, 0xD4, 0xDC, 0x56, 0xFC, 0x71, 0xE9, 0xEC, + 0xE8, 0x36, 0x51, 0xF8, 0x8B, 0x6A, 0xE1, 0x8C, + 0x2B, 0x25, 0x91, 0x91, 0x9B, 0x92, 0x76, 0xB5, + 0x3D, 0x26, 0xA8, 0x53, 0xEA, 0x30, 0x5B, 0x4D, + 0xDA, 0x16, 0xDA, 0x7D, 0x04, 0x88, 0xF5, 0x22, + 0xA8, 0x0C, 0xB9, 0x41, 0xC7, 0x91, 0x64, 0x86, + 0x99, 0x7D, 0x18, 0xB9, 0x67, 0xA2, 0x6E, 0x05, + 0x1A, 0x82, 0x8F, 0xA2, 0xEB, 0x4D, 0x0B, 0x8C, + 0x88, 0x2D, 0xBA, 0x77, 0x87, 0x32, 0x50, 0x3C, + 0x4C, 0xD8, 0xD3, 0x50, 0x39, 0xFA, 0xDF, 0x48, + 0x3E, 0x30, 0xF5, 0x76, 0x06, 0xB0, 0x1A, 0x05, + 0x60, 0x2C, 0xD3, 0xA0, 0x63, 0x1A, 0x19, 0x2D, + 0x6B, 0x76, 0xF2, 0x31, 0x4C, 0xA7, 0xE6, 0x5C, + 0x1B, 0x23, 0x20, 0x41, 0x32, 0xE5, 0x83, 0x47, + 0x04, 0xB6, 0x3E, 0xE0, 0xFD, 0x49, 0x1E, 0x1B, + 0x75, 0x10, 0x11, 0x46, 0xE9, 0xF9, 0x96, 0x9A, + 0xD7, 0x59, 0xFE, 0x38, 0x31, 0xFE, 0x79, 0xC4, + 0xC8, 0x46, 0x88, 0xDE, 0x2E, 0xAE, 0x20, 0xED, + 0x77, 0x50, 0x40, 0x38, 0x26, 0xD3, 0x35, 0xF6, + 0x29, 0x55, 0x6A, 0x6B, 0x38, 0x69, 0xFE, 0x90, + 0x5B, 0xA7, 0xFA, 0x6B, 0x73, 0x4F, 0xB9, 0x5D, + 0xDC, 0x6F, 0x98, 0xC3, 0x6A, 0xC4, 0xB5, 0x09, + 0xC5, 0x84, 0xA5, 0x6A, 0x84, 0xA4, 0xB3, 0x8A, + 0x5F, 0xCA, 0x92, 0x64, 0x9E, 0xC3, 0x0F, 0x84, + 0x8B, 0x2D, 0x48, 0xC6, 0x67, 0xAE, 0x07, 0xE0, + 0x28, 0x38, 0x6D, 0xC4, 0x4D, 0x13, 0x87, 0xE0, + 0xB2, 0x2F, 0xAA, 0xC0, 0xCF, 0x68, 0xD7, 0x9C, + 0xB8, 0x07, 0xE4, 0x51, 0xD7, 0x75, 0x86, 0xFA, + 0x0C, 0x50, 0x74, 0x68, 0x00, 0x64, 0x2A, 0x27, + 0x59, 0xE9, 0x80, 0xEB, 0xC2, 0xA3, 0xFA, 0x58, + 0xCC, 0x03, 0xE7, 0x7B, 0x66, 0x53, 0xFF, 0x90, + 0xA0, 0x85, 0xE2, 0xF8, 0x82, 0xFE, 0xC6, 0x2B, + 0xFF, 0x5E, 0x70, 0x85, 0x34, 0xB7, 0x22, 0x38, + 0xDB, 0xBC, 0x15, 0x30, 0x59, 0xC1, 0x48, 0x42, + 0xE5, 0x38, 0x8D, 0x37, 0x59, 0xDB, 0xA3, 0x20, + 0x17, 0x36, 0x1D, 0x4B, 0xBF, 0x4E, 0xA4, 0x35, + 0xCC, 0xFE, 0xF5, 0x7A, 0x73, 0xB4, 0x6D, 0x20, + 0x1D, 0xC0, 0xE5, 0x21, 0x5C, 0xD2, 0x8A, 0x65, + 0x08, 0xB6, 0x63, 0xAC, 0x9A, 0x1E, 0x3F, 0x3C, + 0xAB, 0xB6, 0x6D, 0x34, 0xB2, 0x3A, 0x08, 0xDA, + 0x29, 0x63, 0xD1, 0xA4, 0x83, 0x52, 0xB0, 0x63, + 0x1B, 0x89, 0x35, 0x57, 0x59, 0x2C, 0x0F, 0x72, + 0x72, 0xFD, 0xA0, 0xAC, 0xDB, 0xB4, 0xA3, 0xA1, + 0x18, 0x10, 0x12, 0x97, 0x99, 0x63, 0x38, 0x98, + 0x96, 0xB5, 0x16, 0x07, 0x4E, 0xE9, 0x2C, 0x97 +}; + +static const struct blockcipher_test_data +triple_des192ctr_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192ctr, + .len = 512 + } +}; + +static const struct blockcipher_test_data +triple_des192ctr_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192ctr, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .digest = { + .data = { + 0xEA, 0x62, 0xB9, 0xB2, 0x78, 0x6C, 0x8E, 0xDB, + 0xA3, 0xB6, 0xFF, 0x23, 0x3A, 0x47, 0xD8, 0xC8, + 0xED, 0x5E, 0x20, 0x1D + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +triple_des192ctr_hmac_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192ctr, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x32, 0xD5, 0x19, 0x8F, 0x79, 0x3A, 0xAA, 0x7B, + 0x70, 0x67, 0x4E, 0x63, 0x88, 0xA3, 0x9A, 0x82, + 0x07, 0x33, 0x12, 0x94 + }, + .len = 20 + } +}; + +static const uint8_t ciphertext512_des128cbc[] = { + 0x28, 0x2a, 0xff, 0x15, 0x5c, 0xdf, 0xd9, 0x6b, + 0x54, 0xbc, 0x7b, 0xfb, 0xc5, 0x64, 0x4d, 0xdd, + 0x3e, 0xf2, 0x9e, 0xb7, 0x53, 0x65, 0x37, 0x05, + 0xe0, 0xdf, 0xae, 0xf7, 0xc9, 0x27, 0xe4, 0xec, + 0x11, 0x27, 0xc2, 0x9e, 0x02, 0x4e, 0x03, 0x3b, + 0x33, 0xf2, 0x66, 0x08, 0x24, 0x5f, 0xab, 0xc2, + 0x7e, 0x21, 0x19, 0x5d, 0x51, 0xc3, 0xe2, 0x97, + 0x6f, 0x2e, 0xb4, 0xaa, 0x34, 0x70, 0x88, 0x78, + 0x4e, 0xe7, 0x3d, 0xe1, 0x9f, 0x87, 0x1c, 0x8b, + 0xac, 0x8d, 0xa1, 0x1a, 0xcd, 0xb0, 0xf8, 0xb6, + 0x24, 0x36, 0xe3, 0x8c, 0x07, 0xe7, 0xe4, 0x92, + 0x13, 0x86, 0x6f, 0x13, 0xec, 0x04, 0x5c, 0xe9, + 0xb9, 0xca, 0x45, 0x8a, 0x2c, 0x46, 0xda, 0x54, + 0x1d, 0xb5, 0x81, 0xb1, 0xcd, 0xf3, 0x7d, 0x11, + 0x6b, 0xb3, 0x0a, 0x45, 0xe5, 0x6e, 0x51, 0x3e, + 0x2c, 0xac, 0x7c, 0xbc, 0xa7, 0x7e, 0x22, 0x4d, + 0xe6, 0x02, 0xe3, 0x3f, 0x77, 0xd7, 0x73, 0x72, + 0x0e, 0xfb, 0x42, 0x85, 0x80, 0xdf, 0xa8, 0x91, + 0x60, 0x40, 0x48, 0xcd, 0x1b, 0xd9, 0xbf, 0x2f, + 0xf2, 0xdf, 0xd0, 0xbd, 0x3f, 0x82, 0xce, 0x15, + 0x9d, 0x6e, 0xc6, 0x59, 0x6f, 0x27, 0x0d, 0xf9, + 0x26, 0xe2, 0x11, 0x29, 0x50, 0xc3, 0x0a, 0xb7, + 0xde, 0x9d, 0xe9, 0x55, 0xa1, 0xe9, 0x01, 0x33, + 0x56, 0x51, 0xa7, 0x3a, 0x9e, 0x63, 0xc5, 0x08, + 0x01, 0x3b, 0x03, 0x4b, 0xc6, 0xc4, 0xa1, 0xc0, + 0xc0, 0xd0, 0x0e, 0x48, 0xe5, 0x4c, 0x55, 0x6b, + 0x4a, 0xc1, 0x0a, 0x24, 0x4b, 0xd0, 0x02, 0xf4, + 0x31, 0x63, 0x11, 0xbd, 0xa6, 0x1f, 0xf4, 0xae, + 0x23, 0x5a, 0x40, 0x7e, 0x0e, 0x4e, 0x63, 0x8b, + 0x66, 0x3d, 0x55, 0x46, 0x6e, 0x5c, 0x76, 0xa7, + 0x68, 0x31, 0xce, 0x5d, 0xca, 0xe2, 0xb4, 0xb0, + 0xc1, 0x1f, 0x66, 0x18, 0x75, 0x64, 0x73, 0xa9, + 0x9e, 0xd5, 0x0e, 0x0e, 0xf7, 0x77, 0x61, 0xf8, + 0x89, 0xc6, 0xcf, 0x0c, 0x41, 0xd3, 0x8f, 0xfd, + 0x22, 0x52, 0x4f, 0x94, 0x5c, 0x19, 0x11, 0x3a, + 0xb5, 0x63, 0xe8, 0x81, 0x33, 0x13, 0x54, 0x3c, + 0x93, 0x36, 0xb5, 0x5b, 0x51, 0xaf, 0x51, 0xa2, + 0x08, 0xae, 0x83, 0x15, 0x77, 0x07, 0x28, 0x0d, + 0x98, 0xe1, 0x2f, 0x69, 0x0e, 0xfb, 0x9a, 0x2e, + 0x27, 0x27, 0xb0, 0xd5, 0xce, 0xf8, 0x16, 0x55, + 0xfd, 0xaa, 0xd7, 0x1a, 0x1b, 0x2e, 0x4c, 0x86, + 0x7a, 0x6a, 0x90, 0xf7, 0x0a, 0x07, 0xd3, 0x81, + 0x4b, 0x75, 0x6a, 0x79, 0xdb, 0x63, 0x45, 0x0f, + 0x31, 0x7e, 0xd0, 0x2a, 0x14, 0xff, 0xee, 0xcc, + 0x97, 0x8a, 0x7d, 0x74, 0xbd, 0x9d, 0xaf, 0x00, + 0xdb, 0x7e, 0xf3, 0xe6, 0x22, 0x76, 0x77, 0x58, + 0xba, 0x1c, 0x06, 0x96, 0xfb, 0x6f, 0x41, 0x71, + 0x66, 0x98, 0xae, 0x31, 0x7d, 0x29, 0x18, 0x71, + 0x0e, 0xe4, 0x98, 0x7e, 0x59, 0x5a, 0xc9, 0x78, + 0x9c, 0xfb, 0x6c, 0x81, 0x44, 0xb4, 0x0f, 0x5e, + 0x18, 0x53, 0xb8, 0x6f, 0xbc, 0x3b, 0x15, 0xf0, + 0x10, 0xdd, 0x0d, 0x4b, 0x0a, 0x36, 0x0e, 0xb4, + 0x76, 0x0f, 0x16, 0xa7, 0x5c, 0x9d, 0xcf, 0xb0, + 0x6d, 0x38, 0x02, 0x07, 0x05, 0xe9, 0xe9, 0x46, + 0x08, 0xb8, 0x52, 0xd6, 0xd9, 0x4c, 0x81, 0x63, + 0x1d, 0xe2, 0x5b, 0xd0, 0xf6, 0x5e, 0x1e, 0x81, + 0x48, 0x08, 0x66, 0x3a, 0x85, 0xed, 0x65, 0xfe, + 0xe8, 0x05, 0x7a, 0xe1, 0xe6, 0x12, 0xf2, 0x52, + 0x83, 0xdd, 0x82, 0xbe, 0xf6, 0x34, 0x8a, 0x6f, + 0xc5, 0x83, 0xcd, 0x3f, 0xbe, 0x58, 0x8b, 0x11, + 0x78, 0xdc, 0x0c, 0x83, 0x72, 0x5d, 0x05, 0x2a, + 0x01, 0x29, 0xee, 0x48, 0x9a, 0x67, 0x00, 0x6e, + 0x14, 0x60, 0x2d, 0x00, 0x52, 0x87, 0x98, 0x5e, + 0x43, 0xfe, 0xf1, 0x10, 0x14, 0xf1, 0x91, 0xcc +}; + +static const struct blockcipher_test_data +triple_des128cbc_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128cbc, + .len = 512 + } +}; + +static const struct blockcipher_test_data +triple_des128cbc_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .digest = { + .data = { + 0x94, 0x45, 0x7B, 0xDF, 0xFE, 0x80, 0xB9, 0xA6, + 0xA0, 0x7A, 0xE8, 0x93, 0x40, 0x7B, 0x85, 0x02, + 0x1C, 0xD7, 0xE8, 0x87 + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +triple_des128cbc_hmac_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x7E, 0xBA, 0xFF, 0x86, 0x8D, 0x65, 0xCD, 0x08, + 0x76, 0x34, 0x94, 0xE9, 0x9A, 0xCD, 0xB2, 0xBB, + 0xBF, 0x65, 0xF5, 0x42 + }, + .len = 20 + } +}; + +static const uint8_t ciphertext512_des192cbc[] = { + 0xd0, 0xc9, 0xdc, 0x51, 0x29, 0x97, 0x03, 0x64, + 0xcd, 0x22, 0xba, 0x3d, 0x2b, 0xbc, 0x21, 0x37, + 0x7b, 0x1e, 0x29, 0x23, 0xeb, 0x51, 0x6e, 0xac, + 0xbe, 0x5b, 0xd3, 0x67, 0xe0, 0x3f, 0xc3, 0xb5, + 0xe3, 0x04, 0x17, 0x42, 0x2b, 0xaa, 0xdd, 0xd6, + 0x0e, 0x69, 0xd0, 0x8f, 0x8a, 0xfc, 0xb4, 0x55, + 0x67, 0x06, 0x51, 0xbb, 0x00, 0x57, 0xee, 0x95, + 0x28, 0x79, 0x3f, 0xd9, 0x97, 0x2b, 0xb0, 0x02, + 0x35, 0x08, 0xce, 0x7a, 0xc3, 0x43, 0x2c, 0x87, + 0xaa, 0x97, 0x6a, 0xad, 0xf0, 0x26, 0xea, 0x1d, + 0xbb, 0x08, 0xe9, 0x52, 0x11, 0xd3, 0xaf, 0x36, + 0x17, 0x14, 0x21, 0xb2, 0xbc, 0x42, 0x51, 0x33, + 0x27, 0x8c, 0xd8, 0x45, 0xb9, 0x76, 0xa0, 0x11, + 0x24, 0x34, 0xde, 0x4d, 0x13, 0x67, 0x1b, 0xc3, + 0x31, 0x12, 0x66, 0x56, 0x59, 0xd2, 0xb1, 0x8f, + 0xec, 0x1e, 0xc0, 0x10, 0x7a, 0x86, 0xb1, 0x60, + 0xc3, 0x01, 0xd6, 0xa8, 0x55, 0xad, 0x58, 0x63, + 0xca, 0x68, 0xa9, 0x33, 0xe3, 0x93, 0x90, 0x7d, + 0x8f, 0xca, 0xf8, 0x1c, 0xc2, 0x9e, 0xfb, 0xde, + 0x9c, 0xc7, 0xf2, 0x6c, 0xff, 0xcc, 0x39, 0x17, + 0x49, 0x33, 0x0d, 0x7c, 0xed, 0x07, 0x99, 0x91, + 0x91, 0x6c, 0x5f, 0x3f, 0x02, 0x09, 0xdc, 0x70, + 0xf9, 0x3b, 0x8d, 0xaa, 0xf4, 0xbc, 0x0e, 0xec, + 0xf2, 0x26, 0xfb, 0xb2, 0x1c, 0x31, 0xae, 0xc6, + 0x72, 0xe8, 0x0b, 0x75, 0x05, 0x57, 0x58, 0x98, + 0x92, 0x37, 0x27, 0x8e, 0x3b, 0x0c, 0x25, 0xfb, + 0xcf, 0x82, 0x02, 0xd5, 0x0b, 0x1f, 0x89, 0x49, + 0xcd, 0x0f, 0xa1, 0xa7, 0x08, 0x63, 0x56, 0xa7, + 0x1f, 0x80, 0x3a, 0xef, 0x24, 0x89, 0x57, 0x1a, + 0x02, 0xdc, 0x2e, 0x51, 0xbd, 0x4a, 0x10, 0x23, + 0xfc, 0x02, 0x1a, 0x3f, 0x34, 0xbf, 0x1c, 0x98, + 0x1a, 0x40, 0x0a, 0x96, 0x8e, 0x41, 0xd5, 0x09, + 0x55, 0x37, 0xe9, 0x25, 0x11, 0x83, 0xf8, 0xf3, + 0xd4, 0xb0, 0xdb, 0x16, 0xd7, 0x51, 0x7e, 0x94, + 0xf7, 0xb4, 0x26, 0xe0, 0xf4, 0x80, 0x01, 0x65, + 0x51, 0xeb, 0xbc, 0xb0, 0x65, 0x8f, 0xdd, 0xb5, + 0xf7, 0x00, 0xec, 0x40, 0xab, 0x7d, 0x96, 0xcc, + 0x8d, 0xec, 0x89, 0x80, 0x31, 0x39, 0xa2, 0x5c, + 0xb0, 0x55, 0x4c, 0xee, 0xdd, 0x15, 0x2b, 0xa9, + 0x86, 0x4e, 0x23, 0x14, 0x36, 0xc5, 0x57, 0xf5, + 0xe3, 0xe8, 0x89, 0xc9, 0xb7, 0xf8, 0xeb, 0x08, + 0xe5, 0x93, 0x12, 0x5c, 0x0f, 0x79, 0xa1, 0x86, + 0xe4, 0xc2, 0xeb, 0xa6, 0xa0, 0x50, 0x6a, 0xec, + 0xd3, 0xce, 0x50, 0x78, 0x4e, 0x4f, 0x93, 0xd8, + 0xdc, 0xb4, 0xec, 0x02, 0xe9, 0xbd, 0x17, 0x99, + 0x1e, 0x16, 0x4e, 0xd7, 0xb0, 0x07, 0x02, 0x55, + 0x63, 0x24, 0x4f, 0x7b, 0x8f, 0xc5, 0x7a, 0x12, + 0x29, 0xff, 0x5d, 0xc1, 0xe7, 0xae, 0x48, 0xc8, + 0x57, 0x53, 0xe7, 0xcd, 0x10, 0x6c, 0x19, 0xfc, + 0xcc, 0xb9, 0xb1, 0xbe, 0x48, 0x9f, 0x2d, 0x3f, + 0x39, 0x2e, 0xdd, 0x71, 0xde, 0x1b, 0x54, 0xee, + 0x7d, 0x94, 0x8f, 0x27, 0x23, 0xe9, 0x74, 0x92, + 0x14, 0x93, 0x84, 0x65, 0xc9, 0x22, 0x7c, 0xa8, + 0x1b, 0x72, 0x73, 0xb1, 0x23, 0xa0, 0x6b, 0xcc, + 0xb5, 0x22, 0x06, 0x15, 0xe5, 0x96, 0x03, 0x4a, + 0x52, 0x8d, 0x1d, 0xbf, 0x3e, 0x82, 0x45, 0x9c, + 0x75, 0x9e, 0xa9, 0x3a, 0x97, 0xb6, 0x5d, 0xc4, + 0x75, 0x67, 0xa1, 0xf3, 0x0f, 0x7a, 0xfd, 0x71, + 0x58, 0x04, 0xf9, 0xa7, 0xc2, 0x56, 0x74, 0x04, + 0x74, 0x68, 0x6d, 0x8a, 0xf6, 0x6c, 0x5d, 0xd8, + 0xb5, 0xed, 0x70, 0x23, 0x32, 0x4d, 0x75, 0x92, + 0x88, 0x7b, 0x39, 0x37, 0x02, 0x4b, 0xb2, 0x1c, + 0x1f, 0x7e, 0x5b, 0x1b, 0x10, 0xfc, 0x17, 0x21, + 0x66, 0x62, 0x63, 0xc2, 0xcd, 0x16, 0x96, 0x3e +}; + +static const struct blockcipher_test_data +triple_des192cbc_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192cbc, + .len = 512 + } +}; + +static const struct blockcipher_test_data +triple_des192cbc_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .digest = { + .data = { + 0x53, 0x27, 0xC0, 0xE6, 0xD6, 0x1B, 0xD6, 0x45, + 0x94, 0x2D, 0xCE, 0x8B, 0x29, 0xA3, 0x52, 0x14, + 0xC1, 0x6B, 0x87, 0x99 + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +triple_des192cbc_hmac_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0xBA, 0xAC, 0x74, 0x19, 0x43, 0xB0, 0x72, 0xB8, + 0x08, 0xF5, 0x24, 0xC4, 0x09, 0xBD, 0x48, 0xC1, + 0x3C, 0x50, 0x1C, 0xDD + }, + .len = 20 + } +}; + +static const struct blockcipher_test_case triple_des_chain_test_cases[] = { + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Encryption Digest", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Decryption Digest Verify", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC SHA1 Encryption Digest", + .test_data = &triple_des128cbc_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-128-CBC SHA1 Decryption Digest Verify", + .test_data = &triple_des128cbc_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-192-CBC HMAC-SHA1 Encryption Digest", + .test_data = &triple_des192cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CBC HMAC-SHA1 Decryption Digest Verify", + .test_data = &triple_des192cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CBC SHA1 Encryption Digest", + .test_data = &triple_des192cbc_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-192-CBC SHA1 Decryption Digest Verify", + .test_data = &triple_des192cbc_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-128-CTR HMAC-SHA1 Encryption Digest", + .test_data = &triple_des128ctr_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CTR HMAC-SHA1 Decryption Digest Verify", + .test_data = &triple_des128ctr_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CTR SHA1 Encryption Digest", + .test_data = &triple_des128ctr_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-128-CTR SHA1 Decryption Digest Verify", + .test_data = &triple_des128ctr_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-192-CTR HMAC-SHA1 Encryption Digest", + .test_data = &triple_des192ctr_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CTR HMAC-SHA1 Decryption Digest Verify", + .test_data = &triple_des192ctr_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CTR SHA1 Encryption Digest", + .test_data = &triple_des192ctr_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-192-CTR SHA1 Decryption Digest Verify", + .test_data = &triple_des192ctr_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Encryption Digest OOP", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Decryption Digest Verify OOP", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Encryption Digest Sessionless", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = + "3DES-128-CBC HMAC-SHA1 Decryption Digest Verify Sessionless", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, +}; + +static const struct blockcipher_test_case triple_des_cipheronly_test_cases[] = { + { + .test_descr = "3DES-128-CBC Encryption", + .test_data = &triple_des128cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC Decryption", + .test_data = &triple_des128cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CBC Encryption", + .test_data = &triple_des192cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CBC Decryption", + .test_data = &triple_des192cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CTR Encryption", + .test_data = &triple_des128ctr_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CTR Decryption", + .test_data = &triple_des128ctr_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CTR Encryption", + .test_data = &triple_des192ctr_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CTR Decryption", + .test_data = &triple_des192ctr_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + } +}; + +#endif /* TEST_CRYPTODEV_DES_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_gcm_test_vectors.h b/app/test/test_cryptodev_gcm_test_vectors.h index f3f8bd3..a0379b5 100644 --- a/app/test/test_cryptodev_gcm_test_vectors.h +++ b/app/test/test_cryptodev_gcm_test_vectors.h @@ -449,27 +449,8199 @@ static const struct gcm_test_data gcm_test_case_7 = { }; /** GMAC Test Vectors */ -static uint8_t gmac_plaintext[] = { - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 +uint8_t gmac_plaintext[] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x33, 0xF3, 0xE2, 0xF1, 0x9E, 0xC4, 0x34, 0x20, + 0xB5, 0x98, 0x88, 0xA5, 0xDA, 0x6B, 0xAC, 0x5F, + 0x01, 0xDE, 0xBE, 0x28, 0x24, 0x9E, 0xA2, 0x3C, + 0xA2, 0xC4, 0x1D, 0xC6, 0xD3, 0x72, 0x83, 0x16, + 0x5C, 0xBB, 0x94, 0x12, 0xB0, 0x8F, 0xFB, 0x98, + 0xA2, 0x3A, 0x9F, 0x27, 0x7B, 0x99, 0x7C, 0x53, + 0x6D, 0x36, 0xFE, 0xA5, 0xB0, 0x33, 0x22, 0x63, + 0x12, 0xE4, 0x05, 0xAF, 0x33, 0xE4, 0xB6, 0x99, + 0xFC, 0x15, 0x00, 0x9E, 0x4C, 0x87, 0x14, 0xD3, + 0x34, 0x6E, 0xBF, 0x35, 0x2B, 0xEC, 0x8D, 0x45, + 0xF8, 0x36, 0x81, 0x18, 0x72, 0x09, 0x67, 0x91, + 0x2E, 0x75, 0x08, 0xD5, 0x65, 0x41, 0xC1, 0x38, + 0xED, 0xEF, 0x18, 0xC1, 0xEE, 0x48, 0xB4, 0x47, + 0x41, 0x5C, 0x6A, 0x97, 0x14, 0xA2, 0xC8, 0x3A, + 0x9F, 0x4B, 0xFB, 0x66, 0xFB, 0x3F, 0x35, 0x6D, + 0xF1, 0xC8, 0x1D, 0x0B, 0xAC, 0x4A, 0xA1, 0x28, + 0x68, 0x18, 0xF5, 0x54, 0xF8, 0x76, 0xE7, 0xB7, + 0x0B, 0x6C, 0xB1, 0xCA, 0x5D, 0x91, 0x9F, 0x00, + 0x12, 0xFD, 0xA6, 0x5C, 0xF8, 0x88, 0x73, 0xE5, + 0x38, 0x21, 0x50, 0x75, 0xF5, 0x09, 0x56, 0x10, + 0x49, 0x80, 0xB1, 0x27, 0xEF, 0xAC, 0xCD, 0x30, + 0x43, 0x6D, 0x3E, 0xF2, 0x91, 0x76, 0xEA, 0x5F, + 0xB7, 0xDD, 0xC7, 0x21, 0xD1, 0x1F, 0x0D, 0xA2, + 0x68, 0x31, 0xEE, 0x25, 0x9B, 0x67, 0x37, 0x3D, + 0xF2, 0x48, 0x2E, 0x4A, 0x61, 0xD3, 0xB6, 0xA1, + 0x69, 0x02, 0x62, 0xCA, 0x2D, 0xDE, 0x40, 0x7E, + 0x7F, 0xCC, 0x26, 0x53, 0x48, 0x9A, 0x2B, 0x6B, + 0x9B, 0x27, 0xE8, 0x57, 0xD7, 0xD3, 0x9F, 0xE2, + 0xC6, 0x2D, 0xD1, 0xC3, 0x10, 0x12, 0x00, 0x7F, + 0xBB, 0x58, 0x15, 0x11, 0x38, 0x78, 0x22, 0x66, + 0xAB, 0xEE, 0xAC, 0xD0, 0xA3, 0x99, 0x7A, 0x1A, + 0xF3, 0xE9, 0xB8, 0x5E, 0x54, 0x85, 0x93, 0xEB, + 0xB8, 0x10, 0x5D, 0xFE, 0xF3, 0x48, 0x46, 0xDA, + 0x69, 0x26, 0xFF, 0x0C, 0x4E, 0x1C, 0x3C, 0xB8, + 0xEA, 0x14, 0xA0, 0xA6, 0xFE, 0xC4, 0x3A, 0x0B, + 0xAB, 0xB1, 0x71, 0x32, 0x94, 0xB0, 0x9D, 0x49, + 0x91, 0x47, 0x9D, 0xB3, 0xEB, 0x68, 0x8B, 0xB5, + 0x6D, 0x3B, 0xA6, 0xE5, 0x9E, 0x35, 0x5F, 0x3F, + 0x92, 0x48, 0x30, 0x0F, 0xBA, 0x66, 0x65, 0x75, + 0x14, 0x2F, 0x4C, 0x24, 0x1E, 0x7C, 0x92, 0x4C, + 0xEA, 0xFA, 0x2C, 0x6B, 0x60, 0xF0, 0x54, 0xEF, + 0x36, 0x35, 0x2F, 0x89, 0xA4, 0x02, 0xA8, 0xB8, + 0x68, 0x6F, 0xBD, 0xD8, 0x40, 0x1C, 0x93, 0x7B, + 0xA0, 0x04, 0x29, 0x85, 0x2F, 0x3F, 0x9C, 0x0D, + 0x1F, 0x3C, 0xE7, 0xE2, 0xE9, 0x93, 0xBD, 0xEF, + 0x80, 0x94, 0x91, 0x94, 0x7D, 0x31, 0x6E, 0xB3, + 0xDE, 0x7C, 0x71, 0x4C, 0x84, 0x1B, 0x39, 0x3B, + 0x0D, 0x49, 0x4F, 0xB8, 0x16, 0x2A, 0xC8, 0x94, + 0xC7, 0xA0, 0x2E, 0x79, 0xD3, 0x6F, 0xFD, 0xE7, + 0x80, 0x7C, 0xAE, 0xAD, 0xA2, 0xDA, 0x1A, 0x48, + 0xE7, 0x55, 0xC0, 0x88, 0xAE, 0x44, 0xA4, 0x15, + 0x48, 0x32, 0x72, 0xDF, 0x2C, 0x0D, 0x5C, 0xC5, + 0x3B, 0xFA, 0x80, 0xC1, 0x73, 0xB7, 0xFA, 0x85, + 0x02, 0xC2, 0x5C, 0x44, 0xE8, 0x2A, 0x4E, 0xA2, + 0xEA, 0xDB, 0x61, 0x6A, 0x3A, 0x08, 0x05, 0x9A, + 0xC9, 0x0A, 0x24, 0xD7, 0xD4, 0x79, 0x0F, 0xBD, + 0x8C, 0x43, 0x29, 0xAD, 0x97, 0xE7, 0x32, 0x08, + 0x4E, 0xE5, 0xE6, 0x9F, 0xF1, 0x9E, 0xD0, 0x08, + 0x50, 0xB0, 0x7E, 0x60, 0x26, 0xF9, 0x1F, 0xD7, + 0x17, 0x3B, 0x9C, 0xC4, 0x0C, 0x88, 0xEE, 0x00, + 0x8B, 0xDE, 0x52, 0xEE, 0xE3, 0xB9, 0x17, 0x23, + 0x0F, 0xE8, 0x5E, 0xC7, 0x23, 0x9C, 0x1F, 0xB7, + 0xEE, 0x01, 0xE7, 0x53, 0xEB, 0x8E, 0xF9, 0xB1, + 0x2B, 0x75, 0x33, 0x7A, 0xE5, 0x28, 0xBC, 0xC1, + 0x4A, 0x90, 0xBF, 0x5C, 0x2B, 0xF4, 0x22, 0x52, + 0xAB, 0x08, 0x81, 0x5B, 0xCF, 0x72, 0x94, 0xB6, + 0x86, 0x47, 0x35, 0xE3, 0xE7, 0x79, 0x1F, 0x00, + 0xCC, 0x1B, 0xF0, 0xCE, 0x68, 0x52, 0xFE, 0xD3, + 0xFD, 0xB9, 0x65, 0x15, 0xDC, 0x39, 0x48, 0x32, + 0x19, 0x78, 0xD8, 0x0D, 0x4D, 0x5A, 0x86, 0x2A, + 0xF8, 0x6B, 0x1F, 0xAD, 0xBF, 0xA7, 0xC2, 0x14, + 0xFA, 0xE4, 0xF2, 0xB9, 0xD1, 0xD0, 0xA1, 0x19, + 0x04, 0x1B, 0xCE, 0xFE, 0xC8, 0xF2, 0x92, 0xF2, + 0x13, 0xB5, 0x0F, 0x18, 0x66, 0x4E, 0xC4, 0x17, + 0x92, 0xD5, 0x38, 0x5A, 0xC8, 0xC7, 0x60, 0x4D, + 0xB2, 0x5C, 0x99, 0x00, 0xF4, 0xDA, 0x05, 0x89, + 0x5A, 0x04, 0x39, 0xC0, 0xFA, 0x6C, 0x8C, 0x84, + 0x4D, 0x6D, 0xBD, 0x29, 0x30, 0xCC, 0x64, 0x53, + 0x4F, 0x28, 0x47, 0x4A, 0xA6, 0xE8, 0x70, 0x0F, + 0x72, 0x09, 0xE5, 0x67, 0x03, 0xCE, 0x3B, 0x26, + 0x55, 0x27, 0xED, 0xCE, 0xFA, 0x5A, 0x81, 0x44, + 0xBC, 0xB6, 0xFA, 0xF1, 0x43, 0x48, 0x83, 0xBB, + 0xBC, 0xF5, 0x2F, 0x3A, 0xB6, 0xCF, 0xAA, 0xF0, + 0x4D, 0x4F, 0x47, 0x56, 0xAB, 0x2C, 0xC9, 0x59, + 0xE9, 0x0F, 0x1F, 0x55, 0xCF, 0xAF, 0x61, 0x58, + 0x3C, 0xD9, 0x44, 0xDC, 0xD6, 0x3B, 0x21, 0x63, + 0x3D, 0x34, 0xF9, 0x31, 0xC5, 0x39, 0x64, 0x70, + 0x37, 0x5F, 0xC5, 0xFB, 0x4A, 0xC2, 0x39, 0xFE, + 0xC1, 0x55, 0x43, 0xCF, 0xDB, 0xE9, 0xA6, 0x8B, + 0xF5, 0xD8, 0x2B, 0x01, 0x0E, 0x7B, 0x36, 0x14, + 0x5C, 0x66, 0x17, 0x5C, 0x08, 0xEE, 0x1A, 0x1B, + 0x7A, 0xB0, 0x67, 0xBA, 0x39, 0x25, 0x67, 0x35, + 0x1A, 0x85, 0xD0, 0x27, 0x55, 0x6E, 0x2C, 0xDF, + 0x01, 0x38, 0x09, 0x9A, 0xF5, 0x5F, 0x41, 0x30, + 0xAD, 0x44, 0xC9, 0xDC, 0x4C, 0xFD, 0xBA, 0x97, + 0x37, 0x6F, 0x61, 0x15, 0x76, 0xEF, 0x0C, 0x31, + 0x64, 0x6B, 0xE2, 0xD5, 0x71, 0x16, 0x01, 0x14, + 0x51, 0x4E, 0x6E, 0xB0, 0xCF, 0x48, 0x03, 0x5A, + 0x2E, 0x84, 0x0C, 0x9D, 0xFD, 0x66, 0x5B, 0x1E, + 0x49, 0x32, 0xBA, 0x0E, 0x69, 0x0A, 0x74, 0xD8, + 0xD8, 0xA5, 0xFB, 0xC9, 0x20, 0xD0, 0x6D, 0x75, + 0x8D, 0xB4, 0xFE, 0xE7, 0x16, 0xF6, 0xE4, 0x05, + 0x75, 0x0B, 0xDC, 0xD6, 0x46, 0x4D, 0x57, 0x00, + 0xD5, 0x6B, 0xE4, 0xD2, 0x32, 0xBD, 0x4C, 0xAE, + 0x40, 0x37, 0xC6, 0xC7, 0x91, 0xCB, 0x0B, 0x79, + 0x91, 0x07, 0x3D, 0x41, 0x5A, 0x6D, 0xEB, 0x14, + 0xA3, 0x32, 0xE7, 0x62, 0xBB, 0x75, 0x09, 0x62, + 0x7A, 0x30, 0x3D, 0x7A, 0x94, 0x2F, 0x89, 0xB0, + 0x0B, 0x96, 0x7B, 0xB0, 0x0D, 0xFF, 0x12, 0xF0, + 0x3A, 0x8F, 0x2E, 0x23, 0x11, 0xA4, 0x1F, 0xB1, + 0xA4, 0x7D, 0xA9, 0x77, 0xD9, 0x94, 0x19, 0x57, + 0xB1, 0x31, 0x01, 0x6D, 0xA9, 0x8E, 0x47, 0x8C, + 0x67, 0xEF, 0x26, 0xD7, 0xFE, 0x70, 0x42, 0xB3, + 0x2E, 0xBA, 0x0F, 0x51, 0x50, 0x49, 0xA7, 0xB4, + 0xDC, 0x12, 0xB4, 0x04, 0xEB, 0x2D, 0x6F, 0xEF, + 0x48, 0x3B, 0x38, 0x2B, 0x42, 0x3F, 0xF4, 0x0D, + 0x8E, 0x77, 0x12, 0x8D, 0x9E, 0x48, 0x89, 0x68, + 0x2A, 0x98, 0xC9, 0x0F, 0xF9, 0x69, 0xED, 0xD3, + 0x0B, 0x10, 0x67, 0x0F, 0x05, 0xD7, 0xB6, 0x4D, + 0xDE, 0x1D, 0x56, 0xF8, 0x19, 0x1F, 0x91, 0xCD, + 0x40, 0x2C, 0x1F, 0x82, 0x06, 0x76, 0xE0, 0xBB, + 0x82, 0xBE, 0xAE, 0xC0, 0xE0, 0xA7, 0xF3, 0x85, + 0x33, 0xCF, 0xFC, 0x0C, 0x62, 0xDB, 0x2A, 0x55, + 0x9D, 0x66, 0xBA, 0x09, 0x25, 0x02, 0x10, 0x39, + 0xEE, 0x91, 0xCD, 0xF4, 0xB3, 0x81, 0x38, 0xE9, + 0xDC, 0xD2, 0x84, 0xBE, 0xA2, 0x07, 0x2F, 0xE9, + 0xF6, 0xFA, 0x49, 0x32, 0xD3, 0xB5, 0x9E, 0x66, + 0x35, 0x06, 0x00, 0xDF, 0xD1, 0xFA, 0x28, 0xE7, + 0x49, 0x66, 0xEC, 0xD3, 0xE3, 0xA4, 0x4F, 0x4C, + 0x3B, 0x05, 0x2A, 0x0D, 0xD5, 0x6E, 0x5B, 0x34, + 0x2F, 0xDA, 0xE2, 0x5B, 0x47, 0x37, 0xE8, 0xC3, + 0xC3, 0xC2, 0x8F, 0xD2, 0xC4, 0xDF, 0x26, 0xC5, + 0x8A, 0x60, 0xE7, 0x8C, 0x0D, 0x33, 0x44, 0xE3, + 0xA5, 0x3C, 0xDE, 0x47, 0xA3, 0x5F, 0x1D, 0x07, + 0xFF, 0x95, 0xE2, 0xED, 0xF1, 0xF9, 0xEF, 0xB6, + 0x44, 0x01, 0x75, 0x8A, 0x00, 0x7A, 0x0C, 0x22, + 0xCC, 0xE0, 0xBF, 0x1E, 0x7D, 0xA1, 0x44, 0x54, + 0x38, 0x8F, 0xE9, 0x44, 0xB9, 0x5B, 0x88, 0xB8, + 0x0C, 0xFE, 0x1C, 0x8D, 0xC6, 0x80, 0x27, 0x2C, + 0x84, 0x36, 0xFC, 0x6D, 0x38, 0x00, 0xAE, 0xFE, + 0x6C, 0x9A, 0xEF, 0x7D, 0x92, 0xC5, 0x19, 0x95, + 0xD6, 0xCF, 0x91, 0x3E, 0xCC, 0x9C, 0x77, 0x45, + 0x0A, 0x84, 0xF5, 0x1B, 0x45, 0xD2, 0x6B, 0x45, + 0x7F, 0x18, 0xAD, 0x0F, 0xCE, 0x2A, 0xC0, 0x2C, + 0x08, 0x6A, 0x75, 0xD2, 0xAC, 0xB9, 0xC7, 0x82, + 0xF7, 0x11, 0x52, 0x54, 0x63, 0x48, 0x24, 0x74, + 0xCE, 0x13, 0x4F, 0x7A, 0xEC, 0x53, 0x3B, 0xD3, + 0xD1, 0xAC, 0x87, 0x65, 0x03, 0xD8, 0xCD, 0x56, + 0xEC, 0xCD, 0x4B, 0xAC, 0xC0, 0xC6, 0x18, 0x19, + 0x0E, 0xC5, 0x3A, 0xC6, 0xF9, 0xCE, 0x89, 0xEB, + 0x98, 0xFE, 0x23, 0xD8, 0xC3, 0xB1, 0xC4, 0x85, + 0x9B, 0x3A, 0x0A, 0xDE, 0x2C, 0xBE, 0x0F, 0xB6, + 0x41, 0xF7, 0x93, 0x70, 0x8B, 0xFD, 0x67, 0x22, + 0x14, 0xDA, 0x37, 0x5F, 0x04, 0x35, 0xAF, 0x4D, + 0x10, 0x0C, 0x35, 0x8A, 0xC0, 0x73, 0x83, 0x18, + 0x60, 0xB7, 0x4B, 0x1F, 0x4B, 0x5B, 0xAC, 0xE3, + 0xAE, 0x3A, 0x98, 0xD4, 0xC3, 0x6B, 0x92, 0x3D, + 0xEF, 0xD1, 0xD8, 0xBF, 0xA8, 0x66, 0xAB, 0x51, + 0x38, 0x79, 0x4D, 0xAB, 0x63, 0x36, 0xF0, 0x67, + 0x98, 0x77, 0x27, 0x95, 0xC2, 0x67, 0xE4, 0xF4, + 0x3A, 0x72, 0x46, 0x39, 0x0B, 0xC8, 0x18, 0xBF, + 0x0E, 0x71, 0x0B, 0xBE, 0x02, 0x86, 0x62, 0xB0, + 0x98, 0x5A, 0x8B, 0xC7, 0xF8, 0x04, 0xBD, 0x53, + 0xBF, 0x93, 0xC1, 0x8C, 0xAE, 0xEE, 0x97, 0xCB, + 0xB5, 0x72, 0xF6, 0x72, 0x3D, 0x1C, 0x5F, 0xD4, + 0x05, 0xC5, 0xFF, 0x87, 0x63, 0x2A, 0x64, 0x58, + 0xCA, 0xFF, 0x8F, 0x2A, 0x5B, 0xD8, 0x62, 0xE5, + 0x24, 0xF9, 0x39, 0x9E, 0xE5, 0x3A, 0xDE, 0xB4, + 0xA2, 0x5E, 0x45, 0x7E, 0x14, 0x66, 0x56, 0x3F, + 0x9F, 0xCA, 0x2F, 0x49, 0xE0, 0xBE, 0xCE, 0x48, + 0x1E, 0x4F, 0x8E, 0x83, 0x69, 0x0C, 0xEF, 0x58, + 0x6A, 0x09, 0x5A, 0xBB, 0x04, 0x5B, 0x81, 0x65, + 0x4C, 0x73, 0xDE, 0xB5, 0xE6, 0x56, 0x3A, 0x83, + 0x9A, 0x04, 0x80, 0x11, 0x07, 0xC9, 0x05, 0x79, + 0x94, 0x0C, 0x69, 0x9C, 0xB9, 0x25, 0x67, 0xE4, + 0x4C, 0xA4, 0x8A, 0x4B, 0x92, 0x27, 0xB1, 0x0A, + 0x6D, 0x0C, 0xE2, 0x14, 0x33, 0x85, 0x2C, 0x12, + 0x1E, 0x9C, 0xB9, 0xAC, 0x0C, 0xBD, 0xF1, 0x6B, + 0x71, 0xB2, 0x7D, 0x91, 0x6C, 0x6F, 0xE2, 0x22, + 0x3B, 0x93, 0xB2, 0x8F, 0x41, 0x91, 0x1F, 0x1F, + 0x2E, 0x4B, 0x52, 0xE3, 0x44, 0x2A, 0x4A, 0x41, + 0x21, 0xA4, 0xC5, 0x26, 0x34, 0x35, 0x89, 0x47, + 0x3C, 0xED, 0x39, 0x8C, 0x3C, 0x3A, 0x29, 0xCF, + 0x80, 0x58, 0x9C, 0xB9, 0xD7, 0xCD, 0x24, 0xDB, + 0xFE, 0x17, 0xD7, 0x6D, 0x6C, 0x5B, 0x9B, 0xF8, + 0x3B, 0x25, 0xF6, 0x85, 0x3D, 0xA9, 0x59, 0xF9, + 0x16, 0xC5, 0x1C, 0x4E, 0xF7, 0xA5, 0x39, 0x90, + 0x08, 0xD5, 0xA3, 0x14, 0xFD, 0x68, 0xAC, 0x03, + 0x3F, 0x21, 0x4D, 0x94, 0x27, 0xB0, 0x98, 0xD6, + 0xA9, 0x87, 0xF7, 0x2C, 0x17, 0xE9, 0x5A, 0x1B, + 0x09, 0x52, 0x31, 0xD4, 0x0F, 0x43, 0x21, 0x2D, + 0x73, 0x05, 0xB1, 0x9D, 0x6C, 0xBE, 0xF2, 0x65, + 0x91, 0xD4, 0x17, 0xAD, 0x5F, 0x2F, 0xC6, 0xAE, + 0xAC, 0xAF, 0x3B, 0x76, 0x5C, 0xCB, 0x3F, 0xAD, + 0x8A, 0x97, 0xEF, 0xD7, 0x44, 0x6D, 0x1B, 0xD0, + 0x25, 0x79, 0xD1, 0x77, 0x7A, 0x40, 0xF6, 0xBC, + 0x55, 0x66, 0x65, 0x8B, 0x3F, 0x9C, 0xCA, 0x8D, + 0x9A, 0xE2, 0xD0, 0x94, 0xF3, 0x59, 0x20, 0x3F, + 0xED, 0xFD, 0xC2, 0xBF, 0xA8, 0xCB, 0x0B, 0x93, + 0x85, 0x3C, 0xAB, 0x13, 0x82, 0x15, 0x4D, 0x04, + 0xD6, 0x00, 0x38, 0x63, 0x3F, 0x29, 0x82, 0xA4, + 0x2F, 0xDA, 0xB8, 0x0F, 0x8B, 0xA1, 0xCD, 0x61, + 0xA6, 0x7D, 0x86, 0xAC, 0xA9, 0xF7, 0x72, 0xC9, + 0x11, 0xCF, 0xDF, 0xC2, 0x96, 0xDC, 0xFC, 0x2B, + 0x4A, 0xFD, 0xF6, 0xEA, 0x68, 0xDA, 0xEE, 0x08, + 0x1A, 0x15, 0xFD, 0x41, 0xF3, 0x1B, 0xB8, 0xD7, + 0xDA, 0x9D, 0x55, 0x52, 0xCF, 0xC7, 0x17, 0x00, + 0xC7, 0x39, 0x53, 0xA8, 0x5B, 0x6E, 0x62, 0xE7, + 0x57, 0xBC, 0xF1, 0x29, 0x82, 0xD6, 0xED, 0xBE, + 0x1D, 0xEB, 0x79, 0x58, 0xF9, 0x35, 0x20, 0x90, + 0xDB, 0xDC, 0x49, 0x43, 0x97, 0xCA, 0x12, 0x4B, + 0xD1, 0x0E, 0x27, 0x22, 0x67, 0xBB, 0xD7, 0x74, + 0x43, 0xE9, 0x0B, 0xBD, 0x17, 0xAF, 0xCA, 0x18, + 0x9F, 0xCB, 0xFF, 0xB2, 0x66, 0x2C, 0x53, 0x92, + 0xD7, 0x4F, 0xE4, 0xCD, 0x41, 0x4B, 0x9A, 0xBC, + 0x01, 0x56, 0x28, 0x08, 0xF9, 0x97, 0x49, 0xF3, + 0x51, 0x3B, 0xD2, 0xBD, 0xF9, 0x0C, 0xEB, 0xC6, + 0xEB, 0x6E, 0xB1, 0x0D, 0x5E, 0x8C, 0x5C, 0x08, + 0x2B, 0x4E, 0x39, 0xDD, 0x0C, 0x21, 0x93, 0x71, + 0xDC, 0x24, 0x8B, 0xD8, 0x01, 0x3A, 0x14, 0xBF, + 0xC7, 0xEF, 0x13, 0x9B, 0x51, 0xFB, 0x9F, 0x05, + 0xCC, 0x6D, 0xF8, 0x2E, 0xA7, 0x52, 0x5D, 0xE8, + 0x4A, 0xE1, 0xF8, 0x39, 0xD1, 0x8D, 0x8B, 0x44, + 0xD5, 0x6E, 0x9D, 0x9F, 0xF4, 0xCE, 0x55, 0xB4, + 0xA6, 0x6D, 0x2E, 0x7B, 0x41, 0xD5, 0xE8, 0x89, + 0xC8, 0xB6, 0x6A, 0xF3, 0x53, 0x73, 0x9B, 0x5C, + 0x79, 0xBA, 0xEA, 0xED, 0xE1, 0x64, 0x92, 0x16, + 0x6D, 0xB7, 0x39, 0x9E, 0xD8, 0x9A, 0x15, 0x13, + 0xA0, 0xB8, 0xF2, 0xEA, 0x35, 0xFE, 0x17, 0x44, + 0x52, 0x05, 0x02, 0xB9, 0xF5, 0x16, 0xE9, 0x5F, + 0xEF, 0xF4, 0xC6, 0x4D, 0x52, 0x4B, 0x74, 0x80, + 0x9E, 0x41, 0x5B, 0x5C, 0x14, 0x8A, 0xBB, 0xCE, + 0xAC, 0xFC, 0xBD, 0x0B, 0x71, 0x12, 0xF5, 0xBB, + 0xFE, 0x15, 0x5A, 0x1D, 0x22, 0x1C, 0x2C, 0x7C, + 0x11, 0x1B, 0xED, 0x02, 0xAA, 0x49, 0xC4, 0xA0, + 0x71, 0x4F, 0x08, 0x16, 0x55, 0x13, 0xBE, 0xD7, + 0xE9, 0x37, 0x83, 0x70, 0x8A, 0x47, 0x05, 0xC9, + 0xBE, 0x69, 0xB6, 0x54, 0x23, 0xCC, 0x64, 0xDC, + 0x44, 0xC2, 0x2B, 0x06, 0xE2, 0xD4, 0x2A, 0x86, + 0xED, 0xC1, 0xEC, 0x33, 0xCB, 0x71, 0x6C, 0x11, + 0xBB, 0xAF, 0x3E, 0xF2, 0x26, 0xAF, 0x5C, 0x8E, + 0xE6, 0xC9, 0x2F, 0x54, 0xB9, 0x92, 0xF0, 0x75, + 0xB7, 0xE9, 0x0C, 0x69, 0xAC, 0x7F, 0x14, 0xF4, + 0xAE, 0xE7, 0x95, 0xD3, 0xAF, 0x10, 0x91, 0x6C, + 0x38, 0x44, 0x01, 0xA1, 0xD4, 0x7F, 0x31, 0x36, + 0x56, 0x32, 0x9E, 0x2C, 0x37, 0x05, 0x10, 0x2B, + 0xB9, 0x27, 0x6B, 0x88, 0x77, 0x1F, 0xC7, 0x8C, + 0x46, 0xE8, 0x30, 0x62, 0x26, 0x01, 0xFB, 0x53, + 0xEC, 0xCF, 0xEE, 0xD8, 0xB3, 0x01, 0xD5, 0x39, + 0xBA, 0x0E, 0x77, 0x8B, 0x4D, 0xA8, 0x06, 0xDD, + 0x1F, 0x5E, 0x97, 0x0B, 0x88, 0xFE, 0xDB, 0xBB, + 0x08, 0x9F, 0x2D, 0xFF, 0x2A, 0xE9, 0xDA, 0xB9, + 0x74, 0xE6, 0x99, 0xFB, 0xEE, 0xFB, 0xD0, 0x17, + 0x8C, 0x07, 0xF1, 0xAB, 0x07, 0xAC, 0x7B, 0xFD, + 0x13, 0x55, 0x0A, 0x3B, 0xC6, 0xF4, 0x11, 0xD9, + 0x14, 0xB7, 0x6C, 0x49, 0x48, 0x66, 0xC2, 0xFC, + 0xDE, 0x20, 0x19, 0xB5, 0xEC, 0x92, 0x87, 0x08, + 0xE2, 0xA9, 0x73, 0x2D, 0xE2, 0xBF, 0x53, 0x4D, + 0xF2, 0x53, 0x9D, 0x56, 0x5A, 0x05, 0xB2, 0x99, + 0x47, 0xE0, 0xCF, 0xEE, 0xAB, 0x54, 0x7A, 0x9B, + 0x43, 0x10, 0xEC, 0xF9, 0x17, 0x05, 0x08, 0x41, + 0x6C, 0x07, 0x6F, 0xA1, 0x38, 0xFA, 0x6C, 0xE9, + 0xA4, 0xCA, 0x48, 0xC0, 0xED, 0xF9, 0x44, 0xCE, + 0xB0, 0xC9, 0xC1, 0x65, 0xFE, 0xE0, 0x69, 0xC1, + 0xD8, 0xF6, 0x32, 0x0D, 0xAB, 0x1F, 0x46, 0xC9, + 0x53, 0x02, 0xA1, 0xDD, 0x74, 0xFD, 0x44, 0xA7, + 0x08, 0xA6, 0x40, 0xAD, 0xF3, 0x6B, 0xAC, 0xC4, + 0x33, 0x8B, 0xAA, 0xD9, 0x5C, 0x83, 0x2D, 0x6B, + 0x2F, 0x60, 0xC9, 0x38, 0xF6, 0x4D, 0xE2, 0xE6, + 0x47, 0xCE, 0x27, 0x18, 0xCE, 0x1E, 0x53, 0xBA, + 0x6E, 0x85, 0x70, 0xF3, 0xC7, 0x7D, 0x94, 0x26, + 0xB7, 0xB4, 0xAD, 0xE5, 0xC7, 0x98, 0x5A, 0x24, + 0x3C, 0xDF, 0x2A, 0x6F, 0xD3, 0x8B, 0x16, 0xF9, + 0xBA, 0x7D, 0x2E, 0x2B, 0x7C, 0xAF, 0xD5, 0x68, + 0xD9, 0x9A, 0x99, 0x36, 0xC6, 0x5D, 0x9D, 0x9F, + 0x5E, 0x6C, 0x17, 0xEE, 0x58, 0xC2, 0xC7, 0xDF, + 0x5B, 0x6E, 0x04, 0x0A, 0xC2, 0x4E, 0x61, 0xF5, + 0x1D, 0x3A, 0x88, 0xC7, 0x88, 0x5D, 0x43, 0xC5, + 0x70, 0xC9, 0xFA, 0x1F, 0x47, 0xA3, 0x75, 0xEC, + 0x22, 0xBC, 0xDA, 0x71, 0xE9, 0xAB, 0xCA, 0x43, + 0xAB, 0x82, 0xFC, 0x10, 0xAD, 0x69, 0x13, 0x2E, + 0xC5, 0xC4, 0x0B, 0x98, 0x30, 0x66, 0x15, 0xEF, + 0xC8, 0xBD, 0x59, 0x90, 0x44, 0x5B, 0xD2, 0x02, + 0xC6, 0x58, 0x31, 0xC3, 0x87, 0xEE, 0xD9, 0x8D, + 0xF0, 0x60, 0x38, 0x71, 0xFC, 0xF4, 0x83, 0x8C, + 0xC5, 0xB9, 0xAC, 0x94, 0x84, 0x22, 0xE8, 0x8C, + 0xB2, 0xAE, 0xF8, 0xCF, 0x5A, 0x63, 0x58, 0x8E, + 0xB1, 0x0D, 0x02, 0x00, 0x13, 0xAC, 0x9C, 0xAA, + 0x4D, 0x95, 0x32, 0x54, 0xF7, 0x7F, 0xAD, 0x0F, + 0x7D, 0xF5, 0x58, 0xE2, 0x32, 0xE4, 0xFA, 0xC7, + 0x39, 0x37, 0xA9, 0x59, 0x9F, 0x3C, 0xA2, 0x8D, + 0x39, 0x9C, 0x70, 0x22, 0x09, 0x2A, 0x7C, 0xF4, + 0xBF, 0x9A, 0x06, 0xCB, 0xDC, 0x12, 0xE9, 0x2C, + 0x14, 0x50, 0xAF, 0xAC, 0xC9, 0xFB, 0x54, 0xEB, + 0x1B, 0xA0, 0xFC, 0x63, 0xD1, 0x79, 0xF6, 0x6E, + 0xA2, 0xE1, 0x0E, 0xA3, 0xF5, 0xC5, 0x05, 0x53, + 0x24, 0x1C, 0x7C, 0xC5, 0x6C, 0x28, 0xAE, 0x3B, + 0xB9, 0xB5, 0x6E, 0xAA, 0x39, 0xFE, 0x00, 0xD0, + 0xD5, 0x7C, 0x81, 0x42, 0xEC, 0x4D, 0x5F, 0xF1, + 0x17, 0xA1, 0x43, 0x1C, 0x7C, 0xDF, 0x73, 0x64, + 0x1B, 0xD6, 0x2E, 0xB2, 0x12, 0x20, 0xEE, 0xD9, + 0x2A, 0xCA, 0x69, 0xD1, 0x83, 0x2B, 0x07, 0x05, + 0x69, 0xAE, 0x9A, 0xFF, 0x2E, 0x5C, 0x80, 0x3B, + 0xCC, 0x29, 0x1B, 0xED, 0xD9, 0xB5, 0xEF, 0x2C, + 0xD6, 0xCE, 0x42, 0x5A, 0x69, 0x8A, 0x21, 0x1F, + 0x7C, 0xC2, 0x96, 0xD2, 0x29, 0x38, 0xB6, 0x93, + 0x6E, 0x9B, 0xE9, 0xC5, 0x42, 0x31, 0x39, 0x4B, + 0xB0, 0x70, 0x16, 0x04, 0x10, 0x15, 0x2F, 0x10, + 0x48, 0xBF, 0x1B, 0x51, 0x1E, 0x06, 0x8B, 0xA7, + 0x92, 0x82, 0xA7, 0x05, 0xB4, 0xF6, 0xBE, 0x2B, + 0x14, 0xB5, 0x6B, 0xA4, 0xF9, 0x2D, 0xE1, 0x5A, + 0x3C, 0x7C, 0xF7, 0x89, 0x57, 0x2C, 0xED, 0x96, + 0x9C, 0x2A, 0xA4, 0xF3, 0xF6, 0x10, 0xF2, 0x5C, + 0xBB, 0xA3, 0x58, 0x04, 0xB0, 0xD7, 0x99, 0xFE, + 0x5F, 0x6D, 0x36, 0xDE, 0xB1, 0x74, 0xB9, 0x84, + 0x54, 0x0E, 0xAC, 0x54, 0x69, 0x1B, 0x22, 0xB5, + 0xC0, 0xE6, 0x1C, 0xC7, 0x70, 0x6B, 0xBD, 0x30, + 0x48, 0xCF, 0x9C, 0x71, 0x1F, 0xCD, 0xE2, 0xE2, + 0xFE, 0x9D, 0x16, 0xBF, 0xBD, 0x37, 0x67, 0x95, + 0x1C, 0xC8, 0x54, 0x91, 0x8B, 0x8A, 0x75, 0x9F, + 0xBC, 0x30, 0xBD, 0xEF, 0x8A, 0xF3, 0x9D, 0xD2, + 0x06, 0x83, 0xF6, 0xBC, 0xD0, 0xBB, 0x5C, 0xFB, + 0x1D, 0x4B, 0x8F, 0xAA, 0x1A, 0xE7, 0x1B, 0xAE, + 0xF4, 0xB9, 0x75, 0xA1, 0xAE, 0x66, 0xD3, 0x2F, + 0x19, 0x5D, 0x86, 0x07, 0x17, 0x0C, 0x05, 0x58, + 0x58, 0x37, 0x79, 0x40, 0xD7, 0x32, 0x81, 0x48, + 0x22, 0x55, 0xD1, 0xB6, 0x6D, 0x6F, 0x36, 0x4C, + 0x3B, 0x52, 0x25, 0x4B, 0xE9, 0x9C, 0x26, 0xAA, + 0x5B, 0x6D, 0xFA, 0xC0, 0x5C, 0x91, 0x10, 0x23, + 0x10, 0x9E, 0xFE, 0x70, 0xAF, 0xA1, 0x64, 0xB1, + 0x16, 0x13, 0x02, 0x5E, 0x0F, 0x12, 0xA9, 0x0D, + 0xE0, 0x1F, 0xD6, 0xB5, 0x4C, 0x7A, 0x7D, 0xD8, + 0x2A, 0xDF, 0x8A, 0x44, 0x69, 0x5C, 0xCF, 0xBA, + 0x87, 0x9B, 0x1D, 0xC9, 0x9D, 0x38, 0x23, 0x91, + 0xB0, 0xCC, 0x01, 0x18, 0x16, 0xDF, 0x53, 0xC9, + 0x0A, 0x70, 0xA0, 0x0D, 0x15, 0xD5, 0x45, 0x47, + 0xBA, 0xF9, 0x5F, 0xDC, 0x4B, 0xCD, 0x92, 0xFA, + 0x2E, 0xF5, 0xC3, 0x9D, 0x94, 0x9D, 0x4E, 0xA2, + 0x72, 0x4C, 0x80, 0x84, 0xEF, 0xAD, 0x76, 0xDD, + 0x31, 0x03, 0x2C, 0xB3, 0xC1, 0x19, 0x36, 0x0A, + 0x6E, 0xAA, 0x3A, 0xDF, 0x1D, 0xCE, 0x3E, 0x0C, + 0xD6, 0x50, 0xD6, 0xFF, 0xC7, 0x3E, 0xBE, 0xA3, + 0x4A, 0x53, 0xAB, 0xDF, 0xE7, 0xA1, 0x60, 0x4F, + 0xF7, 0x83, 0x07, 0xB8, 0x96, 0xD1, 0x09, 0xA4, + 0x0F, 0xE7, 0x9B, 0xCC, 0xB8, 0xF3, 0x8A, 0x62, + 0x2B, 0x0A, 0xFD, 0x49, 0x52, 0x38, 0xCF, 0x64, + 0xCC, 0xB1, 0x19, 0x03, 0x5C, 0xB6, 0xB1, 0x57, + 0xFE, 0x0F, 0x06, 0x6A, 0x6E, 0x61, 0x27, 0xCC, + 0x35, 0xCF, 0xFA, 0xA3, 0x87, 0xEE, 0xA4, 0x27, + 0x42, 0x52, 0x80, 0xC1, 0x2F, 0x7B, 0xA8, 0x86, + 0xFB, 0x7E, 0x3E, 0xF1, 0xB4, 0x53, 0xF7, 0x8C, + 0x56, 0xD4, 0x9C, 0x9D, 0x3E, 0xE2, 0xDA, 0xCB, + 0x86, 0xF3, 0x5D, 0xB3, 0xAE, 0x78, 0xEA, 0x29, + 0x6B, 0xD9, 0x94, 0x63, 0xB9, 0x88, 0xE8, 0x8B, + 0x55, 0xBB, 0x23, 0x9F, 0xFE, 0xEB, 0x46, 0x00, + 0x41, 0x8A, 0xA0, 0xC8, 0xC5, 0x6D, 0x24, 0x94, + 0x52, 0x8D, 0xEB, 0x27, 0x30, 0x45, 0x98, 0xCD, + 0x6E, 0x07, 0xBD, 0x3F, 0x2E, 0xA3, 0xA9, 0xE9, + 0x4F, 0x68, 0x96, 0xBA, 0x82, 0x28, 0x7A, 0x02, + 0xDA, 0xCD, 0x1F, 0x3F, 0xD8, 0x42, 0x2C, 0xC2, + 0x65, 0xEB, 0xEB, 0xE6, 0x58, 0x95, 0x03, 0x08, + 0x3D, 0x44, 0xC3, 0x75, 0xEF, 0x01, 0x93, 0x4E, + 0x08, 0xE8, 0x66, 0xD1, 0xB1, 0x5D, 0x52, 0x9B, + 0xAD, 0xE6, 0xE0, 0x7C, 0xA2, 0x14, 0xF4, 0x5F, + 0xC2, 0x29, 0xE1, 0x46, 0x74, 0xCC, 0xAA, 0xF8, + 0xA9, 0xE8, 0xE7, 0x5B, 0xD2, 0x3D, 0x48, 0x47, + 0xDB, 0x03, 0x35, 0xC6, 0xAF, 0x2F, 0x89, 0xFB, + 0x07, 0xD2, 0x4D, 0x08, 0xF1, 0x13, 0xF5, 0x13, + 0x61, 0x79, 0x44, 0xBD, 0x72, 0xBB, 0x0C, 0xD9, + 0x59, 0x78, 0x7E, 0xD6, 0x8E, 0x63, 0xF8, 0x8D, + 0x62, 0x59, 0xC0, 0xCB, 0x47, 0x9C, 0x7C, 0x48, + 0xD0, 0xDF, 0xB6, 0x43, 0x48, 0xBC, 0x39, 0xDF, + 0x3A, 0x4A, 0xAE, 0x2E, 0xD6, 0xE3, 0x10, 0x50, + 0x7D, 0x4F, 0x21, 0x6F, 0x0A, 0xB6, 0x77, 0xC2, + 0xDD, 0x06, 0x59, 0x90, 0x8C, 0xD8, 0x15, 0x2E, + 0xFB, 0x68, 0x20, 0xD5, 0x42, 0x88, 0x56, 0xCF, + 0x0E, 0x13, 0x4A, 0x12, 0x89, 0x7D, 0x03, 0xAE, + 0x68, 0xFE, 0xD9, 0x0B, 0x0A, 0xB3, 0xCD, 0x0D, + 0xB8, 0x44, 0x35, 0x5B, 0x1A, 0xF5, 0x6B, 0x10, + 0x8E, 0x02, 0xA9, 0xC1, 0x0C, 0x18, 0x32, 0x0B, + 0x5E, 0x93, 0x6C, 0x40, 0x21, 0xBB, 0x5F, 0xC5, + 0x04, 0xAB, 0xAD, 0xFE, 0x81, 0x3B, 0x66, 0x89, + 0x67, 0x15, 0x13, 0x91, 0x06, 0xCA, 0xCD, 0x6F, + 0xE3, 0x3C, 0x91, 0xDF, 0x89, 0x0A, 0x64, 0xF1, + 0x63, 0xA0, 0x82, 0x1B, 0x71, 0x9E, 0x38, 0x49, + 0x0C, 0x4A, 0xF4, 0xFF, 0x7A, 0xFF, 0x98, 0x21, + 0xE1, 0x2C, 0x45, 0x10, 0x9D, 0xA2, 0x62, 0xE7, + 0xA1, 0xD6, 0x5F, 0xE4, 0x85, 0xCD, 0xB1, 0x7B, + 0xB7, 0x58, 0x6B, 0xEF, 0xA2, 0x95, 0x98, 0xCC, + 0x60, 0x8A, 0xAA, 0xB8, 0x46, 0xB6, 0x47, 0x05, + 0xC8, 0xAE, 0x9F, 0xB7, 0xEA, 0x8A, 0xC5, 0x22, + 0x4A, 0x89, 0x4F, 0xFC, 0xE7, 0xE5, 0xA7, 0xEE, + 0x1B, 0xBF, 0xD5, 0xEE, 0x2B, 0xCC, 0xCD, 0xD7, + 0x79, 0xED, 0x9B, 0xB7, 0xB2, 0xD2, 0xF3, 0x85, + 0x9C, 0xF1, 0xE9, 0xC5, 0x20, 0x81, 0x7D, 0xAE, + 0xA4, 0x99, 0x02, 0x8F, 0xEF, 0x31, 0x0E, 0xFD, + 0x25, 0x3D, 0x97, 0xFA, 0x2F, 0x97, 0x01, 0x07, + 0x6A, 0x2A, 0xBE, 0x24, 0x1A, 0x3B, 0x74, 0x11, + 0xDB, 0x7F, 0xC9, 0xC6, 0xD7, 0xC6, 0xCC, 0xFC, + 0x37, 0x26, 0xAD, 0xD9, 0xBE, 0xE0, 0x5D, 0x17, + 0x6B, 0x25, 0x82, 0x3B, 0x34, 0xF3, 0x52, 0x03, + 0xA8, 0xF2, 0x81, 0x58, 0x44, 0xAB, 0x7D, 0xBD, + 0xD2, 0x7E, 0x19, 0xB4, 0x95, 0xC1, 0x21, 0xC7, + 0x7C, 0x7B, 0xDA, 0x54, 0x07, 0xCC, 0x84, 0xE2, + 0x29, 0xEC, 0xE5, 0x9E, 0xDC, 0x00, 0xCA, 0x4C, + 0x13, 0x7B, 0x30, 0x91, 0x91, 0x95, 0x0C, 0xDB, + 0x9B, 0x19, 0xB2, 0xFB, 0x8C, 0x79, 0x49, 0x87, + 0xFA, 0x56, 0x8F, 0xD1, 0xD4, 0xBD, 0x68, 0x24, + 0x76, 0x8C, 0x71, 0x1A, 0x6B, 0x93, 0xFF, 0x79, + 0x54, 0x74, 0xB0, 0xDD, 0x92, 0x4B, 0x5E, 0x90, + 0x32, 0xE7, 0x79, 0x6D, 0xB7, 0xED, 0x59, 0x1F, + 0xB6, 0xAE, 0x3B, 0x26, 0x2C, 0xB9, 0x50, 0x2C, + 0x03, 0xD6, 0x9F, 0xBF, 0x76, 0x77, 0x90, 0x4C, + 0xCC, 0x1D, 0xC0, 0x43, 0xBF, 0x20, 0xD9, 0x10, + 0xBA, 0x12, 0x7B, 0x8D, 0x11, 0xBD, 0xF5, 0x91, + 0x20, 0x2C, 0x7B, 0x81, 0xC3, 0x64, 0xF6, 0x95, + 0xB6, 0x55, 0x81, 0xAC, 0xDC, 0xF5, 0xBD, 0x7C, + 0xD3, 0x79, 0x80, 0x2B, 0xD8, 0x85, 0x70, 0x8B, + 0x74, 0xDF, 0x20, 0x66, 0xE6, 0x6D, 0x78, 0xAC, + 0x4D, 0x38, 0x02, 0xAF, 0x96, 0x37, 0x6A, 0x17, + 0x4F, 0x1E, 0xAC, 0xC4, 0x57, 0xB0, 0x86, 0x43, + 0xDB, 0xC8, 0x9B, 0xD8, 0x1A, 0xA7, 0x06, 0x9C, + 0xDF, 0xD2, 0x45, 0x3A, 0x23, 0x85, 0xFB, 0x6D, + 0x9B, 0xD2, 0x81, 0x36, 0x29, 0xC4, 0x75, 0x86, + 0x4F, 0x58, 0x8F, 0x18, 0x3D, 0xE1, 0x46, 0xFB, + 0x01, 0x14, 0xB7, 0xA5, 0x7E, 0x12, 0xE3, 0x27, + 0x05, 0x1A, 0xCF, 0x68, 0xC4, 0xBC, 0xE3, 0xF8, + 0x2A, 0x9C, 0xED, 0x41, 0x7A, 0x39, 0x09, 0x6B, + 0xD9, 0xCA, 0xC3, 0x25, 0x3A, 0x43, 0x1E, 0x4A, + 0xFC, 0x88, 0x1E, 0x50, 0x86, 0xFD, 0xDE, 0xF2, + 0xD0, 0x38, 0x07, 0xFB, 0x78, 0x88, 0x1E, 0x33, + 0x7E, 0x91, 0x12, 0xBE, 0x77, 0x85, 0xB2, 0xF6, + 0x53, 0x9A, 0x3B, 0x27, 0xA3, 0x51, 0xC1, 0x86, + 0xBC, 0x5B, 0x8A, 0x45, 0x00, 0x6E, 0xF0, 0x10, + 0x29, 0xC1, 0xF4, 0x12, 0xC4, 0x94, 0xFF, 0x27, + 0x9F, 0xC3, 0xDA, 0xF1, 0xBB, 0x64, 0xD7, 0xC6, + 0xC9, 0x52, 0xC4, 0xEB, 0x04, 0xB8, 0x37, 0x4F, + 0x9E, 0x14, 0x9C, 0x94, 0x84, 0xB5, 0xBD, 0xF1, + 0xB9, 0x29, 0xC1, 0x60, 0xEB, 0x3E, 0x43, 0x0C, + 0x2C, 0x17, 0xC8, 0xDA, 0x96, 0xB4, 0x93, 0xA5, + 0x38, 0x72, 0x9D, 0xEC, 0xDF, 0x2A, 0x7A, 0x7F, + 0x32, 0x3F, 0xC8, 0x47, 0xE2, 0xEB, 0x60, 0x82, + 0xFF, 0xF0, 0x48, 0x28, 0x85, 0xD8, 0x4D, 0x4A, + 0xB2, 0x8D, 0x50, 0xAB, 0x43, 0xE3, 0x8C, 0xA3, + 0xE2, 0x55, 0x24, 0x8A, 0xBF, 0xDA, 0x20, 0x8B, + 0x78, 0x8F, 0x04, 0x79, 0x54, 0xEF, 0x3C, 0x4B, + 0xFA, 0x1C, 0xD9, 0x4E, 0xD2, 0x5B, 0x54, 0xD4, + 0x66, 0x25, 0x4E, 0x1A, 0xB2, 0xC9, 0x63, 0xE2, + 0x31, 0xA4, 0x62, 0x3D, 0xC5, 0xA6, 0x72, 0x61, + 0x11, 0xD2, 0x6E, 0x46, 0xC8, 0x7A, 0xF3, 0xF4, + 0x2D, 0xF8, 0x21, 0xAB, 0xC9, 0x6A, 0x09, 0x64, + 0xC8, 0x94, 0x26, 0xDB, 0xB2, 0xEB, 0x9F, 0x45, + 0x58, 0x4B, 0xC0, 0x3A, 0xF1, 0x0E, 0x5C, 0x9D, + 0x12, 0xB3, 0x51, 0x3A, 0xF5, 0xDF, 0x92, 0xA9, + 0x13, 0xF3, 0x36, 0x1A, 0xB4, 0xAD, 0x7F, 0x65, + 0xA7, 0x76, 0x04, 0xA9, 0xFB, 0x6B, 0x8F, 0x3E, + 0x51, 0x20, 0xE6, 0xA4, 0x96, 0xEC, 0x58, 0x87, + 0xD4, 0x5C, 0xB7, 0xA3, 0x86, 0x48, 0x8C, 0xFC, + 0x9E, 0x09, 0x50, 0x04, 0x27, 0x6C, 0x0C, 0x77, + 0x60, 0x72, 0x0F, 0x96, 0x93, 0x51, 0xC0, 0x17, + 0x38, 0x68, 0xDA, 0x8F, 0x0D, 0xEB, 0x14, 0xF3, + 0x8C, 0x67, 0xBC, 0x6A, 0x5C, 0x04, 0xC8, 0xE5, + 0xD8, 0x54, 0x26, 0x46, 0xE0, 0x83, 0x0E, 0xFF, + 0xB0, 0x1E, 0xA2, 0x47, 0x70, 0xB1, 0xA7, 0xB4, + 0xBA, 0xF6, 0xD2, 0xC3, 0xAA, 0x57, 0x72, 0x64, + 0x22, 0xEE, 0xDF, 0xC7, 0xB0, 0x90, 0x5F, 0x0C, + 0xCD, 0x40, 0x77, 0xCC, 0x4A, 0x62, 0x69, 0xA8, + 0xE6, 0x2F, 0xC5, 0x70, 0x95, 0x4B, 0x3E, 0xB5, + 0xF2, 0x7D, 0x14, 0x74, 0xA6, 0xE6, 0xD3, 0xF2, + 0xB3, 0x38, 0xD9, 0xDC, 0x47, 0xD7, 0xF2, 0x7F, + 0xB8, 0x96, 0x1D, 0x81, 0x81, 0x37, 0xEC, 0x95, + 0xC2, 0xB5, 0xA4, 0xE5, 0xD6, 0xC8, 0x43, 0xF6, + 0x8A, 0xC6, 0xB2, 0x7C, 0xC3, 0x99, 0x75, 0x96, + 0x36, 0xBD, 0x52, 0xC0, 0xA7, 0xA0, 0xC8, 0xA4, + 0x6E, 0xB4, 0xCF, 0xF5, 0x97, 0xF3, 0x91, 0xDC, + 0xB8, 0xE9, 0x2A, 0x0A, 0x1B, 0x1F, 0xAF, 0xED, + 0x97, 0x79, 0x25, 0xEB, 0x40, 0x7E, 0x86, 0x84, + 0x93, 0x45, 0x7A, 0xF4, 0x59, 0xF6, 0xC4, 0x8F, + 0x1B, 0x7F, 0xAC, 0x04, 0x1C, 0x48, 0xF8, 0x38, + 0x5B, 0x6C, 0x1F, 0x69, 0xAA, 0x06, 0xC4, 0x89, + 0x50, 0xCE, 0x48, 0xAD, 0x60, 0xC8, 0x71, 0x93, + 0xF9, 0x8E, 0x04, 0xCB, 0xC7, 0xD2, 0x2C, 0x0B, + 0xC8, 0x48, 0x85, 0x44, 0x71, 0x93, 0x90, 0xDE, + 0xB4, 0x9C, 0x6A, 0xC6, 0x5F, 0x61, 0x07, 0xC5, + 0x53, 0x4B, 0x24, 0x31, 0x30, 0x4A, 0x7D, 0xDD, + 0xF5, 0x18, 0x7E, 0xE1, 0xAA, 0x10, 0xD7, 0x9D, + 0xA0, 0xB1, 0x81, 0x9D, 0xC0, 0x80, 0x37, 0x5A, + 0x70, 0x5F, 0x45, 0xBC, 0x1F, 0xCA, 0x53, 0xB8, + 0xDD, 0x60, 0xF6, 0xAE, 0x2A, 0xC0, 0x70, 0xF1, + 0x00, 0x0A, 0x6F, 0x92, 0xC6, 0xF5, 0x6B, 0x29, + 0x7D, 0xB3, 0xF9, 0x01, 0x8A, 0xBD, 0x8A, 0x92, + 0x33, 0x8D, 0xA2, 0x9C, 0x59, 0x0A, 0xDF, 0x45, + 0xC5, 0x85, 0xE9, 0x8A, 0x32, 0xBC, 0x22, 0x08, + 0x1E, 0x4D, 0xDD, 0x20, 0xD7, 0xAA, 0xBA, 0xEE, + 0x4C, 0xB9, 0xF0, 0xB1, 0xFB, 0xBE, 0x86, 0x81, + 0x1A, 0x0F, 0xBB, 0xD8, 0x7A, 0x65, 0x81, 0xD5, + 0xD3, 0xC5, 0x65, 0x14, 0x82, 0x5B, 0xAD, 0x69, + 0xA6, 0xB2, 0x8D, 0x8D, 0x31, 0xF7, 0x2B, 0xDA, + 0x30, 0x04, 0x3E, 0xF5, 0x56, 0x59, 0x60, 0x52, + 0x89, 0x00, 0x8E, 0x3D, 0x57, 0x2B, 0x7B, 0xB9, + 0xED, 0x0B, 0x0E, 0xC7, 0x17, 0x2E, 0xF4, 0xE1, + 0xA3, 0x14, 0xEF, 0xA5, 0xD4, 0x2E, 0x9C, 0xDD, + 0x6B, 0xD7, 0xA9, 0x94, 0x1F, 0xF8, 0xD7, 0x2B, + 0x50, 0x2B, 0x9E, 0x56, 0xC2, 0x14, 0xB5, 0x63, + 0xEE, 0x79, 0x38, 0xFA, 0xA7, 0x62, 0x6A, 0x32, + 0xC1, 0xFB, 0x8E, 0x82, 0xBD, 0xF7, 0xE4, 0x9F, + 0x3C, 0xA9, 0x25, 0x15, 0x64, 0xA9, 0xD9, 0x4D, + 0x27, 0x42, 0x4B, 0xA4, 0xD1, 0xE4, 0x5D, 0xD3, + 0xFB, 0x14, 0x62, 0xDD, 0xC1, 0xB3, 0xDF, 0x5C, + 0x75, 0x91, 0x0A, 0xC0, 0x03, 0x15, 0xD2, 0x4A, + 0xAB, 0x4C, 0x07, 0x25, 0xB1, 0x90, 0x32, 0x7A, + 0x11, 0xA5, 0xD2, 0xDD, 0x87, 0x1E, 0xC3, 0x53, + 0xA4, 0x0F, 0xC5, 0x12, 0xB7, 0x34, 0x33, 0xD4, + 0xD3, 0x48, 0x81, 0xAF, 0x7F, 0x3B, 0x5A, 0x5E, + 0x8C, 0x12, 0xC6, 0x20, 0xBA, 0x70, 0x84, 0x82, + 0x61, 0x14, 0x1F, 0x56, 0xE2, 0xE2, 0xA8, 0x43, + 0x86, 0x1D, 0x25, 0xCC, 0xF0, 0x32, 0x17, 0x6E, + 0xA7, 0x5D, 0xD9, 0x69, 0x44, 0x4D, 0xE0, 0x02, + 0x55, 0xBB, 0xA5, 0x00, 0x60, 0xD3, 0xAD, 0x46, + 0x06, 0xFF, 0xEA, 0x67, 0xE6, 0x07, 0x33, 0x13, + 0xB1, 0xDE, 0x02, 0x25, 0xBD, 0xBB, 0x38, 0x47, + 0xD2, 0x5E, 0x40, 0xD2, 0x41, 0x19, 0x28, 0x2D, + 0x75, 0x84, 0x69, 0xA1, 0x5C, 0xE5, 0xAF, 0x06, + 0xDC, 0x8A, 0xEE, 0x7E, 0x9C, 0xA4, 0xEB, 0xE5, + 0xFC, 0xF5, 0x39, 0xF5, 0xFE, 0x08, 0xA7, 0x4A, + 0x3F, 0x8E, 0x79, 0x2B, 0x87, 0xDD, 0xF0, 0xE2, + 0x1F, 0x90, 0x08, 0x58, 0xAF, 0x96, 0x50, 0x7D, + 0x35, 0x6F, 0x3F, 0x46, 0xB4, 0xF0, 0xD4, 0x02, + 0x7C, 0x3D, 0xA8, 0xDA, 0x59, 0x4F, 0x00, 0x5C, + 0xCA, 0xE2, 0xAF, 0x79, 0x41, 0xE3, 0xE2, 0x52, + 0x89, 0x9A, 0x92, 0x73, 0x40, 0xF9, 0xD1, 0xAB, + 0x23, 0x8E, 0xB6, 0xDE, 0x10, 0xDF, 0x9C, 0x10, + 0xDB, 0xE5, 0x05, 0x96, 0x83, 0xF9, 0x7E, 0x94, + 0xC8, 0xBB, 0x01, 0x1F, 0xBC, 0xF6, 0x57, 0xB0, + 0x4B, 0xAA, 0xC9, 0xC3, 0xCB, 0x73, 0x76, 0x82, + 0x05, 0xAB, 0xB7, 0x4B, 0x13, 0xC4, 0x5B, 0x3C, + 0xCD, 0x23, 0xA0, 0xE5, 0xA5, 0xAD, 0x64, 0x93, + 0x92, 0xDC, 0x77, 0x53, 0xDF, 0x00, 0x55, 0xA4, + 0xF1, 0x46, 0x3E, 0xED, 0xFA, 0x36, 0x4E, 0xC4, + 0xEB, 0x95, 0xF8, 0x1E, 0x7C, 0x1F, 0x22, 0xA7, + 0x34, 0xB2, 0x44, 0x87, 0xC9, 0xD0, 0x75, 0xCB, + 0x4B, 0x55, 0x3E, 0x77, 0x9A, 0x9C, 0xE2, 0x7A, + 0xB3, 0x8C, 0x4C, 0xA3, 0x04, 0xFB, 0xBD, 0xC8, + 0xFB, 0x70, 0x21, 0x61, 0xCC, 0x95, 0x86, 0xF1, + 0x8F, 0x27, 0x66, 0xC9, 0xCD, 0x4B, 0xE8, 0x0C, + 0xF8, 0xD6, 0xA9, 0x7A, 0x98, 0x87, 0x43, 0x19, + 0x69, 0xB1, 0xFB, 0xEC, 0x54, 0x4E, 0x6F, 0xB8, + 0x29, 0x30, 0x4E, 0xB4, 0xAD, 0x32, 0xB5, 0x40, + 0xF3, 0x6E, 0x2C, 0x47, 0x16, 0xBC, 0x35, 0x59, + 0x2F, 0x92, 0x0D, 0x3D, 0x62, 0x67, 0xF9, 0x07, + 0x22, 0xFB, 0xBD, 0x1A, 0xF2, 0x3A, 0x46, 0x4F, + 0x08, 0xDF, 0xEC, 0x96, 0x31, 0x80, 0xF2, 0x0C, + 0xC9, 0x1E, 0x8F, 0xD2, 0x64, 0xF8, 0xB2, 0xE0, + 0x4C, 0xFD, 0x3A, 0xE6, 0x5E, 0xA7, 0x90, 0x28, + 0xF0, 0x34, 0x67, 0x6B, 0xBA, 0x25, 0x73, 0xBF, + 0x49, 0x5A, 0x7E, 0xFC, 0x6E, 0xCF, 0x00, 0x36, + 0x68, 0x77, 0x44, 0x98, 0x5E, 0x7F, 0x3E, 0xF5, + 0xCC, 0x62, 0xFA, 0xB6, 0xEA, 0xFE, 0x07, 0x76, + 0xFE, 0xB2, 0x65, 0xFD, 0xEF, 0xE8, 0xD8, 0x52, + 0xD2, 0x9A, 0xAE, 0x14, 0x83, 0xDE, 0x11, 0xCA, + 0xAF, 0x9B, 0x22, 0xF4, 0x51, 0xEE, 0xBB, 0xF5, + 0x5E, 0xF1, 0x6C, 0x6E, 0xFB, 0xF9, 0xDB, 0xB1, + 0x01, 0x36, 0xD0, 0xE7, 0x8F, 0xEC, 0x9C, 0x1F, + 0xC5, 0x22, 0x8D, 0xA9, 0x4C, 0xF6, 0xEE, 0x8D, + 0x24, 0xE2, 0xFC, 0xD0, 0x1C, 0xC8, 0xAA, 0x8C, + 0x1E, 0x23, 0xBE, 0xC9, 0xBC, 0x8C, 0x8D, 0xF4, + 0x8F, 0x88, 0xBF, 0x86, 0x47, 0xE1, 0x43, 0x0B, + 0x68, 0x38, 0x1F, 0x64, 0x25, 0x88, 0x37, 0x23, + 0xEA, 0xCD, 0x95, 0xD7, 0xB4, 0xC6, 0x22, 0xDB, + 0x86, 0xA6, 0x34, 0x0B, 0x0F, 0x17, 0x64, 0x35, + 0xAB, 0x40, 0x7A, 0x50, 0x1B, 0xD9, 0x5E, 0x51, + 0xA2, 0x81, 0x8C, 0xEB, 0x7E, 0xFB, 0x13, 0xD1, + 0xD2, 0x28, 0x87, 0x9F, 0x63, 0xE4, 0x0A, 0xC3, + 0x4D, 0xBA, 0xE7, 0x5F, 0x32, 0xE1, 0xDC, 0x12, + 0x17, 0x1A, 0xC8, 0x6C, 0x15, 0x64, 0xC5, 0x0A, + 0xFE, 0x87, 0x83, 0x16, 0x58, 0x42, 0x26, 0x6C, + 0x65, 0xDC, 0xF9, 0x10, 0x1C, 0xA3, 0xC9, 0x80, + 0x68, 0xB2, 0xFB, 0xC7, 0x48, 0xB9, 0xD9, 0x91, + 0x79, 0xFC, 0x13, 0xE4, 0x43, 0xD7, 0x96, 0xE5, + 0x00, 0x30, 0xFF, 0xCC, 0x34, 0x3E, 0x30, 0x6C, + 0x84, 0x6A, 0xF6, 0xDD, 0x65, 0x59, 0xBE, 0x8D, + 0xC1, 0xF4, 0x1F, 0xD3, 0x34, 0x49, 0x77, 0x0F, + 0xDA, 0x92, 0xA6, 0x08, 0x12, 0x15, 0x6E, 0x41, + 0xE5, 0x38, 0x6A, 0x1B, 0x8B, 0xD2, 0x41, 0x2F, + 0x7D, 0xAE, 0x5E, 0xE1, 0x00, 0xB9, 0x0B, 0x9F, + 0x1B, 0x0F, 0x1D, 0xB5, 0x98, 0x4C, 0x28, 0xBC, + 0x42, 0x63, 0x69, 0x49, 0xB6, 0xD4, 0xF9, 0x34, + 0x98, 0x54, 0xFE, 0x81, 0xC6, 0x56, 0x4B, 0x4B, + 0xB2, 0x23, 0x80, 0x6D, 0x5D, 0x17, 0x09, 0x69, + 0x40, 0x28, 0x3B, 0x86, 0x43, 0xDE, 0x3C, 0x44, + 0x38, 0xBD, 0xC3, 0x2D, 0x58, 0xDF, 0xF6, 0x37, + 0xB4, 0x62, 0x48, 0xAC, 0x61, 0xA5, 0x4D, 0xFA, + 0x10, 0xEA, 0x9F, 0xA4, 0x59, 0x08, 0x9C, 0x3B, + 0xF6, 0x39, 0xDE, 0x61, 0x73, 0x73, 0xE3, 0xB3, + 0x3D, 0x1E, 0x36, 0xE0, 0xC0, 0x6C, 0xA6, 0x6F, + 0xEE, 0x24, 0x39, 0x93, 0x3E, 0xB3, 0x6E, 0x0C, + 0x14, 0x8E, 0x83, 0xCF, 0x65, 0x4F, 0x21, 0xCB, + 0x0B, 0x8E, 0xB7, 0xDC, 0x80, 0x2D, 0x50, 0x5D, + 0x7C, 0x8E, 0xC5, 0x1F, 0xA1, 0x3D, 0x28, 0x05, + 0xE3, 0x20, 0x2C, 0x64, 0x1B, 0xD0, 0x51, 0x52, + 0x32, 0x0D, 0xC3, 0x13, 0x83, 0x62, 0x5A, 0xB2, + 0x47, 0xBB, 0x8B, 0xB7, 0x29, 0x0F, 0xFB, 0x7A, + 0xF4, 0xA7, 0xEC, 0x0D, 0xA6, 0xAB, 0x3B, 0x39, + 0x5F, 0x46, 0xFB, 0x98, 0xFA, 0x77, 0x50, 0x23, + 0x3C, 0xBB, 0xED, 0x32, 0x78, 0x1B, 0x46, 0xF1, + 0xF7, 0x6F, 0x26, 0x4E, 0x40, 0x1C, 0xB3, 0x52, + 0xC4, 0x37, 0x35, 0xA2, 0x63, 0x39, 0x2B, 0x9B, + 0xD1, 0x84, 0x46, 0x9A, 0x7A, 0xD0, 0x24, 0x0E, + 0xED, 0xE8, 0xD1, 0xDE, 0xC4, 0xDF, 0xFA, 0xE7, + 0xC7, 0x36, 0xDB, 0x3F, 0xCC, 0x2F, 0x3B, 0xDB, + 0xD5, 0xA0, 0x92, 0x98, 0x85, 0x25, 0x09, 0xF7, + 0xA4, 0x7E, 0x5A, 0x93, 0xC7, 0xD1, 0xC4, 0x88, + 0xD4, 0x64, 0x07, 0xB1, 0x0E, 0x7B, 0x61, 0x92, + 0x45, 0x25, 0xD1, 0x9E, 0x4A, 0xFE, 0x52, 0xE2, + 0x1C, 0x0F, 0xAA, 0xD1, 0x27, 0x18, 0x00, 0x09, + 0x40, 0x66, 0xDC, 0xC7, 0x62, 0x24, 0xE8, 0x2B, + 0xC3, 0xC0, 0xA1, 0x0E, 0x01, 0x55, 0x86, 0x29, + 0x14, 0x90, 0x61, 0x02, 0xA5, 0x41, 0xF2, 0x92, + 0x93, 0x0B, 0x12, 0x36, 0xAE, 0x14, 0x75, 0x17, + 0xBA, 0x2E, 0x2B, 0x92, 0x7C, 0xB4, 0x6C, 0x61, + 0x4B, 0x2D, 0xF6, 0x4B, 0xCB, 0x41, 0xF5, 0x66, + 0xE4, 0x9D, 0xC0, 0x31, 0xB8, 0x2C, 0x39, 0x5E, + 0x65, 0xED, 0xA5, 0x52, 0xB3, 0x45, 0x80, 0xE8, + 0xD6, 0x2C, 0x88, 0x21, 0xE5, 0xD0, 0xD7, 0x06, + 0x91, 0xE9, 0x60, 0xBB, 0xF2, 0xE8, 0xDC, 0x85, + 0xE1, 0xDD, 0x37, 0x3F, 0x69, 0x91, 0xAC, 0xE5, + 0x9F, 0x73, 0x39, 0x6D, 0xEB, 0x12, 0x73, 0x9D, + 0xE1, 0x95, 0x33, 0x5E, 0x3C, 0x91, 0x45, 0x3C, + 0x35, 0xB7, 0xBD, 0xCC, 0x9C, 0x35, 0xA8, 0x42, + 0xB2, 0x5C, 0x5B, 0x1E, 0xB0, 0xC2, 0x0D, 0x5E, + 0x6B, 0x01, 0x20, 0x85, 0xEF, 0x89, 0xFF, 0x8F, + 0xEF, 0x3B, 0xC8, 0x53, 0x6B, 0x3F, 0x5C, 0x9C, + 0x52, 0x8A, 0x29, 0xCC, 0x81, 0xC8, 0xB4, 0x0A, + 0xDC, 0xD9, 0xCF, 0x44, 0xDB, 0x51, 0xF3, 0x34, + 0xC6, 0x3E, 0xB2, 0x88, 0x13, 0xEF, 0x3A, 0xE6, + 0x6B, 0xF4, 0xE2, 0x45, 0x3F, 0x36, 0x22, 0xCD, + 0x32, 0x69, 0xBD, 0xAC, 0xAF, 0xE7, 0x43, 0xD9, + 0xA0, 0x7C, 0xEC, 0xF4, 0x9C, 0x49, 0x94, 0xCD, + 0xDD, 0x8F, 0x9C, 0xE0, 0x95, 0xC7, 0xA0, 0xF8, + 0x41, 0x8B, 0x56, 0x5C, 0x93, 0x87, 0xFC, 0xE5, + 0x65, 0xD1, 0x57, 0xD4, 0xB0, 0x23, 0xE0, 0xC2, + 0x07, 0xD2, 0x54, 0x4C, 0x4B, 0xD1, 0x51, 0x7B, + 0x35, 0x98, 0x8D, 0x62, 0xD0, 0x71, 0xA6, 0x99, + 0xA2, 0x4F, 0x11, 0x4D, 0xE4, 0xDB, 0xC8, 0x5A, + 0x81, 0xC1, 0x40, 0x22, 0x1D, 0xE1, 0x06, 0x44, + 0xB7, 0x5E, 0xFC, 0xDB, 0x6A, 0x80, 0x70, 0x36, + 0x81, 0xD6, 0x3F, 0x99, 0x79, 0x74, 0x2F, 0xE2, + 0x6D, 0x51, 0xB6, 0x4D, 0x76, 0xA3, 0x73, 0x57, + 0x19, 0x94, 0xA9, 0x39, 0x01, 0xD9, 0xC0, 0x21, + 0x8E, 0x11, 0x7F, 0xC4, 0x68, 0xAF, 0x04, 0xC4, + 0x9E, 0x3D, 0x30, 0xD7, 0x1D, 0x6B, 0xC0, 0x76, + 0x0B, 0x2B, 0x48, 0x42, 0x84, 0x27, 0xE6, 0x1A, + 0xC0, 0x46, 0xDD, 0x98, 0x4D, 0x83, 0x05, 0x4A, + 0x55, 0xCC, 0xE6, 0xA4, 0x69, 0x1C, 0x92, 0xFA, + 0x73, 0xB8, 0x68, 0xBA, 0x30, 0x55, 0xD0, 0xDA, + 0x2B, 0xF5, 0x6C, 0xD2, 0x67, 0x64, 0xB1, 0x92, + 0x92, 0xA1, 0x83, 0x57, 0x15, 0xBF, 0x76, 0x9F, + 0x90, 0xA6, 0x34, 0x09, 0x2F, 0x6D, 0x35, 0x12, + 0xC6, 0x73, 0x3A, 0x49, 0xC4, 0x1D, 0x76, 0x01, + 0xFC, 0xC6, 0xEA, 0xE0, 0x0A, 0xE4, 0xCE, 0x6D, + 0x92, 0x5D, 0x1C, 0x24, 0xAE, 0x16, 0x47, 0xA3, + 0x65, 0xE2, 0x81, 0x9F, 0xE5, 0xEB, 0xE1, 0xA7, + 0x0B, 0xBA, 0xF5, 0x96, 0xEA, 0x98, 0xE6, 0xF5, + 0xB4, 0x64, 0x8D, 0xE5, 0x3F, 0xF6, 0xBF, 0xC4, + 0x4F, 0x65, 0x8D, 0x02, 0xA0, 0xCE, 0xE3, 0x96, + 0x14, 0xAE, 0x3D, 0x9E, 0x89, 0xEA, 0x5D, 0x07, + 0xB9, 0x95, 0x98, 0x1A, 0x55, 0xAF, 0xF3, 0xEB, + 0xDC, 0x67, 0xB8, 0xCE, 0x37, 0xBD, 0x2F, 0x11, + 0xD7, 0xB8, 0xF7, 0x45, 0xB2, 0xF7, 0x30, 0x9C, + 0x1D, 0x49, 0x69, 0xFA, 0xBA, 0xF9, 0x8C, 0x04, + 0x99, 0xDD, 0x29, 0xFA, 0x1A, 0x90, 0xD7, 0x90, + 0x2F, 0xD6, 0xBD, 0x05, 0x7F, 0xD5, 0x53, 0xD6, + 0x62, 0xCA, 0xEF, 0x40, 0xA4, 0x78, 0xB1, 0x00, + 0x6B, 0xA6, 0x64, 0x54, 0x93, 0xC3, 0xD2, 0xD1, + 0x12, 0x9D, 0x11, 0x85, 0xD3, 0x81, 0xB3, 0x93, + 0x57, 0xC4, 0x9B, 0xE4, 0x2D, 0x30, 0x5E, 0x1F, + 0xA4, 0x1F, 0x8E, 0xE2, 0x31, 0x72, 0xD2, 0x0B, + 0x68, 0x27, 0x89, 0xE9, 0x7C, 0x11, 0x7A, 0x10, + 0x26, 0x44, 0x01, 0xA0, 0x68, 0x32, 0xEB, 0x00, + 0xE5, 0x7A, 0x17, 0x74, 0xDF, 0x5F, 0x20, 0xCA, + 0x26, 0x43, 0x3E, 0x44, 0x8C, 0xD8, 0xA1, 0xCE, + 0xA2, 0xB7, 0xBB, 0x87, 0xBA, 0x5D, 0xD2, 0x11, + 0x4A, 0xD3, 0x98, 0x1D, 0x25, 0x11, 0x74, 0xA3, + 0x49, 0x40, 0x1D, 0x7D, 0x55, 0x0E, 0xAF, 0x56, + 0x42, 0x77, 0x6C, 0x04, 0x3C, 0x84, 0x61, 0xC6, + 0x28, 0x53, 0x14, 0x8A, 0x86, 0xD6, 0xD2, 0x48, + 0x36, 0xB2, 0xDB, 0x99, 0x72, 0x6F, 0x2F, 0xB8, + 0x51, 0x70, 0xD1, 0x8D, 0x2B, 0x58, 0x74, 0x8A, + 0xA2, 0x1F, 0x6B, 0x2D, 0xBB, 0xA5, 0xFB, 0x21, + 0x11, 0x26, 0xBB, 0xE5, 0x6B, 0xAE, 0x59, 0xDA, + 0xA2, 0xF6, 0xA9, 0x3C, 0x1A, 0x78, 0x95, 0xF9, + 0x9D, 0xFD, 0x55, 0x75, 0x7C, 0xA3, 0xAF, 0x10, + 0x97, 0x0B, 0xBA, 0x4A, 0xC2, 0xE9, 0xF5, 0x3C, + 0x32, 0x0D, 0x78, 0xC9, 0x53, 0xC5, 0x7D, 0x63, + 0x52, 0xA2, 0xA9, 0xE8, 0x64, 0xCC, 0x85, 0xF2, + 0x0E, 0xBE, 0xA9, 0x2A, 0x79, 0x43, 0x55, 0x0A, + 0xC5, 0x11, 0xF5, 0x53, 0x0C, 0x87, 0x48, 0x85, + 0x9A, 0xCF, 0x67, 0xF1, 0xD9, 0x02, 0xC2, 0x45, + 0x4E, 0x72, 0x0B, 0x6F, 0x7D, 0xFE, 0xEB, 0xEA, + 0x32, 0xC7, 0xD9, 0x2F, 0x3D, 0x7E, 0xD9, 0xC5, + 0x40, 0x73, 0xE4, 0x7F, 0x6E, 0x0A, 0x0D, 0x92, + 0xDB, 0x2A, 0x2B, 0x0B, 0x10, 0x0F, 0x44, 0x56, + 0x96, 0x1B, 0x9C, 0xCF, 0x83, 0xF9, 0x0A, 0xB0, + 0xE6, 0x7A, 0xD4, 0xC1, 0x36, 0x3F, 0xE0, 0x17, + 0x4E, 0x82, 0x3E, 0x08, 0xB7, 0xDC, 0xB7, 0x50, + 0x75, 0x47, 0x5A, 0x02, 0x02, 0xB2, 0xC0, 0x82, + 0x8E, 0xD9, 0x12, 0x14, 0x92, 0x8A, 0x9F, 0x6F, + 0x36, 0xF4, 0xAD, 0x12, 0x21, 0xDF, 0xE2, 0x79, + 0xFA, 0xBF, 0xCD, 0x1D, 0xD3, 0x9E, 0x02, 0x8C, + 0xCE, 0x81, 0x27, 0x04, 0xE0, 0xE2, 0x2E, 0x39, + 0x16, 0x5D, 0x0D, 0x4E, 0x11, 0x4E, 0xBF, 0x6D, + 0x0C, 0x1C, 0xF6, 0x1E, 0x58, 0xD5, 0xEC, 0xDC, + 0x78, 0xD8, 0xC8, 0x95, 0x62, 0x95, 0xF8, 0x7A, + 0xEE, 0x59, 0x55, 0x82, 0xBB, 0xC0, 0x8E, 0xDC, + 0x55, 0x6F, 0xF0, 0x8D, 0xEF, 0xC7, 0xE9, 0x23, + 0x42, 0x8E, 0x97, 0x7B, 0xBD, 0x4B, 0x40, 0x6D, + 0x18, 0x74, 0x55, 0xB3, 0x35, 0xCC, 0x04, 0x1C, + 0xA3, 0xC1, 0xCB, 0x29, 0xFF, 0x4D, 0xA0, 0x73, + 0x3A, 0xFA, 0x5B, 0xC2, 0x17, 0x72, 0x2C, 0x8C, + 0xEA, 0x2D, 0xB5, 0x9A, 0x7D, 0x89, 0x99, 0x99, + 0x05, 0x72, 0x6B, 0x93, 0xAF, 0x5F, 0xE9, 0xAD, + 0xCE, 0x14, 0x55, 0xF5, 0x3C, 0xD9, 0x90, 0x54, + 0xAD, 0x24, 0x34, 0x29, 0xDC, 0xB2, 0xAB, 0x87, + 0x88, 0x65, 0x11, 0x5E, 0xD9, 0xA7, 0x7C, 0xFA, + 0x88, 0x0B, 0x00, 0x1C, 0x1C, 0x11, 0xD2, 0x28, + 0x1F, 0xDA, 0xD2, 0x81, 0xD3, 0x8B, 0xF9, 0xC0, + 0x2C, 0xF9, 0xEE, 0xDC, 0xE5, 0xEC, 0x95, 0x80, + 0x12, 0x02, 0xDC, 0x04, 0xB0, 0xA6, 0x74, 0x7E, + 0x01, 0x09, 0xDE, 0xFE, 0xA5, 0x02, 0xD6, 0x5D, + 0xC0, 0xA2, 0x59, 0x8A, 0x09, 0xA1, 0x19, 0x0A, + 0xA2, 0x93, 0xB1, 0xDA, 0x3F, 0x63, 0x21, 0x3A, + 0x97, 0x02, 0xC2, 0xF6, 0xC9, 0x3C, 0xEE, 0xD9, + 0xEA, 0x7D, 0x61, 0x1A, 0x1E, 0x4F, 0x05, 0xB0, + 0x13, 0xFD, 0xF3, 0x58, 0xB5, 0x33, 0x7C, 0xE8, + 0x81, 0xF4, 0xBE, 0x08, 0xAD, 0x01, 0x10, 0x3A, + 0xD9, 0x4B, 0xFE, 0x95, 0xB2, 0x86, 0x69, 0x32, + 0x21, 0x52, 0x59, 0x8B, 0x99, 0x12, 0xB6, 0xD8, + 0x06, 0x79, 0x6F, 0x42, 0x61, 0xEA, 0x48, 0xE7, + 0x00, 0xD4, 0xE0, 0xFE, 0x7B, 0x0E, 0xE1, 0xD9, + 0x09, 0xD1, 0xDF, 0xB6, 0x5F, 0x3A, 0x81, 0x3A, + 0x7D, 0x49, 0x86, 0x65, 0x6B, 0x33, 0xE3, 0xAD, + 0x4A, 0xD0, 0xE7, 0x67, 0xCA, 0xAF, 0x48, 0x54, + 0xAD, 0xEE, 0xAC, 0xC4, 0xB4, 0x0C, 0xE1, 0x87, + 0xD9, 0xB5, 0xE6, 0x90, 0xAD, 0x55, 0x5F, 0xB1, + 0x7A, 0xFA, 0x4B, 0x28, 0xEE, 0x99, 0xE2, 0x35, + 0x73, 0x67, 0xC2, 0x3A, 0x70, 0x7F, 0x6B, 0x5E, + 0x77, 0x34, 0x0B, 0x26, 0x46, 0x63, 0x55, 0xEE, + 0xAF, 0x5D, 0xEA, 0xCB, 0x73, 0xE8, 0xE3, 0xFE, + 0x60, 0xA5, 0xC0, 0xBE, 0xAD, 0x7C, 0xE9, 0x2A, + 0x3D, 0xCB, 0xFE, 0x99, 0x65, 0xC8, 0x61, 0x5D, + 0xE9, 0xBD, 0xCD, 0x44, 0x5E, 0x31, 0x7D, 0xC5, + 0x59, 0x68, 0xDC, 0xCA, 0xAF, 0x66, 0xE1, 0x42, + 0x63, 0x96, 0x43, 0x1E, 0x33, 0xDB, 0x20, 0x77, + 0x1A, 0x4D, 0x04, 0x1D, 0xAB, 0x93, 0x91, 0xE6, + 0x71, 0x32, 0x4E, 0xB7, 0x82, 0x22, 0xB8, 0x1A, + 0x7E, 0x82, 0xFF, 0xB6, 0x64, 0x62, 0xC5, 0x5E, + 0x90, 0x75, 0x18, 0xF2, 0xE9, 0xF0, 0x26, 0xD0, + 0x8E, 0x7C, 0x35, 0x8D, 0xB1, 0x8A, 0xFD, 0x65, + 0xC5, 0x80, 0x36, 0x2B, 0x13, 0xC3, 0x28, 0xB1, + 0xE0, 0x46, 0x43, 0x78, 0x9E, 0xD0, 0xCC, 0x4E, + 0x9C, 0xD0, 0xBE, 0xDC, 0x34, 0x46, 0x98, 0x00, + 0x7C, 0x64, 0xF4, 0x45, 0xE7, 0xD2, 0x89, 0x2D, + 0x75, 0x86, 0x4A, 0xCD, 0x59, 0x88, 0xB8, 0x1D, + 0x5B, 0xCD, 0xFF, 0x94, 0x12, 0x20, 0xE6, 0xD4, + 0x75, 0x81, 0xA3, 0xA2, 0x7D, 0x58, 0x07, 0x74, + 0xEE, 0x35, 0x1A, 0x6C, 0xDA, 0x92, 0xB4, 0x9E, + 0x4A, 0x11, 0xB9, 0x70, 0x8D, 0x26, 0xC9, 0x3E, + 0xC7, 0xE5, 0x13, 0xDD, 0x9B, 0x85, 0x2C, 0xF9, + 0x81, 0x7A, 0xD2, 0xAB, 0xBC, 0xB2, 0x39, 0xFD, + 0x1A, 0xF4, 0x85, 0x33, 0x09, 0x46, 0xE7, 0xF1, + 0x65, 0xFB, 0x23, 0x8B, 0x54, 0x0F, 0xCB, 0x2C, + 0x72, 0x6C, 0xCF, 0xA5, 0xA0, 0xA2, 0xFD, 0x76, + 0xF1, 0x07, 0x5B, 0x77, 0x78, 0x2A, 0xC5, 0xD1, + 0x90, 0xF6, 0xBD, 0x48, 0x93, 0x21, 0x21, 0x83, + 0x72, 0xAC, 0x7F, 0xE6, 0x91, 0x40, 0x45, 0xA4, + 0x17, 0xE3, 0x05, 0xE2, 0xF2, 0x50, 0xA0, 0xEE, + 0xC4, 0x2A, 0xD6, 0xF0, 0x28, 0xBC, 0xEB, 0xF4, + 0xFD, 0xD5, 0xA7, 0x87, 0xBB, 0xD1, 0xF2, 0xFA, + 0x00, 0x6D, 0x47, 0x0B, 0x72, 0x15, 0x14, 0x4C, + 0x68, 0x6D, 0x82, 0x99, 0x42, 0xD3, 0x63, 0xCB, + 0xDB, 0xF5, 0xDE, 0x88, 0x8C, 0x73, 0xEE, 0x37, + 0xFB, 0x4D, 0xD5, 0xF0, 0xCD, 0x6B, 0xDE, 0x1F, + 0xAD, 0x6C, 0x54, 0xEA, 0xF4, 0xD6, 0xFD, 0x70, + 0x2E, 0x1B, 0x28, 0x45, 0xD7, 0x4F, 0x12, 0x41, + 0xDD, 0xE6, 0x47, 0x11, 0x72, 0x04, 0x65, 0x8D, + 0xA6, 0xAB, 0x7B, 0xAC, 0x8D, 0x5F, 0x2C, 0x2A, + 0x39, 0xA2, 0xB1, 0x2C, 0x90, 0xBB, 0x5E, 0x99, + 0xE4, 0xD7, 0x5D, 0x0A, 0xDE, 0x8B, 0x88, 0xB1, + 0x21, 0xF2, 0xF9, 0x6C, 0x3E, 0xA7, 0xA7, 0x67, + 0x86, 0xEE, 0x68, 0x5E, 0xA2, 0x72, 0x2A, 0x57, + 0xFC, 0x2A, 0xE2, 0x81, 0xFF, 0x54, 0xDC, 0x2D, + 0x66, 0x2C, 0xD7, 0x3B, 0x56, 0xCA, 0x5B, 0x1D, + 0xE5, 0x06, 0x16, 0x01, 0x5F, 0x38, 0x33, 0xC2, + 0xAB, 0xE2, 0xD8, 0xFE, 0xE5, 0x46, 0x25, 0x2A, + 0xA4, 0x99, 0xB0, 0xB6, 0xA9, 0xB4, 0x3E, 0xD0, + 0x62, 0x51, 0x2E, 0xF2, 0xC3, 0xAE, 0x66, 0x84, + 0x55, 0x07, 0x57, 0x81, 0x50, 0x07, 0x88, 0xD1, + 0xEB, 0xD5, 0x9B, 0x33, 0xD9, 0x7B, 0x6B, 0xEC, + 0x10, 0xCB, 0x36, 0x19, 0x83, 0x9B, 0x05, 0x11, + 0xAD, 0x34, 0xC3, 0xFA, 0x44, 0xE2, 0xC2, 0x1A, + 0x3E, 0x5A, 0x5C, 0x7C, 0x78, 0xDC, 0xA9, 0x57, + 0x82, 0x60, 0x6D, 0x7D, 0x3E, 0x1E, 0xB2, 0x19, + 0x36, 0xDF, 0xFB, 0x34, 0x16, 0x3B, 0xAE, 0x2D, + 0x63, 0x6B, 0x40, 0x55, 0xED, 0xC3, 0x3B, 0x4B, + 0x14, 0x22, 0x3E, 0x40, 0xE6, 0x22, 0xB1, 0xA4, + 0xDF, 0x9D, 0x67, 0xD5, 0x73, 0x90, 0x76, 0x99, + 0x88, 0xDA, 0x96, 0x0B, 0x39, 0x56, 0x10, 0x87, + 0x5E, 0x1E, 0xDC, 0x8D, 0xB9, 0xFA, 0x67, 0x29, + 0x96, 0x16, 0x24, 0x9B, 0x5B, 0x41, 0x75, 0x21, + 0xFF, 0x26, 0x58, 0x64, 0x3D, 0xC5, 0x74, 0x8D, + 0xD2, 0x1C, 0x4A, 0xCB, 0x58, 0x2B, 0x85, 0xED, + 0x53, 0x4A, 0xA3, 0x1A, 0x65, 0x31, 0xA4, 0x30, + 0x29, 0x7C, 0x16, 0xB4, 0x0C, 0xE9, 0xF0, 0x7B, + 0x3D, 0xAE, 0x5E, 0xB3, 0x44, 0xB5, 0x1E, 0xFB, + 0x7C, 0xBE, 0x3B, 0xFC, 0x09, 0x8A, 0xB2, 0x38, + 0x00, 0xA5, 0x9C, 0x24, 0x85, 0xF1, 0x88, 0xB0, + 0xBB, 0x0A, 0xF2, 0xA3, 0xB8, 0x08, 0x27, 0xB6, + 0x59, 0xDF, 0x48, 0xAF, 0x58, 0xF6, 0x58, 0x15, + 0xDE, 0xD8, 0x71, 0xE4, 0x9C, 0xC8, 0xB1, 0x9B, + 0xC0, 0x26, 0xFB, 0x7B, 0xD1, 0xCD, 0xD1, 0x83, + 0x91, 0xEC, 0x96, 0x23, 0x49, 0x8D, 0xA5, 0x2B, + 0x30, 0x2A, 0x50, 0x46, 0xF7, 0x73, 0x2E, 0x96, + 0x11, 0x92, 0x95, 0xF7, 0x19, 0x13, 0xBF, 0x27, + 0xFA, 0xFB, 0x0E, 0x2E, 0x7A, 0x39, 0x41, 0xB4, + 0x4A, 0x9F, 0xD7, 0x37, 0xF1, 0xC7, 0x71, 0x70, + 0x9E, 0xD8, 0x41, 0x7C, 0x8D, 0x78, 0x7D, 0xCF, + 0x87, 0xC2, 0x89, 0x95, 0xBD, 0x6B, 0x1C, 0x4A, + 0x26, 0xC5, 0x9A, 0xB1, 0xCD, 0x0A, 0x58, 0xB6, + 0xDD, 0x28, 0x88, 0x2C, 0x8B, 0xD9, 0xCD, 0x9E, + 0x9E, 0x8A, 0xDE, 0x57, 0xAE, 0xAB, 0x23, 0xA0, + 0x17, 0xEB, 0x9C, 0x81, 0xAC, 0x13, 0xF7, 0x10, + 0x85, 0xC6, 0x04, 0xC1, 0x76, 0x6D, 0x9B, 0xEF, + 0xA8, 0xD3, 0xF2, 0xE7, 0xB5, 0x49, 0x6D, 0x4E, + 0x55, 0xA8, 0x71, 0x34, 0xD7, 0x9D, 0x40, 0xA4, + 0x22, 0x0D, 0x21, 0xCE, 0xD2, 0x20, 0x97, 0x1A, + 0xCC, 0x90, 0x2C, 0x25, 0xD5, 0x14, 0x56, 0x07, + 0xD2, 0xF9, 0xFD, 0xFA, 0x0C, 0xDC, 0x46, 0x7A, + 0x71, 0xB4, 0xEF, 0x0D, 0x81, 0xD1, 0x13, 0x98, + 0x62, 0xE7, 0xCB, 0xFF, 0xCD, 0x5B, 0x78, 0x0C, + 0x09, 0xB4, 0x1A, 0xB9, 0x65, 0x3C, 0x14, 0xE5, + 0x31, 0x4F, 0x2E, 0x9A, 0x79, 0x93, 0xF0, 0xA0, + 0x4A, 0xAB, 0x01, 0x53, 0x42, 0x12, 0xF1, 0xB5, + 0x80, 0x05, 0x0E, 0xFE, 0xFC, 0x91, 0x54, 0xDC, + 0x31, 0x96, 0x57, 0x95, 0xFF, 0x3B, 0x60, 0x70, + 0x7A, 0xCE, 0x6F, 0x3A, 0x17, 0xA2, 0x8D, 0x56, + 0xC8, 0xF5, 0x6A, 0x39, 0x23, 0xE1, 0xE4, 0x6A, + 0x9C, 0x26, 0xD6, 0xA7, 0x27, 0x7D, 0xA3, 0xEB, + 0x89, 0x38, 0xFA, 0xDC, 0xA4, 0x7F, 0x82, 0xD0, + 0xE4, 0x40, 0x17, 0x15, 0xB2, 0xD8, 0xF7, 0xBE, + 0x55, 0x11, 0x49, 0x68, 0x22, 0xDE, 0x0B, 0xA9, + 0xAE, 0xB0, 0xB3, 0x43, 0x0B, 0x1C, 0xF6, 0xE3, + 0x40, 0x7D, 0xF8, 0xA6, 0x25, 0xF9, 0x6B, 0x2E, + 0xDA, 0x69, 0x4F, 0x03, 0xBA, 0xCE, 0x7D, 0x58, + 0x49, 0x37, 0x19, 0x5D, 0xBB, 0x90, 0xF6, 0xB0, + 0xF6, 0xFA, 0x61, 0xC6, 0xDF, 0x89, 0x82, 0xAF, + 0x0C, 0xBB, 0x68, 0x94, 0x55, 0xDA, 0xF1, 0x8C, + 0x55, 0xC2, 0xC0, 0x5F, 0xF9, 0x52, 0x6A, 0xD3, + 0x99, 0x04, 0xAA, 0xA8, 0x79, 0x01, 0x03, 0x84, + 0x12, 0xB3, 0x1C, 0xEB, 0x61, 0x22, 0x41, 0x88, + 0x9A, 0xB6, 0x5A, 0x15, 0x64, 0x7A, 0x43, 0x40, + 0xBC, 0x42, 0xD3, 0x7E, 0x77, 0x4A, 0xA6, 0x99, + 0x0C, 0x8A, 0xD0, 0x37, 0x53, 0x43, 0xF8, 0x05, + 0xFA, 0x03, 0x70, 0x2F, 0xDE, 0xB8, 0x5B, 0xED, + 0xC1, 0x03, 0x74, 0xEE, 0x91, 0x12, 0xF9, 0x3B, + 0x81, 0x16, 0x5B, 0xB9, 0xD3, 0x17, 0xA0, 0xE7, + 0xB1, 0x19, 0xBC, 0xEB, 0x96, 0x3C, 0x89, 0x9D, + 0x39, 0x6E, 0x2C, 0x5D, 0xD0, 0x12, 0xE2, 0x46, + 0x33, 0x12, 0x3D, 0x3C, 0xC8, 0x82, 0xC6, 0xA1, + 0x12, 0x27, 0xDA, 0xF9, 0xF2, 0x03, 0x61, 0xB4, + 0xA5, 0xD8, 0xF3, 0x1C, 0x71, 0xC5, 0xE5, 0xF6, + 0xA9, 0x9A, 0x7C, 0x83, 0xA6, 0x2D, 0x99, 0x30, + 0xF4, 0xB5, 0x71, 0xA2, 0xD4, 0xB4, 0x14, 0x87, + 0x10, 0x1A, 0x82, 0x89, 0xDF, 0x0D, 0xA7, 0x40, + 0xC4, 0xAC, 0xB3, 0xC2, 0xEF, 0x38, 0xF7, 0x64, + 0x58, 0xE9, 0x3D, 0xF5, 0xD7, 0x13, 0x4F, 0x85, + 0xBE, 0x35, 0x82, 0xEA, 0x25, 0x5E, 0xC3, 0x6F, + 0xDA, 0x7F, 0xEA, 0x9A, 0x84, 0x76, 0x4F, 0xFF, + 0x94, 0x6C, 0x22, 0x88, 0xE5, 0x95, 0xAF, 0x17, + 0xA6, 0x6B, 0x58, 0xAE, 0xB7, 0xBA, 0xB0, 0x32, + 0x32, 0xA9, 0x19, 0x17, 0xBB, 0x37, 0xFD, 0xBA, + 0x0E, 0x7F, 0x76, 0x22, 0xD4, 0xDA, 0xC4, 0x9B, + 0x29, 0xF0, 0x1E, 0x2C, 0xE6, 0x2D, 0xD8, 0x98, + 0xA5, 0x38, 0xB6, 0x2C, 0xCF, 0xC1, 0x4E, 0xBA, + 0x28, 0x4C, 0x15, 0x92, 0x80, 0x37, 0xF6, 0x70, + 0x1D, 0xFB, 0xDA, 0xDE, 0xB4, 0xA0, 0xB2, 0x79, + 0xBB, 0x5A, 0xA8, 0x07, 0x95, 0xBA, 0x45, 0x6E, + 0x23, 0x33, 0x14, 0x01, 0xC5, 0x4A, 0xF4, 0xF4, + 0xEE, 0xEF, 0x62, 0x91, 0x60, 0xD6, 0x9C, 0x8C, + 0xE6, 0x04, 0x63, 0x13, 0x84, 0xD0, 0xF7, 0xFC, + 0xAB, 0x88, 0xD6, 0x66, 0x11, 0xAC, 0x95, 0x62, + 0xE8, 0x28, 0x13, 0x95, 0x41, 0x23, 0x41, 0x7A, + 0x45, 0x3F, 0x84, 0x65, 0xAF, 0x8F, 0xCD, 0xD4, + 0xF2, 0x2D, 0x45, 0x70, 0x02, 0x2E, 0xCD, 0x4F, + 0x9D, 0xD6, 0x0F, 0x74, 0x5F, 0xB6, 0xA5, 0xFF, + 0xF4, 0x37, 0x8A, 0x9F, 0xFB, 0x76, 0xC7, 0xA1, + 0x5B, 0x91, 0xB3, 0xC2, 0xD0, 0x2C, 0xB8, 0xFB, + 0x68, 0xCC, 0xE4, 0x8B, 0x9F, 0xFA, 0xDB, 0x03, + 0x85, 0xD9, 0xC7, 0xBC, 0xA7, 0xD5, 0xFF, 0x61, + 0x4A, 0xCA, 0xB8, 0x9A, 0xBC, 0x8D, 0x8B, 0x73, + 0xC8, 0x3E, 0x4D, 0x4C, 0x6F, 0xB9, 0x75, 0x71, + 0x95, 0x93, 0x43, 0x99, 0x0D, 0xE9, 0xFA, 0x26, + 0x38, 0x93, 0xA6, 0xA9, 0x64, 0x83, 0x15, 0x40, + 0x81, 0x98, 0xA0, 0x1E, 0xCE, 0x33, 0xC3, 0xD1, + 0xE3, 0x55, 0xD0, 0x20, 0xE0, 0xB2, 0x79, 0x5E, + 0x5C, 0x22, 0x23, 0x65, 0xDC, 0x32, 0x87, 0x8D, + 0x68, 0x94, 0x10, 0xC8, 0x9E, 0xED, 0x62, 0x03, + 0x3A, 0x91, 0x94, 0xA6, 0x85, 0x8D, 0x22, 0x26, + 0x5B, 0xB2, 0xB6, 0x10, 0x79, 0x0D, 0xF1, 0xAB, + 0xF0, 0x17, 0x75, 0x42, 0xD4, 0x69, 0xD1, 0xC5, + 0xE6, 0xB5, 0x8C, 0xE3, 0x9F, 0x10, 0x2E, 0x18, + 0x41, 0x9D, 0xEC, 0x16, 0x9F, 0x11, 0xF3, 0x3E, + 0x14, 0xDC, 0x1B, 0x01, 0x12, 0xA5, 0x3C, 0xE8, + 0xAE, 0xCD, 0xF7, 0x00, 0x22, 0x86, 0x51, 0xBB, + 0x84, 0x0F, 0x29, 0x66, 0xB7, 0xCE, 0xDD, 0x87, + 0xDE, 0x81, 0x93, 0xDD, 0x92, 0xE3, 0xAE, 0x3F, + 0xBC, 0x43, 0x88, 0x00, 0xFF, 0x87, 0x42, 0x9B, + 0xC4, 0xD8, 0x76, 0xFE, 0x06, 0x05, 0x6A, 0xF6, + 0xDC, 0x40, 0xB7, 0x5D, 0xEF, 0xF5, 0x84, 0x61, + 0x29, 0xB5, 0x1E, 0xDB, 0x29, 0xFC, 0xE6, 0xBB, + 0xA5, 0x1E, 0x2E, 0x73, 0xF2, 0xE6, 0x66, 0x39, + 0xC6, 0x71, 0xBE, 0x9B, 0x15, 0x32, 0x9B, 0xCF, + 0xFC, 0xF3, 0x1A, 0x39, 0xD8, 0x26, 0x04, 0xC2, + 0x3D, 0x5F, 0xF4, 0xFC, 0xF4, 0x38, 0xE8, 0x04, + 0x37, 0x77, 0xCC, 0xCA, 0x14, 0xD7, 0x43, 0x0F, + 0xD2, 0x4F, 0xC2, 0x23, 0x9D, 0x43, 0x9C, 0xC7, + 0xE8, 0xC2, 0xCF, 0x20, 0x52, 0x8C, 0xF4, 0x6D, + 0xF5, 0x37, 0xF5, 0x05, 0xC8, 0xAA, 0xB2, 0x95, + 0x2E, 0x9D, 0x95, 0x95, 0xBA, 0x46, 0x65, 0x7A, + 0xE1, 0xF9, 0x34, 0x65, 0xE0, 0x56, 0xEC, 0x89, + 0x90, 0x85, 0xA8, 0x23, 0x94, 0xE6, 0xB1, 0x88, + 0xF8, 0x3F, 0xDD, 0xA6, 0x42, 0x47, 0x77, 0xA8, + 0x89, 0x9F, 0x31, 0x66, 0xAF, 0x76, 0xDA, 0x66, + 0xF9, 0x2B, 0xEC, 0x74, 0x27, 0xBC, 0xF1, 0xD5, + 0x04, 0x02, 0x77, 0xD1, 0x02, 0xD5, 0x7E, 0x0C, + 0xE8, 0x4A, 0xDE, 0xF1, 0x86, 0x77, 0xA9, 0xFF, + 0xAD, 0x99, 0x01, 0x17, 0xE0, 0x6A, 0xE2, 0x74, + 0x11, 0x1C, 0xB2, 0x35, 0xFD, 0x45, 0xBB, 0xE9, + 0xBD, 0x2B, 0xCA, 0xEA, 0xFC, 0xDC, 0x14, 0x3C, + 0x46, 0x15, 0xA4, 0x4E, 0x61, 0x0B, 0xA4, 0xE8, + 0xC0, 0x8A, 0xDC, 0x52, 0xBD, 0x8C, 0xF3, 0xF2, + 0x6F, 0x1F, 0x9C, 0x76, 0x46, 0xC9, 0xAA, 0x23, + 0xB0, 0xC4, 0x60, 0x05, 0xC7, 0x88, 0x58, 0x4D, + 0xBC, 0xF5, 0xDD, 0x72, 0xD0, 0xED, 0xBB, 0xB3, + 0x8C, 0xAB, 0xD2, 0xF5, 0xE6, 0x2A, 0xA8, 0x00, + 0x11, 0x74, 0xC4, 0x3F, 0x1A, 0x18, 0xCC, 0x12, + 0x57, 0x83, 0x02, 0xE2, 0xFE, 0x8C, 0x18, 0xAF, + 0xA0, 0x32, 0xCB, 0xF0, 0x8A, 0x65, 0xE2, 0xF3, + 0xB1, 0x79, 0x2E, 0x80, 0x68, 0x34, 0xB5, 0x41, + 0xFB, 0xA0, 0x75, 0x77, 0x72, 0xBA, 0x92, 0xBF, + 0xB9, 0x0A, 0x98, 0x17, 0xDC, 0x25, 0x77, 0x31, + 0x0A, 0xA7, 0xA8, 0x38, 0x9F, 0x1B, 0x62, 0xB0, + 0xC4, 0xCF, 0xE2, 0x1B, 0x0B, 0x0C, 0xFA, 0xBB, + 0xC4, 0x06, 0x19, 0x9D, 0xC9, 0xC8, 0x18, 0x1C, + 0x39, 0x63, 0x50, 0xDA, 0xF5, 0x8A, 0x1F, 0x68, + 0xD2, 0x61, 0xA5, 0xA1, 0x9D, 0xFD, 0xAE, 0xF5, + 0xD8, 0x14, 0xE9, 0x28, 0x55, 0xAB, 0x38, 0x98, + 0x4D, 0xE0, 0x5D, 0xA5, 0xFC, 0x9F, 0x25, 0x81, + 0x50, 0x11, 0xCE, 0x74, 0xF3, 0x6C, 0x66, 0xF5, + 0xED, 0x9C, 0x35, 0xD9, 0xDC, 0xC7, 0x11, 0x24, + 0x27, 0x37, 0xD2, 0x89, 0x51, 0xE8, 0x0E, 0x2C, + 0x35, 0xB6, 0x5B, 0x2B, 0xCE, 0xAB, 0x96, 0xB2, + 0xD4, 0x21, 0xB0, 0x21, 0x6D, 0xF3, 0x72, 0x3F, + 0x96, 0x54, 0x22, 0x74, 0x3C, 0x43, 0xE6, 0x02, + 0xAF, 0xF2, 0xB3, 0xED, 0xF8, 0x47, 0xF4, 0x26, + 0xB4, 0x31, 0x2F, 0xDC, 0x21, 0xBA, 0x9C, 0x39, + 0x86, 0x24, 0xA0, 0x1C, 0xFE, 0xDF, 0x06, 0x54, + 0x17, 0xD9, 0xCD, 0xC0, 0x7C, 0xF4, 0xE2, 0x5C, + 0x0E, 0x18, 0x80, 0xEC, 0x24, 0x7E, 0x00, 0xF1, + 0x53, 0x09, 0xD5, 0xBC, 0x9B, 0xB1, 0x4C, 0x2E, + 0xBD, 0x41, 0x0A, 0x6A, 0xF6, 0x33, 0x0C, 0x9E, + 0xC8, 0x42, 0xBD, 0x84, 0xC5, 0x46, 0x49, 0x1D, + 0x97, 0xAA, 0x42, 0xE7, 0x9E, 0x59, 0xD5, 0x99, + 0x12, 0x1B, 0x7A, 0x8E, 0x39, 0xA4, 0x50, 0xE0, + 0x87, 0x4C, 0x62, 0x4A, 0x80, 0xF5, 0xCF, 0x2B, + 0x61, 0x84, 0x74, 0x4B, 0xE5, 0x05, 0xD9, 0xB5, + 0x62, 0x5B, 0x7E, 0x7E, 0x9A, 0x05, 0x13, 0x35, + 0xB1, 0x3D, 0x85, 0xDA, 0x63, 0x2D, 0x62, 0x36, + 0x93, 0x1A, 0x37, 0x72, 0x6E, 0xFD, 0xEB, 0x2E, + 0x47, 0x37, 0xAF, 0xE7, 0x04, 0xD8, 0x3A, 0x55, + 0x8B, 0xC1, 0xF2, 0xB6, 0x8F, 0xE6, 0x16, 0x18, + 0x3E, 0x00, 0x4A, 0x9A, 0x2C, 0xBD, 0x83, 0xCF, + 0x4C, 0x27, 0xB5, 0xBD, 0xEC, 0x03, 0x1D, 0xD7, + 0x49, 0x0F, 0xED, 0x67, 0xD5, 0xC1, 0xA9, 0x14, + 0x40, 0x29, 0xA1, 0x67, 0x75, 0x7E, 0x3C, 0x97, + 0x7D, 0x22, 0x5E, 0x15, 0xE3, 0x3C, 0xD0, 0x42, + 0xF7, 0x25, 0x41, 0x88, 0x46, 0x94, 0xEA, 0x0D, + 0x2D, 0x3D, 0x50, 0xE2, 0xE6, 0xB9, 0x06, 0x8A, + 0x34, 0xB9, 0x1E, 0xE1, 0x79, 0x40, 0x31, 0xC2, + 0x32, 0x79, 0x6F, 0x3B, 0xCB, 0x9D, 0x08, 0x04, + 0x1A, 0xB5, 0x37, 0x57, 0xFA, 0x72, 0xAC, 0xCB, + 0xF2, 0x0B, 0xD1, 0xEE, 0x20, 0xD9, 0x19, 0x83, + 0x55, 0x81, 0x62, 0xDA, 0x22, 0xDB, 0x62, 0x37, + 0x6D, 0x36, 0x27, 0xFA, 0x45, 0x8D, 0x85, 0x87, + 0x16, 0x88, 0x37, 0x91, 0x67, 0x09, 0x86, 0x71, + 0x64, 0xDE, 0xC4, 0x39, 0x07, 0xD0, 0xF2, 0x8D, + 0x5B, 0x66, 0x8F, 0xC8, 0x3B, 0x7E, 0x45, 0x39, + 0x3A, 0xCC, 0x0A, 0x4E, 0xC1, 0x6D, 0x2D, 0x76, + 0x44, 0x82, 0x9F, 0x10, 0x56, 0xCA, 0x40, 0xBA, + 0xA3, 0x48, 0x86, 0xAF, 0x5E, 0x5B, 0x1F, 0xC0, + 0x0A, 0xB1, 0x52, 0xD3, 0x66, 0x0D, 0x6A, 0xD7, + 0xCB, 0x45, 0x20, 0x10, 0x09, 0xCD, 0x3B, 0xBC, + 0x18, 0xE4, 0xFB, 0x1C, 0x0D, 0x5B, 0x51, 0xCF, + 0x4C, 0x04, 0xC7, 0x17, 0x51, 0xAA, 0x8C, 0x4A, + 0x1C, 0xF6, 0x56, 0x8D, 0xF7, 0x36, 0x33, 0xEB, + 0x44, 0x7A, 0x76, 0x9C, 0x59, 0x60, 0x1B, 0x69, + 0x05, 0xA9, 0xD8, 0x25, 0x3D, 0x68, 0x48, 0x33, + 0x39, 0xD4, 0x72, 0xDF, 0x66, 0xC3, 0x3D, 0x71, + 0xE6, 0xAE, 0x32, 0x28, 0x5F, 0x15, 0x2D, 0x3E, + 0x3B, 0x00, 0xFE, 0x17, 0x18, 0x63, 0xCC, 0xC3, + 0x3F, 0xB9, 0x99, 0x6C, 0x3C, 0xD7, 0x58, 0xAD, + 0xED, 0x0B, 0x78, 0x0C, 0xC2, 0x81, 0xC4, 0x7E, + 0x2D, 0x4C, 0x46, 0x49, 0xC8, 0xF3, 0xA6, 0x52, + 0xCD, 0x4F, 0x9F, 0xF7, 0xAC, 0xF6, 0x02, 0x63, + 0xDE, 0xCF, 0x67, 0xE8, 0x69, 0x31, 0x68, 0xD5, + 0x9A, 0xD4, 0xEA, 0xF5, 0x06, 0x5F, 0xC1, 0x93, + 0x26, 0xEC, 0x01, 0x18, 0x81, 0x15, 0x1A, 0xE8, + 0x71, 0xED, 0x2D, 0x14, 0x9C, 0x8B, 0x74, 0xCA, + 0x65, 0xA5, 0x31, 0x31, 0x0E, 0xDA, 0x13, 0x2C, + 0xCB, 0xB6, 0x0A, 0x3E, 0xCD, 0xBA, 0x35, 0x59, + 0x0D, 0xBC, 0xF5, 0x75, 0x1C, 0x63, 0x95, 0xAD, + 0xC3, 0xAB, 0x81, 0x07, 0x7B, 0xEF, 0xDF, 0x7B, + 0xC9, 0x01, 0xDC, 0xE7, 0x33, 0x6E, 0xFC, 0xF7, + 0xE2, 0x6D, 0x68, 0x04, 0x1B, 0xB3, 0xCF, 0x0A, + 0x30, 0x86, 0xBE, 0x3B, 0x97, 0x75, 0x9A, 0xF9, + 0xA2, 0x2B, 0x02, 0xB0, 0x7C, 0x97, 0xB3, 0xB5, + 0xFB, 0x66, 0x53, 0x6B, 0xB4, 0xE4, 0x55, 0x10, + 0x0E, 0xF8, 0xCD, 0x91, 0x7D, 0x2E, 0x27, 0xD6, + 0xA5, 0x00, 0x44, 0xE1, 0x81, 0xE0, 0x04, 0x9F, + 0x89, 0x15, 0xF8, 0x4F, 0xA3, 0x75, 0x7B, 0x68, + 0x09, 0x2A, 0xBA, 0xAD, 0xCF, 0x1C, 0x44, 0x12, + 0xD4, 0xE3, 0xC2, 0x3E, 0xEA, 0x53, 0x52, 0xE8, + 0x37, 0x11, 0xF7, 0x90, 0xE0, 0xE7, 0x5B, 0x6A, + 0xB7, 0x56, 0xE9, 0x89, 0x9C, 0x5B, 0xE1, 0xE8, + 0x2B, 0xE3, 0x85, 0x3C, 0xA0, 0xA7, 0x11, 0x3D, + 0x95, 0x5D, 0x0C, 0x52, 0x8A, 0x60, 0x25, 0xD6, + 0x6E, 0x9D, 0x37, 0x81, 0x7C, 0x8F, 0xB5, 0x89, + 0x74, 0x13, 0xD6, 0x91, 0x0C, 0xFC, 0x5D, 0x66, + 0xF0, 0x25, 0x5B, 0x67, 0xEF, 0x7C, 0x47, 0x79, + 0x19, 0x02, 0xD4, 0x3C, 0x68, 0xC0, 0x5F, 0xB2, + 0x6A, 0x11, 0x2C, 0xA1, 0xFC, 0xAB, 0xC3, 0x54, + 0xF7, 0xB1, 0xF4, 0x74, 0x62, 0x3C, 0xB2, 0x37, + 0xB2, 0x39, 0xAC, 0xBC, 0x74, 0x2B, 0x51, 0xC2, + 0x8A, 0xD4, 0xAE, 0x60, 0x79, 0x22, 0xEC, 0x0A, + 0xCD, 0x5E, 0xA0, 0xB7, 0x6A, 0x3C, 0x3A, 0x0C, + 0x06, 0x65, 0x3A, 0x66, 0x3F, 0xED, 0x57, 0x4E, + 0xA8, 0x9C, 0x62, 0x63, 0xC6, 0x3D, 0x3F, 0x5D, + 0x0C, 0x11, 0x7D, 0xF2, 0x71, 0x6B, 0xDF, 0xB8, + 0x13, 0x4B, 0x96, 0xE7, 0x6B, 0x2E, 0x06, 0x4D, + 0xC6, 0xFF, 0x98, 0x0E, 0xE5, 0x11, 0x8A, 0x9D, + 0x7C, 0x67, 0x43, 0x18, 0x6B, 0x36, 0x4D, 0x12, + 0x29, 0xC7, 0x87, 0x74, 0xDC, 0xE1, 0x75, 0x62, + 0x27, 0x83, 0x13, 0x2E, 0x46, 0xD6, 0xD1, 0xFE, + 0xD3, 0x35, 0xF2, 0xA0, 0xBB, 0x5B, 0xA6, 0x9E, + 0x74, 0xCA, 0x61, 0x10, 0xB0, 0x6D, 0x36, 0xCC, + 0x29, 0x16, 0x1B, 0xD2, 0x3A, 0xA8, 0xF6, 0xB4, + 0xCA, 0x7C, 0x3D, 0x26, 0xD7, 0x11, 0xF3, 0xE9, + 0x53, 0xFA, 0x71, 0xB6, 0xF9, 0x89, 0x5D, 0xC0, + 0x8D, 0x2D, 0x33, 0x25, 0x2C, 0x0B, 0x50, 0x05, + 0x52, 0x96, 0xFE, 0x23, 0xCA, 0x5C, 0x74, 0xFF, + 0x7C, 0x3B, 0xAB, 0x02, 0xBA, 0x2B, 0x2B, 0x2D, + 0xF7, 0xD8, 0x81, 0x5D, 0x5A, 0x59, 0xF2, 0xCE, + 0x90, 0xBB, 0xEE, 0xFB, 0x4E, 0xE2, 0xA2, 0x72, + 0x18, 0x33, 0xAB, 0xF3, 0x2B, 0xA3, 0x90, 0x25, + 0x6B, 0x20, 0xDF, 0xE8, 0x44, 0x1B, 0x3F, 0x8D, + 0x82, 0xD5, 0x45, 0xAF, 0x97, 0x3F, 0x22, 0x06, + 0xE2, 0xAA, 0x52, 0x35, 0xDE, 0xEE, 0xBB, 0x39, + 0xDC, 0xC3, 0x14, 0x03, 0xEA, 0x19, 0x9F, 0xEF, + 0xAA, 0x81, 0xDA, 0x9B, 0x0A, 0x96, 0x73, 0xDF, + 0x98, 0xED, 0x67, 0x4C, 0x27, 0xAD, 0xC5, 0x4E, + 0x6F, 0x7E, 0xDE, 0x44, 0xEC, 0x7A, 0x24, 0x9C, + 0xF9, 0xB6, 0x9A, 0xDD, 0x19, 0x2E, 0x47, 0xDA, + 0x2D, 0x59, 0x88, 0x95, 0x26, 0x19, 0x37, 0x97, + 0x21, 0x0E, 0x67, 0x8D, 0x40, 0xC1, 0xE5, 0x5D, + 0xBB, 0x28, 0x6D, 0xDA, 0x19, 0xDF, 0xD6, 0x51, + 0x04, 0x10, 0x58, 0x97, 0x4A, 0xD4, 0x3B, 0x31, + 0x38, 0x44, 0x0D, 0x5C, 0xF8, 0xF9, 0xFF, 0xDD, + 0x0D, 0xAA, 0x45, 0x7E, 0xD3, 0x71, 0x2C, 0x93, + 0xCC, 0x41, 0xAF, 0x38, 0x24, 0x73, 0xB9, 0xE7, + 0x83, 0xCA, 0x72, 0x3E, 0x98, 0x76, 0xC1, 0x61, + 0xDA, 0xF2, 0x46, 0x3E, 0x10, 0x15, 0x9A, 0x2C, + 0x7E, 0x0D, 0x18, 0x11, 0x8B, 0x89, 0x51, 0x0E, + 0xE3, 0x85, 0x71, 0x0A, 0xAA, 0x6E, 0x45, 0x92, + 0x53, 0x55, 0xA3, 0xF3, 0xAB, 0xA9, 0xC3, 0x9E, + 0x54, 0x2F, 0x43, 0x40, 0x94, 0xD6, 0xD8, 0x02, + 0x97, 0xDC, 0x40, 0x33, 0x37, 0x0C, 0x1B, 0x86, + 0x32, 0x03, 0x7E, 0xE5, 0x64, 0x12, 0x2C, 0xEE, + 0x87, 0x99, 0xEB, 0xE8, 0x74, 0xAB, 0x80, 0x3B, + 0xB7, 0xB3, 0xA5, 0xCD, 0x93, 0xDF, 0xBD, 0xE4, + 0x4C, 0xE7, 0xAB, 0x14, 0x44, 0xE5, 0x3F, 0xAC, + 0xA8, 0xF4, 0xE0, 0x8F, 0x38, 0x9E, 0x76, 0x48, + 0x94, 0x4C, 0xA8, 0xEB, 0x9F, 0xB1, 0xCA, 0x22, + 0xCF, 0x2B, 0x32, 0x89, 0x53, 0xD5, 0x36, 0x5E, + 0xE0, 0x04, 0xBE, 0x61, 0x3C, 0x3B, 0x25, 0xBF, + 0x62, 0x83, 0xCA, 0xF1, 0x03, 0x90, 0xAF, 0x82, + 0x65, 0x51, 0x18, 0xD1, 0x88, 0x6C, 0x7F, 0xF6, + 0x17, 0xB2, 0x83, 0x13, 0xBD, 0xAC, 0x3F, 0x05, + 0xA7, 0xBB, 0x72, 0xB7, 0x50, 0x0E, 0xA3, 0xC1, + 0x01, 0xD1, 0x1E, 0xB7, 0x5D, 0x88, 0x73, 0xAC, + 0xAC, 0x90, 0xFC, 0xB6, 0x18, 0x3F, 0xC0, 0x42, + 0x9B, 0xF5, 0x20, 0x16, 0xCF, 0x05, 0xC7, 0x9D, + 0xD7, 0xAB, 0x69, 0x1B, 0x8E, 0xDA, 0x41, 0x04, + 0xAD, 0x74, 0xB7, 0x8B, 0x32, 0x11, 0xC0, 0x58, + 0x99, 0x26, 0xE0, 0x36, 0xD2, 0xFE, 0x27, 0xF4, + 0x12, 0x68, 0x11, 0xCC, 0x51, 0x28, 0x7F, 0x3F, + 0x15, 0x54, 0xE2, 0xFD, 0x53, 0x76, 0x94, 0x4F, + 0x16, 0x67, 0xB6, 0x53, 0x1B, 0x43, 0x21, 0x11, + 0x23, 0xBE, 0xCE, 0x97, 0x26, 0x3A, 0x59, 0x7D, + 0xE3, 0xE8, 0x02, 0xFD, 0xCA, 0xF6, 0x1A, 0xE7, + 0xAF, 0x29, 0x15, 0x50, 0x98, 0x3E, 0xD8, 0x18, + 0xD4, 0x43, 0x45, 0x3B, 0xF4, 0x98, 0x48, 0x22, + 0x6A, 0x87, 0x43, 0x79, 0xD4, 0xED, 0xFA, 0x12, + 0x73, 0xB9, 0x67, 0xF7, 0xB8, 0x40, 0x80, 0x8D, + 0x5F, 0xCF, 0xAF, 0xB6, 0xC6, 0xE3, 0xD5, 0x62, + 0xF6, 0x79, 0xF6, 0xBC, 0xAC, 0x98, 0xB7, 0x5C, + 0x04, 0x93, 0x12, 0x59, 0x26, 0x95, 0x6C, 0xF3, + 0xA1, 0x1B, 0xC9, 0x78, 0xF4, 0xF7, 0xBA, 0xEA, + 0xB2, 0x06, 0xA0, 0x81, 0x5D, 0xC6, 0x98, 0x0F, + 0x66, 0x14, 0x55, 0x1F, 0x96, 0x42, 0xAF, 0x7B, + 0xDA, 0x6B, 0x92, 0x81, 0x9A, 0x4D, 0xAA, 0x3A, + 0xF6, 0xBA, 0x30, 0x55, 0x31, 0x5F, 0xB9, 0x37, + 0x64, 0xBB, 0xCE, 0x19, 0x73, 0x43, 0x57, 0xA3, + 0xBD, 0xBC, 0x0B, 0x9E, 0x60, 0xB0, 0x29, 0xFE, + 0xAB, 0xE3, 0xA7, 0x8B, 0xB0, 0xCD, 0x64, 0xD1, + 0x03, 0x37, 0x06, 0xC6, 0x70, 0x55, 0x08, 0xA6, + 0x6F, 0x11, 0x9A, 0x2D, 0xFC, 0x47, 0xBA, 0xB1, + 0x26, 0x63, 0x7C, 0x00, 0xC3, 0x0F, 0x7E, 0xA0, + 0x64, 0x6A, 0xE8, 0x0F, 0x10, 0xEF, 0xCD, 0x4E, + 0x3C, 0xBA, 0x1A, 0x82, 0x8E, 0xFA, 0xFD, 0x98, + 0xDC, 0xF3, 0x19, 0x5E, 0xB0, 0xE2, 0xA7, 0x88, + 0x42, 0x59, 0x77, 0x79, 0xC4, 0x4D, 0x69, 0x84, + 0x80, 0xC8, 0x1A, 0x80, 0xF7, 0x8D, 0x10, 0x8E, + 0x9F, 0xA2, 0x79, 0xA1, 0xD0, 0x6C, 0x47, 0x91, + 0xDA, 0x4C, 0xC6, 0x26, 0x61, 0x9D, 0x41, 0xB0, + 0x96, 0x5F, 0x58, 0x11, 0x21, 0x7F, 0x4A, 0xA4, + 0xF6, 0x4D, 0xF8, 0x11, 0xAA, 0x99, 0x77, 0xF2, + 0xE0, 0xFD, 0xD4, 0xF9, 0xDA, 0xA0, 0x2B, 0xEF, + 0x47, 0x08, 0x50, 0x85, 0x28, 0x55, 0x13, 0xFB, + 0x09, 0xF2, 0xC1, 0x0A, 0x83, 0x14, 0xDE, 0xCE, + 0xEB, 0xDE, 0x5D, 0x0D, 0x66, 0xE1, 0x20, 0x03, + 0x6F, 0x52, 0x47, 0x61, 0xB8, 0x41, 0xEA, 0x0B, + 0x51, 0xC3, 0x21, 0x0F, 0x15, 0x20, 0x4F, 0x5C, + 0x47, 0xC6, 0x1A, 0x16, 0xB5, 0x14, 0x91, 0xB9, + 0x2C, 0x31, 0xFF, 0x46, 0xF9, 0xE4, 0x62, 0x31, + 0xD4, 0x43, 0x9C, 0xE0, 0x03, 0xA4, 0x44, 0xD5, + 0xC0, 0x91, 0xD9, 0x04, 0xF6, 0x35, 0x4C, 0x92, + 0xC5, 0xB1, 0x8B, 0x41, 0x56, 0xCF, 0x1B, 0xB9, + 0x7F, 0x46, 0xE2, 0x32, 0x4E, 0xF2, 0x83, 0x12, + 0x90, 0xEC, 0x43, 0x9E, 0x33, 0x6C, 0x2C, 0xFD, + 0xC0, 0x3B, 0xEF, 0xFB, 0xC7, 0xBF, 0x4C, 0x13, + 0x90, 0x00, 0xEF, 0xFA, 0xEC, 0xED, 0x8C, 0xC5, + 0xB2, 0x15, 0x35, 0x7F, 0x60, 0x09, 0x6C, 0xE0, + 0xCC, 0x70, 0x69, 0xD0, 0xA7, 0xF2, 0x5C, 0xA3, + 0xF0, 0x0C, 0x74, 0xBE, 0x5B, 0x88, 0x10, 0x58, + 0x0B, 0x04, 0xBD, 0x5E, 0x40, 0x5C, 0x8F, 0x00, + 0xCE, 0xB5, 0x34, 0x90, 0xA0, 0xF2, 0x0E, 0x2E, + 0x3E, 0x27, 0xFC, 0xDB, 0x8C, 0x42, 0x5B, 0xFC, + 0x8C, 0x41, 0xAE, 0xDD, 0x92, 0x14, 0x8D, 0x1B, + 0x58, 0x91, 0x5C, 0xA5, 0x32, 0x71, 0x61, 0xA4, + 0xA1, 0x21, 0x89, 0xDA, 0xF2, 0x1E, 0x1B, 0xDB, + 0x31, 0x69, 0x7B, 0xD3, 0xC2, 0xD8, 0x9B, 0x3F, + 0xEE, 0xC7, 0xC5, 0x46, 0xE7, 0x45, 0xE3, 0x26, + 0x04, 0x3A, 0x90, 0xAD, 0x00, 0xF7, 0x97, 0x10, + 0x7B, 0x60, 0xEF, 0xE7, 0x09, 0x7E, 0x29, 0x16, + 0xB7, 0xEF, 0x73, 0xD1, 0x63, 0x95, 0x46, 0x1A, + 0x7C, 0x92, 0xA5, 0xBA, 0xEF, 0xF5, 0x2E, 0xA6, + 0x11, 0x68, 0x5B, 0x86, 0x35, 0xC7, 0xF8, 0x72, + 0xFF, 0xEC, 0x1E, 0x02, 0x2D, 0x8B, 0x59, 0x4E, + 0x37, 0x8E, 0xE3, 0xD8, 0xBA, 0xC7, 0x52, 0x08, + 0x7A, 0x93, 0xEA, 0xCD, 0x90, 0xE8, 0x39, 0x92, + 0x8E, 0x26, 0xAB, 0x43, 0x53, 0xB5, 0xEE, 0x3F, + 0x8E, 0xCE, 0x57, 0x44, 0x4B, 0xF7, 0x23, 0xF4, + 0x4F, 0x9B, 0x08, 0x33, 0x8E, 0x1D, 0x70, 0xF9, + 0x1A, 0xCF, 0x9E, 0x18, 0x06, 0x4E, 0x45, 0xAE, + 0x5A, 0x30, 0x7D, 0x43, 0x4B, 0x15, 0x91, 0xA5, + 0x8C, 0x98, 0xD9, 0x55, 0x29, 0x3B, 0x26, 0x64, + 0x9F, 0x70, 0x35, 0xEE, 0xF9, 0x74, 0x09, 0xE8, + 0x28, 0xD7, 0x32, 0x04, 0x3F, 0xF8, 0x83, 0x01, + 0x2E, 0xC5, 0x9F, 0x2B, 0x88, 0x4B, 0x65, 0xCB, + 0x1D, 0x11, 0xFE, 0x1D, 0x10, 0x4F, 0xCC, 0x6C, + 0x90, 0x90, 0xD9, 0x14, 0xA2, 0x1C, 0xBE, 0x45, + 0x56, 0xF6, 0xEB, 0xF7, 0x11, 0xD5, 0x7C, 0x7D, + 0xBE, 0xAA, 0x2B, 0xCE, 0xC8, 0x3F, 0x05, 0x50, + 0x68, 0x16, 0xE4, 0x9E, 0xF4, 0xE7, 0x33, 0x3D, + 0x8C, 0x22, 0x6B, 0xFE, 0xEE, 0x53, 0xD9, 0xB4, + 0xFF, 0xD3, 0xC5, 0x9E, 0x7E, 0x50, 0x2F, 0x65, + 0x1F, 0x9A, 0x13, 0x97, 0x55, 0x62, 0xA4, 0x7E, + 0xC6, 0xB5, 0xC5, 0x3E, 0xD0, 0x9B, 0x45, 0xF4, + 0x16, 0xC2, 0xFF, 0x15, 0xBE, 0x8A, 0x9E, 0x73, + 0xA1, 0x5E, 0x49, 0x2F, 0x0C, 0x16, 0x2F, 0x9B, + 0xF7, 0xD0, 0x8C, 0xCF, 0xB9, 0xD9, 0xB2, 0x1E, + 0x45, 0xA6, 0xBC, 0x1C, 0xD4, 0x99, 0x8C, 0x8D, + 0x18, 0x60, 0x8F, 0x02, 0x01, 0x65, 0x62, 0x94, + 0xD2, 0x52, 0xA5, 0x81, 0x60, 0xCF, 0x95, 0xAE, + 0x9D, 0xB7, 0xF4, 0xD1, 0x14, 0x0B, 0xA0, 0x90, + 0x2B, 0x50, 0x7E, 0x8F, 0x76, 0xAD, 0xE4, 0x00, + 0x4A, 0x51, 0x73, 0xEA, 0xB9, 0x6C, 0xF6, 0xFB, + 0xA5, 0xD7, 0xD7, 0x5D, 0x2E, 0x3E, 0xE5, 0xFF, + 0xCD, 0x55, 0xBE, 0x37, 0xD3, 0xFB, 0xC2, 0xA8, + 0x4D, 0x1C, 0x59, 0x14, 0x22, 0x7D, 0x65, 0x94, + 0xDF, 0xE6, 0xD4, 0x94, 0x4E, 0x89, 0xF8, 0x5C, + 0xEA, 0x0A, 0xCD, 0xEA, 0x46, 0x13, 0xE2, 0xF4, + 0xEC, 0x8A, 0x54, 0x6C, 0xEE, 0x95, 0x94, 0xB9, + 0x47, 0xF4, 0xE7, 0xB3, 0x21, 0x04, 0x4E, 0x5D, + 0xF2, 0x33, 0x12, 0xF4, 0xC8, 0x53, 0xD4, 0x89, + 0xD9, 0x94, 0x26, 0xDE, 0x48, 0x0A, 0x45, 0x36, + 0x27, 0x95, 0x8C, 0x12, 0x83, 0xE9, 0xA3, 0x09, + 0x33, 0x8A, 0xA6, 0x5F, 0x6C, 0x4C, 0x38, 0xAA, + 0xC2, 0xA9, 0xB1, 0xE2, 0x2A, 0x4C, 0xBF, 0x75, + 0xB9, 0xED, 0xB8, 0xD1, 0x3B, 0xDF, 0x08, 0x36, + 0x7B, 0x31, 0x56, 0x72, 0x20, 0x74, 0xF7, 0xA3, + 0x1E, 0x10, 0x4B, 0x85, 0x34, 0x43, 0x3E, 0xF1, + 0x34, 0x9F, 0x52, 0x56, 0x89, 0xD4, 0x56, 0x38, + 0x83, 0x05, 0x4C, 0x7B, 0x17, 0x1A, 0x60, 0x0D, + 0x82, 0xAA, 0x54, 0x43, 0x42, 0x76, 0x7D, 0xF5, + 0xFA, 0xB7, 0xF2, 0xC0, 0x97, 0xEC, 0x6A, 0x37, + 0xFC, 0x68, 0x5E, 0x71, 0x5C, 0x93, 0xD5, 0x5B, + 0x50, 0x59, 0x31, 0x49, 0x90, 0xD5, 0x16, 0xFD, + 0x71, 0x40, 0xFE, 0xEE, 0x21, 0x69, 0x65, 0x3C, + 0x7C, 0xFF, 0x28, 0x5F, 0xFF, 0xD2, 0x3B, 0x4F, + 0xFA, 0x16, 0x2F, 0x78, 0x2F, 0x98, 0x84, 0x6C, + 0xFD, 0xBC, 0xCA, 0xC0, 0x82, 0xA7, 0xCF, 0x58, + 0x55, 0x28, 0x48, 0x8D, 0x23, 0xB4, 0xE4, 0x59, + 0x24, 0x01, 0x2F, 0xF5, 0x57, 0xA3, 0xD5, 0x64, + 0xE6, 0x78, 0x24, 0xD1, 0x3D, 0x14, 0x93, 0x6E, + 0xB0, 0x43, 0x93, 0xF4, 0x09, 0xE0, 0xA3, 0x1D, + 0xA1, 0x71, 0x9E, 0x98, 0xBE, 0x3C, 0x1C, 0x93, + 0x4B, 0xE3, 0x57, 0x2D, 0x2F, 0x74, 0xCB, 0xA3, + 0x26, 0xFF, 0x7F, 0xAC, 0x1B, 0x28, 0x14, 0x7C, + 0xCA, 0x04, 0xE9, 0xD0, 0x76, 0x20, 0x74, 0xEA, + 0x54, 0xF8, 0x56, 0x8F, 0x93, 0x38, 0x21, 0x7E, + 0xEE, 0x58, 0x21, 0x04, 0x75, 0x2E, 0xA0, 0x05, + 0x0E, 0xB8, 0x91, 0x92, 0x63, 0xD7, 0x40, 0x13, + 0xEB, 0xE7, 0xD3, 0x20, 0x77, 0xB0, 0xC6, 0x65, + 0x29, 0x84, 0x87, 0x62, 0x2C, 0xFB, 0xD3, 0x76, + 0x55, 0xC8, 0xF2, 0x27, 0x82, 0x28, 0xD3, 0xDC, + 0x75, 0x8B, 0x00, 0xB4, 0xE4, 0xC1, 0x81, 0x53, + 0x49, 0x1D, 0x7A, 0x47, 0xA9, 0x30, 0x62, 0x94, + 0x63, 0xC6, 0x25, 0x7D, 0xE4, 0x74, 0xDD, 0x68, + 0x93, 0x1C, 0xFF, 0x09, 0xB9, 0xE0, 0x0A, 0x8F, + 0xCB, 0x7A, 0x71, 0x68, 0x42, 0x94, 0x06, 0x70, + 0x69, 0x45, 0x06, 0x24, 0x95, 0xF4, 0x53, 0x4D, + 0xA5, 0xAC, 0xED, 0xAE, 0xFD, 0xC1, 0xA5, 0x6B, + 0xD6, 0xB1, 0xAA, 0x8A, 0x2B, 0x72, 0x38, 0x3E, + 0x74, 0xF0, 0xA1, 0x0C, 0x01, 0xC5, 0xDC, 0xB5, + 0xF5, 0xCB, 0x0E, 0x55, 0xCB, 0x22, 0xDE, 0xA3, + 0xE1, 0xF4, 0x12, 0xC0, 0x4B, 0xFC, 0x5B, 0x55, + 0x8B, 0xC3, 0x8D, 0xCE, 0x1E, 0x8D, 0x0C, 0x51, + 0x22, 0xD2, 0x9C, 0xBE, 0x9D, 0x88, 0xF3, 0xB4, + 0x22, 0xDD, 0x4F, 0xCB, 0x62, 0x7C, 0x17, 0x47, + 0x3E, 0x16, 0x92, 0xFF, 0x21, 0x51, 0x12, 0xB7, + 0x2D, 0xEA, 0x5D, 0x7A, 0xA4, 0xBC, 0xDC, 0x97, + 0xD2, 0x73, 0x7C, 0x97, 0xEA, 0x21, 0x57, 0xBD, + 0x19, 0xC0, 0xD9, 0x50, 0xEE, 0x75, 0x8E, 0x2D, + 0xAF, 0x6A, 0x9D, 0x8D, 0x5A, 0xCA, 0x60, 0xF6, + 0xF2, 0x8E, 0xB5, 0xC2, 0xB4, 0x9C, 0x14, 0x2F, + 0x39, 0xDB, 0x2C, 0x88, 0x33, 0x06, 0x1F, 0xAA, + 0x17, 0x22, 0x7F, 0xC6, 0xD5, 0xFD, 0x30, 0xCC, + 0xEC, 0x02, 0xD1, 0x38, 0x7E, 0x1E, 0xB9, 0x6E, + 0x20, 0x47, 0x34, 0x1C, 0x74, 0x2B, 0xFD, 0x44, + 0x30, 0x3D, 0x65, 0xA3, 0x60, 0x20, 0xDD, 0x55, + 0x02, 0x06, 0x9D, 0x30, 0x71, 0x4C, 0x89, 0x54, + 0x24, 0x6B, 0xC7, 0x6A, 0x94, 0x52, 0xDE, 0x63, + 0xF6, 0x03, 0x54, 0x42, 0xCC, 0xC8, 0x31, 0xFE, + 0xDC, 0x87, 0x74, 0x5C, 0x6C, 0x42, 0x3E, 0x3A, + 0x82, 0x8D, 0x20, 0x81, 0xA2, 0x23, 0xF1, 0x32, + 0x62, 0xB6, 0xC6, 0xE4, 0x60, 0x33, 0xB4, 0x17, + 0x5A, 0x1F, 0x14, 0x57, 0x9F, 0xD6, 0x70, 0xA4, + 0x7D, 0xD4, 0xBA, 0xC1, 0xB3, 0xE4, 0x1A, 0x88, + 0x06, 0x6E, 0x54, 0x57, 0xAA, 0x8E, 0x70, 0x0E, + 0x9E, 0xDD, 0xF1, 0x3D, 0x3B, 0xF4, 0xCD, 0x12, + 0x9A, 0x94, 0xE3, 0x62, 0x87, 0x9C, 0x9D, 0x42, + 0x19, 0xE8, 0xED, 0x2D, 0xAA, 0x85, 0x34, 0x5E, + 0xAE, 0x0F, 0x97, 0x36, 0x06, 0x8A, 0x30, 0x4A, + 0x63, 0x75, 0x75, 0xA6, 0x4B, 0x2F, 0x81, 0xEF, + 0x3B, 0x4B, 0x07, 0xB8, 0x02, 0x82, 0x76, 0xCE, + 0x4B, 0x10, 0x59, 0x85, 0x49, 0xEE, 0xED, 0x85, + 0x53, 0x81, 0xDB, 0xCA, 0x47, 0x78, 0x57, 0x59, + 0xAE, 0x46, 0x98, 0xB2, 0x85, 0x1C, 0x4F, 0x59, + 0xC1, 0xB4, 0x7E, 0xBE, 0xA9, 0xEB, 0xA3, 0x9B, + 0xE1, 0xFA, 0xB7, 0x1D, 0xB3, 0x46, 0xF8, 0x97, + 0xE5, 0x44, 0x37, 0x19, 0x1A, 0xE6, 0xE5, 0xC1, + 0x76, 0x08, 0x9C, 0x48, 0xE2, 0xF5, 0x66, 0x1A, + 0x6E, 0x73, 0x8E, 0x21, 0xF7, 0x0F, 0xB2, 0x94, + 0xAC, 0xA8, 0xCE, 0x5D, 0x11, 0x40, 0x50, 0x26, + 0xB9, 0xB6, 0x6A, 0x48, 0xBD, 0x69, 0xF6, 0xCF, + 0x99, 0xCA, 0x76, 0xBD, 0x74, 0xCA, 0xEB, 0xBE, + 0x86, 0x0C, 0x89, 0x5F, 0xAE, 0x83, 0xA6, 0xB2, + 0x30, 0x38, 0x06, 0xEC, 0xA3, 0x71, 0x4F, 0x56, + 0x2B, 0xB4, 0xD9, 0x9D, 0xDE, 0x6D, 0x3C, 0x27, + 0xFA, 0xBB, 0x07, 0xD3, 0x1D, 0x5A, 0xDD, 0xEF, + 0x35, 0xCF, 0x17, 0x0B, 0xA1, 0x5A, 0x1E, 0x69, + 0x4E, 0x38, 0x62, 0x20, 0x8E, 0xDB, 0x9A, 0x1C, + 0xB6, 0x83, 0x4D, 0xA6, 0x12, 0x36, 0x6E, 0x18, + 0x7A, 0xDF, 0xC0, 0x29, 0x89, 0x98, 0x40, 0xBD, + 0x66, 0x49, 0xE2, 0xC0, 0xC5, 0xE7, 0x55, 0x37, + 0x97, 0x8F, 0xAC, 0xB2, 0xC4, 0x19, 0x4C, 0x89, + 0xA7, 0x9B, 0x07, 0x50, 0x87, 0x5D, 0x8D, 0x39, + 0xFF, 0x7C, 0x30, 0x9D, 0x69, 0xEF, 0x72, 0x55, + 0xA9, 0x94, 0x76, 0xB7, 0xEB, 0xF1, 0xA0, 0xBD, + 0xDC, 0x98, 0x91, 0xF7, 0x09, 0x30, 0x68, 0xC5, + 0x29, 0xEC, 0xC1, 0xFE, 0x66, 0x7A, 0x6E, 0xF1, + 0x09, 0x25, 0x39, 0xA0, 0x01, 0x88, 0xCA, 0x56, + 0xCD, 0x92, 0xFB, 0x5E, 0x59, 0xF0, 0xDF, 0x25, + 0x7E, 0x89, 0x3A, 0x80, 0xE1, 0x93, 0x44, 0x52, + 0x36, 0xC0, 0xE8, 0x2C, 0xD1, 0x9E, 0xC4, 0xA1, + 0x3F, 0x37, 0x5B, 0xC7, 0x99, 0x59, 0x11, 0xAC, + 0x22, 0xCD, 0x14, 0xB5, 0x0D, 0x5E, 0xAB, 0x8E, + 0xB5, 0x76, 0x19, 0xA9, 0xE3, 0xA3, 0xAE, 0xF0, + 0x24, 0x4E, 0xF4, 0xE2, 0x3C, 0x36, 0x6F, 0x35, + 0x73, 0x59, 0x23, 0x83, 0x22, 0xBB, 0x61, 0xC0, + 0xCA, 0x82, 0x4D, 0x8E, 0xC9, 0x16, 0x5F, 0x6D, + 0x0A, 0x28, 0xF9, 0x90, 0xB7, 0x5C, 0x6A, 0x49, + 0x68, 0x9E, 0xF3, 0xA0, 0x46, 0xF7, 0x47, 0x52, + 0xB7, 0xCA, 0x5B, 0xB1, 0xAB, 0x74, 0x45, 0xD5, + 0xB2, 0x9C, 0xAF, 0x68, 0xE7, 0xF0, 0x80, 0x5C, + 0xDD, 0xA4, 0xA5, 0x7B, 0x57, 0xFA, 0xE1, 0xE7, + 0x61, 0xC1, 0x8A, 0xAE, 0x21, 0x50, 0x64, 0x00, + 0x85, 0x92, 0xE6, 0x19, 0xB7, 0x5E, 0x66, 0xB0, + 0xF8, 0x2D, 0x16, 0xCA, 0x16, 0x18, 0x25, 0x4D, + 0x02, 0x79, 0x37, 0x36, 0x3A, 0x73, 0x47, 0x37, + 0x0C, 0x2C, 0xD3, 0xE4, 0xEE, 0x00, 0x41, 0x4B, + 0xBB, 0x90, 0x06, 0x76, 0x31, 0xA2, 0x1B, 0x08, + 0x1D, 0x6B, 0x71, 0xF6, 0xD4, 0xAB, 0x9C, 0xE8, + 0x08, 0xD5, 0x1E, 0xE9, 0x1F, 0x12, 0xF4, 0x7F, + 0x3B, 0x40, 0x47, 0x5D, 0xAB, 0x6E, 0xA2, 0x26, + 0x7C, 0x59, 0xFD, 0x11, 0x0C, 0x53, 0x11, 0x2E, + 0x40, 0x4E, 0xA9, 0x31, 0x1E, 0x5D, 0xD3, 0x17, + 0x5E, 0xF6, 0xAB, 0x60, 0x6B, 0xBF, 0x3B, 0x35, + 0x05, 0xD8, 0x81, 0xF6, 0x39, 0x7A, 0x2F, 0x59, + 0xF8, 0x13, 0x2C, 0x40, 0xB0, 0x24, 0x06, 0xAD, + 0xB1, 0x0F, 0x6F, 0xB6, 0x40, 0xBB, 0xDE, 0xFA, + 0xC2, 0xDE, 0x17, 0x06, 0xB9, 0xC1, 0x3F, 0x9C, + 0x62, 0x2C, 0xD8, 0xFB, 0x9C, 0x28, 0x3E, 0x48, + 0x8B, 0x7A, 0xE4, 0x7E, 0x68, 0x79, 0x9C, 0xFB, + 0x3E, 0xD0, 0xB0, 0xCC, 0xCB, 0xF3, 0x89, 0x0E, + 0xB4, 0x0B, 0xA1, 0x69, 0x8F, 0xE9, 0xE7, 0x97, + 0xF0, 0x93, 0x18, 0xD9, 0x88, 0x28, 0xE4, 0x0B, + 0x31, 0x32, 0xEB, 0x68, 0xD2, 0x70, 0x23, 0xDB, + 0x13, 0x89, 0x2F, 0xA4, 0xBF, 0xD4, 0x12, 0x78, + 0xB2, 0x56, 0x4C, 0x74, 0x36, 0x82, 0x4E, 0xC6, + 0xD2, 0xA1, 0x85, 0x00, 0xB2, 0x5C, 0xF7, 0x64, + 0xB5, 0xFB, 0x27, 0xCC, 0x8E, 0x5F, 0xDB, 0x32, + 0x4F, 0x07, 0xAE, 0x6C, 0x6F, 0x6D, 0xF4, 0xAE, + 0x53, 0x5A, 0x0F, 0x8C, 0x06, 0x2F, 0x3B, 0x9E, + 0xB1, 0xAB, 0x98, 0x23, 0xF3, 0xCB, 0x8E, 0x75, + 0xB7, 0x54, 0x81, 0xBD, 0x78, 0x9B, 0x98, 0xE8, + 0x0B, 0xCF, 0x15, 0xDE, 0xF8, 0xEF, 0xCA, 0x87, + 0xD4, 0x49, 0xBA, 0x5C, 0x56, 0x03, 0x03, 0x44, + 0x7E, 0x00, 0xA3, 0x1E, 0x74, 0xFE, 0xEB, 0xEC, + 0x5A, 0x5C, 0x32, 0x25, 0x10, 0x68, 0x3F, 0x69, + 0xBC, 0x7A, 0x1A, 0x5F, 0x46, 0x79, 0x10, 0xF6, + 0x78, 0x7D, 0x18, 0x98, 0x23, 0xCD, 0xE0, 0x1A, + 0x5F, 0x24, 0xF0, 0xB5, 0xB6, 0x6F, 0xAD, 0x7E, + 0x55, 0xC6, 0x0F, 0x43, 0x8F, 0xF3, 0x38, 0xDE, + 0x91, 0x00, 0x60, 0x1D, 0x24, 0x92, 0x68, 0xD1, + 0x9D, 0x85, 0x08, 0xC4, 0x74, 0x69, 0xE5, 0xA9, + 0x61, 0xEB, 0xB6, 0x38, 0x65, 0x28, 0x10, 0x8C, + 0x86, 0x3F, 0xA8, 0x12, 0x72, 0xC9, 0x96, 0x53, + 0x83, 0xC7, 0x81, 0xAE, 0x99, 0xB9, 0x68, 0xDF, + 0xFA, 0x04, 0x34, 0x8B, 0x70, 0xA7, 0xE6, 0xEC, + 0xD8, 0xBA, 0x8A, 0x20, 0xA5, 0x37, 0xC0, 0x2A, + 0x8E, 0x12, 0x70, 0x95, 0xDC, 0x87, 0x2E, 0x96, + 0x7A, 0x01, 0x89, 0x9B, 0x86, 0x8B, 0x7D, 0x52, + 0x75, 0x32, 0x15, 0x31, 0xD0, 0x0E, 0xD5, 0x35, + 0x74, 0xE2, 0x90, 0x86, 0x56, 0x46, 0x12, 0x12, + 0xD8, 0xA8, 0x0E, 0x60, 0xC3, 0x67, 0xBF, 0x35, + 0x9E, 0x45, 0x7E, 0xFA, 0x7A, 0xB3, 0x75, 0xF9, + 0x17, 0x9E, 0xA1, 0xF7, 0xEB, 0x3F, 0xF4, 0x55, + 0x4E, 0x31, 0xD7, 0xB8, 0xEE, 0xB4, 0x54, 0x03, + 0x90, 0x80, 0xDD, 0xE4, 0xB9, 0x09, 0x2E, 0x7C, + 0x6A, 0xF5, 0xB4, 0x22, 0x11, 0x60, 0x19, 0x5C, + 0x28, 0x5A, 0x42, 0xDB, 0xF7, 0xA7, 0xBF, 0xCA, + 0x53, 0x5A, 0xDA, 0x81, 0x91, 0xF8, 0xB5, 0x45, + 0xF2, 0x2B, 0x47, 0xAA, 0xAE, 0x87, 0x96, 0xC8, + 0xEB, 0x14, 0x0C, 0x7B, 0x35, 0x49, 0xA9, 0x21, + 0x6E, 0x93, 0xF5, 0x27, 0x4E, 0x7B, 0xD2, 0x2F, + 0x24, 0x54, 0x6F, 0xBB, 0x0F, 0x42, 0xD8, 0x08, + 0x21, 0x6D, 0x7E, 0xB8, 0x10, 0x0C, 0xFB, 0xA8, + 0xCB, 0x3A, 0x96, 0x7C, 0x56, 0x8D, 0xE5, 0x0D, + 0xA9, 0x47, 0x5C, 0xB6, 0x26, 0x4D, 0x87, 0x99, + 0x70, 0x47, 0x35, 0xBE, 0x02, 0x34, 0xF0, 0x8D, + 0x1E, 0x86, 0x25, 0xDC, 0xC3, 0xC6, 0xE3, 0x0B, + 0x01, 0x1A, 0x4D, 0x80, 0x05, 0xC2, 0xC3, 0xA6, + 0x63, 0xAE, 0x72, 0x2D, 0x60, 0x76, 0x8E, 0x7C, + 0xE9, 0xB8, 0x72, 0xD4, 0xCC, 0x8C, 0x19, 0xD2, + 0xA7, 0x5F, 0x97, 0xEE, 0x25, 0xFC, 0x01, 0x4E, + 0x3B, 0xF3, 0x09, 0x93, 0x32, 0xBF, 0xF1, 0xEE, + 0x2F, 0x0B, 0x38, 0xC6, 0xB1, 0xA4, 0x8C, 0x5B, + 0xA0, 0x17, 0xEF, 0xAA, 0x9C, 0x14, 0xD3, 0x0C, + 0x8B, 0x1B, 0x9E, 0x5A, 0x17, 0x32, 0x5F, 0xFD, + 0xE0, 0xCE, 0xAB, 0xB4, 0xCC, 0xD3, 0x6B, 0xF2, + 0x48, 0x0A, 0x3E, 0x09, 0x00, 0xD5, 0xDC, 0x74, + 0xA4, 0x52, 0xF8, 0x4A, 0x4F, 0x6B, 0x83, 0xFB, + 0x86, 0xEA, 0x7F, 0x7E, 0xCE, 0x13, 0x0E, 0xD6, + 0x89, 0xAA, 0xBF, 0x3A, 0x61, 0xD3, 0x5F, 0xF6, + 0x4A, 0x46, 0x6F, 0xC9, 0xED, 0xC3, 0xCA, 0xAB, + 0xDA, 0x66, 0xD5, 0x21, 0x96, 0x7C, 0x29, 0xF0, + 0x8C, 0x6F, 0x24, 0x4E, 0x3B, 0x24, 0xAB, 0x1E, + 0x97, 0xD6, 0xBE, 0xBF, 0xB9, 0x48, 0xFC, 0x79, + 0xA5, 0x80, 0xBF, 0x78, 0x11, 0xF9, 0x7A, 0x14, + 0x02, 0xC2, 0xEC, 0x65, 0x6E, 0x72, 0xB9, 0xDC, + 0xC1, 0xBD, 0x6C, 0x88, 0xCB, 0x41, 0xD5, 0x80, + 0x32, 0xC0, 0x89, 0x39, 0xDA, 0x2E, 0xAC, 0xAF, + 0xFE, 0x9C, 0xB7, 0x95, 0x70, 0x2D, 0x58, 0xBD, + 0x4E, 0x89, 0x3D, 0x29, 0x30, 0xF4, 0x01, 0x48, + 0xFF, 0x79, 0x8C, 0x9A, 0x69, 0x66, 0x24, 0x8B, + 0x83, 0x16, 0xF2, 0x95, 0xD5, 0x09, 0x6F, 0x7E, + 0xEA, 0x75, 0x32, 0x4C, 0xB2, 0x0E, 0xE2, 0xA9, + 0x8C, 0x09, 0x0E, 0xFF, 0xC6, 0x2D, 0x65, 0x56, + 0x10, 0x9C, 0x65, 0x0A, 0x63, 0x33, 0xB9, 0x07, + 0x27, 0x63, 0x95, 0xC3, 0xEB, 0x8E, 0xC7, 0x97, + 0x41, 0xF4, 0x97, 0xEE, 0xE1, 0x6C, 0x07, 0x6F, + 0xB2, 0x28, 0x9C, 0x8E, 0x5E, 0x9E, 0x0B, 0x28, + 0x22, 0xCA, 0x79, 0x36, 0x7A, 0x56, 0xDA, 0x24, + 0x82, 0xDB, 0xC3, 0x41, 0xDE, 0x82, 0xA1, 0x73, + 0x50, 0x06, 0x5E, 0x83, 0xEE, 0x18, 0x15, 0x43, + 0x1B, 0xB5, 0xC2, 0xB6, 0x22, 0x24, 0x2E, 0xDF, + 0x6C, 0x99, 0xAF, 0x5D, 0xF6, 0xC3, 0x19, 0xD9, + 0x18, 0x13, 0xA1, 0x6B, 0x07, 0xCD, 0xE2, 0x58, + 0x5B, 0x01, 0xFD, 0x50, 0x32, 0x34, 0x03, 0xE4, + 0x84, 0x3F, 0x2E, 0x08, 0x21, 0x91, 0x8F, 0xFC, + 0xD6, 0x5E, 0xFB, 0x4E, 0x86, 0x69, 0x84, 0xCB, + 0x48, 0xCC, 0x54, 0x85, 0xC3, 0x13, 0x6E, 0x5D, + 0x64, 0x17, 0x05, 0xE3, 0xC8, 0xE9, 0x75, 0x51, + 0xB3, 0x21, 0xD1, 0xAC, 0x40, 0x75, 0x1B, 0x47, + 0x2C, 0x96, 0xAC, 0x00, 0x20, 0xF8, 0x9E, 0xBA, + 0x55, 0x70, 0x7B, 0x39, 0xEE, 0x9A, 0x86, 0xCD, + 0x95, 0x77, 0x84, 0xEC, 0xAF, 0xAB, 0x27, 0xC3, + 0xBF, 0xA8, 0x9E, 0x94, 0x13, 0x52, 0x95, 0xF6, + 0x40, 0xB1, 0x57, 0xD8, 0x4D, 0xB2, 0xA8, 0xBF, + 0x47, 0x06, 0x4A, 0x2F, 0x90, 0x4F, 0x07, 0xA1, + 0x71, 0xDF, 0x1E, 0x20, 0x25, 0xA4, 0x74, 0x53, + 0xA6, 0x65, 0x99, 0x5B, 0x90, 0x2C, 0xEA, 0x1A, + 0xE9, 0x70, 0xD8, 0x2B, 0x2E, 0x74, 0x0A, 0x50, + 0x97, 0xBB, 0x7E, 0xFD, 0x08, 0x00, 0x39, 0x05, + 0x02, 0x73, 0xB2, 0xEF, 0x5D, 0xDE, 0xCE, 0x02, + 0x0F, 0xE1, 0x26, 0x76, 0x2B, 0x23, 0x17, 0x90, + 0xF8, 0xC2, 0x29, 0x68, 0xD0, 0x9B, 0xC2, 0xAB, + 0x33, 0x61, 0x05, 0x03, 0x35, 0xD4, 0x6B, 0xA5, + 0x33, 0x8C, 0x35, 0xFC, 0x9E, 0x96, 0xA8, 0xAF, + 0x04, 0x3F, 0x02, 0x3E, 0xCF, 0xE0, 0x57, 0x3C, + 0xEB, 0x06, 0xEE, 0xCB, 0x65, 0x02, 0xFF, 0x84, + 0x72, 0x37, 0x74, 0xF0, 0x5B, 0xA2, 0xDA, 0x0E, + 0x32, 0x3C, 0xAE, 0xA8, 0x01, 0xA2, 0xCA, 0x32, + 0xA2, 0x0A, 0x4B, 0x2E, 0xE8, 0xCE, 0xB6, 0x7E, + 0x07, 0x3A, 0x04, 0xDA, 0xD8, 0x1D, 0x32, 0x0D, + 0xD9, 0xEC, 0xF6, 0x81, 0xCB, 0x14, 0x78, 0xB7, + 0xC0, 0xE8, 0x61, 0x78, 0x43, 0xAF, 0xCC, 0x90, + 0x1F, 0x26, 0x16, 0xC2, 0x2F, 0xC8, 0xBA, 0x09, + 0xEF, 0x18, 0x10, 0x6F, 0x00, 0x14, 0xCD, 0x22, + 0xE5, 0x01, 0xE0, 0x1B, 0xF2, 0xD7, 0x48, 0xD1, + 0x32, 0x5A, 0x1D, 0xB9, 0xFB, 0xC9, 0x6F, 0xC4, + 0xE6, 0x74, 0xC9, 0x66, 0x1B, 0x7D, 0x2A, 0x31, + 0x2D, 0x3D, 0x7F, 0xF2, 0xD1, 0xC2, 0xB4, 0x0E, + 0x8A, 0x4A, 0x6A, 0x16, 0xA5, 0xDC, 0xFE, 0x3B, + 0xB5, 0x78, 0x6F, 0x1A, 0x64, 0xB5, 0x3D, 0x2C, + 0x45, 0xD8, 0x3C, 0x84, 0xF7, 0xD4, 0xE5, 0x38, + 0xB9, 0xEA, 0xFA, 0xD7, 0x08, 0x20, 0x4A, 0xBA, + 0x3C, 0x36, 0x4F, 0x86, 0xCF, 0x12, 0xAA, 0x45, + 0x83, 0x6B, 0x28, 0xB9, 0x1D, 0x68, 0x61, 0x4C, + 0x54, 0x2F, 0x7A, 0xAB, 0x41, 0x95, 0x9E, 0x28, + 0xEB, 0x93, 0x2E, 0xA9, 0x49, 0x7F, 0x5B, 0xB4, + 0x0A, 0xCE, 0x7A, 0x07, 0x6D, 0xA9, 0x96, 0xA5, + 0x6B, 0x40, 0x3C, 0xB4, 0x5A, 0x93, 0x4C, 0xFB, + 0x1D, 0x32, 0x41, 0x05, 0x28, 0x70, 0x2C, 0x34, + 0x36, 0x7B, 0x75, 0xB9, 0xD1, 0x0B, 0x6C, 0x1D, + 0xD1, 0x8A, 0xD6, 0xA9, 0xD9, 0xE2, 0x90, 0xA6, + 0xA3, 0x49, 0xBA, 0x76, 0xA2, 0x46, 0x93, 0xA2, + 0x2D, 0xAC, 0x6F, 0x1E, 0x25, 0x98, 0xA3, 0xE4, + 0x1C, 0x90, 0xAD, 0x44, 0x1F, 0x77, 0x5E, 0x66, + 0x62, 0x12, 0x1F, 0xDC, 0x96, 0xD3, 0x9A, 0xB2, + 0x5C, 0xDA, 0xBB, 0x51, 0x60, 0x70, 0x81, 0x40, + 0xDB, 0x0D, 0xDA, 0x09, 0xCA, 0x64, 0xB4, 0x83, + 0x0A, 0x01, 0xBB, 0xE1, 0x79, 0xBB, 0x24, 0xE8, + 0xA1, 0x92, 0x5C, 0x77, 0x77, 0x99, 0xC5, 0xBE, + 0x2E, 0x51, 0x97, 0x4E, 0x52, 0x3A, 0xAF, 0xE5, + 0x43, 0x22, 0xE9, 0x7E, 0xDC, 0x5D, 0x82, 0xF5, + 0xB3, 0x63, 0xEB, 0x03, 0x6B, 0xCC, 0x3A, 0x7F, + 0x70, 0x33, 0x7B, 0x6A, 0x0C, 0x85, 0x72, 0xDF, + 0x31, 0x9E, 0x9C, 0xED, 0xB9, 0xB9, 0x82, 0xED, + 0xEB, 0xB5, 0x10, 0x3B, 0x33, 0x30, 0xD0, 0x66, + 0xF2, 0xF6, 0xB9, 0x8F, 0x44, 0xA8, 0x21, 0xE0, + 0x5D, 0x92, 0xC8, 0xC6, 0x02, 0x2E, 0x0C, 0xF6, + 0x86, 0xB5, 0x51, 0x6E, 0x39, 0xA5, 0x87, 0x4C, + 0x2C, 0x9A, 0x04, 0x20, 0x70, 0xC5, 0xB4, 0x20, + 0xB7, 0xCF, 0x72, 0x50, 0x95, 0x66, 0x11, 0xBC, + 0x10, 0xBB, 0x4F, 0xF6, 0xFD, 0xE2, 0x78, 0xFF, + 0x00, 0x17, 0x8C, 0xF0, 0xBB, 0xA1, 0xAA, 0x52, + 0x49, 0xAC, 0x83, 0x0B, 0x9B, 0xAF, 0x07, 0x17, + 0x7E, 0xD1, 0x50, 0x1E, 0xC2, 0x1E, 0xD6, 0x3E, + 0x41, 0x99, 0x84, 0xEC, 0x9A, 0x31, 0x4A, 0x84, + 0xD4, 0x71, 0xFC, 0x5E, 0x5E, 0xF9, 0xC6, 0x4D, + 0x25, 0x86, 0x0F, 0xF3, 0x85, 0xFA, 0xF1, 0x4F, + 0x76, 0xCB, 0x2E, 0x97, 0x69, 0xA7, 0x80, 0xE9, + 0x8A, 0xCA, 0x74, 0x58, 0x1A, 0x0A, 0x3B, 0x88, + 0x56, 0x18, 0x6C, 0x4C, 0x44, 0x91, 0xE6, 0xD7, + 0x49, 0x59, 0xF6, 0xF0, 0xE0, 0x7A, 0x75, 0x3F, + 0x08, 0x67, 0x6A, 0x1D, 0x63, 0x97, 0x8C, 0x62, + 0x6C, 0x97, 0x07, 0xB9, 0x1B, 0x2B, 0xF4, 0x24, + 0x7D, 0x53, 0xB0, 0x6E, 0x76, 0x0D, 0xF3, 0x36, + 0x77, 0xE1, 0xA5, 0x18, 0x0F, 0x29, 0xE8, 0x8B, + 0x5D, 0x26, 0xEA, 0x7B, 0xA4, 0x16, 0x37, 0x92, + 0x1C, 0xD7, 0x46, 0x76, 0x30, 0x30, 0x98, 0x47, + 0xFB, 0x79, 0xD7, 0xC9, 0xE3, 0x1C, 0xAE, 0x3F, + 0x0C, 0x04, 0xC6, 0x5D, 0x78, 0xA6, 0xAF, 0x34, + 0x28, 0x60, 0x53, 0x34, 0x57, 0x94, 0xA5, 0x90, + 0x6E, 0x82, 0xFC, 0xFF, 0x56, 0x64, 0xE8, 0x30, + 0xEC, 0x9F, 0x54, 0x32, 0x74, 0x4F, 0x29, 0x42, + 0xFE, 0x0A, 0x75, 0xFD, 0x99, 0xCC, 0x88, 0x4F, + 0x2F, 0xFB, 0x93, 0xAE, 0x0B, 0xA1, 0x37, 0xD5, + 0xCD, 0x58, 0xAD, 0xF4, 0xFC, 0x14, 0xC9, 0xDB, + 0xCC, 0x3B, 0x62, 0xF6, 0xF1, 0xFD, 0x52, 0xBE, + 0xE7, 0xB5, 0x04, 0x08, 0x49, 0xF0, 0xBE, 0x88, + 0x18, 0x0A, 0x68, 0xC0, 0xCC, 0x1F, 0x42, 0x65, + 0xED, 0x53, 0x0D, 0xD4, 0xE1, 0xE6, 0x5E, 0xBF, + 0x47, 0xF1, 0xCE, 0x97, 0xE3, 0x69, 0xDD, 0x77, + 0x21, 0xA5, 0x3D, 0x07, 0x9C, 0xEC, 0x3C, 0x3C, + 0x2F, 0x62, 0xBF, 0xA8, 0xB4, 0x3F, 0x89, 0x94, + 0x94, 0xBE, 0xB8, 0xE9, 0x56, 0xFF, 0x6D, 0x7A, + 0x75, 0xCD, 0xEA, 0xB4, 0xC6, 0xAE, 0xFC, 0x26, + 0x13, 0x99, 0x62, 0x3E, 0x33, 0x83, 0xEE, 0xB7, + 0xCC, 0x90, 0x7D, 0xB4, 0x17, 0x05, 0x7D, 0x80, + 0xEE, 0x6A, 0xF7, 0x0A, 0xC7, 0x7A, 0x1F, 0xE0, + 0xA2, 0xBA, 0x6A, 0x0A, 0x9D, 0xCF, 0xA7, 0x63, + 0x56, 0x3B, 0x2D, 0x56, 0x36, 0x3B, 0x61, 0xBD, + 0x9B, 0x9E, 0x80, 0x02, 0xA0, 0xD2, 0x03, 0xA9, + 0x28, 0x41, 0xC5, 0xEB, 0x5A, 0xEE, 0x1D, 0xE7, + 0x5D, 0xC8, 0xE9, 0xDB, 0xFF, 0xCA, 0x58, 0x17, + 0xD1, 0x2D, 0xFE, 0x90, 0x5F, 0x63, 0x6F, 0x7F, + 0x62, 0xD0, 0xC8, 0x8D, 0x23, 0xB0, 0x17, 0xAF, + 0x97, 0x42, 0xD0, 0x7D, 0x3D, 0x25, 0x33, 0x30, + 0xDD, 0xA2, 0xAF, 0x83, 0x80, 0x35, 0x47, 0xA5, + 0x21, 0x9D, 0x31, 0xF8, 0xE8, 0xE3, 0x55, 0x45, + 0x9F, 0xDE, 0x80, 0x9B, 0xFF, 0x87, 0x72, 0x08, + 0xEB, 0x49, 0xF6, 0x11, 0xE0, 0x7B, 0xC8, 0x02, + 0x83, 0xBE, 0x55, 0x86, 0x29, 0x4B, 0x5F, 0x42, + 0xFA, 0xDD, 0x14, 0xFC, 0xCB, 0x90, 0xC1, 0xBC, + 0xDC, 0x99, 0x0E, 0x0E, 0x7F, 0xD0, 0x5C, 0xAD, + 0xE8, 0x64, 0x0A, 0xD6, 0x6F, 0xE0, 0x06, 0xB7, + 0x42, 0xAE, 0xCD, 0x07, 0x63, 0x5F, 0x17, 0xA9, + 0x54, 0x0A, 0xCB, 0x31, 0x51, 0xE8, 0xD3, 0x43, + 0xF5, 0xFC, 0xBE, 0xFB, 0x49, 0xA9, 0xF9, 0x4B, + 0x72, 0xBF, 0xA4, 0x8D, 0xFF, 0x01, 0xA8, 0x1F, + 0xF0, 0x80, 0xED, 0xEB, 0xB0, 0x1C, 0xB3, 0x09, + 0xD4, 0xB5, 0x39, 0xD5, 0x33, 0xCC, 0x58, 0xDA, + 0xE7, 0x6C, 0xCA, 0x91, 0xAE, 0x5D, 0x54, 0xA7, + 0xB3, 0xAD, 0x9C, 0x2B, 0x4B, 0x81, 0x34, 0xFE, + 0xFA, 0x8A, 0x43, 0x0B, 0xDA, 0x26, 0xDA, 0x98, + 0x0F, 0xB0, 0x6E, 0x1E, 0x4F, 0xD6, 0xB3, 0x2F, + 0x07, 0x64, 0xEB, 0xB9, 0xE5, 0x03, 0x24, 0xAE, + 0xDD, 0xB5, 0x4B, 0x1E, 0x3F, 0xE9, 0x1F, 0xA6, + 0x96, 0xF3, 0xFA, 0x10, 0xC5, 0x03, 0xB4, 0xC8, + 0x6B, 0x33, 0x3C, 0x0E, 0xFD, 0xEB, 0xC7, 0x6B, + 0xDD, 0x9C, 0xA3, 0x15, 0x42, 0xF0, 0xE1, 0xC1, + 0x7B, 0xDF, 0x35, 0x94, 0xB1, 0xA1, 0x99, 0xDE, + 0x7D, 0xF4, 0x2A, 0xE9, 0x90, 0x8C, 0x17, 0x10, + 0xE4, 0x71, 0x4F, 0xE7, 0x99, 0x81, 0x98, 0x81, + 0xAE, 0xD8, 0x8A, 0x7E, 0xD8, 0xD0, 0xBE, 0xD5, + 0x18, 0x32, 0x1F, 0xCD, 0x24, 0x8F, 0x1B, 0x0D, + 0x75, 0xD7, 0xFD, 0x44, 0xE5, 0x4A, 0x67, 0x49, + 0xFC, 0x0A, 0xA3, 0x32, 0x40, 0x7C, 0xF9, 0x22, + 0x35, 0x47, 0xED, 0x23, 0x34, 0x9B, 0x36, 0xEC, + 0x50, 0xCE, 0x5B, 0x9D, 0x16, 0x3E, 0xD9, 0xE5, + 0x52, 0xCB, 0x02, 0x7F, 0xDC, 0x7E, 0x2B, 0xEF, + 0x01, 0x6F, 0xA6, 0x0D, 0x92, 0xD5, 0x25, 0x6F, + 0x32, 0x81, 0xF7, 0x32, 0xB7, 0x44, 0x54, 0x80, + 0xA2, 0x58, 0x2B, 0xD4, 0xDE, 0x22, 0x26, 0x3B, + 0xB8, 0xD5, 0xA2, 0x50, 0x9C, 0x17, 0x93, 0x92, + 0x51, 0xC8, 0x9B, 0x14, 0x2F, 0xC9, 0xC0, 0x6C, + 0xFD, 0xC5, 0xAB, 0x02, 0x75, 0x2D, 0x91, 0x3C, + 0x33, 0xCB, 0xA5, 0x51, 0x68, 0x2C, 0xF5, 0x2B, + 0x8A, 0xF8, 0x40, 0xB9, 0x3F, 0x2F, 0xC7, 0x94, + 0x43, 0x9A, 0xE2, 0xB3, 0xA2, 0xE2, 0xA4, 0x35, + 0x20, 0x41, 0x47, 0xD7, 0xBF, 0xAB, 0xEF, 0x1E, + 0x05, 0x8C, 0xAF, 0x4D, 0xB1, 0x2A, 0xC6, 0x68, + 0x29, 0x15, 0xDA, 0xB4, 0x75, 0xF8, 0x5C, 0xE4, + 0xFE, 0x97, 0x4C, 0x18, 0xE9, 0x50, 0x0B, 0x34, + 0x90, 0x58, 0x3E, 0x8A, 0x0C, 0xE9, 0x38, 0x5E, + 0x2C, 0x0E, 0x69, 0x58, 0x05, 0x1D, 0xFB, 0xF1, + 0x5B, 0xBF, 0x02, 0xED, 0xDA, 0x37, 0xE8, 0x1D, + 0x83, 0xCD, 0x49, 0x35, 0x27, 0xB7, 0x50, 0xCD, + 0xBF, 0x32, 0xCD, 0xE1, 0x9D, 0xE1, 0x45, 0xCF, + 0x67, 0xD3, 0xF1, 0xF4, 0x8B, 0x1B, 0xAF, 0x36, + 0x6C, 0x85, 0xB8, 0x5C, 0x66, 0xCA, 0x32, 0x26, + 0x53, 0xE7, 0xD5, 0x76, 0xF7, 0x4F, 0x5F, 0x8A, + 0xA5, 0x93, 0x69, 0xAB, 0x81, 0x80, 0xAB, 0xFE, + 0x98, 0x08, 0x7F, 0x35, 0xB9, 0x01, 0x49, 0xD3, + 0x44, 0xFA, 0xD6, 0x1D, 0xE2, 0xB4, 0x13, 0x9D, + 0xB5, 0xCE, 0x08, 0xCB, 0x99, 0xA2, 0x0A, 0xCE, + 0xBA, 0xAB, 0x97, 0xE9, 0x1C, 0xFE, 0xCD, 0xEC, + 0x3E, 0xFA, 0x17, 0x76, 0x8E, 0x6B, 0x0B, 0x50, + 0x6A, 0x65, 0x67, 0x7D, 0x5E, 0x22, 0xA1, 0xA0, + 0x44, 0x05, 0x70, 0x2A, 0xBC, 0xB9, 0x0E, 0x87, + 0x7B, 0xA0, 0x61, 0x5E, 0xBC, 0x8B, 0x2C, 0x64, + 0xCA, 0x51, 0x10, 0x08, 0xA2, 0xDF, 0xB0, 0x0A, + 0x30, 0xD9, 0x6F, 0xA5, 0x57, 0xB1, 0x13, 0x6B, + 0xD9, 0xDD, 0x57, 0x37, 0x90, 0x35, 0xED, 0x9F, + 0x46, 0xCA, 0x7D, 0x3B, 0xBC, 0x56, 0x92, 0x28, + 0xDE, 0x5B, 0xD9, 0xBA, 0x76, 0xB5, 0xA7, 0x1E, + 0x32, 0x9A, 0xCB, 0x7D, 0x52, 0x3A, 0xA7, 0xC3, + 0xB7, 0xAF, 0x5C, 0x4F, 0x76, 0xC3, 0xAD, 0xD6, + 0x57, 0x16, 0x26, 0x29, 0x34, 0xED, 0xC8, 0xAD, + 0xFF, 0xC6, 0xE8, 0xBE, 0x49, 0x58, 0xE3, 0x4D, + 0x61, 0xE8, 0x4F, 0x10, 0x46, 0x55, 0x39, 0xB2, + 0x6A, 0x6D, 0x12, 0x6B, 0xBA, 0x55, 0xB9, 0x19, + 0x72, 0xC0, 0x49, 0x2B, 0x5C, 0x95, 0xDF, 0x6A, + 0xA2, 0x7A, 0xCB, 0x6E, 0x32, 0xC1, 0x59, 0x86, + 0x15, 0xFA, 0x09, 0xA4, 0x24, 0x28, 0x21, 0x42, + 0x6F, 0x91, 0xCF, 0x5E, 0x49, 0x53, 0xBF, 0xC1, + 0xB2, 0xB3, 0xF9, 0x53, 0x39, 0x7B, 0xC0, 0x2F, + 0xDF, 0x02, 0xF2, 0xAC, 0x9C, 0x7F, 0xA6, 0x96, + 0x87, 0x5C, 0x2E, 0x61, 0xAE, 0xB2, 0x5B, 0xA6, + 0x31, 0xA0, 0xDF, 0x1B, 0x2B, 0xF6, 0xDF, 0x5C, + 0x2F, 0x2A, 0x03, 0x13, 0xA0, 0x60, 0xBA, 0xE1, + 0x83, 0xF7, 0x0E, 0x85, 0x48, 0x0B, 0xBC, 0xCB, + 0x81, 0xCA, 0x1D, 0x7A, 0x11, 0xB6, 0xF3, 0x9B, + 0xAC, 0x51, 0x80, 0xB7, 0x85, 0x58, 0xB7, 0xED, + 0x85, 0xF2, 0x5D, 0xD4, 0x70, 0xE3, 0xE4, 0x40, + 0x46, 0xCD, 0xD0, 0xF1, 0x40, 0x2E, 0xAC, 0x86, + 0xF9, 0xCB, 0x21, 0xD3, 0xFC, 0x52, 0x23, 0x0D, + 0x67, 0x06, 0x0B, 0x63, 0x1E, 0x8B, 0x36, 0x47, + 0x39, 0x16, 0xDB, 0xBA, 0xE7, 0x07, 0x18, 0xEE, + 0x6B, 0x65, 0xFF, 0x2B, 0xF3, 0xF3, 0xC9, 0x4C, + 0x31, 0xC9, 0xD2, 0x73, 0x03, 0x8E, 0x79, 0x4C, + 0xD7, 0x67, 0x23, 0x5C, 0xDC, 0xA5, 0x55, 0xB8, + 0x34, 0xCA, 0x7D, 0x2A, 0x5C, 0x4D, 0x0F, 0x42, + 0xC2, 0xAB, 0x30, 0x7D, 0xBC, 0x96, 0x61, 0x8E, + 0x93, 0xA5, 0xE5, 0x88, 0xDF, 0xC0, 0xD5, 0xC1, + 0x86, 0xD2, 0x04, 0xE0, 0x26, 0x77, 0x27, 0xD0, + 0x77, 0xC6, 0x18, 0x10, 0x58, 0x6E, 0xCF, 0x9E, + 0x41, 0xE7, 0x0D, 0xBB, 0xB8, 0xA9, 0x09, 0x58, + 0xCC, 0x01, 0x49, 0xCD, 0xE7, 0x70, 0x7E, 0x02, + 0x22, 0xD7, 0x50, 0x2F, 0x76, 0x79, 0xB4, 0xD5, + 0x94, 0x67, 0x33, 0x56, 0x90, 0x5E, 0x8F, 0x00, + 0xFF, 0xFD, 0x59, 0x32, 0x82, 0xF3, 0x08, 0xA9, + 0x24, 0x84, 0xFE, 0xBB, 0x9D, 0xE4, 0x65, 0x43, + 0x15, 0xF5, 0xEA, 0xDB, 0x18, 0xA3, 0x30, 0x3F, + 0x5E, 0x27, 0x24, 0x18, 0xDF, 0x84, 0xD8, 0xF1, + 0x7B, 0x3C, 0xB3, 0xC1, 0xF5, 0xA4, 0x42, 0x13, + 0x3F, 0x1A, 0xD2, 0x0F, 0x04, 0x2C, 0x92, 0x22, + 0x4F, 0x0C, 0x0A, 0xF0, 0x3E, 0xF4, 0x4A, 0xF0, + 0xBF, 0xB0, 0xBD, 0x72, 0xC2, 0xC6, 0xFF, 0x62, + 0x3A, 0x3D, 0x1F, 0x09, 0x38, 0x3B, 0xEE, 0x9C, + 0xE1, 0x21, 0xE5, 0xF2, 0x8C, 0x49, 0x31, 0xA2, + 0x2A, 0x7D, 0xBE, 0x7D, 0x45, 0x4A, 0x88, 0xDC, + 0x49, 0xDE, 0x95, 0x7B, 0xA8, 0x83, 0x98, 0xC7, + 0xF0, 0x8D, 0x96, 0xB5, 0x75, 0x5C, 0xFF, 0x08, + 0x04, 0xC5, 0x3C, 0x5C, 0x43, 0xC1, 0xFD, 0x9E, + 0xE5, 0xB5, 0x6E, 0x29, 0x3F, 0x3C, 0x0E, 0xE1, + 0x48, 0xD9, 0xC7, 0x80, 0x59, 0x6D, 0xFE, 0x34, + 0x4C, 0x11, 0xF9, 0xDC, 0xA0, 0x82, 0x90, 0x1E, + 0x8F, 0x01, 0x44, 0x12, 0x30, 0x1F, 0x4B, 0x10, + 0xDE, 0x0D, 0x65, 0x6A, 0xA1, 0x05, 0xC2, 0x03, + 0xD0, 0x69, 0xAB, 0xB4, 0x49, 0x10, 0x1F, 0x37, + 0x55, 0xE2, 0x83, 0x1D, 0x4B, 0x1F, 0x85, 0x64, + 0xB6, 0xA4, 0xAA, 0x4A, 0x38, 0xF3, 0xDE, 0x1F, + 0xF2, 0xA3, 0xC3, 0x14, 0xAA, 0xC4, 0xE2, 0x9F, + 0x6E, 0xCE, 0x42, 0xC2, 0xA7, 0x1A, 0xAB, 0xC0, + 0x56, 0xFB, 0xFD, 0x02, 0x5A, 0x12, 0xF9, 0xE8, + 0x81, 0xBB, 0x4E, 0x35, 0x9E, 0x5B, 0x1E, 0xD3, + 0xF9, 0x17, 0x1C, 0x07, 0x79, 0xAB, 0x18, 0xAD, + 0x80, 0xF8, 0xFA, 0x96, 0xB9, 0x6E, 0xD2, 0xB2, + 0xA2, 0x7B, 0x97, 0xCF, 0x67, 0x52, 0x4C, 0x84, + 0x8E, 0xB7, 0xAA, 0x48, 0xC1, 0x25, 0xF7, 0x73, + 0xE4, 0xE3, 0xB9, 0xE0, 0x0B, 0xC8, 0x55, 0x54, + 0xA2, 0x66, 0x8A, 0x51, 0x06, 0x42, 0xCF, 0x04, + 0xF3, 0xFC, 0x64, 0xDE, 0x4D, 0x55, 0x82, 0xC5, + 0x6D, 0x91, 0x1E, 0x81, 0x90, 0x57, 0x9F, 0x47, + 0x3B, 0x07, 0x91, 0xFD, 0xFD, 0xA3, 0x82, 0x58, + 0x4B, 0xC2, 0x04, 0xAB, 0xC2, 0x66, 0xD6, 0x39, + 0xCE, 0x69, 0xF9, 0x9D, 0x7F, 0xB5, 0x77, 0x4B, + 0xBE, 0xE1, 0x97, 0x46, 0xC7, 0xE4, 0xFE, 0xD2, + 0xD4, 0x52, 0x3E, 0x4B, 0x15, 0xED, 0x0D, 0xBA, + 0xD9, 0x41, 0xC6, 0xF6, 0x71, 0x23, 0xD2, 0x57, + 0x62, 0xF7, 0x9B, 0xFB, 0xBF, 0x36, 0x8A, 0xB1, + 0xD5, 0x26, 0xE1, 0x51, 0xF3, 0x2F, 0x14, 0xD2, + 0xED, 0xDD, 0x66, 0x46, 0xCB, 0xF0, 0x50, 0x34, + 0x4C, 0xCC, 0x12, 0x07, 0x52, 0x8E, 0x75, 0xB2, + 0x08, 0x74, 0xEB, 0x62, 0x74, 0xD8, 0x53, 0x2D, + 0x62, 0x9C, 0x29, 0x29, 0xF7, 0xC7, 0x5E, 0x45, + 0x59, 0x7C, 0xB1, 0xA5, 0x64, 0x75, 0xD0, 0xA6, + 0xA0, 0xD2, 0x36, 0xAE, 0xB8, 0x1A, 0x6B, 0xC8, + 0x44, 0x53, 0x32, 0x75, 0x9C, 0x1F, 0xEB, 0xAF, + 0x5A, 0xC2, 0x88, 0x0F, 0xBF, 0x89, 0x8E, 0xDA, + 0xFC, 0x47, 0x49, 0x5A, 0x9E, 0x5C, 0x6D, 0x7B, + 0xF7, 0xAA, 0x5C, 0x68, 0x08, 0x27, 0xDF, 0x24, + 0x38, 0x99, 0x7B, 0xF6, 0x48, 0xD0, 0x8C, 0xB8, + 0xE0, 0x4E, 0x73, 0x84, 0x9C, 0xAE, 0x26, 0xFD, + 0x05, 0x45, 0xF5, 0x7A, 0xDD, 0x7D, 0x3B, 0xBE, + 0x74, 0xDE, 0xA6, 0xC0, 0x59, 0x7F, 0xD9, 0xFD, + 0xD4, 0xCF, 0xB0, 0x6E, 0xB2, 0x42, 0x70, 0x95, + 0x55, 0x11, 0x8F, 0x6F, 0x7C, 0x8F, 0xD8, 0x23, + 0xEF, 0xB9, 0x8C, 0x46, 0x51, 0x13, 0xD7, 0xEB, + 0x34, 0xAB, 0x2B, 0x23, 0x96, 0x1D, 0x4A, 0x01, + 0xA6, 0x55, 0x6F, 0x7F, 0xD3, 0x67, 0x23, 0xBA, + 0x79, 0x7E, 0xB8, 0x7D, 0xA3, 0xBA, 0x0D, 0x5F, + 0x81, 0x51, 0x52, 0x6F, 0x39, 0xB2, 0xF7, 0x70, + 0x5B, 0x3A, 0x17, 0x31, 0xBA, 0x17, 0x0D, 0xF4, + 0x77, 0x87, 0xD8, 0x24, 0x0A, 0x0E, 0xBA, 0x8A, + 0xD0, 0xDB, 0x6E, 0xF9, 0xF6, 0x3B, 0xE4, 0x29, + 0x2A, 0x46, 0x53, 0xDA, 0x30, 0x11, 0xD6, 0x68, + 0x95, 0x4C, 0xD4, 0x38, 0x55, 0xD0, 0xD7, 0xBE, + 0xE2, 0x86, 0x08, 0x68, 0xBA, 0xE7, 0x61, 0xBD, + 0x31, 0x18, 0x24, 0xA7, 0x84, 0x0A, 0xC0, 0x11, + 0x85, 0x69, 0x04, 0x09, 0xF4, 0x2E, 0xF5, 0x65, + 0x08, 0x60, 0x91, 0x98, 0x07, 0xC3, 0xFB, 0xA5, + 0x39, 0xD6, 0xC0, 0x08, 0x59, 0xBA, 0x93, 0x40, + 0x98, 0xD0, 0x81, 0x80, 0x8D, 0x29, 0x19, 0x1C, + 0x28, 0xA1, 0x9F, 0xE5, 0x7B, 0x4D, 0x15, 0xFA, + 0x4E, 0x64, 0x04, 0x1A, 0x10, 0x32, 0x27, 0x78, + 0x21, 0xB9, 0x15, 0x36, 0x96, 0xC6, 0x65, 0xAE, + 0xFB, 0x97, 0x27, 0xA2, 0xD0, 0x1C, 0x43, 0xB7, + 0xCF, 0x0B, 0xEE, 0x49, 0x97, 0xD6, 0xAF, 0x9D, + 0x8A, 0x17, 0xB8, 0xC3, 0xD8, 0x15, 0x5A, 0x54, + 0x1E, 0x69, 0x3C, 0xA5, 0x19, 0xF6, 0x86, 0x69, + 0x57, 0x3A, 0xE9, 0x5B, 0xB1, 0x2D, 0xCA, 0xA6, + 0xE8, 0xEB, 0x30, 0x67, 0xC5, 0x20, 0x05, 0xAC, + 0x84, 0xC8, 0xEB, 0xEF, 0x62, 0x80, 0xBC, 0xBE, + 0xD2, 0xED, 0xFE, 0x48, 0x1E, 0xC0, 0xEE, 0x12, + 0xA6, 0x7A, 0x83, 0x43, 0x46, 0x4E, 0xD6, 0xCE, + 0x05, 0xE6, 0xE2, 0xA0, 0x6D, 0x65, 0xAE, 0xA4, + 0xF2, 0xEF, 0xB5, 0xEC, 0x52, 0x3C, 0x5D, 0x88, + 0x4C, 0x03, 0x87, 0xC0, 0xD6, 0xE0, 0x17, 0xC1, + 0x1F, 0xAA, 0x6B, 0xB7, 0xDD, 0x73, 0x2E, 0x5D, + 0xB4, 0x87, 0x61, 0x87, 0xD9, 0x4A, 0xEA, 0x14, + 0xE0, 0x1A, 0x96, 0x19, 0x4C, 0x59, 0xA8, 0x4D, + 0x79, 0x5B, 0xBB, 0xDC, 0xA4, 0xBA, 0xB3, 0xF5, + 0x5B, 0x1A, 0x86, 0x5E, 0xEC, 0xD6, 0xAC, 0x0A, + 0xCF, 0x01, 0xF6, 0x1C, 0xDD, 0xC7, 0xD1, 0x91, + 0x19, 0x8E, 0x3C, 0xDC, 0xAF, 0x65, 0xF5, 0x71, + 0x30, 0xF8, 0xD1, 0x59, 0x33, 0x1D, 0x4B, 0xD4, + 0x9D, 0xBD, 0xB4, 0x47, 0x19, 0x42, 0xA2, 0xDE, + 0x77, 0xDC, 0xE4, 0xF2, 0xE4, 0x8B, 0xE5, 0xC3, + 0x0D, 0x74, 0xBF, 0xA1, 0x94, 0x4F, 0x75, 0x63, + 0x49, 0x97, 0x46, 0xF1, 0xE2, 0x29, 0xF5, 0x8B, + 0x1A, 0x7A, 0xDF, 0x6D, 0x84, 0xFD, 0x14, 0x1C, + 0x77, 0x63, 0xEB, 0xE5, 0xD1, 0x9E, 0xC2, 0xCA, + 0x72, 0x8E, 0x58, 0xE1, 0xB6, 0xF7, 0xB4, 0xB1, + 0xFF, 0x3A, 0xB8, 0xB0, 0xFA, 0x71, 0xD1, 0x86, + 0x59, 0x4D, 0x91, 0xE5, 0xC7, 0x9C, 0x93, 0x24, + 0xE1, 0x37, 0xFF, 0x69, 0x85, 0x66, 0xA9, 0x74, + 0x12, 0x82, 0xE8, 0xA5, 0x27, 0x38, 0x71, 0x39, + 0xF6, 0xDA, 0x04, 0x64, 0x10, 0xFD, 0x10, 0x6B, + 0x44, 0x69, 0x4F, 0xAF, 0xE6, 0xBD, 0x9A, 0xAE, + 0x4D, 0xBD, 0xCE, 0xDB, 0x47, 0x0B, 0x0C, 0xDC, + 0x3A, 0xD5, 0x8E, 0x73, 0x33, 0x7B, 0x3E, 0xDB, + 0x37, 0x14, 0x51, 0x1E, 0xF7, 0xB8, 0x99, 0xF3, + 0x1F, 0xAB, 0x63, 0x80, 0x47, 0x94, 0xED, 0xE9, + 0x56, 0x66, 0x81, 0xF5, 0xDF, 0xCB, 0x48, 0xA0, + 0x27, 0x3C, 0x17, 0x82, 0x27, 0xBA, 0x27, 0xE1, + 0x11, 0x70, 0x46, 0x0A, 0x21, 0x5E, 0x87, 0x6C, + 0x7D, 0x89, 0x81, 0xC3, 0x25, 0x7E, 0x77, 0x23, + 0x37, 0xE6, 0xC6, 0xDC, 0xF3, 0xF3, 0x14, 0x82, + 0xD6, 0x55, 0x64, 0x17, 0x2A, 0x39, 0x87, 0xD5, + 0x1D, 0x1B, 0xEA, 0xB4, 0x52, 0xB3, 0x49, 0xBE, + 0xC5, 0xC5, 0xBC, 0x2E, 0xE8, 0xAF, 0xD4, 0xCB, + 0xC4, 0xCB, 0x47, 0xB4, 0x56, 0x0C, 0xF6, 0x7A, + 0xD0, 0x52, 0x17, 0xEE, 0x8D, 0x42, 0x0A, 0xEC, + 0xAC, 0xEE, 0x2E, 0x70, 0xCC, 0x99, 0xDB, 0xE3, + 0x1C, 0x90, 0x8D, 0x9B, 0x11, 0x9A, 0x19, 0x2C, + 0x17, 0xA3, 0x45, 0x05, 0xD0, 0xCF, 0x1F, 0x4A, + 0x03, 0x57, 0x81, 0x48, 0x20, 0xC4, 0xBB, 0xD9, + 0xE5, 0x0D, 0xCA, 0xF8, 0xFE, 0xA4, 0x6A, 0x35, + 0xD2, 0xD8, 0xED, 0x34, 0x17, 0xE2, 0x12, 0x30, + 0x15, 0xE0, 0x7E, 0xD8, 0x56, 0x63, 0x6B, 0x39, + 0x18, 0x15, 0x92, 0x07, 0x92, 0xFA, 0x08, 0xEB, + 0x96, 0xBA, 0x6F, 0x08, 0x34, 0x88, 0xF5, 0x77, + 0x92, 0xA7, 0xB6, 0x33, 0x39, 0x36, 0xDD, 0x1D, + 0xBC, 0x84, 0x31, 0x5B, 0xE1, 0x81, 0x74, 0x31, + 0x07, 0x5F, 0xAD, 0x7B, 0x3C, 0xFA, 0x6F, 0xEC, + 0xBA, 0x62, 0xBB, 0xD1, 0x3D, 0x22, 0xD2, 0xA0, + 0xD0, 0xEB, 0x8C, 0xA6, 0xE5, 0xBF, 0xF2, 0xBD, + 0xAF, 0x31, 0xC0, 0xA6, 0xE1, 0x0C, 0x6F, 0x28, + 0xAF, 0x13, 0xC1, 0x1B, 0x83, 0x9F, 0x0D, 0xA8, + 0xA1, 0xF6, 0xC8, 0x8F, 0x06, 0x4C, 0x4D, 0xA6, + 0xDC, 0x02, 0x78, 0x78, 0x66, 0x92, 0x5B, 0x63, + 0xFD, 0xF8, 0xA6, 0x4F, 0x6D, 0xFD, 0x90, 0x61, + 0x61, 0xCE, 0x6C, 0xB1, 0x59, 0x21, 0xC5, 0x84, + 0xAE, 0x52, 0x56, 0xFC, 0xEE, 0x63, 0xE0, 0x0F, + 0x81, 0xFF, 0x0C, 0x7C, 0xD3, 0x83, 0x4A, 0x96, + 0xFC, 0x97, 0xFF, 0x7C, 0x6E, 0x34, 0x4A, 0xCD, + 0x51, 0xB9, 0x3D, 0xFE, 0x51, 0x5B, 0xBC, 0xDF, + 0x07, 0x7F, 0x8E, 0xF4, 0x3F, 0x9A, 0xCD, 0xE8, + 0x5F, 0x08, 0x1D, 0x40, 0x3D, 0xFC, 0xA7, 0x00, + 0x4B, 0xCC, 0xE6, 0xDE, 0x33, 0x0E, 0x45, 0x70, + 0x8C, 0x30, 0x32, 0xA9, 0x7D, 0xBE, 0x16, 0xA3, + 0x71, 0x3E, 0xDB, 0x22, 0xA9, 0x98, 0xC9, 0x40, + 0x18, 0x41, 0xF1, 0xB6, 0x09, 0x08, 0x81, 0x73, + 0xCB, 0x20, 0xA4, 0xE7, 0xCD, 0x33, 0xA3, 0x64, + 0x07, 0xE3, 0x96, 0x14, 0xA8, 0x6C, 0x86, 0xE2, + 0x18, 0x70, 0x59, 0x28, 0xEE, 0xF3, 0x0F, 0x2A, + 0x5E, 0x67, 0x6F, 0xBD, 0x1E, 0x62, 0x4F, 0xC8, + 0x12, 0x24, 0x7D, 0x94, 0x1E, 0x90, 0xCF, 0xED, + 0x51, 0xBF, 0xFE, 0xDE, 0xC5, 0xFE, 0x72, 0x44, + 0x22, 0x2D, 0xBD, 0x9D, 0xAF, 0xCE, 0x7C, 0x36, + 0x89, 0x2A, 0x2B, 0x4B, 0xE0, 0x22, 0x86, 0x6F, + 0x7B, 0x72, 0x6F, 0x2D, 0x5B, 0x8D, 0x5B, 0xA7, + 0xC1, 0xD9, 0xF2, 0x1F, 0xE6, 0x61, 0x24, 0x11, + 0x25, 0x9C, 0xCB, 0xC7, 0xC8, 0x3F, 0xEE, 0x4B, + 0x1A, 0x6C, 0x28, 0x11, 0x42, 0x10, 0xEB, 0xF2, + 0x61, 0x33, 0xF5, 0x81, 0xF8, 0x31, 0x55, 0xE1, + 0x47, 0x33, 0x59, 0x0D, 0x55, 0x24, 0x02, 0xC3, + 0xD3, 0x8F, 0x19, 0x23, 0x9B, 0x0D, 0xA2, 0xB6, + 0xEF, 0x2D, 0x99, 0x88, 0x0D, 0xC7, 0x0D, 0x49, + 0xC2, 0x63, 0xF1, 0x1B, 0x70, 0xB6, 0x48, 0x6E, + 0x5E, 0x3E, 0x6D, 0x64, 0xD2, 0xC0, 0xC1, 0x50, + 0x7E, 0x80, 0x60, 0xAA, 0x5E, 0x4E, 0x2E, 0xBD, + 0x6D, 0xD3, 0x42, 0xA9, 0x1E, 0xD9, 0x3F, 0xC8, + 0x2E, 0x55, 0xCF, 0x93, 0x12, 0xF5, 0x60, 0x13, + 0xC1, 0xC1, 0x2F, 0xA4, 0x1C, 0x84, 0x7B, 0x43, + 0x06, 0x34, 0x7B, 0xB6, 0xCB, 0x6A, 0x49, 0x72, + 0xD9, 0x47, 0x61, 0xF3, 0x39, 0xB1, 0x05, 0x64, + 0x7A, 0x40, 0x9F, 0xA4, 0x37, 0xEE, 0xEC, 0xE1, + 0x76, 0x2E, 0xEA, 0x97, 0xBD, 0x20, 0xFD, 0xC1, + 0x0A, 0xD1, 0xE4, 0x28, 0x30, 0x15, 0xE0, 0xEE, + 0xA2, 0xA1, 0xE9, 0x39, 0x12, 0x1E, 0xF8, 0xA5, + 0xEB, 0xF3, 0x53, 0xC8, 0x92, 0xCC, 0x9D, 0x85, + 0xFC, 0x13, 0x5B, 0xFD, 0x48, 0x7C, 0xB7, 0xDB, + 0xE5, 0xD7, 0x86, 0x9F, 0x57, 0x6B, 0xBB, 0xA5, + 0x18, 0xA1, 0x58, 0xE5, 0x2F, 0xD0, 0x66, 0x13, + 0xC3, 0x35, 0xF5, 0xCE, 0xC1, 0x7A, 0x0A, 0x62, + 0xB8, 0x72, 0xF6, 0x25, 0x7B, 0x46, 0xD3, 0x3D, + 0x77, 0xD3, 0x02, 0x75, 0xDC, 0x5A, 0x71, 0x4B, + 0x88, 0x0F, 0x13, 0x7A, 0x68, 0xD4, 0x79, 0xCB, + 0x9F, 0x64, 0x24, 0x9F, 0x96, 0x6D, 0x18, 0x1C, + 0x28, 0x5F, 0x13, 0x1B, 0x3C, 0xC2, 0x18, 0x4E, + 0xDD, 0x9A, 0x20, 0x9F, 0x46, 0xD9, 0xAD, 0x2A, + 0x05, 0x3B, 0xB2, 0x80, 0x35, 0xF7, 0x4D, 0x5F, + 0x1E, 0xA3, 0x16, 0x20, 0xC9, 0x66, 0xA4, 0xE1, + 0xAD, 0x07, 0x38, 0x82, 0xE4, 0x97, 0x46, 0xDE, + 0xBF, 0x56, 0x2B, 0xB8, 0xBA, 0xED, 0xC8, 0xA7, + 0x46, 0x44, 0xDC, 0xC3, 0x41, 0x23, 0x0D, 0x42, + 0x86, 0x7D, 0x17, 0xEE, 0x61, 0xCA, 0x2C, 0x1C, + 0x78, 0x9A, 0xCD, 0x32, 0xAA, 0xAA, 0xDA, 0x11, + 0x19, 0x52, 0xDA, 0xD4, 0x7E, 0xA3, 0x06, 0x30, + 0x50, 0x54, 0x5A, 0x52, 0x56, 0x53, 0xE0, 0x80, + 0xCB, 0xA2, 0x41, 0x23, 0xBB, 0x68, 0x66, 0x72, + 0xC7, 0x83, 0x8A, 0xCA, 0x38, 0x75, 0xB8, 0x7F, + 0xAC, 0xDC, 0x85, 0xEA, 0xC0, 0x1A, 0x8F, 0xA9, + 0x1C, 0xDE, 0xE5, 0x9C, 0xD8, 0xFC, 0x55, 0xD1, + 0x34, 0x33, 0x63, 0x2D, 0x31, 0x08, 0xFD, 0x4D, + 0x12, 0x8A, 0xCB, 0x24, 0xC4, 0x33, 0x28, 0x82, + 0x85, 0x41, 0x91, 0x2C, 0x60, 0xAE, 0x7A, 0x18, + 0x33, 0x43, 0xA2, 0x6A, 0xC3, 0x52, 0xA5, 0x25, + 0x2C, 0xCF, 0x93, 0xDB, 0x21, 0x01, 0xE5, 0xAC, + 0x40, 0x6B, 0x3B, 0x7D, 0x98, 0x43, 0x29, 0x64, + 0xBC, 0x24, 0x13, 0x70, 0xFC, 0x5E, 0xD8, 0xD0, + 0xDB, 0x68, 0x02, 0x12, 0xD5, 0x29, 0xDF, 0xB8, + 0xC3, 0xAB, 0x4A, 0xEE, 0xB9, 0x35, 0x69, 0x88, + 0x77, 0x7D, 0x49, 0x54, 0x55, 0xF3, 0x22, 0x62, + 0x90, 0xB0, 0x2E, 0x67, 0xA1, 0xB7, 0x84, 0x63, + 0xAF, 0x5C, 0x85, 0x3A, 0x60, 0xDC, 0x8A, 0x5D, + 0xBE, 0x47, 0x39, 0x3F, 0xE5, 0x83, 0x32, 0x5B, + 0x10, 0x6D, 0xD1, 0xD6, 0x20, 0x14, 0x18, 0xBF, + 0x50, 0x60, 0x40, 0x76, 0x7B, 0xE2, 0xA3, 0xE7, + 0xC2, 0x15, 0x66, 0xD2, 0xAF, 0x2E, 0x40, 0x67, + 0x32, 0x56, 0x9A, 0x7B, 0x6C, 0xB9, 0xAC, 0x06, + 0x08, 0xFF, 0x6B, 0x5C, 0xC7, 0x53, 0x6E, 0x9F, + 0x29, 0xC9, 0xEF, 0x95, 0x57, 0x08, 0xE0, 0xD2, + 0x51, 0x02, 0x81, 0x06, 0x28, 0xBC, 0x9F, 0x36, + 0x8A, 0x27, 0xCF, 0x17, 0x97, 0xB6, 0x2E, 0x2E, + 0x5C, 0xFE, 0x0D, 0x01, 0xB6, 0x14, 0xE5, 0xEB, + 0xE5, 0x1C, 0x0B, 0x44, 0xB7, 0xD0, 0x6B, 0xB6, + 0xD2, 0x57, 0x6E, 0x85, 0xC3, 0xE5, 0xA1, 0x06, + 0xDD, 0xB7, 0x5D, 0x18, 0x27, 0xE8, 0x03, 0x23, + 0xEB, 0xE8, 0x20, 0xC0, 0x5A, 0xA6, 0x0D, 0x4F, + 0xDE, 0xE0, 0x14, 0x9D, 0xF1, 0xD3, 0xC6, 0xB4, + 0x57, 0xBA, 0x9C, 0x29, 0xA6, 0x74, 0x0B, 0x86, + 0x78, 0xBB, 0x20, 0x18, 0xAF, 0x06, 0x08, 0xCB, + 0x1D, 0x6A, 0x09, 0x56, 0xE3, 0x0F, 0xA3, 0x7A, + 0x5F, 0x45, 0x69, 0xEE, 0x87, 0xD7, 0xD2, 0xB0, + 0x98, 0x34, 0xBF, 0x44, 0xE1, 0xF0, 0x24, 0xE7, + 0x28, 0x1D, 0xD0, 0xD5, 0x6B, 0x19, 0xF6, 0x3B, + 0x10, 0xDA, 0x80, 0x7F, 0x44, 0x76, 0x13, 0x39, + 0x68, 0x73, 0x78, 0x44, 0xA6, 0x6D, 0x79, 0xEB, + 0x99, 0xF3, 0x19, 0x57, 0x98, 0x89, 0xD2, 0x1A, + 0x07, 0xEA, 0x5E, 0xBD, 0x9B, 0xC5, 0xA7, 0x8A, + 0x6F, 0xEF, 0xF1, 0x86, 0x74, 0x4E, 0xFE, 0xF7, + 0x49, 0x57, 0x36, 0x9A, 0xE5, 0x9E, 0xCB, 0x36, + 0x70, 0x72, 0xD4, 0xAC, 0x5D, 0xEF, 0x58, 0x93, + 0x7D, 0xBB, 0xDD, 0xC8, 0x55, 0x32, 0xB5, 0x55, + 0x57, 0x60, 0xD1, 0x27, 0x0D, 0xA8, 0x27, 0x34, + 0xA3, 0x90, 0x4F, 0x8D, 0x1A, 0x3D, 0x53, 0x43, + 0x0A, 0x9A, 0x5C, 0x5C, 0x05, 0x10, 0xDF, 0x01, + 0xCE, 0xAD, 0x23, 0xB6, 0xF6, 0x86, 0xF5, 0xC3, + 0x90, 0x3D, 0xB3, 0xA1, 0xE8, 0xEA, 0x86, 0xF6, + 0x9E, 0xD4, 0x30, 0x42, 0x9A, 0xA2, 0xC6, 0xEC, + 0x64, 0xD9, 0x34, 0x49, 0x26, 0x0C, 0xC6, 0x0E, + 0x76, 0x07, 0xCD, 0x21, 0x35, 0xCE, 0xB1, 0x91, + 0x52, 0x5E, 0x19, 0x6B, 0x4D, 0xB2, 0x2A, 0xDF, + 0xDC, 0x5C, 0x24, 0x16, 0x3A, 0xCC, 0xD1, 0xA8, + 0x04, 0xBA, 0x04, 0xB4, 0x3A, 0xE3, 0xF1, 0x0A, + 0x58, 0x5A, 0xA5, 0x6F, 0xDB, 0x14, 0xA3, 0x30, + 0xE5, 0x25, 0xB9, 0xB6, 0x05, 0x9A, 0x52, 0xAC, + 0x29, 0x58, 0xA3, 0x2C, 0x68, 0x5C, 0x33, 0x3C, + 0x4C, 0x96, 0x15, 0x0C, 0xF4, 0xC6, 0x26, 0xC0, + 0xFE, 0x3B, 0x7F, 0x1F, 0x86, 0x82, 0xBA, 0x59, + 0xC8, 0x69, 0x5D, 0x4D, 0x1F, 0xC1, 0xAF, 0x71, + 0xD8, 0xCF, 0x72, 0x9F, 0x7F, 0x34, 0x14, 0xFE, + 0x81, 0xA7, 0xA4, 0x5E, 0x54, 0xFE, 0xC7, 0xB0, + 0x72, 0xA1, 0x32, 0x1F, 0xC6, 0x90, 0x97, 0xD2, + 0xD4, 0x81, 0xBC, 0x35, 0xF7, 0x49, 0xE1, 0xBC, + 0x68, 0xB1, 0x1B, 0x76, 0x2E, 0x3D, 0x1C, 0x73, + 0x17, 0xE6, 0x19, 0xCA, 0x96, 0xB8, 0x93, 0x9B, + 0x8D, 0xEC, 0xDC, 0x29, 0xDA, 0x14, 0x63, 0x0F, + 0x59, 0x99, 0x2B, 0x01, 0xC5, 0xA4, 0xC5, 0x77, + 0xE9, 0xC0, 0x83, 0xF3, 0x7D, 0x06, 0x8B, 0x6D, + 0xEC, 0x8A, 0x9B, 0x4B, 0x15, 0x70, 0x4C, 0x8D, + 0x66, 0x92, 0x29, 0xC9, 0x8B, 0x1A, 0xA9, 0xC0, + 0x18, 0x12, 0x0A, 0x0E, 0x47, 0xD5, 0x6A, 0xF8, + 0x30, 0xD2, 0x50, 0x25, 0x50, 0xA4, 0x4C, 0x19, + 0x13, 0xA0, 0x7F, 0xD9, 0xC7, 0xF3, 0x13, 0xC8, + 0x48, 0xCC, 0x84, 0x2F, 0xB7, 0x5B, 0xDE, 0x4B, + 0x29, 0xC8, 0x92, 0x82, 0x35, 0x92, 0x7C, 0xB1, + 0x2E, 0xF6, 0x73, 0xBD, 0x67, 0x4D, 0x8A, 0x92, + 0xF4, 0x74, 0xF2, 0xAB, 0x5B, 0x18, 0x7B, 0xAF, + 0xBA, 0x25, 0xDA, 0xF4, 0xBC, 0x99, 0x8D, 0x9F, + 0x3B, 0x5C, 0xC1, 0xF9, 0x38, 0x8F, 0xFD, 0x0A, + 0x98, 0xE8, 0x22, 0xC6, 0x5A, 0x8B, 0x97, 0x6F, + 0xEA, 0x37, 0xBE, 0x6A, 0xBC, 0x25, 0x54, 0x4C, + 0x16, 0x05, 0x98, 0x6F, 0x6E, 0x02, 0xFB, 0x44, + 0xD5, 0x3B, 0xC0, 0xE3, 0x49, 0x1F, 0x3D, 0xF0, + 0x50, 0xC6, 0xBC, 0xA3, 0xFE, 0x3C, 0xA7, 0x04, + 0x12, 0x37, 0x74, 0x45, 0xCD, 0x44, 0xC7, 0xA1, + 0xAA, 0xDF, 0xCB, 0xF3, 0xBF, 0x6E, 0x32, 0xB0, + 0xBD, 0x77, 0xB1, 0xED, 0xAB, 0x81, 0x54, 0x8B, + 0xFB, 0x97, 0x6C, 0x53, 0x3C, 0xCC, 0x4B, 0x8C, + 0x1A, 0x68, 0xE8, 0x12, 0x8B, 0xD4, 0x82, 0x11, + 0xD5, 0xB2, 0x10, 0xA3, 0x06, 0x95, 0xD5, 0xB9, + 0xC5, 0x3C, 0xA5, 0xE7, 0x47, 0xC8, 0x7C, 0xC3, + 0x91, 0x64, 0xB7, 0xE3, 0x37, 0x87, 0x63, 0xEF, + 0x8B, 0x14, 0x45, 0xD3, 0x76, 0xB6, 0x87, 0x56, + 0x98, 0x5D, 0xF0, 0x7C, 0xB1, 0xFB, 0x7E, 0xFD, + 0x4C, 0x7A, 0x03, 0xB9, 0x0B, 0x91, 0x3F, 0xEF, + 0x27, 0x78, 0x44, 0xA2, 0x89, 0xCF, 0x21, 0xDD, + 0x5C, 0x67, 0xBD, 0x27, 0x3C, 0x77, 0xAE, 0x45, + 0xC2, 0x00, 0x3D, 0xB3, 0xE8, 0xE1, 0x29, 0x16, + 0xC7, 0x75, 0x4F, 0x90, 0x87, 0xCB, 0x94, 0x40, + 0x8C, 0x61, 0x1A, 0xDB, 0x20, 0x3B, 0xAF, 0x30, + 0x9F, 0x7A, 0x9D, 0x4E, 0xE0, 0x34, 0xCF, 0x4D, + 0x47, 0xEF, 0x0F, 0xE0, 0x82, 0xB4, 0xA8, 0xCE, + 0xC5, 0x0B, 0xE5, 0xAC, 0xD0, 0x91, 0xC5, 0x07, + 0xFB, 0x7D, 0x8A, 0x11, 0x62, 0x63, 0x89, 0xC9, + 0x32, 0xA7, 0x8C, 0x02, 0xA7, 0x7C, 0x20, 0x94, + 0xF2, 0x4C, 0x63, 0x1A, 0xB8, 0xBC, 0x71, 0x75, + 0x51, 0xE9, 0x96, 0x57, 0xD7, 0xFD, 0xE9, 0x42, + 0xBC, 0x9E, 0xA9, 0x96, 0xA7, 0x3B, 0x64, 0x74, + 0x51, 0x1A, 0xB7, 0x2D, 0x43, 0x85, 0x43, 0xF1, + 0xF0, 0xEF, 0x8D, 0x0F, 0xBC, 0xB1, 0x2A, 0xB6, + 0xA2, 0x54, 0x92, 0x8A, 0xDE, 0x7C, 0xE6, 0xD6, + 0x5D, 0x77, 0xFF, 0x2C, 0x35, 0xA2, 0xA5, 0x9E, + 0xB4, 0xB0, 0xBB, 0x12, 0x4C, 0x0A, 0xFC, 0x92, + 0x23, 0xF3, 0xEE, 0x73, 0xD7, 0x68, 0x96, 0x74, + 0xE9, 0x07, 0x31, 0xA6, 0x11, 0xE5, 0x14, 0x68, + 0xA8, 0x5B, 0x7A, 0x2F, 0x5F, 0x5E, 0xC6, 0x6A, + 0xC6, 0x80, 0xF9, 0x05, 0xDC, 0x43, 0xF5, 0xB0, + 0x39, 0x19, 0x93, 0x5A, 0x14, 0x38, 0x77, 0x3E, + 0x92, 0x4A, 0x59, 0x53, 0x2C, 0xBE, 0x3B, 0xF4, + 0xA5, 0xE9, 0x6F, 0xF8, 0x6C, 0x78, 0x00, 0xAC, + 0x99, 0x4F, 0x1A, 0xCB, 0x26, 0xEA, 0xAC, 0x09, + 0x37, 0xEB, 0xC5, 0x4B, 0x04, 0xD6, 0x75, 0x61, + 0x4B, 0xC2, 0xAF, 0x69, 0x20, 0xEB, 0x6D, 0x0C, + 0x73, 0xA0, 0x98, 0x7C, 0x10, 0xE6, 0x22, 0xA4, + 0xAD, 0xEF, 0x91, 0x29, 0xA7, 0xE0, 0xEA, 0x61, + 0x7D, 0x7D, 0x05, 0x46, 0x60, 0x2F, 0xB3, 0xEB, + 0xA5, 0x5B, 0xFF, 0xF6, 0xEB, 0xDF, 0x1A, 0xD1, + 0xB5, 0x5D, 0x99, 0x4A, 0x86, 0xE9, 0xBB, 0xD8, + 0x7F, 0x23, 0xCF, 0xD1, 0xC5, 0x4D, 0x85, 0x34, + 0xF9, 0x7E, 0x9F, 0xE4, 0xA3, 0xC1, 0x62, 0xFF, + 0xC4, 0x30, 0x39, 0xF0, 0x53, 0xE6, 0x63, 0xEF, + 0xEF, 0xC5, 0x9C, 0x09, 0x7F, 0x14, 0x2A, 0x03, + 0x93, 0x6A, 0xDD, 0xCB, 0x94, 0xB6, 0xAC, 0x84, + 0x0D, 0xCD, 0xA2, 0x21, 0xAE, 0x46, 0xAF, 0xD8, + 0x5D, 0x4B, 0xA5, 0xFB, 0xD4, 0x47, 0x89, 0x32, + 0xF2, 0xC1, 0xDB, 0x95, 0x09, 0xEF, 0x95, 0xD5, + 0xFF, 0x8F, 0xD9, 0x89, 0x35, 0xC9, 0x86, 0x0F, + 0x62, 0x18, 0xC5, 0x80, 0xBD, 0x27, 0x71, 0xA4, + 0x40, 0x79, 0x52, 0x01, 0x37, 0x93, 0x77, 0x02, + 0x7E, 0xC4, 0xDD, 0xCD, 0x2D, 0xC4, 0x89, 0xC3, + 0x09, 0x4F, 0xBC, 0x6F, 0x4C, 0x4A, 0xB3, 0xE6, + 0xFD, 0x6A, 0x45, 0x1A, 0x7A, 0x37, 0x6D, 0x3C, + 0xB8, 0x0F, 0x1B, 0x43, 0x70, 0x5A, 0x81, 0xD0, + 0xC7, 0x63, 0xC7, 0x9E, 0x63, 0xEF, 0x8C, 0x52, + 0x60, 0x7A, 0x2E, 0x94, 0xCF, 0x26, 0x49, 0xE5, + 0x12, 0xB1, 0xB1, 0x27, 0xD0, 0x38, 0xB1, 0x40, + 0x60, 0xF8, 0x7B, 0x37, 0x80, 0x95, 0xB5, 0x13, + 0xCA, 0x83, 0x7E, 0x27, 0xA8, 0x5E, 0x30, 0x27, + 0x20, 0x57, 0x1D, 0x45, 0x5F, 0xA8, 0xA6, 0xDC, + 0xF3, 0x53, 0xAA, 0x7B, 0x59, 0xC2, 0xAE, 0x60, + 0x09, 0x5A, 0xE3, 0x59, 0x5E, 0xC8, 0x28, 0xBC, + 0x4B, 0x49, 0xE0, 0xDA, 0xAC, 0x74, 0xF0, 0x8B, + 0x20, 0xFF, 0x4F, 0x0E, 0x7E, 0x6A, 0x4E, 0xF3, + 0x00, 0x22, 0x0C, 0xD0, 0x16, 0x23, 0x03, 0x17, + 0x83, 0x66, 0xC1, 0x5E, 0xFC, 0x5E, 0xEA, 0xE6, + 0x9D, 0xCD, 0xF1, 0x6C, 0x8C, 0xC5, 0xD5, 0x08, + 0xA2, 0xA1, 0x9F, 0xE1, 0x1B, 0x9D, 0xEA, 0x2E, + 0x0A, 0x57, 0x2E, 0xCC, 0x9A, 0x66, 0x18, 0x31, + 0x66, 0xF4, 0x77, 0x14, 0x93, 0x6E, 0xB0, 0x5B, + 0x08, 0x30, 0x4A, 0x7D, 0xAA, 0x7B, 0x9B, 0xF1, + 0xC7, 0x80, 0x11, 0xAD, 0x0B, 0x25, 0x95, 0xF3, + 0x20, 0x5A, 0x69, 0x34, 0xFC, 0x08, 0x62, 0x3B, + 0x8F, 0x82, 0xC6, 0xC6, 0x47, 0x39, 0x94, 0x06, + 0xAB, 0x13, 0x11, 0x3A, 0x0C, 0xCC, 0x15, 0x08, + 0x90, 0xCF, 0x4A, 0xDD, 0x22, 0x9C, 0x5A, 0x8D, + 0x5C, 0x46, 0x07, 0x3A, 0xAE, 0x85, 0x90, 0xE2, + 0xA0, 0xA0, 0xB8, 0x0B, 0x62, 0x59, 0xCF, 0x08, + 0xD4, 0x72, 0xD4, 0xB8, 0xA2, 0xFD, 0x86, 0x64, + 0xAE, 0xB6, 0xC1, 0xC2, 0xB6, 0xB2, 0xF1, 0x03, + 0xEE, 0x57, 0x13, 0xAB, 0x60, 0x87, 0xDD, 0xD4, + 0x93, 0x9F, 0x09, 0x0A, 0xA6, 0xE5, 0x44, 0xAB, + 0x7D, 0x6B, 0xE5, 0x7F, 0xC7, 0x81, 0x33, 0x0F, + 0x74, 0xE4, 0x33, 0x8E, 0x9C, 0x99, 0x8C, 0x93, + 0xB6, 0x62, 0x18, 0xAE, 0xDD, 0x5B, 0x6E, 0x17, + 0xD3, 0xDA, 0xF8, 0x3B, 0x37, 0x68, 0xB2, 0xC6, + 0x83, 0x0A, 0xB6, 0xAE, 0x9C, 0xE6, 0x1E, 0x7B, + 0xAC, 0xB2, 0x39, 0x28, 0x33, 0x95, 0xB2, 0xB1, + 0x80, 0x48, 0xA6, 0x3D, 0x96, 0x5F, 0x9E, 0x01, + 0xDA, 0x1A, 0xEC, 0xA6, 0x85, 0x07, 0x35, 0xA7, + 0xF5, 0x84, 0x91, 0xDB, 0x23, 0xD7, 0x1F, 0x81, + 0xA1, 0xC6, 0xF4, 0x6B, 0x98, 0xA7, 0x1A, 0x81, + 0x98, 0xED, 0xB4, 0x15, 0x7C, 0x10, 0xD2, 0x33, + 0xE1, 0x24, 0x7C, 0xEF, 0x99, 0xE1, 0x1F, 0x81, + 0x3E, 0x31, 0xC6, 0x1E, 0x84, 0x61, 0x6B, 0x79, + 0x40, 0x9E, 0x2C, 0xFF, 0x70, 0x25, 0xA8, 0xCA, + 0x1C, 0x6B, 0xAE, 0x46, 0xC7, 0x5C, 0x32, 0x62, + 0x6F, 0xE4, 0x88, 0x73, 0xAD, 0x1D, 0xB2, 0x23, + 0xE9, 0xFB, 0x89, 0x82, 0xC2, 0x78, 0xC1, 0xAF, + 0xFB, 0x9F, 0x94, 0x05, 0xF3, 0x9C, 0x66, 0xE5, + 0x2E, 0x50, 0xAF, 0xE8, 0x6B, 0xB1, 0x6E, 0x5A, + 0x8D, 0xD7, 0xC0, 0x5B, 0xE2, 0xF9, 0xAE, 0xED, + 0x16, 0x41, 0x21, 0x10, 0x12, 0x9B, 0x96, 0x20, + 0xF1, 0x18, 0x8F, 0x3E, 0xA9, 0x08, 0x7D, 0x7E, + 0xB0, 0x90, 0xC8, 0xD9, 0xF3, 0x4A, 0x34, 0x16, + 0x6C, 0x0A, 0xF3, 0x27, 0x85, 0x7F, 0x79, 0xFE, + 0x67, 0xA7, 0x01, 0x2D, 0x1F, 0x65, 0x6C, 0xE1, + 0x6E, 0x37, 0x33, 0x32, 0x1B, 0x80, 0x7A, 0x3F, + 0x5B, 0x5D, 0xA6, 0x8A, 0xE5, 0x1F, 0x31, 0xE9, + 0xB1, 0x01, 0x97, 0x90, 0x74, 0x65, 0x9E, 0x94, + 0xBB, 0xCC, 0x96, 0x39, 0x57, 0x6D, 0xD6, 0x80, + 0xD7, 0xA6, 0x93, 0x4C, 0x71, 0xEC, 0x08, 0x38, + 0xE4, 0x58, 0x77, 0x23, 0x6A, 0x64, 0xC9, 0x47, + 0x3A, 0xFB, 0x6D, 0x94, 0x93, 0x2F, 0xDA, 0xF1, + 0xAE, 0x04, 0x2D, 0x77, 0x88, 0x8F, 0x55, 0xC9, + 0x07, 0x83, 0xC8, 0x5F, 0xD9, 0x8E, 0x41, 0xA6, + 0x81, 0x14, 0x67, 0xE0, 0x2F, 0xB1, 0x51, 0xE4, + 0x09, 0xF9, 0x5E, 0x58, 0xAD, 0x80, 0xB1, 0xF3, + 0x99, 0x54, 0x39, 0x87, 0xCF, 0x6E, 0xC3, 0xB3, + 0xA7, 0xCF, 0xF2, 0xA9, 0xA5, 0x90, 0x9A, 0xED, + 0x04, 0xB8, 0x6B, 0xFA, 0xD3, 0x9C, 0x3F, 0x78, + 0x7D, 0x58, 0x16, 0x7A, 0x3C, 0x33, 0xF1, 0x31, + 0x9C, 0xAC, 0x2A, 0x99, 0x4C, 0x23, 0x68, 0x44, + 0xB7, 0x98, 0x79, 0x51, 0xD1, 0x93, 0x0D, 0x49, + 0x62, 0x54, 0x3B, 0x27, 0xE6, 0x39, 0x75, 0x33, + 0xBA, 0x32, 0xC2, 0x00, 0x55, 0x29, 0x36, 0x09, + 0x30, 0x1C, 0x01, 0x27, 0xEE, 0x54, 0x24, 0x09, + 0x44, 0xFA, 0xE0, 0x05, 0x79, 0x65, 0x41, 0xE3, + 0x23, 0x88, 0x61, 0x7F, 0x9F, 0x6A, 0xBD, 0x81, + 0xDF, 0x14, 0x28, 0xC6, 0x5E, 0x97, 0x21, 0x39, + 0x26, 0xCB, 0x91, 0x01, 0xC6, 0x0E, 0x59, 0x83, + 0x38, 0xC3, 0x73, 0xD3, 0xB9, 0x2A, 0x9A, 0x70, + 0xF1, 0x8D, 0x19, 0xDE, 0x1A, 0xEE, 0x76, 0xC3, + 0x94, 0x27, 0x44, 0x12, 0xB7, 0x1E, 0x41, 0xEA, + 0x2A, 0xCD, 0x4A, 0xEB, 0xF7, 0xFE, 0x47, 0xAB, + 0x8B, 0x13, 0xB3, 0x2F, 0xDA, 0xBE, 0x78, 0x1D, + 0xDF, 0x53, 0xF6, 0x03, 0xE3, 0x8E, 0xE6, 0xAE, + 0x40, 0xB6, 0xFE, 0x72, 0x49, 0xF0, 0xF0, 0x15, + 0xE9, 0x8E, 0xDF, 0x7D, 0xFB, 0x68, 0xEB, 0x0F, + 0xE5, 0xC2, 0xC7, 0xF6, 0x2F, 0x6E, 0xDE, 0xA6, + 0x49, 0xE0, 0x02, 0xA9, 0x13, 0x71, 0x4F, 0xEF, + 0x1F, 0x41, 0x29, 0x67, 0xC0, 0xA1, 0x92, 0xFC, + 0x6B, 0x2E, 0x84, 0x42, 0xA2, 0x14, 0x96, 0x5C, + 0x44, 0xEF, 0xD4, 0x12, 0xE9, 0xED, 0x0B, 0xC2, + 0x94, 0xE2, 0x80, 0x18, 0x08, 0xFB, 0xB9, 0x00, + 0x14, 0x95, 0x0F, 0x47, 0xDC, 0xE3, 0xB4, 0x4A, + 0xFE, 0x58, 0x7A, 0x75, 0x42, 0xD0, 0xB5, 0x5C, + 0xD3, 0xD7, 0xC1, 0x52, 0xC9, 0xBD, 0xDA, 0x53, + 0x73, 0x8C, 0x08, 0x84, 0xCD, 0x37, 0x78, 0x4F, + 0x8B, 0x04, 0xD1, 0x3A, 0x72, 0xAB, 0x3E, 0xBE, + 0x8D, 0x61, 0x8F, 0x0E, 0xD2, 0xE6, 0x63, 0x69, + 0x94, 0xB1, 0xA9, 0xEC, 0x0B, 0xE3, 0x73, 0xC8, + 0xFB, 0xC2, 0x8C, 0x7B, 0x59, 0xEB, 0x92, 0x5B, + 0x56, 0x35, 0x94, 0xD2, 0x29, 0xBD, 0xFA, 0xF7, + 0xB2, 0xD2, 0x20, 0x8D, 0xE4, 0xE6, 0x32, 0x06, + 0x0D, 0x7F, 0xA8, 0x29, 0x12, 0x78, 0x04, 0xEE, + 0xF7, 0x51, 0x99, 0xC5, 0x1B, 0x21, 0x48, 0x47, + 0xE0, 0xAA, 0x42, 0x23, 0xA5, 0xB1, 0x83, 0xE7, + 0x80, 0xEE, 0x52, 0x93, 0xE9, 0xAD, 0xDB, 0x3A, + 0x6E, 0xDA, 0x59, 0xF3, 0x54, 0x5D, 0x44, 0x0B, + 0xD5, 0xB6, 0x9E, 0xB2, 0xCD, 0xA6, 0x83, 0x8D, + 0xA5, 0x59, 0xE8, 0x59, 0xCC, 0xBA, 0xB8, 0x99, + 0x7B, 0xDF, 0x3B, 0x01, 0x91, 0x45, 0xA8, 0xEF, + 0x21, 0x8D, 0x2A, 0xCD, 0xD3, 0x56, 0x17, 0xF4, + 0x60, 0xF5, 0x79, 0xB5, 0x3D, 0x52, 0xC9, 0xED, + 0xE8, 0xCD, 0xBF, 0xF3, 0x2F, 0xA8, 0x70, 0x5C, + 0x04, 0xBB, 0x3D, 0xB5, 0x3A, 0x9F, 0x1F, 0xDB, + 0xA7, 0xDB, 0xCD, 0xD3, 0x47, 0xD3, 0x51, 0xFC, + 0xC3, 0x19, 0xF7, 0x5E, 0xFB, 0x85, 0xE3, 0x2F, + 0x16, 0x7E, 0x01, 0x59, 0x6A, 0x5A, 0x02, 0x33, + 0x58, 0xA3, 0x9A, 0xDF, 0x92, 0xAF, 0xCC, 0xF1, + 0x60, 0xB1, 0xDC, 0x92, 0x5F, 0x73, 0xEB, 0xAE, + 0xFF, 0xA6, 0x67, 0x06, 0xF6, 0xAC, 0x19, 0xB0, + 0x73, 0x90, 0xB1, 0x7D, 0xC0, 0xB8, 0x8C, 0x38, + 0xED, 0xED, 0xAC, 0xDE, 0x5D, 0x10, 0x6F, 0xA2, + 0xB1, 0x8C, 0x3C, 0x7D, 0xFC, 0x81, 0x3D, 0xE3, + 0x7B, 0x92, 0xCF, 0x12, 0x77, 0xE4, 0xE1, 0xAB, + 0x15, 0x6A, 0xBB, 0xE9, 0x64, 0xA6, 0xB7, 0x79, + 0x0F, 0x84, 0x22, 0xF1, 0x59, 0xA3, 0x84, 0xAC, + 0x4A, 0x16, 0x0C, 0xF0, 0x57, 0x1E, 0x9F, 0x28, + 0x8D, 0x48, 0x72, 0x89, 0x68, 0xFF, 0xCE, 0x23, + 0xF5, 0x78, 0x76, 0xF0, 0x3B, 0x23, 0x9F, 0x70, + 0x1E, 0x22, 0x03, 0x03, 0x6E, 0x7A, 0x80, 0xB6, + 0xF0, 0xB1, 0xC3, 0x41, 0xF5, 0x40, 0x42, 0x1D, + 0x1A, 0x55, 0xCD, 0xDA, 0xB5, 0xF8, 0x8D, 0xC7, + 0x31, 0x71, 0xAE, 0x16, 0x9B, 0xBA, 0x3E, 0x4B, + 0xD9, 0xBB, 0x93, 0x69, 0xD7, 0x53, 0x9B, 0x90, + 0xBC, 0xB5, 0x8D, 0x95, 0x0A, 0x5A, 0xBC, 0xA2, + 0x7F, 0xD8, 0x93, 0x8D, 0xBB, 0xB4, 0xF7, 0xBD, + 0xD1, 0xB5, 0xA0, 0x2F, 0x10, 0x71, 0xB9, 0xBE, + 0x74, 0x2C, 0x41, 0x79, 0x8B, 0x1C, 0xC4, 0x1F, + 0x38, 0x8C, 0xCD, 0xBC, 0x9F, 0xCB, 0x3B, 0x75, + 0xF0, 0x65, 0x6F, 0x65, 0x8F, 0x00, 0x51, 0x50, + 0x22, 0x54, 0x79, 0xCC, 0x2E, 0x34, 0xA0, 0x56, + 0xE9, 0x0E, 0xE4, 0x12, 0x54, 0x18, 0x85, 0x7E, + 0xD6, 0x35, 0xFC, 0xF3, 0x63, 0x79, 0x26, 0x0E, + 0x1F, 0x03, 0x57, 0x6B, 0xAE, 0x2E, 0x15, 0x53, + 0x52, 0xB1, 0x3A, 0x94, 0xF8, 0xB9, 0x16, 0x1A, + 0x2F, 0x9D, 0x40, 0x93, 0x47, 0xF7, 0xB9, 0x19, + 0x81, 0x19, 0xDF, 0x7B, 0x1D, 0x96, 0xF4, 0xF6, + 0x99, 0x78, 0x80, 0x31, 0x4F, 0x88, 0x1F, 0x04, + 0x00, 0xBA, 0x07, 0x50, 0x1D, 0xDE, 0xF1, 0xA7, + 0x6A, 0x8C, 0x0D, 0xA3, 0x64, 0xBE, 0x6E, 0x0E, + 0xBB, 0x17, 0xDB, 0x7F, 0xA4, 0x03, 0x32, 0xD0, + 0xDE, 0x48, 0x95, 0x91, 0xD0, 0x31, 0x76, 0x85, + 0x17, 0x9A, 0x3F, 0x3E, 0x14, 0xB5, 0x63, 0x6B, + 0x85, 0xE8, 0x68, 0x6F, 0xB1, 0x56, 0x3E, 0x14, + 0x31, 0xE1, 0x26, 0x7A, 0x49, 0x5A, 0xD0, 0x25, + 0x87, 0xF2, 0x99, 0xAE, 0x8A, 0x89, 0xCF, 0x1A, + 0xD5, 0x21, 0x9F, 0x47, 0x2E, 0x10, 0x94, 0x0D, + 0x8F, 0x89, 0x16, 0xAB, 0x21, 0x54, 0xB0, 0xC3, + 0x23, 0xCE, 0x77, 0x5D, 0x69, 0x59, 0x28, 0xD1, + 0x81, 0x82, 0x98, 0xC0, 0x4B, 0x69, 0xFF, 0xC6, + 0x42, 0x7E, 0xB8, 0xF7, 0x9E, 0x61, 0x70, 0xA4, + 0xAB, 0xC1, 0xE8, 0x5D, 0x14, 0x09, 0x13, 0x04, + 0x7B, 0x41, 0x56, 0x60, 0x91, 0x46, 0xA7, 0x16, + 0x40, 0x53, 0x80, 0x2B, 0x7B, 0x6C, 0x55, 0x56, + 0xF5, 0x52, 0x1B, 0xB2, 0x42, 0x49, 0xCC, 0x33, + 0x9A, 0x75, 0xE9, 0x70, 0xC2, 0x49, 0x38, 0xCC, + 0x2F, 0x0C, 0x21, 0x8F, 0xA4, 0xAA, 0xE7, 0x7B, + 0xFA, 0x2E, 0x79, 0x4D, 0x07, 0xDB, 0xB0, 0xBD, + 0xB4, 0x02, 0x57, 0x77, 0xE8, 0x30, 0x24, 0x60, + 0x3C, 0x6A, 0x3E, 0xBB, 0x08, 0x41, 0x24, 0xB8, + 0x75, 0x49, 0x3A, 0xE1, 0x28, 0x0F, 0xA4, 0xB1, + 0xAF, 0x06, 0x95, 0x86, 0x44, 0x43, 0x39, 0x25, + 0x95, 0xD2, 0x84, 0x65, 0x12, 0xC1, 0xE0, 0xDD, + 0x5D, 0x62, 0x16, 0xE4, 0x41, 0x3A, 0xDD, 0x8D, + 0x29, 0x63, 0x26, 0x85, 0x66, 0x2B, 0xAD, 0xF6, + 0x89, 0x62, 0x31, 0x2F, 0x57, 0xAD, 0xCE, 0x8C, + 0x5C, 0x07, 0x9F, 0xAF, 0x3F, 0xBD, 0x2D, 0xE5, + 0xC4, 0xD4, 0xEF, 0x33, 0x4D, 0xED, 0x56, 0x87, + 0xC0, 0x09, 0xD3, 0x6F, 0xF6, 0x26, 0xF0, 0x6F, + 0x40, 0x34, 0x19, 0x22, 0x60, 0xBD, 0xBB, 0x72, + 0x02, 0xFE, 0x66, 0x06, 0x7F, 0xE3, 0x06, 0xC9, + 0x3B, 0x74, 0x91, 0xBC, 0xE6, 0x76, 0x72, 0x34, + 0x08, 0xA9, 0x7A, 0x63, 0x41, 0xDA, 0x0F, 0x9B, + 0x37, 0xD6, 0xD2, 0xC1, 0x38, 0xD3, 0xBF, 0x1D, + 0x72, 0xBA, 0x32, 0xFD, 0xAE, 0xDA, 0x9B, 0xB3, + 0x96, 0x1F, 0x5D, 0x07, 0x4F, 0x47, 0xF7, 0xDA, + 0xF7, 0x19, 0x82, 0xB9, 0xDF, 0xD4, 0xD0, 0x00, + 0x8D, 0x47, 0x7B, 0x05, 0x0E, 0xD6, 0x77, 0x68, + 0xCA, 0xA5, 0xAF, 0x91, 0x6F, 0x8A, 0xCD, 0xEE, + 0xC8, 0x48, 0x21, 0x6D, 0xEE, 0xC5, 0xA1, 0x49, + 0xC5, 0xED, 0xF3, 0x3D, 0xF3, 0xB3, 0x84, 0x65, + 0x4B, 0x40, 0x3B, 0xB2, 0x01, 0x23, 0x0E, 0xAE, + 0x31, 0xBF, 0x4B, 0x81, 0x43, 0x6E, 0x1E, 0x9B, + 0xAD, 0x37, 0x1C, 0x11, 0xFA, 0x7E, 0xC6, 0x55, + 0x1C, 0xE3, 0x2F, 0xAB, 0x3F, 0xEC, 0x27, 0x0E, + 0x7D, 0xC7, 0x9D, 0x74, 0xCC, 0x96, 0x39, 0xA5, + 0xA8, 0x26, 0xE7, 0xDA, 0xF8, 0x14, 0xB7, 0x3B, + 0xFB, 0x29, 0x6F, 0x3A, 0x6C, 0x68, 0x3A, 0x84, + 0xCE, 0xAB, 0x77, 0x69, 0x96, 0x55, 0x1C, 0xDF, + 0x23, 0x8F, 0xEB, 0xF4, 0xE3, 0x2B, 0x7A, 0xC6, + 0xEF, 0xF5, 0x61, 0xFA, 0x44, 0xBB, 0xE4, 0x6A, + 0x25, 0x5E, 0xC1, 0xA2, 0x6B, 0x15, 0x62, 0xFC, + 0x46, 0x23, 0xE1, 0x78, 0x0E, 0xC9, 0xE6, 0x1D, + 0xF9, 0xD9, 0x6F, 0x5C, 0x37, 0x45, 0x76, 0x5A, + 0x0F, 0x01, 0x8B, 0x53, 0xD4, 0xD8, 0x61, 0x63, + 0xC9, 0xA2, 0xAE, 0xA9, 0xBF, 0xA4, 0xEA, 0x3E, + 0x1B, 0xF8, 0x56, 0x63, 0xAE, 0x6D, 0xAF, 0x94, + 0xFB, 0x30, 0x6B, 0x4F, 0x2C, 0x89, 0xCD, 0x4E, + 0x96, 0xF1, 0xD0, 0xF1, 0x8E, 0x2A, 0x67, 0x41, + 0xE3, 0x9F, 0x4C, 0x99, 0x0E, 0x7D, 0xD8, 0x78, + 0xE2, 0x58, 0x51, 0x52, 0x84, 0x35, 0x99, 0xEB, + 0x20, 0xBB, 0x82, 0x02, 0x47, 0x2E, 0xEB, 0x2D, + 0x73, 0x45, 0x7E, 0x23, 0xD3, 0x16, 0xA8, 0xCA, + 0xF4, 0xD4, 0x85, 0x9B, 0x01, 0xE2, 0x1A, 0x2C, + 0xB5, 0xCD, 0x73, 0x29, 0xFD, 0xB3, 0x8A, 0x86, + 0x0B, 0x23, 0x77, 0x4D, 0x37, 0xF2, 0x43, 0x28, + 0xEE, 0xF7, 0xC7, 0xC1, 0x3C, 0x5C, 0x3B, 0xD2, + 0x7D, 0x52, 0xA2, 0x6A, 0x07, 0x09, 0x51, 0x34, + 0x4E, 0x0F, 0x87, 0xF5, 0x54, 0x6F, 0x60, 0x15, + 0x37, 0x48, 0x8D, 0x4A, 0x51, 0x24, 0x06, 0xF3, + 0xD5, 0x54, 0xCC, 0x96, 0xCA, 0x12, 0xFC, 0xB1, + 0xFD, 0x37, 0x16, 0x94, 0x23, 0x87, 0xAA, 0x08, + 0x9C, 0x76, 0xDE, 0x43, 0x8B, 0x0B, 0x47, 0xD7, + 0x8B, 0x2F, 0x1D, 0x8A, 0xCE, 0xC8, 0xCE, 0xBA, + 0xA8, 0x8E, 0x3A, 0x5F, 0xE3, 0x21, 0xD3, 0xBD, + 0xAF, 0x37, 0x74, 0x1D, 0x1B, 0xB5, 0xC7, 0x49, + 0x64, 0x35, 0xDE, 0x71, 0x91, 0x58, 0xF9, 0x32, + 0xAF, 0x0E, 0x37, 0xAA, 0xF5, 0xCA, 0x2E, 0xC5, + 0xF3, 0xF3, 0x57, 0xE8, 0xC6, 0x77, 0xB9, 0xE7, + 0xFE, 0xDC, 0xF2, 0xAD, 0x2F, 0x43, 0x46, 0x48, + 0x1D, 0x99, 0x70, 0x1C, 0xC1, 0x64, 0x94, 0xFF, + 0xEF, 0x43, 0xDF, 0xCE, 0x1E, 0xC5, 0x9C, 0xA3, + 0x34, 0x4A, 0x9A, 0xB5, 0x7F, 0x9D, 0xD8, 0x45, + 0x3C, 0x4E, 0xE8, 0x4A, 0xE8, 0x5F, 0x86, 0xEC, + 0x91, 0x97, 0xD5, 0xCE, 0xDA, 0x89, 0x9B, 0x9B, + 0x5C, 0xF0, 0xF5, 0xA0, 0x8F, 0xAC, 0x45, 0x8B, + 0xCA, 0x0F, 0x10, 0xEF, 0x7A, 0xE2, 0x6A, 0x6C, + 0xB1, 0x4E, 0xCA, 0xDA, 0x58, 0x32, 0x33, 0x94, + 0xBD, 0x40, 0x9F, 0x50, 0x75, 0xFD, 0xBF, 0x9F, + 0x74, 0x16, 0x90, 0x32, 0x29, 0xA0, 0x03, 0x5B, + 0xD1, 0x16, 0xDB, 0x2F, 0x76, 0x03, 0x16, 0xDD, + 0x6D, 0xEA, 0x22, 0xE9, 0x5A, 0x92, 0x04, 0xFE, + 0xD5, 0xAA, 0x89, 0xFF, 0x27, 0x14, 0xFD, 0x1C, + 0x20, 0x39, 0x0D, 0x1C, 0x7E, 0x9A, 0xE2, 0x9D, + 0x0F, 0x0C, 0x83, 0xC1, 0x6C, 0x72, 0x18, 0x45, + 0xFA, 0x01, 0x0C, 0xC5, 0x25, 0xF1, 0xF0, 0xC4, + 0x93, 0x40, 0x16, 0x3C, 0x1A, 0xE4, 0x6F, 0xFE, + 0x3D, 0x00, 0x4E, 0x14, 0x32, 0x40, 0x06, 0xA6, + 0x0A, 0x1C, 0x6B, 0xE7, 0x15, 0x35, 0xFD, 0xFD, + 0xF8, 0xC5, 0x6D, 0x6F, 0xD3, 0x60, 0x51, 0x7F, + 0x00, 0x40, 0x69, 0xCA, 0xE7, 0x52, 0x07, 0x0E, + 0xCC, 0x02, 0x56, 0x05, 0x43, 0x8D, 0xE0, 0x64, + 0x79, 0x5B, 0xDB, 0x38, 0xDF, 0x02, 0x67, 0xDC, + 0x7A, 0x81, 0xF8, 0x10, 0x26, 0x84, 0x87, 0x2B, + 0x4F, 0xDD, 0x9A, 0xFE, 0xCB, 0x32, 0x39, 0xDF, + 0x5D, 0xFF, 0x77, 0xC9, 0xD3, 0x5F, 0x8C, 0x8D, + 0x07, 0x89, 0xA4, 0xA3, 0x32, 0xC9, 0xC7, 0x4C, + 0x8F, 0x42, 0xE2, 0x4F, 0x4F, 0xF6, 0x10, 0x5B, + 0x9C, 0x7D, 0x41, 0x98, 0x48, 0x84, 0x9A, 0x48, + 0xFB, 0x7D, 0xAF, 0x8C, 0x19, 0xB2, 0xFE, 0xAA, + 0x8D, 0x73, 0xE6, 0x92, 0x87, 0xAE, 0xDA, 0x1B, + 0xB3, 0x0C, 0x87, 0x3D, 0x25, 0x1A, 0x19, 0xE1, + 0x7C, 0x5F, 0x56, 0xE8, 0x1E, 0xC2, 0xE7, 0x9B, + 0xF6, 0xAD, 0x63, 0x6B, 0x6B, 0x03, 0x9D, 0x19, + 0x1E, 0x0B, 0xA9, 0x7D, 0x02, 0xD4, 0xB7, 0x87, + 0xC7, 0xC7, 0x90, 0x49, 0xA6, 0x71, 0x0E, 0x4B, + 0x3A, 0xA6, 0x0E, 0x2C, 0xAE, 0x31, 0xC0, 0x66, + 0xEF, 0xB6, 0xC6, 0xE8, 0x04, 0xC8, 0x93, 0x32, + 0xAA, 0xD1, 0x61, 0x36, 0xB1, 0xF5, 0xCE, 0x21, + 0xAA, 0x49, 0x8D, 0x9F, 0xF4, 0x5D, 0x45, 0x20, + 0x48, 0xC8, 0xDA, 0x69, 0xA7, 0xFB, 0x2A, 0x31, + 0x94, 0x83, 0xF2, 0x13, 0xEB, 0xED, 0x98, 0x97, + 0x80, 0x89, 0x44, 0x61, 0xF1, 0xE6, 0x72, 0xD5, + 0x18, 0xF9, 0xB3, 0x26, 0xC7, 0x7D, 0xE1, 0x71, + 0xAD, 0xFD, 0x69, 0x12, 0x4F, 0x71, 0x96, 0x7B, + 0x70, 0xF3, 0x2B, 0xDD, 0xCD, 0x87, 0x60, 0x50, + 0xA9, 0x37, 0xE5, 0x4D, 0xDE, 0xA4, 0x86, 0xE7, + 0x86, 0x97, 0xA0, 0x24, 0x36, 0xF4, 0xF0, 0xA4, + 0xA4, 0xD3, 0x9D, 0x32, 0xB1, 0x36, 0x08, 0x50, + 0xE6, 0x47, 0x1C, 0xFD, 0x3A, 0xA9, 0x25, 0xC5, + 0xE7, 0xA8, 0xF1, 0xAD, 0x9D, 0x3A, 0x71, 0x20, + 0x67, 0x92, 0x63, 0xAF, 0x0A, 0x78, 0xDD, 0x00, + 0xF4, 0xE1, 0xFA, 0xC8, 0x07, 0x70, 0xC1, 0xEE, + 0x14, 0xAD, 0xFF, 0xE5, 0xB3, 0x73, 0xB1, 0xB8, + 0x7A, 0x37, 0xAF, 0xCE, 0x84, 0x17, 0x08, 0x29, + 0x0F, 0x70, 0xDD, 0x1E, 0x83, 0x1F, 0x0B, 0xAA, + 0xBF, 0x23, 0x5A, 0x16, 0xAD, 0x14, 0x1B, 0xA6, + 0x64, 0x66, 0xE6, 0x0A, 0xB3, 0x9E, 0x3F, 0x60, + 0x79, 0x57, 0xDD, 0x5F, 0xAB, 0x64, 0x5B, 0xC5, + 0x51, 0x53, 0x82, 0x46, 0x5B, 0x3D, 0xCC, 0x38, + 0xBC, 0xA6, 0xC1, 0x92, 0x52, 0xC0, 0xD1, 0xB8, + 0x69, 0x52, 0x76, 0x75, 0x4A, 0x96, 0x04, 0x60, + 0xA8, 0xDA, 0xD3, 0xD0, 0xA0, 0x05, 0x23, 0xCC, + 0x6F, 0x02, 0x36, 0x2E, 0xC8, 0x56, 0x13, 0x92, + 0x05, 0x61, 0xDD, 0xEF, 0xA6, 0x45, 0x61, 0x4E, + 0x97, 0xEF, 0x1D, 0x16, 0x8C, 0x5D, 0xBF, 0x60, + 0x43, 0xFE, 0x94, 0x64, 0xF0, 0xE2, 0x83, 0xCF, + 0xDE, 0xF7, 0x94, 0xEA, 0x49, 0x1B, 0x92, 0x91, + 0xA8, 0x9D, 0x2F, 0xEF, 0x87, 0xDE, 0xE8, 0xCC, + 0xC7, 0xA3, 0x77, 0xD7, 0x32, 0xF4, 0x1E, 0x86, + 0x32, 0xC7, 0xFD, 0x78, 0x09, 0x77, 0x81, 0x2B, + 0x1F, 0x7B, 0xA1, 0xF4, 0x29, 0x17, 0xD7, 0x2D, + 0x58, 0x53, 0xCC, 0x9C, 0x8E, 0xC5, 0x12, 0x81, + 0xEA, 0xE2, 0x7C, 0xAA, 0x70, 0x57, 0xDA, 0xEB, + 0x69, 0xD8, 0x0D, 0x32, 0xBA, 0x88, 0xDC, 0x5D, + 0x31, 0x96, 0xB5, 0x40, 0x91, 0x99, 0x53, 0x83, + 0xFD, 0xFD, 0x91, 0xAD, 0xC7, 0x56, 0x87, 0x49, + 0xEC, 0x04, 0xFE, 0x66, 0x3D, 0x3A, 0x06, 0x65, + 0xDD, 0x35, 0x9D, 0xE4, 0xC7, 0x18, 0xB7, 0xD1, + 0x9F, 0x6F, 0x69, 0xAD, 0x99, 0x27, 0xE5, 0xA3, + 0x1A, 0x70, 0x26, 0xBF, 0x82, 0xD6, 0xFA, 0x23, + 0x55, 0xF0, 0xC4, 0x01, 0x69, 0x60, 0x58, 0xBF, + 0xB8, 0x98, 0x7C, 0x90, 0x10, 0x79, 0x16, 0x16, + 0x7F, 0x0E, 0xB4, 0xD5, 0xAB, 0x20, 0x0A, 0x61, + 0x05, 0xB5, 0x4D, 0xFF, 0xE9, 0xC8, 0x94, 0x0F, + 0xEA, 0xD8, 0x62, 0x3F, 0x52, 0x5C, 0x0B, 0xD1, + 0x33, 0x3A, 0x59, 0xD1, 0x30, 0xBE, 0x5A, 0x58, + 0x5C, 0x0F, 0xBE, 0x63, 0xFB, 0xAC, 0x1A, 0xF4, + 0xC8, 0xFD, 0xCF, 0x26, 0x95, 0x17, 0xD8, 0xBB, + 0x38, 0x78, 0xB4, 0xCF, 0xA4, 0x9F, 0x44, 0xA6, + 0xB8, 0xA3, 0xD9, 0xFE, 0x30, 0xFB, 0x7A, 0x96, + 0xDF, 0x34, 0x86, 0xBE, 0xA5, 0x87, 0x40, 0x7A, + 0x69, 0x6E, 0xB7, 0xAD, 0x99, 0x9C, 0x9D, 0xBE, + 0x7F, 0x2E, 0xE5, 0x14, 0x12, 0x1F, 0xEA, 0x0D, + 0x24, 0x42, 0x08, 0xA2, 0x14, 0xA6, 0x25, 0xC7, + 0x59, 0x59, 0x29, 0xF8, 0x7B, 0xC5, 0x05, 0x02, + 0x5C, 0x22, 0x80, 0xB2, 0x6D, 0x5F, 0x85, 0x65, + 0x35, 0x24, 0x13, 0xF7, 0x28, 0xA0, 0x52, 0x9D, + 0xBE, 0x1B, 0x8E, 0xC1, 0x79, 0xE8, 0xA2, 0xDE, + 0x02, 0xDE, 0x2E, 0x23, 0xAE, 0x14, 0xA4, 0x59, + 0xCB, 0x24, 0x77, 0x9B, 0xCA, 0xA9, 0xAC, 0xAB, + 0xE0, 0xD5, 0xF1, 0xEE, 0xE3, 0x1D, 0x69, 0xB7, + 0xF5, 0x50, 0x47, 0x06, 0x93, 0xCE, 0x20, 0x88, + 0x37, 0xD1, 0xA5, 0xCD, 0xF7, 0xCA, 0x81, 0xFE, + 0x5C, 0x55, 0x7A, 0xCD, 0xED, 0xC3, 0x53, 0x0F, + 0x40, 0x03, 0x01, 0x20, 0xA7, 0x26, 0xED, 0x5A, + 0xE9, 0xB0, 0x64, 0xB2, 0x0E, 0x39, 0x44, 0xA2, + 0x78, 0xF0, 0x10, 0x8B, 0x3B, 0x02, 0x81, 0x9D, + 0x40, 0x6D, 0xAF, 0xC1, 0x29, 0x3A, 0x25, 0x06, + 0x12, 0x80, 0xA5, 0xD7, 0x66, 0xD9, 0xE7, 0x7C, + 0xA2, 0x5D, 0x1A, 0x14, 0x15, 0x7A, 0x6A, 0x9D, + 0x2D, 0x70, 0x8D, 0x62, 0xAE, 0x27, 0x8D, 0x36, + 0x43, 0x5D, 0xD5, 0x51, 0xA4, 0x0B, 0x53, 0x43, + 0x11, 0xAE, 0x9B, 0x39, 0x37, 0x22, 0x6D, 0xA2, + 0xDB, 0x17, 0x8C, 0xFC, 0x8A, 0x00, 0x20, 0xE8, + 0xB0, 0x42, 0xCB, 0xBF, 0x1C, 0x91, 0x8D, 0xB9, + 0x7A, 0x7A, 0x66, 0x61, 0xA8, 0x5E, 0x13, 0x17, + 0x05, 0x18, 0x23, 0x52, 0x10, 0x9B, 0x87, 0x72, + 0x51, 0xB8, 0x89, 0x14, 0x1E, 0x61, 0x8B, 0x1C, + 0x82, 0x92, 0xEC, 0xBF, 0xA8, 0x9A, 0xE2, 0xA5, + 0x9A, 0xEC, 0xA2, 0xDB, 0xB4, 0xAC, 0x8D, 0xCA, + 0x45, 0xB9, 0x9D, 0xB8, 0x51, 0xFF, 0x56, 0xEA, + 0xFD, 0xD4, 0x90, 0xA2, 0x48, 0x13, 0x67, 0xC2, + 0x18, 0xAA, 0x8E, 0xBD, 0xB3, 0xED, 0xEF, 0xA7, + 0x98, 0x0C, 0xBB, 0x8B, 0x64, 0xAC, 0x5B, 0x72, + 0x22, 0x49, 0xCA, 0x50, 0x23, 0xFD, 0xC7, 0x5C, + 0x43, 0xA4, 0x14, 0xE3, 0xDD, 0x55, 0xC1, 0x45, + 0xB7, 0x43, 0x03, 0xC5, 0x5F, 0xD0, 0xF8, 0x96, + 0xC3, 0x5C, 0x51, 0xBF, 0x54, 0xD1, 0xC7, 0xA2, + 0x1C, 0xF7, 0xCC, 0x4A, 0xC3, 0xD4, 0x1E, 0x54, + 0xEE, 0x60, 0x1D, 0xDB, 0xA5, 0x2E, 0x1B, 0xC0, + 0x78, 0x59, 0x5E, 0xEB, 0x86, 0xBC, 0x58, 0xA4, + 0x71, 0x45, 0xE9, 0xA8, 0x48, 0x16, 0xC4, 0x0C, + 0x0E, 0x21, 0x4E, 0xD7, 0x59, 0xAA, 0xD1, 0xFD, + 0xDE, 0x27, 0x7C, 0xDA, 0x07, 0x5E, 0xEA, 0x1C, + 0xB1, 0xFA, 0xC5, 0x1F, 0x07, 0x69, 0xAC, 0x23, + 0x48, 0x94, 0x37, 0x1A, 0xF5, 0x5B, 0xB2, 0x6C, + 0xA9, 0x5E, 0x13, 0x0C, 0x44, 0x81, 0xC3, 0x84, + 0x07, 0xCE, 0x8C, 0x39, 0x63, 0x91, 0x3B, 0x4D, + 0x3C, 0xBE, 0x9F, 0xEE, 0xAB, 0x5F, 0x94, 0x9E, + 0x17, 0xD2, 0x9F, 0x0A, 0x2E, 0x77, 0x8C, 0xEF, + 0x47, 0x66, 0x4B, 0x36, 0x97, 0xD8, 0xC6, 0x80, + 0x7F, 0x4D, 0x1E, 0x5E, 0x3F, 0xF8, 0xC8, 0xE8, + 0x45, 0xB6, 0xE0, 0x44, 0xA1, 0xE3, 0xD3, 0x14, + 0xD4, 0x44, 0x90, 0x94, 0x34, 0xFB, 0x40, 0xF9, + 0x7F, 0xEA, 0xAC, 0x2E, 0x34, 0xB9, 0x10, 0x9B, + 0x8E, 0x2D, 0x82, 0xD2, 0xD4, 0xF4, 0x5E, 0xE3, + 0x63, 0xFB, 0x25, 0x5B, 0x1C, 0x65, 0x73, 0x6D, + 0x4E, 0x4B, 0x8D, 0xB2, 0xFE, 0x9D, 0xFA, 0x0D, + 0xAE, 0x5C, 0xC5, 0xB2, 0xA8, 0x9E, 0x83, 0x34, + 0xE5, 0xC9, 0x72, 0x4B, 0x2C, 0xA5, 0xD2, 0x0C, + 0x0D, 0x15, 0x05, 0xFB, 0x8B, 0x96, 0xC4, 0xD3, + 0x32, 0x97, 0x2D, 0xB1, 0xAF, 0xC5, 0x27, 0x38, + 0x37, 0x1D, 0xE5, 0xDF, 0xAF, 0x32, 0x62, 0xD1, + 0x88, 0x2F, 0x40, 0x77, 0xEB, 0xCA, 0xEA, 0x4B, + 0xB2, 0x37, 0xFF, 0xAA, 0xFD, 0x17, 0x2A, 0x7F, + 0x60, 0x7C, 0xD2, 0x47, 0x78, 0x29, 0xD5, 0x51, + 0xE6, 0xC0, 0xBB, 0x58, 0x30, 0x4C, 0xF0, 0x33, + 0x07, 0x10, 0x66, 0xC8, 0x41, 0xE8, 0xB9, 0x41, + 0x40, 0x97, 0xAE, 0xD3, 0xD9, 0x9D, 0xCA, 0x93, + 0xA9, 0x57, 0x89, 0x5D, 0x45, 0x71, 0xCF, 0xD6, + 0xCE, 0xB2, 0x7D, 0xC8, 0x6B, 0x05, 0xE5, 0x33, + 0x98, 0x90, 0x26, 0x12, 0xD6, 0x03, 0xBC, 0xC1, + 0xE5, 0xFA, 0x81, 0x5C, 0x6B, 0xFF, 0x14, 0xB2, + 0xCD, 0xF2, 0x19, 0x26, 0xC2, 0xB1, 0x98, 0x48, + 0xCA, 0x41, 0x08, 0x14, 0x9F, 0xC3, 0x3B, 0xFD, + 0xD6, 0xFA, 0xE5, 0xA2, 0x9E, 0x65, 0xF8, 0x71, + 0x4A, 0x00, 0x77, 0x5F, 0x41, 0x62, 0xD7, 0xFB, + 0x95, 0x2C, 0x6B, 0xE9, 0xF1, 0xA2, 0x16, 0x26, + 0xBF, 0x9A, 0x67, 0xF6, 0x4F, 0xAA, 0xF0, 0xC2, + 0x9C, 0xE6, 0xD2, 0x68, 0x46, 0x67, 0xDC, 0xE5, + 0x92, 0x10, 0x13, 0x53, 0x88, 0xC1, 0xD3, 0x1A, + 0xEB, 0x4D, 0x37, 0xDE, 0x29, 0x6A, 0xBD, 0xB3, + 0xFD, 0xCD, 0x41, 0xD7, 0xEB, 0xEA, 0xCA, 0x0D, + 0xFD, 0x49, 0x2C, 0xE1, 0xB8, 0xEB, 0x82, 0xB2, + 0x76, 0x56, 0xC6, 0xDD, 0x74, 0x8A, 0x89, 0xBD, + 0xF7, 0xCC, 0xA6, 0x54, 0xF6, 0x35, 0xB7, 0xED, + 0xAC, 0x0B, 0xB3, 0x9D, 0x0A, 0x46, 0x7F, 0xCC, + 0x01, 0x3B, 0x28, 0x77, 0xC6, 0x48, 0x13, 0xB3, + 0x1E, 0x9B, 0xAE, 0x80, 0x93, 0x62, 0xA2, 0xEC, + 0x1E, 0xEA, 0x6D, 0x2D, 0xB9, 0xEF, 0x33, 0x29, + 0x80, 0x9E, 0x54, 0x7C, 0xF0, 0xA8, 0xD0, 0x5D, + 0x65, 0x11, 0xE5, 0x97, 0x6C, 0xF8, 0xED, 0xCB, + 0x50, 0x03, 0xF6, 0x0C, 0x77, 0xCD, 0xAD, 0x62, + 0x8F, 0x17, 0xE2, 0x2A, 0x9E, 0x2E, 0x50, 0xEC, + 0x6A, 0x56, 0x59, 0xEB, 0x8C, 0xB5, 0xE6, 0xB1, + 0x48, 0x5F, 0x2B, 0x4B, 0x16, 0x5E, 0x46, 0x49, + 0xA8, 0x2E, 0xC8, 0xFB, 0xDC, 0x20, 0x37, 0x8D, + 0xE6, 0xF9, 0x42, 0x78, 0x83, 0x27, 0x59, 0x15, + 0xE0, 0x0A, 0x63, 0x8F, 0x9F, 0xCC, 0x0B, 0x09, + 0x75, 0xC4, 0x47, 0x4D, 0x05, 0x03, 0x44, 0x87, + 0x92, 0x09, 0x00, 0x90, 0xA8, 0x68, 0xC9, 0x3D, + 0x3A, 0xDB, 0x45, 0x66, 0x71, 0xD9, 0xDF, 0xEE, + 0xDC, 0x06, 0xC2, 0x52, 0x20, 0x86, 0xDB, 0x85, + 0x2B, 0x43, 0xD9, 0x57, 0x04, 0x17, 0x8F, 0x32, + 0x51, 0x92, 0x2E, 0x23, 0x90, 0x0A, 0x70, 0x73, + 0xC1, 0xA1, 0x1D, 0x40, 0xF5, 0x5F, 0x84, 0x1A, + 0xE8, 0x0E, 0xEA, 0x72, 0x22, 0x1D, 0xCF, 0xE2, + 0x5B, 0xEB, 0x84, 0x7F, 0x93, 0xFD, 0x04, 0x15, + 0x9B, 0x9B, 0xEB, 0x15, 0xE5, 0x18, 0x2F, 0x04, + 0xB2, 0xB0, 0x1A, 0x35, 0xD4, 0xD5, 0xC5, 0x55, + 0x74, 0xC8, 0x35, 0x25, 0xA9, 0xF9, 0x68, 0x35, + 0x25, 0x41, 0x64, 0x84, 0xBA, 0xF5, 0x9D, 0xDF, + 0x95, 0x3F, 0x49, 0x9E, 0xC1, 0xC7, 0x01, 0x03, + 0xA3, 0x96, 0x6B, 0x94, 0xBD, 0x7C, 0x5E, 0x11, + 0x8C, 0xFA, 0x47, 0x92, 0x50, 0x24, 0xC1, 0x17, + 0xF0, 0xF6, 0x5A, 0x87, 0x38, 0x24, 0x0E, 0xC1, + 0x1A, 0xC8, 0x48, 0x6F, 0xEE, 0x62, 0x52, 0xED, + 0x75, 0x65, 0xD7, 0x57, 0xBD, 0x06, 0x17, 0x80, + 0x33, 0xBB, 0x3D, 0x0C, 0x0A, 0xA2, 0xA2, 0x07, + 0x6B, 0xCD, 0xF5, 0x4E, 0xB1, 0x8C, 0x74, 0x19, + 0x06, 0x81, 0xB5, 0x4C, 0x61, 0x9F, 0xC5, 0x90, + 0xE0, 0xCB, 0xC2, 0xEB, 0xDB, 0x9E, 0x3E, 0xC8, + 0xC5, 0xEF, 0x2D, 0xFB, 0x67, 0x2F, 0x27, 0xFB, + 0x26, 0x3E, 0x3B, 0xF5, 0x6C, 0x5A, 0x2C, 0xFA, + 0xD0, 0xB2, 0xC1, 0xAA, 0x88, 0x1D, 0x64, 0xBC, + 0x46, 0xC6, 0x3C, 0x98, 0x69, 0x25, 0x3F, 0xC0, + 0x7F, 0xC0, 0xD9, 0x1B, 0xE7, 0xFF, 0xC6, 0xC7, + 0xE1, 0x66, 0x11, 0x8C, 0x6F, 0x88, 0xAD, 0x40, + 0x15, 0x38, 0xE7, 0x58, 0xC5, 0x4E, 0x28, 0xCB, + 0x67, 0xC5, 0x28, 0x65, 0xA4, 0x05, 0x6D, 0x4E, + 0xED, 0x84, 0x10, 0x0E, 0xF7, 0x7A, 0x0A, 0x07, + 0x21, 0x49, 0x54, 0x48, 0x91, 0x7E, 0xB5, 0xA8, + 0xBF, 0xBA, 0x18, 0x1A, 0xD9, 0x82, 0x49, 0x82, + 0x76, 0x4F, 0x8F, 0x6F, 0xC7, 0x84, 0xF9, 0x49, + 0x28, 0xCE, 0x12, 0xBB, 0xF0, 0x34, 0xBD, 0xAA, + 0x4F, 0xE8, 0x39, 0x6C, 0xB2, 0xB6, 0x95, 0xA0, + 0x2E, 0xEA, 0x90, 0x22, 0xE4, 0x88, 0x82, 0xE5, + 0x54, 0x38, 0x5A, 0xDA, 0x85, 0xAA, 0x78, 0xC8, + 0x88, 0x98, 0xDC, 0x7E, 0xB7, 0x24, 0x8A, 0x7B, + 0x16, 0x93, 0xC7, 0x95, 0x5D, 0x53, 0x52, 0x85, + 0x2A, 0x8C, 0x8B, 0x76, 0xA9, 0x5C, 0x02, 0x72, + 0xBB, 0x88, 0xE6, 0x11, 0x33, 0x64, 0x17, 0x82, + 0x27, 0x9B, 0x5C, 0x21, 0x90, 0xA0, 0x4C, 0x7A, + 0x92, 0xF2, 0x80, 0x23, 0x9D, 0xCE, 0x90, 0xD3, + 0x45, 0x43, 0xA0, 0xDC, 0xD9, 0x06, 0xFC, 0x92, + 0x8A, 0x11, 0x68, 0x47, 0xC5, 0x18, 0xD6, 0x20, + 0x01, 0xF8, 0xCA, 0x89, 0x2D, 0xE7, 0x52, 0x3D, + 0x9C, 0xD8, 0xA6, 0xDB, 0x3E, 0x3E, 0xAF, 0xE7, + 0x21, 0x8D, 0x9F, 0xA4, 0xEF, 0xBC, 0x62, 0xEA, + 0xC7, 0x5E, 0xD3, 0x8F, 0xAF, 0xB3, 0xA5, 0x8F, + 0xE1, 0xF6, 0x2A, 0xAC, 0x53, 0x03, 0x26, 0x8E, + 0x11, 0xF7, 0x76, 0xB3, 0x30, 0x0D, 0x7D, 0xB0, + 0x12, 0xA8, 0x35, 0xB9, 0x44, 0x02, 0x02, 0x79, + 0xEF, 0xBC, 0xD2, 0x32, 0x34, 0x8C, 0x10, 0x58, + 0x7E, 0xDA, 0x41, 0x3E, 0xC4, 0x5C, 0x82, 0x5E, + 0x57, 0xC4, 0x92, 0x7E, 0x10, 0x3B, 0xAB, 0x58, + 0xDC, 0xCB, 0xA7, 0x6C, 0x89, 0x2E, 0x32, 0x23, + 0xF6, 0x76, 0x30, 0xA6, 0x12, 0xCB, 0x00, 0x85, + 0x65, 0xC9, 0x1A, 0x4D, 0xE7, 0xF5, 0x4B, 0xC9, + 0xFD, 0x50, 0x00, 0xAE, 0xD2, 0x07, 0xFE, 0x7D, + 0xD6, 0x02, 0x18, 0x69, 0x01, 0x41, 0x3B, 0xE8, + 0x32, 0xB5, 0x09, 0xAD, 0x3A, 0x27, 0xF4, 0x1A, + 0x9A, 0x7D, 0x62, 0xE2, 0x7F, 0xB7, 0xBD, 0x50, + 0xA5, 0xC5, 0x3E, 0x12, 0x30, 0x01, 0x7E, 0x5D, + 0xB0, 0xE5, 0x3D, 0xF8, 0xF9, 0xFB, 0x4E, 0xB5, + 0x9B, 0x96, 0x9A, 0xE8, 0x91, 0x06, 0x8D, 0x73, + 0x9F, 0xC3, 0x10, 0x87, 0xEB, 0xCD, 0xBA, 0xB5, + 0xBA, 0xE5, 0x10, 0x01, 0x45, 0xDE, 0x86, 0x65, + 0xFD, 0xFA, 0xF1, 0x6F, 0xA4, 0x0E, 0xF0, 0x3D, + 0xC5, 0x45, 0x26, 0xFE, 0xFF, 0x19, 0x0A, 0xAF, + 0x5C, 0x7A, 0xDF, 0x23, 0x67, 0xDE, 0xB8, 0xA1, + 0x09, 0x4F, 0xC7, 0x6D, 0x69, 0x38, 0xA5, 0xBC, + 0x16, 0xFD, 0xF4, 0x9E, 0xFC, 0xB0, 0xA8, 0x48, + 0x35, 0x7B, 0x80, 0xBF, 0x35, 0xF2, 0x7A, 0x5F, + 0xF6, 0xD9, 0x82, 0xCF, 0xE8, 0x3E, 0x3A, 0x0F, + 0x40, 0xCF, 0x4E, 0x2F, 0x01, 0x45, 0x0B, 0xBF, + 0xC1, 0x12, 0xBA, 0xA4, 0xE5, 0x18, 0x1D, 0x91, + 0xDD, 0xC0, 0x3D, 0xB8, 0x8B, 0x6F, 0xD4, 0xE4, + 0x56, 0xBB, 0x5C, 0xC2, 0xAA, 0xE1, 0xA7, 0xDF, + 0xE4, 0xC9, 0x48, 0xB9, 0xD1, 0x75, 0x35, 0x69, + 0x31, 0xE9, 0x03, 0x35, 0xE4, 0x2A, 0x18, 0x54, + 0x54, 0xC4, 0xEB, 0x86, 0x82, 0x8A, 0x8A, 0x18, + 0x2F, 0x37, 0x57, 0x8C, 0x76, 0x0B, 0x36, 0x44, + 0x4B, 0xBD, 0xF0, 0xA0, 0x6A, 0x5C, 0x4D, 0x97, + 0xEA, 0x38, 0xE8, 0xF5, 0x07, 0xE4, 0xF8, 0x71, + 0xAB, 0x94, 0x78, 0x92, 0xCD, 0xA4, 0x84, 0x64, + 0x8F, 0xA0, 0x6E, 0xB2, 0x72, 0xA8, 0x10, 0x2D, + 0xB5, 0x66, 0x04, 0xEC, 0xFE, 0x2E, 0x92, 0x1A, + 0xB5, 0x52, 0xDC, 0x02, 0x2D, 0xF8, 0xFA, 0x93, + 0xA9, 0xE9, 0xF7, 0xA7, 0x71, 0x65, 0x27, 0x7E, + 0x18, 0x16, 0x60, 0xFC, 0xC5, 0x42, 0x0B, 0x69, + 0xBA, 0x50, 0x89, 0x3B, 0x4C, 0x69, 0x38, 0x1F, + 0x94, 0x6A, 0x89, 0x3D, 0xEA, 0x46, 0x0C, 0xB5, + 0x4B, 0x00, 0x04, 0x5A, 0x58, 0xCA, 0x4D, 0x7E, + 0x22, 0x29, 0x3F, 0x1D, 0xC8, 0xD2, 0xDF, 0x80, + 0x63, 0xAB, 0x4A, 0x98, 0x53, 0xE5, 0x3E, 0x9C, + 0xF4, 0x37, 0xBB, 0x72, 0x6A, 0xD7, 0xF6, 0x22, + 0xE1, 0xE3, 0xB5, 0x59, 0x0D, 0xE0, 0x3A, 0xFD, + 0x8B, 0x95, 0xAB, 0x83, 0xA9, 0xF9, 0x78, 0xCF, + 0x38, 0xA7, 0x73, 0xD5, 0xFA, 0x18, 0xA3, 0xA0, + 0xDB, 0x10, 0x82, 0xB4, 0x46, 0x8E, 0xA8, 0x1A, + 0xC8, 0x91, 0x97, 0x92, 0xE2, 0x93, 0xE7, 0x75, + 0x4A, 0xC7, 0x54, 0xFD, 0x94, 0x7B, 0xB1, 0xB3, + 0x88, 0x8A, 0x26, 0x9F, 0x88, 0x01, 0x10, 0x52, + 0xBE, 0xE5, 0x48, 0x1B, 0x96, 0xCD, 0x9D, 0xB8, + 0xB0, 0x02, 0x47, 0x46, 0xDB, 0x90, 0xC6, 0x6E, + 0x7A, 0x53, 0xE5, 0x0E, 0xE9, 0xFA, 0xC3, 0x0F, + 0x17, 0xE0, 0xD5, 0x9F, 0x6A, 0x6F, 0xC9, 0xC5, + 0xE6, 0x5B, 0x75, 0xEA, 0xAF, 0x4A, 0xDC, 0x63, + 0xF5, 0x6B, 0x2F, 0xDF, 0xF0, 0xA8, 0x4F, 0xD9, + 0x6B, 0x77, 0x8F, 0x3E, 0x17, 0x7F, 0x97, 0xB0, + 0x8B, 0x15, 0x1E, 0xA2, 0x9B, 0x3B, 0x07, 0x02, + 0xD3, 0xC9, 0xD3, 0x71, 0x65, 0x81, 0x56, 0x33, + 0x60, 0x0D, 0x32, 0x63, 0xBD, 0x62, 0x2B, 0x66, + 0x19, 0x41, 0x0B, 0x10, 0x91, 0x7B, 0xD0, 0xA7, + 0x00, 0xEF, 0xE7, 0x2D, 0xC0, 0xCF, 0x93, 0x5D, + 0x78, 0xE8, 0x3B, 0xF5, 0x3F, 0xD3, 0xA5, 0x3F, + 0xF3, 0xB8, 0xC6, 0xFD, 0x55, 0xB3, 0xEA, 0x4E, + 0x6F, 0x24, 0x5A, 0x3D, 0x33, 0x53, 0x83, 0x40, + 0xC7, 0x1B, 0xF3, 0x69, 0x07, 0x26, 0xB8, 0x46, + 0xA3, 0xC8, 0xE4, 0x9F, 0x23, 0xC1, 0x5A, 0xAD, + 0x77, 0x3E, 0x38, 0x93, 0xBF, 0xB9, 0xB9, 0x2B, + 0xB3, 0xBC, 0x2E, 0xC2, 0x69, 0x1A, 0x5C, 0x4B, + 0xAA, 0x37, 0x78, 0x14, 0xB9, 0x58, 0x37, 0xE2, + 0xFD, 0x63, 0xD9, 0xED, 0xE0, 0x25, 0x23, 0xA6, + 0xF5, 0xC2, 0xB4, 0x06, 0xFD, 0xB1, 0x83, 0xA6, + 0xE9, 0x76, 0x9B, 0x9D, 0xF9, 0x17, 0x07, 0xD7, + 0x2F, 0x2D, 0xB9, 0x7F, 0x81, 0x31, 0x5D, 0x76, + 0x89, 0x67, 0xAF, 0x97, 0xCD, 0xB0, 0xA0, 0x1C, + 0x04, 0x86, 0xAF, 0xE7, 0x5E, 0xBC, 0xB2, 0x97, + 0x8F, 0x43, 0x8D, 0x5F, 0xBD, 0x21, 0x13, 0x0B, + 0x2C, 0x39, 0x00, 0x48, 0x16, 0xF9, 0xEF, 0x93, + 0xF1, 0xF8, 0x95, 0x39, 0x3B, 0x44, 0xAF, 0x57, + 0x80, 0xF7, 0x0C, 0xE8, 0xFE, 0x50, 0x2E, 0xAC, + 0x70, 0x36, 0x1F, 0xA8, 0xE4, 0x33, 0x34, 0x7E, + 0xDF, 0xDE, 0x71, 0xD2, 0xB2, 0x5A, 0xF9, 0x21, + 0x3B, 0x5C, 0xD3, 0x34, 0xFF, 0x96, 0xF9, 0xB2, + 0x9C, 0x26, 0xF4, 0xDB, 0x52, 0x0F, 0xD9, 0xEF, + 0xB4, 0xDD, 0xD1, 0xA8, 0xB4, 0x6E, 0x27, 0x12, + 0x79, 0x22, 0x84, 0x0A, 0x20, 0x1D, 0x6E, 0x7F, + 0x09, 0xC6, 0x31, 0xD3, 0x2E, 0x98, 0xC9, 0x08, + 0xBD, 0xAA, 0xC3, 0x65, 0x38, 0xD8, 0xC7, 0x13, + 0xF1, 0xCF, 0x18, 0xC3, 0x7B, 0x7E, 0xE5, 0x7C, + 0x5E, 0x22, 0x36, 0x88, 0x71, 0x5C, 0xB7, 0xCC, + 0x4D, 0xA4, 0xF7, 0x83, 0xE0, 0x1E, 0xC2, 0x4F, + 0xEA, 0x2C, 0xFF, 0xF7, 0x1C, 0xBF, 0x84, 0x31, + 0x70, 0x75, 0x12, 0xC8, 0xFB, 0xC6, 0xFE, 0x5A, + 0x14, 0x91, 0x3B, 0xD8, 0x36, 0x67, 0x1E, 0xF9, + 0xF4, 0x29, 0x6F, 0xA1, 0xEA, 0x46, 0x27, 0xA0, + 0xC1, 0x34, 0xAE, 0x09, 0xEA, 0xDA, 0x0E, 0xBB, + 0x83, 0x20, 0x4E, 0x2A, 0x0B, 0x59, 0xF4, 0x1D, + 0xC7, 0x62, 0x47, 0x3A, 0x0E, 0xA0, 0x92, 0xEA, + 0x8E, 0x00, 0x63, 0x70, 0x92, 0x18, 0xF9, 0x78, + 0x8C, 0xED, 0xEE, 0x9D, 0x70, 0x50, 0x58, 0x12, + 0xAB, 0x9C, 0xC8, 0xA6, 0x71, 0x46, 0x94, 0xDD, + 0xC5, 0xE4, 0xE6, 0x87, 0x84, 0x88, 0xFB, 0x77, + 0x4A, 0x79, 0x62, 0x5B, 0x9E, 0x27, 0xD4, 0x85, + 0x1A, 0x33, 0xE4, 0x5A, 0x2E, 0x4C, 0x29, 0xA0, + 0x3D, 0x47, 0xA2, 0x6B, 0xEE, 0x08, 0xFD, 0xB5, + 0xCE, 0xE5, 0xC9, 0x8E, 0x18, 0x1C, 0x04, 0x01, + 0xD1, 0xB3, 0xF4, 0x01, 0x90, 0xB3, 0x2E, 0x70, + 0x85, 0xBE, 0x47, 0x13, 0xD9, 0xBC, 0x00, 0xFE, + 0xA1, 0x9A, 0x72, 0x7B, 0x59, 0x98, 0x75, 0xCC, + 0xDB, 0xA1, 0xB5, 0x5C, 0xF4, 0x8A, 0x19, 0xDF, + 0x5B, 0x1D, 0xC2, 0xCF, 0x3B, 0x82, 0x3C, 0xDB, + 0x67, 0x40, 0x4F, 0xA9, 0xBA, 0x3E, 0xF8, 0xA3, + 0xD1, 0x1B, 0xA0, 0x64, 0x24, 0xED, 0xD0, 0x22, + 0xDF, 0x6D, 0xE5, 0x38, 0xDB, 0x2C, 0x10, 0x49, + 0x86, 0x11, 0xAC, 0x7C, 0xFC, 0xCF, 0xAE, 0x41, + 0x0C, 0x36, 0x05, 0x63, 0x0C, 0x27, 0x08, 0x9E, + 0xED, 0xEB, 0x25, 0x41, 0xFA, 0xB2, 0x8E, 0x12, + 0x79, 0x64, 0x52, 0x80, 0xF5, 0x55, 0x62, 0xBB, + 0x2F, 0x95, 0xE9, 0x41, 0x8D, 0x6E, 0xE7, 0x37, + 0xCA, 0x71, 0xF9, 0xC7, 0x36, 0xE5, 0x6D, 0xA5, + 0x38, 0xB2, 0x90, 0xBB, 0xEA, 0x1F, 0xAF, 0x57, + 0x69, 0x01, 0xD6, 0x3A, 0xA1, 0xC8, 0xF6, 0xBC, + 0x82, 0x1D, 0xF6, 0xE1, 0x0D, 0x5B, 0xE0, 0x30, + 0xB9, 0x87, 0xE5, 0x7F, 0xB9, 0xDB, 0x76, 0x2F, + 0x5A, 0xE8, 0xFA, 0xF2, 0xC9, 0x27, 0x61, 0x87, + 0xFE, 0xA3, 0xC0, 0x1B, 0xA7, 0x99, 0xD7, 0x20, + 0x95, 0x80, 0x45, 0x0E, 0xE3, 0x11, 0xE1, 0x4B, + 0x83, 0xA5, 0xC5, 0xED, 0x53, 0xF3, 0xFD, 0xD2, + 0x34, 0x8F, 0xD1, 0x2B, 0x7A, 0xB5, 0x6F, 0x5F, + 0xEA, 0x55, 0x0D, 0xBB, 0x74, 0x06, 0x85, 0xD7, + 0x07, 0xDC, 0x25, 0x94, 0xB5, 0xBD, 0x22, 0x85, + 0x9F, 0xE1, 0xD8, 0xD5, 0xA6, 0xC9, 0x60, 0x11, + 0x41, 0x8D, 0x5B, 0x60, 0xE5, 0x8A, 0x57, 0xC8, + 0x8C, 0x41, 0x3A, 0xC0, 0x17, 0x99, 0xA5, 0xE4, + 0x0E, 0x90, 0x53, 0x3D, 0xE2, 0xFB, 0x6A, 0x58, + 0x64, 0x37, 0xD5, 0xD9, 0xB5, 0x0A, 0x3E, 0x0B, + 0x86, 0xFD, 0x2B, 0x2C, 0x52, 0x35, 0xE7, 0x9A, + 0xCA, 0x54, 0xD4, 0x3E, 0x75, 0x5B, 0xA9, 0xB7, + 0x2E, 0xF9, 0x2D, 0x5C, 0xF8, 0x8B, 0xB5, 0x22, + 0xD9, 0xEE, 0xE7, 0x20, 0x6C, 0x7D, 0x25, 0x14, + 0x0E, 0x7D, 0xC4, 0x1C, 0x58, 0xB2, 0xF3, 0xF6, + 0x9C, 0xE3, 0x81, 0x74, 0xD5, 0x97, 0xAB, 0x97, + 0x35, 0x71, 0x81, 0xA1, 0x83, 0x4A, 0xBF, 0x3F, + 0x1A, 0x97, 0xDE, 0x65, 0xD6, 0xD8, 0xAD, 0x8A, + 0xDE, 0x10, 0x25, 0xCC, 0xF2, 0xD1, 0x0C, 0xA5, + 0x31, 0xA9, 0x3C, 0xC8, 0x3E, 0x23, 0xD1, 0x4D, + 0x4F, 0x94, 0x99, 0x0B, 0xAC, 0x03, 0xDD, 0x3D, + 0xF3, 0x50, 0xF5, 0xEB, 0x86, 0x4E, 0x4F, 0xD0, + 0x09, 0x52, 0x79, 0x2C, 0x8C, 0xF4, 0x4A, 0x55, + 0xB3, 0x49, 0x51, 0x6E, 0x57, 0x14, 0xF9, 0x7E, + 0x5B, 0x9F, 0xA9, 0xBC, 0x71, 0x48, 0xD6, 0xBD, + 0xA4, 0xC9, 0x5A, 0x6D, 0xC4, 0x1A, 0x02, 0xE2, + 0xB9, 0xC7, 0x64, 0x0E, 0xA2, 0x37, 0x00, 0x3B, + 0xC9, 0x73, 0x21, 0x4E, 0xF1, 0x45, 0x8E, 0x5B, + 0xFD, 0xE1, 0x9A, 0x48, 0x77, 0x1B, 0xC8, 0xD3, + 0x36, 0xC5, 0xEE, 0x47, 0x8D, 0x16, 0x55, 0x4C, + 0x44, 0x3F, 0x82, 0x6E, 0x57, 0x18, 0x70, 0xFD, + 0x65, 0xE3, 0x43, 0x65, 0x36, 0xB0, 0xAF, 0x45, + 0xC7, 0x53, 0xD0, 0xD9, 0x28, 0xB1, 0xE1, 0xD4, + 0x1B, 0x95, 0x77, 0x7E, 0x26, 0x86, 0x68, 0x62, + 0xFA, 0x57, 0x2E, 0x88, 0xB9, 0x2C, 0x95, 0x00, + 0x92, 0xE1, 0x5D, 0x7C, 0x16, 0x47, 0x06, 0x09, + 0x19, 0xF3, 0xD8, 0x87, 0xDE, 0xC7, 0x0B, 0xDB, + 0x89, 0xF4, 0x36, 0x97, 0xF5, 0x1C, 0xE3, 0x46, + 0x31, 0x1B, 0xC7, 0xC4, 0xE3, 0x9B, 0xC7, 0x1C, + 0x4C, 0x04, 0xA8, 0xDA, 0xBC, 0x66, 0x5F, 0xA2, + 0x26, 0x5C, 0xE8, 0xDB, 0x41, 0xF3, 0x0F, 0x33, + 0x5E, 0x9F, 0x5A, 0xBD, 0x92, 0x58, 0xA9, 0xEA, + 0xBA, 0x19, 0xFB, 0x21, 0x04, 0x41, 0xAD, 0xED, + 0x3A, 0xBC, 0xBE, 0xDA, 0xC2, 0x15, 0xCE, 0x4A, + 0x29, 0x7A, 0xCE, 0x35, 0x51, 0x42, 0x4C, 0x20, + 0x52, 0x8A, 0x5F, 0xFB, 0x2C, 0xB6, 0x5D, 0x0F, + 0xAE, 0x09, 0x7C, 0x66, 0x3D, 0x80, 0x62, 0x90, + 0x86, 0x17, 0x61, 0xEF, 0xF4, 0x1A, 0x59, 0x85, + 0xAD, 0x27, 0x0C, 0x6A, 0xE0, 0xF3, 0x18, 0xBF, + 0xEF, 0x2D, 0xAA, 0x80, 0x18, 0xA7, 0x8F, 0xF0, + 0xAB, 0x8A, 0x2C, 0x28, 0x93, 0xBC, 0xD5, 0x3C, + 0xED, 0xBF, 0x02, 0xE9, 0x9B, 0x1F, 0x46, 0xFD, + 0x96, 0x5D, 0xE8, 0x0E, 0xAC, 0xF4, 0x6A, 0xA7, + 0xEB, 0x4A, 0xC7, 0xBA, 0xE1, 0x5D, 0x9E, 0x9B, + 0xB1, 0x5C, 0x13, 0x3A, 0xCF, 0xC9, 0x41, 0x35, + 0x0D, 0xA4, 0xFB, 0x47, 0x1F, 0x42, 0xE3, 0x37, + 0x19, 0xC4, 0x13, 0x56, 0x81, 0xE3, 0xF2, 0x89, + 0xE7, 0x24, 0x80, 0x54, 0xD8, 0xF4, 0x6D, 0xCC, + 0x72, 0x22, 0xC7, 0xDE, 0xB6, 0x06, 0xDF, 0xB7, + 0x4C, 0xB6, 0x31, 0x09, 0xC3, 0x27, 0x29, 0xEA, + 0xFB, 0xEA, 0x40, 0xB9, 0x60, 0xD6, 0x50, 0x11, + 0x01, 0xA2, 0xB1, 0xB2, 0x14, 0x9F, 0x5F, 0x08, + 0xD7, 0x5B, 0x95, 0xF8, 0xD1, 0xA8, 0x94, 0x27, + 0x5F, 0xF7, 0xD7, 0x3F, 0xA5, 0xFF, 0x9A, 0x4C, + 0x86, 0xDF, 0x07, 0xB0, 0x80, 0x05, 0x5D, 0x21, + 0x12, 0xFE, 0xC4, 0x55, 0xFF, 0x10, 0xC8, 0x24, + 0x7F, 0xB3, 0xB1, 0xB2, 0x2D, 0x8F, 0xC7, 0x68, + 0xE2, 0x0F, 0xE1, 0xB4, 0x07, 0xF2, 0xA2, 0x81, + 0x7E, 0xD3, 0xDA, 0x3A, 0x1A, 0xFF, 0xF5, 0x2E, + 0xAE, 0xB1, 0x66, 0x6B, 0x57, 0xE2, 0xE6, 0xE1, + 0xE5, 0xC4, 0x84, 0x18, 0xB8, 0xDC, 0x78, 0x45, + 0xB6, 0x2B, 0xD9, 0x61, 0xEB, 0xCA, 0x30, 0x81, + 0x69, 0x6B, 0xD7, 0xD7, 0xB4, 0x94, 0xD4, 0x68, + 0xB0, 0xF5, 0xA0, 0xA4, 0xF0, 0xD7, 0x94, 0xCE, + 0x09, 0x9C, 0x8B, 0x7C, 0x6D, 0x4F, 0x91, 0x0F, + 0x60, 0x87, 0xA7, 0x4D, 0x3A, 0x05, 0x8A, 0x30, + 0x2E, 0x1B, 0x6F, 0xF2, 0xF4, 0xE9, 0x14, 0xF4, + 0xC2, 0x0B, 0x9D, 0x70, 0x4E, 0xB1, 0xE8, 0xAC, + 0xE4, 0x7E, 0x79, 0x52, 0x85, 0x24, 0x53, 0xFF, + 0x21, 0x68, 0x9A, 0x7A, 0xA2, 0x6A, 0x4E, 0x3D, + 0x57, 0xC8, 0xAB, 0xB8, 0xF3, 0xA0, 0xB4, 0xD6, + 0x33, 0x5E, 0x6A, 0x26, 0xE2, 0x5A, 0xE7, 0x01, + 0x7C, 0x7D, 0x1E, 0x76, 0x05, 0xB0, 0x49, 0xD9, + 0x63, 0x95, 0x40, 0xF2, 0x48, 0xD2, 0xC4, 0x78, + 0x77, 0xA2, 0x29, 0xB0, 0x63, 0x46, 0xE6, 0x2F, + 0x09, 0x5B, 0xB5, 0xE1, 0xE2, 0x10, 0xD2, 0x43, + 0x82, 0x8F, 0x92, 0x51, 0xEA, 0x4E, 0x01, 0x66, + 0xB7, 0xED, 0x43, 0x84, 0x20, 0x5A, 0xE1, 0xD0, + 0x18, 0xBF, 0xBB, 0xC7, 0x76, 0x76, 0xCC, 0xA2, + 0xDC, 0xDC, 0x81, 0xF3, 0xEC, 0xE2, 0x27, 0x5E, + 0x1E, 0x76, 0x0B, 0xE7, 0x59, 0xBA, 0x13, 0xE8, + 0x9B, 0x4D, 0x2D, 0x4A, 0xD7, 0x7F, 0x13, 0x7A, + 0x0B, 0x3E, 0xBB, 0xE3, 0x7A, 0xF9, 0xB3, 0xBE, + 0x65, 0x0A, 0x45, 0xD2, 0xA7, 0x38, 0x0E, 0xFE, + 0x69, 0xF3, 0x85, 0x54, 0x16, 0x08, 0xE7, 0x33, + 0x9A, 0x35, 0x8B, 0x2E, 0xE8, 0x39, 0x9C, 0xE9, + 0x4D, 0xE8, 0x54, 0x6B, 0xF5, 0x00, 0x31, 0xEB, + 0x15, 0x84, 0x22, 0xE8, 0x0C, 0x63, 0xF3, 0x01, + 0x32, 0x92, 0x26, 0x80, 0xAA, 0x9D, 0xE8, 0x16, + 0x32, 0x43, 0x72, 0x6B, 0xB7, 0x51, 0xFF, 0xDD, + 0x01, 0x9A, 0x64, 0xFF, 0x0D, 0xF9, 0x5D, 0xD4, + 0xA7, 0x5B, 0x19, 0xDF, 0x8A, 0x23, 0xC3, 0xBC, + 0x11, 0x99, 0xA9, 0x4D, 0xC1, 0x84, 0x43, 0x65, + 0x8D, 0x72, 0x9E, 0xF3, 0x1E, 0x0B, 0x51, 0xB0, + 0x3D, 0xDF, 0x0B, 0x88, 0x45, 0xB4, 0xFA, 0x44, + 0xE1, 0x53, 0x14, 0xEC, 0xDE, 0x6E, 0xA5, 0x09, + 0x11, 0xA1, 0xEF, 0x09, 0x39, 0x28, 0x12, 0x7E, + 0x75, 0x1D, 0xAA, 0x10, 0xC2, 0x7B, 0xB5, 0xD6, + 0xC1, 0x61, 0x93, 0x84, 0xDA, 0x83, 0xD8, 0x7D, + 0x84, 0xE2, 0x12, 0xAD, 0xAD, 0x5F, 0x0C, 0x63, + 0xD4, 0xD4, 0xA0, 0x4E, 0x0E, 0x03, 0x0D, 0x20, + 0x16, 0x4C, 0x62, 0xD6, 0x42, 0x62, 0xC4, 0x7A, + 0x61, 0x7F, 0xF4, 0xB3, 0xCD, 0xF9, 0x47, 0x6A, + 0x95, 0xA4, 0x33, 0xB8, 0xC3, 0x23, 0x05, 0x18, + 0x46, 0x1E, 0xEA, 0x5F, 0xAD, 0x4A, 0x34, 0x7A, + 0x33, 0x69, 0xF0, 0x26, 0x5C, 0xD0, 0x25, 0x5E, + 0x20, 0x3F, 0x39, 0x13, 0xFF, 0xCA, 0x5B, 0x1D, + 0x88, 0x85, 0x27, 0xE9, 0x94, 0xE1, 0x63, 0x32, + 0x79, 0x99, 0xD7, 0xDC, 0x1A, 0xE0, 0xB4, 0x05, + 0x49, 0x0E, 0x09, 0x88, 0x03, 0xC0, 0xAC, 0x75, + 0xC9, 0x35, 0x7A, 0xEC, 0xB4, 0x14, 0x09, 0x55, + 0x9D, 0xEE, 0x4C, 0xCD, 0xB3, 0x48, 0x55, 0x2D, + 0x5C, 0x92, 0x31, 0x5D, 0xE4, 0x11, 0xA1, 0x3C, + 0x48, 0xAA, 0x44, 0x28, 0x98, 0x98, 0x66, 0xE9, + 0xF7, 0xC3, 0xE4, 0x12, 0x61, 0x19, 0xD8, 0x1F, + 0x37, 0x6D, 0x57, 0xA7, 0x5F, 0xA3, 0xD0, 0x9F, + 0x3D, 0xD3, 0xC3, 0x8B, 0x5D, 0x93, 0xA1, 0xBA, + 0x51, 0xBB, 0x6A, 0x73, 0x86, 0x0D, 0xC8, 0xF1, + 0x39, 0xC1, 0xD8, 0x0F, 0x51, 0x94, 0xFA, 0xA4, + 0x1E, 0x95, 0x46, 0xED, 0x62, 0xEA, 0x23, 0x35, + 0x92, 0xA0, 0xDC, 0xA5, 0x65, 0x60, 0xD3, 0x85, + 0xC7, 0x30, 0xB4, 0x88, 0x5D, 0xC6, 0x50, 0x35, + 0x35, 0x95, 0x8C, 0x17, 0x95, 0xDC, 0xC2, 0x7E, + 0xA4, 0xD9, 0x72, 0x07, 0xCA, 0x70, 0xBF, 0xF4, + 0x2E, 0x0C, 0x54, 0x43, 0xE3, 0xE3, 0x77, 0xA2, + 0x90, 0xFC, 0x9D, 0x93, 0xF8, 0xB5, 0xA8, 0x17, + 0xFD, 0x27, 0xF6, 0x7E, 0x63, 0x5D, 0x1E, 0x0C, + 0xD1, 0x04, 0x47, 0x7B, 0x1C, 0x98, 0x87, 0x81, + 0x85, 0x44, 0xCE, 0x40, 0x3F, 0xD9, 0xFC, 0x5E, + 0x92, 0x60, 0xC2, 0x5C, 0xC3, 0x3F, 0xF4, 0xCA, + 0x01, 0x51, 0x46, 0xDF, 0x96, 0x12, 0x81, 0x0D, + 0x52, 0x4C, 0xBA, 0xD4, 0x57, 0xA0, 0x15, 0xDB, + 0x98, 0xBB, 0x39, 0x30, 0xB3, 0xB9, 0x4D, 0xF8, + 0x0F, 0xD3, 0x6B, 0xAC, 0x04, 0x9D, 0xD9, 0xD9, + 0x7F, 0xA8, 0xE0, 0x9D, 0x71, 0xB1, 0xE7, 0x87, + 0x3C, 0x53, 0x32, 0x8D, 0xB3, 0x15, 0xEB, 0x38, + 0x10, 0xB4, 0x83, 0x9F, 0x8F, 0xC8, 0xB1, 0x41, + 0xCB, 0xA1, 0x87, 0xBB, 0x88, 0xCA, 0x2B, 0x81, + 0x7C, 0xC3, 0x8F, 0x68, 0xC7, 0x1B, 0x98, 0x9E, + 0x59, 0xF2, 0x9B, 0xC7, 0x8D, 0x07, 0x49, 0xFA, + 0x43, 0x73, 0x3F, 0x7A, 0x62, 0xF6, 0x89, 0x8A, + 0xA4, 0xDE, 0x16, 0xC3, 0x67, 0xA9, 0xFE, 0x1D, + 0x3B, 0x00, 0x9B, 0xA4, 0x82, 0x1D, 0xBE, 0x0A, + 0xD4, 0xE5, 0x47, 0x7E, 0xCB, 0x3A, 0x91, 0x35, + 0xA4, 0x3C, 0xF0, 0x12, 0x79, 0x72, 0x76, 0xC3, + 0xA8, 0x27, 0x95, 0x81, 0x8B, 0xF8, 0x4A, 0xD4, + 0x51, 0xB4, 0xD8, 0x1A, 0x41, 0x6F, 0x77, 0x75, + 0xEF, 0x6D, 0xDB, 0x70, 0x07, 0xF3, 0xC8, 0x70, + 0xCD, 0x9C, 0x96, 0x1C, 0xE1, 0x50, 0xEE, 0xE3, + 0x5D, 0x3A, 0x79, 0xE6, 0xD4, 0xE7, 0x32, 0x85, + 0x00, 0x3A, 0xDF, 0xD6, 0x4D, 0x4A, 0x62, 0x7C, + 0x1E, 0xEE, 0xD1, 0x44, 0xF0, 0xBC, 0x7E, 0x60, + 0x76, 0x3C, 0xC6, 0x31, 0x40, 0x08, 0xFC, 0x37, + 0xFF, 0x6C, 0x23, 0x42, 0x92, 0xE7, 0x4C, 0xD7, + 0x0F, 0x53, 0x37, 0x58, 0x2E, 0x93, 0xF2, 0x93, + 0x92, 0x65, 0x69, 0xF1, 0x30, 0x8C, 0xEF, 0x1D, + 0x71, 0x3C, 0x81, 0x32, 0x65, 0x87, 0xB6, 0x63, + 0xC2, 0x8E, 0x05, 0x38, 0xF7, 0xE2, 0xDA, 0x21, + 0x26, 0x1D, 0xD4, 0x8E, 0xF5, 0x4D, 0x63, 0x47, + 0xAE, 0x10, 0x16, 0x42, 0x64, 0xC1, 0xBD, 0xEC, + 0xCB, 0xE4, 0x43, 0xEC, 0xB3, 0x7F, 0x15, 0x97, + 0x10, 0xD4, 0x1A, 0x0C, 0x98, 0x2E, 0x7D, 0x05, + 0x10, 0x33, 0x38, 0xDE, 0xA1, 0x40, 0x27, 0xC8, + 0xC0, 0xE7, 0xD8, 0x12, 0x07, 0xC7, 0xD5, 0x05, + 0x0A, 0xBE, 0x69, 0x89, 0x9F, 0x9B, 0xEC, 0xB2, + 0x7B, 0x44, 0x81, 0x5D, 0xE9, 0x92, 0xFD, 0x94, + 0x86, 0x24, 0x14, 0xC8, 0xCF, 0xA6, 0xB3, 0xA6, + 0xAA, 0xE4, 0x17, 0xC0, 0x08, 0x05, 0x68, 0xC7, + 0x7D, 0xC0, 0x42, 0x58, 0xC4, 0xAF, 0x02, 0xFB, + 0xF0, 0x1F, 0xF6, 0x9F, 0xBC, 0xE9, 0x5B, 0xBA, + 0xD6, 0x75, 0xB4, 0x15, 0x53, 0x88, 0x30, 0xD8, + 0xDA, 0x39, 0xE3, 0x9B, 0x12, 0x9E, 0x91, 0x06, + 0x30, 0xD2, 0x35, 0xF8, 0xCC, 0x75, 0xBA, 0x0A, + 0x66, 0x25, 0x35, 0x2B, 0xC9, 0x27, 0x91, 0x9F, + 0x65, 0x39, 0xFA, 0x21, 0x74, 0xC3, 0x85, 0xC7, + 0xE7, 0x23, 0x80, 0x04, 0x2C, 0x84, 0x90, 0x52, + 0x6D, 0x7E, 0x4B, 0x67, 0xE2, 0x49, 0xCE, 0x02, + 0x44, 0xC5, 0x71, 0xBD, 0x50, 0x58, 0x72, 0x21, + 0xC9, 0x1B, 0x03, 0x42, 0xA8, 0xEC, 0xF5, 0x00, + 0x2F, 0x5F, 0x49, 0x4A, 0x91, 0x9F, 0x24, 0x5E, + 0xBE, 0xC8, 0x70, 0xEE, 0xD5, 0xFA, 0xA2, 0x32, + 0x84, 0x89, 0xFE, 0x9A, 0x34, 0xA6, 0x50, 0x35, + 0x2E, 0xF8, 0x47, 0xD5, 0xDC, 0xDB, 0x36, 0x97, + 0xE4, 0x2B, 0xB9, 0xCA, 0xCB, 0x8B, 0x46, 0xA9, + 0x67, 0x5A, 0x68, 0xD8, 0x97, 0x13, 0x68, 0x20, + 0xEC, 0x6A, 0x56, 0x50, 0x6A, 0x87, 0xFB, 0xF5, + 0xD8, 0x5D, 0x76, 0x6B, 0x57, 0xE0, 0x2B, 0x5A, + 0xD6, 0xF1, 0x48, 0x92, 0x9F, 0xC4, 0x17, 0xE4, + 0x32, 0xE5, 0xB4, 0x08, 0x20, 0x8B, 0x63, 0x38, + 0xC6, 0x83, 0x6B, 0x9D, 0x2E, 0x20, 0x60, 0x85, + 0x2C, 0x3E, 0x15, 0xFB, 0x6C, 0x5D, 0x0A, 0xB0, + 0x8B, 0xC6, 0xAE, 0xE3, 0x36, 0xCF, 0xF5, 0x94, + 0xB6, 0x42, 0x24, 0x3A, 0x7E, 0xAA, 0x38, 0x27, + 0x20, 0xAE, 0x98, 0x13, 0x36, 0x3E, 0x32, 0x43, + 0x63, 0x83, 0x96, 0x8C, 0x5F, 0xF1, 0xD2, 0x81, + 0x4C, 0x57, 0xDF, 0xC7, 0x7B, 0xBC, 0x18, 0x0D, + 0xE1, 0xE3, 0x92, 0x9F, 0x8B, 0x3D, 0x80, 0x05, + 0x76, 0xAA, 0x89, 0x48, 0x71, 0xA4, 0xBB, 0x68, + 0x84, 0x6E, 0xE1, 0x44, 0x39, 0x74, 0xF6, 0xBD, + 0x3E, 0x48, 0x07, 0x15, 0xCD, 0xBD, 0xCF, 0x47, + 0xBF, 0x3A, 0x57, 0x57, 0x6C, 0x0C, 0x3C, 0xC0, + 0xF2, 0xB1, 0x02, 0xC1, 0xA5, 0x14, 0x21, 0xDC, + 0x6E, 0xC5, 0x16, 0xC5, 0xBF, 0xD2, 0x6E, 0x4F, + 0x97, 0x4E, 0x76, 0x87, 0x3A, 0x66, 0xF9, 0xAA, + 0x64, 0x77, 0x19, 0x36, 0xA0, 0x11, 0x05, 0x5D, + 0xD4, 0x2B, 0x1D, 0x83, 0x45, 0xFD, 0xB3, 0xF3, + 0xCB, 0x68, 0x80, 0x02, 0xD4, 0xF9, 0x55, 0x64, + 0x55, 0xC1, 0xDD, 0x31, 0xF8, 0x47, 0x5B, 0x07, + 0xD5, 0x0B, 0xBC, 0x00, 0x13, 0xC6, 0x34, 0x55, + 0x08, 0xD7, 0xD8, 0x71, 0xF9, 0x5A, 0x51, 0xD6, + 0x8C, 0xE1, 0x66, 0x27, 0x99, 0x67, 0x5C, 0x95, + 0x77, 0x14, 0x17, 0x28, 0xD8, 0xD0, 0x22, 0xDD, + 0xDC, 0x3E, 0x5C, 0x69, 0xCE, 0x39, 0x9D, 0x2D, + 0xE2, 0x19, 0x1E, 0x2B, 0xE8, 0x72, 0x22, 0xCF, + 0x13, 0x6F, 0x52, 0xE9, 0x36, 0xE1, 0x51, 0x16, + 0xAD, 0x2E, 0xCF, 0x19, 0x3A, 0x5A, 0xB0, 0xCD, + 0xC9, 0xD1, 0x69, 0x3A, 0x4E, 0x1D, 0xEA, 0x24, + 0xFB, 0x7B, 0x10, 0x84, 0x33, 0x7A, 0xED, 0x81, + 0x76, 0x74, 0x4E, 0x72, 0xB1, 0xEC, 0xE1, 0x3D, + 0x32, 0x35, 0xDC, 0x0A, 0x28, 0x17, 0xCF, 0x42, + 0x92, 0x81, 0x17, 0xF7, 0x2A, 0x46, 0x84, 0xF7, + 0xC4, 0xB4, 0xB1, 0x63, 0xAE, 0xF0, 0x13, 0xFE, + 0x00, 0xA9, 0x93, 0xC7, 0x72, 0x95, 0x8D, 0xE3, + 0x71, 0x4C, 0xAE, 0x74, 0x17, 0xB4, 0x6A, 0x4C, + 0xDF, 0x8E, 0x1E, 0x05, 0x9D, 0xF4, 0x59, 0x56, + 0xCB, 0xCF, 0x02, 0xE6, 0x4A, 0xC0, 0xE6, 0xC3, + 0x6B, 0xA6, 0x6B, 0xC7, 0x92, 0xA1, 0xAE, 0x3C, + 0xFD, 0x57, 0x93, 0x37, 0x8E, 0x9C, 0x49, 0xA1, + 0x8C, 0x81, 0xF7, 0x7F, 0x42, 0xB8, 0x44, 0xE1, + 0x95, 0xB0, 0x9D, 0x16, 0xA8, 0x10, 0x9D, 0xA6, + 0x09, 0x1B, 0x56, 0x5C, 0x64, 0x82, 0x54, 0x3E, + 0xD1, 0xCD, 0xF1, 0x35, 0x4C, 0xF7, 0xBD, 0xD2, + 0xC1, 0x97, 0xAD, 0xEE, 0xDD, 0xA9, 0xAD, 0x8B, + 0x79, 0x08, 0xDD, 0x24, 0x58, 0x2D, 0x28, 0x09, + 0xB2, 0xF0, 0x52, 0x25, 0xF1, 0xC4, 0x1E, 0x7C, + 0xE2, 0x99, 0x6C, 0xB5, 0x14, 0xE2, 0x67, 0x93, + 0x8C, 0x84, 0x56, 0x0E, 0x85, 0x84, 0xBA, 0x52, + 0x70, 0xB3, 0xBE, 0x2F, 0x19, 0x4F, 0xFC, 0xD9, + 0xB3, 0xF3, 0x02, 0xD5, 0x7F, 0x93, 0xF1, 0xBB, + 0xA2, 0x53, 0x93, 0x36, 0x3E, 0x6A, 0x44, 0xE3, + 0x5A, 0x2B, 0x32, 0x1D, 0x38, 0x65, 0x0A, 0x3E, + 0xED, 0x40, 0x0E, 0xFC, 0x2C, 0xCF, 0x95, 0xAA, + 0x36, 0x3E, 0x70, 0xF9, 0x45, 0xB9, 0x99, 0xED, + 0x9D, 0x5F, 0x68, 0x9F, 0x53, 0xA6, 0xDA, 0x4C, + 0xB4, 0x95, 0x6A, 0x9E, 0x64, 0xE3, 0x46, 0x24, + 0x59, 0xDD, 0x80, 0x9A, 0xE4, 0x2C, 0x2A, 0x8B, + 0xAF, 0x36, 0x10, 0x82, 0xDF, 0x7D, 0xD8, 0xAF, + 0xEE, 0xBB, 0xE6, 0x92, 0xFC, 0x2C, 0x98, 0xEF, + 0x67, 0x3F, 0xCF, 0xD0, 0xED, 0xC4, 0x51, 0x84, + 0xB7, 0x8F, 0x46, 0x73, 0x9E, 0x56, 0xE4, 0x8F, + 0x1D, 0x93, 0x87, 0x83, 0xFF, 0xC9, 0x14, 0x4F, + 0xEC, 0x5A, 0xAD, 0xE4, 0x0A, 0x76, 0x61, 0xF0, + 0x17, 0x37, 0xA0, 0xF1, 0x36, 0x3A, 0x72, 0x2E, + 0x6A, 0xF8, 0x4D, 0xD4, 0x9C, 0xA8, 0x09, 0x8C, + 0x6E, 0x26, 0xFD, 0x0D, 0x2D, 0xAF, 0xC0, 0x17, + 0x8E, 0x93, 0xC4, 0xBE, 0x1C, 0xBA, 0x7E, 0xC5, + 0x87, 0x73, 0x17, 0x70, 0x8D, 0xE6, 0xF1, 0xF6, + 0xBB, 0x1E, 0x68, 0xE8, 0x81, 0xF5, 0x99, 0xC0, + 0x35, 0x4B, 0x2B, 0xE0, 0x90, 0xD4, 0x55, 0xC0, + 0xBA, 0x67, 0xA7, 0xFA, 0x08, 0x63, 0xCD, 0xBC, + 0x98, 0xDB, 0x05, 0x56, 0x17, 0xD7, 0x90, 0xB7, + 0x22, 0x5A, 0x42, 0x5A, 0x21, 0x9D, 0xA4, 0xAF, + 0x9A, 0x20, 0x16, 0x30, 0x22, 0xF9, 0xF9, 0xBB, + 0x75, 0x7F, 0x62, 0xBB, 0xF5, 0xEB, 0x47, 0xEA, + 0x16, 0x88, 0x38, 0xEE, 0xE9, 0x1C, 0xF9, 0x0D, + 0x81, 0x2C, 0xE6, 0x1A, 0x51, 0x4C, 0x08, 0xBE, + 0xA2, 0xDF, 0x55, 0xA4, 0x6A, 0xD4, 0xF1, 0x1A, + 0x46, 0xF6, 0xE8, 0xC5, 0x61, 0xC8, 0xB7, 0xF7, + 0xAF, 0xA6, 0xF2, 0x56, 0xC3, 0xAF, 0x3F, 0x44, + 0x7D, 0xA7, 0xC7, 0xC3, 0x90, 0x6D, 0x87, 0x64, + 0x4F, 0xE9, 0x62, 0xE2, 0x87, 0x2D, 0xE5, 0x43, + 0x85, 0x36, 0x34, 0x37, 0x36, 0x20, 0x21, 0x0F, + 0xB6, 0x3E, 0xAC, 0x97, 0x4E, 0xF5, 0x85, 0x34, + 0x3E, 0x4C, 0xBE, 0xFA, 0xA9, 0xBB, 0xE2, 0x13, + 0x36, 0x52, 0x92, 0x51, 0x65, 0x18, 0xCA, 0xEA, + 0x83, 0x90, 0x7A, 0x04, 0xE6, 0xA7, 0xE2, 0xA7, + 0xD1, 0xC5, 0xCD, 0xF5, 0x55, 0xB4, 0x42, 0x1E, + 0x9B, 0x23, 0xC3, 0x01, 0x40, 0xFD, 0x24, 0xC0, + 0x07, 0x3B, 0xCE, 0x39, 0x9F, 0xAD, 0xD2, 0xE5, + 0x11, 0x77, 0xD0, 0x34, 0x96, 0x31, 0xBB, 0x8B, + 0xBD, 0xF7, 0xF9, 0x45, 0x17, 0xBB, 0x2F, 0x6D, + 0x8D, 0xF3, 0xC0, 0x04, 0xE1, 0xE1, 0x7F, 0x3F, + 0x09, 0xF0, 0xF3, 0x64, 0x48, 0xF8, 0xC6, 0x8A, + 0x97, 0x6E, 0x1E, 0x00, 0xB6, 0xC2, 0x9D, 0x10, + 0x41, 0xBC, 0x40, 0x5F, 0x2A, 0xFB, 0xC6, 0x4B, + 0x5D, 0x2D, 0xE8, 0x57, 0xF5, 0x08, 0x2B, 0xD3, + 0x38, 0x5A, 0x49, 0x6E, 0xF7, 0x8A, 0xFB, 0x49, + 0x27, 0xE2, 0x17, 0x68, 0x11, 0x0F, 0x5D, 0x6D, + 0xC3, 0xC5, 0x5C, 0x37, 0xE5, 0xBF, 0xF2, 0x8F, + 0xCF, 0xCA, 0xF9, 0x49, 0xED, 0x94, 0x2B, 0x53, + 0x11, 0x8A, 0xD7, 0x7E, 0x16, 0x0C, 0x0D, 0x4F, + 0xE4, 0x8B, 0x76, 0x98, 0xFD, 0x20, 0xEB, 0x6A, + 0x3E, 0x44, 0x0E, 0x79, 0x7C, 0x9F, 0xE1, 0xC1, + 0xDC, 0xE1, 0x54, 0x83, 0x7C, 0xDB, 0x0E, 0xE1, + 0x88, 0xB4, 0x30, 0xB0, 0x58, 0x72, 0x80, 0x05, + 0xA8, 0x19, 0x7B, 0x91, 0xFD, 0x94, 0x04, 0x66, + 0xBB, 0xC9, 0x9A, 0x7D, 0xB7, 0x91, 0x2D, 0xBC, + 0xE7, 0x48, 0xCF, 0x01, 0xE3, 0xCD, 0x2F, 0x2D, + 0x47, 0xDC, 0x66, 0x7C, 0xF9, 0x4B, 0x75, 0x53, + 0xBA, 0x04, 0x55, 0x7D, 0x93, 0xB8, 0xA7, 0xA5, + 0x95, 0xE8, 0x85, 0x97, 0x59, 0x70, 0xDD, 0xB0, + 0x1D, 0x50, 0x38, 0x06, 0xB8, 0xFA, 0xFF, 0xA5, + 0x83, 0x6F, 0xF9, 0x96, 0xF6, 0x7C, 0x4D, 0x88, + 0x7E, 0x0C, 0x1D, 0xC5, 0x5E, 0x71, 0x6B, 0x2E, + 0x27, 0x39, 0x19, 0xFA, 0xD0, 0x2F, 0xC5, 0x3F, + 0x1F, 0xDF, 0xE3, 0x64, 0xD5, 0x0E, 0xC3, 0xBD, + 0x1D, 0xE7, 0x0B, 0xF7, 0x69, 0x25, 0x2F, 0x75, + 0xB3, 0xF8, 0xD8, 0xD1, 0x59, 0xDF, 0x7B, 0x77, + 0x81, 0x76, 0x87, 0xA7, 0xF0, 0x7C, 0xDF, 0xEE, + 0xFC, 0xE0, 0x5B, 0x8E, 0xAF, 0x65, 0x80, 0x89, + 0xBF, 0x28, 0x7C, 0x2A, 0xDF, 0x7C, 0xD3, 0xE0, + 0x83, 0x20, 0xD5, 0x78, 0x82, 0xB8, 0x24, 0x4C, + 0x58, 0x40, 0xAB, 0xE0, 0xDB, 0x11, 0x5C, 0x65, + 0x03, 0xF2, 0x0F, 0xAF, 0x80, 0x9B, 0x40, 0x1C, + 0x95, 0x94, 0xE3, 0xE2, 0x83, 0xF8, 0xF5, 0x04, + 0xC9, 0x5A, 0xE9, 0x88, 0x96, 0x90, 0x8D, 0xE0, + 0x57, 0x19, 0x8E, 0xB5, 0x07, 0xA3, 0xBE, 0xBE, + 0x92, 0xB7, 0x5B, 0x87, 0x9F, 0x77, 0x36, 0x2C, + 0x2C, 0x39, 0xDE, 0x10, 0x8D, 0x88, 0x88, 0x41, + 0xA9, 0xB9, 0x4E, 0xC9, 0x6E, 0x54, 0xDF, 0x26, + 0xFC, 0xDB, 0xF2, 0xED, 0x2B, 0x89, 0x40, 0xE0, + 0x0C, 0x9F, 0xE5, 0xD0, 0x09, 0x4E, 0x26, 0xA8, + 0x46, 0x23, 0xC6, 0x73, 0x52, 0x9D, 0xB1, 0xE4, + 0x00, 0xE4, 0x17, 0x6C, 0x43, 0x23, 0xAD, 0x2B, + 0xF2, 0xF1, 0xD6, 0xE3, 0x4F, 0x7A, 0xE8, 0xCA, + 0x93, 0xFB, 0x8D, 0x01, 0xE2, 0xF7, 0x1C, 0x3E, + 0xB5, 0x36, 0xD8, 0x90, 0xEB, 0x15, 0xD6, 0x3B, + 0x47, 0x1B, 0xD1, 0xDE, 0xC3, 0xBC, 0xD0, 0x1D, + 0x8A, 0x06, 0xD4, 0x4A, 0xB6, 0x6D, 0x0B, 0xEC, + 0x54, 0xA7, 0xF4, 0xCF, 0xBA, 0x87, 0xEE, 0xB3, + 0x49, 0x3F, 0x72, 0x14, 0x88, 0xA1, 0xB8, 0x99, + 0xCE, 0x71, 0xF6, 0xD8, 0x44, 0x94, 0x08, 0x12, + 0xD9, 0xC1, 0xB3, 0x3B, 0x24, 0xB3, 0x67, 0xB2, + 0x84, 0x46, 0xC1, 0x77, 0x44, 0x9B, 0xF1, 0x3B, + 0x52, 0xA2, 0x1E, 0xF7, 0x72, 0xDB, 0x98, 0x3C, + 0xDF, 0xB4, 0xD8, 0x31, 0xC7, 0x8D, 0x50, 0x6F, + 0x9B, 0x81, 0x0B, 0x65, 0xC0, 0xE1, 0xB7, 0x4A, + 0x49, 0x9B, 0x66, 0x4B, 0x24, 0xDE, 0xFB, 0x64, + 0xAA, 0xEB, 0xCE, 0xF1, 0x46, 0x4E, 0x58, 0x82, + 0x70, 0x9D, 0xF2, 0x09, 0x56, 0x66, 0x61, 0x01, + 0x02, 0xE0, 0x12, 0xD8, 0xDE, 0x2D, 0x4B, 0xAE, + 0x93, 0xBD, 0x6E, 0x19, 0xA5, 0x4B, 0x0D, 0xD9, + 0x02, 0x2F, 0xD3, 0x6E, 0xF1, 0xB2, 0x6E, 0x77, + 0x55, 0xA4, 0xBD, 0x75, 0x88, 0x68, 0x0C, 0x51, + 0xB9, 0x48, 0x50, 0x9C, 0x94, 0x64, 0x79, 0xFA, + 0xD3, 0xC4, 0x54, 0x42, 0x04, 0x74, 0xC3, 0x08, + 0x10, 0x90, 0xE9, 0x83, 0x13, 0x4F, 0x4D, 0xE4, + 0x88, 0x43, 0x9B, 0x56, 0x8D, 0xB7, 0x64, 0xB2, + 0x70, 0xF8, 0xC1, 0x4B, 0x98, 0xF9, 0xFC, 0x83, + 0x04, 0xA3, 0x46, 0xE4, 0xC2, 0x93, 0xD3, 0x0A, + 0x11, 0xD1, 0x93, 0xF3, 0x09, 0x2D, 0x01, 0xD7, + 0xA3, 0x3A, 0x85, 0xD4, 0xD7, 0xD8, 0xA2, 0x32, + 0xC3, 0xD9, 0xA2, 0x50, 0xDD, 0xE5, 0xC1, 0x41, + 0x55, 0x6E, 0xC6, 0x1C, 0x67, 0x28, 0xA2, 0xE2, + 0x99, 0x20, 0x9E, 0x1C, 0x9A, 0x88, 0x29, 0x46, + 0x46, 0x78, 0x6D, 0xEC, 0x48, 0x87, 0xF9, 0x5B, + 0xA7, 0xAC, 0xE7, 0x94, 0x0F, 0xFC, 0x69, 0x5D, + 0xC8, 0x40, 0xA3, 0x5C, 0xB4, 0x5B, 0x59, 0x61, + 0x83, 0x65, 0xBC, 0xB9, 0x7A, 0xC7, 0xFF, 0xED, + 0xA0, 0xA4, 0x3C, 0xC0, 0x15, 0x27, 0x30, 0x46, + 0xAD, 0x34, 0x5C, 0x7D, 0x94, 0x5C, 0x4E, 0xEB, + 0x1E, 0x9D, 0x51, 0xAF, 0xF5, 0xA3, 0xA6, 0x0C, + 0x08, 0xDA, 0xDB, 0x7E, 0x43, 0x72, 0xDF, 0xAF, + 0x39, 0x1D, 0x29, 0x2E, 0x15, 0xC9, 0xBE, 0x1E, + 0x07, 0x1D, 0x11, 0xD3, 0xAC, 0x79, 0xE5, 0xFF, + 0x19, 0xB2, 0xFA, 0xD6, 0x44, 0x69, 0xB6, 0xBC, + 0x39, 0x4B, 0x8B, 0x3D, 0x81, 0x22, 0xB5, 0x37, + 0x3F, 0x7F, 0xD6, 0x29, 0x13, 0xA2, 0x01, 0x3A, + 0xB0, 0xC6, 0xE0, 0x57, 0x33, 0x2B, 0x70, 0xFF, + 0xB2, 0x2C, 0xD1, 0xC9, 0xCB, 0x04, 0xE3, 0x8C, + 0x04, 0x07, 0x81, 0xF6, 0xEB, 0x16, 0x1E, 0xDA, + 0xA1, 0x0A, 0xB8, 0x7E, 0xE8, 0xAB, 0x48, 0xF7, + 0x55, 0xFA, 0xED, 0xD1, 0xC1, 0x17, 0x7A, 0x22, + 0x42, 0x6C, 0x8F, 0x76, 0x65, 0x66, 0x21, 0xEB, + 0xB5, 0x2B, 0x40, 0x12, 0x37, 0xD3, 0xFC, 0x59, + 0x26, 0x1A, 0x49, 0xF1, 0xB2, 0x29, 0xB7, 0xA3, + 0xBB, 0x5A, 0xB3, 0x9C, 0x6B, 0x5B, 0x2B, 0x84, + 0xA8, 0x25, 0xF9, 0x95, 0x7A, 0xDD, 0xAA, 0x6F, + 0x04, 0xC8, 0x02, 0xA4, 0x57, 0xA3, 0x6C, 0xEC, + 0xB5, 0x68, 0x5B, 0xBF, 0x4A, 0x23, 0xB0, 0xCC, + 0x91, 0x21, 0xDA, 0x32, 0x8F, 0x24, 0x93, 0xF3, + 0x4B, 0xC3, 0xCA, 0xAF, 0xB0, 0xD7, 0x59, 0x5B, + 0x70, 0x79, 0x48, 0x84, 0x51, 0xC1, 0x0F, 0xF7, + 0xAC, 0x37, 0x8F, 0xA6, 0x8E, 0x0E, 0x71, 0xE3, + 0xAB, 0xA5, 0x80, 0x18, 0x07, 0xE7, 0x8A, 0x95, + 0x2E, 0x2E, 0xC5, 0xD0, 0xAD, 0x11, 0x7D, 0x9B, + 0xA5, 0xBD, 0x6E, 0x74, 0x61, 0x17, 0xFA, 0x89, + 0x9C, 0x53, 0x7A, 0xB8, 0xC1, 0x8E, 0x26, 0xF3, + 0x5B, 0xC3, 0x10, 0x05, 0x72, 0x5A, 0x04, 0x6D, + 0x57, 0xD6, 0x15, 0x48, 0xBA, 0x4C, 0xAF, 0x9C, + 0xCC, 0x8F, 0x2C, 0xC4, 0x02, 0x6C, 0xF8, 0xF5, + 0x02, 0x03, 0x96, 0x5E, 0xF6, 0x04, 0xB7, 0x8E, + 0xF7, 0x1D, 0x31, 0x39, 0x27, 0xAA, 0x30, 0xF3, + 0xEA, 0xED, 0x8C, 0x04, 0xFF, 0x6A, 0x22, 0x94, + 0x0A, 0x50, 0x14, 0x2F, 0x6B, 0xF4, 0xFF, 0x97, + 0xAB, 0x1A, 0xCF, 0x82, 0x02, 0x47, 0x58, 0x55, + 0xF8, 0xE7, 0x87, 0x82, 0xFE, 0x1F, 0x39, 0xCF, + 0xF9, 0x96, 0x11, 0x7D, 0xE4, 0xA9, 0x3F, 0x18, + 0xA0, 0x54, 0xEB, 0xEC, 0x23, 0x10, 0x72, 0x77, + 0x98, 0xF7, 0x9C, 0xFF, 0x19, 0xB0, 0x2E, 0x34, + 0x38, 0xC3, 0x40, 0x53, 0x3B, 0xCA, 0xC6, 0xF8, + 0x2A, 0xCC, 0xC1, 0x0D, 0x31, 0x7B, 0xB9, 0x39, + 0xB1, 0x3C, 0xEC, 0x1D, 0xC4, 0x81, 0x86, 0x80, + 0x09, 0x86, 0xF5, 0x26, 0x0F, 0x83, 0x79, 0xA3, + 0xAF, 0x93, 0x3B, 0x6F, 0x7A, 0xCD, 0xBD, 0x40, + 0x6C, 0xCA, 0x48, 0x54, 0x30, 0xB3, 0x2B, 0xA6, + 0x06, 0x8B, 0x41, 0xF4, 0x5D, 0x7B, 0x78, 0xDF, + 0x6C, 0x36, 0x6F, 0x59, 0x82, 0x67, 0xCA, 0x81, + 0x94, 0x01, 0xBB, 0x97, 0x98, 0x25, 0xF5, 0x1D, + 0x23, 0xAC, 0xAE, 0x04, 0x43, 0x8D, 0xE5, 0xBE, + 0xD5, 0xAF, 0xEC, 0x31, 0x5E, 0x0A, 0xCD, 0xE3, + 0x55, 0x53, 0xCF, 0x2A, 0x87, 0x45, 0x1B, 0x94, + 0xAB, 0x55, 0x4D, 0x7B, 0x32, 0xB2, 0x01, 0xB6, + 0xEC, 0x19, 0xE7, 0xA0, 0xFC, 0x31, 0xD9, 0x10, + 0x8A, 0x0F, 0xDA, 0xC2, 0x9F, 0x46, 0xBF, 0x75, + 0x86, 0x30, 0x29, 0x33, 0xF4, 0x27, 0xE6, 0xC9, + 0xA2, 0x3F, 0x49, 0xF0, 0x4C, 0xFE, 0x30, 0x9D, + 0x03, 0x76, 0x4A, 0x63, 0xF2, 0x34, 0x1E, 0x10, + 0x97, 0xB1, 0x10, 0x40, 0xFC, 0x4F, 0x79, 0x98, + 0x50, 0xC4, 0xA3, 0x93, 0xBE, 0x4D, 0xC7, 0xB9, + 0xBE, 0xB4, 0x6E, 0x8A, 0xF4, 0x00, 0xDE, 0x64, + 0x5A, 0xD4, 0xB9, 0xCB, 0xCC, 0x9B, 0xD9, 0xC3, + 0x98, 0x07, 0x48, 0xB5, 0x15, 0xD5, 0x6C, 0x82, + 0x42, 0x56, 0x6C, 0x9D, 0x03, 0x39, 0xE6, 0x36, + 0x5D, 0xE9, 0xA1, 0x97, 0x3E, 0x88, 0xB0, 0xBA, + 0x9E, 0xF9, 0x60, 0xAC, 0x68, 0x81, 0x97, 0x3D, + 0xFC, 0xF5, 0x42, 0x24, 0x07, 0x0D, 0xE2, 0xC0, + 0xCC, 0x99, 0x2E, 0x2C, 0x69, 0xFA, 0xC8, 0x6F, + 0x24, 0xEB, 0xEA, 0xCB, 0x05, 0x45, 0xF9, 0x2D, + 0x65, 0x50, 0x7C, 0x60, 0xFB, 0x21, 0xBD, 0xB8, + 0x53, 0x34, 0x36, 0x8B, 0x03, 0xB0, 0x31, 0x03, + 0x9F, 0x78, 0xC6, 0x68, 0x07, 0x2E, 0x62, 0xF2, + 0xF7, 0x99, 0xCE, 0xC3, 0x0E, 0x5A, 0xCB, 0xD3, + 0x19, 0x22, 0xBC, 0xA4, 0x45, 0xF5, 0x25, 0xA2, + 0xCE, 0x21, 0xE9, 0x4E, 0x0D, 0x86, 0x98, 0xE8, + 0x7F, 0xAD, 0x18, 0x84, 0x7C, 0x30, 0x60, 0x62, + 0x98, 0x74, 0xA2, 0x39, 0x0F, 0x18, 0x22, 0xAD, + 0xCE, 0xE8, 0x97, 0xBB, 0x51, 0x3D, 0x92, 0x7E, + 0x63, 0x96, 0x22, 0xC1, 0xF3, 0x7E, 0x0A, 0x12, + 0x1F, 0xDD, 0x12, 0x20, 0xD8, 0x89, 0x4C, 0x92, + 0x0C, 0x13, 0x4F, 0xB2, 0x04, 0x90, 0xF0, 0x19, + 0x6A, 0x41, 0x97, 0x4B, 0xA2, 0xC5, 0x0C, 0x13, + 0x1D, 0xEC, 0x04, 0x46, 0xFB, 0xAE, 0xD9, 0x0E, + 0x1E, 0x93, 0x94, 0x66, 0x95, 0x78, 0x05, 0x98, + 0xC0, 0x29, 0x2F, 0x43, 0x50, 0xD7, 0x08, 0xB5, + 0x20, 0x14, 0xFE, 0x5F, 0xAC, 0x9E, 0xA3, 0xFD, + 0xF2, 0x22, 0x85, 0x26, 0x2E, 0x47, 0x60, 0xA9, + 0xE7, 0xA2, 0xB8, 0x7E, 0xB0, 0x47, 0x4D, 0x0E, + 0xD7, 0x15, 0x2E, 0xF6, 0x4B, 0x69, 0x78, 0xE1, + 0xDF, 0xD9, 0xDA, 0x54, 0x0E, 0x45, 0x13, 0xC3, + 0xBC, 0x3F, 0x98, 0x93, 0xD7, 0xBD, 0x3E, 0xA8, + 0xC4, 0x06, 0x80, 0x88, 0x2D, 0x1D, 0x7D, 0x78, + 0x0B, 0x7E, 0x12, 0x20, 0xBD, 0xB3, 0x73, 0xD5, + 0xD7, 0xBF, 0xC7, 0x78, 0x9E, 0xD4, 0x12, 0xF5, + 0x8A, 0x29, 0x87, 0x10, 0x7A, 0xD3, 0x68, 0x3D, + 0xC4, 0xA6, 0x96, 0x6E, 0xBC, 0x8C, 0x41, 0xE2, + 0x3B, 0x36, 0xDB, 0x30, 0xCE, 0x8D, 0x28, 0x5C, + 0x88, 0x68, 0x13, 0xC3, 0xAE, 0xC5, 0xC4, 0x07, + 0xA3, 0x57, 0x26, 0x93, 0x17, 0x98, 0xF9, 0xDA, + 0x55, 0xEF, 0xD3, 0x95, 0xC8, 0x23, 0xA0, 0x2E, + 0x3A, 0x94, 0xE8, 0xF4, 0x16, 0x30, 0x1D, 0x0B, + 0x0F, 0x45, 0x05, 0x98, 0x55, 0x5F, 0xAF, 0xA1, + 0xCF, 0x66, 0x24, 0x9C, 0xCD, 0x75, 0xFD, 0xE2, + 0xEA, 0xED, 0x35, 0x8D, 0x79, 0xE9, 0x01, 0xCA, + 0xD2, 0x32, 0x63, 0x9C, 0xB2, 0x9B, 0x5E, 0x37, + 0xAA, 0xA1, 0x2C, 0x29, 0xFB, 0x1B, 0xA3, 0x62, + 0x2D, 0x43, 0x1E, 0x65, 0xD3, 0x94, 0xAA, 0xD6, + 0x06, 0xA1, 0xE4, 0x82, 0xE4, 0x45, 0x59, 0x90, + 0x60, 0x31, 0x2B, 0x7A, 0x40, 0x2E, 0xD4, 0x2A, + 0x95, 0x96, 0x5F, 0x37, 0x4A, 0xA8, 0xF1, 0xF2, + 0xCA, 0x49, 0x58, 0x09, 0xC7, 0xDC, 0xC3, 0x30, + 0x1A, 0xBF, 0x2F, 0x70, 0x20, 0x54, 0xF3, 0x06, + 0xCD, 0x16, 0x3C, 0xC1, 0x27, 0x23, 0x1D, 0x7C, + 0x2D, 0x39, 0x2E, 0x72, 0xEF, 0xBD, 0xAF, 0x1D, + 0x56, 0xD9, 0x32, 0xFE, 0x86, 0xD0, 0x78, 0x95, + 0x83, 0xA1, 0x95, 0x26, 0xEB, 0x30, 0xD6, 0xF9, + 0x00, 0xDB, 0x50, 0xBC, 0x71, 0xAE, 0x8C, 0xE5, + 0xDD, 0xB1, 0xB8, 0xA1, 0x9D, 0xC7, 0x34, 0x65, + 0x55, 0x16, 0xE8, 0xD1, 0x1D, 0x9C, 0x9B, 0x83, + 0x7B, 0x77, 0x9B, 0x60, 0x0E, 0xD5, 0xBE, 0xF4, + 0xD6, 0xC1, 0xC9, 0xA0, 0x06, 0x27, 0x00, 0xFB, + 0xBE, 0xC9, 0x1A, 0x5A, 0xF6, 0xC7, 0xF5, 0x1D, + 0xC9, 0x95, 0x46, 0x6B, 0x43, 0xDA, 0x1B, 0x51, + 0x55, 0x91, 0xB4, 0x85, 0xF4, 0xBA, 0x3A, 0xC1, + 0x59, 0x41, 0x0F, 0xF0, 0x37, 0x36, 0x3D, 0x11, + 0x8D, 0x72, 0xCA, 0xB0, 0xCE, 0xAD, 0xF5, 0xDC, + 0xB3, 0x9D, 0xD2, 0xB5, 0x39, 0x97, 0xD6, 0x10, + 0x8A, 0x68, 0x30, 0x4B, 0xD2, 0xB5, 0xC6, 0xD9, + 0xCB, 0x32, 0xAB, 0xA2, 0x19, 0xE1, 0xC9, 0x55, + 0x65, 0x3C, 0x0E, 0x5B, 0x32, 0x4D, 0x2A, 0xA6, + 0x8F, 0xEF, 0xA0, 0x72, 0x6F, 0xC7, 0x23, 0x4A, + 0xE2, 0x36, 0x70, 0xA6, 0xE0, 0xB9, 0xA9, 0x4D, + 0xBC, 0x96, 0x95, 0x20, 0xE3, 0x3D, 0xE4, 0x45, + 0x5F, 0x96, 0x9E, 0x54, 0x96, 0x06, 0x84, 0xE6, + 0xDA, 0x10, 0xA7, 0x14, 0x9F, 0x87, 0xE1, 0xDE, + 0xD0, 0x78, 0x8A, 0x2F, 0x32, 0x3A, 0xBD, 0x9E, + 0x72, 0xFD, 0x7D, 0xA9, 0xF2, 0x9E, 0x21, 0x19, + 0xFD, 0x2B, 0x26, 0x2E, 0xB9, 0x65, 0xE0, 0xA0, + 0x51, 0xC0, 0x50, 0x7D, 0xED, 0xFD, 0x64, 0x7F, + 0xC0, 0x12, 0xCA, 0x61, 0xC0, 0x1D, 0xD4, 0x06, + 0x47, 0xDF, 0x79, 0x61, 0x70, 0xE3, 0x99, 0x62, + 0xBE, 0x6B, 0x60, 0xC3, 0x01, 0x5B, 0x98, 0xE4, + 0x9B, 0xF1, 0x8E, 0x91, 0xF3, 0x14, 0x01, 0x01, + 0xDB, 0x4A, 0xC7, 0xFB, 0x56, 0x70, 0xBF, 0x93, + 0xE3, 0xB1, 0x05, 0x02, 0x9E, 0x77, 0x8A, 0xBA, + 0xF8, 0x72, 0x3C, 0x0C, 0x6E, 0xC8, 0x9B, 0x7A, + 0x90, 0x0D, 0x98, 0xF8, 0x84, 0xC0, 0x41, 0x54, + 0x35, 0x00, 0x7D, 0xE9, 0x7D, 0x40, 0xC8, 0x66, + 0x4F, 0x7C, 0xA1, 0xBE, 0x2C, 0xD0, 0x08, 0x12, + 0xFB, 0x3C, 0x62, 0xB9, 0x6C, 0xA0, 0x5E, 0xCE, + 0x70, 0xBE, 0xE4, 0x6B, 0x05, 0xBD, 0x16, 0x76, + 0x1B, 0x16, 0xCD, 0x38, 0x15, 0xB0, 0x16, 0x2D, + 0x18, 0x44, 0x40, 0xF2, 0x43, 0xFE, 0x72, 0x34, + 0xA9, 0xAA, 0x28, 0x23, 0xAA, 0xA5, 0xEC, 0xB2, + 0x1A, 0xD6, 0x83, 0xAD, 0x86, 0x0A, 0x58, 0x13, + 0x72, 0x0F, 0x16, 0xD0, 0x39, 0xE4, 0x17, 0x78, + 0x09, 0xDC, 0xC0, 0xB5, 0xFD, 0xCC, 0x32, 0xD9, + 0x52, 0x92, 0xBF, 0x9A, 0xE3, 0xE9, 0xA6, 0xC8, + 0x62, 0x9D, 0xCC, 0x20, 0xE9, 0x9A, 0xF2, 0x4E, + 0xE0, 0x3B, 0x8B, 0x87, 0x36, 0x38, 0x97, 0x89, + 0xE8, 0x7E, 0xC2, 0x74, 0x54, 0x56, 0xB8, 0x3E, + 0x34, 0xDC, 0xC2, 0xCB, 0x99, 0x85, 0x5E, 0x8E, + 0xF5, 0xD3, 0xEE, 0x14, 0x6F, 0x46, 0x4F, 0x0E, + 0x8A, 0x11, 0x51, 0x43, 0x77, 0xAA, 0x0C, 0x2B, + 0xD2, 0xE2, 0xF7, 0x32, 0x39, 0x96, 0x2A, 0x7B, + 0x23, 0xE2, 0x02, 0xF8, 0xFA, 0x8C, 0xE9, 0xDB, + 0x5C, 0x94, 0x64, 0xD0, 0xD1, 0x9C, 0xC6, 0xE5, + 0x73, 0x2C, 0x0D, 0x60, 0xB3, 0x15, 0x35, 0x63, + 0x6D, 0xC2, 0xCA, 0xA1, 0x1B, 0x4F, 0x48, 0x0B, + 0x72, 0x69, 0xE7, 0x56, 0x1D, 0x07, 0x50, 0xAC, + 0x77, 0xD1, 0x95, 0x5A, 0xAB, 0x6D, 0x78, 0x00, + 0x8D, 0xE3, 0x5C, 0x47, 0x69, 0x3B, 0x78, 0x01, + 0x2C, 0x63, 0x55, 0xDF, 0x90, 0xAD, 0xAF, 0xF8, + 0xD4, 0x73, 0xDD, 0x5A, 0xD7, 0x26, 0x37, 0xF2, + 0x4B, 0x5B, 0x19, 0xCF, 0x6C, 0xD3, 0xEE, 0x54, + 0xA6, 0x04, 0x3A, 0x26, 0x13, 0xF0, 0xCA, 0x2C, + 0xA3, 0x2D, 0x05, 0x65, 0x84, 0xB5, 0x41, 0x84, + 0x71, 0x15, 0xEF, 0xEB, 0x10, 0xF9, 0xD2, 0x17, + 0x7D, 0x21, 0xFD, 0x52, 0x4A, 0xC0, 0x43, 0x0E, + 0xCB, 0xFF, 0xD7, 0x4E, 0x82, 0xCE, 0x89, 0x8E, + 0xCF, 0x57, 0x60, 0x0C, 0xC6, 0xFC, 0xA6, 0x03, + 0x9F, 0x43, 0x59, 0xFF, 0x26, 0x87, 0xD1, 0x38, + 0xD0, 0x36, 0x83, 0xEB, 0x8E, 0x30, 0x86, 0x19, + 0xB1, 0x17, 0x3C, 0x81, 0xAF, 0xF4, 0xDE, 0xE3, + 0x71, 0x3A, 0xE5, 0x9A, 0xFC, 0x02, 0x54, 0xF7, + 0xF5, 0x0D, 0x64, 0x4A, 0x2A, 0xB7, 0xA1, 0x56, + 0xDB, 0x23, 0xE0, 0x12, 0xD9, 0xA4, 0x9E, 0x97, + 0x36, 0xDA, 0x65, 0x5B, 0x1A, 0xF1, 0x77, 0x4D, + 0x25, 0x35, 0x13, 0xE8, 0x55, 0xEC, 0x43, 0x99, + 0x76, 0x96, 0x02, 0xBC, 0x0B, 0x34, 0x26, 0xC3, + 0x25, 0x75, 0x6D, 0x38, 0x52, 0x2A, 0x9F, 0x6B, + 0x69, 0xB8, 0xCD, 0x87, 0x8A, 0x2B, 0xFF, 0x2F, + 0xDD, 0xE7, 0x69, 0xF6, 0x8E, 0x86, 0x27, 0xFA, + 0xCC, 0x2F, 0xDC, 0x66, 0x92, 0xE9, 0x15, 0x2B, + 0x65, 0xF3, 0x86, 0xF1, 0x51, 0x67, 0x55, 0xA0, + 0x58, 0x88, 0x08, 0xC9, 0x43, 0x29, 0xBB, 0x08, + 0xBF, 0x5C, 0x19, 0x98, 0xB9, 0x58, 0x78, 0xF2, + 0x3B, 0x20, 0xDA, 0x1F, 0x8C, 0x78, 0xAC, 0x13, + 0xF0, 0xDA, 0xFA, 0x42, 0x05, 0xFF, 0x19, 0x73, + 0x7D, 0x1A, 0xB1, 0x4A, 0x53, 0xDC, 0x0E, 0xE0, + 0x1C, 0x93, 0xD5, 0x7A, 0x14, 0x9A, 0xD3, 0x1E, + 0x6D, 0x00, 0x51, 0xC5, 0x1B, 0xEC, 0xFD, 0x23, + 0x41, 0xD3, 0xDF, 0x47, 0xF5, 0x8F, 0x82, 0xF5, + 0x17, 0xA6, 0x7D, 0x19, 0xB1, 0x00, 0xFF, 0x01, + 0xE2, 0x7A, 0xBF, 0xF4, 0x64, 0xC6, 0x3C, 0xBA, + 0x67, 0xA8, 0x71, 0x59, 0xF7, 0xFD, 0x90, 0xCC, + 0x9F, 0x60, 0x99, 0x47, 0x13, 0x7B, 0xDF, 0x2B, + 0xFA, 0xD8, 0xBB, 0x1E, 0x0D, 0x34, 0x5B, 0x16, + 0x83, 0x32, 0x60, 0x5E, 0x47, 0xE0, 0x62, 0x0A, + 0xB2, 0x14, 0x58, 0x77, 0x7B, 0xF9, 0x30, 0x79, + 0x66, 0x30, 0xB2, 0x5D, 0x42, 0xA1, 0x31, 0xA1, + 0xAA, 0x18, 0xE2, 0xFE, 0x73, 0x78, 0x8A, 0x47, + 0xDA, 0xDB, 0xA9, 0x05, 0x75, 0xEE, 0xAE, 0x74, + 0x85, 0x55, 0xC4, 0x4C, 0x3A, 0x47, 0x13, 0xD8, + 0xCA, 0x82, 0x66, 0x0A, 0x6E, 0x6B, 0x42, 0xD5, + 0x95, 0x4D, 0xF1, 0x79, 0x80, 0x13, 0x14, 0x4F, + 0xDA, 0x44, 0x49, 0x47, 0x71, 0x7A, 0x5A, 0xF1, + 0x61, 0xB9, 0x9C, 0xB1, 0x52, 0xDE, 0x3C, 0xC9, + 0xAE, 0x80, 0x9E, 0xC0, 0x3C, 0xD0, 0x74, 0x42, + 0x17, 0xAE, 0x4C, 0x04, 0x3A, 0x0B, 0xAA, 0x31, + 0x24, 0x12, 0xBB, 0x4E, 0x21, 0x8E, 0x36, 0x41, + 0xA0, 0x3A, 0xCA, 0xCF, 0x8B, 0xC6, 0x64, 0x25, + 0xDE, 0x55, 0x75, 0xEA, 0x23, 0x8F, 0x16, 0x37, + 0x78, 0x16, 0xC7, 0xB5, 0xA0, 0xB1, 0xB3, 0x70, + 0x0D, 0xB2, 0x90, 0xB9, 0x51, 0x27, 0x96, 0xF2, + 0x86, 0xBD, 0x3C, 0x8C, 0xBD, 0x47, 0x36, 0xC5, + 0xE7, 0xB6, 0xF0, 0x13, 0x74, 0xA9, 0x77, 0x63, + 0x33, 0x5D, 0xF3, 0x35, 0xA9, 0x9F, 0x47, 0x1A, + 0x37, 0x4B, 0x06, 0x0F, 0xFA, 0x06, 0xFD, 0x28, + 0x09, 0x96, 0x33, 0xEE, 0x6E, 0xC2, 0x44, 0xCA, + 0x26, 0x8D, 0xC1, 0x3D, 0x09, 0x23, 0x79, 0xCB, + 0x28, 0xEB, 0x58, 0x3B, 0x6B, 0xEC, 0x69, 0xF1, + 0x29, 0x30, 0x15, 0x26, 0x2F, 0xAE, 0x0C, 0x61, + 0xF6, 0xF0, 0x43, 0x34, 0x9F, 0xAA, 0xB8, 0xA2, + 0xE6, 0x40, 0x10, 0x74, 0xF7, 0x25, 0x70, 0xD3, + 0x95, 0xF3, 0x3C, 0x11, 0x91, 0x72, 0x2C, 0xF7, + 0xE9, 0x49, 0xA6, 0x7A, 0x8A, 0x42, 0xCC, 0x78, + 0xE0, 0x09, 0x04, 0x50, 0x7A, 0x8E, 0x6E, 0x08, + 0xEB, 0x46, 0xB5, 0x9B, 0x21, 0xD3, 0x2D, 0x98, + 0x73, 0x62, 0x48, 0x5A, 0x07, 0x82, 0x94, 0xDD, + 0xF6, 0x35, 0x0E, 0xD8, 0xCC, 0x05, 0x5B, 0x21, + 0xBB, 0x3A, 0x4B, 0x6B, 0x78, 0xCB, 0x6B, 0x7B, + 0xD6, 0x4B, 0xE7, 0x0F, 0x8A, 0xD3, 0x65, 0x19, + 0xF0, 0x62, 0xD8, 0xBB, 0x57, 0xFB, 0x87, 0x27, + 0xA6, 0x03, 0x4E, 0xC1, 0x5D, 0x99, 0x4B, 0x0D, + 0x77, 0x4A, 0x2C, 0xB7, 0x3B, 0x71, 0x44, 0x62, + 0x37, 0x43, 0x3B, 0xC5, 0xA0, 0x26, 0xC8, 0x50, + 0xEE, 0x7D, 0x0D, 0x8C, 0xAF, 0x5D, 0xE1, 0x24, + 0xF1, 0x41, 0xED, 0x60, 0x50, 0x1B, 0x4B, 0xC7, + 0xEB, 0x5F, 0x94, 0x9E, 0xAC, 0xBA, 0x93, 0x02, + 0x0B, 0x09, 0x2C, 0x2D, 0x7B, 0x2D, 0x6F, 0x4E, + 0xEA, 0x3F, 0x2B, 0x57, 0x0B, 0x90, 0x11, 0xDA, + 0xF2, 0xA3, 0x97, 0x84, 0x78, 0x78, 0x7C, 0x80, + 0x16, 0xEE, 0x5D, 0x10, 0xA5, 0xB9, 0xF2, 0xFB, + 0xB3, 0x77, 0x92, 0xB8, 0xD4, 0x8B, 0xCD, 0x01, + 0x5E, 0x57, 0xBF, 0xA4, 0x21, 0x30, 0x1C, 0xF0, + 0xCB, 0xCE, 0x0D, 0x8D, 0x0D, 0xA2, 0x31, 0x4C, + 0xF9, 0xAA, 0xC7, 0x12, 0x03, 0xA3, 0x68, 0x58, + 0x7E, 0x90, 0x3C, 0xF9, 0xF6, 0x4E, 0x30, 0x7C, + 0xDB, 0x7D, 0x62, 0x56, 0xB7, 0xE2, 0x0A, 0x3C, + 0x59, 0xB3, 0xD0, 0x20, 0x08, 0xF6, 0x62, 0x18, + 0x4F, 0xF8, 0xF4, 0xD6, 0x14, 0xE5, 0xB3, 0x28, + 0xA8, 0xD3, 0x1E, 0xFD, 0xC2, 0x5E, 0x74, 0x7C, + 0xF2, 0x30, 0xE2, 0x9A, 0xA1, 0x7D, 0x33, 0xA3, + 0xCA, 0xF1, 0x1C, 0x92, 0x91, 0xF6, 0xEF, 0xB2, + 0x40, 0xBF, 0x41, 0x65, 0xEF, 0x4E, 0xE8, 0x41, + 0xFA, 0xA9, 0x13, 0xB9, 0x7A, 0xC5, 0xBC, 0xDA, + 0x79, 0xBD, 0x8C, 0xFC, 0x5F, 0x05, 0x30, 0x47, + 0xAE, 0x38, 0x6B, 0x8E, 0x00, 0x76, 0xA5, 0x6F, + 0x42, 0x57, 0x71, 0xA7, 0xE3, 0x07, 0xBB, 0x30, + 0x0D, 0x8F, 0x9E, 0xE5, 0x94, 0xBC, 0xB3, 0x16, + 0xF5, 0x10, 0x92, 0xDE, 0x9F, 0xDC, 0x99, 0x55, + 0xB6, 0xD6, 0xFE, 0xD6, 0x15, 0x2F, 0xEE, 0x24, + 0xAF, 0xE3, 0xDE, 0x5F, 0x91, 0xC6, 0xAA, 0x4A, + 0xD2, 0x0C, 0x39, 0x00, 0x12, 0x52, 0xED, 0x5F, + 0x07, 0xE3, 0x65, 0x92, 0xA4, 0x7B, 0x33, 0x7A, + 0x0F, 0x4B, 0x2D, 0xE7, 0x4E, 0x69, 0x6A, 0x51, + 0x73, 0x1A, 0x50, 0x37, 0x6E, 0x5C, 0x16, 0x50, + 0xBC, 0x5A, 0x22, 0x8B, 0x2B, 0xCD, 0x2C, 0xFD, + 0x69, 0x37, 0x42, 0x30, 0x44, 0x51, 0x88, 0x85, + 0xB5, 0xD5, 0x67, 0xE1, 0xA5, 0x88, 0x00, 0xBB, + 0x85, 0x92, 0x0C, 0x07, 0x8E, 0xC0, 0x5E, 0x06, + 0x08, 0xCB, 0x3E, 0x32, 0x3D, 0x6A, 0xB0, 0xF6, + 0x98, 0x20, 0xF8, 0xBF, 0xF4, 0x40, 0x08, 0xF5, + 0x28, 0x1E, 0x50, 0x36, 0x55, 0xA3, 0xCD, 0xE5, + 0xE3, 0x83, 0xFB, 0xD7, 0x29, 0x3E, 0x75, 0x1B, + 0x87, 0xC6, 0x77, 0xF5, 0x2B, 0xFE, 0x3D, 0x18, + 0xC1, 0x06, 0x92, 0x44, 0x2A, 0xFC, 0x28, 0x93, + 0x28, 0x99, 0xBB, 0x42, 0x6A, 0x9B, 0xC6, 0x6F, + 0xE6, 0xC0, 0xD5, 0x81, 0x3D, 0x78, 0x51, 0x5A, + 0x33, 0xF4, 0xD5, 0x29, 0x49, 0x79, 0x9E, 0xBF, + 0xF1, 0x7D, 0xB2, 0xAF, 0xC0, 0xB5, 0x30, 0xE0, + 0x36, 0x75, 0x82, 0x45, 0x19, 0x76, 0xDA, 0xA1, + 0x62, 0xB6, 0x3C, 0x8E, 0x30, 0xB5, 0x05, 0xF7, + 0x4D, 0x7A, 0x18, 0xFC, 0x51, 0xB0, 0xB1, 0x35, + 0x82, 0xBE, 0x97, 0xAB, 0x94, 0x4D, 0x2F, 0xD6, + 0x72, 0xAF, 0x2C, 0xDD, 0x95, 0x8A, 0x6B, 0x61, + 0xD6, 0x18, 0x89, 0xDD, 0x72, 0x6D, 0x8F, 0x71, + 0xFB, 0x68, 0xA4, 0x9C, 0xD0, 0x6C, 0x7D, 0x79, + 0xAF, 0xC9, 0xE9, 0x95, 0x08, 0xC9, 0xF6, 0x91, + 0x3B, 0x84, 0xE7, 0x97, 0x93, 0x49, 0x40, 0x15, + 0x19, 0xB4, 0xB3, 0x13, 0x75, 0x55, 0xB9, 0x0B, + 0xC1, 0x53, 0x15, 0x84, 0x69, 0xEE, 0x94, 0x1C, + 0x44, 0x7D, 0xCD, 0x7C, 0xC8, 0xD9, 0xC5, 0xFD, + 0x20, 0xCF, 0x74, 0xAD, 0x12, 0xA9, 0x23, 0xDD, + 0x97, 0x21, 0x0D, 0xB6, 0x49, 0x96, 0x12, 0x01, + 0x62, 0x0D, 0x9F, 0xAA, 0x61, 0x01, 0xB3, 0xB6, + 0x25, 0x81, 0x3B, 0x91, 0x60, 0x22, 0x7E, 0x32, + 0x1C, 0x5D, 0x1E, 0x59, 0x1F, 0x58, 0x7A, 0x75, + 0xD9, 0x34, 0xF7, 0xF9, 0xA7, 0xB9, 0xAA, 0x91, + 0x8F, 0xC6, 0x0C, 0xCE, 0x0D, 0x74, 0xDB, 0x11, + 0x70, 0x43, 0xD4, 0xB1, 0x07, 0x1E, 0x17, 0x54, + 0xF6, 0x35, 0x73, 0x30, 0xC2, 0xD0, 0x78, 0xE9, + 0x39, 0x3B, 0x5C, 0xF6, 0x8A, 0x68, 0x8F, 0x98, + 0x08, 0x49, 0x4A, 0x27, 0x60, 0x77, 0x19, 0x81, + 0x3C, 0x13, 0x19, 0x6F, 0x02, 0x5F, 0x3B, 0xB2, + 0x8A, 0x62, 0xE8, 0x06, 0x1A, 0x93, 0x78, 0x95, + 0x85, 0xF8, 0xFD, 0x0B, 0xC2, 0x90, 0xFA, 0x24, + 0x27, 0x0D, 0xB4, 0x49, 0x01, 0xFF, 0x86, 0xEB, + 0x72, 0xF6, 0x8E, 0xEE, 0x8D, 0x93, 0x12, 0x79, + 0x1C, 0x79, 0x9A, 0x3B, 0x44, 0xA7, 0x6F, 0x02, + 0x5E, 0x7B, 0xC2, 0x66, 0x69, 0x96, 0x62, 0x93, + 0xFA, 0x05, 0xEE, 0xA8, 0x3E, 0xC8, 0xC3, 0x37, + 0xBA, 0x88, 0xB8, 0xEC, 0x63, 0x7E, 0x75, 0x5D, + 0x91, 0xDC, 0x17, 0x25, 0xDC, 0x26, 0xA5, 0x0C, + 0x9C, 0x79, 0xF3, 0x59, 0xA7, 0x17, 0xA0, 0xB3, + 0xFD, 0xFA, 0xCA, 0x77, 0x63, 0xE5, 0x0E, 0xA4, + 0xE6, 0xEF, 0x6D, 0x04, 0x31, 0xD6, 0x57, 0xC9, + 0xC4, 0xE4, 0x20, 0x0D, 0x4F, 0x5A, 0x63, 0x45, + 0x99, 0xB1, 0xB4, 0x79, 0x93, 0x3F, 0xA6, 0xF1, + 0x13, 0x04, 0x91, 0xEB, 0x30, 0x5F, 0xF1, 0xD7, + 0x61, 0x1B, 0x6C, 0x98, 0xAE, 0x1E, 0x8B, 0xB6, + 0xE6, 0x88, 0xC9, 0xF9, 0xCE, 0x3D, 0xDE, 0xEB, + 0xAD, 0xAE, 0x2E, 0x48, 0x78, 0x9B, 0x79, 0x42, + 0xC3, 0x7E, 0x58, 0x9E, 0x8B, 0x4E, 0xCF, 0xC2, + 0xA7, 0xFF, 0xA3, 0x8C, 0x43, 0x66, 0xBC, 0x9F, + 0x57, 0x70, 0x1E, 0x90, 0xEB, 0xF4, 0x21, 0x3F, + 0x16, 0xB0, 0x3F, 0x74, 0xAF, 0x44, 0xE9, 0xEF, + 0x1C, 0x5B, 0x2C, 0x01, 0x65, 0xFB, 0x10, 0x3E, + 0xC1, 0xF0, 0x11, 0xC5, 0xAD, 0x4B, 0x68, 0x3F, + 0x48, 0xBF, 0xAF, 0x2D, 0x96, 0x6A, 0xEF, 0xE3, + 0x43, 0x85, 0xB9, 0x24, 0xAF, 0xC2, 0xDA, 0x69, + 0xB0, 0x3B, 0xC8, 0x52, 0x79, 0x72, 0x77, 0x0C, + 0xDE, 0xFF, 0x80, 0x5D, 0xC3, 0xD8, 0x3F, 0x0A, + 0x63, 0x92, 0x27, 0xFA, 0x2B, 0x26, 0x02, 0x94, + 0x90, 0x5F, 0x00, 0x1E, 0xCE, 0xFC, 0xCD, 0x2D, + 0xB7, 0xAA, 0x2B, 0x6D, 0xF7, 0x67, 0xD6, 0xF4, + 0x1E, 0x55, 0xE8, 0x39, 0x76, 0x71, 0x9D, 0x1E, + 0x31, 0xC2, 0x4A, 0xB1, 0x68, 0xDE, 0x2A, 0x7F, + 0x14, 0x89, 0xC0, 0x69, 0xF1, 0x3F, 0x9E, 0x66, + 0x6A, 0xA5, 0xA5, 0x1F, 0x28, 0x65, 0x0F, 0xE1, + 0x14, 0x3E, 0xC7, 0x10, 0xB0, 0xFD, 0xBC, 0xA9, + 0xE4, 0xE2, 0xF4, 0x05, 0x8F, 0x74, 0xF1, 0x6B, + 0xC1, 0xC8, 0x8E, 0xD7, 0x3B, 0xAF, 0xDD, 0xA4, + 0x7B, 0xC5, 0xC2, 0x54, 0x34, 0x86, 0x21, 0x88, + 0xB5, 0x95, 0x53, 0x9D, 0xB4, 0x67, 0xB0, 0x0D, + 0x35, 0xE0, 0x49, 0x90, 0xB0, 0xCC, 0x33, 0x42, + 0x77, 0x1C, 0x72, 0x1A, 0xCB, 0x3A, 0xF4, 0x59, + 0x01, 0x1B, 0x41, 0x58, 0x78, 0x75, 0x90, 0x38, + 0x9A, 0x8C, 0x32, 0x43, 0xF9, 0x6B, 0xBA, 0x62, + 0x60, 0x0A, 0x85, 0x2E, 0xA4, 0xE4, 0xD2, 0x0B, + 0x0E, 0x37, 0x49, 0xFD, 0x31, 0x14, 0x33, 0x47, + 0x00, 0x57, 0xD0, 0x1A, 0x1C, 0x64, 0x6D, 0x51, + 0xD1, 0x5F, 0x2B, 0x5F, 0x5D, 0x84, 0xED, 0x1B, + 0x59, 0xEA, 0xB4, 0x13, 0x48, 0xD4, 0x5D, 0x0A, + 0xA0, 0xF3, 0x6A, 0x9C, 0x09, 0x9A, 0xB5, 0xBE, + 0xF4, 0x0C, 0x84, 0x95, 0xE8, 0x68, 0x9C, 0x32, + 0x39, 0x0F, 0xD7, 0xE2, 0x39, 0x77, 0xAB, 0xBC, + 0x40, 0xB7, 0x12, 0xC7, 0x69, 0xD5, 0xB3, 0x46, + 0x2F, 0x1A, 0xAB, 0x56, 0x98, 0xC0, 0x5C, 0x2D, + 0x94, 0x94, 0xCB, 0xE1, 0x00, 0x67, 0xBE, 0xBE, + 0xB8, 0xC4, 0xFE, 0x20, 0x08, 0x79, 0xBC, 0x3F, + 0xE3, 0xD6, 0xC0, 0x3E, 0x8E, 0x76, 0xF0, 0x63, + 0xC9, 0xD0, 0x9C, 0x0E, 0x31, 0x18, 0x4A, 0x9F, + 0x9F, 0xFB, 0xB6, 0xBC, 0xD9, 0x56, 0x1D, 0x9A, + 0xDE, 0x4F, 0x16, 0xDF, 0x8E, 0xA6, 0xEF, 0x29, + 0x23, 0xB1, 0xD6, 0x8B, 0xC6, 0x02, 0x1F, 0x62, + 0xE1, 0xB8, 0x13, 0x3A, 0xC4, 0x6D, 0x52, 0xBB, + 0xA7, 0x08, 0x2F, 0x52, 0x49, 0x97, 0xED, 0x14, + 0x22, 0x81, 0xB1, 0x8B, 0x5B, 0x3C, 0xCD, 0x20, + 0x33, 0x49, 0x2B, 0xA4, 0x0F, 0x8A, 0x41, 0x81, + 0x0E, 0x04, 0x3B, 0x4C, 0xB1, 0x73, 0x19, 0x09, + 0xA7, 0x0F, 0xF5, 0xEA, 0xE7, 0x6B, 0x11, 0x30, + 0xB7, 0x22, 0x87, 0x1F, 0x36, 0x1F, 0xA7, 0x0C, + 0x23, 0x25, 0xB8, 0xC5, 0x2F, 0xDC, 0x65, 0x48, + 0x53, 0xF1, 0x20, 0x20, 0x33, 0xD0, 0xCA, 0xA4, + 0xE3, 0xE3, 0x8D, 0xC1, 0x65, 0x55, 0xBE, 0x0B, + 0x6E, 0x15, 0x45, 0xCA, 0x04, 0x03, 0x53, 0xBD, + 0xEF, 0x3D, 0x89, 0xAD, 0x74, 0x68, 0x87, 0xAA, + 0x63, 0xD6, 0x2E, 0x35, 0x95, 0x72, 0xBB, 0x16, + 0x65, 0x4D, 0x3E, 0x38, 0x83, 0xFE, 0x76, 0x52, + 0xEE, 0xA1, 0x26, 0xA9, 0x16, 0x7B, 0x76, 0x4F, + 0x14, 0x4E, 0x02, 0x5E, 0xF9, 0xC0, 0x04, 0x27, + 0xBB, 0xF1, 0x9F, 0xA2, 0x63, 0xD7, 0xC2, 0x48, + 0xC7, 0xF1, 0x12, 0x5E, 0x06, 0xC5, 0x43, 0xEE, + 0x3A, 0xEA, 0x66, 0x33, 0xCF, 0x86, 0xFD, 0x97, + 0x50, 0xE7, 0x61, 0x1B, 0xE3, 0x9E, 0xE7, 0x08, + 0x65, 0x76, 0x35, 0x88, 0x52, 0xD2, 0x58, 0xF5, + 0xCB, 0x34, 0xFB, 0x17, 0x86, 0x97, 0xE5, 0x72, + 0x1F, 0x6A, 0x93, 0x35, 0xF4, 0xDA, 0x9D, 0x13, + 0x44, 0x89, 0xE7, 0xFD, 0xBE, 0x81, 0xCA, 0x6B, + 0x33, 0x31, 0xDE, 0x79, 0x1D, 0x72, 0x44, 0xDF, + 0x07, 0x61, 0x2B, 0x49, 0xBD, 0x87, 0xBF, 0x6E, + 0x3A, 0x04, 0x28, 0xCB, 0x62, 0x70, 0x9F, 0x7D, + 0x31, 0x18, 0xD9, 0x79, 0xAF, 0x04, 0x31, 0x0A, + 0x4B, 0xEC, 0xB1, 0x79, 0xD1, 0xC5, 0x8E, 0x9F, + 0xB9, 0xB9, 0xCA, 0xC8, 0xD7, 0x04, 0xF5, 0x45, + 0x19, 0x2E, 0xFE, 0x75, 0xB1, 0x30, 0xD3, 0x5B, + 0xF4, 0x32, 0xA1, 0x92, 0xF0, 0x22, 0x73, 0x3C, + 0xC9, 0xAE, 0x4F, 0x80, 0xC5, 0x22, 0x5A, 0xD7, + 0x13, 0xC2, 0xF0, 0xBB, 0x26, 0x11, 0xAD, 0x7D, + 0x89, 0x6A, 0x17, 0xD5, 0x85, 0x49, 0x7F, 0x8D, + 0xC4, 0x6B, 0x28, 0xF2, 0xF3, 0xF5, 0x76, 0xE5, + 0xC3, 0x46, 0x44, 0x60, 0x22, 0xB7, 0xAD, 0x92, + 0x67, 0x3A, 0x35, 0x79, 0x79, 0x9D, 0xF4, 0xCD, + 0xE0, 0x73, 0x5C, 0x31, 0xAF, 0x7B, 0x8D, 0x9C, + 0x9D, 0xC4, 0x8A, 0x17, 0xB0, 0x8E, 0x3C, 0x02, + 0x6B, 0x7C, 0x4A, 0xA5, 0xE5, 0x30, 0x2D, 0x93, + 0xF8, 0x91, 0x50, 0xCB, 0xDF, 0x7D, 0x57, 0x6F, + 0x7D, 0x70, 0x1E, 0x68, 0xBF, 0x50, 0x09, 0xDC, + 0x9E, 0x70, 0x1A, 0xC5, 0xC3, 0x4D, 0x79, 0x69, + 0xCE, 0x9C, 0x03, 0xCF, 0x3A, 0x73, 0xAB, 0x7D, + 0xAC, 0x12, 0x29, 0x61, 0xAC, 0x20, 0x84, 0x4B, + 0x2C, 0xDE, 0xA1, 0xCD, 0x45, 0xB8, 0x92, 0x74, + 0x3C, 0x2B, 0xA6, 0xAF, 0xD0, 0x40, 0xE4, 0x72, + 0x77, 0x09, 0x61, 0xE8, 0x56, 0x2F, 0xA8, 0x1F, + 0x28, 0x32, 0x0B, 0xC1, 0x51, 0xF2, 0x17, 0xF7, + 0x54, 0x6F, 0x4F, 0xB6, 0x1B, 0xEC, 0x2C, 0xC9, + 0x86, 0xDE, 0xA8, 0xC5, 0x14, 0x56, 0x63, 0x1F, + 0x1E, 0x7F, 0x3B, 0x99, 0xB5, 0xF5, 0x95, 0x38, + 0xC8, 0x5D, 0xE6, 0xD5, 0x7C, 0xA7, 0xC3, 0xFD, + 0x82, 0xA8, 0x2B, 0x8E, 0xDC, 0xC5, 0x94, 0xA6, + 0x06, 0x6D, 0x46, 0xAC, 0x63, 0x5B, 0x6F, 0x20, + 0xBF, 0xD4, 0x9A, 0x0B, 0xB8, 0x5A, 0x52, 0x84, + 0x2C, 0xA6, 0x21, 0x81, 0x27, 0x94, 0x70, 0x55, + 0x47, 0x15, 0x34, 0x01, 0x94, 0xB6, 0x2D, 0x3D, + 0x3E, 0xEB, 0xFD, 0xB3, 0x04, 0xCA, 0xF5, 0x53, + 0x92, 0x14, 0x42, 0xC7, 0x80, 0xFC, 0x38, 0xEA, + 0x32, 0x13, 0x42, 0x73, 0x7A, 0x14, 0x7B, 0x2B, + 0xB4, 0x97, 0xB6, 0xE1, 0x19, 0xEE, 0x07, 0x6B, + 0xC6, 0xB2, 0x3A, 0xF0, 0x32, 0x1A, 0x95, 0x6A, + 0xE2, 0xFD, 0xAF, 0x0B, 0x72, 0x28, 0x6B, 0xC4, + 0x5F, 0x40, 0xD0, 0xCA, 0x1A, 0x5D, 0x20, 0x20, + 0x2C, 0x73, 0x64, 0xBE, 0xA9, 0x87, 0x59, 0x8C, + 0x36, 0x5C, 0x23, 0x7E, 0x99, 0xC5, 0xB8, 0xE8, + 0xBD, 0x80, 0xD0, 0x89, 0xD9, 0x75, 0xB3, 0x9B, + 0x27, 0xB7, 0xE9, 0xC3, 0x1B, 0x71, 0x40, 0x25, + 0x33, 0x8B, 0x2A, 0x32, 0x51, 0x72, 0x44, 0x16, + 0x69, 0xFC, 0xD9, 0x13, 0xDD, 0xCF, 0xEE, 0x89, + 0x19, 0xE1, 0x49, 0x47, 0x18, 0xCD, 0x30, 0xE6, + 0xE9, 0xA7, 0x61, 0x64, 0x31, 0x8D, 0xBF, 0xC7, + 0xAE, 0x88, 0x8F, 0x30, 0x27, 0xC9, 0xA9, 0x53, + 0xE4, 0x64, 0xE9, 0x43, 0x62, 0x0B, 0x9B, 0x93, + 0xE0, 0xC5, 0xE5, 0x95, 0x15, 0x6B, 0x05, 0x4F, + 0xC0, 0xD8, 0x02, 0xA0, 0xD6, 0x4C, 0xF7, 0x94, + 0x85, 0x54, 0x11, 0x3F, 0x28, 0xF3, 0xA5, 0x11, + 0x2F, 0x3C, 0xC2, 0x3D, 0x3D, 0x6D, 0x9B, 0xEE, + 0x3D, 0x6E, 0x17, 0xE5, 0x18, 0x4E, 0x1A, 0xB4, + 0x0A, 0x37, 0x47, 0xB3, 0x88, 0x7B, 0x21, 0xC6, + 0xC7, 0x59, 0x74, 0x6A, 0xD3, 0xE9, 0x40, 0xC2, + 0x1A, 0xAA, 0x8E, 0xDE, 0x15, 0xAA, 0x98, 0x06, + 0x09, 0xD9, 0xAA, 0x67, 0x00, 0x32, 0x13, 0x99, + 0x8F, 0x04, 0x29, 0x25, 0xB2, 0x75, 0x71, 0xFE, + 0x21, 0x6F, 0x9E, 0xAA, 0x35, 0x20, 0xD6, 0x60, + 0x49, 0x81, 0x89, 0xA5, 0x51, 0x7B, 0x34, 0xAD, + 0x49, 0x82, 0xED, 0x31, 0xDE, 0xCA, 0x37, 0xF3, + 0x36, 0x06, 0x00, 0x85, 0x10, 0xE0, 0xE7, 0xFE, + 0xBD, 0xDC, 0xD9, 0x99, 0x2F, 0x42, 0xC5, 0x86, + 0xB3, 0xB2, 0x1E, 0x81, 0x7E, 0xB8, 0x38, 0xDB, + 0x40, 0xE4, 0x8D, 0x77, 0x1C, 0xAD, 0xBD, 0x82, + 0x71, 0x5B, 0x12, 0xD5, 0x07, 0x60, 0x45, 0xDC, + 0x1A, 0xDD, 0xEB, 0xD1, 0xFC, 0x1C, 0x6B, 0x6A, + 0x10, 0x67, 0x33, 0x12, 0x0D, 0x4E, 0xDD, 0xCB, + 0x3C, 0x10, 0x27, 0x80, 0xC7, 0x75, 0xD3, 0x3B, + 0x0A, 0x16, 0xE5, 0x97, 0x48, 0x66, 0x93, 0x3F, + 0x25, 0x53, 0x24, 0x3D, 0x44, 0xAF, 0x66, 0xF0, + 0xF3, 0x3D, 0x36, 0x50, 0x1D, 0xED, 0x3F, 0x3B, + 0x58, 0x2E, 0x9F, 0x7D, 0x6B, 0xD1, 0x84, 0x56, + 0x0D, 0x88, 0x5B, 0x95, 0x5A, 0xBF, 0x18, 0xCA, + 0x9C, 0xE5, 0x13, 0x0E, 0xFD, 0x43, 0x88, 0xB9, + 0x21, 0xD2, 0xF1, 0x81, 0xA1, 0xA5, 0x66, 0x3B, + 0x73, 0xE8, 0x56, 0x86, 0x40, 0x21, 0x67, 0x6A, + 0xB8, 0xF2, 0xE7, 0x8D, 0x32, 0x2B, 0xD5, 0x82, + 0x50, 0xDE, 0xEE, 0x75, 0xA9, 0x65, 0x6D, 0x5F, + 0x14, 0x25, 0x01, 0xC4, 0x5A, 0xA8, 0xDA, 0x10, + 0xA2, 0x07, 0xDE, 0x65, 0xB4, 0xDA, 0x84, 0xBB, + 0x15, 0x89, 0xDB, 0x64, 0xA1, 0x88, 0x6A, 0x15, + 0x73, 0xB8, 0x0D, 0x6A, 0x90, 0xA6, 0x31, 0xD4, + 0x78, 0xB1, 0x5E, 0xC7, 0x32, 0xF2, 0x51, 0x2A, + 0x5C, 0x8D, 0x85, 0xFB, 0x2A, 0xF9, 0xC9, 0xD6, + 0x85, 0x5F, 0xD9, 0x6F, 0x37, 0xB0, 0x4B, 0xA9, + 0x6F, 0xD5, 0x7A, 0x17, 0xDB, 0x0A, 0xFD, 0x33, + 0x25, 0x1B, 0x2A, 0x9C, 0x62, 0x57, 0xBF, 0x5D, + 0x58, 0xBF, 0x7A, 0x64, 0x2D, 0x4C, 0x26, 0x2B, + 0xAC, 0x26, 0xE8, 0xBF, 0x40, 0x60, 0x06, 0xBD, + 0xD7, 0xB1, 0x59, 0xB8, 0x96, 0xAB, 0x0A, 0xD2, + 0x50, 0x6C, 0x25, 0x53, 0x85, 0xBA, 0x69, 0x8B, + 0x8C, 0x22, 0x10, 0xCE, 0x02, 0x2D, 0x33, 0x5A, + 0xC8, 0xDB, 0x61, 0x23, 0x49, 0x1A, 0x94, 0x18, + 0x27, 0x19, 0x06, 0x58, 0x74, 0x4C, 0x75, 0x7F, + 0x08, 0x23, 0x89, 0xBE, 0x64, 0xF0, 0x3D, 0x1D, + 0x86, 0xC1, 0x10, 0xB9, 0xDC, 0xC4, 0x74, 0x04, + 0xED, 0x27, 0x76, 0xC1, 0xAA, 0x95, 0xDF, 0x4E, + 0xDE, 0x46, 0x41, 0xC2, 0x51, 0x8F, 0x7A, 0x2D, + 0xD8, 0xB0, 0x92, 0x44, 0x39, 0xA9, 0xF6, 0xAE, + 0x57, 0x80, 0xE1, 0xE3, 0x28, 0x8E, 0x91, 0xDA, + 0xA2, 0x2B, 0x11, 0x10, 0x89, 0xDB, 0x4E, 0x39, + 0x7E, 0xA0, 0x0C, 0xF3, 0x27, 0xF6, 0x8A, 0x7A, + 0x86, 0xE7, 0xE6, 0x6D, 0x06, 0x2A, 0xE5, 0xF0, + 0x59, 0xBD, 0x9C, 0xE1, 0x93, 0x87, 0x29, 0x74, + 0x28, 0x6B, 0x6B, 0x6E, 0x14, 0x64, 0x85, 0x60, + 0x79, 0xDA, 0x8D, 0xDD, 0x76, 0xF9, 0xBF, 0x68, + 0x80, 0x4A, 0xC8, 0x5C, 0xCB, 0xC9, 0x99, 0xC3, + 0xBD, 0x4B, 0xA4, 0x10, 0xBE, 0x70, 0x76, 0x40, + 0xFE, 0x7F, 0xD7, 0x43, 0x52, 0xDC, 0xBA, 0x4B, + 0x7B, 0x1D, 0xCD, 0xCE, 0x99, 0x36, 0xB1, 0x64, + 0x17, 0x87, 0xC0, 0x70, 0xF7, 0x5B, 0x58, 0x62, + 0x0C, 0x6D, 0x63, 0x29, 0x93, 0xC8, 0x00, 0xD8, + 0x13, 0xC8, 0xB1, 0x04, 0xB3, 0xEE, 0x51, 0x78, + 0x40, 0xAF, 0xA5, 0x75, 0xD6, 0xC5, 0xBE, 0xEE, + 0x3C, 0x97, 0x77, 0x37, 0x56, 0x4E, 0x02, 0x8F, + 0xB4, 0x0E, 0xE5, 0x5D, 0xC0, 0xA2, 0x8B, 0x6B, + 0xC6, 0x82, 0x66, 0xBC, 0x37, 0x91, 0x91, 0xE5, + 0x3D, 0xFE, 0x0C, 0x2E, 0xAE, 0xB7, 0x12, 0xAA, + 0xE1, 0xA3, 0xC3, 0x5F, 0x6F, 0x68, 0x45, 0xF2, + 0x3D, 0xA0, 0x73, 0x46, 0x97, 0x68, 0x54, 0x63, + 0xF7, 0x63, 0x6D, 0xE2, 0x15, 0x69, 0x72, 0x80, + 0x49, 0x5C, 0x62, 0x83, 0x82, 0xCE, 0xB5, 0x33, + 0x4E, 0x63, 0x04, 0x79, 0x4E, 0x43, 0x6B, 0x78, + 0xB4, 0xEF, 0xB0, 0x02, 0x3F, 0xA2, 0x88, 0xF8, + 0x3D, 0xFF, 0x31, 0xF9, 0x25, 0xAB, 0x8E, 0x6A, + 0x9A, 0x7E, 0xCC, 0xBC, 0xD9, 0x05, 0xA3, 0xA5, + 0x2C, 0x29, 0xA5, 0x6F, 0xF3, 0x31, 0xAF, 0x27, + 0xE2, 0x38, 0x3E, 0x5C, 0x5B, 0x19, 0x3D, 0xDB, + 0x86, 0x35, 0x09, 0x8C, 0x5D, 0xEF, 0x1C, 0x4E, + 0x79, 0x0D, 0xAA, 0x1C, 0xA6, 0x49, 0x7D, 0x01, + 0xFB, 0x3B, 0xF6, 0xCC, 0x94, 0xA6, 0xF4, 0x8E, + 0xA7, 0xCA, 0xB5, 0xD9, 0xA1, 0xCD, 0xDB, 0xA5, + 0x93, 0xEC, 0xD6, 0x1B, 0xE1, 0xE7, 0x35, 0x94, + 0xB0, 0x66, 0x1F, 0x96, 0xA4, 0xE0, 0x48, 0x03, + 0xCD, 0xF2, 0xB5, 0x70, 0x86, 0xD5, 0x78, 0x3A, + 0x17, 0xBE, 0x84, 0x30, 0x67, 0x81, 0xB6, 0xB2, + 0xAD, 0x1F, 0x87, 0x62, 0x60, 0x87, 0xF8, 0x09, + 0x39, 0x02, 0x08, 0xF9, 0x34, 0x67, 0xF8, 0x45, + 0xD2, 0xBE, 0xA2, 0x84, 0x3A, 0xFF, 0xA0, 0xA9, + 0x33, 0xDC, 0x4C, 0xAE, 0x7D, 0x4B, 0xDC, 0x5F, + 0xEB, 0x25, 0xA2, 0x1A, 0x18, 0xAE, 0x7A, 0x07, + 0x24, 0x0C, 0xA3, 0x74, 0x5D, 0xC3, 0x72, 0x5E, + 0x02, 0x6D, 0x86, 0x40, 0x88, 0x4A, 0xD1, 0x9F, + 0xD1, 0x6B, 0x04, 0xBE, 0xB8, 0x35, 0x9A, 0xA0, + 0x23, 0x2E, 0x20, 0x1C, 0x2E, 0x1A, 0x4A, 0x01, + 0xA7, 0x1D, 0xCC, 0x64, 0xCA, 0xEF, 0x54, 0x83, + 0xF2, 0x50, 0xEC, 0x92, 0xE5, 0x49, 0x84, 0xDC, + 0xA8, 0x38, 0xAB, 0x9A, 0xA4, 0x36, 0xA9, 0x59, + 0x15, 0xF9, 0x73, 0xCB, 0x97, 0x1A, 0x6E, 0x65, + 0x4A, 0x42, 0x11, 0x28, 0x79, 0xFE, 0xC5, 0xE0, + 0xC3, 0x03, 0xBF, 0xE1, 0xDD, 0xC0, 0x82, 0x64, + 0xC5, 0x9D, 0xF0, 0x2A, 0x8A, 0x62, 0x25, 0x56, + 0x84, 0x92, 0xE5, 0xDF, 0x3F, 0x71, 0xC8, 0xFF, + 0xF4, 0x9A, 0xC5, 0x17, 0x06, 0x8A, 0x02, 0xF0, + 0x3C, 0x76, 0x53, 0xD0, 0xA2, 0x28, 0x1A, 0xE0, + 0x12, 0xB1, 0x9F, 0x03, 0x43, 0x10, 0x0F, 0xEE, + 0xA9, 0x35, 0x9A, 0x53, 0x7E, 0x9B, 0x4C, 0x64, + 0xE1, 0xCF, 0x5A, 0x07, 0x34, 0x06, 0xA3, 0x8E, + 0xAC, 0x10, 0x63, 0xB3, 0xF2, 0xB0, 0xE3, 0x63, + 0x6A, 0x62, 0x0B, 0xA0, 0x02, 0x8C, 0x03, 0x96, + 0xDC, 0x0B, 0xDB, 0x57, 0x34, 0x7B, 0xA9, 0xEF, + 0x4C, 0x46, 0x80, 0x4D, 0x58, 0x78, 0x19, 0x3C, + 0x03, 0x87, 0x26, 0xB3, 0x58, 0xFF, 0x01, 0x22, + 0x1D, 0x41, 0xFA, 0xBE, 0xC1, 0xBD, 0x79, 0x1D, + 0x6F, 0xDE, 0x8B, 0xEC, 0x25, 0x1F, 0xD2, 0xE9, + 0xCA, 0x81, 0x3B, 0xC4, 0x8C, 0xB2, 0x77, 0xDD, + 0x7C, 0xB5, 0x47, 0x04, 0xED, 0xB5, 0x71, 0xE0, + 0xDA, 0x2E, 0xA4, 0xF8, 0xA2, 0x13, 0x3C, 0x90, + 0x48, 0xC5, 0xC0, 0x6C, 0xD2, 0x6D, 0x82, 0x63, + 0x44, 0x98, 0xC1, 0x3C, 0x07, 0x55, 0x8E, 0x0F, + 0xC6, 0xD6, 0x3A, 0xF2, 0xCE, 0x79, 0x4E, 0x39, + 0xA4, 0xB8, 0x07, 0x5F, 0x7B, 0x1D, 0xB1, 0x83, + 0x72, 0xAB, 0x2E, 0x05, 0x04, 0x32, 0x49, 0xC8, + 0x05, 0x41, 0xEA, 0xEB, 0xF8, 0x15, 0x9A, 0x01, + 0x08, 0xB8, 0xED, 0x4F, 0x33, 0x6E, 0x04, 0x0C, + 0xAD, 0xC3, 0xE5, 0x4D, 0x30, 0x2D, 0xFE, 0x54, + 0xC6, 0xA3, 0xAE, 0xA4, 0x6C, 0xBE, 0x44, 0x23, + 0x06, 0x96, 0x4A, 0x97, 0x5B, 0xB6, 0x35, 0x37, + 0x58, 0x51, 0xEE, 0xDE, 0x80, 0xAA, 0x1E, 0xA8, + 0x1C, 0xEA, 0x64, 0xF0, 0xF8, 0x21, 0x83, 0x64, + 0x7D, 0x43, 0xF5, 0x69, 0x99, 0xF4, 0x05, 0x22, + 0xAB, 0xD9, 0xD3, 0x2F, 0xD2, 0x24, 0x48, 0xDA, + 0xCA, 0x6D, 0xE7, 0xE3, 0x32, 0x87, 0xD7, 0x9C, + 0xC1, 0x39, 0x4C, 0x23, 0x18, 0xBE, 0x41, 0xA4, + 0x34, 0xEC, 0x9D, 0xBD, 0x04, 0xF5, 0x92, 0xF4, + 0x43, 0xA8, 0xED, 0xF2, 0x7B, 0x29, 0x77, 0xA7, + 0x17, 0x6B, 0xB1, 0x0C, 0x96, 0x67, 0xD7, 0x82, + 0x15, 0x2E, 0xB0, 0x5F, 0x29, 0x79, 0x0E, 0x18, + 0x76, 0xBA, 0x82, 0x94, 0x3A, 0xC7, 0xE5, 0x01, + 0xCB, 0x63, 0xCD, 0x62, 0x67, 0x6F, 0xD9, 0xE0, + 0x75, 0x26, 0x3F, 0x2D, 0xC4, 0x5D, 0xD1, 0x9D, + 0xEF, 0x41, 0x11, 0xD8, 0x62, 0x1B, 0x41, 0x4E, + 0xBF, 0xBE, 0xCB, 0xC7, 0x48, 0x8D, 0x08, 0xD8, + 0xC3, 0xF0, 0x13, 0xE6, 0xC3, 0xD9, 0x0E, 0x49, + 0xE2, 0x00, 0x1F, 0xF6, 0xD8, 0x4F, 0xFF, 0xE5, + 0x03, 0x32, 0x6D, 0x3A, 0x57, 0x4D, 0x50, 0xDF, + 0x89, 0x1F, 0x3A, 0xB3, 0xD0, 0x5A, 0x9A, 0xBE, + 0x02, 0x31, 0xDA, 0xF4, 0xA1, 0xB6, 0x06, 0x2C, + 0x2F, 0xBB, 0xCF, 0x28, 0xA8, 0xB1, 0x06, 0x63, + 0x52, 0x47, 0x64, 0xA5, 0xBB, 0x23, 0x5A, 0x6A, + 0x87, 0xC1, 0xF6, 0x8D, 0x2B, 0xA4, 0x0C, 0xB6, + 0xF3, 0x97, 0x6A, 0x92, 0x8B, 0xA8, 0x7D, 0xCF, + 0xF0, 0xF1, 0xDE, 0x3C, 0x12, 0x48, 0x48, 0x7F, + 0x5D, 0xE6, 0xF3, 0x71, 0xC7, 0x57, 0xD6, 0xC2, + 0xCB, 0x20, 0x03, 0x38, 0xB2, 0xBA, 0xDD, 0x54, + 0x00, 0xD9, 0x98, 0x11, 0x63, 0x48, 0xC2, 0xF9, + 0x51, 0x78, 0x2C, 0xBC, 0x23, 0xC1, 0x8C, 0xA7, + 0x39, 0xFE, 0xAA, 0xFB, 0x59, 0x7C, 0xB6, 0x7A, + 0x26, 0x1B, 0x64, 0xB0, 0xC4, 0xEB, 0x58, 0xB3, + 0xA9, 0xCF, 0x74, 0x14, 0x72, 0x5A, 0x8F, 0x92, + 0xF9, 0x1A, 0xCF, 0x7C, 0x8F, 0xE7, 0x49, 0xAD, + 0x10, 0x6E, 0xD5, 0xE6, 0xFF, 0x7A, 0xE2, 0x7E, + 0xE2, 0x89, 0xEE, 0x7F, 0xB0, 0xD0, 0xD0, 0x67, + 0x8B, 0x0C, 0x44, 0x0A, 0xF6, 0x6B, 0x47, 0x4E, + 0x7D, 0xF0, 0x22, 0xA7, 0xA9, 0xC9, 0x08, 0x9A, + 0x30, 0xD1, 0x3B, 0xE2, 0x10, 0x23, 0x41, 0x66, + 0x45, 0x39, 0x2A, 0x8C, 0xCA, 0xB3, 0x6C, 0x58, + 0xCC, 0xA2, 0xFC, 0x47, 0x7D, 0x50, 0xF1, 0xF4, + 0xD5, 0x23, 0x32, 0x1B, 0xDA, 0x1D, 0x0A, 0x42, + 0xFC, 0x49, 0x34, 0x49, 0x89, 0xF2, 0x5B, 0x8A, + 0x93, 0xAE, 0xE3, 0x29, 0x4C, 0xDB, 0x7E, 0xCA, + 0x42, 0xCE, 0xE3, 0xA4, 0xE9, 0x7E, 0xC1, 0xF6, + 0x73, 0x78, 0x89, 0x19, 0x3A, 0xD8, 0xDF, 0xDE, + 0x69, 0xC8, 0x7F, 0x61, 0xD7, 0x21, 0xDB, 0x90, + 0x08, 0x13, 0x08, 0x71, 0x87, 0x47, 0x40, 0x67, + 0xBD, 0x86, 0x8A, 0xC2, 0x36, 0x8A, 0x1F, 0xC1, + 0xF7, 0x51, 0x59, 0xAB, 0xCA, 0xDC, 0x60, 0x6A, + 0x98, 0xF8, 0x50, 0xA9, 0x31, 0xCE, 0xB0, 0x91, + 0xC7, 0x19, 0xFC, 0x1C, 0xBC, 0x78, 0x34, 0x56, + 0x8E, 0x34, 0xD1, 0x96, 0x7B, 0x3A, 0xB9, 0x18, + 0xBB, 0xA6, 0x28, 0x0A, 0x77, 0xFF, 0x0B, 0x26, + 0xB1, 0x3A, 0x88, 0x06, 0x2A, 0x28, 0xE0, 0x11, + 0xAF, 0xC2, 0x47, 0x6E, 0xC5, 0xA2, 0x13, 0x98, + 0x15, 0xD7, 0x86, 0x79, 0x8A, 0xEE, 0xB3, 0x30, + 0x66, 0x18, 0x9C, 0xE5, 0x44, 0xF0, 0xA1, 0x25, + 0xB6, 0x2F, 0x5E, 0x85, 0xE0, 0x73, 0xAD, 0x40, + 0x92, 0xDE, 0x19, 0x2A, 0x05, 0x34, 0xB0, 0xC1, + 0x39, 0x4D, 0xC1, 0xFF, 0x39, 0x76, 0xC3, 0xDA, + 0x5D, 0x3C, 0x44, 0x41, 0xAC, 0xB7, 0x29, 0x38, + 0x81, 0x55, 0x20, 0x7A, 0xA0, 0xCF, 0xE0, 0xE6, + 0x75, 0xC9, 0x14, 0x3B, 0x3D, 0xA5, 0xE6, 0x78, + 0xDD, 0xA1, 0x43, 0x29, 0x8E, 0x74, 0x3F, 0xFD, + 0x27, 0xA9, 0xCE, 0x82, 0xF3, 0xA9, 0x7D, 0xE0, + 0xAE, 0xD3, 0xB8, 0x84, 0xB8, 0xAB, 0x49, 0x34, + 0x8D, 0x4A, 0xEB, 0x7D, 0xBD, 0x55, 0x02, 0x61, + 0x42, 0x57, 0x4F, 0x22, 0x55, 0x31, 0x57, 0x18, + 0x7F, 0x08, 0x49, 0x0D, 0xEB, 0x6E, 0x46, 0x44, + 0x87, 0x5A, 0x52, 0xC4, 0xDC, 0x7C, 0xE3, 0x70, + 0x49, 0xBF, 0x62, 0x8A, 0xBD, 0xC9, 0x2C, 0x45, + 0xF1, 0x5E, 0x43, 0x33, 0xF2, 0x83, 0x0D, 0x5F, + 0xF8, 0x4C, 0x45, 0xE6, 0x11, 0x55, 0x28, 0x92, + 0xBB, 0x9E, 0x1C, 0xEC, 0x9F, 0x5F, 0x75, 0x5F, + 0xD8, 0x56, 0x7D, 0x8B, 0xE0, 0x8A, 0x97, 0x77, + 0xAA, 0x43, 0x8C, 0x29, 0x77, 0xE1, 0x8E, 0x06, + 0x39, 0xA4, 0x98, 0xD4, 0x74, 0xDA, 0xF8, 0x52, + 0x51, 0xB6, 0x97, 0x1D, 0xBB, 0x31, 0x81, 0x4B, + 0x06, 0x2D, 0x5E, 0x67, 0xEE, 0x0D, 0x58, 0x01, + 0xB6, 0x1A, 0xAE, 0xBA, 0x16, 0xF5, 0x3E, 0x86, + 0xD9, 0x1E, 0x0C, 0xBB, 0x48, 0x5E, 0x56, 0xC4, + 0x94, 0xD1, 0xCB, 0xD7, 0x8B, 0x21, 0xED, 0xE6, + 0x9F, 0x4B, 0x25, 0x42, 0x33, 0x5A, 0xF1, 0x3B, + 0x65, 0x76, 0x2F, 0x24, 0x85, 0x48, 0x75, 0x71, + 0x7B, 0x3E, 0xDF, 0xAF, 0x85, 0x6C, 0x96, 0x01, + 0x21, 0xEF, 0x27, 0x36, 0x0B, 0x7B, 0xE7, 0x28, + 0x36, 0x91, 0x0D, 0x8A, 0xA4, 0xB7, 0xD9, 0x64, + 0x5D, 0x99, 0xAF, 0x43, 0x09, 0xBE, 0xD2, 0xD8, + 0x28, 0xC0, 0x30, 0x1D, 0x0E, 0xF1, 0x53, 0xEB, + 0xF0, 0x77, 0xE7, 0x37, 0x63, 0x22, 0x8B, 0xB1, + 0x67, 0x92, 0x54, 0x30, 0x69, 0x75, 0x23, 0x97, + 0x33, 0x3F, 0xA1, 0xF4, 0x2E, 0x71, 0x67, 0x9F, + 0x2E, 0x91, 0xE3, 0x16, 0x66, 0x09, 0x8B, 0x2C, + 0x72, 0x60, 0xA2, 0xDB, 0x38, 0x1C, 0xF8, 0xE4, + 0x30, 0xDB, 0x1E, 0x95, 0x28, 0x2D, 0x27, 0xB8, + 0xD2, 0xC0, 0x64, 0x9A, 0x5F, 0xD7, 0x5A, 0x71, + 0xD2, 0xF2, 0xAD, 0x58, 0x35, 0x72, 0x55, 0xCF, + 0x2D, 0xD5, 0x9F, 0x39, 0x3D, 0x92, 0x4E, 0x3D, + 0x03, 0x1B, 0x68, 0x4A, 0xC8, 0x12, 0x2C, 0x91, + 0xAA, 0x5C, 0x1D, 0xE7, 0x4C, 0x41, 0x1A, 0x42, + 0xAC, 0xFC, 0x2A, 0x98, 0x18, 0x7D, 0x65, 0xB4, + 0x6B, 0x19, 0x6F, 0x6A, 0x1D, 0x4F, 0xD8, 0x69, + 0x23, 0xF4, 0xF9, 0x40, 0xF4, 0xD1, 0x91, 0xB2, + 0xB6, 0x0F, 0xA4, 0x3F, 0xED, 0x61, 0x4B, 0xEA, + 0xD2, 0x00, 0x49, 0xCB, 0xC5, 0x25, 0x42, 0xCD, + 0x97, 0xC2, 0x93, 0x13, 0x6D, 0x34, 0x7B, 0x22, + 0xFC, 0xB8, 0xC9, 0x5F, 0x4F, 0x0A, 0xB7, 0xE2, + 0x91, 0x4E, 0x4D, 0x55, 0xB3, 0x53, 0x65, 0xB6, + 0xB9, 0xD5, 0x06, 0xB4, 0x01, 0x85, 0x7C, 0x0A, + 0x53, 0x33, 0xA2, 0x0A, 0x65, 0xFC, 0x96, 0xA4, + 0xC5, 0x66, 0xCA, 0xD8, 0x5D, 0x01, 0x1F, 0x5B, + 0xFD, 0x1F, 0x94, 0xF8, 0xAE, 0xD9, 0x36, 0x58, + 0x54, 0x12, 0xB4, 0xD2, 0xAD, 0xCC, 0xC1, 0x4E, + 0x87, 0xF3, 0xB4, 0xDA, 0x20, 0x9F, 0xBA, 0xFF, + 0x0D, 0x44, 0x3B, 0x6C, 0x47, 0x01, 0xF3, 0x60, + 0x54, 0x6F, 0xCF, 0x8A, 0x7F, 0xF7, 0xE4, 0x2E, + 0x15, 0xB6, 0x80, 0xE1, 0x03, 0x5A, 0x0B, 0x91, + 0xC6, 0x90, 0x05, 0x6A, 0xCD, 0x06, 0xCA, 0x1C, + 0x02, 0xC3, 0x51, 0x12, 0x06, 0x8F, 0xB8, 0x1C, + 0xA7, 0xA2, 0xB0, 0xEC, 0x92, 0x82, 0x8A, 0x50, + 0x2E, 0xB5, 0x8A, 0x99, 0x70, 0x2F, 0x47, 0xFF, + 0x0D, 0xCD, 0x60, 0x53, 0x65, 0x56, 0x6F, 0x43, + 0xCB, 0x6E, 0x0C, 0xCC, 0xB4, 0x2A, 0xE0, 0x45, + 0x65, 0x24, 0x5C, 0x3B, 0x00, 0xB2, 0x9F, 0x41, + 0x3E, 0x4A, 0xCE, 0xBD, 0x41, 0x85, 0xB9, 0x90, + 0x35, 0x53, 0xEE, 0x6B, 0x32, 0x73, 0x45, 0xAD, + 0xFB, 0x4B, 0xA7, 0xFD, 0xA4, 0xCC, 0xFF, 0xF2, + 0xAB, 0xD6, 0x45, 0x9C, 0x7A, 0x30, 0x73, 0x9A, + 0x32, 0x54, 0xE7, 0x9E, 0xA5, 0xFB, 0x7B, 0x1D, + 0x19, 0x77, 0xE7, 0xBF, 0xC8, 0x3B, 0x6D, 0x3E, + 0xBA, 0x90, 0x1A, 0xA4, 0x27, 0xBD, 0x7B, 0x4B, + 0x91, 0xC0, 0xFF, 0x9D, 0x83, 0xAE, 0x71, 0xC6, + 0x2E, 0x34, 0xEA, 0xBA, 0x3E, 0x23, 0x2A, 0x1E, + 0xED, 0x62, 0x52, 0x31, 0x70, 0x45, 0x0C, 0xFB, + 0xC0, 0xEE, 0xA4, 0xA9, 0x30, 0x7D, 0xCE, 0x2A, + 0xD6, 0x1D, 0xBE, 0x01, 0xF1, 0x8F, 0xF7, 0x3E, + 0x19, 0x30, 0x00, 0x33, 0xFA, 0xC8, 0x04, 0xFA, + 0xCB, 0xB3, 0x59, 0x34, 0xB2, 0x83, 0x17, 0xAE, + 0x2A, 0xD9, 0xEC, 0xD2, 0x6E, 0xD8, 0x0B, 0x68, + 0x7D, 0x36, 0x2D, 0x30, 0x31, 0x75, 0xEA, 0x7B, + 0x76, 0x13, 0x24, 0xC1, 0x59, 0x5F, 0xFA, 0x89, + 0x16, 0xF1, 0x1A, 0xC1, 0xCC, 0xED, 0xBD, 0xE0, + 0x56, 0x70, 0xBA, 0x4F, 0x49, 0x80, 0x35, 0x18, + 0x6F, 0x23, 0x4C, 0x7C, 0x3E, 0xEA, 0x00, 0x68, + 0xD3, 0xF4, 0xA6, 0x09, 0x76, 0x70, 0x62, 0x4E, + 0xB6, 0xDB, 0x83, 0xA6, 0x54, 0x0E, 0x28, 0x5D, + 0xE7, 0x15, 0x87, 0x49, 0xE2, 0xA4, 0x3A, 0x00, + 0x3D, 0x72, 0x94, 0x3E, 0xC0, 0x8E, 0xAE, 0x27, + 0xC9, 0x7A, 0xF0, 0x4A, 0xEE, 0xFB, 0xC3, 0x72, + 0xEF, 0x42, 0x15, 0x0F, 0xA2, 0x9B, 0xB0, 0xFF, + 0xE5, 0x61, 0xD5, 0x15, 0x17, 0xA1, 0xFB, 0x59, + 0x62, 0x34, 0x59, 0x76, 0xCA, 0xCD, 0xDD, 0xB0, + 0x6B, 0x54, 0x7C, 0xCD, 0xAB, 0xFE, 0xF4, 0x52, + 0x67, 0xE1, 0x20, 0xE2, 0x33, 0x3D, 0x7A, 0xD9, + 0x63, 0xE9, 0x92, 0x5D, 0x05, 0xC5, 0x44, 0x2C, + 0xE2, 0x92, 0x70, 0xE8, 0xF3, 0x7E, 0xB6, 0x11, + 0x75, 0x8D, 0x42, 0x01, 0xD3, 0xD8, 0x5A, 0xCE, + 0xF8, 0xE1, 0xFC, 0x49, 0x8B, 0x15, 0x20, 0xA9, + 0xE5, 0x27, 0x5D, 0x73, 0xC0, 0xD7, 0x73, 0xB2, + 0xF9, 0xF6, 0x23, 0x93, 0x35, 0xF6, 0x64, 0x3F, + 0xBB, 0xE4, 0x65, 0x46, 0x0C, 0xAB, 0x8D, 0xDE, + 0x0A, 0x17, 0xBA, 0x94, 0x87, 0xB3, 0x52, 0xE9, + 0x1E, 0xBF, 0x6B, 0x04, 0x64, 0x67, 0x63, 0x86, + 0x72, 0x1A, 0x97, 0xF3, 0xBD, 0xEF, 0x68, 0x77, + 0xE8, 0x3C, 0x68, 0xCB, 0x3B, 0x06, 0xF3, 0x54, + 0x4F, 0x6C, 0x1A, 0xC4, 0xC3, 0x0A, 0xDE, 0xEA, + 0x8C, 0x7E, 0x65, 0xFA, 0x25, 0x3E, 0x65, 0xF0, + 0xA4, 0x92, 0xCD, 0x69, 0xA4, 0xE9, 0xB8, 0x20, + 0x00, 0xE4, 0xF7, 0x80, 0x64, 0x75, 0xA1, 0xD2, + 0x32, 0xA4, 0x5E, 0xC3, 0xE1, 0x20, 0x34, 0x5B, + 0x49, 0xB8, 0x59, 0x2E, 0xE8, 0x51, 0xC7, 0x5A, + 0xB8, 0x9E, 0x2C, 0x3D, 0x8F, 0xC0, 0x46, 0x23, + 0x4E, 0x8A, 0x1B, 0xEB, 0x04, 0xCF, 0xFF, 0x77, + 0x98, 0x5E, 0x0D, 0xFA, 0x27, 0x4A, 0x11, 0x15, + 0x67, 0x7E, 0x63, 0x94, 0x30, 0x71, 0x15, 0x18, + 0xAE, 0x64, 0x9B, 0x44, 0x66, 0xA2, 0x24, 0x72, + 0x7C, 0x3A, 0x74, 0xC4, 0x50, 0x0F, 0x50, 0x4E, + 0x39, 0x04, 0x4D, 0x8C, 0x72, 0x75, 0x9B, 0x18, + 0x48, 0xE6, 0x04, 0x01, 0xD6, 0xDF, 0xE0, 0x64, + 0x38, 0x90, 0x88, 0xA2, 0x9F, 0x7B, 0x7B, 0x7F, + 0xEF, 0xD9, 0xDB, 0xF5, 0x4C, 0x70, 0xDC, 0xAF, + 0x38, 0x45, 0x59, 0x14, 0x53, 0x1C, 0xDD, 0x4E, + 0xAF, 0x9D, 0x3A, 0x61, 0xFC, 0xBC, 0x82, 0x88, + 0xC2, 0x43, 0x16, 0x5F, 0x53, 0xCE, 0x27, 0xE6, + 0x61, 0xD6, 0x4D, 0x40, 0x86, 0xD0, 0x2A, 0x99, + 0x60, 0xAA, 0x0D, 0x4E, 0x5A, 0x17, 0x75, 0xD3, + 0xD0, 0xCD, 0x05, 0x10, 0x07, 0xB0, 0xE3, 0x28, + 0xD8, 0x02, 0xBF, 0x0B, 0x0B, 0x7B, 0x8C, 0x74, + 0xCA, 0x38, 0x90, 0x62, 0x97, 0x25, 0x3C, 0x9C, + 0x72, 0x8D, 0xDA, 0xC6, 0xC7, 0xAA, 0xC9, 0xB4, + 0x29, 0x4B, 0xE5, 0xCD, 0x59, 0x62, 0x1B, 0x3C, + 0x5C, 0x5D, 0xB4, 0x32, 0x03, 0x12, 0x19, 0x26, + 0xC4, 0x90, 0xFB, 0xB4, 0xA7, 0x41, 0xD1, 0x03, + 0x4D, 0x2C, 0x60, 0x62, 0xE2, 0x15, 0x8D, 0xDD, + 0x4E, 0x48, 0x43, 0x46, 0x23, 0x55, 0xBE, 0x92, + 0x87, 0xAD, 0x16, 0x7B, 0xC6, 0x5C, 0xA0, 0xE2, + 0xE9, 0x18, 0x10, 0xB4, 0x2F, 0x92, 0xE5, 0xDA, + 0xC0, 0xA8, 0x29, 0x08, 0x22, 0x40, 0x34, 0x61, + 0x69, 0x84, 0xB3, 0x75, 0xFD, 0xAC, 0xEC, 0x81, + 0xA8, 0x2A, 0x20, 0x6C, 0xE7, 0x91, 0xA0, 0x22, + 0xC0, 0x62, 0xB2, 0xAE, 0x7C, 0x01, 0x1E, 0xFB, + 0x20, 0x7A, 0x61, 0x40, 0x71, 0x44, 0xC5, 0xA9, + 0xEB, 0x9C, 0x42, 0xF2, 0xC1, 0x4D, 0x93, 0xC7, + 0x1C, 0xA8, 0x65, 0x03, 0xD4, 0x04, 0x58, 0x57, + 0xDC, 0xF6, 0x2B, 0x10, 0x28, 0xF3, 0x80, 0x6D, + 0x89, 0xEC, 0x9D, 0xDB, 0x21, 0x87, 0x65, 0xD6, + 0x13, 0xD1, 0x8D, 0xF4, 0x0A, 0x29, 0x25, 0x75, + 0xCC, 0xE1, 0x2F, 0x96, 0xD4, 0xD0, 0x2C, 0x6C, + 0x25, 0x0F, 0x65, 0x8F, 0xFB, 0x62, 0x82, 0x22, + 0x0D, 0x69, 0xEE, 0x12, 0xA5, 0x76, 0x43, 0x56, + 0xCA, 0x47, 0xAA, 0xDD, 0x04, 0x17, 0xBF, 0x3F, + 0x76, 0xE6, 0xF9, 0x77, 0xA6, 0xFA, 0x46, 0x09, + 0x41, 0xEB, 0x03, 0x72, 0xB9, 0xF3, 0x87, 0xA5, + 0xA7, 0xEA, 0x74, 0xBE, 0x49, 0xD9, 0xCA, 0x01, + 0x19, 0x34, 0x77, 0x88, 0x4F, 0x5B, 0xA8, 0x4C, + 0xF5, 0xF2, 0x75, 0xE0, 0xD2, 0x05, 0xF1, 0x00, + 0xC7, 0xAA, 0x8D, 0x5C, 0x09, 0xEE, 0xEF, 0xAA, + 0xEC, 0x82, 0x3E, 0x4F, 0xCE, 0x95, 0x39, 0x8C, + 0xCD, 0x36, 0x83, 0xD0, 0x8B, 0x30, 0x87, 0xED, + 0x1E, 0x97, 0x6D, 0x72, 0x38, 0xD5, 0x30, 0x8F, + 0x84, 0xDF, 0xF3, 0x9C, 0xB1, 0x94, 0x8E, 0x92, + 0xD6, 0xB8, 0xBD, 0x25, 0x57, 0x45, 0x42, 0x21, + 0x66, 0xAF, 0xBB, 0xF2, 0xE0, 0x46, 0x02, 0x73, + 0x97, 0x9C, 0x62, 0x7C, 0x7F, 0xA9, 0x79, 0x86, + 0xD9, 0x9C, 0x64, 0xF0, 0x45, 0xC8, 0x23, 0x9A, + 0xB5, 0x1B, 0xB9, 0xCD, 0x98, 0x21, 0x5F, 0x36, + 0x16, 0x70, 0x94, 0x75, 0xAB, 0x3C, 0x4C, 0xCC, + 0x42, 0xBB, 0xC6, 0xEF, 0x45, 0x7E, 0x84, 0xE5, + 0x35, 0x87, 0xD3, 0x12, 0x36, 0xA4, 0x85, 0xD0, + 0x5F, 0x89, 0xE5, 0xDA, 0xA8, 0xCC, 0xD1, 0xC5, + 0xC3, 0x1B, 0xB3, 0x12, 0x96, 0x9A, 0x2D, 0x92, + 0x10, 0xD1, 0x3B, 0x7F, 0x54, 0xA3, 0xAE, 0x78, + 0xA6, 0x5B, 0x07, 0x4D, 0x06, 0xEC, 0xB4, 0x56, + 0x12, 0x9D, 0xA0, 0x3C, 0x31, 0x51, 0x2A, 0x4A, + 0xA9, 0x46, 0xBF, 0x08, 0xBE, 0xF0, 0x03, 0x71, + 0xD3, 0xAA, 0xE2, 0x57, 0xC7, 0x05, 0xA8, 0x5E, + 0x1B, 0x9E, 0xF4, 0x35, 0x69, 0xF0, 0xEC, 0x31, + 0x41, 0xCD, 0xB8, 0x7B, 0xA5, 0xF5, 0x63, 0x48, + 0x60, 0x70, 0x6C, 0x33, 0x2E, 0x60, 0xAF, 0x41, + 0xFE, 0x87, 0xFA, 0x80, 0xF7, 0x0F, 0x78, 0x80, + 0x74, 0xBB, 0x6A, 0xAC, 0x64, 0x7E, 0x9F, 0x65, + 0x70, 0x11, 0xB6, 0xEA, 0x83, 0x3B, 0x9E, 0xE1, + 0xB6, 0xE3, 0x7F, 0x6D, 0xC1, 0x7E, 0xBA, 0x16, + 0xE5, 0xA2, 0x9E, 0x8A, 0x67, 0x46, 0x90, 0xE6, + 0x00, 0x79, 0x5F, 0x9A, 0x6F, 0xEA, 0x22, 0xB8, + 0x68, 0xC4, 0xB5, 0x22, 0x94, 0x60, 0xE8, 0x49, + 0x22, 0x9F, 0x23, 0xDE, 0x14, 0x63, 0xB2, 0x92, + 0xA7, 0xC2, 0x6C, 0xCF, 0x1D, 0xA8, 0x87, 0x68, + 0x50, 0xD3, 0x59, 0xC5, 0xA9, 0xEF, 0xD1, 0x16, + 0xCB, 0x0A, 0xC9, 0x4C, 0x61, 0x8A, 0xCC, 0xAF, + 0x85, 0x5A, 0x64, 0x78, 0x4F, 0x15, 0x2C, 0xFD, + 0xAC, 0x63, 0x9D, 0x92, 0x80, 0x6E, 0xA6, 0x7B, + 0xD5, 0x40, 0x3A, 0xD9, 0x1A, 0x94, 0x6C, 0x6A, + 0xDD, 0xA1, 0xD1, 0xC2, 0xA5, 0x07, 0xBB, 0x31, + 0xED, 0xFF, 0xCB, 0x88, 0x21, 0x94, 0x0D, 0x78, + 0x1D, 0x7C, 0xB8, 0xDD, 0xEA, 0x0B, 0x9C, 0x47, + 0xC1, 0xEB, 0xC9, 0x55, 0x3F, 0xBB, 0x2C, 0xFF, + 0x10, 0xD4, 0xF0, 0x80, 0xB9, 0x06, 0xA7, 0x5C, + 0x43, 0x5F, 0xB8, 0xDB, 0x88, 0x0D, 0x01, 0xF9, + 0xEC, 0x18, 0xDD, 0x2D, 0x37, 0x00, 0x95, 0x38, + 0xDD, 0x92, 0x0A, 0x56, 0xC4, 0x9E, 0xE8, 0x20, + 0xDF, 0xEC, 0xB3, 0x64, 0x79, 0x7D, 0x5D, 0xCD, + 0x45, 0x72, 0xC9, 0x52, 0x17, 0xFB, 0x29, 0xC1, + 0xF4, 0xB1, 0x89, 0x38, 0x97, 0x60, 0xBD, 0x5D, + 0xBF, 0x5D, 0x71, 0x53, 0x10, 0xB1, 0x7B, 0xEB, + 0xEF, 0xEE, 0xCF, 0x76, 0x5E, 0x66, 0xC0, 0x5D, + 0xD5, 0xC3, 0xB2, 0x02, 0x9F, 0x7F, 0xA4, 0xE7, + 0x57, 0x9E, 0xD9, 0xD3, 0xA6, 0x51, 0x03, 0xF1, + 0xE1, 0xB3, 0x59, 0x03, 0xE2, 0x30, 0x82, 0xAA, + 0xC3, 0x7A, 0xF8, 0x04, 0xFA, 0xE1, 0xF5, 0x8B, + 0x0B, 0x93, 0x5C, 0xD3, 0x2D, 0x83, 0x0A, 0x8E, + 0x8A, 0x9D, 0x35, 0xBA, 0xF3, 0x49, 0x5A, 0x7A, + 0x4F, 0x05, 0xB3, 0xF8, 0x3D, 0xF6, 0x37, 0x36, + 0x62, 0xD5, 0x48, 0x15, 0xFA, 0x6D, 0x00, 0xB9, + 0x49, 0xE3, 0x70, 0x95, 0x3C, 0xF7, 0x56, 0xF6, + 0xE2, 0xB7, 0x49, 0xDD, 0x3A, 0x94, 0x71, 0xC4, + 0x40, 0x1E, 0x9F, 0x74, 0xC9, 0x84, 0xE0, 0x2F, + 0x17, 0x2A, 0x6C, 0xD9, 0x9A, 0x17, 0x39, 0x7E, + 0x09, 0xC8, 0x22, 0x16, 0x63, 0x3B, 0x5A, 0xB5, + 0x24, 0xB0, 0xE4, 0xA5, 0xB2, 0x90, 0x70, 0xB0, + 0xEC, 0xB6, 0xB3, 0xFF, 0x18, 0x70, 0xF6, 0x07, + 0xFA, 0xCA, 0x9A, 0x15, 0x3D, 0x62, 0xB9, 0x5F, + 0x50, 0xD7, 0x3B, 0xA8, 0x19, 0xD2, 0xA1, 0x07, + 0x11, 0xC7, 0x9F, 0x92, 0xEA, 0x9B, 0xAD, 0xB3, + 0x32, 0xCE, 0xB7, 0xF3, 0xE2, 0x1D, 0x92, 0x83, + 0xCC, 0xD1, 0x73, 0x03, 0x19, 0xA5, 0x51, 0x08, + 0xE8, 0x2B, 0x74, 0x00, 0x87, 0xD2, 0x39, 0x0A, + 0x46, 0x9C, 0xE7, 0x7F, 0x24, 0x71, 0x51, 0x61, + 0x9D, 0x1B, 0x9F, 0x1E, 0xB3, 0x29, 0x8E, 0x26, + 0x25, 0x7B, 0x46, 0xD9, 0xA8, 0x43, 0x2A, 0x21, + 0xCE, 0x2F, 0x93, 0x3C, 0xC0, 0x32, 0x9D, 0x7B, + 0xE3, 0x93, 0xE4, 0xE1, 0xD8, 0x5E, 0x31, 0x74, + 0xBB, 0x08, 0x4D, 0x78, 0x1D, 0x5A, 0x87, 0x1D, + 0xDC, 0x4A, 0xBD, 0x05, 0xD4, 0x42, 0x3A, 0x05, + 0x02, 0xA9, 0x70, 0xD0, 0x49, 0x18, 0x26, 0xCD, + 0xDA, 0xAC, 0x9C, 0x97, 0xEA, 0xDD, 0x72, 0x9D, + 0x61, 0x4E, 0xB6, 0xE4, 0x9B, 0xE0, 0xE5, 0xB1, + 0x11, 0xE3, 0x2F, 0x26, 0xC1, 0x91, 0xE4, 0x6B, + 0x92, 0xAE, 0x8E, 0xE1, 0xF2, 0x76, 0x35, 0x1D, + 0x90, 0x3B, 0x0B, 0x22, 0x15, 0x39, 0x19, 0xF4, + 0x89, 0x6E, 0xAB, 0xA7, 0xC6, 0xB5, 0xBB, 0x86, + 0x40, 0x0D, 0x88, 0xE2, 0x2A, 0x31, 0xA5, 0xC3, + 0x1C, 0x22, 0x4C, 0x01, 0x4F, 0xAD, 0xDD, 0xC0, + 0xBD, 0x03, 0x5A, 0xB1, 0xC3, 0x93, 0xDF, 0xE9, + 0x75, 0xCA, 0xB1, 0xBF, 0xC9, 0x58, 0xC8, 0x53, + 0x41, 0x6E, 0x12, 0xAC, 0x6A, 0xD4, 0x00, 0x94, + 0xFF, 0xB2, 0x66, 0xDA, 0x98, 0xB4, 0xEF, 0x6D, + 0x58, 0x85, 0xB9, 0xE2, 0x11, 0x80, 0xB4, 0xBA, + 0x82, 0x1F, 0x4D, 0x7D, 0x23, 0x35, 0xE3, 0x70, + 0x0F, 0xF1, 0xBF, 0x5D, 0x05, 0xBF, 0xCB, 0xDF, + 0x3B, 0x32, 0x02, 0xAA, 0x35, 0xFA, 0x72, 0xC1, + 0x5D, 0x71, 0x6C, 0xE5, 0x77, 0xAA, 0x44, 0x26, + 0xF1, 0x73, 0xF4, 0x47, 0x3D, 0xB5, 0x5B, 0xED, + 0xEF, 0x00, 0x21, 0x3A, 0x72, 0x7A, 0x17, 0x10, + 0xE0, 0xE6, 0x7D, 0xB9, 0x4B, 0x8E, 0xA2, 0x75, + 0xB4, 0xD6, 0x13, 0xE3, 0xB8, 0xB5, 0x76, 0x8F, + 0xB4, 0xC6, 0xEE, 0xB6, 0x30, 0x72, 0x27, 0xA9, + 0x6B, 0x36, 0x93, 0x2D, 0x8D, 0x19, 0xB0, 0xFE, + 0x3D, 0x2F, 0x5C, 0xE9, 0xAC, 0x23, 0x4E, 0xA1, + 0xE7, 0xA1, 0x5F, 0x52, 0xAB, 0x2A, 0xA2, 0x81, + 0x4F, 0x42, 0xA6, 0x8D, 0x0E, 0xA6, 0x99, 0x21, + 0xBA, 0xD6, 0xF8, 0x79, 0x14, 0x65, 0x23, 0x90, + 0xE7, 0x11, 0xD9, 0xC7, 0xE7, 0x39, 0x22, 0x4A, + 0x2E, 0xD6, 0xA7, 0xAA, 0x60, 0x21, 0x3F, 0xDF, + 0x30, 0x09, 0x87, 0x5F, 0x79, 0x3D, 0x04, 0x99, + 0x36, 0x1E, 0xCF, 0xDB, 0x79, 0xF3, 0xA4, 0xBC, + 0xD7, 0x5F, 0x2E, 0x3D, 0x84, 0x74, 0x2C, 0x70, + 0xB5, 0xF5, 0xE8, 0xF4, 0x80, 0x6F, 0xB5, 0x4B, + 0xFB, 0xB7, 0xC9, 0x0E, 0xF2, 0xC5, 0x1B, 0xB4, + 0x41, 0x48, 0xFE, 0x33, 0xC1, 0xC6, 0xBA, 0x64, + 0x9A, 0x35, 0xDF, 0x20, 0x5E, 0x5B, 0x4C, 0xCD, + 0xE3, 0xA3, 0x43, 0xA6, 0x87, 0x86, 0x9B, 0xB4, + 0x69, 0x8C, 0xB4, 0xFA, 0x2E, 0xB2, 0xFA, 0x67, + 0xDE, 0xF4, 0xF4, 0x15, 0x42, 0x74, 0xBB, 0xEF, + 0xAE, 0x65, 0x7F, 0x1D, 0x14, 0xA6, 0x66, 0x8A, + 0xEA, 0xB6, 0xDE, 0x02, 0x98, 0x70, 0x34, 0x40, + 0x09, 0xF2, 0xB8, 0x6B, 0xA9, 0x5E, 0xC1, 0x0C, + 0x39, 0x94, 0xB2, 0x21, 0xA4, 0x7F, 0x80, 0xF5, + 0xF7, 0xE5, 0x9C, 0x6D, 0xCE, 0x4E, 0x59, 0x76, + 0x0E, 0x20, 0xBB, 0x04, 0x41, 0xD2, 0xEB, 0x91, + 0x19, 0x14, 0x43, 0xF0, 0xE8, 0xD4, 0xC3, 0x76, + 0x49, 0x7D, 0xE4, 0x52, 0xF1, 0x8F, 0x2F, 0x90, + 0x64, 0xCA, 0x84, 0x89, 0xC1, 0x6D, 0x50, 0x7C, + 0x24, 0x07, 0x6A, 0x44, 0x23, 0x6E, 0x46, 0x56, + 0x63, 0x47, 0x6D, 0xAC, 0x12, 0x94, 0xD2, 0xCC, + 0x70, 0x95, 0x23, 0x88, 0xA0, 0xB4, 0x4D, 0x2F, + 0xC5, 0x44, 0x58, 0x67, 0x59, 0x8C, 0xFA, 0x94, + 0x4C, 0xCE, 0xD5, 0x0F, 0x6F, 0xE2, 0x37, 0x92, + 0xEF, 0x8E, 0xA9, 0x5F, 0xB7, 0x8C, 0x47, 0x2D, + 0xD3, 0xBD, 0x88, 0x73, 0xEF, 0xF7, 0x6D, 0xA7, + 0xE0, 0xBE, 0xC7, 0xE8, 0x6A, 0x70, 0x95, 0xD4, + 0x03, 0x0D, 0x72, 0x4A, 0x47, 0xD7, 0x52, 0x92, + 0xE2, 0x12, 0xB3, 0xE9, 0xDA, 0x3A, 0x73, 0xCD, + 0x2C, 0xD2, 0x68, 0x69, 0x7C, 0x03, 0x36, 0xDB, + 0x5E, 0x9D, 0x9B, 0xEB, 0x2C, 0xCB, 0xE0, 0x0C, + 0x2C, 0x3D, 0xB8, 0xBD, 0x2C, 0x22, 0xD5, 0x0A, + 0x97, 0xF2, 0x7E, 0x35, 0xB7, 0xC7, 0xC3, 0x93, + 0xBC, 0x73, 0xF2, 0x19, 0x07, 0xE8, 0xE6, 0x9B, + 0x0C, 0x15, 0x44, 0xC1, 0xDB, 0x4C, 0x4A, 0xA8, + 0x36, 0x92, 0x3A, 0xD2, 0xED, 0xD7, 0xE4, 0x2B, + 0x49, 0x46, 0x49, 0x89, 0x4C, 0x7F, 0x93, 0xEE, + 0x47, 0x5F, 0x04, 0x36, 0x2D, 0x0A, 0x34, 0xD8, + 0x7C, 0xB3, 0xC6, 0xE6, 0x0F, 0x22, 0xD8, 0x6C, + 0x45, 0xA9, 0x0E, 0x13, 0x24, 0x1D, 0xB4, 0xE9, + 0xB8, 0x3E, 0x28, 0x4F, 0xCC, 0x16, 0xC1, 0x71, + 0xBD, 0x29, 0xA6, 0x00, 0xF7, 0x3B, 0x3D, 0xB4, + 0xA9, 0xD7, 0x1E, 0x2B, 0x66, 0x28, 0x10, 0xBD, + 0xFA, 0x00, 0xA9, 0x98, 0x7D, 0x34, 0x82, 0xBD, + 0x04, 0xD2, 0x79, 0x86, 0x37, 0x0A, 0x97, 0x98, + 0x9A, 0x16, 0xF1, 0xE3, 0xE2, 0x54, 0x68, 0x88, + 0xC6, 0x60, 0x05, 0xED, 0x21, 0x11, 0x32, 0xC4, + 0x83, 0xD1, 0x9A, 0x27, 0xA2, 0xE0, 0x9E, 0x76, + 0x6A, 0xE6, 0x50, 0x6D, 0xE8, 0xE6, 0xB2, 0xA7, + 0xD1, 0x73, 0xBB, 0x4A, 0xFD, 0x53, 0x8F, 0xA4, + 0x3F, 0x87, 0x59, 0xB8, 0x51, 0xA3, 0xF7, 0xD7, + 0xB8, 0x86, 0xB9, 0x30, 0xCF, 0xE2, 0xEB, 0x8A, + 0xAF, 0x74, 0xEB, 0x8F, 0x50, 0xB0, 0xA7, 0xCD, + 0x31, 0xF0, 0x16, 0x8D, 0x00, 0x25, 0x05, 0xE4, + 0x35, 0x3C, 0x79, 0xE3, 0x2F, 0xA6, 0x4C, 0x5A, + 0xD5, 0xE4, 0x05, 0x3A, 0xB3, 0x5B, 0x77, 0x73, + 0x32, 0x31, 0x16, 0x6E, 0x43, 0x28, 0x58, 0xF8, + 0xEB, 0x02, 0xE3, 0xBF, 0xFD, 0x85, 0x6C, 0xAC, + 0x14, 0x5B, 0x73, 0x7A, 0x57, 0x57, 0x60, 0x2B, + 0xEC, 0xA7, 0x8C, 0xC3, 0xA9, 0x8D, 0xD8, 0x80, + 0x78, 0x56, 0x90, 0xB8, 0x7F, 0x42, 0xD1, 0xBD, + 0xAB, 0x17, 0xC5, 0x66, 0x3F, 0xED, 0xB4, 0xB9, + 0x5B, 0xB6, 0x23, 0xFA, 0xCA, 0x83, 0xE1, 0x7F, + 0x0C, 0xD4, 0xE3, 0x19, 0xCF, 0x38, 0x88, 0x00, + 0xC3, 0x1D, 0x92, 0x10, 0xC7, 0x43, 0x50, 0xC7, + 0x29, 0x31, 0x04, 0x4B, 0xB4, 0x93, 0x68, 0x66, + 0x84, 0x46, 0x56, 0xDB, 0x80, 0x87, 0x1F, 0xE0, + 0x33, 0xF2, 0x3E, 0x7B, 0x43, 0x07, 0x8F, 0x68, + 0x3A, 0x8E, 0x95, 0x3B, 0x8B, 0xE8, 0xC2, 0x50, + 0xD4, 0x8C, 0x33, 0x3C, 0x64, 0xCC, 0x4F, 0x2F, + 0xE2, 0x91, 0x36, 0xDB, 0xEE, 0xA1, 0x54, 0xB4, + 0x89, 0x3F, 0xBC, 0xB2, 0xF4, 0xA6, 0x13, 0x63, + 0xA5, 0xFF, 0x71, 0xAE, 0x7E, 0x29, 0x41, 0xD9, + 0x12, 0x24, 0xDB, 0xEB, 0xD3, 0x6B, 0x4B, 0x7F, + 0x6B, 0x6C, 0x78, 0x8E, 0x5E, 0x34, 0x7D, 0x9E, + 0x10, 0xEA, 0xD4, 0x2A, 0x9A, 0xC3, 0xAF, 0x14, + 0x87, 0xFC, 0x4B, 0x00, 0x7F, 0x1D, 0x68, 0x90, + 0xCA, 0x01, 0xA8, 0x48, 0x87, 0xA0, 0x7D, 0x4E, + 0xFB, 0xF8, 0x70, 0xAB, 0x3F, 0x82, 0x53, 0x28, + 0xE4, 0x17, 0x48, 0xEA, 0xFB, 0xBC, 0x4E, 0x7D, + 0x45, 0x83, 0x85, 0x0D, 0x16, 0x32, 0x93, 0x36, + 0x78, 0xE2, 0x73, 0x07, 0x81, 0xEF, 0x98, 0x26, + 0x7A, 0xED, 0x85, 0x4D, 0x00, 0x04, 0xC6, 0xF4, + 0xAD, 0x5D, 0x86, 0xA8, 0xBC, 0x71, 0x5D, 0x63, + 0x86, 0x1E, 0x2F, 0x89, 0x8E, 0xE0, 0x7D, 0xCF, + 0xD1, 0x79, 0xA1, 0x81, 0x00, 0x18, 0xDD, 0x72, + 0xCA, 0xDA, 0x2A, 0x90, 0x60, 0xD2, 0x3D, 0x1A, + 0x44, 0xB0, 0x74, 0x97, 0xAD, 0x71, 0x3C, 0x70, + 0xAD, 0x26, 0xB3, 0x4F, 0x1F, 0xE9, 0x90, 0x99, + 0xBD, 0x4B, 0x3C, 0xD6, 0xD9, 0x9A, 0xC0, 0x8B, + 0x45, 0xB2, 0x07, 0x71, 0xFA, 0xAE, 0x5C, 0x21, + 0x10, 0xBB, 0xFB, 0x2E, 0x6F, 0xDE, 0x78, 0xF1, + 0x6E, 0x84, 0x60, 0x52, 0x9E, 0xC4, 0xBC, 0x0A, + 0x20, 0xB3, 0xD1, 0xE6, 0xD2, 0x13, 0x5B, 0xCF, + 0xF6, 0x51, 0x7C, 0x41, 0x07, 0xA9, 0xBE, 0xB6, + 0x2B, 0xD2, 0x05, 0x24, 0xCC, 0xDA, 0xAD, 0xA2, + 0x94, 0xA6, 0x0A, 0xF5, 0xA9, 0x97, 0x95, 0xA5, + 0xBB, 0x6C, 0x50, 0x85, 0x94, 0x88, 0xB0, 0x15, + 0xB1, 0xB3, 0x9C, 0xC3, 0x2D, 0x97, 0x08, 0xDF, + 0x37, 0x66, 0x81, 0xBE, 0x9C, 0x85, 0xBC, 0x1C, + 0xA8, 0xE3, 0xAA, 0xA0, 0x5B, 0x61, 0xF0, 0x79, + 0x5E, 0xFE, 0xCD, 0xBE, 0x59, 0x8A, 0xAA, 0x4E, + 0xBD, 0x4D, 0x53, 0xBD, 0xB2, 0x8E, 0x51, 0xEE, + 0xBA, 0xC2, 0xA4, 0x8D, 0xBA, 0xC3, 0xA1, 0xC8, + 0x74, 0x29, 0x7E, 0x8E, 0x11, 0x4E, 0x2D, 0xF8, + 0x7C, 0xCB, 0xE9, 0x9A, 0x5A, 0x4A, 0x8B, 0xCF, + 0xD2, 0x85, 0xA3, 0xD9, 0x99, 0xC5, 0x20, 0x60, + 0xF9, 0x87, 0xCC, 0x31, 0xB7, 0x73, 0x51, 0xEA, + 0xE3, 0x7E, 0xEB, 0xFF, 0xAA, 0x52, 0xA9, 0xE2, + 0xE1, 0x26, 0xC8, 0x45, 0xFC, 0x66, 0x01, 0x25, + 0xF4, 0x27, 0xA4, 0x16, 0xCF, 0x62, 0x15, 0x83, + 0xF6, 0xA8, 0x46, 0xB9, 0xA1, 0x57, 0x3A, 0xC3, + 0x45, 0x8B, 0x71, 0x89, 0x85, 0x4F, 0x71, 0x22, + 0x54, 0xB2, 0x46, 0x38, 0x5D, 0x85, 0xE4, 0x7E, + 0x0D, 0x37, 0x2D, 0x60, 0x35, 0x45, 0xE5, 0x31, + 0x8F, 0x18, 0x53, 0xF7, 0x0C, 0x1C, 0x09, 0xD4, + 0xCC, 0x6A, 0xAD, 0x89, 0x66, 0x4D, 0xB1, 0x0E, + 0xD0, 0x2A, 0x5D, 0x7B, 0x6E, 0xF7, 0xD8, 0x10, + 0xB1, 0x7B, 0xAE, 0x8E, 0xD5, 0xB2, 0xBD, 0x80, + 0xBE, 0x34, 0x02, 0x39, 0xDA, 0xCA, 0xFC, 0x60, + 0x89, 0x3F, 0x44, 0x11, 0x99, 0x76, 0xFD, 0x0D, + 0x52, 0xBB, 0x39, 0x19, 0x66, 0xBC, 0x64, 0xDB, + 0x51, 0xB3, 0x4B, 0xD7, 0x68, 0xCA, 0xE4, 0x65, + 0xDF, 0x0E, 0x3F, 0x2B, 0x26, 0x4A, 0xB3, 0x45, + 0x79, 0x77, 0xAC, 0x43, 0x68, 0x40, 0x4F, 0x8F, + 0x2F, 0xA8, 0x2D, 0xDE, 0x2A, 0x9D, 0x5E, 0xE3, + 0x01, 0x87, 0x2B, 0x40, 0xB0, 0x35, 0x2C, 0x0A, + 0x14, 0x19, 0x8E, 0x85, 0x24, 0x35, 0xD7, 0x2C, + 0x5D, 0x59, 0xC2, 0xF0, 0xCE, 0xCE, 0xCD, 0x07, + 0xD8, 0x9B, 0x96, 0xEF, 0x32, 0xF6, 0xA0, 0x7E, + 0x78, 0xF7, 0xFF, 0x6E, 0x94, 0xFE, 0x8B, 0x47, + 0xB7, 0x96, 0xA3, 0x38, 0x8F, 0x94, 0xAD, 0x3F, + 0x84, 0x7E, 0x3E, 0x0C, 0x58, 0x41, 0x4D, 0x0A, + 0xA1, 0xA8, 0xEC, 0x4C, 0x0E, 0x87, 0x7C, 0x71, + 0x86, 0xE0, 0x97, 0x92, 0x7E, 0xBD, 0x56, 0x07, + 0x8C, 0x36, 0x1C, 0x57, 0xF2, 0x00, 0xA0, 0xD3, + 0x5A, 0x47, 0x52, 0x8C, 0xA1, 0x4C, 0x08, 0x7D, + 0xC2, 0x14, 0xF0, 0x78, 0x16, 0x61, 0x4E, 0xF5, + 0x85, 0xAB, 0x42, 0xE9, 0x97, 0x52, 0x49, 0xBD, + 0x30, 0xD6, 0xC3, 0xEC, 0x86, 0xE5, 0x5E, 0xCD, + 0x61, 0xC8, 0x90, 0x2E, 0x28, 0xED, 0x88, 0xC7, + 0x07, 0x5C, 0xC6, 0x82, 0x7A, 0xA3, 0x2A, 0xFC, + 0x18, 0x10, 0x4D, 0x31, 0x84, 0xC3, 0x19, 0x11, + 0x7D, 0xD5, 0xC9, 0x67, 0x87, 0x6C, 0x9C, 0xD5, + 0x65, 0xB1, 0x7D, 0xA0, 0x1F, 0x74, 0x9B, 0xB2, + 0xB1, 0xF9, 0xDC, 0xBF, 0xBF, 0xC1, 0xC2, 0xB5, + 0x62, 0x87, 0x1C, 0x5C, 0xE0, 0x4F, 0x48, 0x39, + 0x23, 0x23, 0x34, 0x26, 0x22, 0x07, 0xC3, 0xD4, + 0xCE, 0x33, 0xD2, 0x9C, 0x2C, 0x4E, 0xA2, 0xB5, + 0xB4, 0xAB, 0x5C, 0xE6, 0x35, 0x96, 0x3E, 0x8B, + 0x26, 0x88, 0xDA, 0x20, 0x75, 0x60, 0xE3, 0xA3, + 0x9F, 0x95, 0xFA, 0x91, 0x9C, 0xB9, 0xD3, 0xBF, + 0xE0, 0x14, 0xF0, 0x08, 0x18, 0x9E, 0xF7, 0x86, + 0xCC, 0x54, 0xF4, 0x86, 0x0F, 0x28, 0xAA, 0x4C, + 0xD6, 0x51, 0xCD, 0xCF, 0x0F, 0x56, 0x10, 0x7D, + 0xC2, 0x95, 0xB5, 0xB9, 0x9E, 0x5C, 0x25, 0x64, + 0x85, 0xFD, 0x57, 0xF1, 0x9D, 0xC1, 0x2B, 0x6B, + 0x29, 0x6C, 0x03, 0x16, 0x35, 0x33, 0x11, 0xD5, + 0xA4, 0x40, 0xA0, 0xC3, 0xC3, 0xC1, 0xDB, 0x2A, + 0xA1, 0x85, 0x49, 0x22, 0x49, 0x73, 0xAB, 0x5E, + 0xAA, 0x77, 0x22, 0x3F, 0x27, 0xCE, 0x20, 0x64, + 0xE3, 0x34, 0x4A, 0x10, 0x65, 0xFD, 0x51, 0x28, + 0x38, 0x5E, 0xE8, 0x2B, 0xC2, 0xBC, 0x70, 0x9C, + 0x97, 0x23, 0xC1, 0xAA, 0xA4, 0x5B, 0xB8, 0x34, + 0x0E, 0x9E, 0x36, 0x60, 0x28, 0xC7, 0xFA, 0xA3, + 0x98, 0xD3, 0x80, 0xAB, 0x03, 0xAB, 0xED, 0x72, + 0x2F, 0x89, 0x40, 0x74, 0x51, 0xDC, 0x09, 0x65, + 0x9B, 0x04, 0x3B, 0x87, 0xA4, 0x75, 0xD6, 0xF9, + 0xE8, 0xD3, 0xE6, 0xFE, 0x3F, 0x1B, 0xD4, 0x35, + 0x93, 0x21, 0xC3, 0x4E, 0x79, 0x6F, 0xD9, 0x2C, + 0x87, 0x2B, 0xDA, 0xAB, 0x54, 0xDD, 0x32, 0x49, + 0xD1, 0xC5, 0xD3, 0x70, 0xA7, 0x03, 0xA4, 0x42, + 0xC1, 0x4A, 0xF6, 0x37, 0xD7, 0xC2, 0x46, 0x58, + 0xB6, 0xA7, 0x02, 0xC0, 0x4B, 0x8C, 0xFB, 0x58, + 0x9F, 0x5F, 0x49, 0x0F, 0x6A, 0x34, 0x8C, 0xE7, + 0x39, 0x29, 0x7C, 0x31, 0x5B, 0xE2, 0xC8, 0x11, + 0x1B, 0xB7, 0xFE, 0x21, 0x40, 0x75, 0x8E, 0x54, + 0xF6, 0xEE, 0x6C, 0x98, 0x21, 0x1D, 0x6D, 0xA0, + 0xCD, 0x9E, 0x93, 0xB0, 0xF2, 0x57, 0xD9, 0x17, + 0x90, 0x41, 0x7E, 0xA7, 0xF6, 0x13, 0x1D, 0x5D, + 0x8B, 0x07, 0x0C, 0xAA, 0x59, 0xCC, 0xE8, 0xFB, + 0xBE, 0x7E, 0x7A, 0x3D, 0x19, 0xF6, 0x84, 0x79, + 0xC2, 0xCC, 0xCF, 0x60, 0x3F, 0x99, 0x73, 0xF3, + 0xEA, 0xB4, 0x55, 0xE2, 0x44, 0xFE, 0x2C, 0x89, + 0xF8, 0x55, 0xE2, 0xE0, 0xF9, 0x4A, 0x9D, 0xD7, + 0xE4, 0x40, 0x0E, 0x25, 0x76, 0x79, 0xB3, 0xBD, + 0x1A, 0x74, 0xC6, 0x81, 0xF5, 0x60, 0x3E, 0xF0, + 0xB7, 0x53, 0xF0, 0xB7, 0x1A, 0x19, 0xC8, 0x9C, + 0x68, 0x75, 0xBC, 0xA9, 0x96, 0x87, 0xBF, 0xFA, + 0x5A, 0x60, 0x8B, 0xEC, 0x46, 0x19, 0x00, 0xB2, + 0x48, 0x25, 0xE2, 0x45, 0xBA, 0xB6, 0xD6, 0xFA, + 0x56, 0xEE, 0x0B, 0xCD, 0xE7, 0x77, 0x16, 0x56, + 0x04, 0xD1, 0x62, 0x89, 0x30, 0x7C, 0x19, 0xF2, + 0x4C, 0x43, 0xAB, 0x60, 0x5D, 0x10, 0x9D, 0x1A, + 0xEA, 0x09, 0x54, 0x09, 0xD4, 0xFC, 0x4D, 0x90, + 0x35, 0x68, 0xF1, 0xA5, 0x1F, 0xC1, 0x77, 0x45, + 0x27, 0x94, 0x47, 0x8F, 0x05, 0x6D, 0xEC, 0xD7, + 0x50, 0x2C, 0xD7, 0xE1, 0x01, 0x15, 0x44, 0x9E, + 0x95, 0x4C, 0xE9, 0x2E, 0xD6, 0x9B, 0x5F, 0xF7, + 0x4D, 0xF1, 0x7B, 0x3A, 0x87, 0xF7, 0xDC, 0x89, + 0xA7, 0x96, 0x08, 0xCE, 0x5F, 0x04, 0x95, 0x00, + 0x29, 0x8E, 0x04, 0x37, 0x01, 0x6D, 0xEB, 0x95, + 0x64, 0x04, 0x46, 0xD9, 0xC5, 0xCB, 0x40, 0x74, + 0x97, 0xCD, 0x37, 0xE4, 0x93, 0x98, 0x42, 0x39, + 0xDB, 0xAB, 0xC9, 0x15, 0xE5, 0x2F, 0x96, 0xCB, + 0xF4, 0xF0, 0x18, 0x45, 0x25, 0xF2, 0x67, 0xDB, + 0x8D, 0xCD, 0x7F, 0xB1, 0x5C, 0xDC, 0x0E, 0xA2, + 0x06, 0xC0, 0x11, 0x41, 0x14, 0xB3, 0x4F, 0x8C, + 0x62, 0x5F, 0x69, 0x5C, 0xE6, 0x1F, 0xF2, 0x0F, + 0x50, 0x05, 0xF2, 0xAF, 0x2D, 0x7D, 0xDF, 0x4E, + 0xF1, 0xC2, 0x40, 0xB6, 0x5E, 0xB4, 0x84, 0x63, + 0xF0, 0x08, 0xEC, 0xCF, 0xDB, 0x78, 0x58, 0xA2, + 0xD8, 0xEE, 0x67, 0xAA, 0x1D, 0x62, 0xFD, 0x33, + 0x5C, 0xD0, 0x77, 0x91, 0xC5, 0xF9, 0xC8, 0xBD, + 0x74, 0x0F, 0x7E, 0x74, 0x26, 0x57, 0x18, 0x25, + 0x89, 0x04, 0x19, 0xB2, 0x43, 0x6E, 0x05, 0xF7, + 0x76, 0x8C, 0xC1, 0x33, 0x0C, 0xE4, 0x3B, 0x0B, + 0x11, 0x99, 0x35, 0x5D, 0x24, 0xFE, 0x16, 0x3E, + 0x93, 0x3A, 0x47, 0x30, 0xAA, 0x85, 0x37, 0x4A, + 0xD0, 0x6C, 0x80, 0x5B, 0xD1, 0xF7, 0xAB, 0x91, + 0x5E, 0xB7, 0x8B, 0x6D, 0x56, 0x19, 0xBD, 0xEC, + 0x8B, 0x85, 0xE8, 0x41, 0x7D, 0xAD, 0x24, 0x74, + 0x2B, 0x07, 0xF6, 0xE8, 0x4F, 0xCE, 0x1E, 0xDC, + 0x27, 0xD3, 0x22, 0x98, 0xE3, 0x09, 0x9A, 0x19, + 0x04, 0xFE, 0x49, 0x28, 0x62, 0xEA, 0x98, 0x90, + 0x7F, 0x23, 0x46, 0xCE, 0x39, 0x58, 0xE5, 0x5A, + 0x93, 0x5A, 0x85, 0xED, 0xAB, 0x56, 0xC8, 0x7C, + 0xE2, 0x48, 0x9D, 0x82, 0x67, 0x29, 0x8D, 0x56, + 0xF4, 0xB7, 0x3F, 0x69, 0x56, 0x0B, 0x21, 0x9B, + 0x81, 0x6B, 0xB1, 0x45, 0xC1, 0x4F, 0x0B, 0xE2, + 0x78, 0xA4, 0x93, 0x07, 0xD4, 0x69, 0x62, 0xC0, + 0x33, 0x3A, 0x5B, 0x59, 0x35, 0x17, 0xC3, 0xED, + 0xB6, 0xF7, 0x02, 0x0A, 0x97, 0x88, 0x39, 0xFE, + 0x11, 0x82, 0x88, 0xE4, 0xD4, 0xB3, 0xE8, 0x0C, + 0xD7, 0x5C, 0xE4, 0x68, 0x74, 0xBC, 0xE5, 0xA7, + 0x1F, 0x8C, 0x26, 0x1F, 0xFE, 0x31, 0x00, 0xDA, + 0x42, 0x9C, 0x4E, 0xAB, 0x36, 0x90, 0x31, 0x36, + 0xDC, 0x78, 0x63, 0x69, 0xF6, 0xA2, 0x0C, 0xC7, + 0x89, 0x76, 0x28, 0x0F, 0x14, 0x9C, 0x5A, 0x8D, + 0x26, 0x87, 0xC1, 0x8D, 0x57, 0xBB, 0x4C, 0x79, + 0x35, 0x4A, 0xA5, 0xFD, 0x7F, 0x79, 0x1A, 0x60, + 0x00, 0xF9, 0xF7, 0x9D, 0x81, 0x92, 0x00, 0x2A, + 0xE0, 0xA1, 0x01, 0xCC, 0x27, 0xB1, 0xA8, 0xA5, + 0xC3, 0xE8, 0xF2, 0xBC, 0xD1, 0x37, 0x60, 0x11, + 0x2D, 0x86, 0xB2, 0x3A, 0xE0, 0x17, 0x52, 0x63, + 0x98, 0x01, 0x47, 0xA4, 0xE6, 0x54, 0x64, 0xA8, + 0x7C, 0xDB, 0x17, 0x02, 0xCC, 0xBE, 0x3B, 0x3A, + 0xD9, 0x06, 0x1E, 0xD4, 0xAD, 0x08, 0xEF, 0x74, + 0x30, 0xFC, 0x81, 0x52, 0x33, 0x57, 0xF3, 0x51, + 0x56, 0x34, 0xAE, 0x4B, 0x64, 0x4F, 0xC5, 0x6E, + 0x56, 0x86, 0x6F, 0xD9, 0xD8, 0x63, 0x5F, 0xF5, + 0x05, 0x83, 0xC9, 0xA5, 0x30, 0xD3, 0x4F, 0xF3, + 0x7F, 0x81, 0xBB, 0x68, 0x5F, 0x43, 0x20, 0x98, + 0x4F, 0x07, 0xDF, 0xE8, 0x29, 0x58, 0x2E, 0x68, + 0x90, 0x54, 0xA7, 0x65, 0xA7, 0x55, 0xC5, 0x11, + 0xBF, 0x49, 0xE2, 0x80, 0x8C, 0x51, 0x5C, 0xB7, + 0xAA, 0x16, 0x22, 0x1F, 0xB0, 0xCB, 0xF9, 0x7F, + 0x8B, 0x5B, 0x90, 0xD7, 0x27, 0x57, 0x41, 0xAA, + 0x74, 0x24, 0x4E, 0xDD, 0xCB, 0x50, 0x75, 0xBA, + 0xB1, 0x4C, 0x38, 0x2D, 0x93, 0x2B, 0x96, 0xC3, + 0x24, 0xC1, 0xF7, 0xA6, 0x1C, 0xD5, 0x10, 0x9E, + 0x36, 0x3B, 0xD8, 0x6F, 0xB4, 0x7D, 0xF3, 0x41, + 0xEB, 0x80, 0x1D, 0x1F, 0xE9, 0xC2, 0xE2, 0x95, + 0xB9, 0xDC, 0x45, 0x0D, 0xD1, 0x89, 0x68, 0x92, + 0x7F, 0x04, 0x34, 0x42, 0xF1, 0xEF, 0xFC, 0x7B, + 0x97, 0x2E, 0xD2, 0x97, 0x49, 0x50, 0xA4, 0x09, + 0xA1, 0x13, 0xB0, 0x69, 0xCE, 0x06, 0x7C, 0xB5, + 0xE9, 0x1A, 0x40, 0xAB, 0xFE, 0xFF, 0x16, 0xBD, + 0x7C, 0x08, 0xB1, 0x78, 0x24, 0x99, 0xA3, 0xB9, + 0xAE, 0x18, 0x46, 0xD0, 0x23, 0xF6, 0xE8, 0x0E, + 0x9B, 0x1C, 0xCA, 0xEF, 0x52, 0x4F, 0x09, 0xD8, + 0x26, 0x47, 0x7E, 0xDE, 0xCF, 0x18, 0xE6, 0xEC, + 0xD2, 0xBC, 0xB4, 0x01, 0x13, 0xE6, 0xC2, 0x70, + 0xA7, 0xD3, 0xC7, 0xFB, 0x59, 0x5C, 0x91, 0x6B, + 0x71, 0xBB, 0xA6, 0xB6, 0x50, 0x0A, 0xF0, 0xDC, + 0x5C, 0x62, 0x37, 0x42, 0x4C, 0x80, 0xBE, 0x0D, + 0x1F, 0xD7, 0xE5, 0x7A, 0x84, 0xC4, 0x6E, 0xCF, + 0x55, 0x88, 0xA1, 0x63, 0x66, 0x6F, 0x74, 0xC3, + 0xD7, 0x0D, 0xAE, 0xC6, 0x69, 0x2D, 0xA8, 0xF8, + 0x51, 0x74, 0x33, 0xE6, 0xB4, 0x52, 0x08, 0x40, + 0x49, 0x74, 0x10, 0x2F, 0x9B, 0x3C, 0x17, 0x5A, + 0x64, 0x22, 0x73, 0xBE, 0x24, 0xB6, 0x73, 0x84, + 0xCF, 0x5A, 0xE8, 0x3E, 0x3C, 0x58, 0x7F, 0x48, + 0x7D, 0x50, 0x62, 0xCF, 0x5C, 0xA9, 0x9B, 0xAC, + 0xFB, 0xDB, 0x34, 0x1F, 0x73, 0x97, 0xF9, 0xF5, + 0x4D, 0x34, 0x36, 0x59, 0x03, 0xBE, 0xE1, 0x05, + 0xC6, 0xBE, 0x62, 0xD6, 0x28, 0x63, 0x52, 0xB2, + 0xEF, 0x7B, 0x26, 0xEA, 0x3D, 0xE5, 0x89, 0x96, + 0xC1, 0xA1, 0xA0, 0xE8, 0x23, 0xC8, 0x66, 0x9F, + 0xBF, 0xE3, 0x39, 0xF4, 0x02, 0xEA, 0x35, 0xCB, + 0xDD, 0x2D, 0xE0, 0xF0, 0x98, 0x09, 0x94, 0xD3, + 0xB8, 0x21, 0x00, 0xDA, 0x8E, 0x10, 0xBD, 0xB2, + 0xCC, 0x88, 0xC1, 0x80, 0x5D, 0x79, 0xDE, 0xC7, + 0x6C, 0x38, 0xF4, 0xEE, 0x96, 0xF1, 0xA4, 0x07, + 0x84, 0x0D, 0x5C, 0xC6, 0xF1, 0xF5, 0x5E, 0x45, + 0x7F, 0x38, 0xBC, 0x5E, 0xF3, 0xD4, 0xE4, 0x94, + 0xA0, 0x36, 0x7D, 0x24, 0xC5, 0xB7, 0xC6, 0x4D, + 0xB0, 0x23, 0x97, 0xD2, 0xDC, 0xE5, 0x29, 0x88, + 0x0D, 0x55, 0xA1, 0x4F, 0x2C, 0x1A, 0x70, 0x8E, + 0x15, 0xDF, 0xE5, 0x44, 0xB2, 0x03, 0xEE, 0xFE, + 0x05, 0x26, 0xFB, 0xCA, 0xD2, 0xAA, 0x18, 0xFD, + 0x46, 0xAD, 0x05, 0x10, 0xD9, 0x50, 0x79, 0xBC, + 0x9C, 0xC5, 0x58, 0x83, 0x1E, 0x62, 0x84, 0x5F, + 0x52, 0x8C, 0xF3, 0x8A, 0x52, 0x37, 0xBF, 0xAA, + 0x8D, 0x09, 0xC7, 0x74, 0x25, 0x6E, 0xA4, 0xA8, + 0x39, 0x72, 0x5E, 0x76, 0x6F, 0x91, 0xF2, 0x10, + 0x50, 0x85, 0x21, 0x80, 0x50, 0xC4, 0xBA, 0x46, + 0x04, 0x92, 0xC9, 0x3B, 0x5F, 0x0E, 0xC7, 0x5B, + 0xB5, 0x98, 0xF3, 0x5C, 0x54, 0xFB, 0x49, 0x6F, + 0xB0, 0x9A, 0xBD, 0x93, 0x22, 0x8A, 0xE5, 0xFF, + 0x46, 0x58, 0xA0, 0x3A, 0x8F, 0x71, 0xB8, 0xCF, + 0xDA, 0xA9, 0x15, 0xFC, 0x98, 0x9A, 0x64, 0x39, + 0x2C, 0x6C, 0x95, 0x9E, 0x00, 0x73, 0x9A, 0x90, + 0x98, 0x80, 0x53, 0x9F, 0xF7, 0xE3, 0xD4, 0x6D, + 0xC8, 0x69, 0x76, 0x60, 0x5B, 0xEE, 0xBC, 0x8A, + 0x3B, 0x0B, 0x2E, 0xCD, 0xA6, 0x30, 0x1E, 0xBB, + 0x6E, 0x67, 0x1B, 0x98, 0xB6, 0x3A, 0xC4, 0xCD, + 0xA1, 0x94, 0x89, 0x22, 0x92, 0x5D, 0x47, 0x5E, + 0xFA, 0xF4, 0x0A, 0xCB, 0x28, 0x4F, 0x2D, 0x4D, + 0xE8, 0x6B, 0x29, 0x07, 0xE0, 0xB6, 0xD6, 0x0F, + 0x4E, 0x5D, 0x3F, 0xDC, 0x31, 0x83, 0x1D, 0xD9, + 0x2C, 0xC0, 0x9F, 0x48, 0x1E, 0xB6, 0x36, 0x7B, + 0x3F, 0x29, 0xBE, 0x75, 0x35, 0x97, 0x6E, 0xCD, + 0x82, 0xA6, 0x6A, 0xF0, 0x58, 0x12, 0xD2, 0x8F, + 0x6E, 0xC8, 0x94, 0x06, 0x09, 0x18, 0xE5, 0x57, + 0xE3, 0xC1, 0xF8, 0x14, 0x2B, 0x19, 0x62, 0x9E, + 0xA0, 0xC2, 0xF8, 0xF2, 0x7F, 0x8B, 0xB2, 0x8B, + 0x14, 0x62, 0xBA, 0xDC, 0xE9, 0xE2, 0x5B, 0x62, + 0x96, 0xF9, 0x11, 0x82, 0x43, 0xC8, 0x46, 0x05, + 0x0E, 0xA0, 0x03, 0x8F, 0x45, 0x3F, 0x3D, 0x68, + 0x6D, 0xBB, 0x71, 0x07, 0x62, 0x19, 0x2D, 0xA6, + 0x2B, 0xD9, 0x45, 0xEE, 0xD6, 0xD0, 0xA5, 0xD5, + 0xE2, 0x77, 0x9E, 0x04, 0x62, 0x09, 0xBE, 0xA8, + 0x12, 0x91, 0xDA, 0xCE, 0x15, 0xB6, 0x3B, 0xAD, + 0xA7, 0x72, 0x43, 0x49, 0x10, 0xE6, 0x55, 0x33, + 0x09, 0xDE, 0x8A, 0xFC, 0x94, 0xF1, 0x5A, 0x51, + 0x1E, 0xDA, 0x45, 0x22, 0xAE, 0x92, 0x3B, 0xBD, + 0xA8, 0xE9, 0x75, 0x3D, 0x4A, 0xBE, 0x12, 0xEB, + 0x1C, 0xC7, 0xE3, 0xD7, 0xFC, 0x2E, 0x03, 0x3E, + 0x5A, 0x3D, 0x9F, 0x6E, 0x1D, 0xC7, 0xAE, 0xDD, + 0x54, 0x8D, 0xF4, 0x23, 0xA7, 0x66, 0xA1, 0x7D, + 0x2F, 0x41, 0x07, 0xA9, 0xDB, 0xE7, 0x03, 0x42, + 0xAE, 0x9A, 0xCA, 0x6F, 0xD8, 0xD8, 0xCE, 0x47, + 0xA0, 0xE3, 0x3B, 0x76, 0x06, 0xB8, 0xD5, 0x87, + 0x78, 0x4F, 0x69, 0x8F, 0x1B, 0x81, 0x8A, 0xF1, + 0x5F, 0x5D, 0xEA, 0xA3, 0x6B, 0xB8, 0xB2, 0x8E, + 0x13, 0xE9, 0x6B, 0x5A, 0xAF, 0x7D, 0x3B, 0xBE, + 0x13, 0x66, 0x86, 0x37, 0x4E, 0xE2, 0xBC, 0x62, + 0xFD, 0x5A, 0xB5, 0xC8, 0xB6, 0x52, 0x3A, 0xDA, + 0x0F, 0x39, 0x7E, 0xD4, 0x73, 0x12, 0xDC, 0x91, + 0x11, 0x3A, 0x57, 0x13, 0xC9, 0x74, 0x5E, 0xFF, + 0xC9, 0x9A, 0xDA, 0x80, 0x03, 0xBF, 0xDC, 0x79, + 0xC1, 0xBA, 0x5A, 0x24, 0x4A, 0xFA, 0xBF, 0x21, + 0x7A, 0x58, 0x91, 0x6D, 0x73, 0x2D, 0xBD, 0x7C, + 0xA5, 0x00, 0x7F, 0x10, 0x0A, 0xF6, 0x07, 0x6E, + 0xE8, 0xB5, 0x8C, 0x1C, 0x61, 0x7F, 0x54, 0x0A, + 0x5C, 0x98, 0x63, 0xCA, 0xAA, 0x10, 0x9F, 0x4C, + 0x5F, 0x1E, 0xD2, 0xAD, 0xB2, 0x8C, 0xC7, 0x5A, + 0xC7, 0xEF, 0xE5, 0x1E, 0xFB, 0x15, 0xBB, 0xB6, + 0x8D, 0x61, 0x64, 0x91, 0x69, 0xEC, 0x24, 0x8B, + 0x1D, 0xB9, 0xE8, 0x6F, 0xBB, 0x36, 0x2F, 0x5A, + 0x09, 0xBC, 0xF7, 0x56, 0x0A, 0x42, 0x19, 0x3F, + 0x10, 0xC8, 0x15, 0x1B, 0xCC, 0xCE, 0x9D, 0x07, + 0x44, 0xD9, 0xFD, 0x21, 0x0E, 0x70, 0xA8, 0x42, + 0xD4, 0xB1, 0xDB, 0xEA, 0x70, 0xAD, 0xCD, 0xF5, + 0xDA, 0xB1, 0x0C, 0x3E, 0x40, 0x74, 0x3D, 0xEA, + 0x28, 0x37, 0x6B, 0x40, 0xEA, 0x61, 0x6F, 0x8C, + 0x6E, 0x7B, 0x23, 0x42, 0x96, 0xB3, 0xF0, 0xFF, + 0x6C, 0x32, 0xF3, 0x65, 0x17, 0x9F, 0x48, 0xF1, + 0x08, 0xC6, 0x0B, 0xD9, 0xFF, 0x72, 0x95, 0xB9, + 0x8F, 0x5C, 0x68, 0x10, 0xD4, 0x38, 0x32, 0x4F, + 0xB0, 0x07, 0xB5, 0x23, 0xE9, 0x3A, 0x12, 0x3A, + 0x84, 0xB3, 0xA7, 0x74, 0x85, 0x20, 0x85, 0x86, + 0x25, 0xBD, 0x32, 0x55, 0x27, 0x49, 0xBB, 0xCD, + 0xF2, 0xF0, 0x40, 0x27, 0x09, 0x50, 0x14, 0x5A, + 0x45, 0x1C, 0xD2, 0xB5, 0xC3, 0xEB, 0x46, 0x2C, + 0x45, 0x96, 0x16, 0x4A, 0x16, 0x68, 0xD9, 0x1B, + 0x22, 0x9C, 0x8C, 0x00, 0xFF, 0x3B, 0x01, 0xFD, + 0xC3, 0x08, 0xB2, 0x02, 0xD1, 0xFD, 0xA8, 0x27, + 0x0B, 0x47, 0x62, 0x1B, 0xE0, 0x26, 0xA2, 0xAD, + 0x39, 0x30, 0xC1, 0x8E, 0x84, 0x9C, 0x0D, 0x84, + 0xAC, 0x5B, 0x74, 0xC8, 0x17, 0x76, 0xE0, 0x97, + 0xF1, 0x46, 0x8C, 0x29, 0x1E, 0xA0, 0x1A, 0xBB, + 0xB5, 0x7E, 0xAE, 0xDF, 0x2B, 0xED, 0x04, 0x0D, + 0xE7, 0xF9, 0x6E, 0xB5, 0x2C, 0xA6, 0x3F, 0x4C, + 0x7B, 0x3D, 0x68, 0xCF, 0x1C, 0xB9, 0xCE, 0xF6, + 0xF5, 0xE8, 0x43, 0xC4, 0xA6, 0x89, 0x71, 0x88, + 0x8C, 0x90, 0x14, 0xA9, 0x92, 0x01, 0x09, 0xE1, + 0xEB, 0x24, 0xCE, 0x1A, 0x32, 0xD4, 0xAB, 0x0E, + 0xE9, 0x92, 0x27, 0xD0, 0xAC, 0x5E, 0x46, 0x0B, + 0xD3, 0x94, 0x29, 0xCC, 0x3E, 0x4B, 0x0D, 0xBA, + 0x12, 0x04, 0x7B, 0x30, 0xEA, 0xAF, 0x17, 0x77, + 0x8C, 0x7F, 0x1E, 0xB3, 0x53, 0x18, 0xA7, 0x6B, + 0x8A, 0x7C, 0xA4, 0x05, 0x4A, 0xA0, 0x00, 0x38, + 0x13, 0x33, 0x0E, 0x20, 0x3E, 0xEE, 0x0F, 0xD7, + 0x06, 0x16, 0xD3, 0x62, 0x97, 0x72, 0x43, 0xF9, + 0x07, 0x13, 0x9A, 0x4E, 0x74, 0x36, 0x76, 0x08, + 0x6C, 0x57, 0xA6, 0x12, 0xC4, 0xE8, 0x8F, 0x93, + 0xBB, 0x1D, 0x8A, 0x91, 0x48, 0x6C, 0x83, 0x63, + 0x58, 0x1C, 0x6E, 0x93, 0xAA, 0xB1, 0x2C, 0x3C, + 0x6D, 0x54, 0x38, 0xA6, 0x59, 0xC1, 0x0E, 0x78, + 0xEF, 0xDF, 0x01, 0x73, 0x3D, 0x31, 0xC2, 0x14, + 0x73, 0xCE, 0x52, 0x57, 0x42, 0xB9, 0xE8, 0x3E, + 0xBD, 0x9A, 0x42, 0xF6, 0xE4, 0x5A, 0x15, 0x1F, + 0xCE, 0x92, 0x36, 0x99, 0x0F, 0xC3, 0xAF, 0x5F, + 0x82, 0x58, 0x4B, 0x71, 0x29, 0xFB, 0xB5, 0xF2, + 0xEB, 0xA9, 0xF0, 0x93, 0x98, 0xF5, 0x3B, 0x21, + 0x67, 0x9C, 0xB6, 0xC9, 0x0D, 0x4B, 0x31, 0x28, + 0x54, 0x51, 0xF4, 0x6B, 0xB1, 0x17, 0x95, 0x39, + 0xC9, 0xFF, 0xE4, 0x29, 0x05, 0x40, 0xD3, 0x40, + 0xD5, 0x87, 0x78, 0xE8, 0xA8, 0xF6, 0x08, 0x95, + 0x8E, 0x82, 0xA5, 0x8E, 0xC3, 0xC0, 0x4D, 0x60, + 0x7F, 0xCF, 0x61, 0xD2, 0x3F, 0xEB, 0x34, 0xD9, + 0x70, 0xEC, 0x54, 0x93, 0x32, 0x30, 0x69, 0x0F, + 0x5F, 0x46, 0xF8, 0x4F, 0xF6, 0x39, 0x35, 0x71, + 0xC9, 0xF2, 0xF5, 0x8A, 0x31, 0x2E, 0xD5, 0xE0, + 0xC9, 0xAD, 0x2A, 0xC5, 0x81, 0x55, 0x7B, 0xF9, + 0x78, 0x74, 0x9B, 0xB8, 0x9B, 0xC8, 0x62, 0xB3, + 0x87, 0x26, 0x17, 0x6A, 0x09, 0xDD, 0x9C, 0x3A, + 0xB6, 0x1C, 0x00, 0x59, 0xCA, 0xA0, 0xF1, 0xA1, + 0x15, 0xE0, 0x60, 0x0F, 0xD9, 0x89, 0xBE, 0x2F, + 0xCF, 0x39, 0xB7, 0x5D, 0xDA, 0x46, 0x80, 0x67, + 0x14, 0x92, 0x19, 0x17, 0xC1, 0x45, 0x29, 0x09, + 0x8F, 0x4A, 0x65, 0x12, 0xDB, 0xD8, 0xF7, 0xC5, + 0x14, 0xE7, 0x47, 0xCC, 0x33, 0xE0, 0x9A, 0xBC, + 0x74, 0x8A, 0x67, 0xF9, 0x35, 0xD1, 0xED, 0x30, + 0x77, 0xDB, 0x64, 0x96, 0x50, 0x27, 0xF4, 0x75, + 0x25, 0xCB, 0x9D, 0xBD, 0xAA, 0x2D, 0xDA, 0x6E, + 0x32, 0x16, 0x00, 0x18, 0xD3, 0x97, 0x2C, 0xD5, + 0xDD, 0xF8, 0x51, 0xCE, 0x55, 0xFE, 0x41, 0x52, + 0x09, 0xB9, 0xDC, 0xAC, 0xC3, 0x7C, 0x75, 0xD0, + 0x26, 0x09, 0x93, 0x04, 0xF2, 0xC5, 0x52, 0xE4, + 0x31, 0x5C, 0xAD, 0x44, 0xEA, 0xDC, 0x09, 0x16, + 0x61, 0x09, 0x9E, 0xDB, 0xB5, 0xD2, 0x04, 0xD5, + 0x94, 0x2E, 0x0E, 0x4A, 0xBA, 0x4E, 0xCD, 0x67, + 0xF1, 0xD7, 0x52, 0x7C, 0xCD, 0x0F, 0xE7, 0x2F, + 0xEB, 0xA2, 0xB4, 0x26, 0xBB, 0xF8, 0x0B, 0x1F, + 0x26, 0x65, 0x14, 0xB3, 0xF3, 0x61, 0xBB, 0xD0, + 0x1C, 0xAA, 0x21, 0xEB, 0x11, 0x9F, 0x81, 0x80, + 0x7B, 0x7C, 0x3B, 0xE8, 0xFA, 0xF4, 0x2A, 0xB0, + 0x8B, 0x20, 0x58, 0x4D, 0xF9, 0xB3, 0x0D, 0xB3, + 0x6C, 0x66, 0xF3, 0xFB, 0xB6, 0x81, 0xF8, 0x7D, + 0xCE, 0x6B, 0x89, 0x72, 0x10, 0x76, 0x4D, 0x23, + 0xF2, 0xD2, 0xDF, 0xF2, 0xAA, 0x11, 0x45, 0x0E, + 0x71, 0x4D, 0xED, 0x0D, 0x53, 0x01, 0xA5, 0xE5, + 0x17, 0xCE, 0xB3, 0x1F, 0x28, 0xE8, 0x18, 0x7C, + 0x3D, 0xEF, 0xA4, 0x74, 0x8C, 0x41, 0x51, 0xF9, + 0x98, 0x87, 0x11, 0x92, 0x74, 0x73, 0xE9, 0xD8, + 0x31, 0xBB, 0xBF, 0xF9, 0x60, 0x23, 0x3D, 0x8E, + 0x7F, 0xAD, 0x7F, 0x22, 0xAF, 0xFB, 0xCD, 0x07, + 0x35, 0xED, 0x3B, 0xB9, 0xD5, 0x3B, 0xBF, 0x6B, + 0xC0, 0xC3, 0xD0, 0x99, 0xC7, 0x58, 0xB8, 0xAA, + 0x4F, 0xDD, 0x5C, 0x42, 0x48, 0x8E, 0x06, 0x79, + 0x06, 0x31, 0x65, 0x60, 0x19, 0x28, 0x8F, 0x62, + 0xAE, 0x1D, 0x0B, 0x7F, 0x6C, 0x48, 0x53, 0xC9, + 0x02, 0x4C, 0xE7, 0x37, 0xF2, 0x7D, 0xFD, 0x8C, + 0xDB, 0xC7, 0xA0, 0x4A, 0x4B, 0x8C, 0xE6, 0x0C, + 0x90, 0x8C, 0x54, 0x89, 0x56, 0x86, 0xDF, 0x04, + 0x23, 0x27, 0x16, 0x90, 0xCC, 0xEC, 0x64, 0x4F, + 0x66, 0x5B, 0x1E, 0x55, 0x33, 0x76, 0xFE, 0x47, + 0x8D, 0xDE, 0x2F, 0xBC, 0xBC, 0xC4, 0x04, 0xF8, + 0xDC, 0xE8, 0xDD, 0xDD, 0x37, 0x46, 0x86, 0x53, + 0x9E, 0x2C, 0x23, 0x7D, 0xEC, 0xF5, 0x37, 0xDA, + 0x26, 0x22, 0x21, 0x85, 0x16, 0x98, 0x16, 0x84, + 0xE3, 0xC3, 0xFA, 0x9D, 0x7F, 0xC5, 0x80, 0x97, + 0x45, 0xAA, 0xB6, 0x4C, 0x39, 0xBF, 0xD0, 0x28, + 0x23, 0xC3, 0x1C, 0x19, 0x92, 0xBD, 0x1B, 0x2B, + 0x96, 0x1F, 0xBA, 0xF3, 0x8E, 0xB1, 0x23, 0x0F, + 0x57, 0xAE, 0x3D, 0x47, 0x03, 0xB3, 0x77, 0xF9, + 0xEC, 0x45, 0x47, 0x3E, 0x3C, 0x91, 0x87, 0x1B, + 0x70, 0x2B, 0x1E, 0x83, 0x9C, 0xCB, 0xC4, 0x36, + 0x5E, 0x45, 0x7A, 0x4D, 0x07, 0x6E, 0x35, 0x37, + 0xA4, 0xDE, 0xD9, 0x66, 0xBB, 0xF8, 0x69, 0x02, + 0xFA, 0x88, 0xD6, 0x2C, 0xED, 0x0F, 0x4B, 0x74, + 0xAB, 0xFD, 0xA1, 0x23, 0x62, 0xFB, 0x03, 0xDD, + 0xF9, 0x50, 0xEB, 0x86, 0x00, 0xC5, 0xDE, 0x0D, + 0x85, 0x84, 0x63, 0x08, 0xCA, 0x77, 0xB1, 0x44, + 0x2F, 0xF3, 0xA9, 0xDB, 0x38, 0x94, 0x82, 0x9B, + 0x5C, 0x90, 0xD4, 0x9E, 0x4E, 0xA7, 0xFC, 0xBB, + 0x1B, 0x26, 0xA8, 0xBA, 0xBE, 0x2F, 0x2F, 0xC1, + 0x84, 0x79, 0x71, 0x76, 0xE0, 0x94, 0x4F, 0x65, + 0x00, 0x69, 0x08, 0x88, 0xF2, 0xEA, 0x9F, 0x69, + 0x3B, 0x07, 0x3F, 0x30, 0x00, 0x51, 0xFB, 0xDB, + 0xA5, 0xF3, 0xF4, 0xF2, 0x6D, 0x6E, 0x24, 0xC1, + 0xC0, 0x66, 0x2A, 0x1B, 0x7D, 0x5A, 0x61, 0x2A, + 0x99, 0x71, 0xD1, 0xD1, 0x8C, 0x1B, 0x30, 0xFD, + 0xC3, 0xA9, 0x9F, 0x60, 0x84, 0xF2, 0x73, 0x7D, + 0x50, 0xEF, 0xF6, 0x50, 0x78, 0x2F, 0xC8, 0xBC, + 0x07, 0x95, 0x95, 0x7A, 0xC9, 0xBA, 0xCD, 0xD4, + 0x27, 0xBA, 0xC8, 0x3E, 0x88, 0x7E, 0x49, 0xEF, + 0xDE, 0x55, 0x69, 0xC9, 0xB8, 0x69, 0xD9, 0xD0, + 0x92, 0x79, 0x9C, 0x40, 0x84, 0xD8, 0xD0, 0x08, + 0x98, 0xFB, 0x79, 0x75, 0x59, 0x47, 0xFE, 0x37, + 0xCB, 0x0B, 0x43, 0x73, 0x77, 0x21, 0x2F, 0xA0, + 0x86, 0x09, 0x24, 0x6E, 0x27, 0x95, 0x80, 0x9D, + 0x0A, 0xB1, 0x3C, 0x01, 0x8C, 0xCC, 0x3F, 0xEB, + 0x3A, 0xD2, 0x4A, 0xD1, 0xA1, 0x82, 0x6D, 0x14, + 0x2F, 0xC4, 0x64, 0x0C, 0x8E, 0x28, 0xF8, 0x62, + 0x55, 0x85, 0xA0, 0x4C, 0xBB, 0x8E, 0x66, 0x89, + 0xA2, 0xAA, 0xF4, 0x70, 0xE0, 0xB0, 0x88, 0xC7, + 0x26, 0xA0, 0xA9, 0xC4, 0x6C, 0xD2, 0xF1, 0x7B, + 0x9D, 0x43, 0x24, 0xD5, 0x79, 0x8A, 0x6D, 0x0A, + 0xBA, 0xFC, 0x1A, 0xD0, 0x55, 0x38, 0xBE, 0x75, + 0x7C, 0xB4, 0xAA, 0xA2, 0x0C, 0x36, 0x6D, 0x2A, + 0x85, 0xA3, 0x3F, 0x69, 0x3D, 0xCC, 0x0D, 0xF0, + 0xE1, 0x77, 0x20, 0x86, 0x14, 0x77, 0x76, 0x24, + 0x48, 0xEB, 0xAB, 0x02, 0xB4, 0x01, 0x41, 0x42, + 0x1C, 0x9E, 0xF4, 0xB2, 0x51, 0xB9, 0x62, 0xA6, + 0x64, 0x88, 0x8C, 0xAF, 0x99, 0x15, 0xA3, 0x9B, + 0x8A, 0xB5, 0x22, 0x88, 0x9B, 0x2F, 0xAF, 0x5F, + 0x3B, 0x5D, 0x79, 0x4E, 0xD4, 0xA8, 0x65, 0xFA, + 0x74, 0x73, 0x58, 0x09, 0x57, 0xD8, 0x35, 0x75, + 0xB6, 0x19, 0x53, 0xDF, 0x89, 0x1A, 0xB3, 0x81, + 0x2B, 0xF5, 0x89, 0xD4, 0x29, 0xEC, 0xC0, 0xA6, + 0x29, 0xCF, 0x2F, 0x6B, 0x44, 0x97, 0xA5, 0x79, + 0xBA, 0xC9, 0x52, 0x0C, 0x23, 0xBC, 0x6F, 0xDF, + 0x5E, 0xB6, 0xD7, 0xEE, 0xC3, 0x19, 0x60, 0x13, + 0x2D, 0x9D, 0x01, 0x45, 0x67, 0xEF, 0x4F, 0xEB, + 0x57, 0x51, 0x1F, 0x9D, 0x9F, 0xB7, 0x1C, 0xE1, + 0x30, 0xC8, 0x55, 0x9A, 0x3D, 0x9A, 0x55, 0x32, + 0x9A, 0x0D, 0x81, 0x24, 0x72, 0x00, 0x82, 0x6D, + 0xAC, 0x95, 0xB1, 0x04, 0x59, 0xD5, 0x58, 0x4B, + 0x64, 0x48, 0xF3, 0x96, 0xE5, 0xB9, 0x80, 0xDB, + 0x69, 0x80, 0x58, 0x49, 0x91, 0xF8, 0xEE, 0xA6, + 0xE1, 0xEC, 0x62, 0x2E, 0x36, 0x6D, 0x54, 0x1E, + 0x3E, 0xF4, 0xFA, 0x4A, 0x6D, 0x35, 0xE1, 0xDF, + 0x25, 0x46, 0x00, 0xBF, 0xDA, 0x5E, 0xAC, 0x67, + 0xBF, 0xF1, 0xFE, 0xC3, 0x23, 0x39, 0x70, 0xA7, + 0x3D, 0x02, 0x9B, 0x30, 0x9F, 0xAA, 0xF9, 0x59, + 0x7A, 0x7C, 0x16, 0xD4, 0xDB, 0x5E, 0x75, 0xCF, + 0x77, 0x85, 0xF5, 0x5C, 0x1B, 0xC1, 0x64, 0x97, + 0x03, 0x2D, 0x0C, 0x5A, 0x3A, 0x1C, 0xB7, 0xD6, + 0xD7, 0x98, 0xEA, 0x83, 0x6D, 0xB2, 0xDC, 0x9C, + 0x26, 0x67, 0x37, 0x56, 0xA6, 0xA4, 0x4D, 0xEF, + 0xAD, 0x98, 0x6A, 0xEE, 0xAE, 0x14, 0x24, 0x93, + 0xA2, 0x81, 0x55, 0xF5, 0x52, 0xFE, 0x45, 0x9A, + 0xCF, 0x4F, 0x65, 0xD0, 0xCE, 0xB6, 0xE0, 0xE6, + 0xCE, 0x9E, 0x3E, 0x94, 0x02, 0xA3, 0x00, 0x54, + 0x50, 0x93, 0x1C, 0xE3, 0x6C, 0xE2, 0xD2, 0x8B, + 0xE4, 0x51, 0xDA, 0x44, 0xFD, 0x01, 0x10, 0x34, + 0x0E, 0xA8, 0x5D, 0x45, 0x54, 0xE6, 0xBD, 0x1A, + 0xD2, 0xB8, 0xB9, 0xA1, 0xA7, 0xD8, 0x40, 0x67, + 0x7E, 0x9B, 0xFC, 0xC9, 0xEA, 0xD8, 0x30, 0x40, + 0x35, 0x33, 0xFE, 0x3F, 0x69, 0x15, 0x0C, 0x2C, + 0xF9, 0x58, 0x58, 0x79, 0x3C, 0x5F, 0x4D, 0x2C, + 0xCE, 0xFE, 0xFA, 0x99, 0xB6, 0x03, 0xED, 0xEF, + 0x9A, 0x48, 0x23, 0x35, 0xF5, 0x1A, 0xA0, 0x38, + 0x84, 0x91, 0xD7, 0xF1, 0x84, 0x98, 0xB3, 0xA8, + 0x27, 0xD9, 0xEB, 0xAD, 0x42, 0x04, 0xA9, 0x79, + 0x6B, 0x50, 0xD1, 0xF2, 0x3F, 0x87, 0x75, 0x4F, + 0x8C, 0x70, 0x64, 0x7F, 0x9A, 0xB1, 0x90, 0x5D, + 0x13, 0x8D, 0x25, 0x04, 0x8D, 0x08, 0x87, 0x0E, + 0xE7, 0xAC, 0x61, 0x17, 0x68, 0x1B, 0xB4, 0xB0, + 0x17, 0x5E, 0x66, 0x72, 0x13, 0xEA, 0xE6, 0x29, + 0xB0, 0xFD, 0xA5, 0xDF, 0x97, 0x5C, 0xB7, 0xBA, + 0x79, 0x09, 0x6C, 0xAB, 0xFA, 0x6E, 0xD5, 0xCD, + 0x77, 0x54, 0xCC, 0x18, 0x87, 0x0D, 0x92, 0x22, + 0x41, 0x2F, 0x4D, 0xD8, 0x56, 0xD4, 0x4D, 0xF0, + 0x09, 0x3A, 0xEF, 0xB0, 0xFD, 0xE4, 0xB2, 0x85, + 0x1A, 0x1C, 0xE2, 0xA2, 0x16, 0x63, 0x24, 0xB6, + 0xC7, 0x7E, 0xC5, 0xB6, 0x33, 0x8F, 0x4D, 0xE1, + 0x18, 0xC5, 0x9A, 0x7B, 0x78, 0x4D, 0x42, 0x66, + 0x24, 0x93, 0x90, 0x89, 0x9A, 0x53, 0xDF, 0xA2, + 0xC5, 0x32, 0x91, 0x0A, 0x59, 0x03, 0x98, 0x80, + 0x35, 0x6F, 0x83, 0x45, 0x13, 0xF8, 0xA1, 0xBB, + 0xFC, 0xC6, 0xA8, 0xBD, 0x4C, 0xEA, 0x66, 0xC8, + 0x2E, 0xB2, 0xE3, 0x83, 0x05, 0x5A, 0xB7, 0xBB, + 0x4C, 0x54, 0x18, 0x55, 0x3F, 0xA0, 0x17, 0x26, + 0xB6, 0x15, 0x50, 0x65, 0x93, 0xB1, 0x80, 0x91, + 0xBF, 0xC8, 0x00, 0x25, 0x33, 0x60, 0xDA, 0x8A, + 0x79, 0xDA, 0x1E, 0x25, 0xA9, 0x70, 0xB3, 0xFA, + 0xC2, 0x98, 0x3A, 0x64, 0x62, 0xF2, 0xDF, 0xC6, + 0x0D, 0x32, 0x19, 0x18, 0x6A, 0x7F, 0xAA, 0x6F, + 0xDF, 0x8E, 0x59, 0x61, 0xC1, 0x55, 0xDA, 0x92, + 0x02, 0x9B, 0x56, 0x16, 0x81, 0x6C, 0x6D, 0x7E, + 0x91, 0x83, 0x0F, 0x15, 0xF0, 0x39, 0xC3, 0x91, + 0x76, 0xD7, 0x44, 0x0B, 0x95, 0x96, 0xD3, 0x1D, + 0x25, 0x2C, 0x89, 0x8F, 0x27, 0x75, 0xAA, 0xCA, + 0x0F, 0x13, 0x1B, 0x7C, 0x9E, 0xD5, 0xB6, 0x18, + 0x0D, 0xB2, 0x92, 0x98, 0xFE, 0x69, 0x21, 0x4A, + 0x0A, 0x3C, 0x6F, 0x55, 0x02, 0xB7, 0xDB, 0x17, + 0xE4, 0x29, 0x1E, 0x35, 0x75, 0xFF, 0x77, 0x9D, + 0x47, 0x93, 0xAA, 0x4A, 0x75, 0x1B, 0xDF, 0xE0, + 0x93, 0x8A, 0x31, 0x0B, 0x1D, 0x6A, 0x9E, 0x95, + 0xE6, 0x54, 0x64, 0x7D, 0x93, 0x2D, 0x07, 0x58, + 0x82, 0xF3, 0x0C, 0x32, 0x21, 0x7A, 0xEB, 0x10, + 0xC5, 0x11, 0x78, 0x38, 0xD6, 0x79, 0xE3, 0xCF, + 0x04, 0x53, 0x45, 0xE6, 0xCD, 0xA5, 0x4C, 0xD9, + 0x9B, 0x35, 0x19, 0x79, 0x60, 0x95, 0x79, 0xEA, + 0x59, 0xE7, 0x64, 0x86, 0x66, 0xE2, 0x3B, 0xD2, + 0xFB, 0xD3, 0xF0, 0x36, 0xAA, 0xF7, 0xE1, 0xA2, + 0xB5, 0xA4, 0x80, 0xC3, 0xB7, 0x76, 0x99, 0xD3, + 0xB7, 0x4A, 0x3D, 0x8E, 0x8F, 0x49, 0xFB, 0x5C, + 0x2D, 0xA2, 0x2A, 0xF4, 0x76, 0x33, 0xC2, 0xFD, + 0x7A, 0xB7, 0x5D, 0x19, 0x80, 0x97, 0x3F, 0xF4, + 0x38, 0x93, 0x02, 0x32, 0xCA, 0xED, 0xCB, 0x12, + 0x2C, 0xA7, 0xCF, 0x83, 0xFA, 0x35, 0xEE, 0xBC, + 0xAF, 0xBA, 0x58, 0xDB, 0xDE, 0xC2, 0xB6, 0x49, + 0x1F, 0x12, 0xFC, 0x61, 0x63, 0x54, 0x33, 0x65, + 0x30, 0x1B, 0x5A, 0x2D, 0x57, 0x64, 0x6F, 0xED, + 0xE7, 0x6E, 0x46, 0x7D, 0x58, 0xDD, 0x66, 0x3C, + 0xD1, 0x99, 0x32, 0x86, 0x6A, 0x2B, 0x58, 0x21, + 0x30, 0x78, 0x90, 0xBF, 0x39, 0x57, 0x32, 0xB7, + 0xAF, 0xCC, 0x88, 0xD1, 0x8A, 0x1D, 0xD3, 0x2D, + 0xC4, 0x3F, 0xBB, 0x8B, 0x74, 0xB5, 0xAD, 0x49, + 0xC8, 0xAF, 0x97, 0x7F, 0x84, 0xC0, 0x51, 0x4F, + 0xA5, 0x5A, 0x5E, 0x17, 0x56, 0x41, 0x73, 0xFB, + 0x77, 0x30, 0xEB, 0xED, 0x7E, 0x23, 0xFA, 0x6A, + 0xC2, 0x57, 0x61, 0x83, 0xDE, 0x18, 0xB0, 0xAA, + 0xD1, 0x83, 0x07, 0x94, 0xFD, 0x99, 0x13, 0xE3, + 0xA3, 0x5A, 0x4A, 0x6F, 0x8E, 0xD2, 0xF3, 0x29, + 0xC7, 0x45, 0xD4, 0x44, 0x98, 0x4F, 0x77, 0xA1, + 0xA7, 0xDC, 0xE4, 0x67, 0x09, 0x9B, 0xE9, 0x0D, + 0x33, 0xBA, 0x76, 0xE8, 0x47, 0x54, 0xC2, 0x93, + 0x31, 0x1A, 0x36, 0x60, 0xE4, 0x7A, 0xE2, 0x54, + 0x04, 0x64, 0x35, 0xD5, 0xAC, 0x66, 0xA1, 0x42, + 0x1C, 0x11, 0x57, 0x39, 0x3E, 0x12, 0x12, 0xB8, + 0x48, 0xCF, 0x36, 0x0F, 0x2A, 0xE7, 0x27, 0x2F, + 0x85, 0xD6, 0x02, 0xDD, 0x59, 0x9D, 0xAA, 0x24, + 0xAB, 0xB6, 0x42, 0x6B, 0x78, 0xFA, 0xE2, 0x26, + 0x95, 0x56, 0x5A, 0xEB, 0x53, 0x64, 0xF4, 0x8D, + 0xD3, 0xC6, 0xC9, 0xDB, 0x01, 0x9B, 0x65, 0xED, + 0x6A, 0x1A, 0xD9, 0x4C, 0x21, 0x0F, 0xAA, 0x9E, + 0xB1, 0x22, 0x0E, 0xD1, 0x39, 0x87, 0x96, 0xC8, + 0x56, 0x6D, 0xF5, 0x26, 0x15, 0xB9, 0x05, 0x88, + 0xF1, 0x27, 0x09, 0x91, 0xD8, 0x6F, 0x36, 0x0A, + 0x9D, 0xFC, 0x80, 0x61, 0xD0, 0x51, 0xAF, 0xC2, + 0x1E, 0x0D, 0xF1, 0x98, 0xCD, 0x2C, 0xCB, 0xBB, + 0xA6, 0x55, 0x90, 0x61, 0xCA, 0xC8, 0xA3, 0x14, + 0xD3, 0xED, 0x58, 0xA3, 0xAF, 0x4A, 0xB0, 0x79, + 0x82, 0x10, 0x59, 0xB9, 0x1A, 0xA5, 0x2E, 0xF0, + 0x33, 0x0C, 0x04, 0xEF, 0x6F, 0xE3, 0x80, 0xF8, + 0x68, 0x1B, 0xA5, 0x24, 0xF5, 0x53, 0x8B, 0x12, + 0x51, 0x5D, 0x0B, 0xF1, 0x73, 0x18, 0x02, 0xBC, + 0x22, 0x27, 0x7A, 0x0B, 0x53, 0x0F, 0x44, 0x61, + 0x3F, 0xCF, 0x98, 0x7F, 0x8A, 0xAE, 0xBD, 0xD1, + 0xB9, 0x79, 0x70, 0x7B, 0xA8, 0xCF, 0x48, 0x60, + 0xDA, 0x48, 0x76, 0x71, 0x7E, 0x42, 0xFC, 0xDF, + 0xCD, 0xAF, 0xDA, 0x0E, 0x09, 0xDB, 0xFE, 0xFC, + 0xE9, 0x42, 0xEF, 0xCF, 0x7D, 0xBD, 0xAC, 0xE8, + 0xE5, 0xF9, 0x2F, 0x8B, 0x5C, 0x1F, 0x7B, 0x97, + 0x55, 0x3B, 0xAC, 0x01, 0x93, 0x1B, 0x6F, 0xA8, + 0xF0, 0x8C, 0xB5, 0x52, 0xDC, 0xA8, 0x98, 0x2E, + 0xA8, 0x47, 0xA8, 0xB8, 0x1F, 0x30, 0xD0, 0xA1, + 0x2E, 0xBF, 0x7A, 0x88, 0x9C, 0xDF, 0x1E, 0xE2, + 0x31, 0x84, 0xB9, 0x9A, 0xB9, 0x9A, 0xA5, 0xCC, + 0xFF, 0x1C, 0x72, 0xB7, 0x6C, 0xA8, 0x56, 0x94, + 0x28, 0xF7, 0xC1, 0x41, 0x3C, 0xFF, 0x8A, 0x85, + 0x08, 0xC5, 0x30, 0xC7, 0x53, 0x19, 0x29, 0x6C, + 0x18, 0x58, 0x88, 0x1C, 0x5C, 0x7B, 0x33, 0xE3, + 0x86, 0xBA, 0x8F, 0x5C, 0xCF, 0x98, 0xF9, 0xBB, + 0xC6, 0x29, 0xA1, 0xFF, 0xCA, 0x6F, 0xD8, 0xF4, + 0x79, 0x99, 0xB2, 0x74, 0x37, 0x98, 0x92, 0x84, + 0x4B, 0xB0, 0x85, 0x07, 0xCA, 0xFF, 0x87, 0xC5, + 0xD6, 0xC7, 0xB9, 0xE7, 0x6F, 0x60, 0xA0, 0xCC, + 0x24, 0x78, 0x3D, 0x83, 0x37, 0x80, 0x44, 0x0F, + 0x87, 0xD0, 0xD8, 0x5D, 0xD3, 0x89, 0x21, 0x53, + 0xE5, 0x3E, 0x90, 0x4D, 0x3A, 0x6B, 0x60, 0x31, + 0x88, 0x2B, 0x1B, 0x5E, 0x40, 0xA4, 0x65, 0x24, + 0x07, 0xE9, 0x0A, 0x50, 0x79, 0xCA, 0x52, 0x81, + 0x6C, 0x4B, 0x61, 0xE0, 0x4B, 0xA3, 0x4A, 0x49, + 0xD2, 0xFA, 0x8D, 0x90, 0x39, 0xFD, 0xD6, 0xE1, + 0xF4, 0xED, 0xBA, 0x3D, 0x2F, 0xDD, 0x65, 0x07, + 0xF3, 0x29, 0x6C, 0x94, 0x6D, 0x38, 0xA4, 0xAC, + 0x2A, 0x44, 0xF7, 0xF6, 0x90, 0x35, 0x66, 0x84, + 0x4C, 0xC1, 0x78, 0x81, 0xF5, 0x4C, 0xBC, 0x0C, + 0xB6, 0x14, 0x4C, 0x63, 0x3F, 0x94, 0xAF, 0x5A, + 0xEC, 0xC8, 0x64, 0xC3, 0xD4, 0xE8, 0xC0, 0x94, + 0xC2, 0xFD, 0x3E, 0xE1, 0xDC, 0x11, 0x55, 0xBF, + 0xF6, 0x9C, 0x18, 0xE3, 0x16, 0x23, 0x0D, 0xF8, + 0x72, 0xEF, 0xE1, 0x01, 0xE7, 0x93, 0x2E, 0xD1, + 0xEE, 0x61, 0x98, 0xC9, 0x81, 0xFD, 0xC5, 0xF1, + 0xAC, 0x0A, 0x76, 0xAE, 0x44, 0x80, 0x8D, 0xA8, + 0x54, 0x3C, 0x2C, 0x14, 0x64, 0x9B, 0xF2, 0xD2, + 0x78, 0xCA, 0x76, 0xAF, 0x79, 0x48, 0x2D, 0xAD, + 0xE1, 0x80, 0xDB, 0xC0, 0x70, 0x9F, 0xFA, 0xE0, + 0x77, 0x5B, 0x20, 0x1F, 0x55, 0xEC, 0xA3, 0x88, + 0x06, 0xA5, 0xBB, 0xE2, 0x37, 0x51, 0x80, 0xCA, + 0xCE, 0x18, 0xE9, 0x96, 0x89, 0x2E, 0x63, 0xB6, + 0xA6, 0x40, 0x71, 0xBA, 0xA9, 0x63, 0x22, 0xEA, + 0xCC, 0xAC, 0x82, 0xBE, 0x3C, 0x27, 0x99, 0x5B, + 0x7A, 0xC2, 0x94, 0x12, 0x5B, 0x06, 0x27, 0x22, + 0x2F, 0xB4, 0xD7, 0x5D, 0x00, 0xD2, 0xBF, 0xCA, + 0x03, 0x1B, 0xB9, 0x96, 0x15, 0xB3, 0x1D, 0x83, + 0x1F, 0xDC, 0xAE, 0xBE, 0x5C, 0x3F, 0x81, 0x2D, + 0x2F, 0x21, 0x07, 0xB7, 0xA6, 0xEE, 0xA1, 0x72, + 0x0F, 0xBC, 0xC1, 0xF7, 0x38, 0xAB, 0xE7, 0x0F, + 0x21, 0x5C, 0x98, 0xFB, 0xCA, 0x43, 0xA4, 0xF1, + 0xCA, 0xE2, 0xE2, 0x00, 0x52, 0x3C, 0xD9, 0x56, + 0x5E, 0xFA, 0x15, 0x6D, 0x17, 0x54, 0xD9, 0xED, + 0x69, 0x00, 0x86, 0x37, 0xAE, 0xFD, 0xF3, 0xA4, + 0xEB, 0xD4, 0x7E, 0x80, 0x75, 0xEF, 0x5B, 0xCB, + 0xB4, 0x96, 0x75, 0x3C, 0x2A, 0xBC, 0x43, 0x0B, + 0x97, 0xA5, 0xC8, 0x6D, 0x41, 0x4D, 0x38, 0x6C, + 0xAB, 0x7A, 0x05, 0x05, 0x73, 0x0E, 0xD8, 0x4C, + 0x3D, 0xBB, 0xC3, 0x3E, 0xE5, 0xB7, 0x21, 0xB9, + 0x47, 0x4E, 0x52, 0x73, 0xF3, 0x05, 0x43, 0xFB, + 0x2D, 0x84, 0x0E, 0x5C, 0x0C, 0xB2, 0x47, 0x61, + 0x2A, 0x30, 0xA5, 0xA3, 0x37, 0x86, 0x76, 0x74, + 0xFD, 0x47, 0x5F, 0x94, 0x78, 0x3F, 0x13, 0xCB, + 0x1D, 0x43, 0x50, 0x36, 0xCD, 0x47, 0xED, 0xEB, + 0x40, 0x18, 0x11, 0x53, 0x83, 0xA9, 0x24, 0xFC, + 0x04, 0x7C, 0x52, 0x68, 0xFB, 0xF2, 0xF6, 0x01, + 0x26, 0xBD, 0xDA, 0x6B, 0xE6, 0xE0, 0x5A, 0xD0, + 0xD3, 0x6F, 0x11, 0xBE, 0x13, 0xC9, 0x9E, 0x37, + 0x19, 0x9D, 0x5E, 0x68, 0x01, 0x4E, 0x8C, 0xC3, + 0x32, 0x42, 0xBC, 0x37, 0x7D, 0xC5, 0x95, 0x42, + 0xF1, 0x8D, 0x18, 0x9C, 0xC3, 0xBE, 0x01, 0x0E, + 0x5B, 0x1E, 0x4B, 0xF4, 0x28, 0xD4, 0x10, 0xD3, + 0x07, 0x98, 0x90, 0x23, 0x8C, 0x93, 0xF8, 0x02, + 0x23, 0x73, 0xBD, 0x96, 0x85, 0xD6, 0xFD, 0x9F, + 0xEC, 0x57, 0xBF, 0x03, 0x4E, 0x28, 0x0E, 0xEA, + 0xA5, 0xCC, 0x12, 0xF6, 0x77, 0xC6, 0x2B, 0x8A, + 0x62, 0x77, 0xA5, 0x5D, 0x96, 0x1E, 0x1F, 0xDA, + 0xE2, 0x3D, 0xA6, 0x24, 0xB5, 0x86, 0x3D, 0xBC, + 0x2B, 0x8B, 0xC2, 0x0A, 0xD5, 0x24, 0x7B, 0x90, + 0x5B, 0x16, 0xEA, 0xA8, 0xF1, 0xFC, 0x13, 0x47, + 0xEF, 0x42, 0x59, 0x01, 0xEF, 0xDE, 0xE8, 0x75, + 0x58, 0x7F, 0x32, 0x92, 0xD6, 0xA7, 0xFF, 0xFC, + 0x04, 0xC5, 0x59, 0x72, 0x83, 0x90, 0xAF, 0x4F, + 0x12, 0xB2, 0x33, 0xA0, 0xE0, 0xD7, 0x2B, 0xF8, + 0x2F, 0x29, 0x43, 0x4A, 0xBB, 0x63, 0x0B, 0xD0, + 0xD7, 0xDE, 0x1F, 0x75, 0x9F, 0x78, 0x81, 0x23, + 0x47, 0x39, 0x49, 0x5D, 0x26, 0x53, 0xF1, 0xDE, + 0x6C, 0x02, 0xC2, 0xC1, 0xD8, 0x44, 0xF5, 0x35, + 0xDB, 0xE9, 0x3A, 0xD6, 0x19, 0x2C, 0x5A, 0xAA, + 0xF9, 0x78, 0x65, 0x71, 0x00, 0xD8, 0x9E, 0xDD, + 0xE1, 0x73, 0x63, 0x75, 0x64, 0x83, 0x03, 0xD7, + 0x60, 0x4E, 0x0B, 0xF9, 0xB9, 0xE2, 0x66, 0x4F, + 0xE2, 0xE6, 0x59, 0x06, 0xDB, 0xA7, 0xB4, 0x05, + 0x03, 0x22, 0xE0, 0x1F, 0xAE, 0x30, 0xEE, 0x4A, + 0x10, 0x6A, 0x38, 0xAA, 0xF3, 0x7F, 0xD1, 0xA2, + 0x29, 0x47, 0x65, 0x67, 0x17, 0x92, 0xB4, 0xDF, + 0x62, 0xA9, 0xA1, 0x30, 0xFB, 0x52, 0x54, 0xBC, + 0xEB, 0x42, 0xEA, 0x78, 0x53, 0xEE, 0x50, 0x91, + 0x95, 0x73, 0xFC, 0x81, 0x3C, 0x6B, 0x9A, 0x11, + 0x94, 0xB6, 0x5D, 0xCB, 0xF4, 0xA9, 0x3C, 0x0E, + 0xBC, 0x8B, 0x95, 0x17, 0xCC, 0xB7, 0x76, 0x59, + 0x81, 0x57, 0x2C, 0x88, 0xD3, 0x53, 0x7F, 0x88, + 0x51, 0x80, 0x16, 0x03, 0x98, 0x7F, 0x7B, 0xE9, + 0x83, 0xF1, 0x29, 0xA7, 0x0A, 0x1C, 0x15, 0x84, + 0xAA, 0x7B, 0x9C, 0x6D, 0x35, 0xFF, 0x9B, 0x77, + 0xE6, 0x2D, 0x46, 0x92, 0x2A, 0x4C, 0x90, 0x4F, + 0xEB, 0xFF, 0xCA, 0xD7, 0xE9, 0x2B, 0x95, 0x2A, + 0x82, 0x88, 0x03, 0xA2, 0x94, 0x61, 0xA7, 0x44, + 0xA2, 0x74, 0x08, 0xC0, 0xAA, 0x7A, 0x10, 0xBA, + 0x14, 0xB0, 0x85, 0xFA, 0x60, 0x8F, 0x9C, 0xC1, + 0xF4, 0xB7, 0x23, 0x71, 0x96, 0x23, 0x58, 0x58, + 0x29, 0xBA, 0x34, 0x6A, 0x95, 0xFF, 0xD8, 0x6B, + 0x74, 0x4C, 0x1C, 0xD7, 0x4D, 0x68, 0xCE, 0x72, + 0x8C, 0x36, 0xFC, 0x61, 0x8E, 0xF0, 0x55, 0x8F, + 0x53, 0x14, 0x54, 0xD7, 0x43, 0x45, 0x50, 0x68, + 0x1F, 0xC0, 0x4C, 0xC2, 0xA1, 0x60, 0x34, 0x6E, + 0xCE, 0x69, 0x61, 0x94, 0x69, 0x47, 0x36, 0xD1, + 0x12, 0xBB, 0x63, 0x2A, 0x8B, 0x95, 0xB7, 0x10, + 0x65, 0x87, 0xFE, 0xBE, 0xE1, 0x6D, 0x69, 0x78, + 0xB0, 0xFC, 0xDB, 0xD0, 0xCE, 0xE1, 0x8C, 0x89, + 0x37, 0x8A, 0x54, 0xA6, 0x43, 0xEA, 0xDA, 0x42, + 0x6E, 0x59, 0x25, 0xAB, 0x7E, 0xF7, 0xAD, 0x95, + 0x8D, 0x8F, 0x0F, 0x27, 0x29, 0xAE, 0xAD, 0xCB, + 0x8D, 0x8D, 0xDB, 0x86, 0x76, 0xAD, 0xE9, 0x65, + 0x90, 0x7B, 0xB2, 0x55, 0xB8, 0x76, 0x70, 0x3C, + 0xFE, 0x12, 0x96, 0xB8, 0x24, 0x74, 0xD7, 0x09, + 0x13, 0x1A, 0x57, 0x7F, 0xD4, 0xE9, 0xB5, 0x9C, + 0xE3, 0x24, 0x71, 0xCC, 0x9B, 0xCD, 0xD1, 0xF4, + 0x8B, 0xC0, 0x7F, 0x6C, 0xEB, 0x73, 0x50, 0x57, + 0xAE, 0xF6, 0xF5, 0xA3, 0x87, 0x2E, 0x84, 0x9D, + 0x96, 0xA0, 0xD9, 0x56, 0x05, 0x04, 0x06, 0x3B, + 0x38, 0x1D, 0x9D, 0x2C, 0x33, 0x7A, 0x1C, 0x70, + 0x2E, 0x19, 0x25, 0xB8, 0xEB, 0xC2, 0x6F, 0x02, + 0xF2, 0x5D, 0x66, 0xA5, 0x81, 0xF5, 0x69, 0x36, + 0x3C, 0x34, 0x73, 0xCE, 0x4D, 0x4D, 0xA5, 0x35, + 0x4E, 0xBA, 0x40, 0x71, 0x09, 0xAE, 0x3E, 0x9B, + 0x4A, 0x3C, 0x75, 0x4E, 0x29, 0x31, 0x4D, 0x4C, + 0x2F, 0x88, 0x80, 0x4F, 0xBA, 0xF0, 0xAD, 0x18, + 0xD5, 0xA0, 0x3D, 0x1A, 0x52, 0xCA, 0x86, 0x29, + 0x26, 0xF0, 0xC1, 0xF7, 0x9C, 0x7A, 0x55, 0xDE, + 0xCA, 0x76, 0x73, 0x92, 0x54, 0x15, 0x16, 0x91, + 0xFD, 0x3C, 0xB5, 0x73, 0xA8, 0xDC, 0x56, 0x90, + 0xFA, 0x16, 0xE4, 0xE6, 0x0A, 0x7E, 0x91, 0xD1, + 0x03, 0xA1, 0xE1, 0x06, 0x88, 0x5E, 0xFB, 0xD8, + 0x61, 0x15, 0xE7, 0x89, 0xE8, 0x49, 0xCB, 0x18, + 0x8E, 0x13, 0x86, 0x6C, 0xAE, 0xBE, 0x3D, 0xB2, + 0x72, 0xEE, 0xC5, 0x3F, 0xC3, 0x6D, 0x14, 0x35, + 0x3E, 0x60, 0x92, 0x8C, 0x7F, 0x51, 0x79, 0xB7, + 0xA0, 0xEF, 0xD1, 0x02, 0x8E, 0x96, 0x7D, 0xAF, + 0x0D, 0x73, 0xC4, 0x17, 0x7E, 0xB1, 0xD9, 0xCB, + 0xCA, 0x94, 0x88, 0x56, 0xD2, 0xD5, 0x3E, 0x75, + 0x0D, 0xDA, 0x2A, 0x10, 0xFB, 0xEF, 0xFE, 0x93, + 0xF7, 0x01, 0x5B, 0x71, 0xD2, 0x2C, 0xCE, 0xB3, + 0x41, 0x2D, 0xBE, 0xA6, 0xA3, 0x63, 0x5F, 0xC0, + 0x53, 0xC2, 0xD4, 0xB7, 0xFD, 0xCA, 0x6A, 0x62, + 0x0F, 0x9F, 0x9D, 0x00, 0xBA, 0xE9, 0x58, 0xE7, + 0xB3, 0x19, 0xF6, 0x90, 0x3C, 0x62, 0xF3, 0xEC, + 0x55, 0x2A, 0x84, 0xCC, 0x91, 0x86, 0x0E, 0x5A, + 0x39, 0x8F, 0x24, 0x71, 0x40, 0xFD, 0x45, 0xBA, + 0x24, 0xB2, 0x0A, 0xD7, 0xE0, 0xE1, 0xF3, 0xAE, + 0x38, 0x07, 0xD4, 0xE7, 0x76, 0xD2, 0xEA, 0x7C, + 0xDC, 0x04, 0xD0, 0x48, 0xE1, 0x43, 0x56, 0xFE, + 0x43, 0xAA, 0xE5, 0xDA, 0x19, 0xB5, 0x80, 0xAF, + 0x7C, 0xDB, 0xFA, 0xEA, 0xE0, 0x8A, 0x38, 0x67, + 0x02, 0xC8, 0x71, 0x3A, 0x1B, 0x12, 0x56, 0x76, + 0x7A, 0x0C, 0x91, 0x18, 0x18, 0x4B, 0xBD, 0xDB, + 0xE9, 0x0F, 0xA1, 0xEC, 0x54, 0xC0, 0x92, 0xF8, + 0x4E, 0xF7, 0xCF, 0x69, 0xFA, 0xF3, 0x6D, 0xB6, + 0xAD, 0xA3, 0xCA, 0xAA, 0x25, 0x13, 0xDA, 0x97, + 0x04, 0x2A, 0xC7, 0xCC, 0x60, 0x7E, 0x65, 0x1D, + 0x57, 0x58, 0xB4, 0x96, 0x53, 0x9A, 0x00, 0xE4, + 0x72, 0xB5, 0x99, 0x1F, 0x7C, 0xDB, 0x3C, 0xB4, + 0x1A, 0x71, 0x38, 0xA3, 0x8B, 0x49, 0x9A, 0xF5, + 0xE7, 0x8D, 0x74, 0xAA, 0x88, 0x66, 0x56, 0x04, + 0xBA, 0xEF, 0xE8, 0x37, 0x56, 0xC2, 0x18, 0x7E, + 0x60, 0xCF, 0x63, 0xCF, 0x1A, 0xEF, 0x28, 0xA9, + 0xDF, 0x2D, 0x3C, 0xAD, 0xC3, 0x5A, 0xDD, 0x7C, + 0xD4, 0x19, 0xDF, 0xDE, 0x80, 0xC2, 0x61, 0xB5, + 0x49, 0x8A, 0x89, 0xB9, 0xB9, 0x72, 0xBF, 0x8B, + 0xF6, 0x04, 0xAA, 0xF5, 0x3E, 0xC1, 0xDC, 0xA8, + 0x86, 0x97, 0x97, 0x0F, 0x29, 0x41, 0x5C, 0x47, + 0xC7, 0x23, 0x48, 0x69, 0xD1, 0xBC, 0x9F, 0x8E, + 0xDD, 0xEA, 0xB6, 0xA6, 0x37, 0x1E, 0x4A, 0x00, + 0xFF, 0xF6, 0x14, 0xC5, 0x42, 0xEF, 0x9F, 0x1D, + 0xE7, 0xCE, 0xD4, 0x31, 0xBC, 0xC3, 0x0E, 0x00, + 0x01, 0xF2, 0xC8, 0xB5, 0x40, 0x82, 0x68, 0x2C, + 0xD0, 0xFA, 0x8B, 0xAC, 0xB4, 0x32, 0xA6, 0x97, + 0xCC, 0x5E, 0x0F, 0x75, 0x45, 0x0A, 0xBA, 0xE5, + 0x5A, 0x84, 0x5F, 0x7E, 0x85, 0x0D, 0x4A, 0x62, + 0x49, 0x3D, 0x12, 0xC0, 0xCE, 0x51, 0x87, 0xB1, + 0x21, 0x1F, 0x6E, 0x1B, 0xDA, 0xEF, 0x12, 0xCC, + 0x18, 0x5A, 0xA9, 0xD9, 0x86, 0x89, 0x06, 0x56, + 0x14, 0x1B, 0xDC, 0xD7, 0x74, 0xFF, 0x71, 0xC6, + 0xE3, 0xEA, 0xF3, 0x0C, 0x20, 0x42, 0xE9, 0x0C, + 0xDE, 0xE8, 0xAC, 0xFD, 0xDA, 0x19, 0x67, 0x7A, + 0x9C, 0xE5, 0xF6, 0x12, 0x5B, 0x20, 0xA4, 0xCE, + 0x4C, 0x34, 0xEE, 0x01, 0xC8, 0xEF, 0x7D, 0xD4, + 0x0D, 0x21, 0xA0, 0x3C, 0xCB, 0xAF, 0x09, 0x6F, + 0x95, 0xF4, 0x76, 0x28, 0x4A, 0x0E, 0x21, 0x5E, + 0xBB, 0x93, 0xA0, 0xD6, 0x33, 0x9E, 0xA7, 0xD3, + 0xF8, 0x65, 0xAD, 0x52, 0xD4, 0x1C, 0x96, 0x33, + 0xC7, 0x8D, 0x67, 0x83, 0xA8, 0xCD, 0x77, 0xD6, + 0xD4, 0xE4, 0xC8, 0x70, 0xAB, 0x85, 0xC9, 0xFE, + 0xB2, 0x47, 0x74, 0x0F, 0xC6, 0x39, 0xB1, 0x6C, + 0x47, 0xEC, 0xB9, 0x26, 0x9A, 0xD3, 0xDE, 0x5E, + 0xB8, 0x0C, 0x14, 0xC7, 0x19, 0x29, 0x47, 0x99, + 0x84, 0x03, 0x80, 0x87, 0xCD, 0xD5, 0xC3, 0x8E, + 0x49, 0x2A, 0xE2, 0xAA, 0x6C, 0x4C, 0x55, 0x20, + 0xCA, 0xF2, 0xD1, 0xA1, 0x04, 0x99, 0x00, 0x62, + 0x00, 0xD1, 0x10, 0x98, 0x68, 0x55, 0xFC, 0x4D, + 0x04, 0x6B, 0xFF, 0xE1, 0x19, 0x82, 0x5F, 0xDB, + 0x7E, 0x47, 0x77, 0xEC, 0x16, 0x14, 0xF8, 0xDC, + 0x01, 0x45, 0xCC, 0x1B, 0x29, 0xC5, 0x4E, 0x38, + 0xE0, 0x07, 0x31, 0xAD, 0x99, 0x65, 0x57, 0x73, + 0xD4, 0x14, 0xD6, 0xA9, 0x6D, 0x63, 0xE4, 0x44, + 0x27, 0x95, 0xCB, 0x43, 0x0C, 0x6B, 0x48, 0xDF, + 0x16, 0x12, 0x3A, 0x00, 0x9B, 0x44, 0x65, 0xD9, + 0xCF, 0x64, 0xCC, 0x59, 0x0D, 0x4D, 0x8F, 0x01, + 0x34, 0x4C, 0x9A, 0xC0, 0x42, 0x59, 0x1E, 0xA8, + 0x28, 0x50, 0x69, 0x4E, 0xD5, 0xC6, 0x6E, 0x16, + 0xDA, 0x2C, 0x58, 0x36, 0xEA, 0x7D, 0x72, 0x19, + 0x3C, 0x96, 0xDD, 0x3C, 0xDC, 0x65, 0xA1, 0x51, + 0x9C, 0xA7, 0x29, 0xBB, 0x34, 0x92, 0x14, 0x52, + 0x57, 0xC7, 0xDD, 0x19, 0x2E, 0x88, 0x25, 0x93, + 0x30, 0xA4, 0x39, 0x1B, 0x05, 0x79, 0x1E, 0xF1, + 0x20, 0x98, 0x80, 0x99, 0x74, 0x2D, 0xB6, 0xE2, + 0x69, 0xD5, 0x68, 0xC7, 0x94, 0xEF, 0x28, 0xE0, + 0x46, 0x62, 0x0F, 0xBE, 0x9D, 0x46, 0xD5, 0xB7, + 0xF7, 0xD1, 0x08, 0x63, 0x0E, 0x7E, 0x29, 0xF7, + 0xAE, 0x61, 0x9E, 0x5B, 0x70, 0x68, 0x3D, 0xEE, + 0x7C, 0xDD, 0xAC, 0xBA, 0xDF, 0xC4, 0x1D, 0xC4, + 0x67, 0x28, 0x6B, 0x6F, 0x20, 0x58, 0x04, 0x1C, + 0x5A, 0x00, 0xD1, 0xC5, 0x40, 0xBC, 0x70, 0xBF, + 0x0F, 0xBC, 0x02, 0xCE, 0x46, 0xBA, 0x42, 0xF6, + 0x21, 0xA0, 0x1F, 0x5F, 0x9E, 0x73, 0xF9, 0x09, + 0x82, 0x7B, 0x75, 0x34, 0x8C, 0x85, 0xBC, 0x25, + 0xDC, 0xE0, 0x50, 0xBA, 0x3D, 0xCD, 0x6E, 0xEF, + 0xA8, 0xB6, 0x86, 0xC9, 0xFB, 0x3C, 0xB1, 0xD1, + 0x7D, 0x3C, 0xBF, 0xFE, 0xA7, 0x98, 0x1F, 0x9F, + 0xD6, 0xBE, 0x05, 0xEC, 0x59, 0x14, 0xD1, 0x54, + 0x1F, 0x44, 0x82, 0xF8, 0x6C, 0x48, 0x23, 0x62, + 0x1C, 0xB1, 0x74, 0x84, 0x99, 0x09, 0x8F, 0x31, + 0x46, 0xEB, 0xF6, 0x19, 0xD6, 0x03, 0x58, 0x46, + 0x26, 0xE5, 0xA9, 0xED, 0x5A, 0xCF, 0x68, 0x07, + 0xFD, 0x49, 0x9E, 0xE5, 0x1E, 0x22, 0x7A, 0xAE, + 0x07, 0x55, 0xA8, 0xF3, 0x5F, 0xB1, 0x5F, 0xFA, + 0xFE, 0x16, 0x55, 0x8F, 0xCA, 0xED, 0x07, 0x17, + 0x76, 0x95, 0xC8, 0xDC, 0x2C, 0x28, 0x00, 0xC3, + 0xA5, 0x29, 0x94, 0x60, 0xAD, 0xDB, 0x91, 0x6A, + 0xE1, 0x1B, 0x91, 0xAF, 0xDC, 0x75, 0xE7, 0xC5, + 0x92, 0x9A, 0x76, 0x15, 0x0F, 0x19, 0xF7, 0xD6, + 0xAE, 0x35, 0x3C, 0x56, 0x39, 0x4B, 0x27, 0xA6, + 0xE0, 0x93, 0xC3, 0x39, 0x09, 0x15, 0x43, 0x39, + 0xC3, 0xEC, 0xC5, 0xBE, 0xF7, 0x8F, 0x28, 0x82, + 0xB9, 0xFE, 0xD4, 0x34, 0x7C, 0x5C, 0xCA, 0x5F, + 0x8D, 0x6B, 0x4B, 0xEF, 0xB9, 0x45, 0x89, 0x48, + 0x85, 0x45, 0xEC, 0x19, 0xEB, 0x0A, 0x62, 0x71, + 0x23, 0x8A, 0x8A, 0x9B, 0x27, 0xE4, 0xA8, 0x86, + 0x55, 0x11, 0xC4, 0xC2, 0xF1, 0x4D, 0x1B, 0x0C, + 0x4F, 0x7D, 0xCA, 0xCA, 0x50, 0x88, 0x98, 0xC9, + 0x86, 0xB9, 0xBD, 0x86, 0x7F, 0x18, 0xAE, 0x5B, + 0xFE, 0x5F, 0x88, 0xF5, 0xBE, 0x69, 0xB4, 0x49, + 0x1A, 0x08, 0xB8, 0x0C, 0x01, 0x3C, 0xD6, 0xB0, + 0xB4, 0x0E, 0xF0, 0x4D, 0xEC, 0x60, 0x90, 0x9A, + 0xFA, 0xF5, 0x18, 0x63, 0x2C, 0x10, 0x12, 0xC8, + 0x1A, 0x5D, 0xAC, 0xD3, 0xA8, 0x42, 0xA1, 0x0D, + 0x4D, 0x6F, 0x4E, 0x57, 0xE5, 0x51, 0x93, 0x50, + 0x00, 0xFB, 0x16, 0xA5, 0x4E, 0x25, 0x62, 0xD6, + 0x21, 0x9C, 0xC9, 0x65, 0x48, 0xC7, 0xDE, 0x69, + 0x83, 0xF7, 0x17, 0x66, 0xE0, 0x4B, 0x7D, 0x8E, + 0xFE, 0xE9, 0x78, 0xDF, 0x49, 0x21, 0xD7, 0x8A, + 0x41, 0xAC, 0xE8, 0xEC, 0x91, 0x75, 0x9E, 0xA4, + 0xC6, 0x72, 0x61, 0xF0, 0xF8, 0x51, 0xD5, 0xDC, + 0x45, 0xCA, 0x6A, 0xC3, 0x64, 0xB9, 0x96, 0x73, + 0x3B, 0xF0, 0xC7, 0x2A, 0x7E, 0x88, 0x4E, 0x17, + 0x20, 0xC0, 0x8B, 0x8A, 0x5C, 0x6F, 0xFB, 0xAD, + 0x2D, 0x3D, 0x86, 0xC6, 0x4E, 0xDB, 0x39, 0x7D, + 0x01, 0x84, 0x28, 0xF5, 0xF0, 0x73, 0x05, 0xE4, + 0x7B, 0x22, 0xF8, 0xD9, 0xD4, 0x0F, 0x17, 0xC0, + 0xC8, 0xA0, 0x2F, 0x62, 0x21, 0xE7, 0xCF, 0x91, + 0x46, 0xAC, 0x84, 0x95, 0x0C, 0x26, 0xDC, 0x3F, + 0x11, 0x2A, 0xE7, 0x60, 0x15, 0x8A, 0x50, 0x6F, + 0x31, 0x22, 0x49, 0x69, 0xDA, 0x16, 0x74, 0x35, + 0x72, 0x8D, 0xC0, 0x94, 0xB6, 0x15, 0x6B, 0x27, + 0xF6, 0x0C, 0x33, 0x69, 0x16, 0x3E, 0x14, 0xC5, + 0x5E, 0xF9, 0xF4, 0x97, 0x75, 0x02, 0x24, 0x3E, + 0x00, 0x9A, 0x4C, 0x01, 0x7D, 0xDB, 0xFE, 0xE0, + 0xE8, 0xBD, 0xBF, 0x27, 0x3E, 0x7F, 0x04, 0xA8, + 0x54, 0x06, 0xF9, 0xE5, 0x9C, 0xB9, 0x67, 0xEF, + 0x2C, 0x03, 0xCC, 0xCE, 0x8F, 0xD5, 0x70, 0x3E, + 0x3E, 0xD1, 0xBB, 0xC4, 0x62, 0x2B, 0x58, 0x46, + 0xA7, 0x76, 0x95, 0x78, 0x96, 0x91, 0xF8, 0x16, + 0xBA, 0xE7, 0x15, 0x63, 0xCE, 0xD4, 0x74, 0x63, + 0x35, 0x26, 0x4B, 0x3A, 0x9A, 0xEF, 0xCB, 0xCA, + 0xA3, 0x26, 0x8C, 0x75, 0x45, 0x42, 0xFF, 0x0E, + 0xE1, 0xFE, 0x7F, 0xCB, 0x5F, 0x58, 0xA8, 0xD5, + 0x8B, 0x88, 0x53, 0x6A, 0x29, 0xCE, 0xA2, 0x25, + 0x49, 0xDD, 0x9D, 0xDD, 0x97, 0xD1, 0xE8, 0x79, + 0x56, 0xDA, 0x32, 0xBB, 0xF7, 0x83, 0xF3, 0xD4, + 0x61, 0x4D, 0x2E, 0xBA, 0x95, 0x83, 0xD2, 0x16, + 0xF7, 0x83, 0x07, 0x7E, 0x01, 0x07, 0x6D, 0x90, + 0x6B, 0x0B, 0x63, 0xC7, 0xE5, 0x31, 0x07, 0x93, + 0x35, 0xA4, 0xC1, 0x1A, 0xB1, 0x12, 0x5A, 0x7D, + 0x5E, 0xD0, 0xB9, 0xD4, 0xDB, 0x4F, 0x8B, 0x18, + 0xF9, 0xE5, 0xC8, 0x29, 0x40, 0xD0, 0x95, 0x3C, + 0x32, 0x8D, 0x77, 0x8B, 0x55, 0x54, 0xC6, 0x65, + 0xB2, 0xE4, 0xEC, 0xE0, 0x21, 0xE2, 0xBD, 0x13, + 0xB7, 0xB5, 0xD8, 0xC1, 0x4A, 0x3B, 0xFE, 0x4D, + 0xF8, 0x46, 0x99, 0x7F, 0xA5, 0x3F, 0x3B, 0x51, + 0xA2, 0x9F, 0x9C, 0x64, 0xFE, 0x7B, 0xB3, 0x22, + 0x2A, 0xC3, 0xD2, 0x24, 0x83, 0xC1, 0x66, 0xD5, + 0x41, 0x04, 0x4C, 0xC3, 0xFC, 0x58, 0x75, 0xD9, + 0xBA, 0xC9, 0x1A, 0x9C, 0xDA, 0x8F, 0xFB, 0x15, + 0x01, 0x14, 0xE3, 0x8E, 0x3C, 0xBF, 0xCD, 0xB6, + 0x87, 0xCA, 0x37, 0x03, 0xCC, 0x65, 0xEF, 0x5A, + 0xBF, 0x4F, 0x26, 0xD7, 0xEA, 0x20, 0x05, 0x0C, + 0x09, 0x1D, 0xC7, 0xB7, 0xA7, 0xA7, 0xA9, 0x8A, + 0xA6, 0x1F, 0x52, 0x53, 0x62, 0x80, 0x56, 0x17, + 0x1D, 0x53, 0x12, 0x45, 0x71, 0x0C, 0xE4, 0x8A, + 0x40, 0xAD, 0x9F, 0x59, 0x2A, 0xDE, 0x12, 0x72, + 0xED, 0x5E, 0x54, 0x1D, 0xE4, 0xE9, 0x24, 0x4B, + 0xCF, 0x32, 0x80, 0x6C, 0xEA, 0xE7, 0xA2, 0x19, + 0x2E, 0x32, 0x86, 0x06, 0xB1, 0x95, 0x35, 0xC7, + 0x0E, 0x45, 0x22, 0xB7, 0x2B, 0xE9, 0x70, 0x61, + 0x66, 0xA8, 0xD2, 0x2A, 0x1C, 0xE9, 0x29, 0x08, + 0x95, 0xCF, 0x14, 0x9D, 0x40, 0x2B, 0x23, 0xFA, + 0x3A, 0xF0, 0xBC, 0x32, 0x9C, 0xF0, 0xA6, 0x1A, + 0x0F, 0x42, 0xC9, 0xA2, 0xAF, 0x20, 0xF9, 0xA9, + 0x2A, 0x05, 0x50, 0x9D, 0xDF, 0x9C, 0xB4, 0x5A, + 0x3B, 0x49, 0x3A, 0x2E, 0x71, 0xC7, 0x3E, 0xC1, + 0xC3, 0x84, 0x7E, 0x9E, 0x2C, 0xA8, 0xDD, 0x0F, + 0x1A, 0x94, 0x13, 0x1A, 0xB1, 0xC4, 0x34, 0x57, + 0xE3, 0xA2, 0x68, 0x5B, 0x04, 0x05, 0x81, 0xC8, + 0x5D, 0x7D, 0x8D, 0x0F, 0x35, 0x67, 0xFC, 0x4D, + 0x25, 0xDE, 0xF4, 0x69, 0xB0, 0x24, 0xCF, 0xFB, + 0xE7, 0xD9, 0x5C, 0x39, 0xE9, 0x96, 0xE3, 0x63, + 0x33, 0x75, 0x0B, 0x3C, 0x72, 0xC3, 0xA0, 0x83, + 0x97, 0xF8, 0xA5, 0x30, 0x7C, 0x8C, 0x70, 0x9E, + 0x50, 0x1D, 0xD9, 0x7F, 0xBE, 0x7B, 0x32, 0x81, + 0xBE, 0x62, 0x4D, 0xA6, 0x1B, 0x4F, 0x2D, 0x6A, + 0x24, 0xC8, 0xF6, 0x59, 0x19, 0x77, 0x83, 0x0D, + 0x18, 0x3A, 0x06, 0x96, 0x1F, 0xA1, 0x42, 0x6C, + 0x99, 0x66, 0x0B, 0x8E, 0xC1, 0xD6, 0x51, 0xD9, + 0x1A, 0x37, 0x2C, 0x95, 0xE8, 0xB5, 0xA3, 0xFF, + 0xAD, 0x80, 0x32, 0xF6, 0x7F, 0xC9, 0xC6, 0xDA, + 0x1B, 0x49, 0x60, 0xDD, 0x76, 0xC5, 0xDF, 0x97, + 0x90, 0x58, 0xB2, 0x22, 0x80, 0xD6, 0x50, 0x4E, + 0xBB, 0x51, 0x3D, 0x78, 0x76, 0x24, 0x5E, 0xD3, + 0xB0, 0x55, 0xC8, 0x09, 0xCE, 0xD5, 0x89, 0x4E, + 0x26, 0x26, 0x6E, 0x10, 0x8E, 0x46, 0xEC, 0xA3, + 0xAB, 0x0A, 0xFC, 0x22, 0x75, 0xCF, 0x80, 0x58, + 0x5F, 0x12, 0xC7, 0x25, 0x81, 0xDD, 0xBA, 0x5F, + 0x0D, 0xBE, 0x92, 0xDD, 0x33, 0x85, 0xE7, 0xE5, + 0x24, 0xCD, 0xF4, 0x64, 0xAE, 0xFC, 0x52, 0xE0, + 0x6E, 0x21, 0xA0, 0xB4, 0x21, 0xFC, 0xE9, 0xAF, + 0x68, 0xE8, 0x00, 0xF8, 0x9A, 0xCF, 0xDE, 0xAA, + 0xF5, 0xBC, 0xA6, 0xE3, 0xAC, 0xBF, 0xB2, 0x32, + 0x69, 0x9F, 0x59, 0x3A, 0x5E, 0xAB, 0xA2, 0x07, + 0xD1, 0xEE, 0x1C, 0xB1, 0x0E, 0x08, 0xF9, 0xB7, + 0xBD, 0x06, 0xB0, 0x82, 0x66, 0x41, 0x75, 0xB9, + 0x1E, 0xB0, 0xF9, 0x94, 0xB8, 0x2F, 0x7E, 0x72, + 0xC6, 0x0D, 0x88, 0x06, 0x67, 0x17, 0x5E, 0x21, + 0x7E, 0x35, 0xC1, 0x44, 0x59, 0xE8, 0x6C, 0x65, + 0x7A, 0x7D, 0x30, 0x34, 0x96, 0xB6, 0x9D, 0x41, + 0x7D, 0x25, 0x82, 0x6C, 0xE9, 0xA9, 0x28, 0xE7, + 0xBA, 0x3E, 0x20, 0x7B, 0xF0, 0x9A, 0xE7, 0xF2, + 0x7D, 0x79, 0x20, 0x7E, 0xA3, 0x64, 0x88, 0x19, + 0xCF, 0x2D, 0x81, 0xEA, 0x4B, 0x6C, 0xD0, 0xEB, + 0xEC, 0xC7, 0x70, 0x54, 0xDE, 0x45, 0x7C, 0x42, + 0xAF, 0x11, 0x43, 0x10, 0xFD, 0xFB, 0xE7, 0xD6, + 0x2B, 0x14, 0x9D, 0x97, 0x5A, 0x82, 0x12, 0xC2, + 0x37, 0x03, 0x0C, 0x48, 0x9A, 0x09, 0xB6, 0xE9, + 0xC3, 0x2A, 0xFC, 0xF5, 0x20, 0x10, 0x73, 0xED, + 0x47, 0x3F, 0xFA, 0xEB, 0x0C, 0xB0, 0xE0, 0x79, + 0xD7, 0xDB, 0x29, 0x34, 0x0F, 0x4D, 0xBF, 0x16, + 0x72, 0xBD, 0x5B, 0x88, 0xE3, 0x48, 0x33, 0x75, + 0x54, 0x6F, 0x1E, 0x49, 0x7A, 0x8B, 0x2B, 0xFA, + 0x4C, 0x52, 0xC4, 0x9C, 0xC5, 0x84, 0xB2, 0x2D, + 0xCD, 0xCD, 0x05, 0x48, 0xC4, 0xEB, 0x5E, 0xA8, + 0x7A, 0x1E, 0xA6, 0x9A, 0x5A, 0x42, 0x3B, 0xDE, + 0xB3, 0xD2, 0xBC, 0x83, 0x7D, 0xF0, 0x0C, 0xD8, + 0x6A, 0x4A, 0xF8, 0x49, 0xAC, 0xD0, 0xA1, 0x21, + 0xCD, 0x3F, 0x5D, 0x65, 0xB8, 0x25, 0x90, 0x61, + 0x04, 0xD8, 0xA1, 0x74, 0x29, 0x9E, 0x31, 0x2D, + 0x8C, 0x5F, 0x38, 0xAD, 0x57, 0x84, 0x93, 0x74, + 0xCD, 0x4E, 0x8D, 0x5D, 0x8F, 0xCF, 0xA0, 0x8E, + 0xE6, 0x2D, 0x2B, 0xED, 0x7F, 0xC0, 0x0F, 0x69, + 0xED, 0x2E, 0x2A, 0xF4, 0x5D, 0xD3, 0x16, 0xD4, + 0xED, 0x9A, 0xBF, 0x59, 0x53, 0x0C, 0x5E, 0x99, + 0x88, 0xB9, 0xF4, 0x00, 0x5B, 0xAC, 0xC7, 0x59, + 0x71, 0xCB, 0xE9, 0xE0, 0x6D, 0xEC, 0x1A, 0xCD, + 0xB9, 0xAA, 0xB2, 0xB4, 0x56, 0x1D, 0x4F, 0x0A, + 0xB2, 0xF5, 0x53, 0x9D, 0x6B, 0xE1, 0xE2, 0xE8, + 0x27, 0x70, 0x50, 0xF5, 0xBC, 0xF2, 0x20, 0x34, + 0xDA, 0x86, 0xF4, 0x11, 0xD7, 0x80, 0xEF, 0xC8, + 0xC3, 0xF0, 0xF0, 0x4E, 0x38, 0xE9, 0x07, 0xCC, + 0x61, 0x6B, 0xE4, 0xA2, 0x2C, 0x13, 0x0A, 0xD0, + 0x81, 0x8A, 0x4A, 0xCC, 0x6F, 0x93, 0x41, 0x5F, + 0x6D, 0x6B, 0xF0, 0x2A, 0x6B, 0x0D, 0x51, 0x0B, + 0x24, 0x30, 0xDA, 0x26, 0x78, 0xD5, 0x84, 0x25, + 0x90, 0x4C, 0x41, 0xF9, 0x83, 0x14, 0x15, 0x20, + 0xCC, 0x8C, 0xAE, 0x4E, 0x3E, 0x99, 0xE6, 0xED, + 0x39, 0x63, 0x04, 0x13, 0x2C, 0xD7, 0x9F, 0x84, + 0x83, 0xD3, 0x49, 0xC6, 0x82, 0x7B, 0x34, 0xA0, + 0xA0, 0x60, 0x1B, 0x2B, 0x57, 0xF2, 0x4C, 0xAB, + 0x80, 0x3B, 0x33, 0x11, 0xE8, 0x55, 0x97, 0x5A, + 0xED, 0xC3, 0xE4, 0x6B, 0x05, 0xA9, 0x83, 0xA0, + 0x5C, 0x83, 0xD4, 0x3A, 0x9D, 0x3B, 0xA2, 0x05, + 0x48, 0xFA, 0xD7, 0x01, 0x46, 0x1F, 0x1F, 0xAC, + 0xF1, 0xF7, 0x1A, 0xB0, 0xD2, 0xF1, 0xEC, 0x8B, + 0x67, 0xCD, 0x98, 0x90, 0x9E, 0xC7, 0x70, 0xDC, + 0x43, 0xAA, 0x56, 0xE9, 0x17, 0xCF, 0x81, 0x72, + 0x45, 0xD3, 0x47, 0x40, 0xF7, 0x38, 0x04, 0xE7, + 0x67, 0x93, 0x5B, 0x4D, 0xE3, 0xE7, 0xDA, 0x77, + 0xA7, 0xC9, 0x1C, 0x26, 0xDF, 0xA2, 0x03, 0xE9, + 0x47, 0x41, 0x35, 0x71, 0xA5, 0xBE, 0x67, 0xA8, + 0xD8, 0x74, 0x47, 0x39, 0xE3, 0xCC, 0xC9, 0x19, + 0xB9, 0xA3, 0x8D, 0xB1, 0x2B, 0xDE, 0xBF, 0xFE, + 0x8E, 0x81, 0xC2, 0x89, 0x30, 0x1D, 0xF7, 0xF0, + 0x47, 0xB9, 0x7C, 0x73, 0xB4, 0xB3, 0x17, 0x10, + 0x8E, 0x7D, 0x68, 0x5A, 0x14, 0x6C, 0x81, 0x7C, + 0x23, 0xAB, 0x8E, 0x45, 0x39, 0x08, 0x34, 0x00, + 0x92, 0xD7, 0x75, 0xE7, 0x64, 0x3E, 0xDC, 0x56, + 0x96, 0xDC, 0x51, 0x9D, 0x63, 0x4C, 0xE4, 0xF2, + 0x75, 0xD2, 0x03, 0x9E, 0xFB, 0x39, 0x1D, 0xCC, + 0x70, 0x9E, 0xB8, 0x03, 0xF1, 0x14, 0xCD, 0x10, + 0x39, 0x66, 0x18, 0xCE, 0xAD, 0xAC, 0xAB, 0x56, + 0x83, 0x06, 0xCF, 0xDB, 0x2B, 0x80, 0x06, 0x39, + 0x97, 0xC7, 0x15, 0x85, 0x48, 0x64, 0x6F, 0xEF, + 0x78, 0x34, 0x01, 0x84, 0xBF, 0x1D, 0xD7, 0xAE, + 0xE0, 0xEE, 0x6C, 0x66, 0x0B, 0x8E, 0xDF, 0xB6, + 0x45, 0xA2, 0x59, 0xBB, 0xAD, 0x3F, 0xC4, 0xC0, + 0x8A, 0x88, 0xA5, 0x54, 0xE0, 0xEE, 0xBD, 0xB4, + 0x4D, 0x74, 0xDC, 0x6F, 0xBC, 0x0E, 0xF1, 0x7E, + 0xA8, 0x32, 0x10, 0x60, 0x89, 0x0D, 0xC3, 0x47, + 0x9F, 0xDE, 0x6C, 0x0B, 0x9D, 0x48, 0x8C, 0x11, + 0x2B, 0x52, 0x61, 0x7E, 0x87, 0xDD, 0x81, 0xC8, + 0xE3, 0x3E, 0x46, 0xBB, 0x1F, 0xFF, 0x67, 0x5F, + 0xF8, 0x24, 0x90, 0x8F, 0x52, 0x11, 0x7E, 0x5B, + 0x59, 0x76, 0xBC, 0x51, 0xAE, 0x3F, 0x39, 0xE7, + 0xAF, 0x99, 0x54, 0x0A, 0x85, 0xDD, 0xCD, 0x0C, + 0x63, 0xA7, 0xA0, 0x99, 0x3E, 0xF9, 0x79, 0xE1, + 0xE8, 0x5A, 0xD7, 0x7D, 0x81, 0x39, 0x9B, 0xFA, + 0x50, 0xC2, 0xAB, 0xF0, 0xAC, 0xC4, 0xA9, 0x00, + 0xAF, 0x3C, 0x63, 0xF1, 0x25, 0x22, 0xA8, 0x53, + 0x47, 0x1C, 0x0F, 0xF6, 0x64, 0x8C, 0x7F, 0x83, + 0x29, 0xF8, 0x9A, 0xF5, 0x6E, 0x3F, 0x32, 0xE5, + 0xE1, 0x31, 0x89, 0xD3, 0xA3, 0x58, 0xA8, 0xEB, + 0x8D, 0x56, 0xE3, 0x79, 0xA7, 0xF6, 0x6C, 0xEF, + 0x79, 0x91, 0x8B, 0xB6, 0x58, 0xF1, 0xBB, 0xA1, + 0xF1, 0x4D, 0x60, 0x4F, 0xBA, 0xF0, 0x5A, 0x4F, + 0x9A, 0xC0, 0x0F, 0x38, 0x17, 0x85, 0xD9, 0xA5, + 0x63, 0x9B, 0x45, 0x2D, 0x1F, 0x58, 0xF8, 0xEF, + 0x92, 0x0A, 0x07, 0xEE, 0xC8, 0x7E, 0x67, 0x62, + 0xB6, 0xD9, 0x34, 0x71, 0xC2, 0xC6, 0x9C, 0xDD, + 0xB3, 0x64, 0xBC, 0x80, 0x4B, 0x46, 0xCE, 0xC0, + 0x4F, 0xD3, 0x6C, 0xAC, 0x47, 0x93, 0x5F, 0x86, + 0x48, 0x79, 0x1A, 0x4F, 0x6C, 0x5D, 0x90, 0x84, + 0x49, 0xD4, 0x82, 0xAF, 0x29, 0xD6, 0xAE, 0x13, + 0x90, 0x07, 0xDB, 0xB8, 0xFB, 0xF1, 0x37, 0x2A, + 0xC6, 0x2D, 0x8E, 0xA6, 0xCF, 0xAE, 0x7B, 0xBD, + 0xD9, 0x00, 0x80, 0xA2, 0xBD, 0x0B, 0xEF, 0xC7, + 0x33, 0xF9, 0x8C, 0x4C, 0x42, 0x7C, 0x68, 0x4E, + 0x54, 0x61, 0x06, 0x1E, 0x23, 0x93, 0x03, 0x76, + 0xF7, 0xD4, 0xC5, 0xBE, 0x89, 0x6E, 0x6C, 0x48, + 0x11, 0xAD, 0xC6, 0xFF, 0xAB, 0x58, 0x10, 0x43, + 0xD7, 0xC5, 0xBF, 0x73, 0x8E, 0x57, 0x0A, 0xCF, + 0xD0, 0x08, 0xE3, 0x24, 0x6B, 0x97, 0x4C, 0x87, + 0x00, 0xB9, 0x45, 0x52, 0x62, 0xF7, 0xEF, 0xAA, + 0xA4, 0xB8, 0x98, 0x5C, 0xC7, 0xF0, 0xE7, 0x2C, + 0xED, 0x26, 0x0F, 0x4C, 0x93, 0x8D, 0x27, 0x08, + 0xB1, 0xC1, 0x7D, 0xC6, 0xB1, 0xE8, 0x25, 0x0F, + 0x8F, 0xD1, 0x71, 0x4A, 0x85, 0x3A, 0xCC, 0x20, + 0xFA, 0x06, 0x98, 0x5A, 0x4F, 0x3F, 0x13, 0x78, + 0xEB, 0x99, 0x80, 0x42, 0xA1, 0x02, 0x90, 0x96, + 0x1F, 0xC9, 0x07, 0xBF, 0x61, 0xCA, 0x2D, 0x98, + 0xA0, 0x0F, 0x5B, 0x84, 0x76, 0x28, 0x5B, 0x4F, + 0x81, 0x14, 0xEE, 0x28, 0x8B, 0x62, 0x01, 0xBD, + 0x34, 0xE9, 0x45, 0x5B, 0x91, 0x1C, 0xEA, 0xAD, + 0x00, 0xD5, 0x23, 0x92, 0x28, 0x4A, 0xA9, 0x89, + 0x3F, 0x57, 0x24, 0xBE, 0xFF, 0x4F, 0xD6, 0x99, + 0x6B, 0x92, 0xF7, 0xB0, 0x1B, 0x9E, 0x9C, 0xB4, + 0xDB, 0x42, 0x65, 0xEB, 0xDD, 0x54, 0x56, 0xE9, + 0x3F, 0xD5, 0x3D, 0x9A, 0x4F, 0xD9, 0xDA, 0xD6, + 0x27, 0x2D, 0x83, 0xF0, 0xF1, 0x33, 0x22, 0x51, + 0x81, 0xF9, 0x00, 0x74, 0xB1, 0x2F, 0xE0, 0x35, + 0x3A, 0x1A, 0x92, 0x27, 0xE5, 0x24, 0x9C, 0x6A, + 0x00, 0x74, 0xFF, 0x52, 0x7A, 0xB8, 0xD5, 0x42, + 0xBF, 0x4E, 0xA2, 0x4D, 0x1E, 0x16, 0x31, 0x41, + 0x0A, 0xEE, 0x89, 0xE4, 0x86, 0x70, 0xCE, 0x85, + 0xCF, 0xB6, 0xE6, 0x7A, 0xF3, 0x56, 0xE9, 0xEB, + 0xE5, 0xDC, 0x0B, 0xCE, 0x5C, 0x3C, 0xEC, 0x92, + 0xA7, 0x7F, 0x12, 0xB5, 0x48, 0x43, 0xD6, 0x68, + 0xB4, 0x0B, 0x4C, 0xA0, 0xD5, 0xEE, 0xD9, 0x7E, + 0xE4, 0xC3, 0xCC, 0x54, 0x93, 0x1A, 0xD3, 0xF8, + 0x91, 0xF7, 0xF3, 0x6D, 0x14, 0x12, 0x40, 0x40, + 0xC0, 0x26, 0xAD, 0xE9, 0x45, 0xFA, 0x9C, 0xCB, + 0x5D, 0x85, 0xBE, 0xE7, 0x52, 0xDD, 0xC2, 0x8D, + 0xBF, 0xA2, 0x0A, 0x33, 0x49, 0x61, 0x5B, 0x2A, + 0x23, 0x12, 0xDF, 0x4E, 0xAF, 0x66, 0x6F, 0x6B, + 0xCE, 0xAB, 0x03, 0x8E, 0x75, 0x08, 0x32, 0x77, + 0xD3, 0x27, 0x45, 0x8D, 0x87, 0xA4, 0x2E, 0x1A, + 0xC5, 0xEC, 0x08, 0x64, 0xF5, 0x0B, 0xAA, 0x63, + 0x00, 0x24, 0x04, 0x2C, 0xD6, 0xD8, 0x6D, 0x5B, + 0x3D, 0xDD, 0x80, 0xD9, 0xF9, 0x68, 0x0C, 0xDF, + 0x98, 0x00, 0x38, 0xF5, 0x59, 0xBD, 0x13, 0xF2, + 0xDC, 0xB1, 0x86, 0x7F, 0x70, 0x6C, 0xFB, 0x7D, + 0x5B, 0x04, 0xAD, 0x53, 0x72, 0xC1, 0xF1, 0x3D, + 0xB2, 0x7E, 0xFD, 0x25, 0xA9, 0x80, 0x10, 0x4F, + 0x98, 0xB3, 0x6A, 0xD8, 0xBD, 0x08, 0x91, 0xC9, + 0x0F, 0x43, 0x09, 0x86, 0x2A, 0x82, 0xB9, 0x27, + 0x78, 0xCE, 0xD4, 0xBC, 0x9E, 0x1E, 0xD9, 0x25, + 0x12, 0x75, 0x7A, 0xD4, 0x03, 0xE7, 0x0C, 0xB1, + 0xCB, 0xF8, 0x04, 0x9C, 0xF4, 0x09, 0x9D, 0x63, + 0x09, 0x8F, 0x1F, 0x95, 0x75, 0x21, 0x12, 0x84, + 0xF9, 0xA1, 0x30, 0x75, 0x70, 0xDA, 0xFD, 0x38, + 0x5D, 0x56, 0x49, 0x7E, 0xCA, 0x53, 0xED, 0x4B, + 0x7D, 0xD5, 0xFE, 0xE7, 0x8F, 0x09, 0x57, 0xAF, + 0x2A, 0x67, 0x0C, 0xDB, 0x55, 0xCB, 0x0E, 0x4C, + 0xA1, 0xC7, 0xE0, 0xC7, 0xEF, 0x2A, 0x77, 0x0B, + 0x55, 0x17, 0xB2, 0xFA, 0x70, 0x88, 0xC2, 0xF0, + 0xB6, 0xD0, 0x24, 0x96, 0xCA, 0x60, 0x01, 0xB3, + 0x99, 0xFB, 0x59, 0x0B, 0xF4, 0x22, 0xDB, 0x32, + 0x8E, 0x01, 0x17, 0x60, 0x96, 0xE5, 0xBF, 0xB7, + 0x40, 0x3F, 0xD6, 0x2E, 0x7F, 0xC5, 0x25, 0x16, + 0xE2, 0x3A, 0xCB, 0x64, 0xFE, 0x97, 0xAA, 0xDD, + 0xB8, 0x88, 0x81, 0x81, 0x7A, 0x4C, 0xE0, 0xCF, + 0x4E, 0xBD, 0x32, 0x80, 0x50, 0x8D, 0xED, 0x82, + 0xAE, 0x68, 0xC4, 0x0C, 0x17, 0x55, 0x67, 0xCE, + 0x99, 0xD6, 0x1E, 0xEA, 0x19, 0x3B, 0x4C, 0xCC, + 0x4E, 0x03, 0x06, 0xB9, 0xDF, 0x98, 0xDA, 0xB1, + 0x2E, 0xB9, 0x8E, 0xFD, 0x3D, 0xA0, 0x9B, 0xD4, + 0xA7, 0x66, 0x3F, 0x6E, 0xE6, 0x99, 0xD3, 0x2E, + 0x4E, 0x78, 0xDF, 0x73, 0xA2, 0x4B, 0xA0, 0x15, + 0x90, 0x9A, 0x2C, 0x1A, 0xB0, 0x5E, 0xE7, 0xB0, + 0xFE, 0x69, 0xD4, 0x6F, 0x34, 0x9F, 0xEA, 0x47, + 0x3B, 0x72, 0x99, 0xD3, 0xA4, 0xA1, 0xDC, 0xD5, + 0xDC, 0x0C, 0x7E, 0x24, 0x31, 0x6B, 0x6D, 0x19, + 0x47, 0x1C, 0x02, 0x3F, 0x3C, 0x8A, 0xF7, 0xA4, + 0x3D, 0xF3, 0x08, 0x36, 0xC0, 0x7A, 0xD1, 0x18, + 0x15, 0x54, 0xDC, 0xFF, 0xF3, 0xFF, 0xAC, 0x76, + 0x56, 0x02, 0x7A, 0x72, 0xAC, 0x8A, 0x59, 0xE4, + 0x7E, 0x7A, 0xC4, 0x4C, 0x37, 0x5D, 0x9C, 0xFF, + 0x97, 0x64, 0x5E, 0x77, 0xC5, 0x2A, 0xE0, 0xD7, + 0x67, 0xAD, 0xE6, 0x2E, 0x92, 0xF9, 0x21, 0x48, + 0x07, 0x26, 0xAB, 0xA7, 0xD3, 0xE9, 0xA1, 0x8D, + 0x27, 0x89, 0xE9, 0x90, 0x2D, 0x4E, 0x33, 0xDE, + 0xDD, 0xB1, 0x41, 0xC6, 0x58, 0x30, 0xA8, 0x55, + 0x9A, 0x06, 0xFF, 0xE2, 0x96, 0x7A, 0x52, 0x3B, + 0xC5, 0x20, 0xDA, 0x43, 0x58, 0xC1, 0x9F, 0x8C, + 0xA1, 0x6F, 0xA8, 0x37, 0xA4, 0xDE, 0xE5, 0x96, + 0x8C, 0x37, 0x08, 0xB7, 0x84, 0xFF, 0x47, 0x8E, + 0xA1, 0x69, 0x4A, 0x20, 0x0C, 0x6E, 0x2F, 0x7D, + 0xEE, 0x9B, 0x25, 0x29, 0xCE, 0x3F, 0x5B, 0xF6, + 0x20, 0x79, 0xC9, 0x1E, 0xFE, 0xB5, 0xA8, 0x98, + 0x33, 0x43, 0x86, 0x5C, 0xDD, 0xDC, 0xBD, 0x8A, + 0x3C, 0xC1, 0xCE, 0x60, 0x22, 0x5D, 0x76, 0xBF, + 0xAF, 0x9D, 0x91, 0x7D, 0x68, 0x22, 0xD5, 0xE5, + 0xC1, 0x37, 0xA8, 0x87, 0xA4, 0x61, 0xD5, 0x2C, + 0x7A, 0xDD, 0xAF, 0xF0, 0x95, 0x8C, 0xB4, 0xB0, + 0x25, 0x58, 0x35, 0x6C, 0x0E, 0xF4, 0xDC, 0x73, + 0xDB, 0xAC, 0x9E, 0xEE, 0x4E, 0x5B, 0x4F, 0xEB, + 0x33, 0xCB, 0x4A, 0xC3, 0x68, 0x3A, 0x6D, 0xCD, + 0x38, 0xCE, 0xD1, 0x3B, 0x17, 0x29, 0x1C, 0x66, + 0xF0, 0x3B, 0x2E, 0x36, 0xFF, 0x14, 0xF6, 0x3C, + 0x58, 0xF5, 0xEB, 0xF3, 0x46, 0x23, 0x66, 0x19, + 0x36, 0xA6, 0x2B, 0x93, 0x7C, 0x35, 0x71, 0x75, + 0xA3, 0x7A, 0x61, 0x00, 0x03, 0xAE, 0x8C, 0x53, + 0xDB, 0xBA, 0xC7, 0x52, 0x2C, 0x01, 0x65, 0xBA, + 0xF5, 0x5D, 0xFD, 0xEF, 0xA5, 0xDB, 0x6F, 0x1F, + 0x83, 0x10, 0xAB, 0x50, 0xF1, 0x7A, 0xBD, 0xF9, + 0x8D, 0xBF, 0x8B, 0xBB, 0x9E, 0x4F, 0x18, 0xA3, + 0xC1, 0x79, 0x36, 0x97, 0xF9, 0xA1, 0x39, 0x4A, + 0x7B, 0x34, 0xD2, 0x48, 0x4F, 0x1B, 0xE6, 0xFB, + 0x93, 0x67, 0x28, 0xA8, 0x28, 0xF8, 0xFF, 0xED, + 0x31, 0x65, 0xA3, 0x47, 0x55, 0xAB, 0x5F, 0x43, + 0x05, 0xAB, 0x54, 0x5C, 0xED, 0x4C, 0x1A, 0x20, + 0xA4, 0x5A, 0x5B, 0x39, 0xBA, 0x5C, 0x5D, 0x5A, + 0x38, 0x78, 0x71, 0x76, 0x66, 0xB3, 0x53, 0x4A, + 0xE5, 0xE2, 0x90, 0xE4, 0xD7, 0x76, 0x84, 0x87, + 0xF7, 0xB5, 0xF4, 0xDD, 0x59, 0xAA, 0xFB, 0x44, + 0xA0, 0x5C, 0x7D, 0x56, 0x04, 0x59, 0xF2, 0x0E, + 0xDD, 0xE9, 0xBF, 0xE3, 0x06, 0xB9, 0x6A, 0x3E, + 0xD3, 0x41, 0xE5, 0xC5, 0xFB, 0xA5, 0x9B, 0x89, + 0x55, 0x1A, 0x2D, 0x27, 0xFF, 0x2E, 0x2E, 0xCA, + 0x95, 0x94, 0x9F, 0x3D, 0x95, 0x7E, 0x27, 0xA3, + 0x47, 0x04, 0xA1, 0x1F, 0xCB, 0xDD, 0xB3, 0xA3, + 0x30, 0x96, 0x4C, 0x78, 0xCE, 0x9B, 0x00, 0xA3, + 0x22, 0xAF, 0xB7, 0x9D, 0x52, 0x5C, 0xB5, 0x40, + 0xFA, 0xC0, 0xA7, 0x20, 0x60, 0xC4, 0x33, 0xD4, + 0xDF, 0x24, 0xBE, 0x9A, 0x7E, 0xE7, 0xC5, 0x21, + 0x37, 0xF1, 0x62, 0x8F, 0x0F, 0x01, 0xB3, 0xF4, + 0x06, 0xC7, 0xBC, 0x21, 0x78, 0x8F, 0x18, 0x89, + 0x03, 0xB5, 0x75, 0x88, 0x28, 0x74, 0x55, 0xA8, + 0xDB, 0xD1, 0x04, 0x01, 0xA0, 0x84, 0x84, 0x27, + 0xE0, 0x6F, 0x19, 0x8F, 0xE5, 0xA6, 0xE3, 0x61, + 0x75, 0x92, 0xE1, 0x25, 0x82, 0x5E, 0x8D, 0x79, + 0x5E, 0x9C, 0x3B, 0x14, 0xAC, 0x51, 0x06, 0x3D, + 0x13, 0xB9, 0x3D, 0xDD, 0xE5, 0x65, 0xFC, 0xBC, + 0x19, 0xD3, 0xA6, 0x1F, 0x3E, 0xB4, 0xA3, 0x08, + 0xEA, 0x67, 0x26, 0x0B, 0x11, 0x9E, 0x8D, 0xC8, + 0xF1, 0x1B, 0x0F, 0x6C, 0x5E, 0x6C, 0xBD, 0xD3, + 0x41, 0xEF, 0x1E, 0xFD, 0xD3, 0x31, 0x0D, 0x41, + 0xAF, 0x9A, 0xD0, 0xAD, 0xC1, 0x31, 0xE3, 0x2E, + 0x81, 0xE9, 0x43, 0x3B, 0xEB, 0x3D, 0x40, 0xF9, + 0x60, 0x29, 0xE7, 0xA1, 0x89, 0xDD, 0x0E, 0xF2, + 0x14, 0x1F, 0x0D, 0xD5, 0xC0, 0x76, 0xFF, 0x72, + 0x4B, 0x09, 0xD5, 0x1A, 0x9A, 0x1D, 0x7F, 0xBA, + 0x24, 0x17, 0x40, 0xC1, 0x72, 0xA8, 0x0A, 0xFF, + 0xEA, 0x3B, 0x33, 0x84, 0xFD, 0xA2, 0xD8, 0xA5, + 0x76, 0x0A, 0x74, 0x15, 0x3B, 0x72, 0x80, 0x94, + 0x24, 0x0F, 0xBB, 0xE1, 0x2C, 0x6E, 0x65, 0xC1, + 0xBA, 0x7B, 0xC9, 0x75, 0x8C, 0x5C, 0x5B, 0xC9, + 0x69, 0x72, 0xFD, 0x62, 0x80, 0x1F, 0x6A, 0x83, + 0xCE, 0xD8, 0x50, 0x6F, 0x43, 0x8D, 0x49, 0x32, + 0x5B, 0x9A, 0xCE, 0xD0, 0x45, 0x90, 0xBD, 0xF6, + 0x21, 0x3C, 0xED, 0x50, 0xC2, 0xA1, 0x69, 0x72, + 0x65, 0x68, 0x78, 0xCA, 0x22, 0xD5, 0xC4, 0xA5, + 0x0B, 0x00, 0x8A, 0x62, 0x88, 0xE9, 0x32, 0xEC, + 0x41, 0x56, 0x76, 0x99, 0x51, 0xD0, 0x96, 0x62, + 0x4E, 0x72, 0xA9, 0x95, 0xA1, 0xDF, 0xBC, 0x75, + 0x47, 0x34, 0x48, 0x72, 0x5C, 0xEF, 0x79, 0x0D, + 0xB4, 0x87, 0xEC, 0x88, 0xE0, 0x87, 0xA7, 0x1C, + 0x8C, 0xC4, 0x9E, 0x8F, 0xC0, 0x6B, 0x7B, 0x69, + 0xF8, 0xE0, 0x75, 0xF3, 0xB5, 0xC5, 0xCA, 0x5E, + 0xE9, 0xBA, 0x42, 0x03, 0x59, 0x21, 0xB8, 0x6C, + 0xEE, 0xAF, 0xE2, 0xD3, 0x5D, 0x55, 0x2D, 0xDE, + 0x29, 0xC5, 0x59, 0x92, 0xA9, 0x8F, 0xC7, 0x81, + 0x2F, 0x74, 0x40, 0x7A, 0xE3, 0x9A, 0xF6, 0x30, + 0x6F, 0x1A, 0xBC, 0xB4, 0x1D, 0xCA, 0x65, 0x0A, + 0x8A, 0x6C, 0x0A, 0x38, 0x9D, 0xD3, 0xCB, 0x24, + 0x96, 0xBD, 0x62, 0xC7, 0xC2, 0xF4, 0x0A, 0x36, + 0x99, 0x33, 0x8B, 0xC8, 0xEC, 0x4C, 0xF2, 0xB6, + 0xA9, 0x60, 0xAD, 0xB2, 0xB8, 0xFF, 0xC8, 0x13, + 0xEE, 0x09, 0xB4, 0x6E, 0xC5, 0x08, 0xF4, 0x28, + 0x6D, 0x1F, 0x59, 0x39, 0x1F, 0x68, 0x9B, 0x7F, + 0xBA, 0x3E, 0xA3, 0x93, 0xCD, 0x51, 0x90, 0x3E, + 0xA6, 0x1A, 0x34, 0x6D, 0x03, 0x1E, 0xBB, 0x40, + 0x63, 0xCF, 0x5D, 0xA2, 0xEA, 0x9A, 0x36, 0x39, + 0x26, 0x23, 0x52, 0x4E, 0xE1, 0x02, 0x65, 0x0D, + 0x27, 0x0E, 0x27, 0xC7, 0xC2, 0x32, 0x3F, 0x4E, + 0x52, 0xF8, 0x81, 0x42, 0x83, 0x98, 0x71, 0x47, + 0x26, 0xA2, 0xB2, 0x29, 0x64, 0x72, 0x97, 0x27, + 0xC0, 0xFF, 0x8F, 0x35, 0x41, 0xD7, 0x0A, 0xDA, + 0x11, 0x43, 0x2A, 0x04, 0x60, 0xF8, 0x97, 0x77, + 0x73, 0x26, 0xC3, 0x53, 0x09, 0xFD, 0x95, 0x55, + 0x78, 0x16, 0x6E, 0xC9, 0x09, 0x00, 0x64, 0x4A, + 0xF3, 0x46, 0xDF, 0x8B, 0xAD, 0x3A, 0x26, 0x9A, + 0x24, 0xE9, 0xE9, 0x38, 0xA1, 0x5A, 0x4E, 0x72, + 0x7A, 0xF4, 0xEF, 0xE1, 0x61, 0x01, 0x24, 0x53, + 0xB0, 0x26, 0x19, 0xB8, 0x9D, 0x21, 0x10, 0xDC, + 0x56, 0x40, 0x86, 0x66, 0x6B, 0xAA, 0x3C, 0x73, + 0x30, 0xF4, 0x0E, 0x10, 0x20, 0x02, 0xC6, 0x86, + 0xB3, 0xCA, 0xDF, 0x57, 0xAE, 0xBC, 0xB1, 0x3F, + 0x12, 0x31, 0x74, 0xE7, 0x63, 0x52, 0xD2, 0x74, + 0x95, 0x1F, 0x7B, 0x5E, 0xE2, 0x4F, 0x4D, 0xF9, + 0x36, 0xC8, 0xF9, 0x05, 0x03, 0x22, 0x44, 0x16, + 0x24, 0x4E, 0x30, 0x6B, 0xAA, 0x67, 0xF1, 0xCD, + 0x99, 0x3E, 0x55, 0xCF, 0x43, 0xC0, 0x69, 0x97, + 0xB4, 0x76, 0x87, 0xB5, 0xD5, 0x92, 0x32, 0x42, + 0xFA, 0xC9, 0x77, 0x2B, 0x33, 0xEA, 0x10, 0xBE, + 0x5F, 0x31, 0x65, 0xBA, 0xD2, 0xBC, 0x49, 0x2A, + 0x9F, 0x93, 0x5B, 0xAD, 0x04, 0x63, 0x2A, 0xE4, + 0x6F, 0x51, 0x0B, 0xB4, 0x5C, 0x0A, 0xD2, 0x07, + 0x95, 0xB8, 0xC8, 0xB7, 0x55, 0xC6, 0x09, 0xE4, + 0xB5, 0xF2, 0x89, 0x68, 0x6D, 0x65, 0x4C, 0xB4, + 0x02, 0xD5, 0xB5, 0xB3, 0x9A, 0x2D, 0xED, 0xE5, + 0x43, 0xE8, 0x64, 0x65, 0xFE, 0xD7, 0xDC, 0x92, + 0x9F, 0xF4, 0x92, 0xA7, 0x38, 0xD5, 0xA1, 0xCB, + 0xCF, 0x32, 0xAD, 0xD2, 0x4A, 0x3F, 0xF5, 0x13, + 0x73, 0x06, 0x3D, 0x0F, 0xCB, 0xF7, 0xA0, 0xA2, + 0x2A, 0x54, 0x60, 0xC7, 0xEA, 0x08, 0xFE, 0x56, + 0x4B, 0xEB, 0x65, 0x7B, 0x7E, 0xD6, 0xD4, 0x71, + 0xC6, 0xF6, 0x5D, 0x27, 0x13, 0x8C, 0x89, 0x2C, + 0x44, 0xD9, 0xE4, 0x3F, 0x5E, 0xC4, 0x90, 0xEA, + 0x33, 0xE6, 0xE1, 0x6F, 0xFF, 0x9E, 0x89, 0xF1, + 0x2C, 0xFF, 0x5D, 0xC0, 0x94, 0x2C, 0xBC, 0xCA, + 0x4D, 0x9A, 0xC4, 0xCA, 0x78, 0x45, 0xC3, 0x3A, + 0x61, 0xD7, 0xA1, 0xF7, 0x8E, 0x26, 0xB4, 0xF6, + 0x9E, 0x75, 0x20, 0x18, 0x1A, 0xAA, 0x35, 0x4F, + 0xAC, 0xA9, 0x82, 0xFE, 0xF8, 0xCA, 0x6D, 0x79, + 0xFD, 0xE1, 0x2C, 0xB5, 0xB1, 0x3B, 0xAB, 0xCC, + 0x5C, 0x55, 0x73, 0x47, 0x8F, 0xB6, 0x04, 0x1A, + 0x49, 0x64, 0x27, 0xC8, 0x88, 0x7D, 0xFD, 0x2F, + 0x78, 0x40, 0x9D, 0xDB, 0x9D, 0x76, 0x25, 0x05, + 0x72, 0xC1, 0x7B, 0x9B, 0xD5, 0x86, 0xD3, 0x62, + 0x91, 0xCF, 0x39, 0xAD, 0x31, 0x9E, 0x5A, 0x36, + 0x37, 0x6D, 0x79, 0xE6, 0xDB, 0x02, 0x3D, 0xD5, + 0x67, 0xB2, 0xC9, 0xE3, 0x09, 0x00, 0x01, 0xBC, + 0xC8, 0x2D, 0x70, 0xB8, 0x03, 0x54, 0x8F, 0xF8, + 0x63, 0x27, 0x43, 0x29, 0x84, 0xDD, 0xB0, 0xC5, + 0xD3, 0x4B, 0x60, 0x2C, 0xB1, 0xF4, 0x47, 0xA5, + 0xD4, 0xC5, 0x88, 0x56, 0x44, 0xBC, 0x3C, 0x63, + 0x87, 0xF3, 0xD4, 0xAE, 0x76, 0xAA, 0x4E, 0x58, + 0x76, 0x65, 0x41, 0xD7, 0xC6, 0x08, 0xB6, 0x39, + 0x54, 0xD9, 0x0B, 0xF2, 0x5C, 0x8B, 0xB2, 0xEA, + 0x0F, 0x90, 0x13, 0xB5, 0x17, 0xA1, 0xAB, 0x7A, + 0xBD, 0xB2, 0x84, 0x8C, 0xB4, 0x17, 0x30, 0x7A, + 0x30, 0xEA, 0x32, 0x8F, 0x67, 0x7A, 0xC6, 0xCC, + 0x8A, 0xB7, 0x32, 0xB0, 0x0B, 0x3D, 0x91, 0x67, + 0x5D, 0x23, 0xDB, 0x7C, 0x87, 0x5F, 0x31, 0xF6, + 0xBD, 0xD5, 0x20, 0x62, 0xE0, 0xAE, 0xA1, 0xB3, + 0xDE, 0xA8, 0x14, 0x5C, 0x27, 0x7A, 0x23, 0x84, + 0x8C, 0x52, 0x14, 0x94, 0x46, 0x3E, 0x6D, 0xAD, + 0xB6, 0xB6, 0xFE, 0x78, 0xD6, 0x1A, 0xF5, 0xCC, + 0x32, 0xE9, 0x16, 0x24, 0xF5, 0xFD, 0xF5, 0x8D, + 0xDE, 0x3D, 0xB6, 0xAD, 0xAC, 0x22, 0x31, 0xAF, + 0x55, 0xA4, 0x50, 0x1F, 0x9E, 0x34, 0x57, 0x06, + 0x45, 0x6B, 0x58, 0x5A, 0xD4, 0x85, 0x56, 0x88, + 0x3F, 0x0F, 0x05, 0x30, 0xF5, 0x3E, 0x82, 0x59, + 0x93, 0xFB, 0xA3, 0x41, 0x5F, 0x54, 0xFD, 0x43, + 0x76, 0x62, 0xB9, 0x23, 0x1A, 0x0A, 0x11, 0xF9, + 0x11, 0x41, 0xA0, 0x75, 0x96, 0x21, 0xFA, 0x60, + 0xC6, 0x9E, 0xF7, 0x2F, 0x45, 0x95, 0x30, 0x24, + 0xA9, 0x02, 0x59, 0xB5, 0x79, 0x01, 0x15, 0x7A, + 0xD2, 0x24, 0x41, 0xEF, 0x1B, 0x31, 0x62, 0x99, + 0x25, 0x21, 0x6B, 0x3E, 0xC7, 0x71, 0xC3, 0x77, + 0x50, 0x7A, 0x0C, 0xDB, 0xEE, 0x82, 0x93, 0x64, + 0xC1, 0x57, 0xD4, 0x1E, 0xF0, 0x02, 0xAA, 0x1A, + 0x7B, 0x65, 0x3F, 0xED, 0x71, 0x6B, 0x1D, 0x81, + 0x78, 0x65, 0x60, 0xCC, 0xC7, 0xF8, 0xD8, 0x77, + 0x86, 0x61, 0xC8, 0x7F, 0x2E, 0x9D, 0xCC, 0xFC, + 0x22, 0x79, 0xE5, 0x9D, 0xE8, 0x87, 0xBB, 0x47, + 0x78, 0xD5, 0xA7, 0xAD, 0x3F, 0xC8, 0x77, 0x80, + 0x61, 0xD8, 0x60, 0x48, 0x9D, 0x7F, 0x6B, 0xB1, + 0x95, 0x2D, 0xE8, 0xD2, 0xDC, 0x77, 0x25, 0x93, + 0xB1, 0xB1, 0x9D, 0x52, 0x91, 0x8F, 0xFD, 0x09, + 0x9B, 0x46, 0x9A, 0x45, 0x6D, 0xA0, 0x1B, 0x49, + 0x2E, 0xA1, 0xED, 0xF4, 0x78, 0xE6, 0xC8, 0x70, + 0xA5, 0xD7, 0xC3, 0x13, 0x3C, 0xE4, 0x9A, 0xDF, + 0xE9, 0x4A, 0xB9, 0x56, 0x0B, 0x75, 0x32, 0x23, + 0x98, 0x60, 0x20, 0xE9, 0xC5, 0xB5, 0xB2, 0x7B, + 0x83, 0x29, 0xA3, 0x29, 0xAE, 0x64, 0xB4, 0x2F, + 0xA3, 0xB5, 0x75, 0xD8, 0x54, 0xA2, 0x94, 0x26, + 0x2C, 0xB9, 0xD4, 0xCA, 0x79, 0x78, 0x1C, 0xF1, + 0xA1, 0x3A, 0x29, 0xB0, 0xE2, 0x8A, 0x62, 0xA6, + 0x55, 0x87, 0x2C, 0x44, 0x3C, 0x6C, 0x5E, 0xD9, + 0x2E, 0x1A, 0xC3, 0x97, 0x20, 0x32, 0xF8, 0x65, + 0x45, 0xF0, 0x87, 0x93, 0x03, 0x93, 0x0D, 0xD1, + 0x6F, 0x2A, 0xD7, 0x28, 0x99, 0xE1, 0x72, 0xA1, + 0x5B, 0x86, 0x7C, 0xD0, 0x12, 0xFE, 0xF5, 0x28, + 0xE1, 0x17, 0x50, 0xE8, 0xE6, 0x08, 0x38, 0xDC, + 0xAB, 0xB5, 0x78, 0x51, 0x9C, 0x19, 0x41, 0xAE, + 0x4F, 0xD4, 0x7F, 0x25, 0x61, 0xEF, 0x53, 0x85, + 0xA2, 0x8C, 0x4E, 0x3E, 0x65, 0x37, 0x06, 0x66, + 0x45, 0xE6, 0x74, 0x11, 0x24, 0x40, 0x46, 0xE4, + 0x25, 0x4D, 0x18, 0xCA, 0x6A, 0x85, 0xC8, 0x2A, + 0x01, 0xD3, 0x26, 0x45, 0x48, 0x78, 0x6C, 0xC7, + 0x01, 0xC0, 0x94, 0xDB, 0x0B, 0x94, 0x23, 0x50, + 0xB1, 0x14, 0xBF, 0x67, 0x4F, 0x61, 0xB3, 0xC7, + 0x89, 0x39, 0xB7, 0x37, 0xF2, 0xCC, 0x72, 0x47, + 0x73, 0x67, 0xA6, 0x29, 0x29, 0x4D, 0x9A, 0x17, + 0xA6, 0x17, 0x7A, 0xFC, 0x2C, 0x9C, 0xE2, 0x91, + 0x40, 0x00, 0xA2, 0x13, 0xA7, 0x8B, 0x6A, 0x98, + 0x2C, 0xB5, 0x2C, 0x4A, 0xCB, 0x4C, 0x1E, 0x98, + 0x49, 0xC9, 0x56, 0x55, 0x1E, 0xF6, 0x40, 0x55, + 0xE3, 0x7F, 0xEB, 0x36, 0x51, 0xF1, 0x17, 0xCE, + 0x98, 0x70, 0x96, 0xAC, 0xBE, 0x3D, 0x34, 0x25, + 0xBA, 0x39, 0x43, 0x5B, 0xDD, 0x6F, 0xE7, 0x48, + 0xCB, 0xE9, 0x9D, 0xF4, 0x88, 0x1E, 0xA0, 0xDF, + 0x4C, 0x25, 0x52, 0x60, 0xF0, 0xCA, 0x54, 0x66, + 0x0D, 0xAD, 0x99, 0x15, 0x02, 0x15, 0xE3, 0x73, + 0x59, 0x24, 0xBB, 0xEA, 0x32, 0x11, 0xB0, 0x3F, + 0xC1, 0xEC, 0x46, 0xBB, 0x6A, 0x60, 0x24, 0x80, + 0x20, 0x2D, 0x86, 0xAA, 0xDD, 0xF1, 0x63, 0xEC, + 0x34, 0xCE, 0xBC, 0x70, 0xAE, 0xA7, 0xA7, 0xE8, + 0xA6, 0xAF, 0x3A, 0x9E, 0xF2, 0xED, 0x13, 0x68, + 0xC7, 0xF8, 0x2B, 0xE7, 0x89, 0x3E, 0xB2, 0x21, + 0x42, 0x63, 0x12, 0x83, 0xCA, 0xBE, 0x7A, 0x95, + 0x75, 0x9C, 0xEA, 0x74, 0xA6, 0x1C, 0x99, 0x15, + 0xB9, 0x0E, 0x6E, 0x1F, 0x9B, 0xB5, 0xA2, 0x4D, + 0x85, 0x08, 0x32, 0xF3, 0xE7, 0x9A, 0x7C, 0x84, + 0x9B, 0x2A, 0x32, 0xEC, 0x29, 0x4F, 0xEA, 0xAD, + 0x44, 0xDB, 0x2D, 0xC8, 0xB7, 0x26, 0x00, 0x65, + 0x0A, 0xA0, 0x05, 0x07, 0x73, 0xC0, 0xAE, 0x01, + 0x08, 0x88, 0x86, 0xD8, 0x0D, 0xC8, 0xC5, 0x4C, + 0x70, 0x13, 0x6A, 0x3F, 0x79, 0x0A, 0x11, 0x12, + 0x0D, 0xC5, 0xAA, 0x22, 0xD3, 0x9B, 0x45, 0x62, + 0xA2, 0x5C, 0xA7, 0x49, 0x5C, 0x7B, 0xF8, 0x22, + 0x3E, 0x98, 0xD3, 0xE0, 0x2C, 0x0E, 0x9A, 0x1E, + 0x2E, 0x19, 0x7A, 0x2D, 0xD9, 0x48, 0x7F, 0xA8, + 0x10, 0x8F, 0x01, 0x07, 0x98, 0x79, 0x1E, 0x5F, + 0xEB, 0x7E, 0xD0, 0x79, 0x35, 0xB6, 0xE2, 0x4D, + 0xA7, 0xE5, 0x34, 0x46, 0x1D, 0x77, 0xE0, 0xE7, + 0xA5, 0xBD, 0x3E, 0xFE, 0xEC, 0xA8, 0x6A, 0xCA, + 0x9A, 0x0B, 0x45, 0xC3, 0x19, 0xAE, 0xF0, 0xA5, + 0x91, 0x72, 0x7D, 0x1B, 0x2D, 0xCD, 0xE6, 0x43, + 0x05, 0x33, 0x87, 0x42, 0x34, 0x76, 0xCD, 0xB0, + 0x04, 0x8B, 0x85, 0x59, 0xD2, 0xB6, 0x01, 0xE7, + 0x92, 0xFB, 0x99, 0x08, 0x74, 0x39, 0xD7, 0x32, + 0xA7, 0xEE, 0x23, 0x3E, 0x3F, 0xBE, 0x8E, 0xDE, + 0x19, 0xC0, 0x38, 0xC3, 0x08, 0x26, 0x2A, 0x22, + 0x75, 0xF7, 0xE4, 0xC5, 0x67, 0x62, 0x10, 0x3D, + 0x16, 0x3F, 0x97, 0x3C, 0x86, 0x27, 0x6D, 0x98, + 0x98, 0xF1, 0x25, 0xE0, 0x85, 0x15, 0x1D, 0xC8, + 0x26, 0x8B, 0x64, 0x8F, 0xB8, 0x89, 0xB7, 0xB7, + 0xB4, 0x58, 0xC4, 0x45, 0x2F, 0x73, 0x12, 0x19, + 0xDD, 0xB3, 0xC9, 0x44, 0xCA, 0xA6, 0xB1, 0xD1, + 0x6F, 0x2C, 0xB9, 0x8C, 0xDE, 0x4B, 0xBE, 0x00, + 0x1B, 0x22, 0x7C, 0x9D, 0x46, 0xEE, 0x36, 0x73, + 0x9E, 0xA5, 0x14, 0x8F, 0x9A, 0xC9, 0x9A, 0xAC, + 0x6A, 0x90, 0xFD, 0x36, 0x8C, 0x7B, 0x32, 0x3A, + 0xDE, 0x04, 0x5D, 0xD7, 0xD7, 0xA7, 0x2D, 0xF3, + 0x9C, 0xAC, 0x6C, 0x75, 0xE7, 0xBC, 0x1E, 0xD7, + 0xC0, 0x96, 0x7F, 0x52, 0xDC, 0xA0, 0xDA, 0xA0, + 0xCC, 0xBF, 0x30, 0x48, 0x8C, 0x7B, 0x21, 0xC4, + 0xB4, 0x2B, 0x8A, 0x27, 0x3E, 0x7F, 0xE3, 0x8D, + 0x1D, 0xF4, 0xF0, 0xC3, 0x50, 0xB0, 0x28, 0x2E, + 0xDA, 0x10, 0xE2, 0x84, 0x78, 0x45, 0xE2, 0xD1, + 0xF6, 0xA8, 0x22, 0xEE, 0xAD, 0x33, 0x39, 0x15, + 0x85, 0x11, 0x82, 0xC7, 0xDB, 0xF3, 0xB3, 0x6D, + 0xF9, 0x48, 0xB3, 0xA0, 0xC5, 0x02, 0x09, 0xF2, + 0xEB, 0x65, 0xF2, 0x3F, 0xFC, 0x56, 0x2F, 0x15, + 0xBB, 0xB3, 0x6C, 0xDD, 0x2A, 0x7B, 0x64, 0xCE, + 0x21, 0x58, 0xD0, 0x9B, 0xEE, 0xC7, 0x2B, 0x96, + 0xD3, 0x13, 0x35, 0xC5, 0x78, 0x46, 0x31, 0xD4, + 0xF2, 0x0E, 0x2C, 0x24, 0xAC, 0x7E, 0x7E, 0x45, + 0x6D, 0xEB, 0x5D, 0xF1, 0x00, 0xAF, 0x1C, 0x97, + 0x20, 0x1C, 0xEB, 0x54, 0x75, 0x17, 0xD0, 0x33, + 0x0C, 0x00, 0x92, 0x3F, 0xD1, 0xF6, 0x81, 0x10, + 0xE6, 0x48, 0x09, 0x33, 0x67, 0xF5, 0x2F, 0x51, + 0xE1, 0xE2, 0x99, 0x85, 0x17, 0xB3, 0xD6, 0x33, + 0x30, 0x9D, 0x23, 0xE2, 0x8A, 0x36, 0xE6, 0xE1, + 0x47, 0x2A, 0x12, 0x3A, 0xF4, 0xE2, 0x7C, 0xAB, + 0xF4, 0xC0, 0xCC, 0xF8, 0xE3, 0x2B, 0x30, 0x7A, + 0x9F, 0x9D, 0xCB, 0x21, 0x86, 0x4B, 0x76, 0x73, + 0x27, 0xA2, 0x96, 0x65, 0x95, 0x48, 0xBB, 0x28, + 0xA7, 0x6C, 0xA3, 0x1B, 0xB7, 0xD5, 0x26, 0xD7, + 0xEA, 0x61, 0xFC, 0xFD, 0xB2, 0xB1, 0x80, 0xEA, + 0x1F, 0x1C, 0x2B, 0x5F, 0x07, 0x5B, 0xBA, 0x4C, + 0x2F, 0xE5, 0x67, 0x1C, 0x2B, 0x3F, 0x30, 0x9D, + 0xBC, 0xB1, 0x0E, 0x43, 0x9D, 0x4C, 0x97, 0xD5, + 0x0F, 0x87, 0x1B, 0xD6, 0x3D, 0xC1, 0x45, 0x06, + 0xE4, 0x2B, 0xE4, 0xA5, 0xB1, 0x47, 0x63, 0xCF, + 0x68, 0x74, 0x41, 0x44, 0x58, 0x76, 0xC3, 0x68, + 0x6D, 0xB0, 0xBC, 0xF8, 0x84, 0x75, 0x18, 0xF5, + 0x0B, 0xB4, 0x42, 0xEC, 0x6B, 0xA6, 0x10, 0xAB, + 0x80, 0x1A, 0x6C, 0x26, 0x55, 0xC7, 0x4E, 0x1E, + 0xD1, 0x6F, 0x71, 0x97, 0xDB, 0x3C, 0x63, 0x63, + 0x7B, 0x0B, 0xD4, 0x17, 0x11, 0xD1, 0xC2, 0xF4, + 0x13, 0xF9, 0x0D, 0xEB, 0x27, 0xE2, 0xB4, 0xB6, + 0x0C, 0x4D, 0xAD, 0xAB, 0x9A, 0x69, 0x79, 0x9E, + 0x07, 0xAB, 0x36, 0xBA, 0xC2, 0x51, 0x81, 0xA1, + 0x70, 0x3F, 0xDA, 0x7B, 0xFE, 0xCD, 0xFF, 0x1C, + 0xF9, 0xD1, 0x71, 0x92, 0x3F, 0xE9, 0xF6, 0x8D, + 0x2B, 0x37, 0xF3, 0xBB, 0x48, 0x6A, 0x51, 0xBD, + 0xA5, 0xBA, 0xC7, 0x84, 0xD0, 0xF8, 0x36, 0x0E, + 0xC4, 0xCF, 0xEE, 0x73, 0x8F, 0x6D, 0x48, 0x1E, + 0x80, 0x19, 0x42, 0x32, 0x2A, 0x37, 0xCD, 0x7A, + 0x03, 0x6B, 0x76, 0x91, 0xDD, 0x81, 0xC5, 0x0F, + 0x23, 0x42, 0x88, 0xB0, 0x6A, 0x9E, 0xDE, 0xC6, + 0x4E, 0xBF, 0xD3, 0x99, 0xA1, 0x8E, 0xF3, 0x8C, + 0x1B, 0x4D, 0x86, 0x15, 0x28, 0x45, 0x71, 0x6A, + 0xF4, 0x71, 0xFA, 0x42, 0x5C, 0xF6, 0x29, 0x90, + 0x4E, 0xE4, 0xA3, 0x3E, 0xFE, 0x2C, 0x45, 0x22, + 0x69, 0xAA, 0x8F, 0xFE, 0xB2, 0x82, 0x7C, 0x67, + 0x74, 0x20, 0xCA, 0x28, 0x29, 0x06, 0xED, 0x41, + 0xF6, 0x8A, 0x6D, 0xEA, 0xDA, 0xB4, 0xDF, 0x89, + 0xBC, 0xA6, 0xFE, 0x09, 0x98, 0x57, 0x28, 0xE1, + 0x37, 0xCC, 0x31, 0x4C, 0xBE, 0xD1, 0x3B, 0x82, + 0x97, 0xE3, 0xE5, 0xEE, 0x9F, 0x0D, 0x1D, 0x09, + 0x6B, 0x35, 0xE6, 0x08, 0x32, 0x77, 0x4C, 0xF0, + 0x12, 0xBD, 0xEF, 0x8B, 0x92, 0x0A, 0x53, 0x71, + 0x70, 0xB7, 0x5D, 0xCA, 0x40, 0x31, 0x66, 0x81, + 0x89, 0x11, 0xED, 0x6F, 0xB2, 0xA3, 0x11, 0x50, + 0x82, 0x12, 0x0A, 0x09, 0x09, 0xF2, 0x90, 0x5A, + 0xDE, 0x1C, 0x82, 0xF3, 0xB7, 0xF8, 0x30, 0x15, + 0x48, 0x8D, 0x9E, 0xF9, 0x5E, 0x9A, 0x12, 0x52, + 0x77, 0xBF, 0x32, 0x9F, 0xC9, 0xF0, 0x73, 0x3C, + 0x6B, 0x79, 0x76, 0xAE, 0xFB, 0x6D, 0xB0, 0xCD, + 0x84, 0x91, 0xA8, 0x33, 0x5A, 0x5F, 0xC7, 0x05, + 0x64, 0xFE, 0xB6, 0xBF, 0x90, 0xBF, 0x9E, 0xA8, + 0x2B, 0x5D, 0x29, 0xB9, 0xD8, 0x3E, 0x5F, 0x9C, + 0xA0, 0x37, 0xE0, 0xD8, 0xC2, 0x4C, 0xF0, 0x09, + 0xB6, 0x96, 0x54, 0x3F, 0x1C, 0xF6, 0x70, 0x19, + 0xE5, 0xB9, 0x99, 0x88, 0x5D, 0xFA, 0xB6, 0x64, + 0xF1, 0xA4, 0x6E, 0xCD, 0x22, 0xAE, 0xE0, 0xCF, + 0x99, 0x3C, 0xB0, 0xD2, 0x09, 0xFA, 0xC7, 0xD9, + 0xAA, 0xFA, 0x1C, 0xA0, 0x60, 0xA8, 0x15, 0x9C, + 0x6E, 0xF6, 0xED, 0xD6, 0x69, 0xCE, 0x40, 0x8B, + 0xA1, 0xEB, 0xCC, 0xD2, 0xF7, 0x34, 0x21, 0x84, + 0xFB, 0xC3, 0xB0, 0x50, 0x58, 0x77, 0xD9, 0x83, + 0x22, 0x0A, 0x81, 0x88, 0x2E, 0xDE, 0xEB, 0xBE, + 0x46, 0x7E, 0xD2, 0x1D, 0x37, 0xC1, 0x98, 0x4A, + 0x40, 0x87, 0x76, 0x4F, 0x14, 0x55, 0x10, 0x70, + 0x91, 0xA3, 0xFA, 0xA2, 0x93, 0xF1, 0xDE, 0x05, + 0x7E, 0xBF, 0x0B, 0xDC, 0x66, 0x04, 0x7F, 0xB5, + 0xA3, 0x4E, 0x19, 0xB7, 0x2D, 0xAB, 0x8A, 0x2E, + 0x7E, 0x5C, 0xC3, 0x80, 0x11, 0x66, 0x0D, 0x96, + 0xCE, 0xD8, 0xFA, 0x48, 0x32, 0xDF, 0x78, 0x1C, + 0x6B, 0xD3, 0xFA, 0x1C, 0xA5, 0xCA, 0x99, 0xF4, + 0xB8, 0x3F, 0xB3, 0x84, 0xB6, 0xD9, 0x5F, 0xBF, + 0x2E, 0x62, 0x1B, 0xBD, 0x03, 0x12, 0x7B, 0x68, + 0x8E, 0x48, 0x72, 0xB5, 0x8A, 0xB9, 0x92, 0xA2, + 0x1E, 0x3A, 0x60, 0x31, 0x47, 0x89, 0x3F, 0xF5, + 0x4B, 0xEE, 0x3B, 0xEF, 0xA3, 0xC4, 0x9C, 0xB5, + 0x69, 0xCD, 0x17, 0xD8, 0x6C, 0x53, 0x7D, 0x9F, + 0xA5, 0x59, 0x1E, 0x60, 0x84, 0x53, 0x2D, 0x94, + 0x7B, 0x6A, 0xAE, 0x49, 0x6F, 0x39, 0x5E, 0x78, + 0x60, 0x73, 0x73, 0xF7, 0xF7, 0xC1, 0xBE, 0x98, + 0xE3, 0x1B, 0xAB, 0xB0, 0xB1, 0xF4, 0x10, 0x0A, + 0x65, 0x76, 0x83, 0x6E, 0x50, 0xE9, 0x45, 0x26, + 0x8A, 0x09, 0x2B, 0xDA, 0xF5, 0xB2, 0x17, 0xDE, + 0xD9, 0x46, 0xB8, 0xE2, 0x8B, 0x3D, 0x19, 0xD8, + 0x1D, 0xA6, 0x9C, 0xF3, 0x56, 0x71, 0xC1, 0xD1, + 0x1A, 0x91, 0xC0, 0x6D, 0xE4, 0x94, 0x55, 0x62, + 0x89, 0x87, 0xEA, 0xD0, 0xDA, 0x56, 0x83, 0x3E, + 0x6B, 0xBC, 0x14, 0x46, 0xD5, 0xE5, 0x7F, 0x11, + 0xBC, 0x38, 0x52, 0xB9, 0x37, 0x5B, 0xE8, 0xAD, + 0x8F, 0xC2, 0x03, 0x7B, 0xB2, 0x3B, 0x5A, 0xA7, + 0x01, 0xE0, 0x8B, 0x8D, 0xD2, 0xA0, 0x8E, 0xD6, + 0xC8, 0x79, 0xA1, 0xF8, 0x6C, 0x5B, 0xE9, 0x38, + 0xD8, 0x20, 0x3B, 0x96, 0xBB, 0x5C, 0x17, 0xE4, + 0xE3, 0x81, 0x15, 0x4A, 0xC5, 0x79, 0xFA, 0xAA, + 0xD5, 0x68, 0x52, 0x11, 0x17, 0xBA, 0xE9, 0xDB, + 0x4C, 0xE0, 0x28, 0x63, 0xD0, 0x22, 0x4F, 0x70, + 0xE6, 0x28, 0xDD, 0xD2, 0x06, 0x76, 0x0B, 0x57, + 0xC8, 0xB1, 0x0B, 0x7E, 0x16, 0x41, 0xB2, 0xDC, + 0xD6, 0xA3, 0xC0, 0xD3, 0x83, 0x0B, 0x53, 0x95, + 0x7D, 0x30, 0x5B, 0x4B, 0xC8, 0xB7, 0x2D, 0xC5, + 0xB2, 0xE8, 0x0D, 0x38, 0x2B, 0x13, 0x96, 0x78, + 0xA0, 0xC2, 0x55, 0xA3, 0xF1, 0x92, 0xF1, 0xA3, + 0x98, 0x33, 0xAB, 0x52, 0x5D, 0xE1, 0xFF, 0x2B, + 0x49, 0x64, 0x2C, 0x26, 0xDE, 0x2C, 0x7E, 0xB5, + 0x30, 0x99, 0xEC, 0xD5, 0x23, 0x75, 0x64, 0x72, + 0xA5, 0xA0, 0x53, 0xDB, 0xC2, 0x5D, 0x62, 0x27, + 0xD3, 0x42, 0x1B, 0x8D, 0x09, 0x78, 0xB9, 0x44, + 0x6E, 0xBF, 0x2C, 0xD6, 0x95, 0x43, 0x80, 0x79, + 0xBF, 0x53, 0x8F, 0xA2, 0x62, 0xA0, 0x26, 0x73, + 0x18, 0xE1, 0x1B, 0x5C, 0x24, 0xA8, 0x25, 0x37, + 0x09, 0x2C, 0xB8, 0x85, 0xEF, 0x0C, 0x4A, 0xDD, + 0xEF, 0x26, 0x27, 0x30, 0xAD, 0xC7, 0xA0, 0x62, + 0x2B, 0x00, 0xEB, 0xF9, 0x78, 0x22, 0xB0, 0x86, + 0xCB, 0x70, 0x4B, 0xBA, 0x96, 0xB6, 0xCC, 0x32, + 0x7E, 0x2D, 0xA2, 0x7E, 0x2A, 0x71, 0xD8, 0xE1, + 0xAE, 0xC3, 0x50, 0x7E, 0x6A, 0xD2, 0xAD, 0xC4, + 0x26, 0x45, 0xE0, 0xE9, 0x4D, 0xEC, 0x20, 0x13, + 0xC0, 0xC6, 0x02, 0xF4, 0x87, 0x5B, 0x95, 0xF6, + 0xFC, 0x80, 0x04, 0x6B, 0xEE, 0x68, 0xE5, 0x1A, + 0x3F, 0xDF, 0x98, 0x9C, 0x73, 0x71, 0xAD, 0x30, + 0x49, 0xD3, 0xC8, 0x7C, 0xBD, 0x5D, 0x32, 0x02, + 0x77, 0x5C, 0x54, 0xF5, 0xA5, 0xB9, 0x2F, 0xAC, + 0x89, 0x2E, 0x44, 0x40, 0x79, 0x71, 0xD8, 0xAF, + 0x45, 0xBE, 0x4A, 0x08, 0x9E, 0x32, 0x58, 0x4F, + 0xAD, 0xE6, 0xF0, 0x8A, 0x0B, 0xEB, 0xFE, 0xFC, + 0xD5, 0xF4, 0x6E, 0x9E, 0x55, 0xF7, 0xB1, 0x78, + 0xF2, 0x6E, 0xEA, 0xFF, 0xC9, 0x9B, 0xEB, 0x9C, + 0x08, 0xDE, 0xB3, 0xAD, 0xC2, 0x0B, 0x96, 0xEB, + 0x1D, 0x60, 0xC9, 0xBE, 0x92, 0x71, 0xBB, 0xB2, + 0xCB, 0x1C, 0x86, 0x78, 0xE8, 0x58, 0xA0, 0x40, + 0xEF, 0x52, 0xFF, 0x14, 0x2D, 0xFF, 0x72, 0x4C, + 0x4C, 0xB3, 0xF3, 0xE9, 0x75, 0xA1, 0xBE, 0x52, + 0x26, 0x79, 0x38, 0x4B, 0x8B, 0x36, 0x57, 0xA7, + 0x39, 0x27, 0x01, 0x8A, 0x81, 0x59, 0x4A, 0xE9, + 0x86, 0x90, 0xE8, 0x08, 0x32, 0x48, 0xCA, 0x54, + 0xC8, 0xD0, 0x72, 0x56, 0x88, 0xAE, 0xC1, 0x31, + 0xCB, 0xC3, 0x37, 0xE0, 0xEA, 0x79, 0x9E, 0x75, + 0x4F, 0xA8, 0xCC, 0x33, 0xC3, 0x50, 0x24, 0x86, + 0x57, 0x79, 0x4B, 0x27, 0xB9, 0x06, 0x13, 0xCE, + 0xFF, 0x67, 0x84, 0x1C, 0x93, 0xDF, 0xF9, 0x0B, + 0xAB, 0x4C, 0x98, 0xDB, 0xE3, 0x6E, 0x06, 0xF6, + 0x88, 0xF7, 0xB0, 0x3E, 0x07, 0xBC, 0xFC, 0xB7, + 0xC3, 0x04, 0x58, 0xD8, 0x57, 0x34, 0x11, 0xFC, + 0xBE, 0x28, 0x45, 0x24, 0xF1, 0x3B, 0x2C, 0x71, + 0x96, 0x56, 0x7C, 0xD1, 0xE8, 0x97, 0x8C, 0x8C, + 0x81, 0x6E, 0xBD, 0x19, 0x62, 0xB1, 0x24, 0xE6, + 0xA7, 0x14, 0x47, 0x3B, 0x93, 0x49, 0x22, 0x51, + 0x6F, 0x97, 0xD6, 0x29, 0x78, 0xE3, 0xE1, 0x8B, + 0xEA, 0x46, 0xF5, 0xEC, 0xF6, 0x81, 0x56, 0xF3, + 0xCD, 0x4C, 0x6E, 0x15, 0x37, 0xFB, 0x11, 0x86, + 0x8F, 0x37, 0x6B, 0x78, 0x3E, 0x8B, 0x51, 0x45, + 0xE0, 0xC7, 0xC0, 0x03, 0x87, 0x8B, 0x7E, 0x71, + 0xD8, 0x34, 0xC1, 0x5D, 0xB3, 0x62, 0x12, 0x70, + 0xA8, 0x58, 0xE3, 0x5E, 0x78, 0xD5, 0xE4, 0x78, + 0xC0, 0xAE, 0xC2, 0xF7, 0xED, 0xBF, 0x71, 0xF6, + 0x26, 0x91, 0x60, 0x15, 0x6C, 0xF4, 0x68, 0x78, + 0x56, 0x4E, 0x87, 0x50, 0x2C, 0x20, 0x7F, 0x91, + 0xCF, 0x76, 0x90, 0xD6, 0x13, 0xB1, 0x77, 0x8D, + 0xBB, 0x15, 0xF7, 0xB7, 0x94, 0x19, 0x88, 0x5C, + 0xC7, 0x6B, 0xB3, 0x20, 0x00, 0xCF, 0x1D, 0x10, + 0xFC, 0xE8, 0xF1, 0x37, 0x19, 0x42, 0xC3, 0xFD, + 0xA0, 0x5E, 0x0E, 0x6D, 0xD5, 0x18, 0x66, 0xD3, + 0xBC, 0xF1, 0x75, 0xEF, 0xD6, 0xF4, 0x9B, 0xE2, + 0x1D, 0x0A, 0x6B, 0x4B, 0x00, 0xFB, 0xA7, 0x73, + 0xD6, 0x68, 0xC3, 0x83, 0xF7, 0xA7, 0xCE, 0xD1, + 0xD8, 0xDC, 0x82, 0xF1, 0xC7, 0x7A, 0xB1, 0xA4, + 0x20, 0xA1, 0x59, 0x70, 0xE4, 0x6E, 0x91, 0x4E, + 0xD7, 0xA7, 0x93, 0x0B, 0x09, 0x86, 0x54, 0xE1, + 0x1A, 0x4A, 0xC3, 0xE2, 0xDD, 0xA2, 0x62, 0x64, + 0x00, 0xDC, 0x14, 0xFF, 0x03, 0x37, 0x82, 0x44, + 0x6B, 0xCF, 0x1F, 0xC1, 0xAD, 0x3E, 0x3F, 0x05, + 0xAA, 0x15, 0x60, 0xA4, 0x9D, 0x95, 0x37, 0xC8, + 0x2D, 0x12, 0x6B, 0x20, 0xEA, 0xD7, 0xF2, 0xAF, + 0x3A, 0x23, 0x3E, 0x1C, 0x9D, 0x05, 0x5B, 0xD3, + 0x86, 0x74, 0x91, 0xBB, 0xE5, 0x93, 0x04, 0xEA, + 0x96, 0xF9, 0xB7, 0x5B, 0xD8, 0xBB, 0x8E, 0x29, + 0x8B, 0xCE, 0x56, 0x88, 0x3C, 0xF1, 0xE5, 0x5D, + 0x05, 0xB0, 0x16, 0xBB, 0xB6, 0xD0, 0xA8, 0x30, + 0xE0, 0x6C, 0xCC, 0x12, 0x95, 0xEF, 0x02, 0x75, + 0xA9, 0xC4, 0x4A, 0x69, 0xBB, 0xB7, 0xE4, 0xA0, + 0x54, 0xDF, 0x21, 0x7B, 0xC7, 0xA5, 0x3C, 0xBB, + 0xC4, 0x7C, 0x64, 0x47, 0xB1, 0x0C, 0x9F, 0x99, + 0xEE, 0x61, 0x56, 0x11, 0xEC, 0x13, 0xF7, 0xF8, + 0x29, 0x01, 0x07, 0x5A, 0x71, 0x7B, 0x0D, 0x8D, + 0xF3, 0xF4, 0x07, 0x40, 0xA3, 0xB6, 0x33, 0xED, + 0x56, 0x28, 0x10, 0xF2, 0xC7, 0x43, 0x7E, 0x36, + 0xC9, 0x7C, 0x5A, 0xEC, 0x1B, 0x9D, 0xB2, 0x44, + 0x72, 0xB8, 0x42, 0x92, 0x95, 0x93, 0xAF, 0xE7, + 0xA3, 0xEA, 0x31, 0x19, 0x31, 0x6F, 0xC7, 0x4F, + 0xA4, 0x5D, 0xB9, 0x9C, 0x54, 0x86, 0x43, 0x16, + 0x3B, 0xF1, 0x6D, 0x8A, 0x84, 0xEC, 0x4E, 0x98, + 0xC6, 0xBC, 0x86, 0x4A, 0x82, 0x61, 0x61, 0x0D, + 0x73, 0xDF, 0xAF, 0x2D, 0x23, 0x89, 0x5D, 0x14, + 0x7F, 0xE6, 0x7B, 0x8D, 0x3A, 0xFE, 0xD6, 0xF0, + 0xDA, 0x87, 0x1A, 0x0C, 0x3E, 0xCA, 0xCA, 0x84, + 0xE0, 0x72, 0x2D, 0x50, 0x19, 0x4D, 0xCC, 0x5F, + 0x3B, 0x63, 0x78, 0xF8, 0x51, 0x30, 0x3F, 0x80, + 0x60, 0x8B, 0xE4, 0xE2, 0xC0, 0xE6, 0xF3, 0x42, + 0xFA, 0xB0, 0xA7, 0x07, 0x57, 0x8E, 0xC8, 0x5D, + 0x1D, 0xFD, 0x39, 0x30, 0xA7, 0x2C, 0xCB, 0xEC, + 0xEB, 0x6A, 0x16, 0xCF, 0x82, 0x36, 0xFB, 0x1E, + 0xEE, 0x76, 0xED, 0xD6, 0xDC, 0x85, 0xBF, 0x71, + 0xC5, 0x26, 0x79, 0x19, 0x46, 0xB9, 0x92, 0x99, + 0xDB, 0x95, 0x5B, 0x78, 0xCF, 0xA7, 0x74, 0xD5, + 0x17, 0x97, 0x54, 0xE5, 0xAE, 0xE4, 0x23, 0xC1, + 0x21, 0xF8, 0xAC, 0x12, 0xFB, 0x1D, 0x6E, 0xF9, + 0xC7, 0x94, 0x0A, 0x7A, 0x60, 0x1B, 0xA0, 0x49, + 0xB4, 0xD2, 0x3B, 0xC9, 0x10, 0x4E, 0x58, 0x37, + 0x56, 0xAE, 0x8D, 0xDD, 0xBF, 0xB5, 0xCF, 0xC0, + 0x10, 0xC3, 0x73, 0x1D, 0x58, 0x97, 0x78, 0x58, + 0xFF, 0x87, 0xC5, 0xF3, 0x31, 0xFE, 0x39, 0xCC, + 0x70, 0x33, 0xA5, 0xF2, 0x20, 0xDF, 0x8A, 0x04, + 0xE0, 0xBE, 0x5D, 0x94, 0x9D, 0x21, 0x62, 0x7F, + 0x47, 0xAC, 0x6F, 0xE8, 0x5E, 0x31, 0xBC, 0x11, + 0xA6, 0x2E, 0xA2, 0x5D, 0xA1, 0xD4, 0x48, 0x58, + 0x7C, 0x1B, 0xA0, 0x80, 0x76, 0x19, 0x5A, 0xDA, + 0xB4, 0x81, 0x6D, 0x42, 0xB4, 0xD0, 0xDF, 0xB5, + 0x41, 0x73, 0x2E, 0x3A, 0x4F, 0x26, 0xCA, 0x90, + 0xB8, 0xC7, 0x22, 0x2D, 0x1F, 0x95, 0x52, 0x09, + 0x19, 0x23, 0x7F, 0x82, 0x5B, 0x9C, 0xC2, 0xE3, + 0xA7, 0xC7, 0x20, 0x03, 0x7D, 0x0D, 0x6E, 0x1C, + 0xA5, 0xDC, 0xF8, 0xED, 0xE7, 0x45, 0x72, 0x71, + 0x1B, 0x69, 0xFB, 0x07, 0x49, 0x5C, 0x54, 0xE2, + 0xF6, 0x59, 0xA8, 0xCD, 0x1D, 0xE9, 0x65, 0x17, + 0x49, 0x12, 0x14, 0xBF, 0x36, 0x58, 0x0C, 0x7B, + 0xE7, 0xF3, 0xFB, 0x8F, 0x9E, 0x2D, 0xE9, 0x17, + 0x5A, 0x25, 0xE5, 0x5F, 0x66, 0xA0, 0x1B, 0xC4, + 0x70, 0x0F, 0x8A, 0x33, 0xE2, 0x9C, 0x68, 0xB6, + 0x52, 0xCD, 0x0C, 0xB4, 0x45, 0x50, 0x73, 0x97, + 0x51, 0x04, 0xF4, 0xE2, 0x92, 0x83, 0x5F, 0xED, + 0xE6, 0xD0, 0x98, 0x58, 0x90, 0xC4, 0xDA, 0x71, + 0xF6, 0xF2, 0xDE, 0x0D, 0xA9, 0x50, 0x70, 0x20, + 0x03, 0x6A, 0x96, 0x07, 0x0D, 0xEC, 0x16, 0x51, + 0x77, 0xEE, 0x90, 0xBD, 0xFB, 0xFF, 0xA8, 0x0D, + 0xDF, 0xDE, 0xD5, 0x08, 0xF8, 0x4D, 0x37, 0x77, + 0x61, 0xB4, 0x74, 0x08, 0x45, 0x75, 0xF6, 0xF7, + 0x42, 0x01, 0xCE, 0xB6, 0x5D, 0xE9, 0xAA, 0xBB, + 0x68, 0x7D, 0xDB, 0x6C, 0xC9, 0xE9, 0xD0, 0xB6, + 0xA2, 0x2A, 0x4D, 0xA7, 0x87, 0x7E, 0xE7, 0xA3, + 0x8E, 0x43, 0xFD, 0x07, 0x3A, 0x64, 0x9C, 0xAB, + 0xFE, 0x7E, 0x93, 0xB6, 0x0C, 0xE3, 0x93, 0x3F, + 0xED, 0x92, 0x38, 0x94, 0xBE, 0xE9, 0x8D, 0x76, + 0xA4, 0xA4, 0x49, 0x0D, 0xEE, 0xF3, 0xE9, 0xD0, + 0xED, 0x6F, 0x1F, 0xCC, 0x16, 0x75, 0xC8, 0x95, + 0xF8, 0x21, 0xA1, 0x76, 0xA9, 0x22, 0x03, 0x90, + 0x23, 0x3C, 0x50, 0x49, 0x79, 0x6E, 0xD0, 0xC0, + 0x54, 0x7B, 0x0E, 0x93, 0x30, 0xEE, 0x7C, 0x68, + 0x2D, 0x53, 0x9B, 0x4D, 0x4B, 0xCF, 0x0C, 0x11, + 0x4C, 0xF3, 0x70, 0x58, 0x08, 0x8C, 0xDA, 0x7B, + 0x63, 0x1D, 0x29, 0xB3, 0xBF, 0x6E, 0x42, 0x1D, + 0x95, 0x9E, 0x7D, 0xD1, 0x11, 0x5B, 0x7D, 0xDE, + 0xFC, 0x06, 0x85, 0x81, 0x30, 0x76, 0x67, 0x6A, + 0x14, 0x4F, 0xD1, 0x5E, 0x97, 0x52, 0x2D, 0x8D, + 0x82, 0x37, 0x71, 0x1D, 0x2B, 0x05, 0x90, 0x9B, + 0xC8, 0x66, 0xAE, 0xAB, 0x6E, 0xAC, 0x25, 0x68, + 0x6A, 0x12, 0x1F, 0x57, 0x7F, 0xB2, 0x72, 0x9E, + 0x8B, 0x13, 0x95, 0x1E, 0x70, 0x5A, 0xEE, 0x77, + 0x51, 0x73, 0xC8, 0x89, 0xEA, 0xCB, 0x35, 0x3B, + 0x9C, 0xA5, 0x9D, 0xEC, 0x9F, 0x63, 0xC4, 0x86, + 0x48, 0x93, 0xD2, 0x9C, 0x3E, 0x4F, 0x10, 0x93, + 0xFA, 0xA2, 0x89, 0x35, 0x30, 0x40, 0x07, 0x33, + 0x7E, 0x7E, 0x7A, 0x31, 0x63, 0x41, 0x01, 0xFC, + 0x50, 0xFD, 0xBE, 0xE5, 0xD3, 0x4F, 0xC1, 0xB0, + 0xD6, 0xAF, 0x87, 0x18, 0xBF, 0x30, 0x31, 0x0F, + 0x74, 0xCD, 0x6C, 0xFF, 0x0A, 0xA9, 0x72, 0x3B, + 0x63, 0xC9, 0xFB, 0x95, 0x09, 0xD5, 0xE5, 0x9E, + 0x6E, 0x62, 0x8F, 0x50, 0x65, 0xEF, 0xC5, 0x4E, + 0x66, 0x8A, 0x77, 0xBC, 0x21, 0x7C, 0x96, 0x11, + 0xE9, 0xD8, 0xB5, 0x79, 0x7E, 0x6A, 0xB8, 0x10, + 0x65, 0xAB, 0xA9, 0x7E, 0x46, 0xA6, 0x46, 0xA5, + 0x26, 0x83, 0xDA, 0x4D, 0x38, 0xB4, 0x2D, 0xA6, + 0xDB, 0xBF, 0x29, 0x7D, 0xAB, 0x46, 0x97, 0xFE, + 0xEE, 0xF0, 0x93, 0xB8, 0x96, 0xFB, 0xD8, 0x91, + 0xF9, 0xAE, 0x99, 0x7B, 0x90, 0x07, 0x5D, 0xA5, + 0x3B, 0xBF, 0x8A, 0x24, 0x26, 0x93, 0xE3, 0x60, + 0xA5, 0xEB, 0x13, 0xF8, 0xFB, 0x24, 0x42, 0xDA, + 0x78, 0xEC, 0xB9, 0xF3, 0xCC, 0x7D, 0x08, 0xBF, + 0x9A, 0x6E, 0xD4, 0xD6, 0xB7, 0xA0, 0xF5, 0xA3, + 0xDB, 0xA9, 0x5E, 0xF5, 0x7F, 0xD4, 0xAA, 0xA7, + 0xB7, 0xE9, 0xF0, 0xF7, 0x7E, 0xC0, 0x43, 0x3F, + 0xFE, 0xBA, 0x3A, 0xED, 0x9C, 0xB4, 0x01, 0x6C, + 0x28, 0x6B, 0xD6, 0xEE, 0xCE, 0x14, 0xE7, 0x9B, + 0xAD, 0xB2, 0xC1, 0x71, 0xA3, 0x5E, 0x73, 0x23, + 0x18, 0xF0, 0x54, 0x2A, 0x88, 0xAC, 0xFA, 0x44, + 0x29, 0x7A, 0x71, 0xE3, 0x07, 0xD5, 0xF5, 0x07, + 0xD8, 0x31, 0xB6, 0x84, 0xF7, 0x3C, 0x6B, 0xF7, + 0xAE, 0x63, 0x0E, 0x61, 0x03, 0xFA, 0x76, 0xFD, + 0x01, 0x42, 0x32, 0x1B, 0xEF, 0x98, 0xE9, 0xF8, + 0xE6, 0x15, 0xAC, 0x46, 0xE3, 0xDE, 0xBE, 0x3F, + 0x55, 0x46, 0x2E, 0xD6, 0x4B, 0xD9, 0x70, 0x75, + 0xF4, 0x06, 0xA2, 0x8B, 0xA2, 0xC3, 0xE4, 0xEF, + 0x5F, 0x51, 0x6D, 0x6A, 0x7D, 0x23, 0x01, 0x8B, + 0x2E, 0x20, 0xE5, 0xAD, 0x9E, 0x43, 0x20, 0x53, + 0x62, 0x62, 0xF4, 0x77, 0xBA, 0xEA, 0x81, 0x13, + 0xF5, 0xB4, 0x0C, 0x3F, 0x7F, 0xC3, 0x07, 0xDC, + 0xBD, 0xAC, 0xB7, 0x80, 0x30, 0x4E, 0xB2, 0xF7, + 0xB3, 0x32, 0x09, 0x87, 0xFE, 0xCB, 0xA8, 0x45, + 0x1F, 0x3C, 0x54, 0x15, 0x0E, 0x87, 0xBC, 0xFB, + 0x33, 0x33, 0x5D, 0x51, 0xEB, 0x4F, 0xF6, 0xB9, + 0xE3, 0x30, 0x3B, 0x80, 0xA6, 0xA2, 0xD5, 0xAC, + 0x82, 0x29, 0x28, 0x2D, 0x74, 0x69, 0x9D, 0x0A, + 0x30, 0x5D, 0x21, 0xC5, 0xFD, 0x8D, 0xD1, 0xED, + 0xD6, 0x63, 0xEC, 0x51, 0x06, 0x31, 0xBF, 0xEA, + 0x1F, 0xD6, 0x44, 0x41, 0xED, 0x06, 0xD0, 0xFF, + 0xB5, 0x77, 0x96, 0x60, 0x7D, 0x2F, 0x35, 0xC9, + 0xB1, 0x63, 0xA9, 0xD9, 0x88, 0x03, 0x46, 0x29, + 0x0B, 0x0C, 0x33, 0xDA, 0x78, 0xB9, 0xF1, 0x97, + 0x33, 0x01, 0xD8, 0x4F, 0xD0, 0x6B, 0x3F, 0xCD, + 0x3D, 0x43, 0x36, 0xA7, 0xD2, 0x2D, 0x18, 0x84, + 0xD9, 0x54, 0x3D, 0x4E, 0x0D, 0x38, 0x8B, 0xE4, + 0xA3, 0xEB, 0x6B, 0x12, 0xAE, 0x41, 0x3A, 0x9B, + 0xB4, 0x04, 0x38, 0xEA, 0x1F, 0x06, 0x04, 0xB6, + 0x05, 0x33, 0xDD, 0x6D, 0xDC, 0xBE, 0xA6, 0xD2, + 0x7A, 0xB5, 0x41, 0xB0, 0x46, 0x01, 0x05, 0x55, + 0xAD, 0x58, 0xD8, 0x49, 0x53, 0x2A, 0x5F, 0x79, + 0x90, 0xB5, 0xBC, 0x75, 0x2B, 0x1F, 0x15, 0x19, + 0x84, 0x81, 0x2D, 0x07, 0xBD, 0x92, 0x2D, 0x35, + 0x93, 0xE9, 0xF6, 0x55, 0x68, 0xA3, 0xBB, 0xAE, + 0x99, 0x2D, 0x23, 0x2E, 0x84, 0xFA, 0x86, 0x92, + 0x66, 0x5F, 0x79, 0x97, 0xB6, 0xA0, 0x2F, 0xCD, + 0x36, 0x61, 0x38, 0xF8, 0x4B, 0xF5, 0x8F, 0x34, + 0xB5, 0xB2, 0x64, 0xE2, 0x0B, 0xD0, 0xA0, 0x7C, + 0xE3, 0xAB, 0x45, 0x3F, 0xB2, 0xD0, 0x10, 0xE3, + 0xC7, 0x8A, 0x67, 0x78, 0x23, 0x21, 0x85, 0xE5, + 0xBB, 0x86, 0xC0, 0xD9, 0xF3, 0x54, 0xF9, 0x28, + 0x7E, 0x26, 0x9F, 0x4D, 0x67, 0x67, 0x14, 0x72, + 0xF3, 0xD5, 0xCF, 0x39, 0xDB, 0x3D, 0xDE, 0x1D, + 0xF1, 0xBC, 0xE6, 0x2B, 0x0A, 0xEC, 0x96, 0xC0, + 0x47, 0xAD, 0x42, 0x9A, 0x83, 0x8E, 0x56, 0x22, + 0x6A, 0x2C, 0x8E, 0xA8, 0xA4, 0x95, 0x01, 0x60, + 0xA4, 0x00, 0x00, 0xE9, 0x01, 0x5F, 0x37, 0x29, + 0xF4, 0xC0, 0x93, 0x73, 0x8F, 0xC0, 0xD4, 0xB3, + 0x9A, 0xC1, 0xFB, 0x11, 0x1D, 0xF9, 0x18, 0xDE, + 0xEA, 0xC6, 0x39, 0xB7, 0x2A, 0xBA, 0xAA, 0xF7, + 0x66, 0x87, 0x5C, 0x1E, 0xAB, 0x02, 0x75, 0xF7, + 0x6E, 0xDA, 0x3E, 0x60, 0x79, 0x8D, 0xE6, 0x1A, + 0xD3, 0x87, 0x59, 0xEF, 0xB3, 0xE4, 0xEC, 0x2E, + 0x41, 0x96, 0xFC, 0x7A, 0x5F, 0xF0, 0x90, 0x5E, + 0x29, 0xEE, 0xA1, 0xD2, 0x72, 0xC0, 0x51, 0x72, + 0x24, 0xB9, 0x9D, 0x3F, 0xE1, 0xE4, 0xD7, 0xBE, + 0x21, 0x33, 0x06, 0xA7, 0x21, 0xFF, 0xE5, 0x63, + 0x39, 0xCD, 0x85, 0x5C, 0xE3, 0xB5, 0xAE, 0xB0, + 0x20, 0xD9, 0x46, 0x5B, 0xA0, 0xA1, 0x45, 0x09, + 0xD5, 0xF9, 0x92, 0x26, 0xEA, 0xB1, 0xCC, 0xAF, + 0x70, 0x68, 0x5B, 0x35, 0x62, 0xB5, 0xC0, 0xB5, + 0x7E, 0x15, 0x61, 0x1A, 0x0D, 0x31, 0xD0, 0xCC, + 0x33, 0x60, 0x00, 0x21, 0xE1, 0xC5, 0xDC, 0xB6, + 0xFA, 0xF9, 0xEB, 0x20, 0x5D, 0x6E, 0xEF, 0x97, + 0x11, 0x0D, 0xEC, 0x2B, 0x4A, 0x49, 0x29, 0x37, + 0xB4, 0xE6, 0x4F, 0x73, 0xC7, 0x14, 0xF4, 0x46, + 0x7F, 0xE7, 0x8A, 0x3E, 0xD0, 0xC2, 0x5F, 0xE2, + 0x5F, 0x1E, 0x09, 0x80, 0xFC, 0xA5, 0x19, 0x34, + 0xDD, 0x0B, 0xFA, 0x30, 0x9A, 0xC8, 0xE7, 0x6C, + 0x66, 0x26, 0x53, 0x0E, 0xC2, 0x8E, 0xE7, 0x1E, + 0x50, 0xDB, 0xED, 0xB8, 0x67, 0x2D, 0x53, 0xEF, + 0x74, 0x1C, 0x9A, 0xFC, 0x7B, 0x0A, 0xFE, 0x1C, + 0x40, 0x3E, 0xBA, 0xD1, 0x0E, 0xE3, 0xB6, 0xA9, + 0x09, 0x1D, 0x10, 0xD5, 0x26, 0x35, 0xBC, 0xC9, + 0x0A, 0x22, 0xA1, 0x1F, 0xC0, 0x5A, 0x59, 0xB7, + 0x77, 0x18, 0x39, 0x31, 0x0A, 0xB6, 0xDC, 0xB6, + 0xAD, 0xB0, 0x37, 0x21, 0xD4, 0x08, 0x14, 0x5A, + 0x4A, 0xD9, 0xE3, 0x4B, 0xF7, 0xAE, 0x28, 0xCE, + 0x38, 0x0B, 0x2F, 0x12, 0x5D, 0xCF, 0xC5, 0xB1, + 0x9B, 0x76, 0xD1, 0x96, 0x7A, 0x56, 0xCE, 0x90, + 0x8C, 0x21, 0x09, 0x00, 0x41, 0x7A, 0xCF, 0x43, + 0xF8, 0x7A, 0xF2, 0xFF, 0xDB, 0xE7, 0x23, 0xFD, + 0xDD, 0x03, 0xA2, 0x72, 0x9E, 0x4A, 0x83, 0x94, + 0x73, 0x0C, 0x2D, 0xB5, 0x2B, 0xF8, 0xF9, 0x13, + 0x9E, 0x9B, 0x82, 0x44, 0xB3, 0xF7, 0x56, 0xF6, + 0xF2, 0x8A, 0xDC, 0x5B, 0xF1, 0x6B, 0xA1, 0xF6, + 0x5D, 0x75, 0x29, 0x59, 0xD8, 0xB9, 0x29, 0x0B, + 0x4F, 0x45, 0x17, 0x31, 0x5F, 0x4F, 0x2E, 0x23, + 0x95, 0xBD, 0x36, 0x27, 0x29, 0x71, 0x9D, 0xE4, + 0x02, 0x96, 0x30, 0x00, 0xA0, 0xBE, 0x82, 0x80, + 0x76, 0x77, 0x8B, 0x6F, 0x4B, 0x88, 0x94, 0x98, + 0x5B, 0x5A, 0x29, 0xF1, 0xBF, 0x49, 0xEC, 0xD7, + 0xCE, 0xD8, 0x02, 0x20, 0x1A, 0x55, 0x54, 0x7B, + 0x8C, 0x6B, 0xB6, 0x6A, 0xEA, 0xCE, 0x1B, 0xA6, + 0x74, 0x52, 0xB4, 0x55, 0x7F, 0xB1, 0x3D, 0x10, + 0xCA, 0xE6, 0xF8, 0x28, 0x21, 0x99, 0x06, 0xFF, + 0x19, 0xF8, 0x0A, 0xB8, 0xF3, 0x14, 0x99, 0xDC, + 0xE5, 0x52, 0xA5, 0x68, 0xCA, 0x3B, 0x4D, 0xED, + 0x50, 0x09, 0x73, 0xE5, 0xAB, 0x51, 0x9E, 0x44, + 0x55, 0x80, 0x10, 0x59, 0x3A, 0x08, 0x63, 0x14, + 0x7E, 0xD2, 0x83, 0x4D, 0x6A, 0xB3, 0x8A, 0x1C, + 0xDF, 0x69, 0x95, 0x93, 0xB7, 0x5B, 0x4C, 0xF0, + 0x5E, 0xA2, 0xD6, 0xAE, 0x77, 0xA4, 0x75, 0x91, + 0x0F, 0x6B, 0x94, 0x81, 0x5A, 0x87, 0x1D, 0x24, + 0xD1, 0x6E, 0xC5, 0xB3, 0x82, 0x4D, 0x3A, 0x0F, + 0x71, 0x93, 0xF5, 0x32, 0xE2, 0x87, 0x3C, 0xDD, + 0xF5, 0x84, 0x80, 0x1C, 0x2D, 0x8D, 0x4D, 0xEE, + 0x4E, 0x25, 0x33, 0x51, 0x6C, 0x9E, 0xE4, 0x5C, + 0x54, 0x7B, 0xB6, 0xA3, 0x40, 0xE9, 0xA7, 0x56, + 0xC1, 0x9C, 0xBC, 0x96, 0x9C, 0xD4, 0x02, 0x80, + 0xC4, 0x01, 0x35, 0x6E, 0x7C, 0xCB, 0x84, 0xC2, + 0x73, 0x57, 0x45, 0xC2, 0x67, 0xA3, 0x57, 0xDB, + 0x03, 0x49, 0xB1, 0x21, 0x5B, 0xDA, 0x7D, 0x51, + 0xBE, 0x30, 0xF0, 0xB6, 0x3A, 0x72, 0x0C, 0x32, + 0x8A, 0xC2, 0x47, 0xEF, 0x00, 0x98, 0xC5, 0xAA, + 0xFE, 0x6C, 0x9A, 0xF6, 0xE4, 0xD9, 0x7B, 0x7F, + 0xA0, 0x38, 0x36, 0xF1, 0x44, 0x37, 0xE1, 0xEC, + 0x5E, 0xD3, 0x49, 0xC2, 0xB3, 0x3F, 0xAF, 0xD6, + 0xAD, 0xB1, 0x6A, 0x44, 0xF8, 0x0C, 0x07, 0x20, + 0xA1, 0x5B, 0x50, 0x9D, 0x05, 0x37, 0xEC, 0x06, + 0x2E, 0x34, 0xE5, 0x8F, 0x1A, 0x24, 0xC8, 0x5C, + 0x99, 0x94, 0xD1, 0xE4, 0xE5, 0x88, 0x70, 0x74, + 0x6B, 0x5F, 0xB1, 0xAB, 0x50, 0x73, 0xED, 0x4B, + 0x34, 0x10, 0xCB, 0x87, 0x36, 0x57, 0x4E, 0xFD, + 0x24, 0x5F, 0xB4, 0xA8, 0x64, 0x77, 0x7C, 0x88, + 0x81, 0x51, 0x95, 0xA5, 0x88, 0xC8, 0x25, 0x09, + 0x9F, 0x3E, 0xA2, 0x30, 0x3F, 0x9C, 0x1F, 0x8D, + 0xFE, 0x23, 0xD4, 0x4B, 0x0D, 0x77, 0x0A, 0xC4, + 0xFA, 0x60, 0x8C, 0xAE, 0x1D, 0x07, 0x0A, 0x0F, + 0x1F, 0xA4, 0xF9, 0x63, 0x42, 0xF7, 0xAB, 0xD2, + 0xB2, 0x4A, 0xEB, 0xBA, 0xE1, 0xF9, 0x6E, 0x52, + 0x24, 0x2B, 0xCD, 0xC5, 0x04, 0xDD, 0x3F, 0x44, + 0xFD, 0x3F, 0x29, 0xBD, 0xF1, 0x49, 0x7B, 0xBC, + 0xF0, 0x8E, 0xBA, 0x32, 0xD4, 0x3D, 0xD9, 0xA8, + 0x8D, 0xBF, 0x44, 0x8B, 0xD2, 0x0B, 0x55, 0x0F, + 0x6E, 0x9B, 0x66, 0xFA, 0xAC, 0x73, 0xDD, 0xC5, + 0x64, 0xCA, 0x7E, 0xA4, 0xEA, 0x5A, 0x03, 0x1C, + 0x08, 0x76, 0x7A, 0xA0, 0x66, 0x1E, 0xDE, 0x4C, + 0x9B, 0x9A, 0x17, 0xCD, 0xF9, 0xE8, 0xDE, 0x1B, + 0xA5, 0x0D, 0xD6, 0x68, 0xCD, 0xEA, 0x20, 0xEA, + 0xAC, 0x38, 0xE5, 0xA1, 0x20, 0xF9, 0xC9, 0xB9, + 0x78, 0x17, 0xC3, 0xDA, 0xA7, 0xD8, 0x09, 0x46, + 0xF4, 0xD7, 0x76, 0x2D, 0x16, 0x75, 0x7B, 0x46, + 0x9A, 0x24, 0x5C, 0x1A, 0x1A, 0x57, 0xD3, 0x1A, + 0x55, 0xA1, 0x0F, 0xF1, 0x3E, 0xA4, 0x86, 0xD2, + 0x56, 0x1B, 0x4B, 0xAD, 0xB7, 0xF5, 0x0A, 0xA9, + 0x5E, 0x8F, 0x61, 0x2B, 0xF4, 0x43, 0x83, 0x16, + 0x3E, 0x27, 0x2B, 0x65, 0x22, 0xAA, 0xB0, 0x07, + 0xEA, 0xF7, 0x84, 0x80, 0xEF, 0x81, 0xC1, 0x49, + 0xD5, 0xA9, 0xA3, 0xB6, 0xF8, 0x87, 0x5B, 0x24, + 0xF0, 0xC4, 0x80, 0xD1, 0x17, 0x51, 0x1E, 0xE7, + 0xE5, 0x36, 0x89, 0x0D, 0x3F, 0x10, 0x86, 0xC5, + 0x16, 0x1B, 0xAD, 0xD0, 0x67, 0xEA, 0x08, 0xD9, + 0x0C, 0x37, 0x15, 0x4D, 0xA4, 0x22, 0xE6, 0x0A, + 0x29, 0x7A, 0x75, 0xC2, 0xEE, 0x5F, 0x45, 0x2B, + 0x64, 0xDA, 0x08, 0xBC, 0x60, 0x16, 0x9A, 0xDC, + 0xF9, 0x2E, 0x3A, 0xE3, 0x12, 0x8B, 0x90, 0x8D, + 0x42, 0x79, 0x6B, 0x11, 0xB2, 0xA7, 0x12, 0x0D, + 0x20, 0xA4, 0x99, 0x99, 0x02, 0xED, 0x09, 0xB3, + 0x1E, 0x9E, 0xDF, 0xA4, 0x8D, 0xAC, 0xB3, 0xC4, + 0x89, 0xFD, 0xD1, 0x96, 0x21, 0xC5, 0x3D, 0x0F, + 0xB2, 0x14, 0xC0, 0xAD, 0xD8, 0x81, 0xB6, 0xB4, + 0x17, 0x78, 0xB0, 0x34, 0x2A, 0xCD, 0xC3, 0x29, + 0xFA, 0x7B, 0xE4, 0xD9, 0x3C, 0x71, 0xAD, 0x12, + 0x56, 0xB9, 0x6D, 0x70, 0x1A, 0xC8, 0x17, 0x7B, + 0xAE, 0x56, 0x25, 0x87, 0x82, 0xCB, 0xB6, 0x5C, + 0xF9, 0x81, 0x7B, 0x64, 0x6F, 0x43, 0x95, 0x38, + 0x0B, 0xC0, 0x38, 0xDF, 0x5C, 0x1C, 0x98, 0x42, + 0xE5, 0x3A, 0x28, 0x98, 0x59, 0xC9, 0x2A, 0xB8, + 0xCA, 0x9B, 0xAF, 0x3B, 0x24, 0xAE, 0xD1, 0xE1, + 0x50, 0x1A, 0x80, 0x38, 0xD4, 0xF9, 0x18, 0xFD, + 0x19, 0x57, 0x39, 0x00, 0xB5, 0xA7, 0x84, 0xC0, + 0x57, 0xA7, 0xE8, 0xBE, 0x30, 0x8C, 0x33, 0x2D, + 0xCF, 0x06, 0x23, 0x99, 0x2C, 0x24, 0x89, 0x8C, + 0x31, 0x18, 0xB9, 0x31, 0x34, 0x72, 0xE6, 0xA7, + 0xC8, 0x11, 0xEF, 0x3C, 0x1D, 0x66, 0x16, 0xA0, + 0xA3, 0xA2, 0x85, 0xA9, 0x9B, 0x09, 0x62, 0x11, + 0x10, 0x07, 0x8F, 0x2C, 0xFC, 0xA7, 0x24, 0xB8, + 0xF8, 0x93, 0xEE, 0xA6, 0x4F, 0x6D, 0xFA, 0xF6, + 0xA4, 0x17, 0x19, 0x14, 0xC1, 0x8F, 0xF8, 0x5C, + 0x7C, 0x8A, 0x3C, 0xAE, 0xD8, 0x5A, 0xBA, 0xE6, + 0x32, 0x04, 0x78, 0xDC, 0xC3, 0xA1, 0x54, 0xE2, + 0xD1, 0x25, 0x93, 0x0A, 0x8C, 0x85, 0xE9, 0xBB, + 0x1E, 0x73, 0xDF, 0xEB, 0xD2, 0xAC, 0x38, 0xE9, + 0xEB, 0xFF, 0x4A, 0x6F, 0xEF, 0x4E, 0x48, 0x20, + 0x0D, 0x04, 0x7A, 0x13, 0x74, 0x07, 0x3B, 0x85, + 0x2A, 0x36, 0x59, 0x4E, 0x54, 0x28, 0xDC, 0xA2, + 0xF8, 0x7E, 0xB2, 0xC5, 0x8C, 0x11, 0x9C, 0x64, + 0x25, 0xCE, 0x3E, 0xB2, 0xD8, 0x5C, 0x4C, 0xB7, + 0x88, 0x24, 0xEF, 0x02, 0x52, 0x27, 0x39, 0xFB, + 0xA4, 0x7A, 0x24, 0x57, 0xEC, 0x0B, 0xB4, 0x95, + 0x0B, 0x48, 0xD4, 0x13, 0x93, 0xA1, 0x60, 0x13, + 0x2F, 0x18, 0xD3, 0xDF, 0x1B, 0xA7, 0x91, 0x39, + 0x55, 0x33, 0xC7, 0x88, 0x00, 0xFA, 0x97, 0x3C, + 0x45, 0xD3, 0xFD, 0x5C, 0xD6, 0x46, 0x54, 0x4B, + 0xE1, 0x62, 0x7C, 0xFF, 0x67, 0x4E, 0x33, 0xD9, + 0x8B, 0x6C, 0x3C, 0x5D, 0xA2, 0xBA, 0x2A, 0x06, + 0x42, 0xCB, 0x78, 0x62, 0x94, 0xDA, 0xD9, 0x4F, + 0xA8, 0x35, 0xAB, 0x49, 0x54, 0x9F, 0x88, 0x05, + 0x48, 0x5F, 0xEE, 0x13, 0x97, 0xD3, 0xE6, 0x37, + 0x3D, 0x8A, 0x29, 0xC1, 0xE6, 0xF4, 0x0F, 0x09, + 0x23, 0x15, 0x83, 0x63, 0x21, 0x8F, 0xBD, 0x32, + 0xC2, 0x72, 0xF2, 0x7F, 0x75, 0x74, 0x50, 0x47, + 0xF6, 0x98, 0x58, 0x91, 0xE7, 0xE9, 0x90, 0xA5, + 0xD1, 0xF3, 0x17, 0x0A, 0x5E, 0xAA, 0x6A, 0x10, + 0x46, 0x84, 0xB7, 0xD4, 0x8E, 0xDD, 0x54, 0x7E, + 0xAD, 0x4A, 0xEF, 0x45, 0x93, 0x63, 0x5C, 0x8E, + 0xCE, 0xD2, 0xB4, 0xB4, 0x0D, 0x68, 0xB9, 0xE7, + 0x2B, 0x46, 0x32, 0x04, 0xCF, 0x43, 0x0A, 0xE8, + 0x56, 0x7A, 0xA4, 0x39, 0xEE, 0x40, 0xA7, 0x87, + 0x8C, 0xC0, 0x2C, 0xCF, 0x9F, 0x53, 0xA3, 0x0E, + 0x2E, 0x03, 0xB8, 0xAB, 0x5A, 0xC1, 0x45, 0x50, + 0xE8, 0xD9, 0xD8, 0x32, 0x49, 0x4C, 0xFF, 0x83, + 0x8F, 0x99, 0x94, 0x35, 0xB3, 0xFD, 0xEC, 0xCE, + 0x03, 0x11, 0x2C, 0x17, 0x98, 0xC3, 0xD9, 0x2D, + 0x00, 0x59, 0xE0, 0x35, 0x11, 0x3F, 0x13, 0xE3, + 0xF8, 0x66, 0xF4, 0xB6, 0xAC, 0x7B, 0xC1, 0xE1, + 0x53, 0xD6, 0xAC, 0x0C, 0x7E, 0xB4, 0xE6, 0xBB, + 0x13, 0x01, 0xE6, 0x84, 0xCC, 0x9B, 0xC7, 0x6C, + 0x21, 0x0F, 0xD7, 0x63, 0xB8, 0xA6, 0x01, 0x64, + 0xAE, 0x0F, 0x2E, 0x9B, 0x32, 0x68, 0xB2, 0x89, + 0xA5, 0xA8, 0xEB, 0xE9, 0x62, 0x83, 0xBB, 0x61, + 0x32, 0xF6, 0x5F, 0xEA, 0x4E, 0x23, 0x53, 0x3A, + 0xE3, 0x41, 0xF6, 0xFC, 0x65, 0x45, 0x86, 0x86, + 0x59, 0xF0, 0x72, 0x06, 0xD9, 0x68, 0xB6, 0x59, + 0xB6, 0x55, 0x53, 0x4E, 0xA0, 0x5B, 0x27, 0xFB, + 0x58, 0x25, 0x7E, 0x0B, 0x9A, 0x30, 0x92, 0xCA, + 0xE6, 0x74, 0x5E, 0x6B, 0xFA, 0xFF, 0xFE, 0xB8, + 0x22, 0xD8, 0x3C, 0xA1, 0xC9, 0x46, 0xE3, 0x19, + 0x40, 0xC2, 0xBF, 0x89, 0xA2, 0x8D, 0x5D, 0x77, + 0xF5, 0xF3, 0xE9, 0x32, 0x1D, 0xB0, 0x29, 0x2D, + 0x44, 0x1C, 0x8B, 0xAF, 0x4E, 0x52, 0xCC, 0xB6, + 0x86, 0x79, 0xF7, 0x27, 0x82, 0xAA, 0xBE, 0x53, + 0xC1, 0x1E, 0x59, 0xC6, 0x29, 0x96, 0x10, 0xDF, + 0xD4, 0x55, 0x91, 0x19, 0x57, 0x89, 0x89, 0x54, + 0xA1, 0x26, 0x63, 0x82, 0xAA, 0x65, 0xBA, 0xDB, + 0xBD, 0x74, 0xB1, 0xDC, 0x77, 0x73, 0xA7, 0xBF, + 0x21, 0xA1, 0x88, 0x36, 0xB6, 0x23, 0x56, 0x2D, + 0x81, 0x25, 0xAA, 0x82, 0xF1, 0x72, 0xAF, 0x76, + 0x32, 0xAB, 0xA8, 0x7E, 0xB9, 0x2B, 0xB3, 0x32, + 0x23, 0x3E, 0x88, 0xB5, 0x8A, 0x21, 0xDC, 0x21, + 0xDD, 0x01, 0x23, 0xFE, 0x5B, 0xC3, 0x9A, 0x11, + 0xB7, 0x47, 0x8C, 0x93, 0x12, 0x1C, 0x00, 0x3A, + 0x98, 0xF5, 0x7F, 0xD1, 0xB6, 0xBE, 0xC1, 0x16, + 0x4C, 0x2B, 0xBD, 0xFC, 0x87, 0xDD, 0xCC, 0x37, + 0x0B, 0x5E, 0x8D, 0xA3, 0x77, 0x78, 0x52, 0x05, + 0x3B, 0xFE, 0x3C, 0x6E, 0x5C, 0x2E, 0x98, 0x34, + 0x65, 0xCC, 0xF6, 0xCF, 0x8C, 0x82, 0x99, 0x05, + 0xFD, 0xD3, 0x8C, 0x4A, 0xE6, 0xF1, 0x73, 0xE0, + 0xB6, 0x00, 0x79, 0x53, 0xD1, 0xE4, 0xCF, 0xF1, + 0x3C, 0xC3, 0x9F, 0x21, 0x06, 0x18, 0xC8, 0xB8, + 0x95, 0x4F, 0xFE, 0x56, 0x18, 0x78, 0x95, 0x68, + 0x2D, 0x6C, 0xC9, 0x9E, 0xBC, 0xEB, 0xFE, 0x27, + 0x52, 0x27, 0xC7, 0xAE, 0x45, 0xB8, 0x94, 0xFA, + 0x2E, 0xF1, 0xC3, 0x75, 0xC7, 0xA2, 0x92, 0x24, + 0x6B, 0x83, 0xA8, 0xED, 0xC3, 0x56, 0x8C, 0xEB, + 0x4E, 0x2C, 0xED, 0x7C, 0x1F, 0x43, 0xD3, 0x9F, + 0x59, 0xFE, 0xE2, 0x86, 0xB8, 0x42, 0xFE, 0x39, + 0x0F, 0x19, 0xB2, 0x89, 0xA2, 0xF7, 0x86, 0x86, + 0xB4, 0xA4, 0xDB, 0x82, 0x83, 0x68, 0xE5, 0x2A, + 0x9A, 0xFE, 0x27, 0x0C, 0x12, 0xF3, 0x9C, 0x2F, + 0xD3, 0x8A, 0x34, 0x75, 0xE5, 0x6F, 0xCB, 0xFA, + 0x65, 0xBF, 0x60, 0xE9, 0xE5, 0x7C, 0x2C, 0xEC, + 0xD4, 0x29, 0x6C, 0x8E, 0x96, 0x52, 0x9C, 0x7A, + 0xE4, 0x17, 0x4F, 0x13, 0x1C, 0xE7, 0x09, 0x45, + 0xCA, 0x63, 0xCB, 0x2B, 0x04, 0x1A, 0xCB, 0x5C, + 0xF8, 0x3C, 0x83, 0x9C, 0x16, 0x6D, 0xFF, 0x43, + 0xAD, 0xF0, 0xF2, 0x31, 0x66, 0x37, 0x00, 0xFF, + 0x66, 0x40, 0xDE, 0xCD, 0xEF, 0x67, 0xB9, 0x5E, + 0x1E, 0x71, 0xA5, 0x48, 0xB1, 0xFA, 0x22, 0xBC, + 0x55, 0xE9, 0x80, 0x64, 0x8E, 0xA3, 0xE6, 0x7D, + 0x8F, 0xF5, 0xAA, 0x13, 0xFA, 0xC8, 0x80, 0x27, + 0x3E, 0x75, 0x67, 0x0B, 0x9E, 0x79, 0x8D, 0x24, + 0x27, 0xE0, 0xE3, 0x80, 0x5B, 0x00, 0xB9, 0xD1, + 0x3E, 0x95, 0x47, 0x27, 0xE9, 0xD7, 0xBF, 0x2B, + 0x17, 0xC3, 0xE0, 0xD8, 0xD5, 0x54, 0x98, 0xF9, + 0xF3, 0x0E, 0x96, 0x52, 0x45, 0x50, 0xE0, 0x64, + 0x95, 0xC8, 0xB9, 0x84, 0x4E, 0xB0, 0x08, 0x6A, + 0x38, 0x49, 0x92, 0x18, 0xFB, 0xDF, 0x95, 0xD4, + 0xB9, 0xBA, 0x1F, 0x07, 0x72, 0x18, 0x0E, 0x92, + 0xB8, 0xA0, 0x49, 0xBF, 0x93, 0x88, 0x31, 0xFE, + 0xA9, 0xAB, 0xA6, 0x8F, 0x4F, 0xF2, 0xA8, 0x84, + 0xCB, 0xB0, 0x75, 0x72, 0x5B, 0x49, 0x7D, 0x79, + 0x5D, 0x67, 0x58, 0x1F, 0x38, 0xA2, 0x89, 0x99, + 0x2A, 0xF3, 0xD8, 0x63, 0x77, 0x15, 0x30, 0x6D, + 0x11, 0x90, 0xD1, 0x5C, 0x26, 0xCC, 0xAF, 0x3C, + 0x78, 0xD3, 0xC3, 0x4C, 0xA2, 0x74, 0x3F, 0xE0, + 0xE3, 0x55, 0x21, 0xC5, 0x9A, 0x7F, 0xAE, 0x96, + 0xCC, 0x49, 0x27, 0x3C, 0x53, 0xFA, 0x73, 0xAB, + 0x02, 0xA1, 0xAC, 0xD4, 0x13, 0xB3, 0xC8, 0x60, + 0x44, 0xAC, 0x80, 0xB4, 0x11, 0xE1, 0x03, 0xCF, + 0x36, 0xD1, 0x80, 0x3F, 0xB4, 0x74, 0xFF, 0x0E, + 0xFD, 0x77, 0xF1, 0xB1, 0x05, 0x50, 0xF4, 0x3D, + 0x94, 0x0E, 0x1F, 0x09, 0x93, 0xB8, 0xE9, 0xC6, + 0x6B, 0x8F, 0x5E, 0x84, 0xC5, 0x2D, 0x89, 0x49, + 0xDD, 0x0C, 0x57, 0xFB, 0x75, 0x5E, 0x74, 0x60, + 0x1E, 0x54, 0xBF, 0x89, 0xD4, 0x3C, 0x81, 0x29, + 0x3B, 0x06, 0xF8, 0x8F, 0x25, 0xC8, 0xCF, 0xE5, + 0xB5, 0x7C, 0x01, 0x55, 0xFC, 0x7C, 0xE8, 0xDD, + 0xBC, 0x9D, 0x85, 0x49, 0x16, 0xCE, 0xF7, 0xA4, + 0x94, 0xB7, 0x48, 0xA3, 0xC4, 0x10, 0x0A, 0x13, + 0x58, 0xD9, 0xEF, 0x0C, 0x6C, 0x14, 0xD4, 0xA0, + 0x44, 0xB8, 0xF1, 0xA9, 0xB2, 0x6E, 0xDF, 0x91, + 0xDF, 0x2B, 0x32, 0x4E, 0xC3, 0x5A, 0x7A, 0xED, + 0xFF, 0x63, 0x10, 0xDB, 0x8B, 0x4A, 0xC7, 0xD1, + 0xBB, 0x7D, 0x43, 0x06, 0xB1, 0x4C, 0x01, 0x7B, + 0x61, 0x78, 0xEB, 0x4D, 0xD7, 0x6A, 0x5E, 0x71, + 0x6F, 0xB8, 0xA2, 0x6E, 0xC2, 0xBC, 0x65, 0x1D, + 0xD8, 0xDB, 0xDA, 0xCF, 0x60, 0x69, 0x41, 0x4E, + 0x2C, 0x13, 0x9B, 0xF8, 0x58, 0xB1, 0x18, 0x3E, + 0xD2, 0xBD, 0xC2, 0x18, 0xA3, 0xDE, 0xE9, 0x3F, + 0xCD, 0xD8, 0x0C, 0x4E, 0x48, 0xB1, 0x0D, 0xED, + 0x9D, 0x53, 0x68, 0xB9, 0x71, 0x13, 0x51, 0x2A, + 0x53, 0x54, 0x2D, 0x29, 0x4A, 0xA8, 0x86, 0xA1, + 0x83, 0x0B, 0x94, 0x4D, 0x14, 0x50, 0xA6, 0x99, + 0x9F, 0xDD, 0x16, 0x64, 0x15, 0xE7, 0xA0, 0x20, + 0x57, 0x94, 0x53, 0xA0, 0x28, 0x32, 0x6E, 0x13, + 0x92, 0x7A, 0x11, 0x5B, 0x8B, 0xDE, 0x9C, 0xE8, + 0x85, 0x1C, 0x7C, 0x6B, 0xBF, 0x39, 0x95, 0x3D, + 0xC6, 0xAD, 0x3C, 0xCA, 0x63, 0x82, 0x75, 0x11, + 0xBA, 0x71, 0x22, 0x97, 0x08, 0x9C, 0x2E, 0x15, + 0x96, 0x58, 0xCE, 0x14, 0x7C, 0x03, 0x66, 0x78, + 0x7B, 0xC6, 0xE5, 0x54, 0xB9, 0xAA, 0x58, 0xDE, + 0x72, 0xD2, 0x8C, 0x19, 0x7E, 0xED, 0xB6, 0x79, + 0x51, 0x44, 0x9F, 0x8F, 0xB5, 0x5F, 0xBA, 0x3A, + 0x07, 0x71, 0x6A, 0xD2, 0xEA, 0x91, 0xAC, 0xEB, + 0x60, 0x8C, 0xE4, 0xD5, 0x83, 0x47, 0x21, 0x2E, + 0xBB, 0x43, 0x54, 0x93, 0xD6, 0x23, 0x8A, 0xA3, + 0x89, 0x2B, 0xA2, 0xBE, 0xFF, 0x69, 0x9B, 0xD7, + 0x8E, 0x01, 0x54, 0x9C, 0x25, 0x1D, 0x5B, 0x36, + 0x00, 0x60, 0x88, 0xAC, 0x9D, 0xCD, 0x85, 0x2B, + 0x21, 0xA4, 0xF7, 0xDA, 0x7A, 0x02, 0xD1, 0x39, + 0x11, 0xF3, 0x40, 0x3A, 0x1D, 0x9C, 0x85, 0x86, + 0x8A, 0xB0, 0xD4, 0x54, 0x8A, 0xCF, 0xFC, 0x96, + 0x2A, 0xE9, 0x66, 0x2B, 0x33, 0xD4, 0x7D, 0xBC, + 0xEE, 0xCC, 0x40, 0xAE, 0xBA, 0x49, 0x99, 0x82, + 0xF5, 0xF4, 0xD5, 0x52, 0x7B, 0xDF, 0x35, 0x62, + 0xF2, 0x27, 0x04, 0x5F, 0xC6, 0x60, 0xB6, 0x4F, + 0xC2, 0x81, 0x71, 0x78, 0x3D, 0x4E, 0x26, 0x1D, + 0xA4, 0x9B, 0xC1, 0x24, 0x18, 0x61, 0x09, 0x4C, + 0x0C, 0xF2, 0xF0, 0x15, 0x62, 0x4D, 0xEF, 0x9A, + 0x52, 0x02, 0x16, 0x20, 0x09, 0x6B, 0x53, 0xEA, + 0xA5, 0xF1, 0x67, 0x2E, 0x59, 0x77, 0x01, 0x1F, + 0xE1, 0x5C, 0xD2, 0xF5, 0x79, 0x2F, 0xEC, 0xFF, + 0xF2, 0xA4, 0x8A, 0xB5, 0x1E, 0x15, 0x38, 0x42, + 0x98, 0x82, 0x32, 0x7E, 0x05, 0x16, 0xE6, 0xA7, + 0x8F, 0x95, 0x1B, 0x19, 0x1A, 0x6E, 0x98, 0x17, + 0x04, 0x42, 0xF8, 0x37, 0xED, 0x93, 0x99, 0x85, + 0xDC, 0x67, 0x44, 0x4E, 0x19, 0x6E, 0x64, 0xA6, + 0xC7, 0xF5, 0x58, 0x94, 0x0A, 0xD7, 0xC2, 0xC5, + 0x80, 0xDE, 0xC6, 0x31, 0x10, 0x09, 0xC7, 0x17, + 0x92, 0xDA, 0x3E, 0x7E, 0x37, 0x68, 0xDE, 0x34, + 0xCE, 0x02, 0x3F, 0x06, 0xA8, 0x5B, 0x36, 0x10, + 0x52, 0x73, 0x8A, 0xCB, 0x00, 0x36, 0x63, 0x1F, + 0x48, 0x0E, 0xD4, 0x9C, 0x42, 0x2B, 0xD2, 0xBD, + 0x1C, 0x4F, 0xD1, 0x33, 0x58, 0xF6, 0x48, 0xAA, + 0x29, 0xD9, 0xCD, 0xE2, 0x72, 0xFA, 0x13, 0xC1, + 0xDC, 0x8D, 0xA7, 0x1D, 0xB0, 0xCE, 0x66, 0x58, + 0xD1, 0xF9, 0xC8, 0x0A, 0x68, 0xA8, 0x09, 0x36, + 0x8B, 0xFD, 0xFD, 0xE0, 0x25, 0xEA, 0x57, 0x2D, + 0x59, 0x87, 0x62, 0x8A, 0x5D, 0x22, 0x25, 0x6F, + 0x20, 0x02, 0xDB, 0x77, 0xFB, 0xB3, 0xF0, 0xDA, + 0x43, 0xED, 0x25, 0x8E, 0xCB, 0xA5, 0x5F, 0xF3, + 0xC6, 0xFE, 0x96, 0x55, 0x20, 0x2A, 0x66, 0x1B, + 0x5F, 0x54, 0x45, 0xDF, 0x2C, 0x68, 0x75, 0x0E, + 0xF0, 0x57, 0x59, 0xB4, 0xFF, 0x2A, 0xFC, 0x0D, + 0xF0, 0x34, 0xFD, 0xD2, 0xD4, 0xD4, 0xD1, 0x12, + 0x0F, 0x50, 0x5F, 0xC0, 0x4E, 0x7A, 0x5E, 0x5B, + 0xFB, 0x78, 0x25, 0x69, 0xB0, 0xDA, 0x5E, 0x0C, + 0x9C, 0x17, 0x43, 0xCD, 0xE3, 0x69, 0xED, 0x00, + 0xE1, 0xDC, 0x4A, 0x29, 0xFD, 0x1C, 0x0F, 0x47, + 0x34, 0x5C, 0x40, 0x93, 0xCC, 0xDF, 0x42, 0xA0, + 0x80, 0x7E, 0x72, 0x9A, 0x34, 0xA6, 0x40, 0x22, + 0xAC, 0xF7, 0xAD, 0x02, 0xF2, 0x42, 0x2C, 0x67, + 0xD2, 0x5B, 0x4E, 0x3A, 0xF6, 0xD9, 0xC2, 0xBD, + 0x72, 0xAA, 0x2F, 0xA0, 0x0B, 0x22, 0x45, 0x72, + 0x83, 0x94, 0xD3, 0x10, 0x28, 0x43, 0xCE, 0x47, + 0x39, 0x36, 0xD0, 0x44, 0xA0, 0x7A, 0x82, 0x90, + 0x43, 0xBB, 0x9F, 0x6A, 0x0C, 0xD9, 0xEF, 0xE4, + 0x7C, 0xAF, 0x2E, 0xFD, 0x0B, 0x47, 0xD4, 0x40, + 0x32, 0x0F, 0x8F, 0x62, 0x1B, 0x6A, 0x0A, 0x61, + 0x6D, 0x25, 0x65, 0x62, 0x50, 0xD3, 0x39, 0x42, + 0x3B, 0xE6, 0x68, 0xFD, 0xB7, 0xCE, 0x6D, 0x48, + 0x8D, 0xFE, 0x30, 0xAB, 0xDE, 0x62, 0x04, 0xEC, + 0x75, 0x66, 0x82, 0x76, 0x90, 0x47, 0x66, 0x7A, + 0x1F, 0x9C, 0x00, 0x18, 0xCA, 0x5C, 0xE9, 0xF8, + 0x8B, 0x1F, 0x14, 0x64, 0x9B, 0x5E, 0x0B, 0xF9, + 0x86, 0xFA, 0xC1, 0x88, 0x13, 0x23, 0x36, 0xC9, + 0xF1, 0x66, 0x6B, 0x5C, 0xA5, 0x89, 0xC3, 0x32, + 0x92, 0xD4, 0x4A, 0xB3, 0xF5, 0x56, 0x84, 0xA7, + 0x10, 0x45, 0x1C, 0xBE, 0x5E, 0xC8, 0xF4, 0x4F, + 0x7A, 0x4F, 0x4C, 0xC5, 0x95, 0xB2, 0x6B, 0x4C, + 0x6F, 0xB1, 0xB3, 0x6A, 0x18, 0x2B, 0x64, 0x8E, + 0x83, 0x3E, 0xBC, 0x59, 0x49, 0xD9, 0xA1, 0xF8, + 0xF4, 0xC1, 0x40, 0x09, 0x8E, 0x11, 0x8E, 0x0E, + 0xA8, 0x51, 0x2B, 0xEE, 0x5D, 0x87, 0x8A, 0xAC, + 0xF9, 0x4F, 0xA8, 0xD4, 0x10, 0x28, 0x3F, 0x1D, + 0x5B, 0xAD, 0x09, 0x93, 0x16, 0x8B, 0xD5, 0x96, + 0xE4, 0x15, 0xB0, 0x83, 0x9F, 0xB0, 0x3A, 0x6A, + 0x5A, 0x68, 0xAF, 0x3B, 0x51, 0xBC, 0xF8, 0x3C, + 0x0F, 0x80, 0xD5, 0xBF, 0xA3, 0xC4, 0xFF, 0xAB, + 0x05, 0xFA, 0xA3, 0x96, 0xAC, 0x31, 0x22, 0x94, + 0xC9, 0xCA, 0xB1, 0xFB, 0xAE, 0xF9, 0x00, 0x0B, + 0x0A, 0x68, 0xD6, 0x20, 0x19, 0xEA, 0xC6, 0x77, + 0x1A, 0xBF, 0x26, 0x3C, 0x46, 0x4A, 0x43, 0x8A, + 0xCC, 0x8C, 0x33, 0xB1, 0x49, 0x78, 0x7F, 0x57, + 0x65, 0xB5, 0x10, 0x8C, 0x03, 0xF8, 0xDE, 0xFA, + 0x97, 0x9B, 0xEE, 0x54, 0x70, 0x84, 0x7D, 0xE0, + 0xBB, 0x5A, 0x72, 0x92, 0x5E, 0x0E, 0x57, 0x3B, + 0x45, 0x91, 0x5B, 0x5E, 0x89, 0xD1, 0x26, 0x62, + 0xC9, 0xEF, 0x7B, 0x6E, 0x5F, 0xC6, 0x7F, 0x87, + 0x2E, 0x3C, 0xC8, 0x5F, 0x7F, 0xC1, 0x66, 0xF6, + 0x09, 0x27, 0xFB, 0xD8, 0x6A, 0x33, 0x18, 0x71, + 0x8C, 0x4E, 0x4B, 0xC3, 0x50, 0xB7, 0x88, 0x81, + 0xEB, 0x21, 0x20, 0x03, 0x75, 0x2B, 0xA9, 0x8F, + 0xEE, 0x3C, 0x35, 0xD6, 0x30, 0xD9, 0x8F, 0x75, + 0xAB, 0x67, 0x54, 0xDF, 0x22, 0x25, 0x2D, 0x8B, + 0xB7, 0x29, 0xE7, 0x49, 0x72, 0x23, 0x40, 0x7C, + 0x4A, 0x2D, 0x3F, 0xB9, 0xCE, 0x4F, 0x4F, 0xC9, + 0x39, 0x94, 0x19, 0x4B, 0x9F, 0xE0, 0x4B, 0x44, + 0x4A, 0xC4, 0xA1, 0x6A, 0xFA, 0x55, 0xF4, 0xC3, + 0x9A, 0x8C, 0xF4, 0x8B, 0xBB, 0xB4, 0x17, 0x80, + 0xBC, 0x79, 0xBC, 0xE2, 0x71, 0x1C, 0x73, 0xEE, + 0x8A, 0x29, 0x49, 0x86, 0x59, 0xED, 0x37, 0xC2, + 0xDB, 0x11, 0xD7, 0x46, 0xAD, 0xDB, 0x81, 0xF9, + 0xDE, 0x3D, 0x4C, 0x2B, 0xEA, 0xAC, 0xDC, 0xA2, + 0x77, 0x00, 0xBA, 0xCF, 0x8A, 0x21, 0xB3, 0x25, + 0xFE, 0x69, 0x82, 0x1E, 0x8F, 0x90, 0xD5, 0x5D, + 0x55, 0xD2, 0x36, 0x91, 0xD0, 0xE4, 0xAF, 0x9E, + 0x41, 0xDB, 0x56, 0x86, 0xCF, 0x86, 0xC8, 0x40, + 0x7D, 0xF9, 0x23, 0xCC, 0xA1, 0xDA, 0x8B, 0x74, + 0xEB, 0x84, 0x22, 0xC8, 0x81, 0xCD, 0x1F, 0x35, + 0x78, 0x14, 0x42, 0x1C, 0xEF, 0x42, 0xF3, 0x58, + 0x9E, 0x2E, 0x48, 0x40, 0x29, 0xEF, 0x1C, 0x7F, + 0xBB, 0x32, 0xCD, 0x00, 0xEA, 0x49, 0x4F, 0xDE, + 0x6F, 0xB5, 0x6E, 0x31, 0x36, 0xBF, 0x72, 0x36, + 0x06, 0x06, 0xF6, 0x7A, 0xD2, 0xBB, 0x9A, 0xC2, + 0xA6, 0x73, 0x44, 0xFD, 0xB6, 0xFD, 0x9D, 0x17, + 0x7F, 0xCA, 0x5F, 0xB7, 0x0F, 0xD7, 0xF2, 0xAB, + 0x33, 0x24, 0x98, 0x2D, 0x5D, 0xD4, 0xC4, 0xD0, + 0xF0, 0x40, 0xC3, 0xC6, 0x4E, 0xDA, 0x52, 0x2F, + 0x47, 0x14, 0xE3, 0xA4, 0x66, 0x20, 0xDD, 0xE4, + 0x72, 0x06, 0x1D, 0x81, 0xE0, 0xF7, 0x24, 0x2B, + 0x69, 0xB3, 0x18, 0x65, 0x3C, 0x41, 0xCC, 0x74, + 0xE3, 0xB9, 0x13, 0xCE, 0x44, 0xAC, 0xD3, 0x17, + 0x7F, 0x8A, 0x8E, 0x54, 0xF7, 0xA3, 0x62, 0x1B, + 0x0E, 0x0A, 0xF4, 0x02, 0x7A, 0x7D, 0x6F, 0x22, + 0x80, 0xB5, 0x22, 0x8B, 0xDF, 0xA3, 0x65, 0x41, + 0x9C, 0x3D, 0xF7, 0x86, 0x2E, 0x17, 0x03, 0xDC, + 0x09, 0x09, 0xB1, 0x57, 0xC5, 0x48, 0xC8, 0xDD, + 0x9D, 0xEA, 0x6C, 0x00, 0x64, 0xC6, 0xC2, 0x3A, + 0x00, 0x13, 0x0B, 0x56, 0x0C, 0x67, 0x70, 0xAE, + 0x6C, 0x4F, 0x16, 0xE4, 0x25, 0x03, 0x4D, 0x1D, + 0x33, 0xF5, 0x1C, 0x29, 0x17, 0x88, 0x74, 0x09, + 0x22, 0x33, 0xD4, 0x35, 0xE2, 0x76, 0x7E, 0xAA, + 0x52, 0x72, 0x19, 0x41, 0xD4, 0x82, 0xDA, 0x8D, + 0x03, 0xCF, 0x96, 0x88, 0x7A, 0x73, 0xAD, 0xFD, + 0x39, 0x52, 0x71, 0x37, 0xC1, 0x0A, 0xCA, 0x95, + 0xEF, 0x16, 0xF9, 0x71, 0xAA, 0x77, 0x2E, 0xEC, + 0xAA, 0xEE, 0x07, 0xB8, 0xAC, 0xD0, 0x12, 0x28, + 0x45, 0xC4, 0xFE, 0x6F, 0x86, 0x60, 0xFD, 0x6E, + 0xD4, 0x9B, 0xAC, 0x6F, 0xC1, 0x18, 0xAC, 0x3B, + 0x7C, 0x75, 0xE4, 0x05, 0x50, 0xE9, 0xFF, 0x7B, + 0xB2, 0x43, 0x38, 0x27, 0x6F, 0xF3, 0xFD, 0xA0, + 0x06, 0xF1, 0x7A, 0x45, 0x80, 0xEF, 0xCD, 0xF1, + 0xC3, 0x1E, 0x11, 0x3F, 0xA7, 0x0D, 0x9C, 0x23, + 0x2C, 0x12, 0x5E, 0xF0, 0x56, 0xB8, 0xF5, 0xF5, + 0x77, 0xAF, 0xD4, 0x81, 0x94, 0xD8, 0x79, 0xB7, + 0x59, 0xA6, 0x6A, 0xC8, 0x77, 0xFC, 0x60, 0xA8, + 0x2F, 0xE3, 0x37, 0xF8, 0x16, 0x96, 0xCF, 0x8B, + 0x10, 0x48, 0xCF, 0xFD, 0x1D, 0x63, 0x2C, 0x26, + 0xA0, 0x79, 0xB2, 0xE2, 0xFB, 0xBE, 0xE2, 0xC6, + 0x1D, 0xDB, 0x8B, 0x68, 0x76, 0x0B, 0x12, 0xA7, + 0xB0, 0x56, 0x01, 0x3B, 0x31, 0x28, 0x66, 0x4D, + 0xDD, 0xA7, 0x9F, 0x80, 0x6B, 0x30, 0x75, 0xF5, + 0x67, 0x80, 0x55, 0xA0, 0xB4, 0x5E, 0x29, 0x9F, + 0xE2, 0xB0, 0x74, 0xAA, 0x0B, 0x9A, 0x35, 0x57, + 0x55, 0xC1, 0xAE, 0xF9, 0x7C, 0x4A, 0xEB, 0x62, + 0x61, 0x96, 0xFA, 0x4F, 0xBD, 0x0B, 0x8F, 0xDA, + 0xCF, 0x8E, 0x6A, 0xBC, 0x39, 0x77, 0x70, 0x11, + 0x8A, 0x65, 0x68, 0xAD, 0xE5, 0x18, 0x7E, 0xF4, + 0xA5, 0xC9, 0x57, 0xB9, 0x36, 0xB2, 0xA9, 0xA8, + 0x3B, 0xE4, 0xCA, 0x38, 0x22, 0xB3, 0x6E, 0xE0, + 0xB1, 0x36, 0xAE, 0x79, 0xC7, 0x19, 0x65, 0xBD, + 0x92, 0xCF, 0x4D, 0x13, 0x6C, 0x42, 0x64, 0x2B, + 0xF7, 0x6F, 0x85, 0x50, 0xDB, 0x51, 0xC9, 0xF3, + 0xC7, 0xDF, 0x3A, 0x7D, 0x40, 0x3B, 0x2D, 0x85, + 0x1E, 0x3F, 0xC5, 0x8B, 0xDF, 0x71, 0x49, 0xF3, + 0xD9, 0xAF, 0x90, 0xE8, 0xAD, 0x18, 0x04, 0x51, + 0xA7, 0x51, 0x6E, 0x3B, 0xC3, 0xB8, 0x9A, 0x3C, + 0x11, 0xA5, 0x89, 0x9F, 0x37, 0x27, 0x9F, 0xC4, + 0x2F, 0xDE, 0x15, 0xA1, 0xA9, 0x3C, 0xF8, 0x6B, + 0xA9, 0x88, 0x60, 0x4C, 0x07, 0xFF, 0xEA, 0x6C, + 0xD1, 0xD2, 0x2E, 0x21, 0x74, 0x5C, 0x4E, 0x43, + 0xCA, 0x41, 0xCE, 0x2D, 0x9C, 0x04, 0x8C, 0xD2, + 0xE5, 0xF3, 0x5A, 0xC0, 0xA7, 0x21, 0xD5, 0x26, + 0xC9, 0x9F, 0x14, 0xE5, 0x69, 0x16, 0xF2, 0xEB, + 0x62, 0xBD, 0xFA, 0x3E, 0xAD, 0x61, 0x34, 0xA5, + 0x28, 0x4E, 0xF2, 0x20, 0x5B, 0x08, 0x78, 0x1C, + 0x91, 0x03, 0xD1, 0xB2, 0x60, 0x49, 0x87, 0xD7, + 0x30, 0x0F, 0x34, 0xD9, 0xB6, 0x97, 0xCA, 0xD0, + 0x9F, 0x51, 0xD3, 0x5F, 0xFB, 0xD5, 0xB3, 0xBD, + 0x30, 0xE5, 0x52, 0xBF, 0x14, 0x38, 0xDD, 0x2E, + 0x59, 0x62, 0x02, 0xA4, 0xC8, 0x23, 0xFF, 0x37, + 0x73, 0x42, 0x35, 0x48, 0x56, 0xEF, 0xC1, 0x8D, + 0x46, 0xD1, 0xAE, 0x7C, 0x31, 0x34, 0x6D, 0xD7, + 0xF3, 0x9A, 0xCF, 0x9E, 0x29, 0xF4, 0xB4, 0xE3, + 0x8A, 0xF0, 0x35, 0x3E, 0xB3, 0x6C, 0x2E, 0x5B, + 0x4E, 0xB5, 0xDF, 0xC7, 0x29, 0x6B, 0xD2, 0x9B, + 0xCF, 0x41, 0xBC, 0xA0, 0x5C, 0xF6, 0x16, 0x16, + 0x90, 0x2B, 0x11, 0x2C, 0x58, 0xDA, 0xCE, 0x52, + 0xE6, 0x47, 0xBC, 0x5A, 0xE2, 0xD2, 0x9B, 0xCF, + 0x6A, 0x91, 0x85, 0x7C, 0x99, 0x3C, 0x5F, 0xED, + 0x53, 0x3D, 0x82, 0xB7, 0x38, 0x83, 0xD4, 0xCE, + 0x13, 0xDA, 0x10, 0xD3, 0xBB, 0xFE, 0x18, 0x59, + 0xDE, 0x79, 0xCB, 0x52, 0xD6, 0xB7, 0xD7, 0x5D, + 0x7D, 0x8E, 0x13, 0x86, 0xC0, 0x7D, 0x7F, 0x64, + 0x09, 0x2B, 0xB4, 0x49, 0xC0, 0x54, 0xFF, 0x5E, + 0x39, 0xA6, 0x13, 0xB6, 0x4E, 0x3B, 0x2F, 0xC3, + 0x9C, 0xA4, 0x50, 0x19, 0x2C, 0x29, 0x43, 0x03, + 0x6C, 0x34, 0xA2, 0xAF, 0x5D, 0x3B, 0x24, 0xB3, + 0x91, 0x71, 0x70, 0xC8, 0xB6, 0xA9, 0x8F, 0x29, + 0xF6, 0xA3, 0xFE, 0x41, 0x2F, 0x20, 0x8E, 0x17, + 0x13, 0xAC, 0xF9, 0x4A, 0x8E, 0x45, 0x43, 0x00, + 0xD8, 0xDF, 0x39, 0xC7, 0x19, 0xDD, 0xCA, 0x21, + 0xA7, 0x79, 0xDF, 0x46, 0x81, 0x01, 0x70, 0x74, + 0x42, 0x3F, 0xB5, 0xAF, 0x1D, 0xCC, 0xD7, 0x97, + 0xDD, 0x37, 0x1C, 0x49, 0x74, 0xDE, 0x29, 0xD2, + 0xF7, 0x70, 0xDC, 0x37, 0xA9, 0x69, 0x25, 0x83, + 0xDF, 0x75, 0xE5, 0x64, 0x72, 0xAB, 0x5B, 0xE0, + 0x1B, 0x97, 0x97, 0x91, 0xD7, 0x33, 0x19, 0x22, + 0x12, 0x5B, 0xDB, 0x19, 0x57, 0xFD, 0x98, 0x96, + 0xE4, 0xE9, 0x4E, 0x9C, 0x0A, 0x0A, 0xFF, 0xEA, + 0x26, 0xFF, 0xC3, 0x8F, 0xEF, 0x06, 0x67, 0xC6, + 0x43, 0xC2, 0x8F, 0xA1, 0xF5, 0x87, 0x87, 0xA5, + 0xA5, 0x8D, 0x93, 0xB9, 0xEF, 0x46, 0xC9, 0x3F, + 0x7B, 0x17, 0x07, 0x7C, 0xA7, 0x41, 0xCD, 0xD7, + 0xA4, 0x74, 0xF5, 0x3F, 0x2D, 0x79, 0x63, 0xDD, + 0x80, 0x99, 0xE3, 0x32, 0xC5, 0x40, 0x07, 0x12, + 0x0C, 0x7F, 0xC0, 0xF6, 0x1E, 0x85, 0xF2, 0xEC, + 0x2E, 0x9E, 0x7C, 0x77, 0x00, 0x29, 0x37, 0x85, + 0xFB, 0x4D, 0xEB, 0xDD, 0xD5, 0xA5, 0x12, 0x18, + 0xB6, 0x91, 0x74, 0xC0, 0x1E, 0x26, 0x6D, 0x6A, + 0x9C, 0x75, 0x6C, 0xA1, 0xE6, 0x5B, 0xDF, 0xF3, + 0x5F, 0xCB, 0xE3, 0x58, 0x83, 0x98, 0xE3, 0x54, + 0x33, 0xBB, 0x5D, 0xF8, 0xAE, 0xBB, 0x6B, 0xB4, + 0xA2, 0xC3, 0x63, 0x24, 0x06, 0xD9, 0x88, 0x31, + 0x0D, 0x8B, 0x4E, 0xF7, 0xAD, 0x3C, 0x65, 0x2D, + 0x8A, 0xDD, 0x3F, 0xDB, 0xBF, 0x49, 0xCE, 0xD5, + 0x03, 0x2B, 0x02, 0x91, 0x8D, 0x2C, 0x7C, 0xA3, + 0xDC, 0xB0, 0x2D, 0x07, 0x8D, 0x08, 0x2C, 0x3B, + 0x25, 0x2F, 0x2F, 0x59, 0xFF, 0xFD, 0x46, 0xEB, + 0xB5, 0x59, 0x4B, 0xA1, 0xE8, 0x05, 0x05, 0x3E, + 0xBB, 0x71, 0xA5, 0x9F, 0xE0, 0x94, 0x6A, 0xAD, + 0x92, 0x8E, 0xCD, 0xB1, 0x07, 0x5A, 0x01, 0x9B, + 0x0A, 0x92, 0x56, 0x8A, 0x59, 0x87, 0xB7, 0x9F, + 0x10, 0x1B, 0xF3, 0xB4, 0xE6, 0x88, 0x4A, 0xB9, + 0x88, 0x4F, 0xDA, 0x7B, 0x29, 0x19, 0x8F, 0xE8, + 0x0B, 0xC4, 0xEB, 0x7C, 0xE0, 0x23, 0x00, 0xDB, + 0x81, 0x36, 0x4D, 0x4D, 0x0A, 0x03, 0xBA, 0x8F, + 0x84, 0xA8, 0xD5, 0x18, 0xDD, 0x90, 0x67, 0x02, + 0x11, 0xF0, 0x90, 0x59, 0x95, 0x1B, 0x38, 0x92, + 0x62, 0x47, 0xE8, 0xED, 0x88, 0xEB, 0x93, 0x6E, + 0xB7, 0xB8, 0x4A, 0x8A, 0xFE, 0x85, 0xE6, 0xD0, + 0x54, 0xA7, 0x3A, 0x4E, 0xF8, 0x6A, 0x66, 0xC4, + 0xC2, 0x56, 0xB4, 0xA3, 0x30, 0x18, 0xED, 0x0A, + 0x29, 0xA9, 0xFE, 0xC8, 0x50, 0x10, 0x87, 0xB1, + 0x60, 0x3E, 0x99, 0x93, 0xDB, 0xD7, 0xD9, 0xA6, + 0xD3, 0xB9, 0x0E, 0x68, 0x9D, 0x29, 0xB4, 0xBB, + 0xC4, 0x79, 0x5A, 0xEA, 0x8E, 0xBF, 0x34, 0xF2, + 0xDB, 0xF4, 0xAC, 0x20, 0xE2, 0xF3, 0x1E, 0xED, + 0x5D, 0xAA, 0xC4, 0xD7, 0xFF, 0xF2, 0xD8, 0xBA, + 0xA7, 0x9C, 0xB8, 0x97, 0xC9, 0xFF, 0xA7, 0x48, + 0x11, 0x57, 0x0C, 0x31, 0x16, 0x54, 0x41, 0xF1, + 0xD6, 0x71, 0xED, 0x74, 0xBD, 0xC8, 0xC5, 0xFE, + 0xC4, 0x07, 0x18, 0x53, 0x38, 0xEA, 0x1B, 0x48, + 0xAD, 0x2A, 0xDA, 0x8E, 0x86, 0xE5, 0x96, 0xB1, + 0xB9, 0x20, 0xC9, 0x74, 0x31, 0x95, 0x4A, 0x28, + 0xF5, 0x6C, 0x7F, 0xC9, 0x71, 0xF9, 0xA0, 0x37, + 0x04, 0x10, 0x5A, 0x28, 0x77, 0xA7, 0x04, 0xCD, + 0x7D, 0x48, 0xD0, 0x69, 0xE3, 0xF2, 0x2A, 0x86, + 0xBD, 0xC3, 0xD6, 0x63, 0x18, 0xB8, 0xEB, 0x05, + 0x90, 0x11, 0x04, 0xFE, 0xA1, 0x9D, 0xAF, 0x87, + 0x1F, 0x27, 0x29, 0xA0, 0x85, 0x4D, 0x7C, 0x0C, + 0x4D, 0xE0, 0x77, 0x1C, 0x36, 0x8A, 0x43, 0xEA, + 0xC9, 0x6E, 0x67, 0x3F, 0xEB, 0x6D, 0x05, 0x1C, + 0xF3, 0x0C, 0x4C, 0xB0, 0xEB, 0xD5, 0xA0, 0xC6, + 0xDA, 0xA5, 0x0A, 0x02, 0x8C, 0x8B, 0xF9, 0x36, + 0x97, 0xBC, 0xBA, 0x37, 0x3C, 0xBB, 0xE1, 0x7B, + 0xD3, 0x74, 0x38, 0x24, 0x95, 0xDB, 0x0E, 0x57, + 0x74, 0x01, 0xE7, 0x4D, 0x2F, 0x83, 0xE9, 0x9E, + 0xD6, 0xE6, 0x10, 0xD8, 0x0A, 0x0B, 0xCF, 0xB2, + 0x40, 0x65, 0x07, 0xEC, 0xBE, 0xBD, 0x49, 0x7F, + 0x95, 0x97, 0x5C, 0x82, 0x4A, 0xCD, 0xFB, 0xFA, + 0xE0, 0x37, 0x03, 0x2D, 0x5A, 0x66, 0x0C, 0x15, + 0xEE, 0x2E, 0x8E, 0xBA, 0x38, 0x6A, 0xCB, 0xFF, + 0xCD, 0xAD, 0x83, 0xCE, 0x9A, 0x8B, 0x12, 0xB1, + 0xF1, 0x3A, 0xAF, 0x46, 0x65, 0x68, 0x46, 0xB7, + 0x1C, 0x98, 0x0F, 0x64, 0x8E, 0xF7, 0xDC, 0xFC, + 0xD0, 0xC8, 0x13, 0x02, 0xDA, 0x5E, 0xAE, 0x93, + 0x3F, 0xF3, 0x1B, 0x82, 0x52, 0x23, 0xFB, 0x8C, + 0xAC, 0x04, 0xDC, 0xF7, 0x8B, 0x53, 0x90, 0xAB, + 0x84, 0xB8, 0x36, 0x01, 0x66, 0x05, 0xB2, 0x45, + 0xC6, 0xBD, 0x55, 0x3F, 0x87, 0x33, 0x53, 0xC6, + 0xC4, 0xDE, 0xF2, 0xAA, 0xFC, 0xAF, 0x56, 0x84, + 0xFB, 0x3A, 0x78, 0x41, 0x8A, 0x37, 0x93, 0x5B, + 0x52, 0xD5, 0x41, 0x55, 0xDC, 0x9B, 0xAF, 0xA0, + 0x1F, 0xB2, 0xAA, 0x0C, 0x3A, 0x15, 0x61, 0x31, + 0x3D, 0x20, 0xB8, 0xB0, 0xBB, 0xF2, 0x8C, 0x50, + 0x71, 0x5D, 0x38, 0x6C, 0x99, 0x57, 0x5E, 0x00, + 0x0F, 0x39, 0x17, 0x91, 0x8F, 0x10, 0xCC, 0xBF, + 0x25, 0xEC, 0x4D, 0x05, 0xCB, 0x36, 0x2E, 0x03, + 0x03, 0x9D, 0x89, 0x6E, 0x22, 0xB2, 0xAC, 0xE4, + 0x73, 0xAA, 0x67, 0x48, 0x27, 0xA4, 0x91, 0x87, + 0x7E, 0x12, 0xDF, 0x9A, 0x4D, 0xCE, 0x5B, 0x7F, + 0x19, 0x6C, 0x72, 0xB4, 0x60, 0xE2, 0xDD, 0xA3, + 0xEA, 0xF3, 0x6F, 0xB8, 0xBA, 0x7F, 0xD8, 0x99, + 0x13, 0x0E, 0x1D, 0x14, 0xD9, 0xB0, 0x13, 0x3E, + 0x23, 0x8F, 0xB6, 0xB4, 0x46, 0x7E, 0x60, 0xC9, + 0x14, 0x5F, 0x9A, 0x1C, 0xA1, 0x9E, 0x98, 0xFD, + 0xE0, 0xE8, 0x64, 0x9C, 0x3A, 0x00, 0x4F, 0x50, + 0xC2, 0xA6, 0x63, 0xF6, 0x15, 0xB5, 0xA0, 0xF2, + 0x7E, 0xD2, 0xD8, 0x87, 0x79, 0x15, 0x14, 0xE0, + 0xA0, 0xFC, 0xF9, 0x3A, 0x13, 0xD7, 0xE5, 0x53, + 0x1E, 0x5D, 0x87, 0xD1, 0x4A, 0x12, 0x34, 0x62, + 0x04, 0x4B, 0x3D, 0xDD, 0xF4, 0xD2, 0xF3, 0x97, + 0xF7, 0xA6, 0xDA, 0xAD, 0xE8, 0x95, 0x00, 0x80, + 0xE6, 0x55, 0x6A, 0x44, 0x21, 0xF2, 0xAB, 0xE9, + 0x2A, 0x06, 0xBB, 0x04, 0x55, 0x4C, 0xC5, 0x8C, + 0x88, 0xAA, 0xDD, 0x9E, 0x84, 0xBA, 0x98, 0x80, + 0x35, 0x13, 0x8E, 0xD9, 0x48, 0xD6, 0xE2, 0xC6, + 0x27, 0x02, 0xA1, 0x60, 0xBE, 0xCC, 0x62, 0x02, + 0x40, 0x4C, 0x20, 0x6E, 0x71, 0x75, 0xDA, 0x50, + 0xFC, 0x89, 0xD9, 0x29, 0x56, 0x13, 0xF4, 0x7C, + 0x5D, 0xE5, 0x35, 0x14, 0x13, 0xEF, 0x73, 0x0A, + 0x82, 0x84, 0x73, 0x06, 0xA1, 0x18, 0x25, 0x9D, + 0xB1, 0x3E, 0xB7, 0x49, 0xEA, 0x18, 0xE2, 0x87, + 0xAC, 0xED, 0xC3, 0x65, 0x53, 0x51, 0x4B, 0x33, + 0xB2, 0x17, 0xFB, 0xF5, 0xC9, 0x7E, 0xFA, 0xFF, + 0x9D, 0x94, 0x14, 0x93, 0x02, 0xB5, 0x99, 0x9E, + 0x93, 0x09, 0xDF, 0xED, 0xD3, 0x01, 0xAE, 0x6E, + 0xF8, 0x2C, 0x45, 0x67, 0x95, 0x90, 0x57, 0xE6, + 0xB4, 0x5C, 0xAD, 0x2E, 0x9F, 0xDA, 0x94, 0xF7, + 0x6B, 0xA3, 0x1B, 0x69, 0xE2, 0xBB, 0xD6, 0x29, + 0xC1, 0x45, 0xC8, 0xB3, 0xCF, 0xEC, 0x1F, 0xD3, + 0x62, 0x55, 0x97, 0x8D, 0x0B, 0xE0, 0x57, 0xB8, + 0xB7, 0x00, 0x4A, 0x13, 0x20, 0x4D, 0x1D, 0xB2, + 0xCC, 0x69, 0x5A, 0x5C, 0x26, 0x23, 0x72, 0x8B, + 0x74, 0x0A, 0x78, 0xA8, 0x3A, 0x0F, 0x35, 0xA8, + 0xA2, 0xC3, 0x0A, 0x66, 0x33, 0xBF, 0xEA, 0x7A, + 0x53, 0xB6, 0x9E, 0x55, 0x33, 0xDD, 0x3D, 0x9C, + 0xCF, 0x43, 0x76, 0xC8, 0xE0, 0x90, 0xC9, 0x66, + 0xAC, 0x3C, 0x8E, 0x72, 0x0C, 0x75, 0xE4, 0xDC, + 0x52, 0xCD, 0x3E, 0x8A, 0x88, 0xD6, 0x8C, 0xD1, + 0x21, 0x54, 0xAB, 0x3B, 0xEC, 0x0C, 0xDC, 0x70, + 0xCC, 0xD0, 0x63, 0x1A, 0x30, 0x51, 0x5E, 0x32, + 0x98, 0x68, 0x5E, 0xD7, 0x1C, 0x71, 0x94, 0x1A, + 0xE8, 0x4E, 0x2A, 0x02, 0x16, 0x00, 0x1A, 0xC5, + 0xD2, 0xFF, 0x6B, 0xA0, 0x48, 0xB1, 0xF6, 0xE1, + 0xDA, 0x0E, 0x6E, 0xC3, 0xD3, 0xFD, 0x5D, 0xE7, + 0x6C, 0xFB, 0xC0, 0x2E, 0x6F, 0xD0, 0xA9, 0x4F, + 0xD0, 0x97, 0xCB, 0x70, 0x89, 0x1C, 0xE0, 0x7C, + 0xCB, 0xFC, 0x8B, 0x78, 0x27, 0x54, 0x1E, 0x74, + 0x86, 0x32, 0xF0, 0x69, 0xC7, 0xE4, 0x97, 0xE4, + 0x84, 0xCD, 0x30, 0x7C, 0xAD, 0xE3, 0x79, 0xC6, + 0xC7, 0x59, 0xB2, 0x56, 0x27, 0x74, 0xB0, 0x98, + 0x87, 0x09, 0xF6, 0x7B, 0x73, 0xA1, 0x1A, 0x53, + 0xC2, 0x6B, 0x2D, 0x1B, 0x7C, 0xBE, 0x45, 0x94, + 0x95, 0xED, 0x37, 0x00, 0x0A, 0x17, 0x75, 0x89, + 0x63, 0x85, 0xAA, 0x3F, 0xA8, 0x87, 0xB8, 0x18, + 0x48, 0x82, 0x90, 0xFE, 0xCE, 0x7E, 0xD6, 0x68, + 0x0E, 0x99, 0x20, 0xDC, 0xBD, 0x16, 0xE0, 0x96, + 0xEB, 0x3C, 0x7D, 0xE6, 0x6C, 0x4C, 0xBA, 0xA5, + 0x0B, 0x73, 0x51, 0x27, 0x9B, 0xDF, 0xC6, 0x92, + 0xDE, 0xED, 0x36, 0xCA, 0x5A, 0xAE, 0xF3, 0x02, + 0x7F, 0xEE, 0xB1, 0xB3, 0x01, 0xE0, 0xAB, 0x2F, + 0x13, 0xCE, 0x62, 0x1E, 0x0B, 0xB9, 0x45, 0x38, + 0x03, 0x09, 0x5E, 0xCB, 0xB1, 0x68, 0xD7, 0x10, + 0xCF, 0x5D, 0x47, 0xE5, 0x28, 0x72, 0x28, 0x4E, + 0x7C, 0x09, 0x38, 0x2A, 0xCB, 0x48, 0xF4, 0x3C, + 0xD8, 0x7C, 0x9E, 0x04, 0x44, 0x7B, 0xCA, 0xC5, + 0x4A, 0xA6, 0xD2, 0x82, 0x5A, 0x26, 0x45, 0xB6, + 0xB0, 0x22, 0xB2, 0x0A, 0xC2, 0x6B, 0x0C, 0x91, + 0x6A, 0x2C, 0xA2, 0x9A, 0x3C, 0xC5, 0xE2, 0xEE, + 0x15, 0x4F, 0x02, 0x0B, 0x2B, 0xCF, 0x93, 0x93, + 0xCA, 0x93, 0x60, 0x59, 0xD9, 0x79, 0x32, 0x0E, + 0xAA, 0xC7, 0x21, 0x81, 0xA2, 0x70, 0x08, 0xF7, + 0x46, 0xD1, 0x85, 0xBD, 0xA6, 0x02, 0x85, 0x7E, + 0x3F, 0xE0, 0x08, 0x9E, 0x37, 0x9A, 0xF0, 0xE7, + 0xB0, 0x88, 0x51, 0xFF, 0xF8, 0xE2, 0x2B, 0xF7, + 0x7C, 0xA4, 0xDB, 0x6B, 0x36, 0xBD, 0xF1, 0x41, + 0xFE, 0xD6, 0x5B, 0xC4, 0x39, 0x2A, 0xFA, 0xEB, + 0x45, 0x89, 0xEA, 0xA2, 0x7B, 0xAD, 0x25, 0x75, + 0x02, 0x43, 0xC7, 0xF7, 0x49, 0x2F, 0xFB, 0xCB, + 0xA1, 0x26, 0x68, 0xF7, 0x68, 0xF3, 0xC5, 0x0B, + 0x18, 0x30, 0xEC, 0x5F, 0x8D, 0x24, 0xD6, 0xBA, + 0x21, 0x57, 0x4A, 0x90, 0x05, 0xE3, 0x02, 0xBA, + 0xF5, 0x00, 0x20, 0x55, 0xB2, 0xDC, 0x4E, 0xCB, + 0x1A, 0xC8, 0xD5, 0x6A, 0x05, 0xE5, 0xB5, 0x9E, + 0x43, 0x24, 0x34, 0xB9, 0x76, 0x48, 0x98, 0xAB, + 0x0A, 0x6B, 0xD8, 0xBE, 0xF5, 0x2A, 0xC2, 0x34, + 0x9A, 0xB2, 0xC7, 0x44, 0xA9, 0xD7, 0xC3, 0x8B, + 0xF6, 0x93, 0x57, 0xFC, 0xE2, 0xD4, 0x94, 0x93, + 0x1D, 0xA4, 0x78, 0x5A, 0xB4, 0x3D, 0x86, 0x6D, + 0xF2, 0xC3, 0xBE, 0x04, 0x1F, 0x44, 0x86, 0xE2, + 0xF8, 0xE7, 0x6A, 0xD1, 0x67, 0x32, 0x44, 0xD0, + 0x7C, 0xA6, 0xF6, 0xED, 0x34, 0xCD, 0x6C, 0xC2, + 0x42, 0xAE, 0x3B, 0x81, 0x69, 0x16, 0xFF, 0x38, + 0x26, 0xC2, 0x0B, 0x16, 0x34, 0xA7, 0xC9, 0xF5, + 0x41, 0x4E, 0xFE, 0x83, 0xB6, 0xD1, 0x8C, 0xAF, + 0xB3, 0xE7, 0x99, 0x5C, 0xBA, 0xF9, 0x38, 0xFB, + 0xA1, 0x6E, 0x26, 0x6E, 0x26, 0xD1, 0xD0, 0x0E, + 0x44, 0xC1, 0x30, 0xE0, 0x1F, 0x2F, 0xE6, 0x04, + 0xF0, 0x2E, 0x79, 0x91, 0x8B, 0xE1, 0xE9, 0x65, + 0x2B, 0x63, 0x3D, 0xB8, 0xD2, 0x9D, 0xC3, 0xB4, + 0x93, 0x4B, 0x1A, 0x69, 0x8F, 0xD4, 0xEF, 0xEC, + 0x91, 0xF1, 0xDD, 0xB9, 0x50, 0x40, 0x05, 0xDC, + 0xDD, 0x3A, 0xD5, 0xBC, 0x40, 0x8F, 0x92, 0xCB, + 0xC2, 0xAC, 0x67, 0x6F, 0x3F, 0xBE, 0xDB, 0xAA, + 0x9B, 0x2B, 0x5C, 0x9E, 0x47, 0x03, 0x1D, 0x31, + 0xB6, 0x9D, 0xAC, 0x69, 0x4A, 0x2C, 0x02, 0xD2, + 0x5E, 0x02, 0x48, 0xDC, 0xF8, 0x51, 0x26, 0xA5, + 0x29, 0xF9, 0x09, 0xD7, 0xB8, 0x20, 0x5C, 0x42, + 0x96, 0x07, 0x04, 0x90, 0x47, 0x7D, 0x02, 0x69, + 0x28, 0x4A, 0x0F, 0x84, 0x9B, 0xBD, 0x77, 0xF5, + 0x56, 0xD7, 0x5A, 0x34, 0xC6, 0xE2, 0x9D, 0x25, + 0x73, 0x21, 0x08, 0xB0, 0xA9, 0x1F, 0x87, 0x07, + 0x36, 0x44, 0x92, 0x89, 0x4F, 0xE3, 0x78, 0x1F, + 0x6B, 0x69, 0x67, 0x25, 0x7B, 0xBE, 0xA5, 0x26, + 0x1C, 0xB7, 0x72, 0x3A, 0x92, 0x83, 0xEE, 0x0F, + 0x43, 0x68, 0x42, 0x88, 0xEE, 0x61, 0xC1, 0xAE, + 0x95, 0xB0, 0x6D, 0x7E, 0xCD, 0xA1, 0xF4, 0x90, + 0x05, 0xB1, 0x1E, 0x7B, 0x05, 0x0A, 0xB7, 0xBB, + 0x75, 0x77, 0x5E, 0x19, 0x3F, 0x37, 0x31, 0x90, + 0x25, 0x4F, 0x1C, 0x70, 0xEE, 0x69, 0x71, 0xC7, + 0x30, 0xDE, 0xAC, 0x9D, 0x20, 0x9E, 0xB0, 0xD1, + 0xAC, 0x72, 0x92, 0xDC, 0x76, 0xF2, 0x01, 0x00, + 0x19, 0x32, 0x98, 0xFC, 0x75, 0x25, 0x7F, 0x68, + 0x0D, 0x77, 0xE3, 0x48, 0x61, 0x99, 0x0C, 0xF1, + 0xD1, 0x91, 0x4C, 0x1F, 0xB1, 0x8B, 0x84, 0x79, + 0x42, 0x9A, 0x6C, 0x83, 0xFC, 0x89, 0xB4, 0x75, + 0x86, 0x41, 0x19, 0x8A, 0x4C, 0xE5, 0x0B, 0x83, + 0xBE, 0xB6, 0xAA, 0x1F, 0x46, 0x69, 0x0C, 0xBE, + 0x56, 0x59, 0x73, 0x29, 0x91, 0x0D, 0x44, 0x72, + 0x10, 0xEE, 0xBA, 0x10, 0x23, 0x10, 0x39, 0x5F, + 0x19, 0x71, 0x6E, 0x2A, 0x06, 0x2A, 0x77, 0x66, + 0xC6, 0x9B, 0x80, 0x6B, 0xAF, 0xE7, 0xC8, 0xB6, + 0x17, 0xF4, 0xF5, 0xE8, 0x13, 0x4B, 0xDD, 0x71, + 0xEB, 0xF7, 0x74, 0xB0, 0xEB, 0xF1, 0x82, 0x3A, + 0x83, 0x51, 0xAA, 0xB5, 0x5C, 0x9F, 0x4C, 0xCA, + 0x0A, 0x97, 0xFB, 0xC3, 0x07, 0xD7, 0x27, 0xF3, + 0x31, 0x80, 0x46, 0xEA, 0xDE, 0xA7, 0x0F, 0xC6, + 0xDD, 0x3C, 0xFE, 0x86, 0x06, 0x8F, 0x5A, 0x20, + 0xBF, 0x7D, 0xF1, 0xDC, 0xBF, 0x1B, 0x5F, 0x19, + 0xA4, 0xE4, 0x73, 0xB4, 0xBD, 0x3C, 0x29, 0xA5, + 0xA1, 0xAB, 0xC8, 0x21, 0x06, 0xC7, 0x1A, 0x26, + 0xCE, 0xB5, 0xCE, 0xA6, 0xD5, 0xE9, 0x36, 0x81, + 0x70, 0x8F, 0x7C, 0x30, 0x14, 0x9D, 0x15, 0x22, + 0x05, 0xC8, 0x22, 0x73, 0xE8, 0xA0, 0x93, 0x47, + 0x58, 0x68, 0x89, 0x54, 0xCA, 0x88, 0x3F, 0xCE, + 0x0C, 0x93, 0x1D, 0x4C, 0x58, 0xA2, 0xC3, 0x5A, + 0xBE, 0xB1, 0xB0, 0xB1, 0xC2, 0xDF, 0x2F, 0x05, + 0x09, 0x67, 0x05, 0xC4, 0x88, 0xEB, 0xE3, 0xE3, + 0x36, 0xD8, 0x91, 0xD6, 0x05, 0x10, 0x8D, 0x91, + 0x3B, 0x8B, 0x9D, 0x70, 0x9E, 0x63, 0xE8, 0xD5, + 0xAF, 0x3D, 0x9A, 0xA4, 0x82, 0xC3, 0x30, 0x76, + 0x72, 0x7C, 0x8D, 0xA2, 0xC7, 0x0C, 0xD7, 0x55, + 0x30, 0x25, 0x01, 0x70, 0x09, 0xB7, 0x7E, 0x4F, + 0x1E, 0x94, 0x9D, 0xB9, 0x94, 0xCA, 0xF6, 0xF2, + 0x05, 0xB7, 0x9B, 0x65, 0x34, 0x52, 0xE2, 0x96, + 0xAA, 0x58, 0xB2, 0x2D, 0x65, 0x26, 0x58, 0xA7, + 0xDC, 0x4E, 0x6B, 0x95, 0x52, 0x81, 0xF7, 0x97, + 0xB9, 0x01, 0x17, 0x5F, 0xC7, 0xCF, 0xE0, 0x33, + 0x80, 0xF6, 0xC6, 0x45, 0x5A, 0x8C, 0x4F, 0x38, + 0xE2, 0xBC, 0xCB, 0x29, 0x18, 0x9E, 0x52, 0x21, + 0x43, 0x12, 0x03, 0xF3, 0x45, 0xC9, 0xC1, 0x5A, + 0x62, 0x85, 0xAD, 0x12, 0x3F, 0x84, 0x0B, 0x99, + 0x55, 0xE9, 0xE4, 0xA8, 0x36, 0x2B, 0xE2, 0x88, + 0x68, 0xE4, 0xF6, 0xB9, 0x63, 0xAD, 0xB8, 0xFF, + 0xA6, 0xB7, 0x78, 0xD1, 0x6B, 0xD8, 0x94, 0xA3, + 0xB0, 0xE4, 0xC1, 0x0E, 0x5F, 0xC6, 0x7A, 0x3A, + 0x97, 0x46, 0xA0, 0x6C, 0xC0, 0xE2, 0x24, 0xDE, + 0xAF, 0x6D, 0x25, 0xF9, 0x4C, 0x1F, 0xC2, 0x13, + 0xF3, 0x69, 0xDE, 0xBE, 0xE1, 0xCC, 0xA2, 0x61, + 0x38, 0x46, 0xB8, 0x72, 0x5C, 0x43, 0x31, 0x6F, + 0x14, 0x5B, 0x8A, 0xCC, 0xF0, 0x54, 0x7B, 0xBF, + 0xF0, 0x7A, 0x76, 0xF8, 0x32, 0x84, 0x8A, 0xD1, + 0x09, 0x1B, 0x78, 0x77, 0xF0, 0xFE, 0x50, 0x92, + 0x0A, 0xB5, 0xC3, 0x6B, 0x76, 0x94, 0x40, 0xB5, + 0xDB, 0xB6, 0x18, 0x85, 0x91, 0x71, 0x1D, 0x52, + 0xA8, 0x99, 0xB5, 0xCC, 0xD0, 0x18, 0xA4, 0x42, + 0x62, 0x34, 0x3C, 0x78, 0xD6, 0xA5, 0x98, 0x29, + 0x9D, 0x4D, 0xE1, 0xB6, 0xF4, 0xA2, 0x93, 0xED, + 0xB9, 0xB8, 0xE6, 0x88, 0xC7, 0x16, 0xA0, 0x35, + 0xFB, 0x2C, 0x9D, 0x0A, 0x83, 0x0D, 0x3D, 0x6B, + 0xAC, 0xEA, 0x61, 0x05, 0x0A, 0xE6, 0xA7, 0xDD, + 0x3F, 0x08, 0x14, 0x73, 0xCA, 0x0D, 0x84, 0xB8, + 0x22, 0xE2, 0xDF, 0x96, 0xB3, 0x73, 0xE4, 0x20, + 0x13, 0xEE, 0x19, 0x72, 0x22, 0x56, 0x1D, 0x11, + 0xAC, 0xF7, 0xBA, 0x0E, 0xE0, 0xA2, 0x18, 0xEE, + 0x5B, 0xC3, 0xF6, 0x13, 0xAE, 0x6D, 0x42, 0x9B, + 0xB1, 0xCC, 0x8F, 0xDD, 0x04, 0xE9, 0x95, 0x26, + 0x26, 0x2C, 0x09, 0x91, 0xBA, 0x6F, 0xC1, 0x23, + 0x4C, 0x09, 0x77, 0xAF, 0x78, 0x81, 0x3E, 0x05, + 0x12, 0xDE, 0xC8, 0x91, 0xDC, 0x87, 0xB8, 0xB2, + 0x35, 0x81, 0x6E, 0x19, 0xE2, 0xC2, 0x86, 0x0F, + 0x58, 0xFA, 0xE4, 0xE1, 0xBA, 0xF7, 0xB4, 0x22, + 0xEF, 0x0A, 0xFA, 0x53, 0xA5, 0x9B, 0x82, 0x6C, + 0xBA, 0xDF, 0x26, 0x2D, 0x70, 0x07, 0x27, 0xD0, + 0xAB, 0x33, 0xAD, 0x71, 0x08, 0xB3, 0x91, 0xC9, + 0x8A, 0xE0, 0x4F, 0x4C, 0xD6, 0xC5, 0xBA, 0xE0, + 0x7C, 0xE0, 0xBF, 0x4D, 0x01, 0x7A, 0xC8, 0xFC, + 0xE5, 0x03, 0x72, 0x87, 0xA9, 0x30, 0x9A, 0xD4, + 0xA3, 0xD6, 0xE9, 0xB3, 0x08, 0x3E, 0x54, 0xB5, + 0xA6, 0x98, 0xBA, 0x9B, 0x2B, 0xF0, 0x00, 0x0B, + 0x3A, 0xE9, 0xF0, 0xB1, 0x5A, 0xB9, 0x87, 0x33, + 0x42, 0x77, 0x03, 0xC8, 0x57, 0xBD, 0x6C, 0x59, + 0x92, 0xC3, 0xDE, 0xA8, 0x71, 0xA6, 0x41, 0xF4, + 0xDE, 0x6D, 0x49, 0xAB, 0xBD, 0x39, 0x1E, 0x8A, + 0xEF, 0xCD, 0x59, 0x72, 0xC3, 0x3D, 0x74, 0x63, + 0xFC, 0x41, 0xFA, 0x4C, 0xB6, 0x79, 0xA9, 0xBC, + 0x7B, 0x9E, 0xD8, 0x1D, 0x0E, 0x23, 0xA7, 0x66, + 0x39, 0x3D, 0x7E, 0xAA, 0xC0, 0x3E, 0x3B, 0x05, + 0x3F, 0xC9, 0x11, 0xC4, 0x92, 0xCC, 0xD3, 0xF2, + 0xDB, 0xB9, 0xEF, 0x13, 0x07, 0x70, 0xC4, 0x68, + 0x3C, 0x2C, 0x07, 0x23, 0xE6, 0xA9, 0x09, 0xC3, + 0xBE, 0xBC, 0x9F, 0x1E, 0xA8, 0x58, 0xCC, 0xEE, + 0x9D, 0xC8, 0xC8, 0x7B, 0x53, 0xE1, 0x93, 0x8A, + 0x26, 0x79, 0x6C, 0x9D, 0x7B, 0x57, 0x61, 0x5E, + 0x42, 0xD2, 0x64, 0x5F, 0x16, 0xC3, 0x40, 0xD8, + 0xF0, 0x92, 0x6D, 0x95, 0x5E, 0x4B, 0x3C, 0x48, + 0xA6, 0x59, 0x57, 0xF4, 0x30, 0x51, 0x1B, 0x45, + 0x00, 0x02, 0x65, 0xAE, 0x56, 0x16, 0xE5, 0xD5, + 0x1E, 0x65, 0x5D, 0xEF, 0xA0, 0x3F, 0x86, 0x76, + 0x7B, 0x35, 0xE9, 0xF5, 0x14, 0x48, 0xD7, 0x99, + 0x4C, 0x91, 0x01, 0xA4, 0x51, 0xD1, 0x6B, 0x48, + 0x3A, 0x42, 0x25, 0x47, 0xE7, 0xFD, 0x7E, 0x21, + 0x32, 0xB7, 0xCB, 0xF7, 0xE5, 0x36, 0x95, 0x64, + 0x12, 0x73, 0xB2, 0xA8, 0xEE, 0x2D, 0x88, 0xF9, + 0x8D, 0xFE, 0xDB, 0xB3, 0xD7, 0xD1, 0x7E, 0x28, + 0xC2, 0x91, 0x49, 0xC0, 0xC0, 0x65, 0x25, 0xF6, + 0xDD, 0xB2, 0x39, 0xEF, 0x2C, 0x75, 0xA5, 0xBA, + 0x18, 0x81, 0xB2, 0x4D, 0x8D, 0x62, 0x29, 0x71, + 0x65, 0x88, 0x4E, 0x25, 0xCE, 0x9F, 0x91, 0xB9, + 0xB9, 0xD9, 0xF2, 0xA4, 0x0B, 0xA3, 0x3B, 0x84, + 0xD9, 0xD4, 0x3A, 0x94, 0xA6, 0x1B, 0x93, 0x71, + 0x33, 0x6C, 0x4C, 0x9F, 0x30, 0x3B, 0x18, 0x3D, + 0xAC, 0x15, 0x6C, 0x49, 0x9F, 0xC4, 0x86, 0xFF, + 0x5F, 0x8C, 0xCF, 0xCB, 0xE7, 0x70, 0x17, 0x70, + 0x65, 0x25, 0xBB, 0x1A, 0xD0, 0xE3, 0x10, 0x9B, + 0x1D, 0x19, 0x4D, 0x19, 0x58, 0x45, 0xB7, 0x41, + 0xFF, 0xE5, 0xC9, 0x05, 0xDC, 0xC2, 0x4F, 0x6D, + 0x0D, 0x68, 0x37, 0xFC, 0x4D, 0x5D, 0x9A, 0x85, + 0xFA, 0x40, 0x2F, 0xBE, 0x56, 0x15, 0x13, 0x9A, + 0x64, 0x9E, 0x4C, 0x9C, 0xE0, 0x8F, 0x18, 0xDF, + 0x53, 0x47, 0x19, 0xA1, 0x03, 0x66, 0xD3, 0x32, + 0xFE, 0x0D, 0xC0, 0x40, 0x94, 0xA2, 0x00, 0xFB, + 0x53, 0xF7, 0x71, 0xC4, 0xD4, 0x47, 0x29, 0x1A, + 0x7D, 0x02, 0x16, 0x3F, 0x56, 0x96, 0x2B, 0x9E, + 0x57, 0x17, 0x02, 0x9A, 0x5F, 0x27, 0x93, 0xD6, + 0x48, 0xFB, 0xA5, 0xE9, 0x14, 0xD9, 0xC1, 0x45, + 0x63, 0x38, 0xB2, 0xB6, 0xCA, 0xBD, 0x6A, 0xCE, + 0x80, 0xB4, 0x5C, 0xC8, 0xD7, 0x6D, 0x09, 0xA7, + 0x27, 0xF9, 0x12, 0x88, 0x3E, 0x3C, 0x79, 0x48, + 0xCF, 0xE6, 0x54, 0x12, 0x8D, 0x91, 0x9B, 0x5B, + 0xF2, 0x74, 0x38, 0xE6, 0x96, 0xC0, 0xAF, 0xED, + 0x96, 0x20, 0x6F, 0xD5, 0xB3, 0x95, 0x82, 0xB1, + 0xE1, 0x38, 0x46, 0xF4, 0x85, 0xAD, 0x9F, 0x68, + 0x4C, 0x76, 0x93, 0x9E, 0x08, 0xDD, 0xAC, 0x36, + 0x2C, 0x08, 0x2A, 0xA7, 0x21, 0x56, 0x62, 0xBE, + 0x9F, 0x46, 0x6B, 0xA0, 0x36, 0xC7, 0xC9, 0x6A, + 0xEF, 0xE8, 0xE1, 0x6A, 0x42, 0xA1, 0x35, 0x64, + 0xCF, 0xCA, 0xF6, 0x0E, 0x3C, 0x9E, 0xBB, 0xF9, + 0x88, 0xA3, 0x0A, 0xAC, 0x81, 0x3D, 0x5E, 0x82, + 0xB8, 0x71, 0x46, 0xC6, 0xAE, 0x14, 0x71, 0xFE, + 0x47, 0x33, 0xC3, 0xA5, 0x46, 0x02, 0x97, 0x5A, + 0x44, 0x4E, 0x00, 0x38, 0x8C, 0x24, 0xB5, 0x0E, + 0x19, 0x14, 0xFD, 0xF4, 0x89, 0x99, 0x72, 0x19, + 0xEB, 0x55, 0x5C, 0xC9, 0x62, 0xE8, 0xFD, 0x92, + 0x03, 0x44, 0xB9, 0x2E, 0x01, 0x99, 0x48, 0xE0, + 0xD9, 0xB0, 0xD9, 0x5F, 0x75, 0x7E, 0xB2, 0xD0, + 0xD5, 0xE8, 0xBD, 0xF0, 0x6C, 0xCD, 0x4F, 0x54, + 0x6C, 0x1D, 0xB1, 0x12, 0x82, 0x6E, 0x53, 0xE7, + 0x67, 0xD8, 0xDC, 0xE8, 0xD4, 0xB5, 0x68, 0x51, + 0x15, 0xC6, 0x26, 0x44, 0x65, 0xB4, 0x70, 0x4D, + 0xD6, 0x3F, 0x63, 0xDC, 0xEE, 0x70, 0x71, 0x13, + 0xB2, 0x52, 0x5B, 0xF0, 0x5E, 0xCD, 0x71, 0x44, + 0x46, 0x83, 0x8F, 0x47, 0xC6, 0xE1, 0x48, 0x8A, + 0xD5, 0xCF, 0xBE, 0x1F, 0x91, 0x76, 0x91, 0xE5, + 0x9F, 0x2A, 0xB0, 0x63, 0x6F, 0x37, 0x32, 0x4B, + 0x54, 0xD0, 0x7F, 0x91, 0x24, 0xD7, 0x8F, 0xB2, + 0xF4, 0xD0, 0x44, 0x55, 0xD5, 0x88, 0x10, 0xD1, + 0xE5, 0x1D, 0xF8, 0xF8, 0x73, 0xD5, 0xA8, 0x37, + 0x30, 0xAD, 0x0E, 0xF0, 0x75, 0x3A, 0x0B, 0xFC, + 0xD8, 0x97, 0x78, 0xA1, 0x38, 0xFC, 0x55, 0x97, + 0x31, 0x7D, 0x84, 0x55, 0x7C, 0xFF, 0x77, 0x90, + 0x1D, 0xE5, 0x40, 0x14, 0x0E, 0x58, 0xEF, 0xA4, + 0xC2, 0x9D, 0x52, 0xBC, 0x96, 0x41, 0xF8, 0x36, + 0x2A, 0xB6, 0xF9, 0x68, 0x45, 0x5D, 0xB1, 0xDF, + 0x02, 0x24, 0x3E, 0xF4, 0x59, 0x62, 0x1C, 0x38, + 0x45, 0x5E, 0x7C, 0xB6, 0xC8, 0x08, 0x55, 0x4C, + 0x3D, 0x46, 0xA2, 0x2F, 0x0D, 0xDD, 0x56, 0x1A, + 0x9D, 0x67, 0xC8, 0x48, 0x62, 0xA2, 0x5B, 0xD6, + 0x06, 0x98, 0x72, 0x41, 0xAD, 0x89, 0x59, 0x0B, + 0xBD, 0x34, 0x3A, 0xBA, 0xF3, 0x87, 0xB5, 0xA4, + 0xC6, 0x4F, 0x3C, 0x31, 0x22, 0x5F, 0x7F, 0x8E, + 0x07, 0x57, 0x36, 0x4B, 0x91, 0x10, 0x9A, 0x57, + 0x6A, 0x97, 0x7E, 0x82, 0x8A, 0x79, 0x8B, 0xC0, + 0x4A, 0x74, 0xB0, 0x36, 0x26, 0xE4, 0x61, 0xB7, + 0x09, 0x23, 0x3B, 0xFF, 0xAC, 0x93, 0x0C, 0x57, + 0x46, 0x67, 0xFA, 0xD0, 0x5C, 0x23, 0x66, 0xC5, + 0xB2, 0x84, 0x46, 0xDE, 0x00, 0x90, 0xD1, 0x7F, + 0x5E, 0x7F, 0x90, 0x3B, 0xEC, 0x6E, 0xF6, 0xB6, + 0x97, 0x31, 0x6D, 0x78, 0x29, 0x18, 0xF8, 0x3E, + 0xC5, 0x44, 0xB9, 0x9D, 0x07, 0x0F, 0x43, 0x35, + 0x63, 0xCC, 0x9C, 0xBE, 0xAD, 0x53, 0x74, 0xF6, + 0xE0, 0x34, 0x77, 0x86, 0x9B, 0xFD, 0x38, 0xD0, + 0xF8, 0xB1, 0xEC, 0x49, 0x21, 0xF8, 0xAD, 0x06, + 0x55, 0x04, 0x70, 0x7B, 0x55, 0x30, 0xC9, 0xBF, + 0xD3, 0x30, 0x21, 0x06, 0x83, 0xB8, 0xCA, 0x57, + 0x4E, 0xFC, 0x5E, 0x05, 0xF3, 0x6A, 0x8A, 0x14, + 0x16, 0xF9, 0xD3, 0xF3, 0x09, 0x21, 0x8D, 0x1D, + 0xEC, 0xED, 0x5C, 0x9A, 0x4E, 0xDF, 0x90, 0xBE, + 0xC6, 0x7B, 0x2E, 0x85, 0x48, 0xDF, 0xBD, 0xE0, + 0xA7, 0xB3, 0x88, 0xF9, 0xDA, 0x17, 0x7A, 0x4A, + 0xAC, 0x86, 0xEF, 0xA3, 0xA2, 0x2D, 0xD1, 0x3F, + 0xB0, 0x68, 0x32, 0x6A, 0x46, 0x4E, 0x86, 0x5F, + 0x9C, 0xE0, 0x40, 0xE4, 0x3F, 0x72, 0xCC, 0x77, + 0x22, 0xFF, 0xBE, 0x8D, 0x82, 0xFB, 0x77, 0x2A, + 0x6B, 0xB0, 0x3C, 0x8E, 0x44, 0xD8, 0xAB, 0x79, + 0x3C, 0x9D, 0xCD, 0x49, 0x61, 0xEE, 0x3E, 0x74, + 0x9E, 0x8C, 0x5B, 0x6C, 0xB3, 0x81, 0x07, 0x83, + 0xFA, 0xB7, 0x77, 0xAA, 0x65, 0x71, 0x9C, 0xDB, + 0x70, 0xC7, 0x5E, 0x6E, 0x55, 0xBE, 0xB3, 0xEA, + 0xAB, 0xDC, 0x49, 0xE0, 0x42, 0xC6, 0xDF, 0x20, + 0x25, 0xE1, 0x19, 0xCD, 0xAA, 0x32, 0xE5, 0x48, + 0x72, 0xD6, 0x8C, 0xFE, 0xFA, 0x97, 0x40, 0x4D, + 0x9D, 0x1F, 0x15, 0xA7, 0xD9, 0xF3, 0x61, 0x81, + 0x7E, 0x7F, 0x36, 0xFA, 0x49, 0x0D, 0xB1, 0x45, + 0x3C, 0x0C, 0xD9, 0x1E, 0x53, 0xF9, 0xE6, 0x12, + 0x2A, 0xDE, 0x3A, 0x81, 0xD0, 0x5F, 0x6E, 0x63, + 0x30, 0x21, 0x7D, 0xAA, 0x26, 0x67, 0xC8, 0x54, + 0x5B, 0x70, 0x24, 0x6F, 0xFF, 0xA9, 0xB6, 0x07, + 0x87, 0x75, 0x31, 0x00, 0x96, 0x87, 0x06, 0x9B, + 0xAD, 0x52, 0xBB, 0x30, 0x8E, 0xD0, 0x93, 0xD6, + 0x14, 0x64, 0xBE, 0x38, 0x7E, 0xA7, 0x84, 0xDD, + 0x81, 0x2F, 0x03, 0x61, 0x71, 0x18, 0x51, 0x3F, + 0x1A, 0x64, 0xBD, 0xF2, 0xE8, 0xD8, 0x79, 0x2F, + 0xC5, 0x3B, 0xFB, 0xF7, 0x0A, 0x77, 0xFA, 0xB3, + 0xDA, 0x99, 0xCE, 0x50, 0xAD, 0x10, 0xA3, 0xFC, + 0x14, 0xBC, 0x0D, 0x6B, 0xF6, 0x69, 0xB4, 0x3E, + 0xEF, 0x73, 0xB2, 0xA7, 0x2B, 0xE8, 0x8A, 0xC8, + 0x54, 0xBD, 0x2C, 0x2D, 0x49, 0x59, 0x85, 0x8A, + 0xE7, 0xE1, 0x63, 0x48, 0x5F, 0xE7, 0x95, 0x78, + 0x64, 0xF2, 0xA3, 0xD3, 0xA7, 0x9F, 0x0A, 0x56, + 0x97, 0xA1, 0x57, 0xA9, 0xA0, 0x8A, 0x80, 0x13, + 0x38, 0xD2, 0xD0, 0xAF, 0x03, 0x16, 0x0D, 0x51, + 0xF0, 0x38, 0x48, 0xEB, 0x0F, 0x61, 0x36, 0xE2, + 0xC1, 0x5C, 0xD4, 0x76, 0xBF, 0xF1, 0x83, 0xCA, + 0xD0, 0xA6, 0x91, 0xCE, 0xCA, 0x02, 0x7A, 0x9D, + 0x92, 0x6B, 0x83, 0x10, 0x40, 0x1A, 0xD7, 0xAC, + 0xC2, 0x6F, 0x8D, 0x87, 0x5A, 0x9E, 0x53, 0xDB, + 0x32, 0xA3, 0x91, 0x00, 0x76, 0x9C, 0xEE, 0x62, + 0x54, 0x98, 0x9F, 0xF5, 0x68, 0x35, 0x8B, 0xB7, + 0x20, 0x2D, 0x24, 0x9E, 0x4E, 0x4A, 0xC9, 0x08, + 0x70, 0x97, 0x84, 0x7B, 0xCD, 0xFC, 0xF4, 0xF5, + 0x76, 0x4F, 0xDA, 0xBC, 0xDB, 0x59, 0xCF, 0x07, + 0x3A, 0x84, 0x9B, 0x18, 0xEE, 0xAB, 0x4E, 0xD6, + 0x4A, 0x92, 0x94, 0xD2, 0xD9, 0x3E, 0x08, 0x2D, + 0xB4, 0x1E, 0xB8, 0x71, 0xE5, 0x82, 0xFD, 0x7B, + 0x67, 0x94, 0xF8, 0x15, 0x61, 0xC6, 0xFF, 0x0F, + 0xA5, 0xFF, 0x30, 0x57, 0x18, 0x6A, 0xDA, 0xEF, + 0xB8, 0x44, 0xF9, 0x53, 0x63, 0x13, 0x70, 0xB4, + 0xB5, 0x1D, 0x51, 0x29, 0xF6, 0x9F, 0x55, 0xC6, + 0x29, 0xD9, 0x1C, 0x06, 0x67, 0x4F, 0x48, 0x03, + 0xF6, 0x32, 0xEA, 0x89, 0x19, 0x1C, 0xC8, 0x6F, + 0x3A, 0x0B, 0x02, 0x60, 0x03, 0x4C, 0x9B, 0x89, + 0xDB, 0x96, 0x6A, 0x16, 0x18, 0x67, 0xEF, 0x8D, + 0x1C, 0xE7, 0xDC, 0xC8, 0xDE, 0xA6, 0x3D, 0xDF, + 0xF7, 0xB4, 0x06, 0x4E, 0xA0, 0x0A, 0xA6, 0xD9, + 0x7F, 0xFA, 0x5C, 0xF3, 0x2E, 0x2E, 0x21, 0x40, + 0x6A, 0xA9, 0x50, 0x9D, 0xB1, 0xF4, 0x4F, 0xA0, + 0x03, 0xFF, 0x08, 0xA6, 0xA2, 0x39, 0xDE, 0x23, + 0x6B, 0x53, 0xB4, 0x08, 0x51, 0x31, 0xE8, 0xA5, + 0xAD, 0xBD, 0x97, 0xB6, 0x7F, 0xCF, 0x07, 0x65, + 0x3F, 0x88, 0xFD, 0x51, 0xD6, 0xCF, 0x34, 0x22, + 0x01, 0xCA, 0x8B, 0xE7, 0x07, 0xD3, 0x1D, 0xC7, + 0xB1, 0xF9, 0xF5, 0xB5, 0x73, 0xEE, 0x04, 0x15, + 0x6D, 0xDC, 0xC3, 0x64, 0xEF, 0xD0, 0x29, 0x37, + 0xB6, 0xDE, 0xBE, 0x13, 0xAE, 0x62, 0x3C, 0x7C, + 0xCB, 0xAC, 0x13, 0xF0, 0x41, 0x61, 0xC5, 0x48, + 0x9E, 0xFC, 0x5A, 0x4F, 0x8E, 0x00, 0xF1, 0xB0, + 0xEE, 0x59, 0x01, 0x83, 0x21, 0x79, 0xD9, 0x94, + 0x01, 0xBB, 0x77, 0x29, 0x0D, 0x6B, 0x42, 0x6C, + 0xA7, 0x59, 0x48, 0x0C, 0x4B, 0xEB, 0xD2, 0x3C, + 0xF9, 0x00, 0x47, 0x5F, 0x34, 0xFE, 0x0E, 0x06, + 0x99, 0x25, 0xED, 0xCB, 0x19, 0x40, 0x76, 0xA4, + 0xAA, 0xEF, 0x64, 0x09, 0xC2, 0x08, 0x20, 0xBC, + 0x67, 0xC6, 0xAD, 0x62, 0x54, 0xC2, 0x0E, 0x32, + 0xC9, 0xB0, 0x95, 0x83, 0xCD, 0xF9, 0xA9, 0x17, + 0x9E, 0xE2, 0xDD, 0x02, 0xB4, 0x3C, 0xD6, 0x9F, + 0x2E, 0xC2, 0x35, 0x93, 0xA1, 0xB1, 0xA9, 0x58, + 0x44, 0x0C, 0x58, 0x2D, 0x90, 0xA6, 0xD2, 0x41, + 0x4D, 0xFC, 0xC8, 0x48, 0xEF, 0x4E, 0x82, 0x4E, + 0x4D, 0xFF, 0x28, 0x09, 0xF7, 0xD5, 0xCE, 0x8E, + 0x5B, 0x4C, 0xBB, 0x48, 0xCB, 0xF4, 0x58, 0x11, + 0x35, 0x8F, 0x5D, 0x9E, 0xCF, 0x2F, 0xFD, 0x73, + 0xC4, 0xA2, 0x9E, 0xAD, 0xF7, 0xDE, 0x41, 0xAB, + 0xC2, 0x35, 0xFD, 0x37, 0x36, 0x51, 0x27, 0xE2, + 0x8D, 0xC2, 0xE1, 0xE1, 0x5F, 0x61, 0xB1, 0xF3, + 0xA7, 0x56, 0xD1, 0x0B, 0x7C, 0xA5, 0xCE, 0xA7, + 0xE7, 0x6B, 0x5A, 0xF8, 0x40, 0xA2, 0x03, 0xCF, + 0xD3, 0x07, 0x62, 0x2D, 0xC8, 0x22, 0x3F, 0x28, + 0x6D, 0xD5, 0x81, 0x6B, 0x08, 0x79, 0x2B, 0x0C, + 0x96, 0x7E, 0x5C, 0x0E, 0xA0, 0xDB, 0xAA, 0x9D, + 0xD3, 0xAD, 0xDB, 0xB0, 0xE5, 0x07, 0x9C, 0x92, + 0xA4, 0x52, 0xE1, 0x1F, 0x76, 0xAD, 0x44, 0xD4, + 0x9F, 0xDB, 0xD9, 0x6A, 0x2D, 0x06, 0x92, 0x50, + 0x71, 0xD2, 0xE4, 0x9B, 0xCA, 0xC9, 0x28, 0x48, + 0x76, 0x98, 0x75, 0x9E, 0x6D, 0xB2, 0x5A, 0xDF, + 0x13, 0x65, 0x89, 0x14, 0xFE, 0x08, 0x3E, 0x0D, + 0xFF, 0x99, 0x90, 0x1E, 0x71, 0xCB, 0x3D, 0x4B, + 0x4A, 0xAA, 0x31, 0x33, 0xD1, 0x4C, 0x87, 0x7E, + 0x0E, 0xAA, 0x89, 0x28, 0x4C, 0x83, 0x49, 0x31, + 0xBB, 0x67, 0x78, 0x9B, 0x02, 0x7C, 0x42, 0x45, + 0x70, 0x4B, 0xD2, 0x02, 0xAB, 0x30, 0x5C, 0x9F, + 0xB8, 0x87, 0xEC, 0xFE, 0x98, 0xC2, 0x5F, 0x3A, + 0xF2, 0x6D, 0xBF, 0x50, 0xBC, 0x51, 0x4B, 0x09, + 0x2B, 0x98, 0x86, 0xC1, 0x1A, 0x9B, 0xD3, 0x66, + 0x49, 0x48, 0xDC, 0x65, 0x69, 0xD3, 0xB0, 0x2C, + 0x43, 0xB1, 0xE2, 0xF2, 0x27, 0xAE, 0xD2, 0xAD, + 0xF5, 0xA0, 0xFC, 0x86, 0x83, 0xF8, 0xB8, 0xBA, + 0x50, 0x0C, 0x29, 0x09, 0x3B, 0xF2, 0xF5, 0x3C, + 0x72, 0x26, 0x81, 0x6B, 0xB2, 0xBA, 0xC3, 0x80, + 0xA3, 0xD5, 0x20, 0x99, 0x8A, 0xBB, 0xAC, 0xB8, + 0xDA, 0xA7, 0x30, 0xA4, 0xCE, 0x2D, 0xBB, 0xDC, + 0xF9, 0xF3, 0xD4, 0xB5, 0xC7, 0xEA, 0xC0, 0x3F, + 0xE4, 0x0D, 0x8B, 0xF8, 0x3A, 0xCF, 0x84, 0x11, + 0x3D, 0xBC, 0x4C, 0x0F, 0x30, 0x5D, 0xE1, 0x4C, + 0x91, 0x0F, 0xF1, 0x23, 0xDA, 0x5A, 0xDC, 0x0A, + 0x9F, 0x88, 0xFC, 0x8B, 0x85, 0x7E, 0x95, 0x36, + 0x7D, 0x82, 0x0F, 0xE2, 0x2A, 0x71, 0xB1, 0x50, + 0xA6, 0xF9, 0xAB, 0xF6, 0x0B, 0x30, 0xDA, 0x8E, + 0x6F, 0xF3, 0xDD, 0xC3, 0x30, 0xAF, 0xFB, 0x08, + 0x83, 0xC7, 0x16, 0x99, 0x00, 0x4F, 0x99, 0x01, + 0x2B, 0x8A, 0x9F, 0x40, 0x2B, 0xC4, 0x91, 0x10, + 0x65, 0x68, 0x8C, 0x7E, 0xFA, 0x45, 0xC6, 0x96, + 0x75, 0xC5, 0x4D, 0x34, 0x92, 0xA2, 0x49, 0x01, + 0xC4, 0x07, 0x4F, 0x6E, 0xCA, 0x85, 0xD5, 0xEE, + 0x5A, 0xF2, 0x2F, 0x98, 0x53, 0x69, 0x95, 0xB3, + 0xD2, 0xC6, 0x1C, 0x28, 0x88, 0x43, 0xC5, 0xF1, + 0x77, 0x1A, 0x80, 0x46, 0xE8, 0xEA, 0x7E, 0x53, + 0xB8, 0xC0, 0x02, 0x24, 0xF0, 0x28, 0xC6, 0xDB, + 0x4F, 0xF5, 0x01, 0x0F, 0xF2, 0x40, 0xFB, 0x38, + 0x28, 0xDA, 0xD3, 0x79, 0x5C, 0xA5, 0x98, 0x76, + 0x7B, 0x1D, 0xF3, 0xE4, 0x17, 0x62, 0xAD, 0x30, + 0xC8, 0x8B, 0xDD, 0xE8, 0xB5, 0xDE, 0x22, 0xF2, + 0xE4, 0x98, 0x6C, 0xCC, 0x07, 0x89, 0x83, 0x4E, + 0xD7, 0xB6, 0xF2, 0x6A, 0x19, 0xD5, 0x2B, 0xC5, + 0x9C, 0x28, 0xC5, 0x71, 0x4F, 0x6D, 0xCB, 0xD9, + 0x96, 0x98, 0xF5, 0x0D, 0xA1, 0x96, 0x92, 0x5F, + 0x2F, 0xCE, 0x88, 0xAF, 0xB7, 0x41, 0x7E, 0x00, + 0x56, 0x01, 0x53, 0x7C, 0xC8, 0x35, 0xF4, 0xA5, + 0x9F, 0xC9, 0xBA, 0x03, 0xB3, 0x69, 0x99, 0x40, + 0x94, 0x3D, 0x95, 0xE0, 0xDD, 0xA6, 0x5F, 0x7A, + 0xC7, 0x04, 0xC8, 0xBF, 0x37, 0x12, 0x07, 0x15, + 0x58, 0x00, 0x0F, 0xB4, 0x28, 0x8D, 0x48, 0x35, + 0xA6, 0x12, 0xC3, 0x88, 0xCE, 0xEA, 0x6A, 0x06, + 0xE6, 0x6E, 0x1B, 0x2D, 0x25, 0x9F, 0x28, 0x03, + 0x66, 0xDC, 0xA8, 0x6D, 0xA7, 0x20, 0x35, 0x40, + 0x58, 0x57, 0xD1, 0xB8, 0xDB, 0x5D, 0xF0, 0x67, + 0x2E, 0x30, 0xF5, 0xB2, 0x99, 0x4E, 0x91, 0x06, + 0x06, 0x26, 0xFD, 0x72, 0xCF, 0xDE, 0x67, 0x49, + 0xDB, 0x6B, 0x0D, 0x7F, 0xAF, 0x89, 0x43, 0x07, + 0x1F, 0xB6, 0x56, 0x42, 0x99, 0xDE, 0xDF, 0x56, + 0xF8, 0xED, 0xB9, 0xB3, 0xE6, 0x77, 0x91, 0x30, + 0xC2, 0x27, 0x90, 0xDE, 0x79, 0xE7, 0x00, 0x7D, + 0xE4, 0xAE, 0x2C, 0x1E, 0xB5, 0x46, 0x2C, 0x4E, + 0x79, 0x8A, 0x08, 0xD5, 0xF1, 0xF1, 0x2C, 0xAF, + 0xA9, 0x80, 0x91, 0x91, 0x79, 0xAE, 0x25, 0x87, + 0xC2, 0xFF, 0x18, 0x86, 0x3E, 0x1D, 0x1D, 0xA2, + 0x75, 0x41, 0xED, 0xEF, 0xE6, 0x4A, 0x26, 0xFE, + 0xD4, 0x75, 0xE5, 0x82, 0x90, 0x58, 0x6E, 0x7F, + 0x0C, 0x1D, 0xB5, 0xB5, 0xF2, 0x3B, 0x19, 0x6E, + 0x07, 0xF8, 0x0C, 0xF0, 0x0C, 0x08, 0x9D, 0x51, + 0x9A, 0x77, 0xE7, 0x98, 0x4E, 0xB7, 0x50, 0x69, + 0xCA, 0x8B, 0x8D, 0xCD, 0xC2, 0xFC, 0xD9, 0xB2, + 0xA0, 0x34, 0x75, 0xB3, 0x60, 0xB3, 0xB0, 0x2C, + 0x11, 0xA6, 0x15, 0xB6, 0x0E, 0x4D, 0x8F, 0x41, + 0x94, 0x0A, 0x7D, 0xC2, 0x74, 0x1F, 0xA3, 0x58, + 0xFA, 0x1D, 0x26, 0x55, 0x85, 0x62, 0xFD, 0x93, + 0x60, 0x60, 0x32, 0x15, 0x75, 0xCC, 0x33, 0x4E, + 0x21, 0x35, 0x4B, 0x8C, 0x30, 0x13, 0xE7, 0x24, + 0xEF, 0xEB, 0x2B, 0x14, 0x48, 0x72, 0x7D, 0x83, + 0x8C, 0x70, 0x99, 0x71, 0x0B, 0x1F, 0x34, 0xF2, + 0xEF, 0x96, 0xEF, 0xFD, 0x8D, 0xB8, 0x0E, 0x35, + 0x55, 0x5C, 0x38, 0x5B, 0x72, 0xDD, 0x0A, 0xE2, + 0x62, 0x93, 0x0B, 0x61, 0x5E, 0x71, 0x9A, 0x90, + 0x3F, 0x2E, 0x53, 0x2E, 0xB7, 0xDC, 0xA0, 0xD1, + 0xE6, 0xCD, 0x18, 0x14, 0x08, 0x5F, 0x7A, 0x98, + 0x77, 0xF9, 0x36, 0xBE, 0xB0, 0xF7, 0x39, 0x42, + 0xCB, 0xC4, 0x44, 0xEB, 0xFB, 0x49, 0xF1, 0xE0, + 0x43, 0xF9, 0x35, 0x09, 0x68, 0x7D, 0x2C, 0x87, + 0x3D, 0x09, 0xBF, 0x80, 0x26, 0x11, 0x2A, 0xB7, + 0x6E, 0x58, 0x44, 0xA9, 0x5F, 0xEB, 0x42, 0xC5, + 0xF2, 0x09, 0xE0, 0x2F, 0xC5, 0x1E, 0xA5, 0x74, + 0xF1, 0xE4, 0xBD, 0x14, 0xBC, 0x05, 0x93, 0x74, + 0xA2, 0x74, 0x35, 0x3A, 0x4A, 0x76, 0x54, 0xE5, + 0x9D, 0xF0, 0x27, 0x18, 0x0C, 0x7B, 0xF8, 0x90, + 0xB0, 0x86, 0x30, 0x12, 0x9D, 0xE2, 0xF7, 0xA7, + 0x07, 0xB1, 0xFF, 0x1B, 0x5C, 0xBD, 0xA7, 0xDB, + 0x6D, 0xE7, 0xDF, 0x3B, 0xD9, 0xFA, 0xB1, 0x5D, + 0xBB, 0x0F, 0x85, 0xB2, 0x47, 0x10, 0x48, 0xE8, + 0x3A, 0xF8, 0xFA, 0x56, 0xD9, 0x2D, 0x4A, 0xCA, + 0x40, 0xF4, 0xE4, 0x78, 0x36, 0x41, 0xD5, 0x23, + 0x6F, 0x9D, 0x4F, 0xDB, 0x3C, 0x09, 0x3E, 0x5F, + 0x5D, 0x81, 0xCA, 0x5E, 0xA3, 0x0A, 0x4C, 0x86, + 0xD3, 0x2F, 0x22, 0x12, 0x0A, 0x2D, 0x39, 0xD9, + 0xAA, 0x10, 0xB5, 0x57, 0x84, 0x18, 0x9D, 0x2E, + 0x2A, 0xA6, 0x98, 0xB4, 0x61, 0xFE, 0x92, 0xEB, + 0x3F, 0xB3, 0x1B, 0x78, 0xAC, 0x6E, 0xB9, 0xF4, + 0xA2, 0xD1, 0xB2, 0x29, 0x53, 0x73, 0xF1, 0x3C, + 0x3E, 0x84, 0x05, 0x11, 0xCD, 0x4E, 0x85, 0x6D, + 0xF2, 0x90, 0xA6, 0xBB, 0x18, 0x32, 0x20, 0xA4, + 0x4D, 0xA8, 0x3D, 0x11, 0x8B, 0xCA, 0x5C, 0xEB, + 0x5B, 0xF2, 0xC8, 0x2E, 0xA3, 0xD4, 0x34, 0x89, + 0xF4, 0xB0, 0x2B, 0xBC, 0x0C, 0x5F, 0x16, 0xAA, + 0x38, 0x88, 0x90, 0xCD, 0xEE, 0x69, 0xC2, 0x1F, + 0x35, 0x28, 0x85, 0xB9, 0x15, 0x0A, 0x18, 0xE6, + 0x84, 0x72, 0xD1, 0x5B, 0x65, 0xAE, 0x7E, 0x11, + 0x16, 0xCD, 0x89, 0x13, 0xA5, 0x6D, 0x81, 0xF5, + 0x54, 0xC8, 0x6B, 0xDC, 0x8E, 0x2F, 0x73, 0x54, + 0x52, 0x62, 0x34, 0x30, 0x34, 0xA3, 0x41, 0x91, + 0x5D, 0x1E, 0x57, 0xA2, 0xAD, 0x4C, 0x1D, 0xC2, + 0x01, 0x0D, 0x60, 0xC3, 0x6B, 0x27, 0xFC, 0x06, + 0x02, 0xAB, 0x6E, 0x6E, 0x42, 0x6E, 0x2C, 0x91, + 0x4E, 0xDA, 0x59, 0xBE, 0x7E, 0xA3, 0x15, 0x5E, + 0xBE, 0xB8, 0x6A, 0xE9, 0x26, 0x09, 0xD2, 0xFB, + 0x77, 0xE8, 0x41, 0x19, 0xB4, 0x7E, 0x53, 0x29, + 0x8D, 0xA5, 0xDC, 0x84, 0xD9, 0x10, 0xAA, 0xF4, + 0x99, 0x0D, 0xDA, 0x73, 0x0A, 0x14, 0x4B, 0xB1, + 0x53, 0x80, 0x86, 0x2C, 0x10, 0x54, 0x61, 0x33, + 0xD4, 0x26, 0xFB, 0xE1, 0xA5, 0xF5, 0x38, 0xEC, + 0x1B, 0xEF, 0x95, 0x8E, 0x88, 0xA7, 0x16, 0xDC, + 0x22, 0xAF, 0xBC, 0x39, 0x41, 0x19, 0xAA, 0xFC, + 0xE3, 0xE4, 0xC8, 0x90, 0xF0, 0xD0, 0x35, 0x8F, + 0x3A, 0xF6, 0x00, 0xDB, 0x50, 0x23, 0x80, 0xAF, + 0x7A, 0x3D, 0x55, 0x45, 0x7A, 0x32, 0x53, 0x4F, + 0xF6, 0x86, 0x28, 0x2D, 0xE4, 0x9C, 0x7B, 0xA1, + 0x4F, 0x68, 0xBF, 0xD6, 0xD8, 0x97, 0xCB, 0xF9, + 0x15, 0xE4, 0x88, 0x35, 0xD1, 0x3D, 0xE4, 0x9A, + 0xA4, 0x47, 0xEB, 0x44, 0x4C, 0x92, 0x22, 0x6F, + 0x2D, 0xBE, 0x4B, 0xFE, 0x96, 0xE2, 0x2D, 0x5A, + 0x03, 0xCB, 0x6E, 0x91, 0xBE, 0x73, 0x14, 0xEF, + 0x8B, 0xAC, 0x65, 0x09, 0xDA, 0x68, 0xA9, 0xE3, + 0x08, 0xB1, 0x17, 0x9A, 0xAB, 0x88, 0x1F, 0x7B, + 0x48, 0xAF, 0xB0, 0xBA, 0x2B, 0x92, 0x42, 0x1D, + 0x92, 0x26, 0x17, 0xEE, 0x58, 0x3E, 0x36, 0xAF, + 0xB7, 0x5C, 0x75, 0x79, 0x77, 0xB3, 0xB0, 0x96, + 0x87, 0x46, 0x80, 0x95, 0x91, 0x7A, 0x22, 0xC4, + 0x5E, 0xBB, 0xEA, 0xDD, 0xD6, 0x11, 0x1E, 0xAB, + 0x1F, 0x09, 0x7D, 0x9D, 0x2F, 0x2D, 0xD4, 0x4E, + 0x3C, 0x33, 0x5D, 0x6F, 0xD3, 0x54, 0xD1, 0xD0, + 0x4F, 0x2A, 0x12, 0x07, 0x2D, 0x19, 0x72, 0x39, + 0xEF, 0xC5, 0xA5, 0xC9, 0xDA, 0xC6, 0x71, 0xED, + 0xBC, 0x1B, 0x85, 0x88, 0x11, 0x2A, 0x02, 0xA7, + 0xFD, 0x3C, 0xF7, 0x31, 0x4D, 0x57, 0xEE, 0x56, + 0xF0, 0xBC, 0xF1, 0x90, 0x88, 0xFA, 0xC8, 0xC0, + 0xF5, 0x41, 0x39, 0x5B, 0x92, 0x1E, 0xE9, 0x94, + 0x79, 0x29, 0x58, 0xE2, 0x04, 0xB5, 0x9C, 0xEE, + 0x68, 0x2F, 0x5C, 0x91, 0xFA, 0xF6, 0x09, 0xCE, + 0x10, 0xFB, 0xBD, 0x4A, 0xCA, 0x8B, 0x51, 0xFC, + 0x1F, 0xC7, 0x16, 0xA3, 0x49, 0x1A, 0x70, 0xCC, + 0x38, 0xE6, 0x9C, 0xCA, 0x21, 0x2B, 0x13, 0xBA, + 0x51, 0x94, 0xCB, 0x25, 0x45, 0x55, 0x12, 0x2F, + 0xA5, 0xF7, 0xAB, 0x1A, 0x75, 0xD2, 0xAC, 0x03, + 0xAD, 0xFF, 0x9D, 0x79, 0x87, 0x83, 0xBA, 0xA6, + 0x80, 0x32, 0x7A, 0x32, 0x3B, 0x26, 0xF5, 0xCF, + 0xDF, 0xEC, 0xBE, 0x07, 0x89, 0x3F, 0x87, 0x38, + 0x77, 0x93, 0xA8, 0xD4, 0x6B, 0x5B, 0x73, 0x42, + 0x45, 0xD8, 0x71, 0x2D, 0x86, 0x33, 0x6F, 0xCD, + 0x6E, 0xE4, 0x3E, 0x08, 0xE1, 0x02, 0xE3, 0x2E, + 0x2D, 0xF8, 0x03, 0x8C, 0x80, 0x23, 0x0B, 0x95, + 0x50, 0xE3, 0x07, 0xDB, 0x84, 0xB6, 0xA6, 0x4F, + 0xDB, 0xAF, 0x77, 0x8D, 0xD6, 0xEE, 0x2C, 0x52, + 0x31, 0x8F, 0xF6, 0xDF, 0xB4, 0x92, 0x9F, 0x29, + 0x2E, 0x2B, 0x7D, 0x57, 0xE9, 0x8A, 0xB3, 0x00, + 0xB4, 0xC9, 0x73, 0x96, 0x61, 0x99, 0x99, 0x62, + 0xC7, 0x8B, 0x8E, 0x90, 0xB7, 0x08, 0xA4, 0x9C, + 0x62, 0xA4, 0x54, 0x3D, 0xD1, 0x97, 0x3B, 0x82, + 0xEB, 0xAC, 0x3E, 0xA1, 0x55, 0xF9, 0x29, 0x39, + 0xCB, 0x4C, 0xC9, 0x3C, 0x1E, 0xCE, 0x9A, 0x6D, + 0x1E, 0x8B, 0xA0, 0x4F, 0x6A, 0xF2, 0xE7, 0xC0, + 0x96, 0x6F, 0x05, 0x44, 0xA7, 0xB0, 0x49, 0x4D, + 0x8C, 0xB1, 0xD3, 0x0D, 0x23, 0xC1, 0xB6, 0x90, + 0xA6, 0x59, 0x44, 0xDD, 0x50, 0xAC, 0x08, 0xF0, + 0x7A, 0x63, 0xD4, 0xA6, 0xC4, 0xE7, 0x38, 0xA1, + 0x34, 0x51, 0xCA, 0x6C, 0xBE, 0xF5, 0x44, 0xD2, + 0x37, 0xF1, 0xA3, 0xEE, 0xAA, 0x69, 0xCA, 0xDE, + 0x06, 0xCE, 0x9C, 0xFA, 0x24, 0x63, 0xE7, 0xF9, + 0xCB, 0xD3, 0xF8, 0x0D, 0x97, 0x5F, 0xFA, 0xAF, + 0xBF, 0x21, 0x26, 0x5D, 0x4D, 0xBD, 0xA7, 0x61, + 0xED, 0x13, 0xC7, 0x20, 0xD6, 0xB5, 0x58, 0x49, + 0x2B, 0x7C, 0xA2, 0x1B, 0x36, 0x91, 0x00, 0xF0, + 0x9C, 0x32, 0xD8, 0xB7, 0xF1, 0x5F, 0x40, 0x46, + 0x89, 0xE4, 0xE6, 0x1A, 0x84, 0x1B, 0x9A, 0xB4, + 0xA9, 0xE8, 0x6B, 0x02, 0x91, 0xB3, 0xCB, 0x48, + 0xB1, 0x65, 0x0F, 0x43, 0x37, 0x71, 0x0F, 0x14, + 0xC0, 0x46, 0x8A, 0xA7, 0x03, 0x6F, 0xD4, 0x5B, + 0xE8, 0x1F, 0xC1, 0xB1, 0x14, 0x30, 0x01, 0x3E, + 0x61, 0x78, 0xCA, 0xE2, 0x0A, 0x01, 0xAE, 0x56, + 0xFF, 0xE3, 0xD3, 0x10, 0x70, 0x9B, 0x52, 0xD1, + 0x82, 0x2F, 0x11, 0xF3, 0x47, 0xFA, 0x1E, 0x3B, + 0xD7, 0xF9, 0x93, 0xE1, 0x9A, 0x74, 0x4B, 0x4E, + 0x79, 0x3E, 0xC4, 0x08, 0x1A, 0xB6, 0x04, 0x04, + 0x6A, 0x39, 0x89, 0x4A, 0xAB, 0x96, 0xE9, 0xDF, + 0xEB, 0x6D, 0xA1, 0x65, 0xF3, 0x3E, 0xDC, 0xB9, + 0x89, 0xEA, 0x83, 0x5C, 0xA3, 0x1B, 0xF0, 0x59, + 0x0C, 0xFE, 0x5B, 0xB3, 0xCC, 0x58, 0x8F, 0xC4, + 0x2F, 0xD7, 0x11, 0x04, 0x53, 0x23, 0xFA, 0x47, + 0xAB, 0xA0, 0xA9, 0x5A, 0x00, 0x9B, 0x25, 0x0C, + 0x68, 0x8F, 0x4D, 0x51, 0x1A, 0xCA, 0x77, 0xC9, + 0xB5, 0xB1, 0x35, 0xE1, 0x18, 0x09, 0x4C, 0x64, + 0x82, 0xE5, 0xF9, 0xDF, 0x9C, 0x09, 0x64, 0x31, + 0xC7, 0xAB, 0xB0, 0xEB, 0x79, 0x32, 0xB7, 0xAC, + 0x02, 0xD8, 0xF6, 0x0D, 0x95, 0x3F, 0x4E, 0x2D, + 0x4A, 0x17, 0x06, 0xC8, 0x62, 0x8C, 0x2C, 0xF7, + 0xB4, 0xE6, 0xAF, 0x99, 0x55, 0x4F, 0x8B, 0x06, + 0x99, 0xD6, 0x9A, 0xA3, 0x76, 0x13, 0x94, 0xF8, + 0xA2, 0x7F, 0xD4, 0x00, 0x2B, 0xB1, 0xF2, 0x49, + 0xF2, 0x85, 0xD5, 0xE4, 0xBF, 0x17, 0xA7, 0x37, + 0x13, 0x9E, 0x5A, 0xE6, 0xCE, 0x4A, 0xC1, 0x09, + 0x14, 0x7D, 0xB3, 0xF8, 0x24, 0x03, 0x5C, 0x63, + 0x57, 0x03, 0xCC, 0x2E, 0xF6, 0xB4, 0xB6, 0x69, + 0xA1, 0xD8, 0xB8, 0x17, 0xF2, 0x11, 0x4B, 0x26, + 0x42, 0x26, 0xFB, 0xBB, 0x31, 0x78, 0xDB, 0x4C, + 0x9E, 0xD1, 0xE9, 0x91, 0xBB, 0x62, 0x4F, 0x11, + 0xBB, 0xDD, 0x7F, 0x77, 0xD4, 0x83, 0x15, 0x89, + 0x4D, 0xC9, 0x5C, 0xD3, 0xD1, 0x82, 0x86, 0x75, + 0x8A, 0x59, 0xE7, 0x09, 0x0E, 0xC5, 0xEF, 0xAA, + 0x01, 0x2A, 0x29, 0x70, 0xE2, 0x15, 0x46, 0xAA, + 0xA2, 0xD5, 0x3E, 0x9F, 0x02, 0x28, 0x7E, 0x35, + 0x15, 0x71, 0x52, 0x93, 0xD5, 0xA3, 0x97, 0x44, + 0x47, 0x3B, 0x7E, 0xC8, 0x36, 0x70, 0x20, 0xC1, + 0xB0, 0x43, 0x93, 0x26, 0xBD, 0xCF, 0x68, 0x52, + 0x50, 0x05, 0x71, 0xEF, 0x65, 0x34, 0x88, 0x2E, + 0x84, 0x58, 0x31, 0x46, 0x4A, 0xF3, 0xF9, 0xE3, + 0x16, 0x09, 0x77, 0x50, 0x3B, 0xE1, 0xCF, 0x46, + 0xC5, 0x3B, 0xBF, 0xAF, 0x82, 0x58, 0x69, 0x89, + 0x42, 0x0B, 0x30, 0x87, 0x90, 0xAA, 0xBD, 0x9E, + 0x7F, 0x9B, 0x12, 0xB0, 0xD9, 0xBC, 0xB4, 0xAF, + 0x47, 0x1A, 0xB7, 0x39, 0x1B, 0xBE, 0xC3, 0x46, + 0x7B, 0x40, 0x97, 0xDE, 0xA2, 0x35, 0xAE, 0x7E, + 0x75, 0x9E, 0x06, 0xBF, 0x17, 0x00, 0x0A, 0x8F, + 0x64, 0x69, 0x40, 0x02, 0xEB, 0x62, 0xB4, 0xC1, + 0x4C, 0x20, 0xB6, 0x0A, 0x56, 0x7E, 0x4F, 0xB7, + 0x15, 0xB1, 0x5F, 0xCE, 0x20, 0xEB, 0x3C, 0xEA, + 0x60, 0xCC, 0xF1, 0x54, 0x99, 0x2C, 0xE5, 0x8C, + 0x08, 0xB4, 0xFB, 0x40, 0xF6, 0xB6, 0x7B, 0xE0, + 0xD6, 0x22, 0x38, 0xBF, 0x2D, 0xA6, 0x1E, 0xA3, + 0xE1, 0x6A, 0x07, 0xAC, 0xD6, 0xB0, 0x46, 0xA6, + 0xF7, 0x1C, 0x64, 0x2E, 0x52, 0xCC, 0x5C, 0x75, + 0x71, 0x06, 0x3F, 0x70, 0x84, 0x52, 0x07, 0x91, + 0xBA, 0x8E, 0x9D, 0x38, 0x10, 0x79, 0xA1, 0xB0, + 0xE8, 0x50, 0x5F, 0x5B, 0xA3, 0x83, 0xAF, 0x5C, + 0xAD, 0x48, 0xB8, 0x7A, 0x61, 0xBE, 0x08, 0x7D, + 0xA0, 0xC1, 0x30, 0x16, 0x27, 0x48, 0xC3, 0x0F, + 0x99, 0x69, 0x64, 0x70, 0xB7, 0x0B, 0xA0, 0xE2, + 0xA6, 0xD6, 0xA1, 0xBE, 0x83, 0xC8, 0xC7, 0xC9, + 0x34, 0xE1, 0x73, 0x48, 0x40, 0x5A, 0x4F, 0xB5, + 0xCE, 0x44, 0x0B, 0xA4, 0x5E, 0xE0, 0xC9, 0x19, + 0x30, 0x49, 0x19, 0x24, 0x6B, 0xC9, 0xC6, 0x5C, + 0x2A, 0x6C, 0x04, 0x08, 0x68, 0x05, 0xBC, 0x40, + 0x4C, 0x76, 0x05, 0x5F, 0xE0, 0xED, 0x64, 0x6D, + 0x19, 0xE7, 0x26, 0x2D, 0x11, 0x05, 0x1E, 0x34, + 0xA8, 0xD4, 0x32, 0x9C, 0xBD, 0xDD, 0xD7, 0x40, + 0xC1, 0xFC, 0x63, 0x3C, 0x4C, 0x55, 0xB9, 0x35, + 0x7E, 0xCB, 0x55, 0xB1, 0x9D, 0x8F, 0x17, 0x1C, + 0x47, 0xFA, 0xE7, 0x75, 0xD9, 0x61, 0x8C, 0x09, + 0x50, 0xD8, 0x04, 0x15, 0x28, 0x10, 0xBB, 0x93, + 0x2D, 0x94, 0xFA, 0xE4, 0x24, 0xA0, 0xD0, 0x2F, + 0x30, 0x0B, 0x60, 0x27, 0x46, 0x88, 0x4B, 0x1A, + 0x94, 0xA8, 0x62, 0x59, 0x1A, 0x8F, 0xDF, 0x47, + 0xF4, 0x05, 0xF7, 0xFF, 0x04, 0x66, 0x36, 0x1D, + 0xD0, 0x99, 0x33, 0xEC, 0xB4, 0xAE, 0x67, 0x5C, + 0x88, 0x2C, 0xCD, 0x3A, 0x7A, 0xB7, 0x66, 0x7B, + 0x29, 0x51, 0x1E, 0x3C, 0x60, 0xF3, 0x2A, 0x03, + 0xF0, 0x81, 0x69, 0xD2, 0xA5, 0x24, 0x47, 0xEF, + 0x25, 0x7D, 0x61, 0xF9, 0xD1, 0xAD, 0xB3, 0xAE, + 0x82, 0x7E, 0x03, 0x25, 0xB4, 0x3F, 0x23, 0x7F, + 0x1E, 0x3F, 0xA2, 0xAB, 0x09, 0xC0, 0xFB, 0x42, + 0x73, 0x92, 0x8C, 0x36, 0x84, 0x4E, 0x7E, 0xFE, + 0x5C, 0x0B, 0x14, 0x47, 0x7A, 0x06, 0xF9, 0x0C, + 0x08, 0x88, 0x22, 0x82, 0xB9, 0xE4, 0xD2, 0x92, + 0x1E, 0x13, 0xAF, 0xD3, 0x39, 0xDE, 0x13, 0xF7, + 0x8C, 0xF6, 0xCB, 0xA0, 0xE6, 0xD3, 0xD0, 0xF9, + 0x64, 0xEA, 0x0F, 0xB0, 0x0F, 0xA7, 0x16, 0x4D, + 0xA5, 0x3B, 0x37, 0x5D, 0x13, 0x86, 0xA1, 0x60, + 0x2C, 0x9C, 0xE6, 0x72, 0xC3, 0xB0, 0xD4, 0x77, + 0xF4, 0xE6, 0xAF, 0x56, 0x4E, 0x56, 0x96, 0x85, + 0x47, 0xE5, 0x38, 0xD3, 0xCA, 0x01, 0x93, 0xDA, + 0x2F, 0x79, 0xE0, 0x10, 0x60, 0x86, 0x9D, 0xB4, + 0xF6, 0x45, 0x2D, 0xDE, 0xAB, 0x48, 0x35, 0x47, + 0xA7, 0x8E, 0xE2, 0x41, 0x33, 0xC7, 0x02, 0x09, + 0x9C, 0xDB, 0xE8, 0xBB, 0x89, 0xD3, 0xC9, 0x0D, + 0x90, 0x93, 0x4B, 0xB0, 0xA5, 0xC3, 0xFA, 0x4A, + 0x94, 0xCB, 0x65, 0x48, 0x26, 0x7B, 0xDE, 0x82, + 0xB2, 0x02, 0xA6, 0xB9, 0x34, 0x8E, 0xD4, 0x12, + 0x8A, 0xB4, 0xCA, 0x55, 0xEF, 0x96, 0xCE, 0xB5, + 0x5C, 0x62, 0x55, 0xC0, 0xD6, 0xEF, 0xDB, 0x63, + 0x08, 0xA0, 0x12, 0x69, 0xAF, 0x35, 0xAD, 0x44, + 0xA2, 0x75, 0x26, 0x56, 0x5A, 0xBB, 0xE3, 0x69, + 0x5D, 0x6B, 0x7C, 0xA7, 0x66, 0x14, 0x0A, 0x54, + 0x1C, 0x3C, 0x36, 0xBC, 0xE8, 0x43, 0x3E, 0x5F, + 0x59, 0x6C, 0xBC, 0x87, 0x93, 0xB9, 0xAE, 0x85, + 0x0E, 0x95, 0xDC, 0x0A, 0x66, 0x63, 0x09, 0x64, + 0xC2, 0xDA, 0x2B, 0x80, 0xE6, 0x86, 0xA5, 0x85, + 0x06, 0x2A, 0x31, 0x03, 0x15, 0x13, 0xFE, 0x95, + 0x34, 0x86, 0xAF, 0xBF, 0x68, 0x5A, 0x17, 0xB9, + 0xB5, 0x97, 0x9B, 0x27, 0x80, 0x2F, 0x6B, 0x31, + 0xB8, 0xC8, 0xA6, 0x9B, 0x3C, 0x62, 0x28, 0xC8, + 0x0D, 0x33, 0xE1, 0xE6, 0x4E, 0x18, 0x1B, 0xDD, + 0x3B, 0x33, 0x39, 0x93, 0xAB, 0xB0, 0x4A, 0x43, + 0x27, 0xFB, 0x05, 0x9F, 0xC3, 0x51, 0xD7, 0xBE, + 0x55, 0xDE, 0x62, 0x53, 0xFC, 0x34, 0xB6, 0xC3, + 0xC2, 0x7C, 0x3C, 0xF7, 0x12, 0x33, 0x7E, 0x5D, + 0xBC, 0xAA, 0x65, 0xA0, 0xA7, 0x89, 0xD8, 0x74, + 0x1F, 0xF2, 0x82, 0x37, 0x21, 0x5C, 0x1A, 0x7B, + 0xFD, 0xCB, 0x5F, 0xCB, 0x0D, 0xBA, 0xD4, 0x1F, + 0xBD, 0x00, 0xAD, 0x77, 0x57, 0xA6, 0xC1, 0x2B, + 0x4F, 0xF6, 0x33, 0xC3, 0xF9, 0xEA, 0xD4, 0xC4, + 0x7B, 0xE4, 0x46, 0xE5, 0xE5, 0x96, 0xA6, 0x57, + 0x12, 0xD3, 0xCD, 0xB4, 0xA8, 0x2B, 0xAC, 0x11, + 0xD1, 0xE7, 0x15, 0x01, 0x21, 0xD8, 0x9A, 0xE3, + 0x6D, 0xB6, 0x86, 0x73, 0x3F, 0xC7, 0xD7, 0xFF, + 0xF3, 0x0E, 0x32, 0xE9, 0x6C, 0xE8, 0xAD, 0x1A, + 0xC1, 0xF0, 0x49, 0x3E, 0x49, 0x39, 0x5B, 0xFF, + 0x70, 0xB2, 0x41, 0xDA, 0xC5, 0xB3, 0x80, 0xF5, + 0x33, 0xBD, 0x24, 0x04, 0x68, 0xF3, 0x99, 0x22, + 0xAD, 0xFE, 0x2B, 0xAF, 0x12, 0x5E, 0xAF, 0x44, + 0x83, 0xBE, 0x12, 0xEF, 0x3D, 0x02, 0x80, 0x79, + 0xA2, 0xA7, 0x3A, 0x96, 0x27, 0x14, 0x82, 0x80, + 0x60, 0x8A, 0x56, 0x9C, 0x5A, 0xCB, 0x4F, 0x80, + 0xAA, 0xF2, 0xFA, 0x75, 0xFB, 0x1D, 0x3A, 0x4A, + 0xCC, 0xB9, 0xD7, 0x5F, 0xDF, 0xCA, 0x1C, 0x7B, + 0x42, 0xCB, 0x77, 0x6D, 0x8B, 0x68, 0x69, 0x67, + 0xF2, 0x20, 0x7A, 0xE1, 0xB3, 0xF5, 0x6E, 0x20, + 0xCC, 0xFF, 0x2C, 0x1D, 0xDC, 0x34, 0x39, 0x80, + 0xBB, 0x02, 0x44, 0x14, 0xBD, 0xA2, 0xB6, 0x46, + 0xDF, 0x44, 0x1E, 0x87, 0xEE, 0xD5, 0x9A, 0x68, + 0xCF, 0xD7, 0x5E, 0x33, 0x4D, 0x53, 0xE3, 0x71, + 0x19, 0xE5, 0xEA, 0x68, 0x31, 0x77, 0xCE, 0x94, + 0xE0, 0xF6, 0x38, 0xDF, 0xA3, 0x06, 0x46, 0xDA, + 0xDE, 0x7F, 0xCC, 0x19, 0xD7, 0xD7, 0x37, 0x16, + 0x9B, 0x81, 0x1C, 0x26, 0xF4, 0xC0, 0x61, 0xC5, + 0xBB, 0xBB, 0xDB, 0xD6, 0x20, 0xEA, 0x57, 0x22, + 0xF8, 0x8D, 0xF0, 0xD3, 0x58, 0xB9, 0x4D, 0x9B, + 0x3C, 0xB2, 0x1B, 0x3B, 0xDF, 0x89, 0x12, 0x03, + 0x27, 0x42, 0xBA, 0xC1, 0xDB, 0xBB, 0x7E, 0xA2, + 0xF4, 0x40, 0xAD, 0xDB, 0xE4, 0xE2, 0x6D, 0xE4, + 0x28, 0xFC, 0x62, 0x88, 0x4F, 0x75, 0xAF, 0x87, + 0x50, 0x2E, 0x29, 0x54, 0xE8, 0x03, 0x9A, 0x14, + 0x2D, 0xCA, 0xDE, 0xED, 0x21, 0xF6, 0xC6, 0x45, + 0xF2, 0x9C, 0x77, 0x0C, 0x5D, 0x9F, 0x29, 0x42, + 0x8B, 0x94, 0x87, 0x4A, 0x3A, 0x00, 0xD5, 0xCE, + 0xCE, 0x8D, 0x3F, 0x1C, 0x61, 0xBE, 0x3E, 0x35, + 0xBC, 0xD9, 0x18, 0xA3, 0x61, 0xC5, 0xB7, 0xC9, + 0x73, 0xCF, 0xFA, 0x8E, 0xC7, 0x08, 0x59, 0x34, + 0xF6, 0xB9, 0xE4, 0xF7, 0xDC, 0x46, 0x43, 0x4C, + 0x66, 0x0C, 0x86, 0x24, 0xC1, 0xF8, 0xB5, 0x29, + 0x7E, 0xBA, 0xBC, 0xEB, 0x43, 0x46, 0x91, 0x3D, + 0x66, 0x39, 0xCE, 0x9B, 0x83, 0xBF, 0x4F, 0x7F, + 0x19, 0x03, 0xF3, 0x78, 0x53, 0x5E, 0x0D, 0x43, + 0x2E, 0x7F, 0x2B, 0xB5, 0xE9, 0x95, 0xF9, 0x87, + 0x4C, 0x35, 0x3F, 0x17, 0x99, 0x54, 0x06, 0xD6, + 0x4A, 0xAD, 0x86, 0x83, 0x57, 0x0A, 0x4A, 0x54, + 0xA6, 0x53, 0x5D, 0xB4, 0xE4, 0x05, 0xEC, 0xCF, + 0x29, 0x34, 0x28, 0x79, 0x00, 0xC8, 0xF1, 0xF2, + 0xCF, 0xF7, 0x45, 0x24, 0xD3, 0x6D, 0xA8, 0x43, + 0xD8, 0xA0, 0x08, 0xB5, 0xB1, 0x61, 0x37, 0x94, + 0x37, 0xB5, 0xB0, 0x92, 0x8B, 0x3A, 0xFA, 0xDF, + 0x75, 0x1F, 0xEE, 0xA9, 0xF1, 0x2B, 0x72, 0x18, + 0xD2, 0x2A, 0x63, 0xA3, 0xE7, 0x20, 0x82, 0x05, + 0x9B, 0xF3, 0xEE, 0x22, 0x85, 0x3B, 0xDA, 0x25, + 0x8B, 0x4D, 0x78, 0x73, 0x55, 0xBF, 0x24, 0x2E, + 0x38, 0x13, 0x42, 0x79, 0xEA, 0xCA, 0x7D, 0x53, + 0x98, 0x6F, 0x0C, 0x06, 0x23, 0xB8, 0x88, 0xCC, + 0x92, 0x73, 0xCB, 0xA2, 0xDA, 0x1C, 0x70, 0x22, + 0x3D, 0xD3, 0x32, 0x29, 0xD0, 0x3A, 0x4E, 0x52, + 0x7A, 0x7E, 0x90, 0xA6, 0x54, 0x94, 0x30, 0x06, + 0x72, 0xB0, 0x4C, 0x44, 0x28, 0x6F, 0xA5, 0x54, + 0x1D, 0xF2, 0x07, 0xDE, 0x7E, 0xF7, 0x4E, 0x08, + 0xC6, 0x33, 0x45, 0x88, 0x2D, 0x87, 0x84, 0xE4, + 0x5F, 0xDC, 0x08, 0x43, 0x7C, 0x88, 0x3A, 0x8D, + 0x22, 0x95, 0x43, 0xC6, 0x2C, 0x59, 0x91, 0xF8, + 0xAA, 0x78, 0xB4, 0x7C, 0x19, 0x5A, 0xD9, 0xF1, + 0xE2, 0x2B, 0xDC, 0x7C, 0x96, 0x61, 0xC2, 0x24, + 0x62, 0xA3, 0xB1, 0x54, 0x47, 0x93, 0x80, 0x43, + 0xE1, 0xD3, 0xFF, 0xCA, 0x40, 0xB4, 0x1B, 0x6D, + 0xFE, 0xC6, 0x35, 0x61, 0x38, 0x3F, 0x91, 0x47, + 0xE2, 0xF4, 0xCC, 0x7D, 0x72, 0xD9, 0xEC, 0xDF, + 0x46, 0x1B, 0x94, 0x04, 0x6D, 0x5E, 0x74, 0xF7, + 0xAC, 0x62, 0x76, 0x4C, 0x31, 0xF7, 0x59, 0xCD, + 0xBF, 0xA0, 0x8C, 0x60, 0x1E, 0x07, 0xA9, 0xEF, + 0x6B, 0x43, 0x6C, 0xA2, 0x64, 0x64, 0x19, 0xAD, + 0x95, 0x1A, 0xD8, 0x34, 0xBB, 0xC2, 0xD0, 0xA5, + 0xE8, 0x54, 0x26, 0xC5, 0x7B, 0x48, 0x4E, 0x98, + 0xD3, 0xD7, 0x0C, 0xEB, 0x3C, 0x89, 0xFA, 0x57, + 0x0F, 0x4F, 0x17, 0x24, 0x62, 0xC8, 0xC1, 0xCF, + 0x05, 0xC0, 0x92, 0x97, 0x4D, 0x99, 0x56, 0x33, + 0x6B, 0xA5, 0xFB, 0x4F, 0x33, 0x8E, 0xE8, 0x42, + 0xB5, 0xB3, 0x21, 0xFD, 0xDB, 0x94, 0xC5, 0x3C, + 0x6A, 0x21, 0x5F, 0x0C, 0x74, 0xA4, 0xB5, 0x85, + 0xB2, 0x60, 0xA9, 0xD5, 0x20, 0x3E, 0x97, 0x7B, + 0x0A, 0xE1, 0xCD, 0x55, 0x98, 0x34, 0x41, 0x40, + 0x6A, 0xE6, 0x53, 0x88, 0xAF, 0x2C, 0xF3, 0x43, + 0x67, 0xD6, 0xB1, 0x22, 0xC0, 0x72, 0xB2, 0xCE, + 0x7E, 0xDC, 0xE4, 0xF6, 0x10, 0xCD, 0x95, 0x52, + 0xD1, 0x0B, 0xEC, 0xA6, 0xD8, 0x25, 0xCA, 0x4E, + 0x02, 0xAF, 0xE0, 0x32, 0x68, 0xA5, 0xBC, 0xFF, + 0xC0, 0x79, 0x33, 0xE2, 0xAF, 0x3A, 0x85, 0xF1, + 0x6C, 0x43, 0x3C, 0x5D, 0x6E, 0x8B, 0xED, 0xE3, + 0x20, 0x33, 0x37, 0x73, 0x3F, 0x5C, 0x53, 0xB0, + 0x45, 0xE2, 0x13, 0x6B, 0x96, 0x1D, 0x3D, 0x11, + 0x52, 0x28, 0x5D, 0xA2, 0x5E, 0x33, 0x9E, 0x97, + 0x4B, 0x2E, 0x76, 0x91, 0x93, 0x9D, 0x25, 0x99, + 0x94, 0x47, 0x86, 0x76, 0xF2, 0x7C, 0xC7, 0x72, + 0x08, 0x50, 0x54, 0xBB, 0xFC, 0xD7, 0xF1, 0x65, + 0xF1, 0x9A, 0x50, 0x65, 0x00, 0x00, 0xAC, 0x45, + 0x13, 0xE1, 0xDD, 0x8E, 0x53, 0x0A, 0xD9, 0x1A, + 0x91, 0xA5, 0x1B, 0xD6, 0xA5, 0x75, 0x29, 0x66, + 0x25, 0xEC, 0x16, 0x7E, 0xBC, 0x0F, 0x2A, 0xED, + 0x43, 0xFC, 0xE4, 0xEE, 0xE9, 0x31, 0xCE, 0xDF, + 0x0B, 0x46, 0x40, 0x31, 0x76, 0x24, 0x5B, 0xEB, + 0x2A, 0x83, 0x02, 0x42, 0xD4, 0x91, 0xCB, 0x82, + 0x82, 0x11, 0x7C, 0xB4, 0x27, 0x0E, 0xA0, 0x4B, + 0xB6, 0x6D, 0xFD, 0xCE, 0x0B, 0xDB, 0xF9, 0x26, + 0x89, 0xC6, 0x85, 0x77, 0x1B, 0xB9, 0xC0, 0x9F, + 0xF5, 0xB9, 0x10, 0x90, 0x8E, 0x67, 0x4E, 0x89, + 0xBB, 0x80, 0xC6, 0xA2, 0x6B, 0xA3, 0xD2, 0x5E, + 0x25, 0xB2, 0x9E, 0x56, 0x0B, 0x76, 0x1D, 0xFC, + 0x2E, 0xA2, 0x2C, 0xA2, 0xCB, 0x2B, 0x60, 0x9D, + 0xF1, 0xC3, 0x05, 0x89, 0x0B, 0x70, 0x32, 0x3C, + 0x4D, 0x5D, 0x6A, 0x93, 0x20, 0x8F, 0x6C, 0x9F, + 0x1F, 0x64, 0xAA, 0x52, 0xE0, 0x3B, 0x62, 0xF5, + 0xBD, 0xC2, 0x39, 0x62, 0x0F, 0x01, 0x86, 0xA0, + 0x37, 0x9C, 0x06, 0x31, 0x03, 0xC7, 0x0D, 0x9F, + 0x12, 0x90, 0x1B, 0xE2, 0xE8, 0x51, 0x22, 0x74, + 0x2D, 0x0E, 0x36, 0xD7, 0xD3, 0x33, 0x5D, 0xD5, + 0x0B, 0x8C, 0x42, 0xD8, 0x0D, 0x68, 0xA0, 0xB9, + 0x14, 0x84, 0xB6, 0xFA, 0xE2, 0xE6, 0x60, 0xC4, + 0x2E, 0x0F, 0xDA, 0xF5, 0xF6, 0x60, 0x01, 0xFC, + 0x0A, 0xDC, 0x1E, 0x98, 0x22, 0x27, 0xBC, 0x72, + 0xDE, 0x23, 0x95, 0x70, 0x60, 0x66, 0x6B, 0x8B, + 0xA7, 0xE7, 0x1E, 0x49, 0xE7, 0xC5, 0x7F, 0xF9, + 0x3B, 0xE6, 0xA8, 0x7D, 0x56, 0xC1, 0x13, 0x79, + 0xDA, 0x71, 0xE9, 0x01, 0x40, 0x43, 0xFA, 0xA6, + 0xF6, 0xE6, 0x4A, 0x74, 0x20, 0x01, 0xD6, 0x79, + 0x0C, 0xFC, 0xAE, 0xF5, 0xDC, 0x40, 0x06, 0xF7, + 0xC7, 0x05, 0x77, 0x23, 0xC3, 0x7B, 0x14, 0x57, + 0xFD, 0x53, 0xFC, 0x73, 0xCC, 0xBC, 0x0D, 0xE7, + 0x27, 0x0A, 0x38, 0xDF, 0xEA, 0xAB, 0x90, 0xBF, + 0xF2, 0x4D, 0x0B, 0x97, 0x98, 0xD7, 0x31, 0xAA, + 0x5E, 0x19, 0xB9, 0xFD, 0x8F, 0x49, 0x17, 0xA9, + 0x5A, 0xBA, 0xC6, 0x7A, 0x2C, 0x29, 0xC6, 0x67, + 0xCC, 0x26, 0xB9, 0x86, 0x6E, 0xB5, 0xC2, 0xAD, + 0x2A, 0xF2, 0xBD, 0x4B, 0x48, 0xC1, 0xC7, 0x34, + 0x14, 0xB8, 0x53, 0xA5, 0x40, 0x2A, 0x7C, 0xA4, + 0x2B, 0xB0, 0x9F, 0xD9, 0x7B, 0xDD, 0xDF, 0x14, + 0x0D, 0x51, 0xB2, 0x2E, 0xEC, 0xFB, 0x3C, 0x81, + 0xD8, 0xD1, 0xFD, 0x3C, 0x19, 0xC7, 0x00, 0x35, + 0xF3, 0xC2, 0x93, 0x70, 0xA0, 0x8B, 0x24, 0x2B, + 0xD7, 0x95, 0x04, 0x03, 0x44, 0x0E, 0x0A, 0x50, + 0xB5, 0x9C, 0x09, 0x25, 0x6A, 0x19, 0xB5, 0x08, + 0x08, 0x43, 0xB1, 0x50, 0x65, 0x59, 0x1A, 0xCF, + 0xA4, 0xFF, 0x92, 0x6C, 0xBA, 0x05, 0x13, 0xFD, + 0x31, 0xBF, 0xFB, 0x52, 0xCD, 0x68, 0x8F, 0x01, + 0x94, 0x19, 0xCD, 0xD8, 0x1E, 0x4E, 0x71, 0x44, + 0xAF, 0x5E, 0xE4, 0xDC, 0x43, 0x07, 0x42, 0xF2, + 0x5A, 0xEA, 0x7F, 0xBA, 0xD9, 0x8C, 0x84, 0xC4, + 0x2A, 0xE3, 0xCB, 0xA9, 0xB6, 0x6D, 0x94, 0x11, + 0xAB, 0x50, 0x84, 0x56, 0x42, 0xAC, 0x6E, 0xB9, + 0xBD, 0xBC, 0x98, 0x82, 0x66, 0xAF, 0x40, 0x33, + 0x50, 0xF3, 0x13, 0xE5, 0x6E, 0x34, 0x24, 0xFF, + 0x5F, 0x0F, 0xCE, 0x29, 0x54, 0x32, 0xE0, 0x6F, + 0x0B, 0x8B, 0x52, 0x14, 0x6B, 0x0C, 0x2A, 0x57, + 0x7F, 0xB6, 0x2D, 0xD4, 0x2C, 0xD2, 0xD4, 0x1A, + 0x60, 0xF7, 0x1C, 0xBB, 0xF4, 0x07, 0x69, 0x02, + 0xF5, 0xE2, 0x2E, 0xC4, 0xFB, 0xE2, 0x83, 0xA0, + 0x60, 0x8C, 0x69, 0x6C, 0x1B, 0x9D, 0x0B, 0x90, + 0xE8, 0x0F, 0xD3, 0x8C, 0x76, 0x97, 0x0C, 0xC5, + 0x84, 0x61, 0x4F, 0x61, 0x0E, 0x84, 0xF5, 0x7D, + 0xC2, 0xD5, 0x0A, 0x9A, 0xC7, 0x56, 0x56, 0xD9, + 0xDE, 0x79, 0xD0, 0xE2, 0x65, 0xF3, 0x88, 0xBD, + 0x41, 0xE3, 0x10, 0xB6, 0x36, 0x65, 0x62, 0xBB, + 0x72, 0x5B, 0x7B, 0xD9, 0x67, 0xD9, 0x40, 0xB8, + 0x50, 0xA4, 0x3D, 0x06, 0xD5, 0x51, 0x25, 0x32, + 0xE8, 0x0B, 0x0E, 0x2D, 0xFA, 0xAB, 0x1C, 0x9C, + 0x80, 0x55, 0x51, 0x5B, 0x5A, 0x69, 0x76, 0x4D, + 0x95, 0x16, 0x84, 0x8A, 0xD7, 0x30, 0xA6, 0x2E, + 0xE9, 0x03, 0x33, 0x80, 0x4F, 0xF0, 0x9A, 0xBA, + 0x41, 0x4A, 0xDB, 0x9F, 0xB3, 0x7F, 0xC1, 0x9D, + 0xE5, 0x3B, 0x66, 0xC1, 0x15, 0xB9, 0x9A, 0x72, + 0x74, 0x7B, 0xF6, 0x52, 0x17, 0xF7, 0x5C, 0x46, + 0xE4, 0x4F, 0xD2, 0xF7, 0x8C, 0x49, 0x69, 0xE6, + 0x58, 0x21, 0xE4, 0xAE, 0xC0, 0x55, 0x01, 0xA7, + 0x18, 0x57, 0x10, 0x6E, 0x3F, 0x42, 0x7B, 0xC2, + 0x05, 0xEE, 0x24, 0x5D, 0x23, 0xB6, 0xC1, 0x59, + 0xF7, 0xA6, 0x40, 0xFD, 0xF0, 0x91, 0xE0, 0xA9, + 0x2C, 0x1E, 0x94, 0xB0, 0xFD, 0x05, 0xAA, 0xAE, + 0xDD, 0xB0, 0x61, 0x6F, 0x0F, 0xC7, 0x26, 0xE4, + 0x0E, 0xDB, 0x7A, 0x0B, 0x3E, 0x78, 0x92, 0x7E, + 0xB9, 0xD6, 0xAF, 0x36, 0x4A, 0x4F, 0x07, 0x2E, + 0x5E, 0xDB, 0xE7, 0x25, 0x4A, 0x9D, 0xB6, 0x88, + 0xB6, 0x7D, 0xD4, 0x60, 0xFC, 0xD0, 0xA5, 0x32, + 0x8A, 0x94, 0x5A, 0x53, 0xDF, 0x9B, 0xF9, 0x8B, + 0x57, 0xC9, 0xEB, 0xCC, 0xC2, 0x90, 0xFF, 0x6F, + 0xA2, 0x8F, 0xAC, 0xE3, 0xAA, 0xC2, 0xE0, 0x5D, + 0x89, 0x71, 0x0A, 0xC0, 0x0D, 0xDF, 0x6A, 0x14, + 0x98, 0x71, 0x34, 0xC6, 0x22, 0x55, 0xE5, 0x5A, + 0x7A, 0xA1, 0xFB, 0xE4, 0xB7, 0x15, 0x15, 0xE2, + 0xDE, 0xFD, 0x26, 0x4D, 0x99, 0x96, 0x87, 0x06, + 0xA9, 0x29, 0x86, 0x80, 0x3C, 0x91, 0x63, 0xCF, + 0x25, 0x91, 0x4A, 0xD0, 0x2A, 0xF8, 0xF6, 0x5E, + 0xB4, 0x58, 0xAA, 0xA0, 0x15, 0x46, 0xF0, 0xCB, + 0xED, 0x98, 0x26, 0xD5, 0xC5, 0x7F, 0x35, 0xE6, + 0xE5, 0x9E, 0xED, 0x75, 0x97, 0x75, 0x29, 0xFD, + 0x92, 0xA6, 0x71, 0xBE, 0xAF, 0x0D, 0x5E, 0x0A, + 0x80, 0x60, 0x72, 0xF5, 0x8F, 0x3D, 0x4B, 0x62, + 0xFF, 0x87, 0x5D, 0x5F, 0x38, 0x02, 0x82, 0x94, + 0x34, 0xEB, 0xAE, 0x8E, 0x5B, 0xC6, 0x5A, 0x44, + 0xD8, 0x11, 0x4C, 0x21, 0x56, 0xEC, 0x6D, 0x75, + 0x26, 0x57, 0x30, 0x59, 0x35, 0x39, 0x02, 0xA6, + 0x0C, 0xC3, 0x5A, 0x06, 0x06, 0xAD, 0x73, 0xA1, + 0x75, 0x83, 0xE5, 0xB6, 0x69, 0x7B, 0x70, 0x93, + 0x5A, 0xC7, 0x26, 0x7A, 0x5C, 0xB0, 0xE6, 0xB9, + 0xC5, 0x13, 0xCA, 0x4C, 0xDB, 0xE0, 0x8A, 0xB7, + 0x7C, 0xA5, 0xE5, 0x0A, 0x4C, 0x18, 0xB9, 0x42, + 0x6F, 0xCF, 0x75, 0x6F, 0x3C, 0x11, 0xB6, 0xC2, + 0xCC, 0xF3, 0x3C, 0x58, 0xC7, 0xB9, 0x5D, 0x59, + 0x9F, 0xD0, 0x39, 0x17, 0xE6, 0x90, 0x22, 0x83, + 0xDE, 0x97, 0xC0, 0x50, 0x2A, 0x5A, 0xBE, 0x10, + 0x30, 0x32, 0x1F, 0xB5, 0xDD, 0xE6, 0x79, 0xA2, + 0xE2, 0xB0, 0x4E, 0x4E, 0xB6, 0x1D, 0x1C, 0xF8, + 0xE3, 0xE6, 0xB6, 0xF4, 0x8C, 0x26, 0xFA, 0x1E, + 0xAF, 0xA7, 0x55, 0xE5, 0x56, 0x0C, 0xB8, 0xF8, + 0xDD, 0x17, 0xFA, 0x0D, 0x45, 0xF7, 0x04, 0x20, + 0x89, 0xD2, 0x3B, 0x8A, 0x7B, 0x0B, 0x62, 0xCC, + 0xB3, 0xC3, 0xE5, 0xC0, 0x04, 0x8D, 0x46, 0xDE, + 0xC1, 0x58, 0xB9, 0x93, 0xC6, 0x76, 0x17, 0x25, + 0xE1, 0xB6, 0x34, 0x82, 0x11, 0xB0, 0x40, 0xF1, + 0x33, 0xA0, 0x6C, 0x79, 0x1A, 0x4C, 0x28, 0x15, + 0xDF, 0x94, 0xE2, 0x39, 0x8A, 0x8F, 0xDE, 0xBF, + 0xE4, 0xEE, 0xBB, 0xDF, 0x84, 0x1A, 0xEE, 0x0F, + 0x67, 0xCD, 0xCC, 0x9F, 0x9F, 0xDC, 0xDC, 0x9B, + 0x67, 0x9D, 0x72, 0xC2, 0x71, 0x3F, 0xD9, 0x72, + 0xA2, 0x89, 0xF2, 0xF7, 0x5A, 0xD1, 0x69, 0x87, + 0x68, 0x85, 0x91, 0x52, 0x29, 0xF4, 0x10, 0x13, + 0xC1, 0xCD, 0xE4, 0x73, 0x9B, 0x06, 0x7D, 0x91, + 0xFB, 0xDD, 0xE7, 0x9D, 0xB9, 0x0A, 0xB3, 0x83, + 0xC1, 0x1C, 0x03, 0x97, 0xD2, 0xE1, 0xF0, 0xEF, + 0xDA, 0x9E, 0xBD, 0xB0, 0x6A, 0x3B, 0xC5, 0x0A, + 0x61, 0x37, 0xBF, 0x12, 0x9F, 0x57, 0x22, 0x5C, + 0x05, 0xDC, 0xD9, 0xC7, 0x75, 0x0B, 0x0A, 0xDF, + 0xFA, 0x84, 0xC1, 0x3D, 0x79, 0x21, 0x60, 0xFA, + 0xBD, 0xBF, 0xE1, 0xBB, 0xCE, 0xEE, 0x71, 0x90, + 0xB2, 0x7B, 0x8B, 0xCE, 0x57, 0xF7, 0x22, 0xA7, + 0xF1, 0x1C, 0x43, 0x6F, 0xC0, 0x71, 0xAA, 0xD0, + 0x8F, 0x84, 0xF8, 0xBD, 0xCF, 0xEF, 0xBF, 0xCB, + 0x3D, 0xAF, 0x61, 0xB5, 0xE1, 0x8F, 0x39, 0xFA, + 0xD4, 0x67, 0xCE, 0xAB, 0xBA, 0x31, 0x54, 0xB1, + 0xC6, 0x03, 0x24, 0x81, 0x33, 0x5E, 0x77, 0x55, + 0xB3, 0x36, 0xD1, 0x4E, 0xF8, 0x20, 0xCE, 0x46, + 0x99, 0x75, 0xA6, 0x6F, 0x19, 0x2C, 0x61, 0x4A, + 0xEB, 0x5B, 0xE3, 0x6B, 0x5C, 0x46, 0xFB, 0x18, + 0xF0, 0x7B, 0x97, 0xA5, 0x1A, 0xBD, 0x20, 0x86, + 0x0D, 0x5A, 0xE3, 0x6A, 0x83, 0x81, 0xF6, 0xAE, + 0xE2, 0x8A, 0x94, 0x22, 0xE6, 0xAF, 0x8E, 0xDC, + 0x15, 0x00, 0x28, 0x3F, 0x8F, 0xC0, 0xFF, 0xDE, + 0x5E, 0xC2, 0xF1, 0x74, 0xED, 0xAC, 0x75, 0xE8, + 0x0F, 0x0D, 0x7B, 0x0E, 0x4A, 0xC0, 0x85, 0x58, + 0xBA, 0xED, 0x86, 0x5C, 0x78, 0xBB, 0x5C, 0x53, + 0x41, 0x2A, 0x2D, 0x3B, 0xBF, 0x1F, 0xCB, 0xB7, + 0xCE, 0x49, 0x84, 0x9C, 0x81, 0x17, 0x5E, 0xEF, + 0x02, 0x67, 0x8C, 0x6A, 0x06, 0xD6, 0x8F, 0xB9, + 0x6C, 0x72, 0x6D, 0xE5, 0x59, 0xAC, 0xD8, 0xC2, + 0xF4, 0x01, 0x00, 0xBD, 0xFF, 0x5D, 0x38, 0x50, + 0x27, 0xD9, 0x4A, 0xB4, 0xAD, 0xDB, 0xF3, 0x7B, + 0x83, 0x26, 0x6D, 0x3F, 0x9E, 0x9C, 0x77, 0x99, + 0xB5, 0x7B, 0x89, 0x59, 0x4D, 0xC5, 0xA0, 0xE1, + 0xB1, 0xFB, 0x9C, 0xDA, 0x65, 0x24, 0x99, 0xD6, + 0x09, 0x0C, 0x58, 0xFE, 0x47, 0xA2, 0xBC, 0xF8, + 0xC7, 0x5C, 0x89, 0xD9, 0x60, 0x8A, 0xA8, 0x09, + 0x20, 0xC5, 0x29, 0x92, 0x34, 0xF1, 0x44, 0x0E, + 0xA6, 0x2F, 0xEC, 0xD7, 0x13, 0xA5, 0x5B, 0x86, + 0xF3, 0x00, 0x89, 0x9B, 0x6D, 0xAD, 0xCE, 0xBC, + 0xE7, 0x08, 0x84, 0x78, 0xA9, 0xD7, 0x79, 0x24, + 0x0C, 0xEE, 0x55, 0xB7, 0xDE, 0xA3, 0x7B, 0x23, + 0x7D, 0xB8, 0xF6, 0x94, 0x53, 0xB4, 0x0B, 0xC2, + 0xC7, 0x98, 0x7E, 0xF8, 0x1D, 0x1C, 0x88, 0x55, + 0xD1, 0xCB, 0xA9, 0x27, 0x35, 0xCC, 0x35, 0x95, + 0xF7, 0x80, 0x06, 0x1C, 0x8D, 0x22, 0x94, 0x99, + 0xB9, 0xE5, 0x1C, 0xE6, 0x62, 0xDF, 0xCA, 0x75, + 0x5E, 0x8D, 0x50, 0xE8, 0x45, 0x63, 0x94, 0xEC, + 0xD4, 0xC3, 0x2A, 0x2C, 0xC2, 0x88, 0x33, 0xDF, + 0x05, 0x01, 0xAE, 0x92, 0x4C, 0xC8, 0xA9, 0xB2, + 0x95, 0x68, 0x1A, 0x86, 0x3F, 0x53, 0x83, 0x48, + 0x9A, 0x25, 0x4F, 0x78, 0x1B, 0xD4, 0x26, 0x0B, + 0x8F, 0x7B, 0x2D, 0xDC, 0x91, 0x0C, 0xEA, 0xB0, + 0x9A, 0x1C, 0x63, 0xF9, 0x2F, 0x48, 0x17, 0x5F, + 0x6B, 0x1D, 0xA7, 0x1A, 0x55, 0x44, 0x50, 0x7C, + 0x54, 0x19, 0xBE, 0x0F, 0x6E, 0x50, 0x2D, 0x2A, + 0xC7, 0x24, 0x8A, 0xD2, 0x75, 0xD0, 0x3A, 0x2D, + 0x60, 0x21, 0x76, 0x4A, 0x14, 0x40, 0xE0, 0x24, + 0xC0, 0x1E, 0x2D, 0x09, 0xCA, 0xD5, 0xED, 0xB3, + 0x8D, 0xBA, 0xD9, 0x17, 0xEB, 0x8A, 0xCC, 0x3A, + 0x2A, 0x64, 0x05, 0x5B, 0xE8, 0x7E, 0x13, 0x5C, + 0x9E, 0x97, 0x6B, 0x89, 0x70, 0xC1, 0xD7, 0xC4, + 0x6C, 0x3D, 0x42, 0x34, 0xF6, 0x4B, 0xA9, 0x81, + 0xE3, 0xEC, 0xA2, 0x63, 0xAA, 0x44, 0x1D, 0x5C, + 0x83, 0xCF, 0x10, 0x43, 0x93, 0xEF, 0xCC, 0x8D, + 0x16, 0xA0, 0xB4, 0x3B, 0x9D, 0x89, 0x1E, 0xFB, + 0x58, 0xCF, 0xCA, 0xFC, 0x66, 0x3E, 0x6F, 0x9A, + 0xF2, 0xFA, 0xFF, 0xBF, 0xF8, 0x5A, 0x5B, 0xB2, + 0x24, 0x2B, 0x2E, 0x74, 0x32, 0x9A, 0x18, 0x70, + 0x68, 0xB3, 0xB0, 0x21, 0x77, 0x4A, 0x7B, 0x7D, + 0x94, 0x1F, 0x1C, 0xC1, 0x93, 0xC5, 0x24, 0x09, + 0x47, 0xDC, 0x3C, 0xED, 0xA8, 0xF7, 0x92, 0x5C, + 0xE2, 0x35, 0xDE, 0x63, 0x3A, 0xFC, 0xD7, 0xD9, + 0x48, 0xDB, 0x64, 0x29, 0x6B, 0x70, 0xB4, 0x4C, + 0xFD, 0xB0, 0x33, 0x85, 0xDB, 0x00, 0x97, 0xFA, + 0x1C, 0x63, 0x52, 0x9B, 0x3C, 0xA2, 0xD2, 0x68, + 0x10, 0xFD, 0x76, 0x5A, 0x0E, 0xFF, 0x5B, 0x88, + 0x6D, 0x8B, 0x00, 0xDB, 0xE6, 0x34, 0x6B, 0x4A, + 0x73, 0x9C, 0x8A, 0x70, 0x60, 0x05, 0xFC, 0x99, + 0xFA, 0x9D, 0x93, 0x6E, 0xFE, 0xF7, 0xDD, 0xB2, + 0x64, 0xFF, 0x59, 0x23, 0x25, 0x43, 0xD5, 0xDE, + 0xAC, 0x05, 0xC0, 0x9F, 0x33, 0xA1, 0x29, 0xF3, + 0xDA, 0xC6, 0xC6, 0xA1, 0x41, 0x79, 0xBC, 0x80, + 0x31, 0x2E, 0x35, 0x56, 0x2C, 0x34, 0xE4, 0x4C, + 0xA8, 0x6D, 0xF4, 0x6A, 0x14, 0xA9, 0x5F, 0xE5, + 0xE7, 0xA0, 0xCE, 0x88, 0xD2, 0x95, 0xF4, 0xAE, + 0x07, 0xD5, 0x2E, 0xF1, 0x1E, 0x7F, 0x2E, 0xCD, + 0x9A, 0x8B, 0xA9, 0x96, 0x99, 0x5A, 0x0B, 0x38, + 0x2D, 0xB5, 0x02, 0xB3, 0x3B, 0xB6, 0x50, 0xC9, + 0x05, 0xEC, 0x18, 0x29, 0x79, 0x98, 0xC6, 0x24, + 0xB7, 0x15, 0xDE, 0x6B, 0x80, 0x89, 0x8A, 0x02, + 0x5D, 0x49, 0x26, 0xD8, 0x6E, 0x00, 0x82, 0x60, + 0x0B, 0x4E, 0x08, 0xB7, 0x92, 0xAC, 0x96, 0xFB, + 0xD7, 0xF9, 0x7D, 0x42, 0xAE, 0x50, 0xB1, 0x6C, + 0xB2, 0x8B, 0x3E, 0x4A, 0xFF, 0xAD, 0xF8, 0x4D, + 0x10, 0xAE, 0x0D, 0x08, 0x44, 0x4D, 0x1B, 0x02, + 0xC7, 0xE5, 0x3E, 0xB6, 0x45, 0xD7, 0xE2, 0xF3, + 0x41, 0xF1, 0xBB, 0x91, 0x2B, 0x59, 0xDA, 0xD7, + 0x49, 0x07, 0xD0, 0xBF, 0x23, 0x16, 0xAD, 0x43, + 0x79, 0xBB, 0xA9, 0xAA, 0x96, 0x84, 0x9A, 0xA4, + 0xED, 0xF2, 0x0C, 0xDF, 0x89, 0xDC, 0xC4, 0x5E, + 0x7C, 0x75, 0x85, 0x45, 0x21, 0x68, 0x77, 0x6C, + 0xB8, 0x72, 0x11, 0x6D, 0x6F, 0xBA, 0xC5, 0x1C, + 0x0B, 0x82, 0x71, 0x34, 0x36, 0xF2, 0x42, 0xCE, + 0x85, 0xA8, 0x61, 0xDE, 0xFF, 0x96, 0xF3, 0xE2, + 0x63, 0xB6, 0x01, 0xC5, 0x05, 0xC3, 0x0F, 0x46, + 0xE8, 0xD8, 0xB5, 0x30, 0xCF, 0xA7, 0xCA, 0xEF, + 0xB6, 0x83, 0xF3, 0x30, 0xF9, 0x70, 0x77, 0x08, + 0x17, 0x2E, 0x21, 0x6B, 0x2D, 0xFE, 0xD4, 0xAA, + 0x62, 0xAC, 0xED, 0x3F, 0x5F, 0x2D, 0xEC, 0x26, + 0xB5, 0x38, 0x16, 0x20, 0x9D, 0xF6, 0x7B, 0xF8, + 0x1B, 0x4D, 0x8A, 0xE8, 0xAE, 0x8A, 0x6A, 0x80, + 0xF3, 0x44, 0x2C, 0xAE, 0xF5, 0xEC, 0x5A, 0xD6, + 0xFB, 0x9D, 0x0D, 0x41, 0x67, 0x37, 0x62, 0x85, + 0xB1, 0x55, 0x47, 0xF8, 0xFD, 0x7B, 0x4D, 0x86, + 0x7D, 0xBE, 0x37, 0x1A, 0x35, 0x15, 0xEB, 0x56, + 0x38, 0xB0, 0x16, 0xDD, 0x3B, 0xF8, 0x28, 0x05, + 0x53, 0x36, 0xE1, 0x79, 0x50, 0x2B, 0x91, 0x00, + 0x24, 0x0B, 0xB4, 0x1F, 0x27, 0xE4, 0xAF, 0x55, + 0x11, 0x23, 0xBE, 0x22, 0x12, 0xFD, 0x65, 0xAC, + 0xE6, 0xA5, 0xC4, 0x0E, 0x25, 0xEC, 0x49, 0xD1, + 0x92, 0x69, 0x44, 0x5C, 0x55, 0xFE, 0x18, 0x1C, + 0xEE, 0xEF, 0xF3, 0x47, 0x4A, 0xA7, 0x65, 0x89, + 0x8B, 0x71, 0x35, 0x30, 0x27, 0xAC, 0x6B, 0x53, + 0xD2, 0xF2, 0xA0, 0x5D, 0x2C, 0xD1, 0xD7, 0xF1, + 0x58, 0xC9, 0xA7, 0xC9, 0xE5, 0x6B, 0x89, 0xA1, + 0xBE, 0xEB, 0x02, 0x86, 0xDA, 0x15, 0x73, 0xF2, + 0x5A, 0xC7, 0x59, 0x7B, 0x46, 0xAA, 0x68, 0x6C, + 0x01, 0xFB, 0x0A, 0x74, 0xAC, 0x4C, 0xD5, 0x3C, + 0x9F, 0x51, 0x1A, 0x71, 0x4E, 0x1B, 0x81, 0x81, + 0x1A, 0x56, 0x93, 0x80, 0x59, 0x9B, 0xD6, 0x42, + 0xE6, 0x93, 0x5A, 0xC3, 0xAA, 0x2B, 0xC6, 0x58, + 0x51, 0x5D, 0x62, 0x47, 0x27, 0x47, 0xDB, 0xA0, + 0x2D, 0x4F, 0x95, 0xB4, 0xC8, 0x29, 0x4C, 0xD2, + 0x9E, 0x09, 0x66, 0x30, 0xBE, 0xFF, 0x74, 0x07, + 0xC3, 0x98, 0x6E, 0x3F, 0xD1, 0xA0, 0x5D, 0xFA, + 0x29, 0x4F, 0x7F, 0x1E, 0x83, 0xFF, 0xBA, 0x4E, + 0x78, 0x4B, 0xF0, 0xC0, 0xF7, 0xD5, 0xA6, 0xC1, + 0xBF, 0x2E, 0x1E, 0x94, 0xFB, 0x8A, 0x2D, 0xC2, + 0x88, 0x68, 0xBD, 0xF9, 0x90, 0x72, 0xBA, 0x57, + 0xD9, 0x24, 0x1C, 0x81, 0x47, 0x2F, 0x22, 0x60, + 0xBE, 0x64, 0x44, 0xA6, 0xD2, 0x99, 0xE2, 0x9D, + 0xD8, 0x6A, 0x8D, 0x06, 0x96, 0x37, 0xB9, 0x9D, + 0x34, 0xAF, 0xF8, 0x62, 0x09, 0x06, 0x43, 0x70, + 0x4F, 0xCF, 0xC4, 0x53, 0x81, 0xE7, 0x22, 0x09, + 0x60, 0x17, 0xA6, 0xEE, 0xF7, 0x97, 0x14, 0xD7, + 0x54, 0x8D, 0xA7, 0x83, 0x73, 0xF4, 0x0F, 0x15, + 0x8F, 0x4C, 0x69, 0x1B, 0x92, 0xFB, 0x0D, 0xB9, + 0x1B, 0x40, 0x6B, 0xFC, 0x4D, 0xF3, 0x5B, 0x8E, + 0xDC, 0x02, 0xE2, 0x49, 0xDC, 0xF0, 0xB8, 0xBB, + 0x2C, 0xB1, 0x5D, 0x75, 0x05, 0xED, 0x33, 0x94, + 0xA7, 0x2B, 0x72, 0xBB, 0xEC, 0x33, 0x46, 0xC6, + 0xC8, 0x4A, 0xEF, 0xB8, 0xB7, 0xAD, 0x07, 0xBC, + 0xF0, 0x76, 0xDF, 0x85, 0xE0, 0x8F, 0x52, 0x98, + 0x9C, 0x0B, 0xAC, 0x5A, 0xD7, 0xFA, 0x25, 0xAD, + 0x48, 0xC5, 0x8F, 0x80, 0xC4, 0xAF, 0x92, 0x3B, + 0xB3, 0x00, 0x14, 0xD8, 0xD0, 0xC2, 0x13, 0x67, + 0x3E, 0xB1, 0x5E, 0xE8, 0x59, 0xB7, 0x40, 0xD3, + 0x14, 0x94, 0x25, 0xE8, 0xA3, 0x21, 0x37, 0xF9, + 0xDC, 0x17, 0x55, 0x62, 0x18, 0x06, 0xF4, 0x2D, + 0xBD, 0x3F, 0x5B, 0x9D, 0xF0, 0x6A, 0xAD, 0xC2, + 0xD0, 0xC9, 0x54, 0xF8, 0x1B, 0x0A, 0x55, 0xA7, + 0xD3, 0x4A, 0x5F, 0xF2, 0x58, 0xC1, 0x3B, 0x46, + 0xAA, 0xB1, 0x15, 0x2E, 0xC7, 0xE9, 0xCF, 0x76, + 0x79, 0xDD, 0xC5, 0x8C, 0x47, 0xF3, 0x2A, 0xB5, + 0x74, 0x18, 0xC8, 0x98, 0x22, 0xD7, 0xFE, 0x3D, + 0x50, 0xDE, 0xEC, 0x52, 0x25, 0x1A, 0x8D, 0xC5, + 0xC2, 0xBC, 0xBB, 0x71, 0xDC, 0x48, 0x07, 0xF1, + 0x9B, 0xC6, 0x25, 0xC3, 0x3C, 0xA6, 0xCA, 0x45, + 0xBC, 0x61, 0xA1, 0x88, 0x7A, 0xBF, 0xCC, 0x1E, + 0x45, 0xE7, 0x4D, 0x7B, 0xDD, 0x16, 0x46, 0x00, + 0x7C, 0xAE, 0x2C, 0x1C, 0x7E, 0x0C, 0x9A, 0xC1, + 0xE9, 0x39, 0x3C, 0x3B, 0x8A, 0x52, 0xEB, 0x2D, + 0x98, 0x94, 0x84, 0xA8, 0xFD, 0x19, 0x33, 0x37, + 0xC2, 0xD3, 0x7A, 0xE3, 0x06, 0x24, 0x67, 0xAC, + 0x8F, 0x40, 0xB0, 0xFB, 0x6C, 0x8D, 0xA0, 0xE9, + 0x34, 0xA8, 0xC8, 0x38, 0x56, 0xA0, 0x34, 0x8D, + 0x64, 0x3F, 0x25, 0x10, 0x2B, 0x92, 0x3C, 0xD0, + 0x48, 0xBE, 0x84, 0x29, 0x8B, 0x3B, 0xAB, 0x34, + 0xAB, 0x6A, 0xA8, 0x43, 0x83, 0xF5, 0xB9, 0x81, + 0x3D, 0xB8, 0xFA, 0x5F, 0xFF, 0x2D, 0x04, 0xD2, + 0x9A, 0x6C, 0x86, 0xA1, 0x91, 0xE1, 0x01, 0xDC, + 0x7E, 0xB1, 0xF3, 0xA2, 0x86, 0x55, 0xD8, 0x09, + 0xE2, 0xB1, 0xB0, 0xDA, 0x0B, 0xDA, 0x18, 0xB2, + 0x7B, 0x2A, 0x76, 0x42, 0x21, 0xBC, 0xB4, 0xD1, + 0x22, 0xA0, 0xC8, 0x7B, 0xA9, 0xBA, 0xA3, 0xF0, + 0xE3, 0x8C, 0x05, 0xFC, 0x3B, 0x0C, 0xFA, 0x35, + 0xD0, 0xFC, 0xAF, 0xED, 0x7B, 0x52, 0x53, 0x7F, + 0x5E, 0xEC, 0x81, 0xEF, 0x66, 0x80, 0x22, 0x8E, + 0xDA, 0x5C, 0x25, 0x0A, 0x18, 0x4B, 0x0E, 0x06, + 0x74, 0xD6, 0x4D, 0x06, 0xEF, 0x13, 0xDA, 0x8F, + 0x97, 0x28, 0x9F, 0x7F, 0x4C, 0xC1, 0x0E, 0x4A, + 0xBF, 0xDC, 0x46, 0x78, 0x07, 0x0F, 0x52, 0x9B, + 0x29, 0x28, 0x35, 0xBE, 0x54, 0x59, 0xE8, 0x03, + 0x5E, 0xFD, 0x0C, 0x4A, 0xEC, 0xFE, 0x7E, 0x60, + 0xAF, 0xC1, 0x0F, 0x8E, 0x30, 0xAC, 0x90, 0xD5, + 0xC6, 0x35, 0x65, 0x81, 0x2C, 0xEF, 0x01, 0x3F, + 0xF7, 0x67, 0x4E, 0x1C, 0x62, 0xA1, 0x29, 0x6E, + 0xE2, 0x08, 0xE4, 0xBE, 0x01, 0xE1, 0xEE, 0xDD, + 0x2F, 0xCB, 0xBC, 0xF3, 0xBF, 0xBE, 0x62, 0x96, + 0xB4, 0x7B, 0xB9, 0x14, 0x38, 0xF7, 0x78, 0xC3, + 0x7E, 0xB0, 0xB8, 0x85, 0xB3, 0x2E, 0x4F, 0xD1, + 0x12, 0xD8, 0x69, 0x7C, 0x84, 0x96, 0x41, 0x24, + 0x9F, 0x08, 0xF8, 0x6B, 0x20, 0xF7, 0xEA, 0xDC, + 0xB1, 0xA5, 0x09, 0x49, 0xE1, 0x8B, 0xC4, 0x77, + 0x9B, 0x22, 0xBB, 0x38, 0xC1, 0xD1, 0x82, 0xCC, + 0x86, 0x78, 0xE4, 0xE4, 0x56, 0xF4, 0x9B, 0x70, + 0x2C, 0xBB, 0x86, 0x52, 0x94, 0x47, 0x65, 0xE7, + 0x97, 0x17, 0xAF, 0xA7, 0x29, 0x54, 0xD6, 0xAA, + 0x38, 0x15, 0x85, 0xC8, 0xDC, 0xAB, 0x2F, 0x09, + 0x79, 0x53, 0xE1, 0xD9, 0x85, 0xF5, 0x85, 0x08, + 0xB9, 0x18, 0x6E, 0x7C, 0x1B, 0x3F, 0x3C, 0xA7, + 0xAA, 0x89, 0x03, 0xAD, 0xB2, 0x3A, 0x9F, 0x5A, + 0x13, 0x03, 0xCD, 0xB4, 0x95, 0xC1, 0xE3, 0xE7, + 0xBA, 0x6E, 0xE7, 0x6B, 0x58, 0x80, 0xE2, 0xA3, + 0x20, 0x5B, 0x76, 0x28, 0xAC, 0x82, 0x91, 0x89, + 0xE3, 0x08, 0x39, 0xAB, 0x87, 0xD9, 0x0E, 0x5B, + 0x22, 0xB9, 0x0D, 0x19, 0x7D, 0x0A, 0x86, 0xD8, + 0x95, 0x42, 0xD4, 0x13, 0xDD, 0x35, 0xA5, 0x3A, + 0x0A, 0x50, 0x7C, 0x9D, 0x16, 0x72, 0x3D, 0x8C, + 0x23, 0x78, 0x36, 0x4A, 0x8F, 0xB7, 0x65, 0xC4, + 0xD8, 0x49, 0x69, 0x82, 0xDB, 0x4D, 0xDC, 0xD3, + 0xD2, 0xAF, 0x16, 0x86, 0x7E, 0xCD, 0x79, 0xF1, + 0x4C, 0x9D, 0xDF, 0xFB, 0xD4, 0x65, 0xC2, 0x47, + 0x4F, 0x51, 0x3D, 0x62, 0xA9, 0x5E, 0x9C, 0xBB, + 0xD8, 0x3F, 0x48, 0x1F, 0xB8, 0x26, 0xDC, 0xB4, + 0xDA, 0x45, 0x01, 0x05, 0xF1, 0xA5, 0xEF, 0x1F, + 0x11, 0xA0, 0x65, 0x68, 0x7A, 0x01, 0x5C, 0xB1, + 0xC3, 0xF8, 0x94, 0xDF, 0x38, 0x5F, 0x5F, 0x01, + 0xBD, 0xCA, 0x47, 0x9D, 0x74, 0xC5, 0xB3, 0xB2, + 0x65, 0x37, 0xCA, 0x60, 0x3D, 0x57, 0x83, 0x1E, + 0x7B, 0xFE, 0xAF, 0x37, 0xF3, 0x7E, 0x14, 0x25, + 0xBF, 0x78, 0x37, 0xC7, 0xB4, 0x01, 0x17, 0xC6, + 0xFB, 0x1C, 0x96, 0x48, 0xB3, 0x6E, 0x4D, 0xDE, + 0xAC, 0x5B, 0x78, 0xD5, 0x3A, 0x1A, 0x24, 0xB4, + 0x7C, 0x37, 0xDC, 0x49, 0x08, 0xE4, 0x99, 0x65, + 0x4D, 0x47, 0x7F, 0xF4, 0x40, 0x99, 0xE9, 0xA5, + 0xEF, 0xEE, 0xBF, 0x5B, 0x13, 0xD1, 0xC4, 0x6F, + 0xED, 0x3D, 0x6D, 0xD0, 0x1B, 0x8E, 0xC7, 0x8E, + 0x80, 0xA8, 0xAC, 0xDF, 0x9E, 0xEE, 0x5E, 0x45, + 0x8C, 0x1E, 0x92, 0x4E, 0xD3, 0x60, 0x4A, 0x62, + 0x9D, 0xA7, 0x14, 0x7C, 0xC1, 0x5A, 0x00, 0x32, + 0x81, 0x5E, 0x84, 0xEB, 0x8A, 0x3A, 0x27, 0xDB, + 0xA5, 0xA6, 0x4C, 0xD6, 0xDB, 0x23, 0xDD, 0x2C, + 0x5C, 0x59, 0x75, 0x51, 0xE9, 0x7F, 0xF6, 0x38, + 0x76, 0x80, 0x5B, 0x4F, 0xD4, 0x07, 0xE4, 0xE3, + 0xE7, 0x74, 0xB1, 0x06, 0xE3, 0xEA, 0xC8, 0x97, + 0x37, 0x5B, 0x8F, 0x09, 0x76, 0x90, 0xE5, 0x5D, + 0x5B, 0x4E, 0x36, 0x59, 0x99, 0x03, 0xBD, 0x71, + 0xC9, 0xDA, 0xB2, 0x2A, 0x82, 0xA7, 0x85, 0x7B, + 0x6E, 0x33, 0xBA, 0x56, 0x6C, 0xE6, 0xE2, 0x76, + 0x9B, 0xE2, 0xF0, 0xCC, 0x76, 0xF0, 0x16, 0x1A, + 0x58, 0xC7, 0x38, 0x2E, 0xF1, 0x3D, 0x46, 0xC6, + 0x45, 0xCF, 0x85, 0x08, 0x23, 0x8D, 0xC0, 0x1A, + 0x02, 0xF5, 0x1E, 0x7D, 0xDF, 0x88, 0xEB, 0xFF, + 0xB4, 0xB9, 0xAC, 0xA6, 0x7D, 0xE2, 0xD2, 0x88, + 0x8C, 0x0B, 0xDA, 0xC9, 0x17, 0x44, 0x5C, 0x86, + 0xEC, 0x52, 0x82, 0x71, 0x5B, 0x40, 0x66, 0x83, + 0xE8, 0x7C, 0x02, 0x92, 0x3A, 0xFD, 0x81, 0x0F, + 0x3B, 0xC2, 0xDF, 0x2B, 0xFE, 0xB0, 0x68, 0xA4, + 0xF0, 0xED, 0x47, 0xF6, 0x07, 0x8D, 0x3D, 0x3E, + 0x4C, 0x79, 0x2A, 0x32, 0x51, 0x4F, 0x78, 0xEE, + 0x50, 0x0D, 0xDE, 0x32, 0x78, 0xE9, 0xE2, 0x16, + 0x7D, 0x02, 0x31, 0x5B, 0x4F, 0xC8, 0x6D, 0xBB, + 0x22, 0x44, 0x6C, 0x39, 0x1A, 0x72, 0xDD, 0xC3, + 0x29, 0x66, 0xAA, 0x95, 0xB4, 0xB3, 0x53, 0x6B, + 0x0B, 0x1B, 0xFA, 0x37, 0x0D, 0x31, 0x31, 0xAF, + 0x46, 0x10, 0xFB, 0xE6, 0xAC, 0x14, 0xA8, 0x42, + 0xBE, 0x9D, 0xDE, 0x00, 0x52, 0x7E, 0x39, 0xD2, + 0xF4, 0x5D, 0x34, 0xF7, 0x52, 0x04, 0xBC, 0x9C, + 0x17, 0xB9, 0x5F, 0xB5, 0xBC, 0x11, 0x73, 0x9A, + 0x08, 0x6B, 0x71, 0x5A, 0xC9, 0x4B, 0x11, 0xCA, + 0x05, 0x33, 0xCA, 0x07, 0xA7, 0xAA, 0x85, 0x7A, + 0x02, 0x47, 0x18, 0xB0, 0x0B, 0xE5, 0xCC, 0x75, + 0x24, 0x9B, 0x6D, 0xAF, 0xCD, 0xBB, 0x0B, 0x95, + 0x5C, 0x70, 0x82, 0xF6, 0x2D, 0xA7, 0x37, 0xED, + 0xD1, 0x65, 0x8B, 0x77, 0x1D, 0x76, 0xE6, 0xD8, + 0x11, 0xD1, 0x88, 0xEB, 0xDF, 0xD9, 0xC7, 0x9C, + 0x4C, 0x5F, 0xDF, 0x31, 0x8B, 0x63, 0x6D, 0x8E, + 0x30, 0xCE, 0x68, 0x39, 0x46, 0x75, 0xD4, 0x35, + 0x63, 0x4D, 0x34, 0x89, 0x59, 0x87, 0x15, 0x47, + 0xDF, 0x5C, 0xD9, 0x92, 0xD1, 0xC7, 0xDC, 0xC2, + 0xF0, 0x55, 0x1B, 0xA8, 0xF8, 0x57, 0xFF, 0xB5, + 0x4C, 0x97, 0xC6, 0xC8, 0x96, 0xBE, 0xA4, 0xCE, + 0x57, 0xAA, 0x71, 0x24, 0x4B, 0x7C, 0x1E, 0xA9, + 0x9B, 0xA5, 0xD2, 0xCA, 0xE8, 0x43, 0x71, 0xA5, + 0xD8, 0xE7, 0x79, 0x7F, 0xE9, 0xCD, 0xE1, 0xBF, + 0x8C, 0x9C, 0xAC, 0x93, 0x02, 0x62, 0x0C, 0xA5, + 0x44, 0xB6, 0x43, 0x3F, 0x3A, 0xF5, 0xC2, 0xA4, + 0x9F, 0x0C, 0x09, 0xC7, 0xCB, 0xA8, 0x20, 0x05, + 0x1F, 0x8C, 0x6E, 0x35, 0x88, 0x87, 0x92, 0xAE, + 0x37, 0x81, 0x49, 0x3D, 0x06, 0xA8, 0xF5, 0xA1, + 0x7B, 0xD8, 0xC4, 0x48, 0xE7, 0x35, 0x6D, 0xF4, + 0x14, 0x60, 0xDC, 0x63, 0xF4, 0x32, 0x90, 0xC1, + 0x9F, 0x9B, 0x23, 0xED, 0xC8, 0x39, 0x73, 0x04, + 0xF2, 0xF7, 0x6D, 0x3F, 0x1C, 0x71, 0x65, 0x80, + 0x6B, 0x41, 0xF9, 0xAB, 0xCB, 0xB0, 0x44, 0xFA, + 0x15, 0x37, 0xF4, 0xFF, 0x58, 0x78, 0x20, 0xB4, + 0x5A, 0x90, 0xE2, 0xC1, 0x4B, 0xC3, 0xC7, 0x81, + 0xF6, 0x75, 0x1E, 0xA4, 0x6B, 0xAB, 0xA4, 0x29, + 0xE6, 0x33, 0x50, 0xCE, 0x7D, 0xD7, 0xE5, 0x7A, + 0x4E, 0x23, 0xA2, 0xAB, 0xCD, 0x42, 0x90, 0x7F, + 0xE0, 0x33, 0xAF, 0x8A, 0x6D, 0x71, 0xC4, 0x1C, + 0xBD, 0xFA, 0xB7, 0x57, 0x57, 0xC6, 0xAA, 0x25, + 0xE6, 0x2C, 0xB2, 0x9A, 0x29, 0xF9, 0x8E, 0xF3, + 0x00, 0xB7, 0xD1, 0x95, 0x17, 0xE2, 0xDF, 0xA9, + 0x17, 0x44, 0xFF, 0x4A, 0x7A, 0xBD, 0x98, 0xB0, + 0xDF, 0x8E, 0xFB, 0x61, 0xFD, 0xCA, 0x84, 0x57, + 0xFC, 0xBB, 0xCE, 0xA8, 0x62, 0xCD, 0x73, 0x53, + 0x1E, 0x95, 0xA1, 0x20, 0x92, 0xB3, 0x14, 0x37, + 0x4C, 0x99, 0xD2, 0xDA, 0xCE, 0xA3, 0xEB, 0x1B, + 0xCF, 0x28, 0x42, 0x1A, 0xC7, 0x2C, 0x28, 0x4C, + 0x7D, 0x40, 0x5B, 0xD0, 0xE2, 0x6B, 0xA6, 0x47, + 0x92, 0xEF, 0x7A, 0x7B, 0x19, 0xF2, 0x84, 0x12, + 0x3A, 0x7B, 0xF9, 0xF3, 0xE4, 0xF8, 0x4F, 0x88, + 0x92, 0x4E, 0x19, 0x25, 0x45, 0x8A, 0x4B, 0x7C, + 0x4F, 0x24, 0xFB, 0x25, 0xBE, 0xF2, 0x10, 0x99, + 0x91, 0x0E, 0xFC, 0xDE, 0xB6, 0xCD, 0x43, 0x92, + 0xF6, 0xFD, 0x60, 0x4F, 0x4B, 0x05, 0x81, 0xD7, + 0x80, 0x48, 0xD6, 0xDD, 0x01, 0x94, 0xCE, 0x47, + 0x26, 0xA4, 0x56, 0x54, 0x25, 0x30, 0x9E, 0x14, + 0x11, 0x1D, 0xCD, 0xC2, 0xE8, 0x39, 0x19, 0x75, + 0xCC, 0xD3, 0xC0, 0x35, 0x38, 0x70, 0x6C, 0xD3, + 0xAF, 0x92, 0xCE, 0x06, 0x01, 0xB4, 0xBA, 0xB9, + 0x3D, 0x8D, 0x7E, 0x89, 0x88, 0x7B, 0xD2, 0x4A, + 0x16, 0x20, 0xC9, 0xA9, 0x3E, 0x60, 0xE5, 0x4A, + 0xCF, 0x8A, 0xB3, 0xE2, 0x00, 0x98, 0x55, 0x0D, + 0x38, 0x56, 0x8D, 0x90, 0x7F, 0xC6, 0x81, 0xC7, + 0xF9, 0x31, 0x56, 0x0B, 0xEB, 0x8B, 0xC5, 0x2E, + 0xBB, 0xB2, 0x01, 0xA6, 0xD1, 0xD2, 0x65, 0x99, + 0xD7, 0xC7, 0xF9, 0x83, 0x6F, 0x26, 0xEB, 0x47, + 0x7D, 0xBE, 0x46, 0x6E, 0xE6, 0xF2, 0x3B, 0x09, + 0xFF, 0x0D, 0x4B, 0xC8, 0xCB, 0x59, 0xB6, 0x00, + 0xC2, 0x3C, 0x4C, 0xEA, 0x66, 0x86, 0x59, 0x82, + 0xAB, 0x31, 0xB6, 0xFF, 0xAE, 0xF4, 0x91, 0x7C, + 0x45, 0x28, 0xDB, 0x03, 0xF7, 0x08, 0x51, 0xC9, + 0xCD, 0xCD, 0xD3, 0xC8, 0x4D, 0x9A, 0x23, 0x8C, + 0xFC, 0x06, 0x6F, 0x4A, 0x2E, 0xDE, 0x66, 0xCF, + 0xD0, 0xCC, 0x94, 0x2D, 0x53, 0xF1, 0x56, 0x5D, + 0xB1, 0x33, 0xCF, 0x39, 0x8F, 0x80, 0x14, 0x21, + 0xF5, 0x3C, 0xCE, 0x7E, 0xAE, 0x91, 0x60, 0x30, + 0xE8, 0x3B, 0xE8, 0x23, 0x6F, 0x82, 0x2F, 0xCA, + 0x64, 0x1C, 0x47, 0x3D, 0x56, 0xD6, 0xB8, 0xFD, + 0x78, 0xBD, 0x23, 0x0D, 0x01, 0xBB, 0x12, 0x9C, + 0xD2, 0x58, 0x00, 0xAC, 0x62, 0xB5, 0x4D, 0x68, + 0x61, 0xA4, 0x7B, 0xFC, 0xF3, 0x95, 0x3A, 0x2C, + 0x05, 0x7F, 0x1F, 0x42, 0xD7, 0xCF, 0xC5, 0xEC, + 0x83, 0xC0, 0x6A, 0x1E, 0x0D, 0x7B, 0x3B, 0x32, + 0x76, 0x75, 0xF9, 0x1A, 0x5D, 0x01, 0x9A, 0x6C, + 0x19, 0xC7, 0xFF, 0x1C, 0x60, 0xE1, 0x58, 0x6A, + 0x13, 0x86, 0x43, 0xCF, 0xB7, 0x6B, 0x30, 0xEF, + 0x3E, 0x33, 0xF2, 0xAB, 0xBE, 0xAC, 0xA0, 0xDE, + 0xD0, 0x58, 0xC4, 0x83, 0x77, 0x09, 0x4F, 0x84, + 0x24, 0xEF, 0x68, 0x2F, 0xA0, 0x6C, 0x60, 0x24, + 0x5D, 0xFF, 0xF5, 0x4C, 0xD3, 0xD7, 0x58, 0xC3, + 0x0C, 0xA9, 0x41, 0x56, 0xDD, 0x88, 0xFE, 0xB9, + 0xA8, 0xAD, 0x8F, 0xFB, 0x9A, 0x49, 0xE7, 0xCF, + 0x66, 0x9E, 0x7B, 0xCF, 0x60, 0x25, 0xAB, 0x25, + 0x5C, 0x25, 0x3C, 0xC0, 0xB1, 0xAE, 0x76, 0xC9, + 0xB1, 0xFC, 0x2A, 0xBE, 0x03, 0x54, 0xE6, 0x08, + 0xBC, 0xC7, 0xE9, 0xF9, 0x7D, 0x2B, 0x65, 0x9A, + 0x84, 0x78, 0x31, 0xA2, 0x63, 0x13, 0xF1, 0x05, + 0xBD, 0xE7, 0x4A, 0xEA, 0x6E, 0x30, 0xFC, 0x99, + 0x17, 0xE5, 0xA4, 0x9F, 0xF5, 0x59, 0xB1, 0x1F, + 0xAB, 0xF7, 0x91, 0x81, 0x0E, 0xB8, 0x8E, 0x95, + 0x8B, 0x8D, 0x1D, 0xD3, 0x68, 0x79, 0x48, 0x07, + 0xA4, 0xF8, 0xAD, 0xDD, 0x64, 0x40, 0x3B, 0xCC, + 0x78, 0x5C, 0xD9, 0x2E, 0xF7, 0x9C, 0x1B, 0x1E, + 0x89, 0x9A, 0x68, 0x8F, 0x22, 0xB5, 0x3E, 0xFC, + 0xA2, 0x23, 0x11, 0x34, 0xCE, 0x15, 0xA4, 0xB6, + 0xD8, 0x6D, 0x8F, 0x94, 0xEF, 0x20, 0x3D, 0x16, + 0xF1, 0x1A, 0xCD, 0x5F, 0xCA, 0x28, 0x44, 0x7A, + 0x80, 0x96, 0x93, 0x67, 0xAA, 0xE2, 0x06, 0x75, + 0x4B, 0xAF, 0x6E, 0xCB, 0x4A, 0x56, 0x45, 0x32, + 0xDE, 0x2D, 0x13, 0xB8, 0x0B, 0xFB, 0xD5, 0x3F, + 0x46, 0xC0, 0xDD, 0x7A, 0x7C, 0xFE, 0x12, 0xD7, + 0xC1, 0x51, 0x21, 0x0F, 0xF7, 0x9B, 0x3C, 0x6F, + 0x4B, 0x52, 0x72, 0x40, 0xE2, 0x76, 0x5B, 0x81, + 0x05, 0xEE, 0x68, 0xC1, 0x28, 0xE2, 0x11, 0xB2, + 0xA6, 0xA3, 0x47, 0x7D, 0xC6, 0x80, 0x13, 0xB8, + 0xE5, 0x99, 0x41, 0x7A, 0x8C, 0xD4, 0xB2, 0x2A, + 0x6C, 0xED, 0x8C, 0x7B, 0xE3, 0x8A, 0x88, 0x93, + 0x29, 0xF3, 0x7B, 0x4E, 0x03, 0x1E, 0xC9, 0x7C, + 0x75, 0x44, 0xAD, 0xF9, 0xAC, 0xB5, 0x22, 0xFD, + 0x93, 0x4F, 0x41, 0x95, 0x99, 0x17, 0xCE, 0x03, + 0xB1, 0x1C, 0xFF, 0x7A, 0xE5, 0xED, 0x2A, 0xC7, + 0x49, 0xE3, 0x8A, 0x39, 0x07, 0x7E, 0x19, 0x42, + 0x21, 0xA6, 0x61, 0xA2, 0x0C, 0xA3, 0x28, 0x08, + 0x77, 0x95, 0xB3, 0x7C, 0xB0, 0xBD, 0x90, 0xB5, + 0xC7, 0x08, 0x8B, 0x82, 0xC1, 0xFF, 0x92, 0x2E, + 0x71, 0xAC, 0x14, 0x8A, 0xC5, 0xE2, 0x6D, 0xEE, + 0xA9, 0x52, 0x06, 0xFE, 0xEB, 0xC8, 0x4A, 0x92, + 0xCC, 0x3B, 0x27, 0x22, 0xE0, 0x4C, 0x17, 0xEB, + 0x06, 0x88, 0x59, 0xBE, 0x25, 0x6C, 0x60, 0xAC, + 0x35, 0x30, 0x30, 0x82, 0x83, 0x02, 0x1F, 0x96, + 0xB5, 0xFD, 0x9C, 0xFA, 0x3E, 0xB8, 0x9D, 0x35, + 0x55, 0x4E, 0xCB, 0x34, 0x3F, 0x25, 0x08, 0x07, + 0xCA, 0x34, 0x39, 0xD2, 0xA3, 0xD5, 0xD4, 0x7A, + 0xA4, 0xC7, 0xC8, 0x29, 0xC3, 0xEE, 0x36, 0x5E, + 0x16, 0xFD, 0x71, 0xC4, 0xB4, 0x04, 0xF2, 0x38, + 0x37, 0x69, 0x81, 0x0C, 0xC0, 0x52, 0x1C, 0x1D, + 0xC4, 0xFF, 0x74, 0x1B, 0xD4, 0x50, 0x59, 0x74, + 0x92, 0x50, 0xCC, 0x34, 0xED, 0x1C, 0x23, 0xE1, + 0x36, 0x2B, 0x92, 0x32, 0xD6, 0xAC, 0x21, 0x65, + 0x9E, 0x4C, 0x51, 0x5F, 0x5F, 0xCB, 0xE9, 0x3C, + 0x7F, 0x3A, 0x74, 0xB6, 0x05, 0x30, 0x41, 0x1F, + 0x76, 0xEA, 0x20, 0xAA, 0x5E, 0xC2, 0xE3, 0xBA, + 0xD9, 0x86, 0x6B, 0x8E, 0x0D, 0xEB, 0xB6, 0xCF, + 0xE0, 0xE8, 0xF5, 0xFD, 0xE4, 0x3C, 0x29, 0x7C, + 0xD9, 0xDB, 0xCA, 0xA7, 0x87, 0xC5, 0xE0, 0x65, + 0x47, 0xBB, 0x73, 0xEE, 0xF9, 0xE7, 0xA4, 0x42, + 0x56, 0xD7, 0xCA, 0x0D, 0x6A, 0xAB, 0x70, 0xCA, + 0x6C, 0x2B, 0x59, 0x3C, 0x8B, 0x5A, 0x19, 0x90, + 0xC7, 0x50, 0x96, 0x21, 0x04, 0x06, 0x7A, 0x6B, + 0x99, 0xF3, 0x73, 0x7A, 0x02, 0xEC, 0xB5, 0x1B, + 0x32, 0xD7, 0xCA, 0x56, 0x66, 0xD4, 0xC1, 0xB6, + 0x39, 0x8A, 0x10, 0x29, 0x0C, 0x81, 0x80, 0x72, + 0x8E, 0x8C, 0x0F, 0x1E, 0x93, 0x61, 0xF7, 0x00, + 0xA1, 0xA4, 0x65, 0x5F, 0xD4, 0x4E, 0xD9, 0x62, + 0x27, 0x65, 0xF9, 0x21, 0xE3, 0x8C, 0xC8, 0xFC, + 0x14, 0xC7, 0x08, 0x8C, 0x9C, 0x0C, 0xFD, 0x97, + 0x08, 0x4D, 0x8B, 0x41, 0x47, 0x76, 0x68, 0x34, + 0x86, 0xC1, 0x64, 0xC4, 0xB9, 0x0B, 0x83, 0x36, + 0x77, 0xB9, 0x63, 0x8D, 0x04, 0xC0, 0x60, 0x2B, + 0x15, 0x2D, 0x98, 0xA6, 0x84, 0xF0, 0x28, 0x91, + 0x88, 0x63, 0x1F, 0x01, 0x2E, 0xE1, 0x60, 0xB1, + 0x17, 0xB8, 0x2A, 0x65, 0x94, 0x46, 0x23, 0xAD, + 0x2D, 0xA2, 0x89, 0x4C, 0xFC, 0x58, 0x8C, 0x8B, + 0x34, 0x04, 0x37, 0xF0, 0x5D, 0xC4, 0xA6, 0x0B, + 0xF8, 0x0C, 0xF8, 0x69, 0xCD, 0xC2, 0xDD, 0x9B, + 0x1F, 0x76, 0xE5, 0xAE, 0x54, 0x30, 0x0C, 0xD9, + 0x58, 0x22, 0x98, 0x0F, 0x93, 0xDB, 0x31, 0xB0, + 0x1A, 0x6A, 0xE1, 0xE1, 0xA7, 0x3C, 0x2B, 0x83, + 0x49, 0x7D, 0x40, 0x94, 0x09, 0xEF, 0x40, 0xC3, + 0x65, 0x2B, 0xE5, 0x40, 0x9A, 0xE7, 0x19, 0xBE, + 0x3E, 0xF2, 0x1C, 0x4B, 0x6D, 0x41, 0x20, 0x42, + 0xE5, 0x8E, 0xB4, 0x8B, 0x44, 0xF7, 0x06, 0xB6, + 0x00, 0x50, 0x58, 0x69, 0xA4, 0xA3, 0x26, 0x10, + 0x2F, 0x79, 0xA4, 0xA0, 0xA6, 0xC9, 0x65, 0x14, + 0xC5, 0xDC, 0x1D, 0x77, 0x0D, 0xA8, 0xAB, 0xF4, + 0x60, 0x41, 0xED, 0xED, 0x93, 0x82, 0xE0, 0xA4, + 0x74, 0xBB, 0xF6, 0xE9, 0xAA, 0xDB, 0x73, 0x3A, + 0x0C, 0x50, 0xEF, 0x23, 0x65, 0x98, 0xA1, 0x2A, + 0xF9, 0x20, 0xF4, 0xFF, 0x60, 0x53, 0x32, 0x06, + 0x8E, 0xC3, 0x96, 0xDF, 0x2F, 0xC0, 0xEF, 0x26, + 0xB0, 0x83, 0x29, 0x5F, 0xDB, 0x4A, 0x0B, 0x42, + 0x97, 0x8B, 0xFC, 0x6D, 0xAA, 0x13, 0xF3, 0x57, + 0xEB, 0x48, 0xF4, 0x1D, 0xD1, 0x75, 0x44, 0x0E, + 0xEB, 0x5E, 0xB6, 0x79, 0xED, 0xCF, 0xC6, 0xDE, + 0x5D, 0x1D, 0x09, 0x22, 0x51, 0x40, 0x52, 0x58, + 0xC0, 0x98, 0x8B, 0xE1, 0xE3, 0x91, 0x3A, 0xEE, + 0x2D, 0xBE, 0xCB, 0x77, 0x35, 0xFF, 0x03, 0xA8, + 0x6A, 0x8C, 0xC2, 0x88, 0x2F, 0x59, 0x39, 0x72, + 0x31, 0xFA, 0x90, 0xE3, 0x54, 0x38, 0xE0, 0xE5, + 0xB2, 0x65, 0xDC, 0xD7, 0x0B, 0x03, 0x64, 0xCF, + 0xCA, 0x70, 0x30, 0x0B, 0x36, 0x8B, 0x9A, 0xB2, + 0x6F, 0x42, 0x49, 0xB1, 0x62, 0xED, 0x4D, 0xB3, + 0x75, 0xAF, 0x58, 0xE6, 0x7D, 0xC6, 0x75, 0x13, + 0xB7, 0x9B, 0xE4, 0x3B, 0x79, 0xC3, 0x35, 0x79, + 0x9F, 0x21, 0x08, 0x9A, 0x59, 0xC7, 0x6F, 0x2C, + 0x85, 0x53, 0x8B, 0xF6, 0xAE, 0x02, 0x03, 0x5E, + 0x42, 0xF9, 0x0F, 0x04, 0xD7, 0x12, 0x22, 0x41, + 0x1A, 0x34, 0xD7, 0x27, 0x2C, 0x84, 0xFF, 0x74, + 0x43, 0x7A, 0x85, 0x26, 0x00, 0xD3, 0x72, 0x62, + 0xFB, 0x8D, 0x6F, 0x40, 0x0C, 0x06, 0xCF, 0xC8, + 0x9A, 0x5D, 0xD2, 0x6B, 0x55, 0x05, 0x25, 0xCF, + 0xF2, 0xEE, 0x4D, 0x3C, 0x79, 0xD3, 0xDE, 0x72, + 0x36, 0x9B, 0xA3, 0x53, 0xCF, 0xF6, 0x4D, 0xAD, + 0x10, 0xEB, 0xF0, 0x91, 0x34, 0x21, 0x01, 0x04, + 0x84, 0xC5, 0xA2, 0x01, 0x60, 0x6E, 0x7E, 0xE8, + 0x33, 0xE7, 0xEA, 0xF8, 0x09, 0x44, 0x7C, 0x40, + 0x63, 0xDF, 0x47, 0xA5, 0x6D, 0x78, 0xDF, 0x0E, + 0x18, 0x4D, 0x62, 0x09, 0xCD, 0x43, 0x53, 0xFB, + 0x67, 0x2C, 0x52, 0xC4, 0x35, 0x8E, 0xD7, 0x06, + 0xFC, 0x1C, 0x3A, 0xBA, 0xF3, 0xFE, 0xAF, 0x27, + 0x0B, 0x29, 0xA3, 0x3E, 0xA4, 0xE1, 0xE3, 0x70, + 0x7C, 0x05, 0x49, 0xDA, 0xE5, 0x37, 0xAB, 0xF3, + 0xF4, 0x7B, 0xED, 0xFB, 0x83, 0x47, 0x26, 0xD7, + 0xEE, 0x81, 0x25, 0xF0, 0xD9, 0x23, 0xFE, 0xFD, + 0xC1, 0xBE, 0x76, 0x20, 0x63, 0xB6, 0x74, 0xC6, + 0xF3, 0xCF, 0x33, 0x56, 0x62, 0x89, 0x50, 0xA9, + 0x9D, 0xA6, 0x2C, 0xAD, 0x8A, 0xFF, 0x0A, 0x4B, + 0xDA, 0x38, 0x6C, 0xD4, 0x5D, 0x5D, 0x0D, 0x71, + 0x8A, 0x26, 0xEE, 0x00, 0x11, 0x69, 0xEC, 0x1A, + 0xEA, 0xEE, 0x42, 0x06, 0x9A, 0xBF, 0xBF, 0xE3, + 0xA8, 0x87, 0xEA, 0x68, 0x2F, 0x30, 0xE4, 0x31, + 0xB8, 0x49, 0x22, 0x9E, 0x9E, 0xCA, 0xAB, 0x0C, + 0x7A, 0x57, 0x51, 0x50, 0xCF, 0x27, 0xCD, 0x01, + 0x4D, 0x1B, 0x7C, 0x5C, 0xBE, 0xC7, 0x7D, 0x47, + 0xF2, 0xFF, 0x8E, 0xA2, 0xDE, 0xB4, 0xC0, 0x6B, + 0x70, 0x63, 0x54, 0x52, 0x21, 0x6B, 0xDA, 0xBD, + 0xD6, 0xC8, 0xF7, 0x33, 0xAD, 0x13, 0x6C, 0x91, + 0x80, 0xCC, 0x6C, 0x99, 0x97, 0xE0, 0x59, 0x6E, + 0x83, 0x72, 0xF1, 0x19, 0xE5, 0xDD, 0xB3, 0x49, + 0xE3, 0x50, 0xD7, 0x1B, 0x68, 0x5E, 0xE6, 0x6D, + 0x5A, 0x7F, 0x59, 0xFA, 0x37, 0xE4, 0xDD, 0xEF, + 0xE4, 0x4B, 0xBF, 0x78, 0x25, 0x89, 0x49, 0xA4, + 0x1E, 0x51, 0x43, 0xA4, 0x43, 0xBD, 0x6A, 0x5A, + 0x1D, 0xCC, 0x9D, 0x14, 0xC1, 0x15, 0xDC, 0x1A, + 0x2F, 0xF1, 0x82, 0x5C, 0x13, 0x23, 0x3C, 0x72, + 0xA0, 0xA8, 0x3A, 0x70, 0x99, 0xD5, 0x29, 0xF4, + 0x57, 0x8C, 0xAB, 0xE7, 0x1A, 0xC9, 0x79, 0x53, + 0x5B, 0x55, 0x0D, 0xD9, 0x10, 0xAD, 0xD7, 0xD5, + 0xB5, 0x9C, 0xFC, 0xC9, 0x0B, 0x73, 0x23, 0xA2, + 0x88, 0x68, 0x1B, 0x35, 0x8F, 0x95, 0x92, 0x4B, + 0x11, 0x37, 0x6A, 0xA8, 0xBF, 0x53, 0x0A, 0xEE, + 0x56, 0x01, 0xE0, 0x61, 0x38, 0x4D, 0x7E, 0xC7, + 0xCE, 0xC2, 0xBE, 0x20, 0x1E, 0x00, 0xC5, 0x2B, + 0x9C, 0x41, 0x03, 0xC4, 0xD8, 0xD5, 0xB9, 0x8F, + 0x98, 0xF9, 0x06, 0x6B, 0xC1, 0x71, 0x0E, 0x49, + 0xA4, 0xA3, 0x27, 0xD3, 0x08, 0xAF, 0xA2, 0xFB, + 0xB6, 0xC8, 0xB4, 0x30, 0xC8, 0x4C, 0x97, 0x2F, + 0x52, 0x1E, 0xBF, 0x30, 0x04, 0xE1, 0x47, 0x2D, + 0x7D, 0xB2, 0xC4, 0x8B, 0x41, 0x7A, 0xC7, 0xBA, + 0x6E, 0x29, 0x57, 0x33, 0xC2, 0xFB, 0xDE, 0x8F, + 0x31, 0x2B, 0xD4, 0xD1, 0x71, 0x28, 0x81, 0x12, + 0x08, 0x28, 0xAF, 0xBB, 0x1F, 0x1F, 0x24, 0x6D, + 0xB8, 0xAD, 0xBF, 0x72, 0x1F, 0x1F, 0xB9, 0x2A, + 0x5B, 0xD8, 0x12, 0x07, 0x5D, 0xEA, 0xDC, 0x15, + 0x87, 0xC0, 0xE5, 0xE3, 0x3A, 0xE1, 0xF3, 0xF1, + 0xA5, 0x5A, 0x16, 0x94, 0xBC, 0x7A, 0xBF, 0x9F, + 0x6F, 0x7E, 0x1D, 0xD1, 0xE8, 0x27, 0xEA, 0x17, + 0xD6, 0xCD, 0x4C, 0x9B, 0x40, 0x3C, 0xA7, 0xEA, + 0x53, 0x04, 0x7B, 0x0A, 0xC7, 0x58, 0x54, 0x92, + 0x70, 0x14, 0x0C, 0x8D, 0xB6, 0x2C, 0xA7, 0xA0, + 0x4C, 0xF1, 0x68, 0x7E, 0xFC, 0xA0, 0x7E, 0x71, + 0x03, 0x88, 0xAD, 0x0B, 0x97, 0x8C, 0xD9, 0x40, + 0x51, 0xD8, 0xE2, 0x41, 0x16, 0xBC, 0x03, 0xA7, + 0xB6, 0x3C, 0x85, 0xB8, 0x24, 0x7C, 0x11, 0x9D, + 0x55, 0x82, 0x19, 0x5F, 0x93, 0x5E, 0x4C, 0xBD, + 0x4B, 0x15, 0x66, 0xBE, 0x1F, 0x5D, 0xF4, 0xBD, + 0xA7, 0xE1, 0x59, 0x2A, 0xAB, 0x54, 0xDF, 0x22, + 0x7E, 0x21, 0xDF, 0x99, 0x57, 0x1D, 0xA2, 0xDF, + 0x04, 0xEE, 0xC1, 0x97, 0x53, 0xD9, 0x66, 0xE7, + 0x95, 0xD8, 0xB4, 0x1E, 0xFB, 0x59, 0x2F, 0xBF, + 0x10, 0x33, 0x9F, 0xA2, 0xA2, 0x10, 0x6D, 0x6D, + 0x03, 0x0A, 0xEB, 0x30, 0x44, 0x32, 0x9E, 0x5E, + 0x0C, 0x3B, 0xDC, 0xA9, 0x33, 0x44, 0x89, 0xC1, + 0x26, 0x3E, 0x7D, 0x79, 0xB9, 0x36, 0xFC, 0xDA, + 0x9C, 0xA2, 0x93, 0x6F, 0x7E, 0x28, 0x06, 0xF7, + 0x55, 0x99, 0x74, 0xEE, 0xD9, 0x23, 0xD6, 0x51, + 0xA3, 0x8E, 0xA5, 0x46, 0x03, 0xD4, 0xAB, 0x81, + 0x10, 0x61, 0x09, 0x13, 0xF9, 0x95, 0xF7, 0x74, + 0x57, 0x55, 0x78, 0x65, 0x63, 0x73, 0x22, 0xD2, + 0x73, 0xEB, 0x4B, 0xAE, 0xD4, 0xD0, 0x8D, 0x5C, + 0x34, 0x3C, 0xD6, 0xF9, 0x85, 0xF5, 0x85, 0x0C, + 0xA2, 0xDC, 0x15, 0xE7, 0xBA, 0xCB, 0xD7, 0x54, + 0x6E, 0x47, 0x71, 0xFE, 0xCC, 0xD7, 0x12, 0x55, + 0x5C, 0x87, 0x81, 0x58, 0x8B, 0xE2, 0x24, 0x5D, + 0x13, 0x65, 0x02, 0xC9, 0x2B, 0x27, 0xE9, 0xFC, + 0x67, 0x36, 0x17, 0xB1, 0x7D, 0xDA, 0x2D, 0x8C, + 0x84, 0xE3, 0xEA, 0x6F, 0x18, 0x8A, 0x3A, 0xBE, + 0x7F, 0xF2, 0x35, 0x74, 0x72, 0x0C, 0x6D, 0xFF, + 0x0F, 0x23, 0xFF, 0xED, 0x53, 0x2F, 0xCF, 0x66, + 0xF3, 0x96, 0x19, 0xE2, 0x06, 0x12, 0xAA, 0x7A, + 0x16, 0xCF, 0xCB, 0xEF, 0x21, 0x62, 0x80, 0x3A, + 0xF6, 0x8B, 0x68, 0x94, 0x30, 0xDB, 0x3D, 0xF5, + 0x9F, 0x6F, 0x86, 0x3F, 0x7F, 0x35, 0xB7, 0xCC, + 0x71, 0xA8, 0x8C, 0x6A, 0x8A, 0x4F, 0xB7, 0xE0, + 0x5A, 0xA1, 0xB4, 0x25, 0xF8, 0x90, 0x72, 0xDA, + 0x28, 0xAB, 0x3A, 0xDC, 0xDB, 0x53, 0xC3, 0xC4, + 0x3A, 0x4C, 0x89, 0xF2, 0xCE, 0x4B, 0x32, 0x76, + 0xE0, 0xAC, 0x3E, 0xFC, 0x57, 0x76, 0xEB, 0x00, + 0x69, 0x63, 0x0D, 0xB1, 0x72, 0xE2, 0x1C, 0x9B, + 0x59, 0xB6, 0x31, 0x3A, 0x58, 0x0B, 0x3A, 0xB9, + 0x45, 0xA6, 0x6B, 0xC8, 0xDE, 0xC2, 0xB6, 0x56, + 0x00, 0xBB, 0xA8, 0xFA, 0xA5, 0xBD, 0x0D, 0xB9, + 0x2D, 0x0A, 0xAF, 0x35, 0x45, 0x78, 0xD9, 0x1D, + 0x4C, 0xE5, 0x7F, 0x55, 0x72, 0x07, 0xCD, 0x75, + 0xA3, 0x20, 0x95, 0x00, 0xDF, 0x60, 0x46, 0x8A, + 0xE3, 0xBF, 0x70, 0x3C, 0x69, 0xDC, 0xD5, 0xD0, + 0x66, 0x96, 0x76, 0x48, 0xB4, 0x32, 0x86, 0xE5, + 0x0B, 0x1E, 0xFD, 0xEA, 0x86, 0xD6, 0x32, 0xD6, + 0x01, 0x8F, 0xFA, 0x18, 0x5C, 0x84, 0x28, 0x88, + 0x2C, 0x8F, 0x5C, 0x86, 0x2E, 0x55, 0x8A, 0x01, + 0x1E, 0x88, 0x6D, 0x83, 0x8E, 0xE0, 0xEF, 0xCB, + 0x16, 0xCD, 0xEE, 0xB6, 0xA9, 0x8D, 0x17, 0x8F, + 0xE1, 0xE4, 0xF2, 0x61, 0x2C, 0xB0, 0x1E, 0x00, + 0x11, 0x07, 0xEC, 0x9A, 0xE1, 0xB4, 0xAD, 0x12, + 0xE9, 0x46, 0x44, 0x78, 0xA9, 0xDF, 0x79, 0x08, + 0x8F, 0x75, 0x8A, 0x7C, 0xAD, 0xAC, 0x9F, 0x96, + 0x96, 0xEA, 0x9A, 0xCE, 0xA6, 0x9E, 0xCA, 0x85, + 0xA3, 0x25, 0x64, 0x10, 0x03, 0xB9, 0x64, 0x2F, + 0xE4, 0x1E, 0x0E, 0xB8, 0x15, 0xD3, 0x50, 0xA1, + 0x70, 0x65, 0xCC, 0xDC, 0xC0, 0xE7, 0x5E, 0x3D, + 0x78, 0x38, 0x72, 0xB5, 0xBA, 0x8A, 0x5A, 0xE3, + 0x1A, 0x26, 0xFA, 0x16, 0xC4, 0x34, 0xC4, 0xA9, + 0xFE, 0xED, 0xA7, 0x00, 0x1D, 0xAF, 0x73, 0x8F, + 0x66, 0xB4, 0xA7, 0x30, 0x34, 0x37, 0x30, 0x23, + 0x1C, 0xCE, 0x76, 0x6B, 0x60, 0x25, 0xC4, 0x21, + 0xC0, 0x2F, 0x6F, 0x2D, 0xD1, 0x19, 0xE6, 0x66, + 0x41, 0x8F, 0x73, 0x64, 0xF4, 0x0D, 0xDC, 0x88, + 0x23, 0x38, 0x3F, 0xAB, 0x94, 0x5B, 0x92, 0x17, + 0x96, 0x62, 0xAC, 0x50, 0xD1, 0x42, 0xEE, 0x0E, + 0x75, 0x44, 0xE3, 0x0D, 0xA4, 0xCB, 0x70, 0x32, + 0x6A, 0x07, 0xB6, 0xF2, 0x62, 0x6E, 0xBC, 0xFA, + 0x9C, 0xB3, 0x51, 0x50, 0xA2, 0x31, 0xEE, 0xC4, + 0xB8, 0x30, 0x29, 0xA7, 0x91, 0x16, 0x1F, 0x5D, + 0x2E, 0x99, 0x29, 0x27, 0xC4, 0x8C, 0x45, 0x95, + 0xF4, 0x16, 0xB3, 0x9E, 0x18, 0xA1, 0xD7, 0x2D, + 0x14, 0xD2, 0x1A, 0x04, 0x59, 0x2C, 0x7B, 0xC8, + 0xDE, 0x94, 0x26, 0x0A, 0x90, 0xF1, 0x00, 0x14, + 0xA0, 0x71, 0x92, 0x78, 0x71, 0x9E, 0xA2, 0x12, + 0xD5, 0x0D, 0xC8, 0x88, 0x06, 0x05, 0xF8, 0xDA, + 0x60, 0xD1, 0x71, 0xE8, 0x62, 0x35, 0x33, 0x30, + 0xD6, 0x5D, 0xF4, 0x25, 0x00, 0x5C, 0x18, 0x82, + 0x67, 0x07, 0xD6, 0xF8, 0xCF, 0x86, 0x79, 0xDF, + 0xF2, 0x95, 0xF4, 0xF9, 0xE1, 0x4C, 0x16, 0x7B, + 0x8D, 0xAB, 0x2B, 0x88, 0xAD, 0xBA, 0xF0, 0x50, + 0x2E, 0x93, 0x49, 0x34, 0xBC, 0x3A, 0x5C, 0x44, + 0xFA, 0xB4, 0x43, 0x54, 0x32, 0xE7, 0xF5, 0xCA, + 0x41, 0xE7, 0x84, 0xCE, 0x28, 0x06, 0x58, 0xA9, + 0xED, 0x9B, 0x98, 0xEC, 0x20, 0x33, 0x25, 0xCE, + 0xBA, 0xB6, 0x0C, 0xCB, 0x0D, 0xD2, 0x61, 0x71, + 0x59, 0x86, 0x97, 0xA0, 0xCA, 0xFA, 0x14, 0x03, + 0x87, 0xAE, 0x90, 0xD4, 0x6E, 0xAC, 0x6A, 0xA8, + 0xDD, 0x58, 0x66, 0x3E, 0xA5, 0x90, 0xB1, 0x22, + 0x8C, 0x28, 0x2F, 0x28, 0x63, 0x5D, 0x65, 0xFE, + 0x18, 0xAF, 0x17, 0x38, 0xCE, 0x6E, 0x02, 0x77, + 0x4C, 0xC2, 0x96, 0xA9, 0xBB, 0x89, 0x74, 0x58, + 0x97, 0xC4, 0xF7, 0xB3, 0x57, 0xC5, 0x92, 0x47, + 0x21, 0x09, 0xB2, 0xA5, 0xC3, 0x7D, 0xC6, 0x02, + 0x1A, 0x92, 0x0E, 0x3D, 0xEE, 0x91, 0x80, 0x6D, + 0xB0, 0xD0, 0xD5, 0x69, 0x5C, 0x52, 0x38, 0x98, + 0xA6, 0x85, 0xA9, 0xA3, 0x64, 0x77, 0x15, 0x80, + 0xDE, 0x83, 0x83, 0x9A, 0x16, 0x27, 0x22, 0xF2, + 0x59, 0x25, 0x54, 0x91, 0x82, 0x7B, 0xCA, 0x24, + 0x03, 0x50, 0x4C, 0xE7, 0x23, 0xA8, 0x23, 0x4A, + 0x4A, 0xE9, 0x5D, 0x91, 0xDE, 0x19, 0xA3, 0xFD, + 0xB6, 0x8B, 0x01, 0xF4, 0xD0, 0x4E, 0xE6, 0x2C, + 0xF8, 0xD5, 0x82, 0xC7, 0xCF, 0x10, 0xBE, 0xBA, + 0x89, 0xE8, 0x7F, 0xE2, 0x4F, 0x80, 0xA8, 0x28, + 0x62, 0x1A, 0x86, 0x7C, 0x66, 0x91, 0x82, 0x2E, + 0x18, 0x4B, 0x41, 0x63, 0x41, 0x0B, 0x7F, 0xF2, + 0x61, 0xAD, 0x6F, 0xAC, 0x1A, 0x10, 0x3B, 0x90, + 0xEE, 0xCC, 0x8A, 0x68, 0x26, 0x48, 0x32, 0x16, + 0x1A, 0x46, 0x07, 0xED, 0x15, 0xE8, 0x2B, 0x50, + 0x04, 0xA5, 0x81, 0xFE, 0xD8, 0xEA, 0x24, 0x86, + 0x25, 0x63, 0xD7, 0x4C, 0x61, 0xD7, 0x8E, 0xA8, + 0xC1, 0x22, 0xCE, 0x89, 0xB2, 0xCD, 0xD1, 0xC0, + 0x56, 0x7A, 0x35, 0x65, 0xD8, 0xB6, 0xE4, 0xB1, + 0x93, 0x0F, 0x94, 0xE5, 0x69, 0x32, 0xB7, 0x91, + 0x21, 0xB1, 0x2A, 0xBE, 0xF2, 0xF8, 0x94, 0xB7, + 0x09, 0x90, 0x6B, 0x12, 0x7D, 0x1B, 0xDA, 0xCE, + 0xE0, 0xA6, 0x8B, 0xBE, 0x33, 0x7B, 0xF3, 0xF7, + 0xED, 0xC3, 0xEC, 0x01, 0xDC, 0x1B, 0x70, 0x9C, + 0xEB, 0xFA, 0xED, 0x16, 0xB3, 0x87, 0x75, 0xB5, + 0x26, 0x83, 0x90, 0x60, 0x73, 0x03, 0x63, 0xCA, + 0x20, 0xCD, 0x57, 0x85, 0x4C, 0xA4, 0x4D, 0xEE, + 0x8A, 0x41, 0x75, 0x01, 0x1B, 0x51, 0x8A, 0x9D, + 0xC1, 0x0E, 0x33, 0xBB, 0x9C, 0xC4, 0x4B, 0x4B, + 0x04, 0x26, 0x1F, 0x0A, 0x05, 0x4F, 0xC4, 0xDA, + 0xB2, 0x12, 0xA5, 0x96, 0x6E, 0x6E, 0x97, 0xEC, + 0xF8, 0xB2, 0x64, 0xB7, 0x3F, 0x85, 0x6F, 0x0E, + 0xD8, 0x33, 0x4B, 0xA7, 0x7A, 0x1C, 0xCB, 0x2F, + 0xE3, 0xA8, 0xD9, 0xC0, 0x4B, 0xDC, 0xE7, 0xC1, + 0x79, 0xCA, 0xFA, 0x7B, 0xDE, 0x20, 0xEA, 0x06, + 0xBE, 0x8A, 0x99, 0x47, 0x04, 0x66, 0xD5, 0x7B, + 0xD2, 0xDF, 0x0B, 0x8B, 0x1D, 0x63, 0xE4, 0x38, + 0xDB, 0x9B, 0xA5, 0x3A, 0xA9, 0x0E, 0xAE, 0xAC, + 0x47, 0xD5, 0x4E, 0xF6, 0xDF, 0x27, 0x5D, 0xE4, + 0x0A, 0x36, 0xC9, 0xCA, 0x8C, 0x1F, 0x48, 0xCA, + 0xD8, 0x10, 0xE3, 0x58, 0x08, 0x47, 0x0E, 0xB9, + 0xF1, 0x48, 0xAE, 0xF4, 0x42, 0x3F, 0x2A, 0x7D, + 0xB8, 0xEA, 0x11, 0x0C, 0x36, 0xE4, 0x83, 0x2B, + 0x15, 0x89, 0xB8, 0xB9, 0xCB, 0x0D, 0xA4, 0xDA, + 0x2C, 0xAA, 0xF0, 0x92, 0x56, 0x4D, 0xA1, 0x7B, + 0xAA, 0x78, 0xC4, 0x5B, 0x19, 0xB5, 0x39, 0xCB, + 0xAA, 0x09, 0x99, 0x30, 0x32, 0xB2, 0x8F, 0x93, + 0xB6, 0x89, 0x49, 0x99, 0x0D, 0x1A, 0xD6, 0xA1, + 0x96, 0x3D, 0x1A, 0x98, 0xDE, 0xF1, 0xC8, 0xEE, + 0x9A, 0x03, 0x95, 0xC8, 0xD4, 0x75, 0x6F, 0x8C, + 0x8B, 0x0A, 0x17, 0xEE, 0x6A, 0xFA, 0x33, 0x26, + 0xD2, 0x52, 0x41, 0xD8, 0x8B, 0xAD, 0xCF, 0x87, + 0x47, 0x0A, 0xEB, 0x1D, 0x7A, 0xF6, 0x84, 0x70, + 0xD9, 0xA7, 0x06, 0xEC, 0x73, 0xCE, 0x46, 0x0B, + 0x4E, 0xB0, 0x26, 0xBE, 0x93, 0xD9, 0xC2, 0x1D, + 0x2B, 0xC7, 0x64, 0x9F, 0x1B, 0x68, 0x43, 0xCD, + 0xE9, 0x95, 0x3B, 0xD9, 0xFB, 0xFF, 0xCC, 0x2A, + 0x7F, 0x84, 0x4F, 0x0A, 0x07, 0x0F, 0xFA, 0x80, + 0x65, 0x48, 0x29, 0x5C, 0x63, 0x0B, 0x5F, 0x0C, + 0x03, 0xEF, 0x3E, 0x87, 0x0A, 0x6F, 0x44, 0x7A, + 0x5E, 0xBD, 0xD5, 0xF3, 0x13, 0x9D, 0x6B, 0x38, + 0x7E, 0x78, 0xDB, 0x36, 0xF6, 0xD7, 0x8E, 0x4E, + 0x20, 0xF8, 0xDC, 0x1F, 0xCF, 0xEA, 0x1B, 0x04, + 0x52, 0x62, 0xDF, 0xA4, 0xCC, 0xEE, 0x89, 0x67, + 0x3C, 0x56, 0x5B, 0xE1, 0x0B, 0xB3, 0x31, 0xDD, + 0xEE, 0x53, 0xC7, 0x9F, 0xE6, 0x1F, 0x87, 0x7C, + 0x06, 0xD5, 0xC2, 0xC2, 0xEC, 0x51, 0x69, 0xBD, + 0xAB, 0xA2, 0x22, 0xDE, 0x71, 0xD3, 0x08, 0xA8, + 0x15, 0x14, 0x56, 0x15, 0xF0, 0xA9, 0xE4, 0x54, + 0x93, 0x35, 0xD6, 0xD0, 0x00, 0x92, 0x58, 0xDF, + 0x71, 0x16, 0x7D, 0x01, 0x97, 0xE4, 0x14, 0x9B, + 0x80, 0x1A, 0xB7, 0x9F, 0xCE, 0xCF, 0xBE, 0x2C, + 0xF4, 0x15, 0x05, 0xAC, 0x31, 0xA4, 0x31, 0x4E, + 0x25, 0x05, 0x9B, 0x3E, 0xA3, 0x6D, 0x58, 0xAD, + 0xC2, 0xF7, 0x3F, 0xA3, 0x64, 0xF1, 0x4C, 0x32, + 0x60, 0x00, 0x54, 0x89, 0x56, 0x16, 0xCC, 0x5C, + 0x14, 0xD2, 0xB1, 0xC1, 0x5D, 0xB7, 0x06, 0x70, + 0x00, 0xE8, 0x4A, 0x97, 0xDB, 0x46, 0xE3, 0x74, + 0xD4, 0xD6, 0x33, 0x56, 0x65, 0xF5, 0x45, 0x1E, + 0xA1, 0x03, 0x7D, 0x42, 0x10, 0x95, 0x32, 0x62, + 0x39, 0x71, 0xE0, 0x30, 0xBC, 0x92, 0x32, 0x36, + 0x06, 0xB7, 0x00, 0x04, 0xD2, 0x80, 0x7A, 0xDE, + 0xDD, 0xDD, 0x56, 0x49, 0x0F, 0x12, 0xAE, 0x46, + 0x18, 0xAC, 0x1F, 0xC1, 0x70, 0x9F, 0xC1, 0xE9, + 0xC8, 0xEB, 0x18, 0x4D, 0x72, 0x47, 0x08, 0x38, + 0x30, 0x00, 0xD3, 0x99, 0xE7, 0xBC, 0xB1, 0x34, + 0xA7, 0x65, 0x60, 0x9C, 0x30, 0xDE, 0xA6, 0x0E, + 0x7A, 0x05, 0x96, 0x4A, 0xAD, 0xED, 0x11, 0xE7, + 0xCC, 0xB3, 0xCB, 0x44, 0xB4, 0x9F, 0x4F, 0x95, + 0x4E, 0x45, 0xE4, 0xB0, 0xC4, 0x64, 0x6E, 0x8C, + 0x05, 0xE2, 0xCD, 0x7B, 0xC2, 0x3A, 0xF6, 0x3D, + 0xFF, 0xF6, 0xF9, 0x8A, 0xC8, 0xBA, 0x07, 0x89, + 0x56, 0xD5, 0x69, 0x81, 0xB6, 0x89, 0xF5, 0x0A, + 0xDA, 0x02, 0xCC, 0x8D, 0x01, 0x5A, 0x4A, 0x3E, + 0x00, 0x92, 0x40, 0x1D, 0x36, 0x1A, 0x36, 0x06, + 0x72, 0xA8, 0x63, 0x0C, 0xF4, 0xB6, 0xEA, 0x97, + 0x2A, 0x37, 0xC9, 0xE8, 0x81, 0x4B, 0xF4, 0x52, + 0xA5, 0x0A, 0x67, 0x8B, 0x46, 0x1D, 0x84, 0x78, + 0xF3, 0xAC, 0x86, 0x3E, 0x99, 0x65, 0x18, 0xE0, + 0x4F, 0x6B, 0xEA, 0x23, 0x11, 0x55, 0x3F, 0xF0, + 0xC3, 0xCD, 0x76, 0x68, 0x13, 0xCB, 0x74, 0x70, + 0xE0, 0xA7, 0x68, 0x8D, 0xAC, 0x8D, 0x86, 0x23, + 0x87, 0xF5, 0x29, 0x81, 0x2E, 0x61, 0x2C, 0x68, + 0xF5, 0x3E, 0x96, 0xD0, 0xEF, 0x1F, 0x8B, 0x05, + 0x52, 0xB3, 0x55, 0xF4, 0x13, 0xC5, 0xDC, 0xE7, + 0x65, 0xC4, 0xFD, 0x76, 0x4B, 0x9E, 0x90, 0x28, + 0x0F, 0xEC, 0xCD, 0x2D, 0x42, 0x05, 0x7D, 0x0B, + 0xCA, 0xCA, 0x28, 0x5D, 0x74, 0x4F, 0xB9, 0x03, + 0x7D, 0x38, 0x33, 0xB6, 0xF5, 0x72, 0x81, 0x68, + 0x3C, 0x23, 0xC5, 0x14, 0x74, 0xFB, 0x51, 0xE4, + 0xF4, 0xBC, 0x62, 0x48, 0x29, 0xD4, 0xC0, 0x1A, + 0x6E, 0x6F, 0x8B, 0x20, 0xA0, 0x83, 0x47, 0xD1, + 0xE1, 0x04, 0xB6, 0x81, 0xB6, 0x76, 0x0F, 0xF3, + 0x3B, 0x5D, 0x77, 0xE1, 0x45, 0x40, 0xB6, 0xAB, + 0x59, 0x6F, 0x59, 0xC4, 0x9F, 0xF5, 0x85, 0x4E, + 0xB1, 0xB2, 0x60, 0x97, 0xEA, 0x0A, 0xA6, 0xAF, + 0x9F, 0xAD, 0xA8, 0x7F, 0xC7, 0x76, 0x99, 0x6B, + 0xF9, 0x50, 0x7A, 0x55, 0x42, 0x94, 0xCC, 0x53, + 0x5F, 0x0F, 0xD3, 0xDB, 0x7A, 0x0F, 0x81, 0xC8, + 0x5F, 0xBB, 0x27, 0x64, 0x53, 0x09, 0x5A, 0xCC, + 0x82, 0x9E, 0x84, 0x9E, 0x1B, 0x19, 0x68, 0xDD, + 0xA0, 0x90, 0xCE, 0xF9, 0x33, 0xE5, 0x61, 0xF0, + 0xFF, 0x01, 0x93, 0xEA, 0x94, 0x6B, 0x3E, 0xE9, + 0x06, 0x33, 0x0D, 0x83, 0x7C, 0xC1, 0x44, 0x4A, + 0x5E, 0x13, 0xA4, 0xAD, 0x60, 0xA7, 0x8E, 0xF1, + 0x2C, 0xED, 0x11, 0xCA, 0x2E, 0x55, 0x67, 0x4B, + 0x1D, 0x84, 0xE8, 0xB2, 0x32, 0xB6, 0xC1, 0x15, + 0x7F, 0xD9, 0x70, 0xF7, 0xEB, 0xF0, 0x6F, 0x5D, + 0xE3, 0x27, 0xA4, 0xF2, 0xBB, 0xF9, 0xA8, 0xF2, + 0x13, 0x37, 0x89, 0x4F, 0x2D, 0xE7, 0xD6, 0x37, + 0xE8, 0x30, 0x29, 0x7E, 0xD1, 0x2E, 0x00, 0x0E, + 0x0D, 0xCA, 0x53, 0x93, 0x92, 0x92, 0xCE, 0x8C, + 0xA4, 0xE7, 0x9F, 0xF1, 0x51, 0xDE, 0x15, 0x06, + 0x33, 0x84, 0x70, 0x24, 0x37, 0xB5, 0xFE, 0x6A, + 0xB9, 0x64, 0x2B, 0x50, 0xA0, 0x26, 0x8A, 0x00, + 0x96, 0x5B, 0xFE, 0xAF, 0xD4, 0xC6, 0xE3, 0x17, + 0xF2, 0xAB, 0xAB, 0xF3, 0xE3, 0xF0, 0x03, 0x73, + 0x90, 0xBE, 0x6C, 0x04, 0x6D, 0xCA, 0x8F, 0x9C, + 0x0B, 0x35, 0xE1, 0xCA, 0x39, 0x81, 0xB2, 0x6F, + 0xD5, 0x0B, 0xC7, 0xCD, 0x0D, 0x6C, 0xD4, 0x30, + 0xBD, 0x7A, 0x25, 0x01, 0xB0, 0x28, 0x65, 0xA8, + 0xE7, 0x8D, 0xFD, 0x9F, 0xE5, 0xAD, 0x8E, 0xFD, + 0xD4, 0x16, 0x1F, 0xA7, 0x58, 0x6B, 0x43, 0xE1, + 0x46, 0x61, 0x66, 0xB7, 0xFE, 0x4B, 0x09, 0xD4, + 0xE7, 0x60, 0x8A, 0x72, 0x10, 0xB8, 0xB9, 0x11, + 0x0E, 0x52, 0x8D, 0x4B, 0xEE, 0x55, 0x89, 0xC3, + 0x2D, 0x04, 0x66, 0x8E, 0xCE, 0x2D, 0x33, 0xCF, + 0xF7, 0x8C, 0xB8, 0xE7, 0x33, 0x5B, 0x93, 0x95, + 0x37, 0x6D, 0x9B, 0xAA, 0xD5, 0x1E, 0xFA, 0x56, + 0x92, 0xAE, 0x2A, 0x61, 0x33, 0x99, 0xDE, 0xD1, + 0xFE, 0x05, 0xAA, 0x2D, 0x2A, 0xE0, 0x70, 0x3C, + 0x78, 0x99, 0x52, 0xCB, 0x35, 0x89, 0x49, 0x4F, + 0xD7, 0x3F, 0x5D, 0x36, 0x92, 0x20, 0x42, 0x43, + 0x02, 0xBC, 0xE0, 0xE9, 0xE0, 0xDF, 0x06, 0x62, + 0x4D, 0x95, 0x90, 0x32, 0x23, 0x04, 0x4D, 0x06, + 0xAA, 0x29, 0xE8, 0x7A, 0xD6, 0xD5, 0x8F, 0x0F, + 0xF4, 0x76, 0x89, 0x1E, 0x6F, 0x75, 0x89, 0xE5, + 0x4C, 0x12, 0xA8, 0x1D, 0xB2, 0x79, 0x51, 0xFC, + 0x84, 0x3E, 0xF0, 0x04, 0xE5, 0x73, 0x0B, 0x65, + 0x79, 0xAC, 0x6A, 0x88, 0x6E, 0xCA, 0x24, 0xBF, + 0x20, 0x8C, 0x51, 0x26, 0xFE, 0x79, 0x40, 0xEB, + 0x17, 0xF7, 0xFF, 0x6F, 0xAC, 0x9F, 0x55, 0x48, + 0xD5, 0x12, 0x73, 0xBF, 0x23, 0xE5, 0xD4, 0x42, + 0xAA, 0x2C, 0x11, 0xAB, 0xE8, 0x17, 0x39, 0x0C, + 0x38, 0x62, 0xFC, 0x6E, 0x3D, 0x00, 0xE6, 0xDF, + 0x2B, 0x35, 0x8A, 0x0B, 0x11, 0xA6, 0x4E, 0xFC, + 0x27, 0x3E, 0xAD, 0xFD, 0x51, 0xFB, 0x91, 0x13, + 0x0A, 0x52, 0x59, 0x08, 0xF1, 0x30, 0x9A, 0x65, + 0x04, 0xDB, 0xBF, 0xF2, 0x62, 0xDD, 0x88, 0x3A, + 0x9B, 0x8F, 0x48, 0x12, 0x34, 0x3A, 0x7E, 0x2C, + 0xBF, 0xC6, 0x6C, 0xCF, 0xBC, 0xBD, 0x75, 0x2E, + 0x92, 0xD4, 0x24, 0x58, 0x19, 0xDA, 0x25, 0xA5, + 0x07, 0x31, 0x13, 0x53, 0x58, 0x58, 0xC1, 0x03, + 0x26, 0x53, 0x24, 0x8C, 0x22, 0x54, 0x58, 0xCD, + 0xB5, 0xE8, 0x55, 0x74, 0x42, 0xE3, 0x0A, 0x20, + 0x2F, 0x04, 0xC7, 0xB3, 0x82, 0x67, 0x57, 0xDC, + 0x58, 0xC8, 0x8B, 0xE3, 0xE3, 0x29, 0x7C, 0x57, + 0xA1, 0xBC, 0x3C, 0xA5, 0x0B, 0x8F, 0xEC, 0x79, + 0xD3, 0x6D, 0x91, 0xF6, 0x39, 0xA6, 0xFD, 0x67, + 0x26, 0xDD, 0xFD, 0xFE, 0x2C, 0x87, 0xF6, 0xDE, + 0x12, 0x8B, 0xA7, 0x3C, 0xDE, 0xA3, 0x52, 0x9A, + 0x71, 0xB2, 0xC9, 0x65, 0xC4, 0xBC, 0x43, 0xDF, + 0x6B, 0x89, 0x1F, 0xDB, 0x25, 0x09, 0x6B, 0x47, + 0x39, 0xE2, 0xD8, 0x69, 0x15, 0x99, 0xC9, 0x61, + 0x89, 0x33, 0x85, 0x66, 0x7B, 0x2A, 0x07, 0xD4, + 0x2B, 0x42, 0x06, 0x45, 0xD9, 0x8A, 0x01, 0xEF, + 0xBF, 0xF6, 0x4A, 0x64, 0x5A, 0x4E, 0x4D, 0xEC, + 0xC5, 0xAC, 0x2E, 0x5E, 0xA4, 0x1B, 0x41, 0xE3, + 0xD9, 0x8B, 0x91, 0xF0, 0xF4, 0x4C, 0x11, 0x3D, + 0xE5, 0x1B, 0x53, 0x57, 0xF8, 0x18, 0xCB, 0xF7, + 0xB5, 0x53, 0x51, 0x1E, 0xB8, 0x29, 0x9E, 0xE8, + 0xD7, 0xF2, 0x6F, 0x8A, 0x9B, 0x9F, 0xC7, 0x85, + 0xA3, 0xB6, 0xD9, 0xAC, 0xD8, 0xB7, 0x44, 0x80, + 0xF4, 0x8A, 0xC5, 0x6B, 0x25, 0xB2, 0xD8, 0xBF, + 0x0C, 0xA6, 0xD2, 0xC0, 0x5B, 0x48, 0x37, 0x88, + 0x28, 0x52, 0xD5, 0x31, 0x1D, 0x02, 0x9D, 0x37, + 0x15, 0x60, 0xA3, 0x08, 0x86, 0xF9, 0xCA, 0x62, + 0x58, 0x18, 0xA1, 0x1B, 0xCF, 0x20, 0x30, 0x69, + 0x9A, 0x9F, 0xE2, 0x2A, 0xED, 0xA2, 0x63, 0x8C, + 0xA7, 0xBC, 0x8C, 0x68, 0xB5, 0x00, 0xE4, 0x04, + 0xC4, 0x8F, 0x91, 0x67, 0xEF, 0xB5, 0x9C, 0xBA, + 0xC7, 0x74, 0x1F, 0x6F, 0x20, 0xE5, 0x19, 0x13, + 0xCD, 0xB4, 0x96, 0x38, 0x5D, 0xE7, 0x93, 0x1E, + 0x5B, 0x96, 0xBC, 0xF8, 0x68, 0x08, 0xD5, 0x46, + 0x69, 0x10, 0x0E, 0xBB, 0x5D, 0xB9, 0xFC, 0xE5, + 0x90, 0xE1, 0x58, 0x31, 0x0B, 0xC2, 0x08, 0x10, + 0x94, 0x21, 0xD2, 0x36, 0x46, 0x22, 0x89, 0xAB, + 0x28, 0x6C, 0x5D, 0x56, 0xB9, 0x78, 0x86, 0xD1, + 0x07, 0x26, 0xE9, 0x20, 0x80, 0x9F, 0x30, 0xB4, + 0xB2, 0x10, 0xE3, 0xA6, 0x61, 0x9C, 0x8A, 0xA0, + 0xD2, 0x2A, 0x37, 0x45, 0xB8, 0x75, 0x5A, 0xC9, + 0xE5, 0x81, 0x12, 0xCB, 0x74, 0xBC, 0x41, 0xB1, + 0x75, 0x34, 0xBC, 0x6E, 0x8F, 0xEC, 0xF1, 0xB6, + 0xE0, 0xC6, 0xAD, 0xAF, 0x8A, 0x42, 0xB7, 0x8E, + 0x16, 0xFC, 0x5A, 0xC4, 0xA3, 0x41, 0xC5, 0xC4, + 0xDB, 0x07, 0x9C, 0x5D, 0xB7, 0x71, 0x24, 0xB8, + 0x93, 0x72, 0x0A, 0x08, 0xD8, 0x01, 0xCC, 0x79, + 0x52, 0xE7, 0x24, 0x32, 0x5E, 0x59, 0xCF, 0x01, + 0xBA, 0xAC, 0x67, 0x47, 0x40, 0x33, 0x69, 0x6F, + 0x6A, 0x02, 0xC9, 0xD8, 0x6C, 0x22, 0x33, 0x05, + 0x68, 0xB3, 0x29, 0x52, 0x67, 0xF1, 0x61, 0x2A, + 0xB8, 0x67, 0x1C, 0x69, 0x52, 0xA6, 0x13, 0x00, + 0x32, 0x6B, 0x09, 0xCC, 0xEE, 0xC7, 0x16, 0x0E, + 0x7F, 0xEA, 0xD7, 0x8D, 0xB9, 0x8A, 0x80, 0x62, + 0x0A, 0x60, 0xC0, 0x32, 0xD9, 0x8F, 0xBE, 0xA2, + 0xF9, 0x79, 0x4F, 0xC9, 0x08, 0x58, 0x69, 0x2D, + 0x57, 0x52, 0xF3, 0x08, 0x65, 0xA7, 0xA3, 0x61, + 0x27, 0xC0, 0x5B, 0x58, 0x64, 0x39, 0x99, 0xC7, + 0x33, 0x73, 0x4F, 0x30, 0x61, 0x37, 0x13, 0xE1, + 0x75, 0xDB, 0xF5, 0x40, 0x37, 0x38, 0x03, 0x56, + 0x79, 0xCC, 0xC5, 0x48, 0xF1, 0x29, 0x62, 0x39, + 0x81, 0x4F, 0xBE, 0x85, 0x43, 0xB8, 0x3A, 0xC7, + 0xF9, 0x46, 0xFB, 0x99, 0x21, 0xF1, 0x0B, 0x27, + 0x1E, 0x1D, 0x56, 0xD1, 0x22, 0x2F, 0x2C, 0xFA, + 0x6B, 0x16, 0x78, 0xEA, 0x0A, 0x3D, 0x56, 0xC0, + 0x56, 0xDE, 0x06, 0x92, 0x50, 0x57, 0x94, 0xBD, + 0x2D, 0x7F, 0x4A, 0x26, 0x32, 0x9E, 0xFC, 0xBA, + 0x0C, 0x14, 0xAF, 0x5A, 0xC5, 0x56, 0x72, 0x4A, + 0xB5, 0xE8, 0x8F, 0x62, 0x06, 0xE0, 0x1F, 0x6A, + 0x7E, 0x66, 0x19, 0xD3, 0x98, 0xA8, 0xCE, 0xAE, + 0xA9, 0xDE, 0x2D, 0x86, 0x43, 0xE8, 0xF5, 0x9D, + 0x4B, 0x60, 0x99, 0xC6, 0x90, 0xF9, 0xEC, 0xFA, + 0xAC, 0x24, 0x43, 0xE1, 0x83, 0x7D, 0xB9, 0xA5, + 0x81, 0xC1, 0xA1, 0xED, 0x87, 0xF3, 0x93, 0xA6, + 0x15, 0x1B, 0xBC, 0x4B, 0x27, 0x50, 0xE8, 0xEB, + 0x2B, 0x6F, 0xF1, 0x32, 0xFE, 0xB7, 0x5D, 0x99, + 0xA9, 0x43, 0x3A, 0x7A, 0x23, 0x3F, 0x72, 0x79, + 0x44, 0x8E, 0xDA, 0x98, 0xD0, 0xBD, 0x66, 0x9B, + 0x23, 0xDA, 0x2F, 0xF4, 0x15, 0xF9, 0xEA, 0x81, + 0xB5, 0x08, 0x32, 0xD8, 0x31, 0x3E, 0x34, 0x3C, + 0x44, 0x2C, 0x88, 0xE8, 0x68, 0x06, 0x34, 0x91, + 0xB5, 0x81, 0x48, 0xEA, 0x9B, 0x03, 0x27, 0x13, + 0x1D, 0xE0, 0x55, 0xD7, 0x83, 0xE0, 0x8E, 0x1A, + 0xC7, 0xCA, 0x69, 0xBC, 0x2E, 0x66, 0x9C, 0x5B, + 0x36, 0xA3, 0xCA, 0x6E, 0x84, 0xBC, 0xD2, 0xCF, + 0x06, 0x86, 0x47, 0xE1, 0xEE, 0x48, 0x41, 0xBE, + 0xE3, 0x71, 0xD0, 0xC8, 0xDD, 0xA7, 0xDC, 0xCA, + 0x0D, 0x0A, 0xC2, 0x29, 0xBE, 0x8E, 0x21, 0xDC, + 0x09, 0xC9, 0x41, 0x33, 0xC2, 0xED, 0x40, 0xF8, + 0x4A, 0x45, 0x37, 0x17, 0xD4, 0xFC, 0xE5, 0x16, + 0x4C, 0x36, 0xDB, 0x2C, 0x22, 0x33, 0x90, 0xB4, + 0xFA, 0x83, 0x68, 0x6E, 0xCC, 0x49, 0xCD, 0x3B, + 0x4A, 0x8E, 0xF2, 0xA1, 0x7C, 0xD5, 0x6D, 0x25, + 0xF8, 0x8B, 0x80, 0xC2, 0x3B, 0xC6, 0xF1, 0x7D, + 0xA6, 0x75, 0x02, 0x9C, 0xC1, 0x78, 0xC2, 0xD2, + 0x6B, 0x9F, 0x13, 0x57, 0x2C, 0xD0, 0xD5, 0x30, + 0x69, 0xC7, 0x5D, 0x88, 0x6A, 0x57, 0x9C, 0x23, + 0xF9, 0x1C, 0xCE, 0x8B, 0x07, 0xF3, 0xB9, 0x15, + 0xAB, 0x9E, 0x66, 0x99, 0xD2, 0x3E, 0x52, 0x07, + 0x9D, 0x85, 0x7D, 0xAC, 0x19, 0x63, 0xF6, 0x51, + 0x43, 0x28, 0x6D, 0xD0, 0xD9, 0xAB, 0x02, 0x1D, + 0xF7, 0xC8, 0xF0, 0xAA, 0x0B, 0x1A, 0x22, 0xB5, + 0x4A, 0x11, 0x40, 0x00, 0x12, 0x2D, 0xB6, 0xBC, + 0x34, 0x01, 0xFA, 0xF0, 0xE0, 0xAA, 0xD4, 0xD9, + 0xAF, 0x6E, 0x73, 0x6F, 0x63, 0xAD, 0xF4, 0x29, + 0x9D, 0x54, 0x31, 0xB2, 0x17, 0xBE, 0xFD, 0x44, + 0x0A, 0xE7, 0x44, 0x85, 0x87, 0x80, 0x91, 0x48, + 0xC0, 0x7B, 0x26, 0xF1, 0x93, 0x3F, 0x55, 0x99, + 0x18, 0xEC, 0x84, 0xA6, 0xC8, 0x3D, 0x54, 0x47, + 0xD5, 0x51, 0x3B, 0x44, 0xF6, 0x1D, 0x3B, 0x3A, + 0x67, 0x55, 0xCF, 0x39, 0xB9, 0xEC, 0x14, 0x98, + 0x64, 0xA9, 0x1F, 0x15, 0x94, 0xB1, 0x77, 0x5A, + 0x33, 0x40, 0xAD, 0x43, 0x53, 0x55, 0xBF, 0x32, + 0x29, 0xAE, 0xF2, 0x2B, 0xD0, 0x1A, 0x6C, 0x20, + 0xA2, 0xD3, 0x53, 0xFB, 0xA7, 0x00, 0xF5, 0xF1, + 0xC6, 0x61, 0x59, 0xB7, 0x07, 0x2E, 0xE4, 0x91, + 0xD6, 0x63, 0xF0, 0xD5, 0x3C, 0x82, 0x18, 0xFF, + 0xEB, 0x19, 0x46, 0x48, 0x3D, 0xBE, 0x8C, 0x96, + 0x32, 0x82, 0x6F, 0xF6, 0x39, 0xDF, 0x28, 0xFA, + 0xFA, 0x6F, 0x26, 0x67, 0xAF, 0xB7, 0x1A, 0x1A, + 0x5E, 0xB2, 0x15, 0xDF, 0xC0, 0x14, 0x6C, 0x05, + 0x61, 0xCF, 0xB9, 0x06, 0xD5, 0x3C, 0x9B, 0x08, + 0xA2, 0xE5, 0xD8, 0x66, 0x14, 0x71, 0xE9, 0x77, + 0xA2, 0x7E, 0x57, 0x25, 0x1B, 0xAD, 0x12, 0x07, + 0x27, 0xC4, 0x91, 0x3F, 0xE2, 0x91, 0xD9, 0xE4, + 0xB0, 0xD5, 0x43, 0x85, 0x34, 0x50, 0x31, 0xAD, + 0x62, 0x8B, 0x5F, 0x6E, 0x82, 0x2C, 0x95, 0x06, + 0x53, 0x55, 0xD1, 0x31, 0x95, 0xAE, 0x4C, 0xD8, + 0x06, 0x3D, 0xE9, 0x9A, 0x0A, 0x9C, 0xA2, 0x6C, + 0xB1, 0x89, 0x3B, 0xD9, 0x55, 0x42, 0x34, 0x7C, + 0x4B, 0x32, 0x57, 0x0A, 0x5D, 0x4F, 0xA8, 0xC3, + 0x6D, 0x28, 0x0A, 0x20, 0x8E, 0x16, 0xF3, 0xD3, + 0x9A, 0x61, 0x08, 0x7F, 0x77, 0x39, 0x3E, 0xFD, + 0x82, 0x3B, 0x83, 0x18, 0x81, 0x1C, 0xBE, 0x25, + 0x72, 0x20, 0xD1, 0x9D, 0x3D, 0x6C, 0xC0, 0xC7, + 0xA0, 0x4C, 0x85, 0xA1, 0x54, 0x1B, 0x30, 0x77, + 0x89, 0x12, 0x87, 0xFB, 0x93, 0xE5, 0xF9, 0xBE, + 0x33, 0xD2, 0xFB, 0xD9, 0xB7, 0xD3, 0x8F, 0xBE, + 0x91, 0x1B, 0x63, 0x8A, 0x69, 0x06, 0x4C, 0x5E, + 0x1B, 0xA0, 0x74, 0x03, 0xD0, 0x00, 0xDF, 0xD1, + 0xB7, 0x4E, 0xAD, 0x6D, 0x48, 0x9F, 0x8B, 0x28, + 0x0C, 0x40, 0xDD, 0xA6, 0x72, 0x88, 0x89, 0x18, + 0x0B, 0xAD, 0xE0, 0x8D, 0x6B, 0xCD, 0x2D, 0xC9, + 0x58, 0x43, 0x95, 0xCD, 0x3A, 0x82, 0xEF, 0x9B, + 0xCB, 0xE4, 0xF9, 0xB5, 0xAF, 0x3B, 0x48, 0x3B, + 0xFF, 0xD1, 0x67, 0x27, 0x1D, 0x9A, 0xF8, 0x9C, + 0xE7, 0xD0, 0x12, 0x2C, 0xF1, 0xE3, 0x80, 0x77, + 0xB5, 0xD4, 0x32, 0xEC, 0x45, 0xCF, 0x1C, 0xAF, + 0x6A, 0xEC, 0x37, 0x2B, 0xBC, 0xCF, 0xD5, 0xB1, + 0x13, 0xA7, 0xF8, 0x94, 0xFA, 0xB3, 0x3D, 0x5D, + 0xCD, 0x32, 0x7C, 0xFB, 0xE3, 0x7E, 0xC8, 0x8C, + 0xD8, 0x8C, 0xC2, 0x8A, 0x8A, 0x82, 0x0C, 0x08, + 0x34, 0xD5, 0xA0, 0xCD, 0x73, 0x85, 0x4D, 0xAA, + 0xDA, 0xAA, 0x03, 0x87, 0x66, 0xC9, 0xA4, 0x64, + 0x08, 0xB9, 0x97, 0x10, 0x26, 0x32, 0xE6, 0xB0, + 0x46, 0x71, 0x8F, 0x15, 0xB4, 0xA3, 0xE5, 0x63, + 0x5A, 0x3C, 0x48, 0x05, 0xAD, 0x04, 0xC3, 0x7B, + 0x44, 0x08, 0x02, 0xC8, 0x66, 0x6A, 0xC1, 0x4E, + 0x67, 0x43, 0xC7, 0xFE, 0x65, 0xCE, 0x0A, 0xB0, + 0x41, 0xCE, 0x95, 0x52, 0x2E, 0x72, 0x72, 0x3C, + 0xCD, 0x88, 0xA1, 0xCA, 0x1B, 0xF0, 0xFB, 0x02, + 0xC0, 0x07, 0x08, 0x24, 0xC6, 0xCD, 0xBE, 0xD3, + 0xCE, 0x0A, 0xC0, 0x9F, 0x9B, 0xB2, 0xA8, 0x81, + 0xB5, 0xB1, 0xB3, 0x37, 0xC7, 0x6F, 0xA8, 0xA3, + 0x45, 0xF2, 0x6D, 0x4D, 0xB8, 0x0C, 0x67, 0xD2, + 0x2B, 0x37, 0x68, 0x8A, 0x61, 0x02, 0xF0, 0x30, + 0x40, 0xA6, 0x7D, 0xEE, 0x64, 0x6A, 0xF5, 0x79, + 0xC7, 0xBE, 0xB4, 0x8F, 0x3E, 0x4B, 0xA8, 0x21, + 0x55, 0x8C, 0xDE, 0xB3, 0x0E, 0xBC, 0x77, 0xF1, + 0x6B, 0x5D, 0x3A, 0x6A, 0x2D, 0x96, 0x60, 0x8A, + 0x34, 0x38, 0x10, 0xD7, 0x7B, 0x9D, 0x50, 0xB2, + 0xFE, 0xD3, 0xE9, 0x59, 0x88, 0x17, 0xBF, 0xBA, + 0xF9, 0x77, 0xA5, 0x94, 0xEC, 0x04, 0x7D, 0x32, + 0xF3, 0x28, 0x42, 0x06, 0xFC, 0x56, 0x8E, 0xEE, + 0x68, 0xEA, 0xC9, 0x59, 0xA7, 0xB2, 0x32, 0x40, + 0x3A, 0x09, 0xB0, 0xF9, 0xDB, 0xC0, 0x99, 0xA5, + 0xF4, 0x06, 0xFD, 0x39, 0xE5, 0xD6, 0x07, 0x46, + 0xF4, 0xDE, 0x73, 0x70, 0x1A, 0xBF, 0x8B, 0x62, + 0xB2, 0x5E, 0xAD, 0x0C, 0x4E, 0x6D, 0x64, 0x5C, + 0x61, 0x5B, 0x31, 0xF3, 0x60, 0x59, 0xED, 0x86, + 0x4E, 0xCC, 0xCB, 0x32, 0xE5, 0x5A, 0xF2, 0xD2, + 0xBC, 0x3D, 0x85, 0xD7, 0xA0, 0xFE, 0x54, 0xCF, + 0x31, 0xCB, 0xAC, 0xF5, 0x31, 0xD2, 0x72, 0x37, + 0x6B, 0xC8, 0x68, 0xEE, 0x9E, 0xD9, 0x4A, 0xD7, + 0x0C, 0xE8, 0x53, 0xF2, 0x1A, 0x34, 0xAC, 0xEB, + 0x54, 0x00, 0x57, 0x71, 0x37, 0xCF, 0x81, 0xD3, + 0xF6, 0x89, 0xFB, 0x9B, 0xAC, 0x18, 0xB1, 0x02, + 0xC1, 0x44, 0x89, 0xCC, 0x25, 0x06, 0xF6, 0x96, + 0x8A, 0xA2, 0xCF, 0xF2, 0x0A, 0x8D, 0xB1, 0xB7, + 0xF5, 0x1B, 0xA0, 0x7D, 0xA6, 0xA5, 0xD6, 0xEB, + 0x37, 0xB1, 0x5F, 0x94, 0xEE, 0xF2, 0xD2, 0xE9, + 0x86, 0x7F, 0x9D, 0xCE, 0x8F, 0xB8, 0x0E, 0x19, + 0xC2, 0x60, 0x2C, 0x4D, 0xF1, 0x1D, 0x15, 0x24, + 0x8E, 0x3F, 0xC8, 0xFC, 0x97, 0x36, 0x5C, 0x17, + 0x99, 0x0D, 0x1B, 0xDB, 0x60, 0xCF, 0x97, 0x4A, + 0x60, 0xF8, 0xB3, 0xA7, 0x9B, 0xBF, 0x25, 0x14, + 0x16, 0x32, 0x44, 0x6D, 0x34, 0x49, 0x1A, 0x70, + 0xA8, 0x33, 0x2C, 0x0A, 0xFD, 0x65, 0x4A, 0x3C, + 0xB9, 0x01, 0xF0, 0xFA, 0x36, 0x27, 0x64, 0xC7, + 0x17, 0xC8, 0xC5, 0x0C, 0xFD, 0x7D, 0x50, 0x00, + 0x7C, 0x07, 0xA6, 0x1C, 0x52, 0xA4, 0xD9, 0x08, + 0xEA, 0x79, 0xAF, 0x73, 0x48, 0x56, 0x6E, 0xB6, + 0x61, 0x72, 0x88, 0x39, 0x3D, 0x8D, 0xC2, 0x38, + 0xE0, 0xFA, 0x01, 0xD6, 0x5A, 0xB2, 0x84, 0xBB, + 0x04, 0x7F, 0x21, 0xF3, 0x64, 0xE7, 0x01, 0x1B, + 0xF7, 0x50, 0x67, 0xB0, 0x3F, 0xB2, 0x31, 0xEA, + 0x0E, 0x57, 0x04, 0x4E, 0xD7, 0xD8, 0x01, 0x80, + 0x45, 0xB4, 0xB9, 0x65, 0xD8, 0x58, 0xDB, 0x99, + 0xA4, 0xAF, 0xFF, 0xE2, 0xCC, 0x6B, 0xD4, 0x3A, + 0x60, 0x09, 0x84, 0x4F, 0x38, 0x72, 0x86, 0xB7, + 0x0B, 0xF7, 0x7F, 0xBF, 0x12, 0x90, 0x1A, 0xDF, + 0x8B, 0xAE, 0xF8, 0x16, 0x4F, 0xB4, 0x7E, 0xF9, + 0x22, 0x77, 0x00, 0xE0, 0x80, 0xAE, 0xB6, 0x4B, + 0x98, 0xA0, 0x22, 0x06, 0xF9, 0x7D, 0x68, 0x6B, + 0xBD, 0x46, 0xA1, 0x6C, 0x18, 0x86, 0x95, 0x35, + 0x50, 0x39, 0x96, 0x7D, 0x5E, 0x04, 0xD3, 0xD2, + 0xFF, 0x1F, 0x95, 0xEC, 0x9B, 0xEC, 0xFD, 0x94, + 0x4E, 0x8F, 0x65, 0xAA, 0x3C, 0xFA, 0x3D, 0x79, + 0x93, 0x04, 0x11, 0xB2, 0x8C, 0x0E, 0xB2, 0xDE, + 0x4A, 0xDD, 0x0F, 0x3B, 0x66, 0xD1, 0xA6, 0x6E, + 0x9F, 0x64, 0xC4, 0x8B, 0x38, 0xF9, 0x8E, 0x33, + 0x8B, 0x04, 0xA4, 0x16, 0x51, 0x83, 0xBC, 0xCB, + 0xC6, 0x7E, 0xC7, 0xF1, 0xFB, 0x9B, 0xAC, 0x18 }; static const struct gmac_test_data gmac_test_case_1 = { @@ -569,4 +8741,37 @@ static const struct gmac_test_data gmac_test_case_3 = { }, }; +static const struct gmac_test_data gmac_test_case_4 = { + .key = { + .data = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 + }, + .len = 16 + }, + .iv = { + .data = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 + }, + .len = 12 + }, + .aad = { + .data = gmac_plaintext, + .len = 65376 + }, + .plaintext = { + .data = NULL, + .len = 0 + }, + .gmac_tag = { + .data = { + 0xde, 0xb4, 0xd1, 0x3e, 0xf7, 0x55, 0x99, 0x1b, + 0x40, 0x8a, 0x5c, 0xdc, 0xf3, 0x38, 0xfb, 0x30 + }, + .len = 16 + } +}; + + #endif /* TEST_CRYPTODEV_GCM_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_hash_test_vectors.h b/app/test/test_cryptodev_hash_test_vectors.h new file mode 100644 index 0000000..dfc84db --- /dev/null +++ b/app/test/test_cryptodev_hash_test_vectors.h @@ -0,0 +1,491 @@ +/* + * 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 TEST_CRYPTODEV_HASH_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_HASH_TEST_VECTORS_H_ + +static const uint8_t plaintext_hash[] = { + "What a lousy earth! He wondered how many people " + "were destitute that same night even in his own " + "prosperous country, how many homes were " + "shanties, how many husbands were drunk and " + "wives socked, and how many children were " + "bullied, abused, or abandoned. How many " + "families hungered for food they could not " + "afford to buy? How many hearts were broken? How " + "many suicides would take place that same night, " + "how many people would go insane? How many " + "cockroaches and landlords would triumph? How " + "many winners were losers, successes failures, " + "and rich men poor men? How many wise guys were " + "stupid? How many happy endings were unhappy " + "endings? How many honest men were liars, brave " + "men cowards, loyal men traitors, how many " + "sainted men were corrupt, how many people in " + "positions of trust had sold their souls to " + "bodyguards, how many had never had souls? How " + "many straight-and-narrow paths were crooked " + "paths? How many best families were worst " + "families and how many good people were bad " + "people? When you added them all up and then " + "subtracted, you might be left with only the " + "children, and perhaps with Albert Einstein and " + "an old violinist or sculptor somewhere." +}; + +static const struct blockcipher_test_data +md5_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_MD5, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0xB3, 0xE6, 0xBB, 0x50, 0x41, 0x35, 0x3C, 0x6B, + 0x7A, 0xFF, 0xD2, 0x64, 0xAF, 0xD5, 0x1C, 0xB2 + }, + .len = 16 + } +}; + +static const struct blockcipher_test_data +hmac_md5_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_MD5_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD + }, + .len = 16 + }, + .digest = { + .data = { + 0x50, 0xE8, 0xDE, 0xC5, 0xC1, 0x76, 0xAC, 0xAE, + 0x15, 0x4A, 0xF1, 0x7F, 0x7E, 0x04, 0x42, 0x9B + }, + .len = 16 + } +}; + +static const struct blockcipher_test_data +sha1_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0xA2, 0x8D, 0x40, 0x78, 0xDD, 0x9F, 0xBB, 0xD5, + 0x35, 0x62, 0xFB, 0xFA, 0x93, 0xFD, 0x7D, 0x70, + 0xA6, 0x7D, 0x45, 0xCA + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +hmac_sha1_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0xC4, 0xB7, 0x0E, 0x6B, 0xDE, 0xD1, 0xE7, 0x77, + 0x7E, 0x2E, 0x8F, 0xFC, 0x48, 0x39, 0x46, 0x17, + 0x3F, 0x91, 0x64, 0x59 + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +sha224_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA224, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0x91, 0xE7, 0xCD, 0x75, 0x14, 0x9C, 0xA9, 0xE9, + 0x2E, 0x46, 0x12, 0x20, 0x22, 0xF9, 0x68, 0x28, + 0x39, 0x26, 0xDF, 0xB5, 0x78, 0x62, 0xB2, 0x6E, + 0x5E, 0x8F, 0x25, 0x84 + }, + .len = 28 + } +}; + +static const struct blockcipher_test_data +hmac_sha224_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA224_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92, + 0xFB, 0xBF, 0xB0, 0x8C + }, + .len = 28 + }, + .digest = { + .data = { + 0x70, 0x0F, 0x04, 0x4D, 0x22, 0x02, 0x7D, 0x31, + 0x36, 0xDA, 0x77, 0x19, 0xB9, 0x66, 0x37, 0x7B, + 0xF1, 0x8A, 0x63, 0xBB, 0x5D, 0x1D, 0xE3, 0x9F, + 0x92, 0xF6, 0xAA, 0x19 + }, + .len = 28 + } +}; + +static const struct blockcipher_test_data +sha256_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA256, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0x7F, 0xF1, 0x0C, 0xF5, 0x90, 0x97, 0x19, 0x0F, + 0x00, 0xE4, 0x83, 0x01, 0xCA, 0x59, 0x00, 0x2E, + 0x1F, 0xC7, 0x84, 0xEE, 0x76, 0xA6, 0x39, 0x15, + 0x76, 0x2F, 0x87, 0xF9, 0x01, 0x06, 0xF3, 0xB7 + }, + .len = 32 + } +}; + +static const struct blockcipher_test_data +hmac_sha256_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92, + 0xFB, 0xBF, 0xB0, 0x8C, 0x29, 0x87, 0x90, 0xAC + }, + .len = 32 + }, + .digest = { + .data = { + 0xAF, 0x8F, 0x70, 0x1B, 0x4B, 0xAF, 0x34, 0xCB, + 0x02, 0x24, 0x48, 0x45, 0x83, 0x52, 0x8F, 0x22, + 0x06, 0x4D, 0x64, 0x09, 0x0A, 0xCC, 0x02, 0x77, + 0x71, 0x83, 0x48, 0x71, 0x07, 0x02, 0x25, 0x17 + }, + .len = 32 + } +}; + +static const struct blockcipher_test_data +sha384_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA384, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0x1D, 0xE7, 0x3F, 0x55, 0x86, 0xFE, 0x48, 0x9F, + 0xAC, 0xC6, 0x85, 0x32, 0xFA, 0x8E, 0xA6, 0x77, + 0x25, 0x84, 0xA5, 0x98, 0x8D, 0x0B, 0x80, 0xF4, + 0xEB, 0x2C, 0xFB, 0x6C, 0xEA, 0x7B, 0xFD, 0xD5, + 0xAD, 0x41, 0xAB, 0x15, 0xB0, 0x03, 0x15, 0xEC, + 0x9E, 0x3D, 0xED, 0xCB, 0x80, 0x7B, 0xF4, 0xB6 + }, + .len = 48 + } +}; + +static const struct blockcipher_test_data +hmac_sha384_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA384_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92, + 0xFB, 0xBF, 0xB0, 0x8C, 0x29, 0x87, 0x90, 0xAC, + 0x39, 0x8B, 0x5C, 0x49, 0x68, 0x1E, 0x3A, 0x05, + 0xCC, 0x68, 0x5C, 0x76, 0xCB, 0x3C, 0x71, 0x89 + }, + .len = 48 + }, + .digest = { + .data = { + 0xE2, 0x83, 0x18, 0x55, 0xB5, 0x8D, 0x94, 0x9B, + 0x01, 0xB6, 0xE2, 0x57, 0x7A, 0x62, 0xF5, 0xF4, + 0xAB, 0x39, 0xF3, 0x3C, 0x28, 0xA0, 0x0F, 0xCC, + 0xEE, 0x1C, 0xF1, 0xF8, 0x69, 0xF1, 0x24, 0x3B, + 0x10, 0x90, 0x0A, 0xE3, 0xF0, 0x59, 0xDD, 0xC0, + 0x6F, 0xE6, 0x8C, 0x84, 0xD5, 0x03, 0xF8, 0x9E + }, + .len = 48 + } +}; + +static const struct blockcipher_test_data +sha512_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA512, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0xB9, 0xBA, 0x28, 0x48, 0x3C, 0xC2, 0xD3, 0x65, + 0x4A, 0xD6, 0x00, 0x1D, 0xCE, 0x61, 0x64, 0x54, + 0x45, 0x8C, 0x64, 0x0E, 0xED, 0x0E, 0xD8, 0x1C, + 0x72, 0xCE, 0xD2, 0x44, 0x91, 0xC8, 0xEB, 0xC7, + 0x99, 0xC5, 0xCA, 0x89, 0x72, 0x64, 0x96, 0x41, + 0xC8, 0xEA, 0xB2, 0x4E, 0xD1, 0x21, 0x13, 0x49, + 0x64, 0x4E, 0x15, 0x68, 0x12, 0x67, 0x26, 0x0F, + 0x2C, 0x3C, 0x83, 0x25, 0x27, 0x86, 0xF0, 0xDB + }, + .len = 64 + } +}; + +static const struct blockcipher_test_data +hmac_sha512_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA512_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92, + 0xFB, 0xBF, 0xB0, 0x8C, 0x29, 0x87, 0x90, 0xAC, + 0x39, 0x8B, 0x5C, 0x49, 0x68, 0x1E, 0x3A, 0x05, + 0xCC, 0x68, 0x5C, 0x76, 0xCB, 0x3C, 0x71, 0x89, + 0xDE, 0xAA, 0x36, 0x44, 0x98, 0x93, 0x97, 0x1E, + 0x6D, 0x53, 0x83, 0x87, 0xB3, 0xB7, 0x56, 0x41 + }, + .len = 64 + }, + .digest = { + .data = { + 0xB8, 0x0B, 0x35, 0x97, 0x3F, 0x24, 0x3F, 0x05, + 0x2A, 0x7F, 0x2F, 0xD8, 0xD7, 0x56, 0x58, 0xAD, + 0x6F, 0x8D, 0x1F, 0x4C, 0x30, 0xF9, 0xA8, 0x29, + 0x7A, 0xE0, 0x8D, 0x88, 0xF5, 0x2E, 0x94, 0xF5, + 0x06, 0xF7, 0x5D, 0x57, 0x32, 0xA8, 0x49, 0x29, + 0xEA, 0x6B, 0x6D, 0x95, 0xBD, 0x76, 0xF5, 0x79, + 0x97, 0x37, 0x0F, 0xBE, 0xC2, 0x45, 0xA0, 0x87, + 0xAF, 0x24, 0x27, 0x0C, 0x78, 0xBA, 0xBE, 0x20 + }, + .len = 64 + } +}; + +static const struct blockcipher_test_case hash_test_cases[] = { + { + .test_descr = "MD5 Digest", + .test_data = &md5_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "MD5 Digest Verify", + .test_data = &md5_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-MD5 Digest", + .test_data = &hmac_md5_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-MD5 Digest Verify", + .test_data = &hmac_md5_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA1 Digest", + .test_data = &sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA1 Digest Verify", + .test_data = &sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA1 Digest", + .test_data = &hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA1 Digest Verify", + .test_data = &hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA224 Digest", + .test_data = &sha224_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA224 Digest Verify", + .test_data = &sha224_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA224 Digest", + .test_data = &hmac_sha224_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA224 Digest Verify", + .test_data = &hmac_sha224_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA256 Digest", + .test_data = &sha256_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA256 Digest Verify", + .test_data = &sha256_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA256 Digest", + .test_data = &hmac_sha256_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA256 Digest Verify", + .test_data = &hmac_sha256_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA384 Digest", + .test_data = &sha384_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA384 Digest Verify", + .test_data = &sha384_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA384 Digest", + .test_data = &hmac_sha384_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA384 Digest Verify", + .test_data = &hmac_sha384_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA512 Digest", + .test_data = &sha512_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA512 Digest Verify", + .test_data = &sha512_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA512 Digest", + .test_data = &hmac_sha512_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA512 Digest Verify", + .test_data = &hmac_sha512_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, +}; + +#endif /* TEST_CRYPTODEV_HASH_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_perf.c b/app/test/test_cryptodev_perf.c index 20713d4..513b794 100644 --- a/app/test/test_cryptodev_perf.c +++ b/app/test/test_cryptodev_perf.c @@ -97,12 +97,28 @@ static struct rte_cryptodev_sym_session * test_perf_create_snow3g_session(uint8_t dev_id, enum chain_mode chain, enum rte_crypto_cipher_algorithm cipher_algo, unsigned cipher_key_len, enum rte_crypto_auth_algorithm auth_algo); +static struct rte_cryptodev_sym_session * +test_perf_create_libcrypto_session(uint8_t dev_id, enum chain_mode chain, + enum rte_crypto_cipher_algorithm cipher_algo, + unsigned int cipher_key_len, enum rte_crypto_auth_algorithm auth_algo); static struct rte_mbuf * test_perf_create_pktmbuf(struct rte_mempool *mpool, unsigned buf_sz); static inline struct rte_crypto_op * test_perf_set_crypto_op_snow3g(struct rte_crypto_op *op, struct rte_mbuf *m, struct rte_cryptodev_sym_session *sess, unsigned data_len, unsigned digest_len); +static inline struct rte_crypto_op * +test_perf_set_crypto_op_aes(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len); +static inline struct rte_crypto_op * +test_perf_set_crypto_op_aes_gcm(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len); +static inline struct rte_crypto_op * +test_perf_set_crypto_op_3des(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len); static uint32_t get_auth_digest_length(enum rte_crypto_auth_algorithm algo); @@ -273,9 +289,24 @@ testsuite_setup(void) } } + /* Create 2 LIBCRYPTO devices if required */ + if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_LIBCRYPTO_PMD) { + nb_devs = rte_cryptodev_count_devtype(RTE_CRYPTODEV_LIBCRYPTO_PMD); + if (nb_devs < 2) { + for (i = nb_devs; i < 2; i++) { + ret = rte_eal_vdev_init( + RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), NULL); + + TEST_ASSERT(ret == 0, + "Failed to create instance %u of pmd : %s", + i, RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD)); + } + } + } + nb_devs = rte_cryptodev_count(); if (nb_devs < 1) { - RTE_LOG(ERR, USER1, "No crypto devices found?"); + RTE_LOG(ERR, USER1, "No crypto devices found?\n"); return TEST_FAILED; } @@ -2149,6 +2180,151 @@ test_perf_snow3G_vary_burst_size(void) return 0; } +static int +test_perf_libcrypto_optimise_cyclecount(struct perf_test_params *pparams) +{ + uint32_t num_to_submit = pparams->total_operations; + struct rte_crypto_op *c_ops[num_to_submit]; + struct rte_crypto_op *proc_ops[num_to_submit]; + uint64_t failed_polls, retries, start_cycles, end_cycles, total_cycles = 0; + uint32_t burst_sent = 0, burst_received = 0; + uint32_t i, burst_size, num_sent, num_ops_received; + + struct crypto_testsuite_params *ts_params = &testsuite_params; + + static struct rte_cryptodev_sym_session *sess; + + static struct rte_crypto_op *(*test_perf_set_crypto_op) + (struct rte_crypto_op *, struct rte_mbuf *, + struct rte_cryptodev_sym_session *, unsigned int, + unsigned int); + + unsigned int digest_length = get_auth_digest_length(pparams->auth_algo); + + if (rte_cryptodev_count() == 0) { + printf("\nNo crypto devices found. Is PMD build configured?\n"); + return TEST_FAILED; + } + + /* Create Crypto session*/ + sess = test_perf_create_libcrypto_session(ts_params->dev_id, + pparams->chain, pparams->cipher_algo, + pparams->cipher_key_length, pparams->auth_algo); + TEST_ASSERT_NOT_NULL(sess, "Session creation failed"); + + /* Generate Crypto op data structure(s)*/ + for (i = 0; i < num_to_submit ; i++) { + struct rte_mbuf *m = test_perf_create_pktmbuf( + ts_params->mbuf_mp, + pparams->buf_size); + TEST_ASSERT_NOT_NULL(m, "Failed to allocate tx_buf"); + + struct rte_crypto_op *op = + rte_crypto_op_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC); + TEST_ASSERT_NOT_NULL(op, "Failed to allocate op"); + + switch (pparams->cipher_algo) { + case RTE_CRYPTO_CIPHER_3DES_CBC: + case RTE_CRYPTO_CIPHER_3DES_CTR: + test_perf_set_crypto_op = test_perf_set_crypto_op_3des; + break; + case RTE_CRYPTO_CIPHER_AES_CBC: + case RTE_CRYPTO_CIPHER_AES_CTR: + test_perf_set_crypto_op = test_perf_set_crypto_op_aes; + break; + case RTE_CRYPTO_CIPHER_AES_GCM: + test_perf_set_crypto_op = test_perf_set_crypto_op_aes_gcm; + break; + default: + return TEST_FAILED; + } + + op = test_perf_set_crypto_op(op, m, sess, pparams->buf_size, + digest_length); + TEST_ASSERT_NOT_NULL(op, "Failed to attach op to session"); + + c_ops[i] = op; + } + + printf("\nOn %s dev%u qp%u, %s, cipher algo:%s, cipher key length:%u, " + "auth_algo:%s, Packet Size %u bytes", + pmd_name(gbl_cryptodev_perftest_devtype), + ts_params->dev_id, 0, + chain_mode_name(pparams->chain), + cipher_algo_name(pparams->cipher_algo), + pparams->cipher_key_length, + auth_algo_name(pparams->auth_algo), + pparams->buf_size); + printf("\nOps Tx\tOps Rx\tOps/burst "); + printf("Retries EmptyPolls\tIACycles/CyOp\tIACycles/Burst\tIACycles/Byte"); + + for (i = 2; i <= 128 ; i *= 2) { + num_sent = 0; + num_ops_received = 0; + retries = 0; + failed_polls = 0; + burst_size = i; + total_cycles = 0; + while (num_sent < num_to_submit) { + start_cycles = rte_rdtsc_precise(); + burst_sent = rte_cryptodev_enqueue_burst(ts_params->dev_id, + 0, &c_ops[num_sent], + ((num_to_submit - num_sent) < burst_size) ? + num_to_submit - num_sent : burst_size); + end_cycles = rte_rdtsc_precise(); + if (burst_sent == 0) + retries++; + num_sent += burst_sent; + total_cycles += (end_cycles - start_cycles); + + /* Wait until requests have been sent. */ + rte_delay_ms(1); + + start_cycles = rte_rdtsc_precise(); + burst_received = rte_cryptodev_dequeue_burst( + ts_params->dev_id, 0, proc_ops, burst_size); + end_cycles = rte_rdtsc_precise(); + if (burst_received < burst_sent) + failed_polls++; + num_ops_received += burst_received; + + total_cycles += end_cycles - start_cycles; + } + + while (num_ops_received != num_to_submit) { + /* Sending 0 length burst to flush sw crypto device */ + rte_cryptodev_enqueue_burst(ts_params->dev_id, 0, NULL, 0); + + start_cycles = rte_rdtsc_precise(); + burst_received = rte_cryptodev_dequeue_burst( + ts_params->dev_id, 0, proc_ops, burst_size); + end_cycles = rte_rdtsc_precise(); + + total_cycles += end_cycles - start_cycles; + if (burst_received == 0) + failed_polls++; + num_ops_received += burst_received; + } + + printf("\n%u\t%u\t%u", num_sent, num_ops_received, burst_size); + printf("\t\t%"PRIu64, retries); + printf("\t%"PRIu64, failed_polls); + printf("\t\t%"PRIu64, total_cycles/num_ops_received); + printf("\t\t%"PRIu64, (total_cycles/num_ops_received)*burst_size); + printf("\t\t%"PRIu64, + total_cycles/(num_ops_received*pparams->buf_size)); + } + printf("\n"); + + for (i = 0; i < num_to_submit ; i++) { + rte_pktmbuf_free(c_ops[i]->sym->m_src); + rte_crypto_op_free(c_ops[i]); + } + + return TEST_SUCCESS; +} + static uint32_t get_auth_key_max_length(enum rte_crypto_auth_algorithm algo) { switch (algo) { @@ -2164,6 +2340,8 @@ static uint32_t get_auth_key_max_length(enum rte_crypto_auth_algorithm algo) return 128; case RTE_CRYPTO_AUTH_SHA512_HMAC: return 128; + case RTE_CRYPTO_AUTH_AES_GCM: + return 0; default: return 0; } @@ -2184,23 +2362,35 @@ static uint32_t get_auth_digest_length(enum rte_crypto_auth_algorithm algo) return TRUNCATED_DIGEST_BYTE_LENGTH_SHA384; case RTE_CRYPTO_AUTH_SHA512_HMAC: return TRUNCATED_DIGEST_BYTE_LENGTH_SHA512; + case RTE_CRYPTO_AUTH_AES_GCM: + return DIGEST_BYTE_LENGTH_AES_GCM; default: return 0; } } -static uint8_t aes_cbc_key[] = { +static uint8_t aes_key[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static uint8_t aes_cbc_iv[] = { +static uint8_t aes_iv[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static uint8_t triple_des_key[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static uint8_t triple_des_iv[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + static uint8_t hmac_sha_key[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -2250,7 +2440,7 @@ test_perf_create_aes_sha_session(uint8_t dev_id, enum chain_mode chain, cipher_xform.cipher.algo = cipher_algo; cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; - cipher_xform.cipher.key.data = aes_cbc_key; + cipher_xform.cipher.key.data = aes_key; cipher_xform.cipher.key.length = cipher_key_len; /* Setup HMAC Parameters */ @@ -2328,8 +2518,77 @@ test_perf_create_snow3g_session(uint8_t dev_id, enum chain_mode chain, } } -#define AES_CBC_BLOCK_SIZE 16 -#define AES_CBC_CIPHER_IV_LENGTH 16 +static struct rte_cryptodev_sym_session * +test_perf_create_libcrypto_session(uint8_t dev_id, enum chain_mode chain, + enum rte_crypto_cipher_algorithm cipher_algo, + unsigned int cipher_key_len, + enum rte_crypto_auth_algorithm auth_algo) +{ + struct rte_crypto_sym_xform cipher_xform = { 0 }; + struct rte_crypto_sym_xform auth_xform = { 0 }; + + /* Setup Cipher Parameters */ + cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; + cipher_xform.cipher.algo = cipher_algo; + cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; + + switch (cipher_algo) { + case RTE_CRYPTO_CIPHER_3DES_CBC: + case RTE_CRYPTO_CIPHER_3DES_CTR: + cipher_xform.cipher.key.data = triple_des_key; + break; + case RTE_CRYPTO_CIPHER_AES_CBC: + case RTE_CRYPTO_CIPHER_AES_CTR: + case RTE_CRYPTO_CIPHER_AES_GCM: + cipher_xform.cipher.key.data = aes_key; + break; + default: + return NULL; + } + + cipher_xform.cipher.key.length = cipher_key_len; + + /* Setup Auth Parameters */ + auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; + auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; + auth_xform.auth.algo = auth_algo; + + switch (auth_algo) { + case RTE_CRYPTO_AUTH_SHA1_HMAC: + auth_xform.auth.key.data = hmac_sha_key; + break; + case RTE_CRYPTO_AUTH_AES_GCM: + auth_xform.auth.key.data = NULL; + break; + default: + return NULL; + } + + auth_xform.auth.key.length = get_auth_key_max_length(auth_algo); + auth_xform.auth.digest_length = get_auth_digest_length(auth_algo); + + switch (chain) { + case CIPHER_HASH: + cipher_xform.next = &auth_xform; + auth_xform.next = NULL; + /* Create Crypto session*/ + return rte_cryptodev_sym_session_create(dev_id, &cipher_xform); + case HASH_CIPHER: + auth_xform.next = &cipher_xform; + cipher_xform.next = NULL; + /* Create Crypto session*/ + return rte_cryptodev_sym_session_create(dev_id, &auth_xform); + default: + return NULL; + } +} + +#define AES_BLOCK_SIZE 16 +#define AES_CIPHER_IV_LENGTH 16 + +#define TRIPLE_DES_BLOCK_SIZE 8 +#define TRIPLE_DES_CIPHER_IV_LENGTH 8 + #define SNOW3G_CIPHER_IV_LENGTH 16 static struct rte_mbuf * @@ -2348,7 +2607,7 @@ test_perf_create_pktmbuf(struct rte_mempool *mpool, unsigned buf_sz) } static inline struct rte_crypto_op * -test_perf_set_crypto_op(struct rte_crypto_op *op, struct rte_mbuf *m, +test_perf_set_crypto_op_aes(struct rte_crypto_op *op, struct rte_mbuf *m, struct rte_cryptodev_sym_session *sess, unsigned data_len, unsigned digest_len) { @@ -2362,19 +2621,53 @@ test_perf_set_crypto_op(struct rte_crypto_op *op, struct rte_mbuf *m, (m->data_off + data_len); op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, data_len); op->sym->auth.digest.length = digest_len; - op->sym->auth.aad.data = aes_cbc_iv; - op->sym->auth.aad.length = AES_CBC_CIPHER_IV_LENGTH; + op->sym->auth.aad.data = aes_iv; + op->sym->auth.aad.length = AES_CIPHER_IV_LENGTH; /* Cipher Parameters */ - op->sym->cipher.iv.data = aes_cbc_iv; - op->sym->cipher.iv.length = AES_CBC_CIPHER_IV_LENGTH; + op->sym->cipher.iv.data = aes_iv; + op->sym->cipher.iv.length = AES_CIPHER_IV_LENGTH; /* Data lengths/offsets Parameters */ op->sym->auth.data.offset = 0; op->sym->auth.data.length = data_len; - op->sym->cipher.data.offset = AES_CBC_BLOCK_SIZE; - op->sym->cipher.data.length = data_len - AES_CBC_BLOCK_SIZE; + op->sym->cipher.data.offset = AES_BLOCK_SIZE; + op->sym->cipher.data.length = data_len - AES_BLOCK_SIZE; + + op->sym->m_src = m; + + return op; +} + +static inline struct rte_crypto_op * +test_perf_set_crypto_op_aes_gcm(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len) +{ + if (rte_crypto_op_attach_sym_session(op, sess) != 0) { + rte_crypto_op_free(op); + return NULL; + } + + /* Authentication Parameters */ + op->sym->auth.digest.data = (uint8_t *)m->buf_addr + + (m->data_off + data_len); + op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, data_len); + op->sym->auth.digest.length = digest_len; + op->sym->auth.aad.data = aes_iv; + op->sym->auth.aad.length = AES_CIPHER_IV_LENGTH; + + /* Cipher Parameters */ + op->sym->cipher.iv.data = aes_iv; + op->sym->cipher.iv.length = AES_CIPHER_IV_LENGTH; + + /* Data lengths/offsets Parameters */ + op->sym->auth.data.offset = AES_BLOCK_SIZE; + op->sym->auth.data.length = data_len - AES_BLOCK_SIZE; + + op->sym->cipher.data.offset = AES_BLOCK_SIZE; + op->sym->cipher.data.length = data_len - AES_BLOCK_SIZE; op->sym->m_src = m; @@ -2415,7 +2708,39 @@ test_perf_set_crypto_op_snow3g(struct rte_crypto_op *op, struct rte_mbuf *m, return op; } +static inline struct rte_crypto_op * +test_perf_set_crypto_op_3des(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len) +{ + if (rte_crypto_op_attach_sym_session(op, sess) != 0) { + rte_crypto_op_free(op); + return NULL; + } + + /* Authentication Parameters */ + op->sym->auth.digest.data = (uint8_t *)m->buf_addr + + (m->data_off + data_len); + op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, data_len); + op->sym->auth.digest.length = digest_len; + op->sym->auth.aad.data = triple_des_iv; + op->sym->auth.aad.length = TRIPLE_DES_CIPHER_IV_LENGTH; + + /* Cipher Parameters */ + op->sym->cipher.iv.data = triple_des_iv; + op->sym->cipher.iv.length = TRIPLE_DES_CIPHER_IV_LENGTH; + + /* Data lengths/offsets Parameters */ + op->sym->auth.data.offset = 0; + op->sym->auth.data.length = data_len; + op->sym->cipher.data.offset = TRIPLE_DES_BLOCK_SIZE; + op->sym->cipher.data.length = data_len - TRIPLE_DES_BLOCK_SIZE; + + op->sym->m_src = m; + + return op; +} /* An mbuf set is used in each burst. An mbuf can be used by multiple bursts at * same time, i.e. as they're not dereferenced there's no need to wait until @@ -2486,7 +2811,7 @@ test_perf_aes_sha(uint8_t dev_id, uint16_t queue_id, "and free ops below."); } else { for (i = 0; i < ops_needed; i++) - ops[i] = test_perf_set_crypto_op(ops[i], + ops[i] = test_perf_set_crypto_op_aes(ops[i], mbufs[i + (pparams->burst_size * (j % NUM_MBUF_SETS))], sess, pparams->buf_size, digest_length); @@ -2697,6 +3022,154 @@ test_perf_snow3g(uint8_t dev_id, uint16_t queue_id, return TEST_SUCCESS; } +static int +test_perf_libcrypto(uint8_t dev_id, uint16_t queue_id, + struct perf_test_params *pparams) +{ + uint16_t i, k, l, m; + uint16_t j = 0; + uint16_t ops_unused = 0; + + uint64_t burst_enqueued = 0, total_enqueued = 0, burst_dequeued = 0; + uint64_t processed = 0, failed_polls = 0, retries = 0; + uint64_t tsc_start = 0, tsc_end = 0; + + unsigned int digest_length = get_auth_digest_length(pparams->auth_algo); + + struct rte_crypto_op *ops[pparams->burst_size]; + struct rte_crypto_op *proc_ops[pparams->burst_size]; + + struct rte_mbuf *mbufs[pparams->burst_size * NUM_MBUF_SETS]; + + struct crypto_testsuite_params *ts_params = &testsuite_params; + + static struct rte_cryptodev_sym_session *sess; + + static struct rte_crypto_op *(*test_perf_set_crypto_op) + (struct rte_crypto_op *, struct rte_mbuf *, + struct rte_cryptodev_sym_session *, unsigned int, + unsigned int); + + switch (pparams->cipher_algo) { + case RTE_CRYPTO_CIPHER_3DES_CBC: + case RTE_CRYPTO_CIPHER_3DES_CTR: + test_perf_set_crypto_op = test_perf_set_crypto_op_3des; + break; + case RTE_CRYPTO_CIPHER_AES_CBC: + case RTE_CRYPTO_CIPHER_AES_CTR: + test_perf_set_crypto_op = test_perf_set_crypto_op_aes; + break; + case RTE_CRYPTO_CIPHER_AES_GCM: + test_perf_set_crypto_op = test_perf_set_crypto_op_aes_gcm; + break; + default: + return TEST_FAILED; + } + + if (rte_cryptodev_count() == 0) { + printf("\nNo crypto devices found. Is PMD build configured?\n"); + return TEST_FAILED; + } + + /* Create Crypto session*/ + sess = test_perf_create_libcrypto_session(ts_params->dev_id, + pparams->chain, pparams->cipher_algo, + pparams->cipher_key_length, pparams->auth_algo); + TEST_ASSERT_NOT_NULL(sess, "Session creation failed"); + + /* Generate a burst of crypto operations */ + for (i = 0; i < (pparams->burst_size * NUM_MBUF_SETS); i++) { + mbufs[i] = test_perf_create_pktmbuf( + ts_params->mbuf_mp, + pparams->buf_size); + + if (mbufs[i] == NULL) { + printf("\nFailed to get mbuf - freeing the rest.\n"); + for (k = 0; k < i; k++) + rte_pktmbuf_free(mbufs[k]); + return -1; + } + } + + tsc_start = rte_rdtsc_precise(); + + while (total_enqueued < pparams->total_operations) { + uint16_t burst_size = + total_enqueued + pparams->burst_size <= pparams->total_operations ? + pparams->burst_size : pparams->total_operations - total_enqueued; + uint16_t ops_needed = burst_size - ops_unused; + + if (ops_needed != rte_crypto_op_bulk_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC, ops, ops_needed)){ + printf("\nFailed to alloc enough ops, finish dequeuing " + "and free ops below."); + } else { + for (i = 0; i < ops_needed; i++) + ops[i] = test_perf_set_crypto_op(ops[i], + mbufs[i + (pparams->burst_size * + (j % NUM_MBUF_SETS))], + sess, pparams->buf_size, digest_length); + + /* enqueue burst */ + burst_enqueued = rte_cryptodev_enqueue_burst(dev_id, + queue_id, ops, burst_size); + + if (burst_enqueued < burst_size) + retries++; + + ops_unused = burst_size - burst_enqueued; + total_enqueued += burst_enqueued; + } + + /* dequeue burst */ + burst_dequeued = rte_cryptodev_dequeue_burst(dev_id, queue_id, + proc_ops, pparams->burst_size); + if (burst_dequeued == 0) + failed_polls++; + else { + processed += burst_dequeued; + + for (l = 0; l < burst_dequeued; l++) + rte_crypto_op_free(proc_ops[l]); + } + j++; + } + + /* Dequeue any operations still in the crypto device */ + while (processed < pparams->total_operations) { + /* Sending 0 length burst to flush sw crypto device */ + rte_cryptodev_enqueue_burst(dev_id, queue_id, NULL, 0); + + /* dequeue burst */ + burst_dequeued = rte_cryptodev_dequeue_burst(dev_id, queue_id, + proc_ops, pparams->burst_size); + if (burst_dequeued == 0) + failed_polls++; + else { + processed += burst_dequeued; + + for (m = 0; m < burst_dequeued; m++) + rte_crypto_op_free(proc_ops[m]); + } + } + + tsc_end = rte_rdtsc_precise(); + + double ops_s = ((double)processed / (tsc_end - tsc_start)) + * rte_get_tsc_hz(); + double throughput = (ops_s * pparams->buf_size * NUM_MBUF_SETS) + / 1000000000; + + printf("\t%u\t%6.2f\t%10.2f\t%8"PRIu64"\t%8"PRIu64, pparams->buf_size, + ops_s / 1000000, throughput, retries, failed_polls); + + for (i = 0; i < pparams->burst_size * NUM_MBUF_SETS; i++) + rte_pktmbuf_free(mbufs[i]); + + printf("\n"); + return TEST_SUCCESS; +} + /* perf_test_aes_sha("avx2", HASH_CIPHER, 16, CBC, SHA1); @@ -2844,6 +3317,166 @@ test_perf_snow3G_vary_pkt_size(void) } static int +test_perf_libcrypto_vary_pkt_size(void) +{ + unsigned int total_operations = 1000000; + unsigned int burst_size = { 64 }; + unsigned int buf_lengths[] = { 64, 128, 256, 512, 768, 1024, 1280, 1536, + 1792, 2048 }; + uint8_t i, j; + + struct perf_test_params params_set[] = { + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key_length = 24, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key_length = 32, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key_length = 24, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_GCM, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_AES_GCM + }, + }; + + for (i = 0; i < RTE_DIM(params_set); i++) { + params_set[i].total_operations = total_operations; + params_set[i].burst_size = burst_size; + printf("\n%s. cipher algo: %s auth algo: %s cipher key size=%u." + " burst_size: %d ops\n", + chain_mode_name(params_set[i].chain), + cipher_algo_name(params_set[i].cipher_algo), + auth_algo_name(params_set[i].auth_algo), + params_set[i].cipher_key_length, + burst_size); + printf("\nBuffer Size(B)\tOPS(M)\tThroughput(Gbps)\tRetries\t" + "EmptyPolls\n"); + for (j = 0; j < RTE_DIM(buf_lengths); j++) { + params_set[i].buf_size = buf_lengths[j]; + test_perf_libcrypto(testsuite_params.dev_id, 0, ¶ms_set[i]); + } + } + + return 0; +} + +static int +test_perf_libcrypto_vary_burst_size(void) +{ + unsigned int total_operations = 4096; + uint16_t buf_lengths[] = { 40 }; + uint8_t i, j; + + struct perf_test_params params_set[] = { + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key_length = 24, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key_length = 32, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key_length = 24, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_GCM, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_AES_GCM + }, + }; + + printf("\n\nStart %s.", __func__); + printf("\nThis Test measures the average IA cycle cost using a " + "constant request(packet) size. "); + printf("Cycle cost is only valid when indicators show device is not busy," + " i.e. Retries and EmptyPolls = 0"); + + for (i = 0; i < RTE_DIM(params_set); i++) { + printf("\n"); + params_set[i].total_operations = total_operations; + + for (j = 0; j < RTE_DIM(buf_lengths); j++) { + params_set[i].buf_size = buf_lengths[j]; + test_perf_libcrypto_optimise_cyclecount(¶ms_set[i]); + } + } + + return 0; +} + +static int test_perf_aes_cbc_vary_burst_size(void) { return test_perf_crypto_qp_vary_burst_size(testsuite_params.dev_id); @@ -2887,6 +3520,19 @@ static struct unit_test_suite cryptodev_snow3g_testsuite = { } }; +static struct unit_test_suite cryptodev_libcrypto_testsuite = { + .suite_name = "Crypto Device LIBCRYPTO Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, + test_perf_libcrypto_vary_pkt_size), + TEST_CASE_ST(ut_setup, ut_teardown, + test_perf_libcrypto_vary_burst_size), + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + static int perftest_aesni_mb_cryptodev(void /*argv __rte_unused, int argc __rte_unused*/) { @@ -2919,7 +3565,17 @@ perftest_qat_snow3g_cryptodev(void /*argv __rte_unused, int argc __rte_unused*/) return unit_test_suite_runner(&cryptodev_snow3g_testsuite); } +static int +perftest_libcrypto_cryptodev(void /*argv __rte_unused, int argc __rte_unused*/) +{ + gbl_cryptodev_perftest_devtype = RTE_CRYPTODEV_LIBCRYPTO_PMD; + + return unit_test_suite_runner(&cryptodev_libcrypto_testsuite); +} + REGISTER_TEST_COMMAND(cryptodev_aesni_mb_perftest, perftest_aesni_mb_cryptodev); REGISTER_TEST_COMMAND(cryptodev_qat_perftest, perftest_qat_cryptodev); REGISTER_TEST_COMMAND(cryptodev_sw_snow3g_perftest, perftest_sw_snow3g_cryptodev); REGISTER_TEST_COMMAND(cryptodev_qat_snow3g_perftest, perftest_qat_snow3g_cryptodev); +REGISTER_TEST_COMMAND(cryptodev_libcrypto_perftest, + perftest_libcrypto_cryptodev); -- 2.5.0 ^ permalink raw reply [flat|nested] 34+ messages in thread
* [dpdk-dev] [PATCH v3 3/3] examples/l2fwd-crypto: updated example for libcrypto PMD 2016-09-29 14:14 ` [dpdk-dev] [PATCH v3 0/3] new crypto software based device Slawomir Mrozowicz 2016-09-29 14:14 ` [dpdk-dev] [PATCH v3 1/3] libcrypto_pmd: initial implementation of SW crypto device Slawomir Mrozowicz 2016-09-29 14:14 ` [dpdk-dev] [PATCH v3 2/3] app/test: added tests for libcrypto PMD Slawomir Mrozowicz @ 2016-09-29 14:39 ` Slawomir Mrozowicz 2016-09-30 16:17 ` [dpdk-dev] [PATCH v4 0/5] new crypto software based device Slawomir Mrozowicz 3 siblings, 0 replies; 34+ messages in thread From: Slawomir Mrozowicz @ 2016-09-29 14:39 UTC (permalink / raw) To: dev; +Cc: Slawomir Mrozowicz, Daniel Mrzyglod Libcrypto PMD has support for: Supported cipher algorithms: RTE_CRYPTO_CIPHER_3DES_CBC RTE_CRYPTO_CIPHER_AES_CBC RTE_CRYPTO_CIPHER_AES_CTR RTE_CRYPTO_CIPHER_3DES_CTR RTE_CRYPTO_CIPHER_AES_GCM Supported authentication algorithms: RTE_CRYPTO_AUTH_AES_GMAC RTE_CRYPTO_AUTH_MD5 RTE_CRYPTO_AUTH_SHA1 RTE_CRYPTO_AUTH_SHA224 RTE_CRYPTO_AUTH_SHA256 RTE_CRYPTO_AUTH_SHA384 RTE_CRYPTO_AUTH_SHA512 RTE_CRYPTO_AUTH_MD5_HMAC RTE_CRYPTO_AUTH_SHA1_HMAC RTE_CRYPTO_AUTH_SHA224_HMAC RTE_CRYPTO_AUTH_SHA256_HMAC RTE_CRYPTO_AUTH_SHA384_HMAC RTE_CRYPTO_AUTH_SHA512_HMAC Signed-off-by: Daniel Mrzyglod <danielx.t.mrzyglod@intel.com> --- v3: - change description --- examples/l2fwd-crypto/main.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/examples/l2fwd-crypto/main.c b/examples/l2fwd-crypto/main.c index b348d59..2e9d082 100644 --- a/examples/l2fwd-crypto/main.c +++ b/examples/l2fwd-crypto/main.c @@ -340,18 +340,27 @@ fill_supported_algorithm_tables(void) strcpy(supported_auth_algo[i], "NOT_SUPPORTED"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_AES_GCM], "AES_GCM"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_AES_GMAC], "AES_GMAC"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_MD5_HMAC], "MD5_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_MD5], "MD5"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_NULL], "NULL"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_AES_XCBC_MAC], "AES_XCBC_MAC"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA1_HMAC], "SHA1_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA1], "SHA1"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA224_HMAC], "SHA224_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA224], "SHA224"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA256_HMAC], "SHA256_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA256], "SHA256"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA384_HMAC], "SHA384_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA384], "SHA384"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA512_HMAC], "SHA512_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA512], "SHA512"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SNOW3G_UIA2], "SNOW3G_UIA2"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_KASUMI_F9], "KASUMI_F9"); + + for (i = 0; i < RTE_CRYPTO_CIPHER_LIST_END; i++) strcpy(supported_cipher_algo[i], "NOT_SUPPORTED"); @@ -361,6 +370,8 @@ fill_supported_algorithm_tables(void) strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_NULL], "NULL"); strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_SNOW3G_UEA2], "SNOW3G_UEA2"); strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_KASUMI_F8], "KASUMI_F8"); + strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_3DES_CTR], "3DES_CTR"); + strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_3DES_CBC], "3DES_CBC"); } -- 2.5.0 ^ permalink raw reply [flat|nested] 34+ messages in thread
* [dpdk-dev] [PATCH v4 0/5] new crypto software based device 2016-09-29 14:14 ` [dpdk-dev] [PATCH v3 0/3] new crypto software based device Slawomir Mrozowicz ` (2 preceding siblings ...) 2016-09-29 14:39 ` [dpdk-dev] [PATCH v3 3/3] examples/l2fwd-crypto: updated example " Slawomir Mrozowicz @ 2016-09-30 16:17 ` Slawomir Mrozowicz 2016-09-30 16:17 ` [dpdk-dev] [PATCH v4 1/5] libcrypto_pmd: initial implementation of SW crypto device Slawomir Mrozowicz ` (2 more replies) 3 siblings, 3 replies; 34+ messages in thread From: Slawomir Mrozowicz @ 2016-09-30 16:17 UTC (permalink / raw) To: dev; +Cc: Slawomir Mrozowicz This code provides the initial implementation of the libcrypto poll mode driver. All cryptography operations are using Openssl library crypto API. Each algorithm uses EVP_ interface from openssl API - which is recommended by Openssl maintainers. For more information about how to use this driver, go to: doc/guides/cryptodevs/libcrypto.rst Changes in V4: - move aes test rework to another patch - move big data test to another patch - checking if libcrypto pmd is available Changes in V3: - add nagative verification tests - add big data test - fix pmd according to negative verification tests - change gmac aad max size - update documentation and commits comments Changes in V2: - add gcm/gmac algorithm correction - unit test rework Slawomir Mrozowicz (1): libcrypto_pmd: initial implementation of SW crypto device Piotr Azarewicz (3) app/test: cryptodev AES tests rework app/test: added tests for libcrypto PMD app/test: added big data GMAC test for libcrypto Daniel Mrzyglod (1) examples/l2fwd-crypto: updated example for libcrypto PMD MAINTAINERS | 4 + app/test/Makefile | 2 +- app/test/test_cryptodev.c | 1583 +++- app/test/test_cryptodev.h | 1 + app/test/test_cryptodev_aes.c | 687 -- app/test/test_cryptodev_aes.h | 1124 --- app/test/test_cryptodev_aes_test_vectors.h | 1095 +++ app/test/test_cryptodev_blockcipher.c | 531 ++ app/test/test_cryptodev_blockcipher.h | 125 + app/test/test_cryptodev_des_test_vectors.h | 952 +++ app/test/test_cryptodev_gcm_test_vectors.h | 8245 +++++++++++++++++++- app/test/test_cryptodev_hash_test_vectors.h | 491 ++ app/test/test_cryptodev_perf.c | 689 +- config/common_base | 6 + doc/guides/cryptodevs/index.rst | 1 + doc/guides/cryptodevs/libcrypto.rst | 116 + doc/guides/rel_notes/release_16_11.rst | 23 +- drivers/crypto/Makefile | 1 + drivers/crypto/libcrypto/Makefile | 60 + drivers/crypto/libcrypto/rte_libcrypto_pmd.c | 1051 +++ drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c | 708 ++ .../crypto/libcrypto/rte_libcrypto_pmd_private.h | 174 + .../crypto/libcrypto/rte_pmd_libcrypto_version.map | 3 + examples/l2fwd-crypto/main.c | 9 + lib/librte_cryptodev/rte_cryptodev.h | 5 +- mk/rte.app.mk | 23 +- 26 files changed, 15748 insertions(+), 1961 deletions(-) delete mode 100644 app/test/test_cryptodev_aes.c delete mode 100644 app/test/test_cryptodev_aes.h create mode 100644 app/test/test_cryptodev_aes_test_vectors.h create mode 100644 app/test/test_cryptodev_blockcipher.c create mode 100644 app/test/test_cryptodev_blockcipher.h create mode 100644 app/test/test_cryptodev_des_test_vectors.h create mode 100644 app/test/test_cryptodev_hash_test_vectors.h create mode 100644 doc/guides/cryptodevs/libcrypto.rst create mode 100644 drivers/crypto/libcrypto/Makefile create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd.c create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h create mode 100644 drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map -- 2.5.0 ^ permalink raw reply [flat|nested] 34+ messages in thread
* [dpdk-dev] [PATCH v4 1/5] libcrypto_pmd: initial implementation of SW crypto device 2016-09-30 16:17 ` [dpdk-dev] [PATCH v4 0/5] new crypto software based device Slawomir Mrozowicz @ 2016-09-30 16:17 ` Slawomir Mrozowicz 2016-09-30 16:32 ` [dpdk-dev] [PATCH v4 2/5] app/test: cryptodev AES tests rework Slawomir Mrozowicz 2016-10-03 14:26 ` [dpdk-dev] [PATCH v5 0/4] new crypto software based device Slawomir Mrozowicz 2 siblings, 0 replies; 34+ messages in thread From: Slawomir Mrozowicz @ 2016-09-30 16:17 UTC (permalink / raw) To: dev Cc: Slawomir Mrozowicz, Michal Kobylinski, Tomasz Kulasek, Daniel Mrzyglod This code provides the initial implementation of the libcrypto poll mode driver. All cryptography operations are using Openssl library crypto API. Each algorithm uses EVP_ interface from openssl API - which is recommended by Openssl maintainers. This patch adds libcrypto poll mode driver support to librte_cryptodev library. Signed-off-by: Slawomir Mrozowicz <slawomirx.mrozowicz@intel.com> Signed-off-by: Michal Kobylinski <michalx.kobylinski@intel.com> Signed-off-by: Tomasz Kulasek <tomaszx.kulasek@intel.com> Signed-off-by: Daniel Mrzyglod <danielx.t.mrzyglod@intel.com> --- v2: - add gcm crypto cipher and authentication algorithm - rework gmac crypto authentication algorithm v3: - fix pmd according to negative verification tests - change gmac aad max size - update documentation --- MAINTAINERS | 4 + config/common_base | 6 + doc/guides/cryptodevs/index.rst | 1 + doc/guides/cryptodevs/libcrypto.rst | 116 +++ doc/guides/rel_notes/release_16_11.rst | 23 +- drivers/crypto/Makefile | 1 + drivers/crypto/libcrypto/Makefile | 60 ++ drivers/crypto/libcrypto/rte_libcrypto_pmd.c | 1051 ++++++++++++++++++++ drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c | 708 +++++++++++++ .../crypto/libcrypto/rte_libcrypto_pmd_private.h | 174 ++++ .../crypto/libcrypto/rte_pmd_libcrypto_version.map | 3 + lib/librte_cryptodev/rte_cryptodev.h | 5 +- mk/rte.app.mk | 23 +- 13 files changed, 2162 insertions(+), 13 deletions(-) create mode 100644 doc/guides/cryptodevs/libcrypto.rst create mode 100644 drivers/crypto/libcrypto/Makefile create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd.c create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h create mode 100644 drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map diff --git a/MAINTAINERS b/MAINTAINERS index 58a10b8..1e9d1f8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -439,6 +439,10 @@ M: Declan Doherty <declan.doherty@intel.com> F: drivers/crypto/null/ F: doc/guides/cryptodevs/null.rst +LibCrypto Crypto PMD +M: Declan Doherty <declan.doherty@intel.com> +F: drivers/crypto/libcrypto/ +F: doc/guides/cryptodevs/libcrypto.rst Packet processing ----------------- diff --git a/config/common_base b/config/common_base index 3a412ee..87b8646 100644 --- a/config/common_base +++ b/config/common_base @@ -376,6 +376,12 @@ CONFIG_RTE_LIBRTE_PMD_AESNI_MB=n CONFIG_RTE_LIBRTE_PMD_AESNI_MB_DEBUG=n # +# Compile PMD for Software backed device +# +CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO=n +CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO_DEBUG=n + +# # Compile PMD for AESNI GCM device # CONFIG_RTE_LIBRTE_PMD_AESNI_GCM=n diff --git a/doc/guides/cryptodevs/index.rst b/doc/guides/cryptodevs/index.rst index 906f1b4..bae8e53 100644 --- a/doc/guides/cryptodevs/index.rst +++ b/doc/guides/cryptodevs/index.rst @@ -39,6 +39,7 @@ Crypto Device Drivers aesni_mb aesni_gcm kasumi + libcrypto null snow3g qat diff --git a/doc/guides/cryptodevs/libcrypto.rst b/doc/guides/cryptodevs/libcrypto.rst new file mode 100644 index 0000000..77eff95 --- /dev/null +++ b/doc/guides/cryptodevs/libcrypto.rst @@ -0,0 +1,116 @@ +.. 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. + +LibCrypto Crypto Poll Mode Driver + +This code provides the initial implementation of the libcrypto poll mode +driver. All cryptography operations are using Openssl library crypto API. +Each algorithm uses EVP_ interface from openssl API - which is recommended +by Openssl maintainers. + +For more details about openssl library please visit openssl webpage: +https://www.openssl.org/ + +Features +-------- + +LibCrypto PMD has support for: + +Supported cipher algorithms: +* ``RTE_CRYPTO_CIPHER_3DES_CBC`` +* ``RTE_CRYPTO_CIPHER_AES_CBC`` +* ``RTE_CRYPTO_CIPHER_AES_CTR`` +* ``RTE_CRYPTO_CIPHER_3DES_CTR`` +* ``RTE_CRYPTO_CIPHER_AES_GCM`` + +Supported authentication algorithms: +* ``RTE_CRYPTO_AUTH_AES_GMAC`` +* ``RTE_CRYPTO_AUTH_MD5`` +* ``RTE_CRYPTO_AUTH_SHA1`` +* ``RTE_CRYPTO_AUTH_SHA224`` +* ``RTE_CRYPTO_AUTH_SHA256`` +* ``RTE_CRYPTO_AUTH_SHA384`` +* ``RTE_CRYPTO_AUTH_SHA512`` +* ``RTE_CRYPTO_AUTH_MD5_HMAC`` +* ``RTE_CRYPTO_AUTH_SHA1_HMAC`` +* ``RTE_CRYPTO_AUTH_SHA224_HMAC`` +* ``RTE_CRYPTO_AUTH_SHA256_HMAC`` +* ``RTE_CRYPTO_AUTH_SHA384_HMAC`` +* ``RTE_CRYPTO_AUTH_SHA512_HMAC`` + + +Installation +------------ + +To compile libcrypto PMD, it has to be enabled in the config/common_base file +and appropriate openssl packages have to be installed in the build environment. + +The newest openssl library version is supported: +* 1.0.2h-fips 3 May 2016. +Older versions that were also verified: +* 1.0.1f 6 Jan 2014 +* 1.0.1 14 Mar 2012 + +For Ubuntu 14.04 LTS these packages have to be installed in the build system: +sudo apt-get install openssl +sudo apt-get install libc6-dev-i386 (for i686-native-linuxapp-gcc target) + +This code was also verified on Fedora 24. +This code was NOT yet verified on FreeBSD. + +Initialization +-------------- + +User can use app/test application to check how to use this pmd and to verify +crypto processing. + +Test name is cryptodev_libcrypto_autotest. +For performance test cryptodev_libcrypto_perftest can be used. + +To verify real traffic l2fwd-crypto example can be used with this command: + +.. code-block:: console + +sudo ./build/l2fwd-crypto -c 0x3 -n 4 --vdev "cryptodev_libcrypto_pmd" +--vdev "cryptodev_libcrypto_pmd"-- -p 0x3 --chain CIPHER_HASH +--cipher_op ENCRYPT --cipher_algo AES_CBC +--cipher_key 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f +--iv 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:ff +--auth_op GENERATE --auth_algo SHA1_HMAC +--auth_key 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11 +:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11 +:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11 + +Limitations +----------- + +* Maximum number of sessions is 2048. +* Chained mbufs are not supported. +* Hash only is not supported for GCM and GMAC. +* Cipher only is not supported for GCM and GMAC. diff --git a/doc/guides/rel_notes/release_16_11.rst b/doc/guides/rel_notes/release_16_11.rst index cc507a9..6e92966 100644 --- a/doc/guides/rel_notes/release_16_11.rst +++ b/doc/guides/rel_notes/release_16_11.rst @@ -34,7 +34,28 @@ New Features Refer to the previous release notes for examples. - This section is a comment. Make sure to start the actual text at the margin. +* **Added libcrypto PMD.** + + A new crypto PMD has been added, which provides several ciphering and hashing. + All cryptography operations are using Openssl library crypto API. + +* ** Added support of C3xxx Device in QAT PMD.** + Support for Device c3xxx has been enabled in QAT PMD. + +* ** Added support of C62XX Device in QAT PMD.** + Support for Device c62xx has been enabled in QAT PMD. + + +* **Updated the QAT PMD.** + The QAT PMD was updated with changes including the following: + + * Added support for MD5_HMAC algorithm. + * Added support for SHA224-HMAC algorithm. + * Added support for SHA384-HMAC algorithm. + * Added support for NULL algorithm. + * Added support for KASUMI (F8 and F9) algorithm. + * Added support for GMAC algorithm. + * Added support for 3DES block cipher algorithm. * ** Added support of C3xxx Device in QAT PMD.** Support for Device c3xxx has been enabled in QAT PMD. diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index 17d74fc..b452ea6 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -33,6 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += aesni_gcm DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += aesni_mb +DIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += libcrypto DIRS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += qat DIRS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += snow3g DIRS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI) += kasumi diff --git a/drivers/crypto/libcrypto/Makefile b/drivers/crypto/libcrypto/Makefile new file mode 100644 index 0000000..c5f8cf2 --- /dev/null +++ b/drivers/crypto/libcrypto/Makefile @@ -0,0 +1,60 @@ +# 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 + +# library name +LIB = librte_pmd_libcrypto.a + +# build flags +CFLAGS += -O3 +CFLAGS += $(WERROR_FLAGS) + +# library version +LIBABIVER := 1 + +# versioning export map +EXPORT_MAP := rte_pmd_libcrypto_version.map + +# external library dependencies +LDLIBS += -lcrypto + +# library source files +SRCS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += rte_libcrypto_pmd.c +SRCS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += rte_libcrypto_pmd_ops.c + +# library dependencies +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_eal +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_mbuf +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_mempool +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_ring +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_cryptodev + +include $(RTE_SDK)/mk/rte.lib.mk diff --git a/drivers/crypto/libcrypto/rte_libcrypto_pmd.c b/drivers/crypto/libcrypto/rte_libcrypto_pmd.c new file mode 100644 index 0000000..d9a60d0 --- /dev/null +++ b/drivers/crypto/libcrypto/rte_libcrypto_pmd.c @@ -0,0 +1,1051 @@ +/*- + * 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_common.h> +#include <rte_hexdump.h> +#include <rte_cryptodev.h> +#include <rte_cryptodev_pmd.h> +#include <rte_dev.h> +#include <rte_malloc.h> +#include <rte_cpuflags.h> + +#include <openssl/evp.h> + +#include "rte_libcrypto_pmd_private.h" + +static int cryptodev_libcrypto_uninit(const char *name); + +/*----------------------------------------------------------------------------*/ + +/** + * Global static parameter used to create a unique name for each + * LIBCRYPTO crypto device. + */ +static unsigned int unique_name_id; + +static inline int +create_unique_device_name(char *name, size_t size) +{ + int ret; + + if (name == NULL) + return -EINVAL; + + ret = snprintf(name, size, "%s_%u", RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), + unique_name_id++); + if (ret < 0) + return ret; + return 0; +} + +/** + * Increment counter by 1 + * Counter is 64 bit array, big-endian + */ +static void +ctr_inc(uint8_t *ctr) +{ + uint64_t *ctr64 = (uint64_t *)ctr; + + *ctr64 = __builtin_bswap64(*ctr64); + (*ctr64)++; + *ctr64 = __builtin_bswap64(*ctr64); +} + +/* + *------------------------------------------------------------------------------ + * Session Prepare + *------------------------------------------------------------------------------ + */ + +/** Get xform chain order */ +static enum libcrypto_chain_order +libcrypto_get_chain_order(const struct rte_crypto_sym_xform *xform) +{ + enum libcrypto_chain_order res = LIBCRYPTO_CHAIN_NOT_SUPPORTED; + + if (xform != NULL) { + if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) { + if (xform->next == NULL) + res = LIBCRYPTO_CHAIN_ONLY_AUTH; + else if (xform->next->type == + RTE_CRYPTO_SYM_XFORM_CIPHER) + res = LIBCRYPTO_CHAIN_AUTH_CIPHER; + } + if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) { + if (xform->next == NULL) + res = LIBCRYPTO_CHAIN_ONLY_CIPHER; + else if (xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH) + res = LIBCRYPTO_CHAIN_CIPHER_AUTH; + } + } + + return res; +} + +/** Get session cipher key from input cipher key */ +static void +get_cipher_key(uint8_t *input_key, int keylen, uint8_t *session_key) +{ + memcpy(session_key, input_key, keylen); +} + +/** Get key ede 24 bytes standard from input key */ +static int +get_cipher_key_ede(uint8_t *key, int keylen, uint8_t *key_ede) +{ + int res = 0; + + /* Initialize keys - 24 bytes: [key1-key2-key3] */ + switch (keylen) { + case 24: + memcpy(key_ede, key, 24); + break; + case 16: + /* K3 = K1 */ + memcpy(key_ede, key, 16); + memcpy(key_ede + 16, key, 8); + break; + case 8: + /* K1 = K2 = K3 (DES compatibility) */ + memcpy(key_ede, key, 8); + memcpy(key_ede + 8, key, 8); + memcpy(key_ede + 16, key, 8); + break; + default: + LIBCRYPTO_LOG_ERR("Unsupported key size"); + res = -EINVAL; + } + + return res; +} + +/** Get adequate libcrypto function for input cipher algorithm */ +static uint8_t +get_cipher_algo(enum rte_crypto_cipher_algorithm sess_algo, size_t keylen, + const EVP_CIPHER **algo) +{ + int res = 0; + + if (algo != NULL) { + switch (sess_algo) { + case RTE_CRYPTO_CIPHER_3DES_CBC: + switch (keylen) { + case 16: + *algo = EVP_des_ede_cbc(); + break; + case 24: + *algo = EVP_des_ede3_cbc(); + break; + default: + res = -EINVAL; + } + break; + case RTE_CRYPTO_CIPHER_3DES_CTR: + break; + case RTE_CRYPTO_CIPHER_AES_CBC: + switch (keylen) { + case 16: + *algo = EVP_aes_128_cbc(); + break; + case 24: + *algo = EVP_aes_192_cbc(); + break; + case 32: + *algo = EVP_aes_256_cbc(); + break; + default: + res = -EINVAL; + } + break; + case RTE_CRYPTO_CIPHER_AES_CTR: + switch (keylen) { + case 16: + *algo = EVP_aes_128_ctr(); + break; + case 24: + *algo = EVP_aes_192_ctr(); + break; + case 32: + *algo = EVP_aes_256_ctr(); + break; + default: + res = -EINVAL; + } + break; + case RTE_CRYPTO_CIPHER_AES_GCM: + switch (keylen) { + case 16: + *algo = EVP_aes_128_gcm(); + break; + case 24: + *algo = EVP_aes_192_gcm(); + break; + case 32: + *algo = EVP_aes_256_gcm(); + break; + default: + res = -EINVAL; + } + break; + default: + res = -EINVAL; + break; + } + } else { + res = -EINVAL; + } + + return res; +} + +/** Get adequate libcrypto function for input auth algorithm */ +static uint8_t +get_auth_algo(enum rte_crypto_auth_algorithm sessalgo, + const EVP_MD **algo) +{ + int res = 0; + + if (algo != NULL) { + switch (sessalgo) { + case RTE_CRYPTO_AUTH_MD5: + case RTE_CRYPTO_AUTH_MD5_HMAC: + *algo = EVP_md5(); + break; + case RTE_CRYPTO_AUTH_SHA1: + case RTE_CRYPTO_AUTH_SHA1_HMAC: + *algo = EVP_sha1(); + break; + case RTE_CRYPTO_AUTH_SHA224: + case RTE_CRYPTO_AUTH_SHA224_HMAC: + *algo = EVP_sha224(); + break; + case RTE_CRYPTO_AUTH_SHA256: + case RTE_CRYPTO_AUTH_SHA256_HMAC: + *algo = EVP_sha256(); + break; + case RTE_CRYPTO_AUTH_SHA384: + case RTE_CRYPTO_AUTH_SHA384_HMAC: + *algo = EVP_sha384(); + break; + case RTE_CRYPTO_AUTH_SHA512: + case RTE_CRYPTO_AUTH_SHA512_HMAC: + *algo = EVP_sha512(); + break; + default: + res = -EINVAL; + break; + } + } else { + res = -EINVAL; + } + + return res; +} + +/** Set session cipher parameters */ +static int +libcrypto_set_session_cipher_parameters(struct libcrypto_session *sess, + const struct rte_crypto_sym_xform *xform) +{ + /* Select cipher direction */ + sess->cipher.direction = xform->cipher.op; + /* Select cipher key */ + sess->cipher.key.length = xform->cipher.key.length; + + /* Select cipher algo */ + switch (xform->cipher.algo) { + case RTE_CRYPTO_CIPHER_3DES_CBC: + case RTE_CRYPTO_CIPHER_AES_CBC: + case RTE_CRYPTO_CIPHER_AES_CTR: + case RTE_CRYPTO_CIPHER_AES_GCM: + sess->cipher.mode = LIBCRYPTO_CIPHER_LIB; + sess->cipher.algo = xform->cipher.algo; + sess->cipher.ctx = EVP_CIPHER_CTX_new(); + + if (get_cipher_algo(sess->cipher.algo, sess->cipher.key.length, + &sess->cipher.evp_algo) != 0) + return -EINVAL; + + get_cipher_key(xform->cipher.key.data, sess->cipher.key.length, + sess->cipher.key.data); + + break; + + case RTE_CRYPTO_CIPHER_3DES_CTR: + sess->cipher.mode = LIBCRYPTO_CIPHER_DES3CTR; + sess->cipher.ctx = EVP_CIPHER_CTX_new(); + + if (get_cipher_key_ede(xform->cipher.key.data, + sess->cipher.key.length, sess->cipher.key.data) != 0) + return -EINVAL; + break; + + default: + sess->cipher.algo = RTE_CRYPTO_CIPHER_NULL; + return -EINVAL; + } + + return 0; +} + +/* Set session auth parameters */ +static int +libcrypto_set_session_auth_parameters(struct libcrypto_session *sess, + const struct rte_crypto_sym_xform *xform) +{ + /* Select auth generate/verify */ + sess->auth.operation = xform->auth.op; + sess->auth.algo = xform->auth.algo; + + /* Select auth algo */ + switch (xform->auth.algo) { + case RTE_CRYPTO_AUTH_AES_GMAC: + case RTE_CRYPTO_AUTH_AES_GCM: + /* Check additional condition for AES_GMAC/GCM */ + if (sess->cipher.algo != RTE_CRYPTO_CIPHER_AES_GCM) + return -EINVAL; + sess->chain_order = LIBCRYPTO_CHAIN_COMBINED; + break; + + case RTE_CRYPTO_AUTH_MD5: + case RTE_CRYPTO_AUTH_SHA1: + case RTE_CRYPTO_AUTH_SHA224: + case RTE_CRYPTO_AUTH_SHA256: + case RTE_CRYPTO_AUTH_SHA384: + case RTE_CRYPTO_AUTH_SHA512: + sess->auth.mode = LIBCRYPTO_AUTH_AS_AUTH; + if (get_auth_algo(xform->auth.algo, &sess->auth.auth.evp_algo) != 0) + return -EINVAL; + sess->auth.auth.ctx = EVP_MD_CTX_create(); + break; + + case RTE_CRYPTO_AUTH_MD5_HMAC: + case RTE_CRYPTO_AUTH_SHA1_HMAC: + case RTE_CRYPTO_AUTH_SHA224_HMAC: + case RTE_CRYPTO_AUTH_SHA256_HMAC: + case RTE_CRYPTO_AUTH_SHA384_HMAC: + case RTE_CRYPTO_AUTH_SHA512_HMAC: + sess->auth.mode = LIBCRYPTO_AUTH_AS_HMAC; + sess->auth.hmac.ctx = EVP_MD_CTX_create(); + if (get_auth_algo(xform->auth.algo, &sess->auth.hmac.evp_algo) != 0) + return -EINVAL; + sess->auth.hmac.pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, + xform->auth.key.data, xform->auth.key.length); + break; + + default: + return -EINVAL; + } + + return 0; +} + +/** Parse crypto xform chain and set private session parameters */ +int +libcrypto_set_session_parameters(struct libcrypto_session *sess, + const struct rte_crypto_sym_xform *xform) +{ + const struct rte_crypto_sym_xform *cipher_xform = NULL; + const struct rte_crypto_sym_xform *auth_xform = NULL; + + sess->chain_order = libcrypto_get_chain_order(xform); + switch (sess->chain_order) { + case LIBCRYPTO_CHAIN_ONLY_CIPHER: + cipher_xform = xform; + break; + case LIBCRYPTO_CHAIN_ONLY_AUTH: + auth_xform = xform; + break; + case LIBCRYPTO_CHAIN_CIPHER_AUTH: + cipher_xform = xform; + auth_xform = xform->next; + break; + case LIBCRYPTO_CHAIN_AUTH_CIPHER: + auth_xform = xform; + cipher_xform = xform->next; + break; + default: + return -EINVAL; + } + + /* cipher_xform must be check before auth_xform */ + if (cipher_xform) { + if (libcrypto_set_session_cipher_parameters(sess, cipher_xform)) { + LIBCRYPTO_LOG_ERR( + "Invalid/unsupported cipher parameters"); + return -EINVAL; + } + } + + if (auth_xform) { + if (libcrypto_set_session_auth_parameters(sess, auth_xform)) { + LIBCRYPTO_LOG_ERR( + "Invalid/unsupported auth parameters"); + return -EINVAL; + } + } + + return 0; +} + +/** Reset private session parameters */ +void +libcrypto_reset_session(struct libcrypto_session *sess) +{ + EVP_CIPHER_CTX_free(sess->cipher.ctx); + + switch (sess->auth.mode) { + case LIBCRYPTO_AUTH_AS_AUTH: + EVP_MD_CTX_destroy(sess->auth.auth.ctx); + break; + case LIBCRYPTO_AUTH_AS_HMAC: + EVP_PKEY_free(sess->auth.hmac.pkey); + EVP_MD_CTX_destroy(sess->auth.hmac.ctx); + break; + default: + break; + } +} + +/** Provide session for operation */ +static struct libcrypto_session * +get_session(struct libcrypto_qp *qp, struct rte_crypto_op *op) +{ + struct libcrypto_session *sess = NULL; + + if (op->sym->sess_type == RTE_CRYPTO_SYM_OP_WITH_SESSION) { + /* get existing session */ + if (likely(op->sym->session != NULL && + op->sym->session->dev_type == + RTE_CRYPTODEV_LIBCRYPTO_PMD)) + sess = (struct libcrypto_session *) + op->sym->session->_private; + } else { + /* provide internal session */ + void *_sess = NULL; + + if (!rte_mempool_get(qp->sess_mp, (void **)&_sess)) { + sess = (struct libcrypto_session *) + ((struct rte_cryptodev_sym_session *)_sess) + ->_private; + + if (unlikely(libcrypto_set_session_parameters( + sess, op->sym->xform) != 0)) { + rte_mempool_put(qp->sess_mp, _sess); + sess = NULL; + } else + op->sym->session = _sess; + } + } + + if (sess == NULL) + op->status = RTE_CRYPTO_OP_STATUS_INVALID_SESSION; + + return sess; +} + +/* + *------------------------------------------------------------------------------ + * Process Operations + *------------------------------------------------------------------------------ + */ + +/** Process standard libcrypto cipher encryption */ +static int +process_libcrypto_cipher_encrypt(uint8_t *src, uint8_t *dst, + uint8_t *iv, uint8_t *key, int srclen, + EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo) +{ + int dstlen, totlen; + + if (EVP_EncryptInit_ex(ctx, algo, NULL, key, iv) <= 0) + goto process_cipher_encrypt_err; + + if (EVP_EncryptUpdate(ctx, dst, &dstlen, src, srclen) <= 0) + goto process_cipher_encrypt_err; + + if (EVP_EncryptFinal_ex(ctx, dst + dstlen, &totlen) <= 0) + goto process_cipher_encrypt_err; + + return 0; + +process_cipher_encrypt_err: + LIBCRYPTO_LOG_ERR("Process libcrypto cipher encrypt failed"); + return -EINVAL; +} + +/** Process standard libcrypto cipher decryption */ +static int +process_libcrypto_cipher_decrypt(uint8_t *src, uint8_t *dst, + uint8_t *iv, uint8_t *key, int srclen, + EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo) +{ + int dstlen, totlen; + + if (EVP_DecryptInit_ex(ctx, algo, NULL, key, iv) <= 0) + goto process_cipher_decrypt_err; + + if (EVP_CIPHER_CTX_set_padding(ctx, 0) <= 0) + goto process_cipher_decrypt_err; + + if (EVP_DecryptUpdate(ctx, dst, &dstlen, src, srclen) <= 0) + goto process_cipher_decrypt_err; + + if (EVP_DecryptFinal_ex(ctx, dst + dstlen, &totlen) <= 0) + goto process_cipher_decrypt_err; + + return 0; + +process_cipher_decrypt_err: + LIBCRYPTO_LOG_ERR("Process libcrypto cipher decrypt failed"); + return -EINVAL; +} + +/** Process cipher des 3 ctr encryption, decryption algorithm */ +static int +process_libcrypto_cipher_des3ctr(uint8_t *src, uint8_t *dst, + uint8_t *iv, uint8_t *key, int srclen, EVP_CIPHER_CTX *ctx) +{ + uint8_t ebuf[8], ctr[8]; + int unused, n; + + /* We use 3DES encryption also for decryption. + * IV is not important for 3DES ecb + */ + if (EVP_EncryptInit_ex(ctx, EVP_des_ede3_ecb(), NULL, key, NULL) <= 0) + goto process_cipher_des3ctr_err; + + memcpy(ctr, iv, 8); + n = 0; + + while (n < srclen) { + if (n % 8 == 0) { + if (EVP_EncryptUpdate(ctx, (unsigned char *)&ebuf, &unused, + (const unsigned char *)&ctr, 8) <= 0) + goto process_cipher_des3ctr_err; + ctr_inc(ctr); + } + dst[n] = src[n] ^ ebuf[n % 8]; + n++; + } + + return 0; + +process_cipher_des3ctr_err: + LIBCRYPTO_LOG_ERR("Process libcrypto cipher des 3 ede ctr failed"); + return -EINVAL; +} + +/** Process auth/encription aes-gcm algorithm */ +static int +process_libcrypto_auth_encryption_gcm(uint8_t *src, int srclen, + uint8_t *aad, int aadlen, uint8_t *iv, int ivlen, + uint8_t *key, uint8_t *dst, uint8_t *tag, + EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo) +{ + int len = 0, unused = 0; + uint8_t empty[] = {}; + + if (EVP_EncryptInit_ex(ctx, algo, NULL, NULL, NULL) <= 0) + goto process_auth_encryption_gcm_err; + + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, NULL) <= 0) + goto process_auth_encryption_gcm_err; + + if (EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv) <= 0) + goto process_auth_encryption_gcm_err; + + if (aadlen > 0) { + if (EVP_EncryptUpdate(ctx, NULL, &len, aad, aadlen) <= 0) + goto process_auth_encryption_gcm_err; + + /* Workaround open ssl bug in version less then 1.0.1f */ + if (EVP_EncryptUpdate(ctx, empty, &unused, empty, 0) <= 0) + goto process_auth_encryption_gcm_err; + } + + if (srclen > 0) + if (EVP_EncryptUpdate(ctx, dst, &len, src, srclen) <= 0) + goto process_auth_encryption_gcm_err; + + if (EVP_EncryptFinal_ex(ctx, dst + len, &len) <= 0) + goto process_auth_encryption_gcm_err; + + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag) <= 0) + goto process_auth_encryption_gcm_err; + + return 0; + +process_auth_encryption_gcm_err: + LIBCRYPTO_LOG_ERR("Process libcrypto auth encryption gcm failed"); + return -EINVAL; +} + +static int +process_libcrypto_auth_decryption_gcm(uint8_t *src, int srclen, + uint8_t *aad, int aadlen, uint8_t *iv, int ivlen, + uint8_t *key, uint8_t *dst, uint8_t *tag, + EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo) +{ + int len = 0, unused = 0; + uint8_t empty[] = {}; + + if (EVP_DecryptInit_ex(ctx, algo, NULL, NULL, NULL) <= 0) + goto process_auth_decryption_gcm_err; + + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, NULL) <= 0) + goto process_auth_decryption_gcm_err; + + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag) <= 0) + goto process_auth_decryption_gcm_err; + + if (EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv) <= 0) + goto process_auth_decryption_gcm_err; + + if (aadlen > 0) { + if (EVP_DecryptUpdate(ctx, NULL, &len, aad, aadlen) <= 0) + goto process_auth_decryption_gcm_err; + + /* Workaround open ssl bug in version less then 1.0.1f */ + if (EVP_DecryptUpdate(ctx, empty, &unused, empty, 0) <= 0) + goto process_auth_decryption_gcm_err; + } + + if (srclen > 0) + if (EVP_DecryptUpdate(ctx, dst, &len, src, srclen) <= 0) + goto process_auth_decryption_gcm_err; + + if (EVP_DecryptFinal_ex(ctx, dst + len, &len) <= 0) + goto process_auth_decryption_gcm_final_err; + + return 0; + +process_auth_decryption_gcm_err: + LIBCRYPTO_LOG_ERR("Process libcrypto auth decription gcm failed"); + return -EINVAL; + +process_auth_decryption_gcm_final_err: + return -EFAULT; +} + +/** Process standard libcrypto auth algorithms */ +static int +process_libcrypto_auth(uint8_t *src, uint8_t *dst, + __rte_unused uint8_t *iv, __rte_unused EVP_PKEY * pkey, + int srclen, EVP_MD_CTX *ctx, const EVP_MD *algo) +{ + size_t dstlen; + + if (EVP_DigestInit_ex(ctx, algo, NULL) <= 0) + goto process_auth_err; + + if (EVP_DigestUpdate(ctx, (char *)src, srclen) <= 0) + goto process_auth_err; + + if (EVP_DigestFinal_ex(ctx, dst, (unsigned int *)&dstlen) <= 0) + goto process_auth_err; + + return 0; + +process_auth_err: + LIBCRYPTO_LOG_ERR("Process libcrypto auth failed"); + return -EINVAL; +} + +/** Process standard libcrypto auth algorithms with hmac */ +static int +process_libcrypto_auth_hmac(uint8_t *src, uint8_t *dst, + __rte_unused uint8_t *iv, EVP_PKEY *pkey, + int srclen, EVP_MD_CTX *ctx, const EVP_MD *algo) +{ + size_t dstlen; + + if (EVP_DigestSignInit(ctx, NULL, algo, NULL, pkey) <= 0) + goto process_auth_err; + + if (EVP_DigestSignUpdate(ctx, (char *)src, srclen) <= 0) + goto process_auth_err; + + if (EVP_DigestSignFinal(ctx, dst, &dstlen) <= 0) + goto process_auth_err; + + return 0; + +process_auth_err: + LIBCRYPTO_LOG_ERR("Process libcrypto auth failed"); + return -EINVAL; +} + +/*----------------------------------------------------------------------------*/ + +/** Process auth/cipher combined operation */ +static void +process_libcrypto_combined_op + (struct rte_crypto_op *op, struct libcrypto_session *sess, + struct rte_mbuf *mbuf_src, struct rte_mbuf *mbuf_dst) +{ + /* cipher */ + uint8_t *src = NULL, *dst = NULL, *iv, *tag, *aad; + int srclen, ivlen, aadlen, status = -1; + + iv = op->sym->cipher.iv.data; + ivlen = op->sym->cipher.iv.length; + aad = op->sym->auth.aad.data; + aadlen = op->sym->auth.aad.length; + + tag = op->sym->auth.digest.data; + if (tag == NULL) + tag = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *, + op->sym->cipher.data.offset + + op->sym->cipher.data.length); + + if (sess->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) + srclen = 0; + else { + srclen = op->sym->cipher.data.length; + src = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *, + op->sym->cipher.data.offset); + dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *, + op->sym->cipher.data.offset); + } + + if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) + status = process_libcrypto_auth_encryption_gcm( + src, srclen, aad, aadlen, iv, ivlen, + sess->cipher.key.data, dst, tag, + sess->cipher.ctx, sess->cipher.evp_algo); + else + status = process_libcrypto_auth_decryption_gcm( + src, srclen, aad, aadlen, iv, ivlen, + sess->cipher.key.data, dst, tag, + sess->cipher.ctx, sess->cipher.evp_algo); + + if (status != 0) { + if (status == (-EFAULT) && + sess->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY) + op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED; + else + op->status = RTE_CRYPTO_OP_STATUS_ERROR; + } +} + +/** Process cipher operation */ +static void +process_libcrypto_cipher_op + (struct rte_crypto_op *op, struct libcrypto_session *sess, + struct rte_mbuf *mbuf_src, struct rte_mbuf *mbuf_dst) +{ + uint8_t *src, *dst, *iv; + int srclen, status; + + srclen = op->sym->cipher.data.length; + src = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *, + op->sym->cipher.data.offset); + dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *, + op->sym->cipher.data.offset); + + iv = op->sym->cipher.iv.data; + + if (sess->cipher.mode == LIBCRYPTO_CIPHER_LIB) + if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) + status = process_libcrypto_cipher_encrypt(src, dst, iv, + sess->cipher.key.data, srclen, + sess->cipher.ctx, sess->cipher.evp_algo); + else + status = process_libcrypto_cipher_decrypt(src, dst, iv, + sess->cipher.key.data, srclen, + sess->cipher.ctx, sess->cipher.evp_algo); + else + status = process_libcrypto_cipher_des3ctr(src, dst, iv, + sess->cipher.key.data, srclen, sess->cipher.ctx); + + if (status != 0) + op->status = RTE_CRYPTO_OP_STATUS_ERROR; +} + +/** Process auth operation */ +static void +process_libcrypto_auth_op + (struct rte_crypto_op *op, struct libcrypto_session *sess, + struct rte_mbuf *mbuf_src, struct rte_mbuf *mbuf_dst) +{ + uint8_t *src, *dst; + int srclen, status; + + srclen = op->sym->auth.data.length; + src = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *, + op->sym->auth.data.offset); + + if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY) + dst = (uint8_t *)rte_pktmbuf_append(mbuf_src, + op->sym->auth.digest.length); + else { + dst = op->sym->auth.digest.data; + if (dst == NULL) + dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *, + op->sym->auth.data.offset + + op->sym->auth.data.length); + } + + switch (sess->auth.mode) { + case LIBCRYPTO_AUTH_AS_AUTH: + status = process_libcrypto_auth(src, dst, + NULL, NULL, srclen, + sess->auth.auth.ctx, sess->auth.auth.evp_algo); + break; + case LIBCRYPTO_AUTH_AS_HMAC: + status = process_libcrypto_auth_hmac(src, dst, + NULL, sess->auth.hmac.pkey, srclen, + sess->auth.hmac.ctx, sess->auth.hmac.evp_algo); + break; + default: + status = -1; + break; + } + + if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY) { + if (memcmp(dst, op->sym->auth.digest.data, + op->sym->auth.digest.length) != 0) { + op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED; + } + /* Trim area used for digest from mbuf. */ + rte_pktmbuf_trim(mbuf_src, + op->sym->auth.digest.length); + } + + if (status != 0) + op->status = RTE_CRYPTO_OP_STATUS_ERROR; +} + +/** Process crypto operation for mbuf */ +static int +process_op(const struct libcrypto_qp *qp, struct rte_crypto_op *op, + struct libcrypto_session *sess) +{ + struct rte_mbuf *msrc, *mdst; + int retval; + + msrc = op->sym->m_src; + mdst = op->sym->m_dst ? op->sym->m_dst : op->sym->m_src; + + op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED; + + switch (sess->chain_order) { + case LIBCRYPTO_CHAIN_ONLY_CIPHER: + process_libcrypto_cipher_op(op, sess, msrc, mdst); + break; + case LIBCRYPTO_CHAIN_ONLY_AUTH: + process_libcrypto_auth_op(op, sess, msrc, mdst); + break; + case LIBCRYPTO_CHAIN_CIPHER_AUTH: + process_libcrypto_cipher_op(op, sess, msrc, mdst); + process_libcrypto_auth_op(op, sess, mdst, mdst); + break; + case LIBCRYPTO_CHAIN_AUTH_CIPHER: + process_libcrypto_auth_op(op, sess, msrc, mdst); + process_libcrypto_cipher_op(op, sess, msrc, mdst); + break; + case LIBCRYPTO_CHAIN_COMBINED: + process_libcrypto_combined_op(op, sess, msrc, mdst); + break; + default: + op->status = RTE_CRYPTO_OP_STATUS_ERROR; + break; + } + + /* Free session if a session-less crypto op */ + if (op->sym->sess_type == RTE_CRYPTO_SYM_OP_SESSIONLESS) { + libcrypto_reset_session(sess); + memset(sess, 0, sizeof(struct libcrypto_session)); + rte_mempool_put(qp->sess_mp, op->sym->session); + op->sym->session = NULL; + } + + + if (op->status == RTE_CRYPTO_OP_STATUS_NOT_PROCESSED) + op->status = RTE_CRYPTO_OP_STATUS_SUCCESS; + + if (op->status != RTE_CRYPTO_OP_STATUS_ERROR) + retval = rte_ring_enqueue(qp->processed_ops, (void *)op); + else + retval = -1; + + return retval; +} + +/* + *------------------------------------------------------------------------------ + * PMD Framework + *------------------------------------------------------------------------------ + */ + +/** Enqueue burst */ +static uint16_t +libcrypto_pmd_enqueue_burst(void *queue_pair, struct rte_crypto_op **ops, + uint16_t nb_ops) +{ + struct libcrypto_session *sess; + struct libcrypto_qp *qp = queue_pair; + int i, retval; + + for (i = 0; i < nb_ops; i++) { + sess = get_session(qp, ops[i]); + if (unlikely(sess == NULL)) + goto enqueue_err; + + retval = process_op(qp, ops[i], sess); + if (unlikely(retval < 0)) + goto enqueue_err; + } + + qp->stats.enqueued_count += i; + return i; + +enqueue_err: + qp->stats.enqueue_err_count++; + return i; +} + +/** Dequeue burst */ +static uint16_t +libcrypto_pmd_dequeue_burst(void *queue_pair, struct rte_crypto_op **ops, + uint16_t nb_ops) +{ + struct libcrypto_qp *qp = queue_pair; + + unsigned int nb_dequeued = 0; + + nb_dequeued = rte_ring_dequeue_burst(qp->processed_ops, + (void **)ops, nb_ops); + qp->stats.dequeued_count += nb_dequeued; + + return nb_dequeued; +} + +/** Create LIBCRYPTO crypto device */ +static int +cryptodev_libcrypto_create(const char *name, + struct rte_crypto_vdev_init_params *init_params) +{ + struct rte_cryptodev *dev; + char crypto_dev_name[RTE_CRYPTODEV_NAME_MAX_LEN]; + struct libcrypto_private *internals; + + /* create a unique device name */ + if (create_unique_device_name(crypto_dev_name, + RTE_CRYPTODEV_NAME_MAX_LEN) != 0) { + LIBCRYPTO_LOG_ERR("failed to create unique cryptodev name"); + return -EINVAL; + } + + dev = rte_cryptodev_pmd_virtual_dev_init(crypto_dev_name, + sizeof(struct libcrypto_private), init_params->socket_id); + if (dev == NULL) { + LIBCRYPTO_LOG_ERR("failed to create cryptodev vdev"); + goto init_error; + } + + dev->dev_type = RTE_CRYPTODEV_LIBCRYPTO_PMD; + dev->dev_ops = rte_libcrypto_pmd_ops; + + /* register rx/tx burst functions for data path */ + dev->dequeue_burst = libcrypto_pmd_dequeue_burst; + dev->enqueue_burst = libcrypto_pmd_enqueue_burst; + + dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO | + RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING | + RTE_CRYPTODEV_FF_CPU_AESNI; + + /* Set vector instructions mode supported */ + internals = dev->data->dev_private; + + internals->max_nb_qpairs = init_params->max_nb_queue_pairs; + internals->max_nb_sessions = init_params->max_nb_sessions; + + return 0; + +init_error: + LIBCRYPTO_LOG_ERR("driver %s: cryptodev_libcrypto_create failed", name); + + cryptodev_libcrypto_uninit(crypto_dev_name); + return -EFAULT; +} + +/** Initialise LIBCRYPTO crypto device */ +static int +cryptodev_libcrypto_init(const char *name, + const char *input_args) +{ + struct rte_crypto_vdev_init_params init_params = { + RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_QUEUE_PAIRS, + RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_SESSIONS, + rte_socket_id() + }; + + rte_cryptodev_parse_vdev_init_params(&init_params, input_args); + + RTE_LOG(INFO, PMD, "Initialising %s on NUMA node %d\n", name, + init_params.socket_id); + RTE_LOG(INFO, PMD, " Max number of queue pairs = %d\n", + init_params.max_nb_queue_pairs); + RTE_LOG(INFO, PMD, " Max number of sessions = %d\n", + init_params.max_nb_sessions); + + return cryptodev_libcrypto_create(name, &init_params); +} + +/** Uninitialise LIBCRYPTO crypto device */ +static int +cryptodev_libcrypto_uninit(const char *name) +{ + if (name == NULL) + return -EINVAL; + + RTE_LOG(INFO, PMD, + "Closing LIBCRYPTO crypto device %s on numa socket %u\n", + name, rte_socket_id()); + + return 0; +} + +static struct rte_driver cryptodev_libcrypto_pmd_drv = { + .type = PMD_VDEV, + .init = cryptodev_libcrypto_init, + .uninit = cryptodev_libcrypto_uninit +}; + +PMD_REGISTER_DRIVER(cryptodev_libcrypto_pmd_drv, CRYPTODEV_NAME_LIBCRYPTO_PMD); +DRIVER_REGISTER_PARAM_STRING(CRYPTODEV_NAME_LIBCRYPTO_PMD, + "max_nb_queue_pairs=<int> " + "max_nb_sessions=<int> " + "socket_id=<int>"); diff --git a/drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c b/drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c new file mode 100644 index 0000000..b5d7bd5 --- /dev/null +++ b/drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c @@ -0,0 +1,708 @@ +/*- + * 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 <string.h> + +#include <rte_common.h> +#include <rte_malloc.h> +#include <rte_cryptodev_pmd.h> + +#include "rte_libcrypto_pmd_private.h" + + +static const struct rte_cryptodev_capabilities libcrypto_pmd_capabilities[] = { + { /* MD5 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_MD5_HMAC, + .block_size = 64, + .key_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .digest_size = { + .min = 16, + .max = 16, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* MD5 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_MD5, + .block_size = 64, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 16, + .max = 16, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA1 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .block_size = 64, + .key_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .digest_size = { + .min = 20, + .max = 20, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA1 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA1, + .block_size = 64, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 20, + .max = 20, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA224 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA224_HMAC, + .block_size = 64, + .key_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .digest_size = { + .min = 28, + .max = 28, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA224 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA224, + .block_size = 64, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 28, + .max = 28, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA256 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA256_HMAC, + .block_size = 64, + .key_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .digest_size = { + .min = 32, + .max = 32, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA256 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA256, + .block_size = 64, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 32, + .max = 32, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA384 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA384_HMAC, + .block_size = 128, + .key_size = { + .min = 128, + .max = 128, + .increment = 0 + }, + .digest_size = { + .min = 48, + .max = 48, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA384 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA384, + .block_size = 128, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 48, + .max = 48, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA512 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA512_HMAC, + .block_size = 128, + .key_size = { + .min = 128, + .max = 128, + .increment = 0 + }, + .digest_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA512 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA512, + .block_size = 128, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* AES CBC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, + {.cipher = { + .algo = RTE_CRYPTO_CIPHER_AES_CBC, + .block_size = 16, + .key_size = { + .min = 16, + .max = 32, + .increment = 8 + }, + .iv_size = { + .min = 16, + .max = 16, + .increment = 0 + } + }, } + }, } + }, + { /* AES CTR */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, + {.cipher = { + .algo = RTE_CRYPTO_CIPHER_AES_CTR, + .block_size = 16, + .key_size = { + .min = 16, + .max = 32, + .increment = 8 + }, + .iv_size = { + .min = 16, + .max = 16, + .increment = 0 + } + }, } + }, } + }, + { /* AES GCM (AUTH) */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_AES_GCM, + .block_size = 16, + .key_size = { + .min = 16, + .max = 32, + .increment = 8 + }, + .digest_size = { + .min = 16, + .max = 16, + .increment = 0 + }, + .aad_size = { + .min = 8, + .max = 12, + .increment = 4 + } + }, } + }, } + }, + { /* AES GCM (CIPHER) */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, + {.cipher = { + .algo = RTE_CRYPTO_CIPHER_AES_GCM, + .block_size = 16, + .key_size = { + .min = 16, + .max = 16, + .increment = 0 + }, + .iv_size = { + .min = 12, + .max = 16, + .increment = 4 + } + }, } + }, } + }, + { /* AES GMAC (AUTH) */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_AES_GMAC, + .block_size = 16, + .key_size = { + .min = 16, + .max = 32, + .increment = 8 + }, + .digest_size = { + .min = 16, + .max = 16, + .increment = 0 + }, + .aad_size = { + .min = 8, + .max = 65532, + .increment = 4 + } + }, } + }, } + }, + { /* 3DES CBC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, + {.cipher = { + .algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .block_size = 8, + .key_size = { + .min = 16, + .max = 24, + .increment = 8 + }, + .iv_size = { + .min = 8, + .max = 8, + .increment = 0 + } + }, } + }, } + }, + { /* 3DES CTR */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, + {.cipher = { + .algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .block_size = 8, + .key_size = { + .min = 16, + .max = 24, + .increment = 8 + }, + .iv_size = { + .min = 8, + .max = 8, + .increment = 0 + } + }, } + }, } + }, + + RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST() +}; + + +/** Configure device */ +static int +libcrypto_pmd_config(__rte_unused struct rte_cryptodev *dev) +{ + return 0; +} + +/** Start device */ +static int +libcrypto_pmd_start(__rte_unused struct rte_cryptodev *dev) +{ + return 0; +} + +/** Stop device */ +static void +libcrypto_pmd_stop(__rte_unused struct rte_cryptodev *dev) +{ +} + +/** Close device */ +static int +libcrypto_pmd_close(__rte_unused struct rte_cryptodev *dev) +{ + return 0; +} + + +/** Get device statistics */ +static void +libcrypto_pmd_stats_get(struct rte_cryptodev *dev, + struct rte_cryptodev_stats *stats) +{ + int qp_id; + + for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) { + struct libcrypto_qp *qp = dev->data->queue_pairs[qp_id]; + + stats->enqueued_count += qp->stats.enqueued_count; + stats->dequeued_count += qp->stats.dequeued_count; + + stats->enqueue_err_count += qp->stats.enqueue_err_count; + stats->dequeue_err_count += qp->stats.dequeue_err_count; + } +} + +/** Reset device statistics */ +static void +libcrypto_pmd_stats_reset(struct rte_cryptodev *dev) +{ + int qp_id; + + for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) { + struct libcrypto_qp *qp = dev->data->queue_pairs[qp_id]; + + memset(&qp->stats, 0, sizeof(qp->stats)); + } +} + + +/** Get device info */ +static void +libcrypto_pmd_info_get(struct rte_cryptodev *dev, + struct rte_cryptodev_info *dev_info) +{ + struct libcrypto_private *internals = dev->data->dev_private; + + if (dev_info != NULL) { + dev_info->dev_type = dev->dev_type; + dev_info->feature_flags = dev->feature_flags; + dev_info->capabilities = libcrypto_pmd_capabilities; + dev_info->max_nb_queue_pairs = internals->max_nb_qpairs; + dev_info->sym.max_nb_sessions = internals->max_nb_sessions; + } +} + +/** Release queue pair */ +static int +libcrypto_pmd_qp_release(struct rte_cryptodev *dev, uint16_t qp_id) +{ + if (dev->data->queue_pairs[qp_id] != NULL) { + rte_free(dev->data->queue_pairs[qp_id]); + dev->data->queue_pairs[qp_id] = NULL; + } + return 0; +} + +/** set a unique name for the queue pair based on it's name, dev_id and qp_id */ +static int +libcrypto_pmd_qp_set_unique_name(struct rte_cryptodev *dev, + struct libcrypto_qp *qp) +{ + unsigned int n = snprintf(qp->name, sizeof(qp->name), + "libcrypto_pmd_%u_qp_%u", + dev->data->dev_id, qp->id); + + if (n > sizeof(qp->name)) + return -1; + + return 0; +} + + +/** Create a ring to place processed operations on */ +static struct rte_ring * +libcrypto_pmd_qp_create_processed_ops_ring(struct libcrypto_qp *qp, + unsigned int ring_size, int socket_id) +{ + struct rte_ring *r; + + r = rte_ring_lookup(qp->name); + if (r) { + if (r->prod.size >= ring_size) { + LIBCRYPTO_LOG_INFO( + "Reusing existing ring %s for processed ops", + qp->name); + return r; + } + + LIBCRYPTO_LOG_ERR( + "Unable to reuse existing ring %s for processed ops", + qp->name); + return NULL; + } + + return rte_ring_create(qp->name, ring_size, socket_id, + RING_F_SP_ENQ | RING_F_SC_DEQ); +} + + +/** Setup a queue pair */ +static int +libcrypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id, + const struct rte_cryptodev_qp_conf *qp_conf, + int socket_id) +{ + struct libcrypto_qp *qp = NULL; + + /* Free memory prior to re-allocation if needed. */ + if (dev->data->queue_pairs[qp_id] != NULL) + libcrypto_pmd_qp_release(dev, qp_id); + + /* Allocate the queue pair data structure. */ + qp = rte_zmalloc_socket("LIBCRYPTO PMD Queue Pair", sizeof(*qp), + RTE_CACHE_LINE_SIZE, socket_id); + if (qp == NULL) + return -ENOMEM; + + qp->id = qp_id; + dev->data->queue_pairs[qp_id] = qp; + + if (libcrypto_pmd_qp_set_unique_name(dev, qp)) + goto qp_setup_cleanup; + + qp->processed_ops = libcrypto_pmd_qp_create_processed_ops_ring(qp, + qp_conf->nb_descriptors, socket_id); + if (qp->processed_ops == NULL) + goto qp_setup_cleanup; + + qp->sess_mp = dev->data->session_pool; + + memset(&qp->stats, 0, sizeof(qp->stats)); + + return 0; + +qp_setup_cleanup: + if (qp) + rte_free(qp); + + return -1; +} + +/** Start queue pair */ +static int +libcrypto_pmd_qp_start(__rte_unused struct rte_cryptodev *dev, + __rte_unused uint16_t queue_pair_id) +{ + return -ENOTSUP; +} + +/** Stop queue pair */ +static int +libcrypto_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev, + __rte_unused uint16_t queue_pair_id) +{ + return -ENOTSUP; +} + +/** Return the number of allocated queue pairs */ +static uint32_t +libcrypto_pmd_qp_count(struct rte_cryptodev *dev) +{ + return dev->data->nb_queue_pairs; +} + +/** Returns the size of the session structure */ +static unsigned +libcrypto_pmd_session_get_size(struct rte_cryptodev *dev __rte_unused) +{ + return sizeof(struct libcrypto_session); +} + +/** Configure the session from a crypto xform chain */ +static void * +libcrypto_pmd_session_configure(struct rte_cryptodev *dev __rte_unused, + struct rte_crypto_sym_xform *xform, void *sess) +{ + if (unlikely(sess == NULL)) { + LIBCRYPTO_LOG_ERR("invalid session struct"); + return NULL; + } + + if (libcrypto_set_session_parameters( + sess, xform) != 0) { + LIBCRYPTO_LOG_ERR("failed configure session parameters"); + return NULL; + } + + return sess; +} + + +/** Clear the memory of session so it doesn't leave key material behind */ +static void +libcrypto_pmd_session_clear(struct rte_cryptodev *dev __rte_unused, void *sess) +{ + /* + * Current just resetting the whole data structure, need to investigate + * whether a more selective reset of key would be more performant + */ + if (sess) { + libcrypto_reset_session(sess); + memset(sess, 0, sizeof(struct libcrypto_session)); + } +} + +struct rte_cryptodev_ops libcrypto_pmd_ops = { + .dev_configure = libcrypto_pmd_config, + .dev_start = libcrypto_pmd_start, + .dev_stop = libcrypto_pmd_stop, + .dev_close = libcrypto_pmd_close, + + .stats_get = libcrypto_pmd_stats_get, + .stats_reset = libcrypto_pmd_stats_reset, + + .dev_infos_get = libcrypto_pmd_info_get, + + .queue_pair_setup = libcrypto_pmd_qp_setup, + .queue_pair_release = libcrypto_pmd_qp_release, + .queue_pair_start = libcrypto_pmd_qp_start, + .queue_pair_stop = libcrypto_pmd_qp_stop, + .queue_pair_count = libcrypto_pmd_qp_count, + + .session_get_size = libcrypto_pmd_session_get_size, + .session_configure = libcrypto_pmd_session_configure, + .session_clear = libcrypto_pmd_session_clear +}; + +struct rte_cryptodev_ops *rte_libcrypto_pmd_ops = &libcrypto_pmd_ops; diff --git a/drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h b/drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h new file mode 100644 index 0000000..dbef57f --- /dev/null +++ b/drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h @@ -0,0 +1,174 @@ +/*- + * 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 _LIBCRYPTO_PMD_PRIVATE_H_ +#define _LIBCRYPTO_PMD_PRIVATE_H_ + +#include <openssl/evp.h> +#include <openssl/des.h> + + +#define LIBCRYPTO_LOG_ERR(fmt, args...) \ + RTE_LOG(ERR, CRYPTODEV, "[%s] %s() line %u: " fmt "\n", \ + RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), \ + __func__, __LINE__, ## args) + +#ifdef RTE_LIBRTE_LIBCRYPTO_DEBUG +#define LIBCRYPTO_LOG_INFO(fmt, args...) \ + RTE_LOG(INFO, CRYPTODEV, "[%s] %s() line %u: " fmt "\n", \ + RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), \ + __func__, __LINE__, ## args) + +#define LIBCRYPTO_LOG_DBG(fmt, args...) \ + RTE_LOG(DEBUG, CRYPTODEV, "[%s] %s() line %u: " fmt "\n", \ + RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), \ + __func__, __LINE__, ## args) +#else +#define LIBCRYPTO_LOG_INFO(fmt, args...) +#define LIBCRYPTO_LOG_DBG(fmt, args...) +#endif + + +/** LIBCRYPTO operation order mode enumerator */ +enum libcrypto_chain_order { + LIBCRYPTO_CHAIN_ONLY_CIPHER, + LIBCRYPTO_CHAIN_ONLY_AUTH, + LIBCRYPTO_CHAIN_CIPHER_AUTH, + LIBCRYPTO_CHAIN_AUTH_CIPHER, + LIBCRYPTO_CHAIN_COMBINED, + LIBCRYPTO_CHAIN_NOT_SUPPORTED +}; + +/** LIBCRYPTO cipher mode enumerator */ +enum libcrypto_cipher_mode { + LIBCRYPTO_CIPHER_LIB, + LIBCRYPTO_CIPHER_DES3CTR, +}; + +/** LIBCRYPTO auth mode enumerator */ +enum libcrypto_auth_mode { + LIBCRYPTO_AUTH_AS_AUTH, + LIBCRYPTO_AUTH_AS_HMAC, +}; + +/** private data structure for each LIBCRYPTO crypto device */ +struct libcrypto_private { + unsigned int max_nb_qpairs; + /**< Max number of queue pairs */ + unsigned int max_nb_sessions; + /**< Max number of sessions */ +}; + +/** LIBCRYPTO crypto queue pair */ +struct libcrypto_qp { + uint16_t id; + /**< Queue Pair Identifier */ + char name[RTE_CRYPTODEV_NAME_LEN]; + /**< Unique Queue Pair Name */ + struct rte_ring *processed_ops; + /**< Ring for placing process packets */ + struct rte_mempool *sess_mp; + /**< Session Mempool */ + struct rte_cryptodev_stats stats; + /**< Queue pair statistics */ +} __rte_cache_aligned; + +/** LIBCRYPTO crypto private session structure */ +struct libcrypto_session { + enum libcrypto_chain_order chain_order; + /**< chain order mode */ + + /** Cipher Parameters */ + struct { + enum rte_crypto_cipher_operation direction; + /**< cipher operation direction */ + enum libcrypto_cipher_mode mode; + /**< cipher operation mode */ + enum rte_crypto_cipher_algorithm algo; + /**< cipher algorithm */ + + struct { + uint8_t data[32]; + /**< key data */ + size_t length; + /**< key length in bytes */ + } key; + + const EVP_CIPHER *evp_algo; + /**< pointer to EVP algorithm function */ + EVP_CIPHER_CTX *ctx; + /**< pointer to EVP context structure */ + } cipher; + + /** Authentication Parameters */ + struct { + enum rte_crypto_auth_operation operation; + /**< auth operation generate or verify */ + enum libcrypto_auth_mode mode; + /**< auth operation mode */ + enum rte_crypto_auth_algorithm algo; + /**< cipher algorithm */ + + union { + struct { + const EVP_MD *evp_algo; + /**< pointer to EVP algorithm function */ + EVP_MD_CTX *ctx; + /**< pointer to EVP context structure */ + } auth; + + struct { + EVP_PKEY *pkey; + /**< pointer to EVP key */ + const EVP_MD *evp_algo; + /**< pointer to EVP algorithm function */ + EVP_MD_CTX *ctx; + /**< pointer to EVP context structure */ + } hmac; + }; + } auth; + +} __rte_cache_aligned; + +/** Set and validate LIBCRYPTO crypto session parameters */ +extern int +libcrypto_set_session_parameters(struct libcrypto_session *sess, + const struct rte_crypto_sym_xform *xform); + +/** Reset LIBCRYPTO crypto session parameters */ +extern void +libcrypto_reset_session(struct libcrypto_session *sess); + +/** device specific operations function pointer structure */ +extern struct rte_cryptodev_ops *rte_libcrypto_pmd_ops; + +#endif /* _LIBCRYPTO_PMD_PRIVATE_H_ */ diff --git a/drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map b/drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map new file mode 100644 index 0000000..cc5829e --- /dev/null +++ b/drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map @@ -0,0 +1,3 @@ +DPDK_16.11 { + local: *; +}; diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h index b1658eb..311fd78 100644 --- a/lib/librte_cryptodev/rte_cryptodev.h +++ b/lib/librte_cryptodev/rte_cryptodev.h @@ -56,6 +56,8 @@ extern "C" { /**< AES-NI Multi buffer PMD device name */ #define CRYPTODEV_NAME_AESNI_GCM_PMD crypto_aesni_gcm /**< AES-NI GCM PMD device name */ +#define CRYPTODEV_NAME_LIBCRYPTO_PMD cryptodev_libcrypto +/**< Open SSL Crypto PMD device name */ #define CRYPTODEV_NAME_QAT_SYM_PMD crypto_qat /**< Intel QAT Symmetric Crypto PMD device name */ #define CRYPTODEV_NAME_SNOW3G_PMD crypto_snow3g @@ -73,7 +75,8 @@ enum rte_cryptodev_type { RTE_CRYPTODEV_QAT_SYM_PMD, /**< QAT PMD Symmetric Crypto */ RTE_CRYPTODEV_SNOW3G_PMD, /**< SNOW 3G PMD */ RTE_CRYPTODEV_KASUMI_PMD, /**< KASUMI PMD */ - RTE_CRYPTODEV_ZUC_PMD /**< ZUC PMD */ + RTE_CRYPTODEV_ZUC_PMD, /**< ZUC PMD */ + RTE_CRYPTODEV_LIBCRYPTO_PMD, /**< LibCrypto PMD */ }; extern const char **rte_cyptodev_names; diff --git a/mk/rte.app.mk b/mk/rte.app.mk index 440bf83..43ea1c1 100644 --- a/mk/rte.app.mk +++ b/mk/rte.app.mk @@ -131,18 +131,19 @@ endif # $(CONFIG_RTE_LIBRTE_VHOST) _LDLIBS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += -lrte_pmd_vmxnet3_uio ifeq ($(CONFIG_RTE_LIBRTE_CRYPTODEV),y) -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -lrte_pmd_aesni_mb -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += -lrte_pmd_aesni_gcm -lcrypto -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -lrte_pmd_aesni_mb +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += -lrte_pmd_aesni_gcm -lcrypto +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += -lrte_pmd_libcrypto -lcrypto _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO) += -lrte_pmd_null_crypto -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += -lrte_pmd_qat -lcrypto -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += -lrte_pmd_snow3g -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += -L$(LIBSSO_SNOW3G_PATH)/build -lsso_snow3g -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI) += -lrte_pmd_kasumi -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI) += -L$(LIBSSO_KASUMI_PATH)/build -lsso_kasumi -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_ZUC) += -lrte_pmd_zuc -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_ZUC) += -L$(LIBSSO_ZUC_PATH)/build -lsso_zuc +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += -lrte_pmd_qat -lcrypto +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += -lrte_pmd_snow3g +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += -L$(LIBSSO_SNOW3G_PATH)/build -lsso_snow3g +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI) += -lrte_pmd_kasumi +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI) += -L$(LIBSSO_KASUMI_PATH)/build -lsso_kasumi +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_ZUC) += -lrte_pmd_zuc +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_ZUC) += -L$(LIBSSO_ZUC_PATH)/build -lsso_zuc endif # CONFIG_RTE_LIBRTE_CRYPTODEV endif # !CONFIG_RTE_BUILD_SHARED_LIBS -- 2.5.0 ^ permalink raw reply [flat|nested] 34+ messages in thread
* [dpdk-dev] [PATCH v4 2/5] app/test: cryptodev AES tests rework 2016-09-30 16:17 ` [dpdk-dev] [PATCH v4 0/5] new crypto software based device Slawomir Mrozowicz 2016-09-30 16:17 ` [dpdk-dev] [PATCH v4 1/5] libcrypto_pmd: initial implementation of SW crypto device Slawomir Mrozowicz @ 2016-09-30 16:32 ` Slawomir Mrozowicz 2016-09-30 16:32 ` [dpdk-dev] [PATCH v4 3/5] app/test: added tests for libcrypto PMD Slawomir Mrozowicz ` (2 more replies) 2016-10-03 14:26 ` [dpdk-dev] [PATCH v5 0/4] new crypto software based device Slawomir Mrozowicz 2 siblings, 3 replies; 34+ messages in thread From: Slawomir Mrozowicz @ 2016-09-30 16:32 UTC (permalink / raw) To: dev; +Cc: Slawomir Mrozowicz, Piotr Azarewicz, Fiona Trahe This patch rework AES tests . In general - rename AES-named functions to blockcipher functions pattern. Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com> Signed-off-by: Fiona Trahe <fiona.trahe@intel.com> --- app/test/Makefile | 2 +- app/test/test_cryptodev.c | 74 +- app/test/test_cryptodev_aes.c | 687 ----------------- app/test/test_cryptodev_aes.h | 1124 ---------------------------- app/test/test_cryptodev_aes_test_vectors.h | 797 ++++++++++++++++++++ app/test/test_cryptodev_blockcipher.c | 509 +++++++++++++ app/test/test_cryptodev_blockcipher.h | 124 +++ 7 files changed, 1478 insertions(+), 1839 deletions(-) delete mode 100644 app/test/test_cryptodev_aes.c delete mode 100644 app/test/test_cryptodev_aes.h create mode 100644 app/test/test_cryptodev_aes_test_vectors.h create mode 100644 app/test/test_cryptodev_blockcipher.c create mode 100644 app/test/test_cryptodev_blockcipher.h diff --git a/app/test/Makefile b/app/test/Makefile index 611d77a..5be023a 100644 --- a/app/test/Makefile +++ b/app/test/Makefile @@ -193,7 +193,7 @@ endif SRCS-$(CONFIG_RTE_LIBRTE_PMD_RING) += test_pmd_ring.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_RING) += test_pmd_ring_perf.c -SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_aes.c +SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_blockcipher.c SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_perf.c SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev.c diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c index 9d7caba..c46db94 100644 --- a/app/test/test_cryptodev.c +++ b/app/test/test_cryptodev.c @@ -43,7 +43,8 @@ #include "test.h" #include "test_cryptodev.h" -#include "test_cryptodev_aes.h" +#include "test_cryptodev_blockcipher.h" +#include "test_cryptodev_aes_test_vectors.h" #include "test_cryptodev_kasumi_test_vectors.h" #include "test_cryptodev_kasumi_hash_test_vectors.h" #include "test_cryptodev_snow3g_test_vectors.h" @@ -86,12 +87,16 @@ struct crypto_unittest_params { */ static int test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( - struct crypto_unittest_params *ut_params); + struct crypto_unittest_params *ut_params, uint8_t *cipher_key, + uint8_t *hmac_key); static int test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, struct crypto_unittest_params *ut_params, - struct crypto_testsuite_params *ts_param); + struct crypto_testsuite_params *ts_param, + const uint8_t *cipher, + const uint8_t *digest, + const uint8_t *iv); static struct rte_mbuf * setup_test_string(struct rte_mempool *mpool, @@ -313,7 +318,7 @@ testsuite_setup(void) nb_devs = rte_cryptodev_count(); if (nb_devs < 1) { - RTE_LOG(ERR, USER1, "No crypto devices found?"); + RTE_LOG(ERR, USER1, "No crypto devices found?\n"); return TEST_FAILED; } @@ -872,7 +877,6 @@ static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA1_digest[] = { 0x18, 0x8c, 0x1d, 0x32 }; - static int test_AES_CBC_HMAC_SHA1_encrypt_digest(void) { @@ -1003,17 +1007,24 @@ static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA512_digest[] = { static int test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( - struct crypto_unittest_params *ut_params); + struct crypto_unittest_params *ut_params, + uint8_t *cipher_key, + uint8_t *hmac_key); static int test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, struct crypto_unittest_params *ut_params, - struct crypto_testsuite_params *ts_params); + struct crypto_testsuite_params *ts_params, + const uint8_t *cipher, + const uint8_t *digest, + const uint8_t *iv); static int test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( - struct crypto_unittest_params *ut_params) + struct crypto_unittest_params *ut_params, + uint8_t *cipher_key, + uint8_t *hmac_key) { /* Setup Cipher Parameters */ @@ -1022,7 +1033,7 @@ test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC; ut_params->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT; - ut_params->cipher_xform.cipher.key.data = aes_cbc_key; + ut_params->cipher_xform.cipher.key.data = cipher_key; ut_params->cipher_xform.cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC; /* Setup HMAC Parameters */ @@ -1031,7 +1042,7 @@ test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SHA512_HMAC; - ut_params->auth_xform.auth.key.data = hmac_sha512_key; + ut_params->auth_xform.auth.key.data = hmac_key; ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA512; ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA512; @@ -1042,12 +1053,15 @@ test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( static int test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, struct crypto_unittest_params *ut_params, - struct crypto_testsuite_params *ts_params) + struct crypto_testsuite_params *ts_params, + const uint8_t *cipher, + const uint8_t *digest, + const uint8_t *iv) { /* Generate test mbuf data and digest */ ut_params->ibuf = setup_test_string(ts_params->mbuf_pool, (const char *) - catch_22_quote_2_512_bytes_AES_CBC_ciphertext, + cipher, QUOTE_512_BYTES, 0); ut_params->digest = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, @@ -1055,7 +1069,7 @@ test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, TEST_ASSERT_NOT_NULL(ut_params->digest, "no room to append digest"); rte_memcpy(ut_params->digest, - catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA512_digest, + digest, DIGEST_BYTE_LENGTH_SHA512); /* Generate Crypto op data structure */ @@ -1085,7 +1099,7 @@ test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, ut_params->ibuf, 0); sym_op->cipher.iv.length = CIPHER_IV_LENGTH_AES_CBC; - rte_memcpy(sym_op->cipher.iv.data, aes_cbc_iv, + rte_memcpy(sym_op->cipher.iv.data, iv, CIPHER_IV_LENGTH_AES_CBC); sym_op->cipher.data.offset = CIPHER_IV_LENGTH_AES_CBC; @@ -1115,14 +1129,15 @@ test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, } static int -test_AES_mb_all(void) +test_AES_chain_mb_all(void) { struct crypto_testsuite_params *ts_params = &testsuite_params; int status; - status = test_AES_all_tests(ts_params->mbuf_pool, + status = test_blockcipher_all_tests(ts_params->mbuf_pool, ts_params->op_mpool, ts_params->valid_devs[0], - RTE_CRYPTODEV_AESNI_MB_PMD); + RTE_CRYPTODEV_AESNI_MB_PMD, + BLKCIPHER_AES_CHAIN_TYPE); TEST_ASSERT_EQUAL(status, 0, "Test failed"); @@ -1130,14 +1145,15 @@ test_AES_mb_all(void) } static int -test_AES_qat_all(void) +test_AES_chain_qat_all(void) { struct crypto_testsuite_params *ts_params = &testsuite_params; int status; - status = test_AES_all_tests(ts_params->mbuf_pool, + status = test_blockcipher_all_tests(ts_params->mbuf_pool, ts_params->op_mpool, ts_params->valid_devs[0], - RTE_CRYPTODEV_QAT_SYM_PMD); + RTE_CRYPTODEV_QAT_SYM_PMD, + BLKCIPHER_AES_CHAIN_TYPE); TEST_ASSERT_EQUAL(status, 0, "Test failed"); @@ -4024,7 +4040,8 @@ test_multi_session(void) uint16_t i; - test_AES_CBC_HMAC_SHA512_decrypt_create_session_params(ut_params); + test_AES_CBC_HMAC_SHA512_decrypt_create_session_params(ut_params, + aes_cbc_key, hmac_sha512_key); rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info); @@ -4043,10 +4060,13 @@ test_multi_session(void) i); /* Attempt to send a request on each session */ - TEST_ASSERT_SUCCESS(test_AES_CBC_HMAC_SHA512_decrypt_perform( - sessions[i], ut_params, ts_params), - "Failed to perform decrypt on request " - "number %u.", i); + TEST_ASSERT_SUCCESS( + test_AES_CBC_HMAC_SHA512_decrypt_perform(sessions[i], ut_params, + ts_params, + catch_22_quote_2_512_bytes_AES_CBC_ciphertext, + catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA512_digest, + aes_cbc_iv), + "Failed to perform decrypt on request number %u.", i); /* free crypto operation structure */ if (ut_params->op) rte_crypto_op_free(ut_params->op); @@ -4700,7 +4720,7 @@ static struct unit_test_suite cryptodev_qat_testsuite = { TEST_CASE_ST(ut_setup, ut_teardown, test_multi_session), - TEST_CASE_ST(ut_setup, ut_teardown, test_AES_qat_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_qat_all), TEST_CASE_ST(ut_setup, ut_teardown, test_stats), /** AES GCM Authenticated Encryption */ @@ -4836,7 +4856,7 @@ static struct unit_test_suite cryptodev_aesni_mb_testsuite = { .setup = testsuite_setup, .teardown = testsuite_teardown, .unit_test_cases = { - TEST_CASE_ST(ut_setup, ut_teardown, test_AES_mb_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_mb_all), TEST_CASES_END() /**< NULL terminate unit test array */ } diff --git a/app/test/test_cryptodev_aes.c b/app/test/test_cryptodev_aes.c deleted file mode 100644 index e19c45b..0000000 --- a/app/test/test_cryptodev_aes.c +++ /dev/null @@ -1,687 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2015-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_common.h> -#include <rte_hexdump.h> -#include <rte_mbuf.h> -#include <rte_malloc.h> -#include <rte_memcpy.h> - -#include <rte_crypto.h> -#include <rte_cryptodev.h> -#include <rte_cryptodev_pmd.h> - -#include "test.h" -#include "test_cryptodev_aes.h" - -#ifndef AES_TEST_MSG_LEN -#define AES_TEST_MSG_LEN 256 -#endif - -#define AES_TEST_OP_ENCRYPT 0x01 -#define AES_TEST_OP_DECRYPT 0x02 -#define AES_TEST_OP_AUTH_GEN 0x04 -#define AES_TEST_OP_AUTH_VERIFY 0x08 - -#define AES_TEST_FEATURE_OOP 0x01 -#define AES_TEST_FEATURE_SESSIONLESS 0x02 -#define AES_TEST_FEATURE_STOPPER 0x04 /* stop upon failing */ - -#define AES_TEST_TARGET_PMD_MB 0x0001 /* Multi-buffer flag */ -#define AES_TEST_TARGET_PMD_QAT 0x0002 /* QAT flag */ - -#define AES_TEST_OP_CIPHER (AES_TEST_OP_ENCRYPT | \ - AES_TEST_OP_DECRYPT) - -#define AES_TEST_OP_AUTH (AES_TEST_OP_AUTH_GEN | \ - AES_TEST_OP_AUTH_VERIFY) - -#define AES_TEST_OP_ENC_AUTH_GEN (AES_TEST_OP_ENCRYPT | \ - AES_TEST_OP_AUTH_GEN) - -#define AES_TEST_OP_AUTH_VERIFY_DEC (AES_TEST_OP_DECRYPT | \ - AES_TEST_OP_AUTH_VERIFY) - -struct aes_test_case { - const char *test_descr; /* test description */ - const struct aes_test_data *test_data; - uint8_t op_mask; /* operation mask */ - uint8_t feature_mask; - uint32_t pmd_mask; -}; - -static const struct aes_test_case aes_test_cases[] = { - { - .test_descr = "AES-128-CTR HMAC-SHA1 Encryption Digest", - .test_data = &aes_test_data_1, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CTR HMAC-SHA1 Decryption Digest " - "Verify", - .test_data = &aes_test_data_1, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-192-CTR XCBC Encryption Digest", - .test_data = &aes_test_data_2, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-192-CTR XCBC Decryption Digest Verify", - .test_data = &aes_test_data_2, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-256-CTR HMAC-SHA1 Encryption Digest", - .test_data = &aes_test_data_3, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-256-CTR HMAC-SHA1 Decryption Digest " - "Verify", - .test_data = &aes_test_data_3, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest", - .test_data = &aes_test_data_4, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " - "Verify", - .test_data = &aes_test_data_4, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA256 Encryption Digest", - .test_data = &aes_test_data_5, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA256 Decryption Digest " - "Verify", - .test_data = &aes_test_data_5, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest", - .test_data = &aes_test_data_6, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest " - "Sessionless", - .test_data = &aes_test_data_6, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .feature_mask = AES_TEST_FEATURE_SESSIONLESS, - .pmd_mask = AES_TEST_TARGET_PMD_MB - }, - { - .test_descr = "AES-128-CBC HMAC-SHA512 Decryption Digest " - "Verify", - .test_data = &aes_test_data_6, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC XCBC Encryption Digest", - .test_data = &aes_test_data_7, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC XCBC Decryption Digest Verify", - .test_data = &aes_test_data_7, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest " - "OOP", - .test_data = &aes_test_data_4, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .feature_mask = AES_TEST_FEATURE_OOP, - .pmd_mask = AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " - "Verify OOP", - .test_data = &aes_test_data_4, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .feature_mask = AES_TEST_FEATURE_OOP, - .pmd_mask = AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA224 Encryption Digest", - .test_data = &aes_test_data_8, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA224 Decryption Digest " - "Verify", - .test_data = &aes_test_data_8, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA384 Encryption Digest", - .test_data = &aes_test_data_9, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA384 Decryption Digest " - "Verify", - .test_data = &aes_test_data_9, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, -}; - -static int -test_AES_one_case(const struct aes_test_case *t, - struct rte_mempool *mbuf_pool, - struct rte_mempool *op_mpool, - uint8_t dev_id, - enum rte_cryptodev_type cryptodev_type, - char *test_msg) -{ - struct rte_mbuf *ibuf = NULL; - struct rte_mbuf *obuf = NULL; - struct rte_mbuf *iobuf; - struct rte_crypto_sym_xform *cipher_xform = NULL; - struct rte_crypto_sym_xform *auth_xform = NULL; - struct rte_crypto_sym_xform *init_xform = NULL; - struct rte_crypto_sym_op *sym_op = NULL; - struct rte_crypto_op *op = NULL; - struct rte_cryptodev_sym_session *sess = NULL; - - int status = TEST_SUCCESS; - const struct aes_test_data *tdata = t->test_data; - uint8_t cipher_key[tdata->cipher_key.len]; - uint8_t auth_key[tdata->auth_key.len]; - uint32_t buf_len = tdata->ciphertext.len; - uint32_t digest_len = 0; - char *buf_p = NULL; - - if (tdata->cipher_key.len) - memcpy(cipher_key, tdata->cipher_key.data, - tdata->cipher_key.len); - if (tdata->auth_key.len) - memcpy(auth_key, tdata->auth_key.data, - tdata->auth_key.len); - - switch (cryptodev_type) { - case RTE_CRYPTODEV_QAT_SYM_PMD: - digest_len = tdata->digest.len; - break; - case RTE_CRYPTODEV_AESNI_MB_PMD: - digest_len = tdata->digest.truncated_len; - break; - default: - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Unsupported PMD type"); - status = TEST_FAILED; - goto error_exit; - } - - /* preparing data */ - ibuf = rte_pktmbuf_alloc(mbuf_pool); - if (!ibuf) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Allocation of rte_mbuf failed"); - status = TEST_FAILED; - goto error_exit; - } - - if (t->op_mask & AES_TEST_OP_CIPHER) - buf_len += tdata->iv.len; - if (t->op_mask & AES_TEST_OP_AUTH) - buf_len += digest_len; - - buf_p = rte_pktmbuf_append(ibuf, buf_len); - if (!buf_p) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "No room to append mbuf"); - status = TEST_FAILED; - goto error_exit; - } - - if (t->op_mask & AES_TEST_OP_CIPHER) { - rte_memcpy(buf_p, tdata->iv.data, tdata->iv.len); - buf_p += tdata->iv.len; - } - - /* only encryption requires plaintext.data input, - * decryption/(digest gen)/(digest verify) use ciphertext.data - * to be computed */ - if (t->op_mask & AES_TEST_OP_ENCRYPT) { - rte_memcpy(buf_p, tdata->plaintext.data, - tdata->plaintext.len); - buf_p += tdata->plaintext.len; - } else { - rte_memcpy(buf_p, tdata->ciphertext.data, - tdata->ciphertext.len); - buf_p += tdata->ciphertext.len; - } - - if (t->op_mask & AES_TEST_OP_AUTH_VERIFY) - rte_memcpy(buf_p, tdata->digest.data, digest_len); - else - memset(buf_p, 0, digest_len); - - if (t->feature_mask & AES_TEST_FEATURE_OOP) { - obuf = rte_pktmbuf_alloc(mbuf_pool); - if (!obuf) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, - "Allocation of rte_mbuf failed"); - status = TEST_FAILED; - goto error_exit; - } - - buf_p = rte_pktmbuf_append(obuf, buf_len); - if (!buf_p) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, - "No room to append mbuf"); - status = TEST_FAILED; - goto error_exit; - } - memset(buf_p, 0, buf_len); - } - - /* Generate Crypto op data structure */ - op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_SYMMETRIC); - if (!op) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Failed to allocate symmetric crypto " - "operation struct"); - status = TEST_FAILED; - goto error_exit; - } - - sym_op = op->sym; - - sym_op->m_src = ibuf; - - if (t->feature_mask & AES_TEST_FEATURE_OOP) { - sym_op->m_dst = obuf; - iobuf = obuf; - } else { - sym_op->m_dst = NULL; - iobuf = ibuf; - } - - /* sessionless op requires allocate xform using - * rte_crypto_op_sym_xforms_alloc(), otherwise rte_zmalloc() - * is used */ - if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) { - uint32_t n_xforms = 0; - - if (t->op_mask & AES_TEST_OP_CIPHER) - n_xforms++; - if (t->op_mask & AES_TEST_OP_AUTH) - n_xforms++; - - if (rte_crypto_op_sym_xforms_alloc(op, n_xforms) - == NULL) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, "Failed to " - "allocate space for crypto transforms"); - status = TEST_FAILED; - goto error_exit; - } - } else { - cipher_xform = rte_zmalloc(NULL, - sizeof(struct rte_crypto_sym_xform), 0); - - auth_xform = rte_zmalloc(NULL, - sizeof(struct rte_crypto_sym_xform), 0); - - if (!cipher_xform || !auth_xform) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, "Failed to " - "allocate memory for crypto transforms"); - status = TEST_FAILED; - goto error_exit; - } - } - - /* preparing xform, for sessioned op, init_xform is initialized - * here and later as param in rte_cryptodev_sym_session_create() - * call */ - if (t->op_mask == AES_TEST_OP_ENC_AUTH_GEN) { - if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) { - cipher_xform = op->sym->xform; - auth_xform = cipher_xform->next; - auth_xform->next = NULL; - } else { - cipher_xform->next = auth_xform; - auth_xform->next = NULL; - init_xform = cipher_xform; - } - } else if (t->op_mask == AES_TEST_OP_AUTH_VERIFY_DEC) { - if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) { - auth_xform = op->sym->xform; - cipher_xform = auth_xform->next; - cipher_xform->next = NULL; - } else { - auth_xform->next = cipher_xform; - cipher_xform->next = NULL; - init_xform = auth_xform; - } - } else if ((t->op_mask == AES_TEST_OP_ENCRYPT) || - (t->op_mask == AES_TEST_OP_DECRYPT)) { - if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) - cipher_xform = op->sym->xform; - else - init_xform = cipher_xform; - cipher_xform->next = NULL; - } else if ((t->op_mask == AES_TEST_OP_AUTH_GEN) || - (t->op_mask == AES_TEST_OP_AUTH_VERIFY)) { - if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) - auth_xform = op->sym->xform; - else - init_xform = auth_xform; - auth_xform->next = NULL; - } else { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Unrecognized operation"); - status = TEST_FAILED; - goto error_exit; - } - - /*configure xforms & sym_op cipher and auth data*/ - if (t->op_mask & AES_TEST_OP_CIPHER) { - cipher_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; - cipher_xform->cipher.algo = tdata->crypto_algo; - if (t->op_mask & AES_TEST_OP_ENCRYPT) - cipher_xform->cipher.op = - RTE_CRYPTO_CIPHER_OP_ENCRYPT; - else - cipher_xform->cipher.op = - RTE_CRYPTO_CIPHER_OP_DECRYPT; - cipher_xform->cipher.key.data = cipher_key; - cipher_xform->cipher.key.length = tdata->cipher_key.len; - - sym_op->cipher.data.offset = tdata->iv.len; - sym_op->cipher.data.length = tdata->ciphertext.len; - sym_op->cipher.iv.data = rte_pktmbuf_mtod(sym_op->m_src, - uint8_t *); - sym_op->cipher.iv.length = tdata->iv.len; - sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys( - sym_op->m_src); - } - - if (t->op_mask & AES_TEST_OP_AUTH) { - uint32_t auth_data_offset = 0; - uint32_t digest_offset = tdata->ciphertext.len; - - if (t->op_mask & AES_TEST_OP_CIPHER) { - digest_offset += tdata->iv.len; - auth_data_offset += tdata->iv.len; - } - - auth_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; - auth_xform->auth.algo = tdata->auth_algo; - auth_xform->auth.key.length = tdata->auth_key.len; - auth_xform->auth.key.data = auth_key; - auth_xform->auth.digest_length = digest_len; - - if (t->op_mask & AES_TEST_OP_AUTH_GEN) { - auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; - sym_op->auth.digest.data = rte_pktmbuf_mtod_offset - (iobuf, uint8_t *, digest_offset); - sym_op->auth.digest.phys_addr = - rte_pktmbuf_mtophys_offset(iobuf, - digest_offset); - } else { - auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; - sym_op->auth.digest.data = rte_pktmbuf_mtod_offset - (sym_op->m_src, uint8_t *, digest_offset); - sym_op->auth.digest.phys_addr = - rte_pktmbuf_mtophys_offset(sym_op->m_src, - digest_offset); - } - - sym_op->auth.data.offset = auth_data_offset; - sym_op->auth.data.length = tdata->ciphertext.len; - sym_op->auth.digest.length = digest_len; - } - - /* create session for sessioned op */ - if (!(t->feature_mask & AES_TEST_FEATURE_SESSIONLESS)) { - sess = rte_cryptodev_sym_session_create(dev_id, - init_xform); - if (!sess) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, - "Session creation failed"); - status = TEST_FAILED; - goto error_exit; - } - - /* attach symmetric crypto session to crypto operations */ - rte_crypto_op_attach_sym_session(op, sess); - } - - /* Process crypto operation */ - if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Error sending packet for encryption"); - status = TEST_FAILED; - goto error_exit; - } - - op = NULL; - - while (rte_cryptodev_dequeue_burst(dev_id, 0, &op, 1) == 0) - rte_pause(); - - if (!op) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Failed to process sym crypto op"); - status = TEST_FAILED; - goto error_exit; - } - - TEST_HEXDUMP(stdout, "m_src:", - rte_pktmbuf_mtod(sym_op->m_src, uint8_t *), buf_len); - if (t->feature_mask & AES_TEST_FEATURE_OOP) - TEST_HEXDUMP(stdout, "m_dst:", - rte_pktmbuf_mtod(sym_op->m_dst, uint8_t *), - buf_len); - - /* Verify results */ - if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) { - if (t->op_mask & AES_TEST_OP_AUTH_VERIFY) - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: Digest verification failed " - "(0x%X)", __LINE__, op->status); - else - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: Digest verification failed " - "(0x%X)", __LINE__, op->status); - status = TEST_FAILED; - goto error_exit; - } - - if (t->op_mask & AES_TEST_OP_CIPHER) { - uint8_t *crypto_res; - const uint8_t *compare_ref; - uint32_t compare_len; - - crypto_res = rte_pktmbuf_mtod_offset(iobuf, uint8_t *, - tdata->iv.len); - - if (t->op_mask & AES_TEST_OP_ENCRYPT) { - compare_ref = tdata->ciphertext.data; - compare_len = tdata->ciphertext.len; - } else { - compare_ref = tdata->plaintext.data; - compare_len = tdata->plaintext.len; - } - - if (memcmp(crypto_res, compare_ref, compare_len)) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, - "Crypto data not as expected"); - status = TEST_FAILED; - goto error_exit; - } - } - - if (t->op_mask & AES_TEST_OP_AUTH_GEN) { - uint8_t *auth_res; - - if (t->op_mask & AES_TEST_OP_CIPHER) - auth_res = rte_pktmbuf_mtod_offset(iobuf, - uint8_t *, - tdata->iv.len + tdata->ciphertext.len); - else - auth_res = rte_pktmbuf_mtod_offset(iobuf, - uint8_t *, tdata->ciphertext.len); - - if (memcmp(auth_res, tdata->digest.data, digest_len)) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, "Generated " - "digest data not as expected"); - status = TEST_FAILED; - goto error_exit; - } - } - - snprintf(test_msg, AES_TEST_MSG_LEN, "PASS"); - -error_exit: - if (!(t->feature_mask & AES_TEST_FEATURE_SESSIONLESS)) { - if (sess) - rte_cryptodev_sym_session_free(dev_id, sess); - if (cipher_xform) - rte_free(cipher_xform); - if (auth_xform) - rte_free(auth_xform); - } - - if (op) - rte_crypto_op_free(op); - - if (obuf) - rte_pktmbuf_free(obuf); - - if (ibuf) - rte_pktmbuf_free(ibuf); - - return status; -} - -int -test_AES_all_tests(struct rte_mempool *mbuf_pool, - struct rte_mempool *op_mpool, - uint8_t dev_id, - enum rte_cryptodev_type cryptodev_type) -{ - int status, overall_status = TEST_SUCCESS; - uint32_t i, test_index = 0; - char test_msg[AES_TEST_MSG_LEN + 1]; - uint32_t n_test_cases = sizeof(aes_test_cases) / - sizeof(aes_test_cases[0]); - uint32_t target_pmd_mask = 0; - - switch (cryptodev_type) { - case RTE_CRYPTODEV_AESNI_MB_PMD: - target_pmd_mask = AES_TEST_TARGET_PMD_MB; - break; - case RTE_CRYPTODEV_QAT_SYM_PMD: - target_pmd_mask = AES_TEST_TARGET_PMD_QAT; - break; - default: - TEST_ASSERT(-1, "Unrecognized cryptodev type"); - break; - } - - for (i = 0; i < n_test_cases; i++) { - const struct aes_test_case *tc = &aes_test_cases[i]; - - if (!(tc->pmd_mask & target_pmd_mask)) - continue; - - status = test_AES_one_case(tc, mbuf_pool, op_mpool, - dev_id, cryptodev_type, test_msg); - - printf(" %u) TestCase %s %s\n", test_index ++, - tc->test_descr, test_msg); - - if (status != TEST_SUCCESS) { - if (overall_status == TEST_SUCCESS) - overall_status = status; - - if (tc->feature_mask & AES_TEST_FEATURE_STOPPER) - break; - } - } - - return overall_status; -} diff --git a/app/test/test_cryptodev_aes.h b/app/test/test_cryptodev_aes.h deleted file mode 100644 index ef518e0..0000000 --- a/app/test/test_cryptodev_aes.h +++ /dev/null @@ -1,1124 +0,0 @@ -/*- - * 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 TEST_CRYPTODEV_AES_H_ -#define TEST_CRYPTODEV_AES_H_ - -struct aes_test_data { - enum rte_crypto_cipher_algorithm crypto_algo; - - struct { - uint8_t data[64]; - unsigned len; - } cipher_key; - - struct { - uint8_t data[64] __rte_aligned(16); - unsigned len; - } iv; - - struct { - uint8_t data[2048]; - unsigned len; - } plaintext; - - struct { - uint8_t data[2048]; - unsigned len; - } ciphertext; - - enum rte_crypto_auth_algorithm auth_algo; - - struct { - uint8_t data[128]; - unsigned len; - } auth_key; - - struct { - uint8_t data[128]; - unsigned len; /* for qat */ - unsigned truncated_len; /* for mb */ - } digest; -}; - -int -test_AES_all_tests(struct rte_mempool *mbuf_pool, - struct rte_mempool *op_mpool, - uint8_t dev_id, - enum rte_cryptodev_type cryptodev_type); - -/* test vectors */ -/* AES128-CTR-SHA1 test vector */ -static const struct aes_test_data aes_test_data_1 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, - .cipher_key = { - .data = { - 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, - 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C - }, - .len = 16 - }, - .iv = { - .data = { - 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, - 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF - }, - .len = 16 - }, - .plaintext = { - .data = { - 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, - 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, - 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, - 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, - 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, - 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, - 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, - 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 - }, - .len = 64 - }, - .ciphertext = { - .data = { - 0x87, 0x4D, 0x61, 0x91, 0xB6, 0x20, 0xE3, 0x26, - 0x1B, 0xEF, 0x68, 0x64, 0x99, 0x0D, 0xB6, 0xCE, - 0x98, 0x06, 0xF6, 0x6B, 0x79, 0x70, 0xFD, 0xFF, - 0x86, 0x17, 0x18, 0x7B, 0xB9, 0xFF, 0xFD, 0xFF, - 0x5A, 0xE4, 0xDF, 0x3E, 0xDB, 0xD5, 0xD3, 0x5E, - 0x5B, 0x4F, 0x09, 0x02, 0x0D, 0xB0, 0x3E, 0xAB, - 0x1E, 0x03, 0x1D, 0xDA, 0x2F, 0xBE, 0x03, 0xD1, - 0x79, 0x21, 0x70, 0xA0, 0xF3, 0x00, 0x9C, 0xEE - }, - .len = 64 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, - .auth_key = { - .data = { - 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, - 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, - 0xDE, 0xF4, 0xDE, 0xAD - }, - .len = 20 - }, - .digest = { - .data = { - 0x9B, 0x6F, 0x0C, 0x43, 0xF5, 0xC1, 0x3E, 0xB0, - 0xB1, 0x70, 0xB8, 0x2B, 0x33, 0x09, 0xD2, 0xB2, - 0x56, 0x20, 0xFB, 0xFE - }, - .len = 20, - .truncated_len = 12 - } -}; - -/** AES-192-CTR XCBC test vector */ -static const struct aes_test_data aes_test_data_2 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, - .cipher_key = { - .data = { - 0xCB, 0xC5, 0xED, 0x5B, 0xE7, 0x7C, 0xBD, 0x8C, - 0x50, 0xD9, 0x30, 0xF2, 0xB5, 0x6A, 0x0E, 0x5F, - 0xAA, 0xAE, 0xAD, 0xA2, 0x1F, 0x49, 0x52, 0xD4 - }, - .len = 24 - }, - .iv = { - .data = { - 0x3F, 0x69, 0xA8, 0xCD, 0xE8, 0xF0, 0xEF, 0x40, - 0xB8, 0x7A, 0x4B, 0xED, 0x2B, 0xAF, 0xBF, 0x57 - }, - .len = 16 - }, - .plaintext = { - .data = { - 0x01, 0x0F, 0x10, 0x1F, 0x20, 0x1C, 0x0E, 0xB8, - 0xFB, 0x5C, 0xCD, 0xCC, 0x1F, 0xF9, 0xAF, 0x0B, - 0x95, 0x03, 0x74, 0x99, 0x49, 0xE7, 0x62, 0x55, - 0xDA, 0xEA, 0x13, 0x20, 0x1D, 0xC6, 0xCC, 0xCC, - 0xD1, 0x70, 0x75, 0x47, 0x02, 0x2F, 0xFB, 0x86, - 0xBB, 0x6B, 0x23, 0xD2, 0xC9, 0x74, 0xD7, 0x7B, - 0x08, 0x03, 0x3B, 0x79, 0x39, 0xBB, 0x91, 0x29, - 0xDA, 0x14, 0x39, 0x8D, 0xFF, 0x81, 0x50, 0x96, - }, - .len = 64 - }, - .ciphertext = { - .data = { - 0x4A, 0x6C, 0xC8, 0xCC, 0x96, 0x2A, 0x13, 0x84, - 0x1C, 0x36, 0x88, 0xE9, 0xE5, 0x94, 0x70, 0xB2, - 0x14, 0x5B, 0x13, 0x80, 0xEA, 0xD8, 0x8D, 0x37, - 0xFD, 0x70, 0xA8, 0x83, 0xE8, 0x2B, 0x88, 0x1E, - 0xBA, 0x94, 0x3F, 0xF6, 0xB3, 0x1F, 0xDE, 0x34, - 0xF3, 0x5B, 0x80, 0xE9, 0xAB, 0xF5, 0x1C, 0x29, - 0xB6, 0xD9, 0x76, 0x2B, 0x06, 0xC6, 0x74, 0xF1, - 0x59, 0x5E, 0x9E, 0xA5, 0x7B, 0x2D, 0xD7, 0xF0 - }, - .len = 64 - }, - .auth_algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC, - .auth_key = { - .data = { - 0x87, 0x61, 0x54, 0x53, 0xC4, 0x6D, 0xDD, 0x51, - 0xE1, 0x9F, 0x86, 0x64, 0x39, 0x0A, 0xE6, 0x59 - }, - .len = 16 - }, - .digest = { - .data = { - 0xCA, 0x33, 0xB3, 0x3B, 0x16, 0x94, 0xAA, 0x55, - 0x36, 0x6B, 0x45, 0x46 - }, - .len = 12, - .truncated_len = 12 - } -}; - -/** AES-256-CTR SHA1 test vector */ -static const struct aes_test_data aes_test_data_3 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, - .cipher_key = { - .data = { - 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, - 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, - 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, - 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 - }, - .len = 32 - }, - .iv = { - .data = { - 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, - 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF - }, - .len = 16 - }, - .plaintext = { - .data = { - 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, - 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, - 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, - 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, - 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, - 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, - 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, - 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 - }, - .len = 64 - }, - .ciphertext = { - .data = { - 0x60, 0x1E, 0xC3, 0x13, 0x77, 0x57, 0x89, 0xA5, - 0xB7, 0xA7, 0xF5, 0x04, 0xBB, 0xF3, 0xD2, 0x28, - 0xF4, 0x43, 0xE3, 0xCA, 0x4D, 0x62, 0xB5, 0x9A, - 0xCA, 0x84, 0xE9, 0x90, 0xCA, 0xCA, 0xF5, 0xC5, - 0x2B, 0x09, 0x30, 0xDA, 0xA2, 0x3D, 0xE9, 0x4C, - 0xE8, 0x70, 0x17, 0xBA, 0x2D, 0x84, 0x98, 0x8D, - 0xDF, 0xC9, 0xC5, 0x8D, 0xB6, 0x7A, 0xAD, 0xA6, - 0x13, 0xC2, 0xDD, 0x08, 0x45, 0x79, 0x41, 0xA6 - }, - .len = 64 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, - .auth_key = { - .data = { - 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, - 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, - 0xDE, 0xF4, 0xDE, 0xAD - }, - .len = 20 - }, - .digest = { - .data = { - 0x3B, 0x1A, 0x9D, 0x82, 0x35, 0xD5, 0xDD, 0x64, - 0xCC, 0x1B, 0xA9, 0xC0, 0xEB, 0xE9, 0x42, 0x16, - 0xE7, 0x87, 0xA3, 0xEF - }, - .len = 20, - .truncated_len = 12 - } -}; - -/** AES-128-CBC SHA1 test vector */ -static const struct aes_test_data aes_test_data_4 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, - .auth_key = { - .data = { - 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, - 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, - 0xDE, 0xF4, 0xDE, 0xAD - }, - .len = 20 - }, - .digest = { - .data = { - 0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60, - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0x18, 0x8C, 0x1D, 0x32 - }, - .len = 20, - .truncated_len = 12 - } -}; - -/** AES-128-CBC SHA256 test vector */ -static const struct aes_test_data aes_test_data_5 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC, - .auth_key = { - .data = { - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60 - }, - .len = 32 - }, - .digest = { - .data = { - 0xC8, 0x57, 0x57, 0x31, 0x03, 0xE0, 0x03, 0x55, - 0x07, 0xC8, 0x9E, 0x7F, 0x48, 0x9A, 0x61, 0x9A, - 0x68, 0xEE, 0x03, 0x0E, 0x71, 0x75, 0xC7, 0xF4, - 0x2E, 0x45, 0x26, 0x32, 0x7C, 0x12, 0x15, 0x15 - }, - .len = 32, - .truncated_len = 16 - } -}; - -/** AES-128-CBC SHA512 test vector */ -static const struct aes_test_data aes_test_data_6 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA512_HMAC, - .auth_key = { - .data = { - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, - 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, - 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, - 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, - 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, - 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 - }, - .len = 64 - }, - .digest = { - .data = { - 0x5D, 0x54, 0x66, 0xC1, 0x6E, 0xBC, 0x04, 0xB8, - 0x46, 0xB8, 0x08, 0x6E, 0xE0, 0xF0, 0x43, 0x48, - 0x37, 0x96, 0x9C, 0xC6, 0x9C, 0xC2, 0x1E, 0xE8, - 0xF2, 0x0C, 0x0B, 0xEF, 0x86, 0xA2, 0xE3, 0x70, - 0x95, 0xC8, 0xB3, 0x06, 0x47, 0xA9, 0x90, 0xE8, - 0xA0, 0xC6, 0x72, 0x69, 0x05, 0xC0, 0x0D, 0x0E, - 0x21, 0x96, 0x65, 0x93, 0x74, 0x43, 0x2A, 0x1D, - 0x2E, 0xBF, 0xC2, 0xC2, 0xEE, 0xCC, 0x2F, 0x0A - }, - .len = 64, - .truncated_len = 32 - } -}; - -/** AES-128-CBC XCBC test vector */ -static const struct aes_test_data aes_test_data_7 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC, - .auth_key = { - .data = { - 0x87, 0x61, 0x54, 0x53, 0xC4, 0x6D, 0xDD, 0x51, - 0xE1, 0x9F, 0x86, 0x64, 0x39, 0x0A, 0xE6, 0x59 - }, - .len = 16 - }, - .digest = { - .data = { - 0xE0, 0xAC, 0x9A, 0xC4, 0x22, 0x64, 0x35, 0x89, - 0x77, 0x1D, 0x8B, 0x75 - }, - .len = 12, - .truncated_len = 12 - } -}; - -/** AES-128-CBC SHA224 test vector */ -static const struct aes_test_data aes_test_data_8 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA224_HMAC, - .auth_key = { - .data = { - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, - 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, - 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, - 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, - 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, - 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 - }, - .len = 64 - }, - .digest = { - .data = { - 0xA3, 0xCA, 0xC7, 0x1D, 0xA8, 0x61, 0x30, 0x98, - 0x3B, 0x8F, 0x01, 0x19, 0xAE, 0x8D, 0xBD, 0x34, - 0x40, 0x63, 0xA8, 0x2F, 0xDF, 0x85, 0x2B, 0x7F, - 0x63, 0x7C, 0xDD, 0xB7 - }, - .len = 28, - .truncated_len = 14 - } -}; - -/** AES-128-CBC SHA384 test vector */ -static const struct aes_test_data aes_test_data_9 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA384_HMAC, - .auth_key = { - .data = { - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, - 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, - 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, - 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, - 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, - 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60, - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, - 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, - 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, - 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, - 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, - 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 - }, - .len = 128 - }, - .digest = { - .data = { - 0x23, 0x60, 0xC8, 0xB1, 0x2D, 0x6C, 0x1E, 0x72, - 0x25, 0xAB, 0xF9, 0xC3, 0x9A, 0xA9, 0x4F, 0x8C, - 0x56, 0x38, 0x65, 0x0E, 0x74, 0xD5, 0x45, 0x9D, - 0xA3, 0xFD, 0x7E, 0x6D, 0x9E, 0x74, 0x88, 0x9D, - 0xA7, 0x12, 0x9D, 0xD8, 0x81, 0x3C, 0x86, 0x2F, - 0x4D, 0xF9, 0x6F, 0x0A, 0xB0, 0xC9, 0xEB, 0x0B - }, - .len = 48, - .truncated_len = 24 - } -}; - -#endif /* TEST_CRYPTODEV_AES_H_ */ diff --git a/app/test/test_cryptodev_aes_test_vectors.h b/app/test/test_cryptodev_aes_test_vectors.h new file mode 100644 index 0000000..92c0cc2 --- /dev/null +++ b/app/test/test_cryptodev_aes_test_vectors.h @@ -0,0 +1,797 @@ +/* + * 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 TEST_CRYPTODEV_AES_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_AES_TEST_VECTORS_H_ + +/* test vectors */ +static const uint8_t plaintext_aes128ctr[] = { + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, + 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, + 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, + 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, + 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, + 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, + 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 +}; + +static const uint8_t ciphertext64_aes128ctr[] = { + 0x87, 0x4D, 0x61, 0x91, 0xB6, 0x20, 0xE3, 0x26, + 0x1B, 0xEF, 0x68, 0x64, 0x99, 0x0D, 0xB6, 0xCE, + 0x98, 0x06, 0xF6, 0x6B, 0x79, 0x70, 0xFD, 0xFF, + 0x86, 0x17, 0x18, 0x7B, 0xB9, 0xFF, 0xFD, 0xFF, + 0x5A, 0xE4, 0xDF, 0x3E, 0xDB, 0xD5, 0xD3, 0x5E, + 0x5B, 0x4F, 0x09, 0x02, 0x0D, 0xB0, 0x3E, 0xAB, + 0x1E, 0x03, 0x1D, 0xDA, 0x2F, 0xBE, 0x03, 0xD1, + 0x79, 0x21, 0x70, 0xA0, 0xF3, 0x00, 0x9C, 0xEE +}; + +static const uint8_t plaintext_aes192ctr[] = { + 0x01, 0x0F, 0x10, 0x1F, 0x20, 0x1C, 0x0E, 0xB8, + 0xFB, 0x5C, 0xCD, 0xCC, 0x1F, 0xF9, 0xAF, 0x0B, + 0x95, 0x03, 0x74, 0x99, 0x49, 0xE7, 0x62, 0x55, + 0xDA, 0xEA, 0x13, 0x20, 0x1D, 0xC6, 0xCC, 0xCC, + 0xD1, 0x70, 0x75, 0x47, 0x02, 0x2F, 0xFB, 0x86, + 0xBB, 0x6B, 0x23, 0xD2, 0xC9, 0x74, 0xD7, 0x7B, + 0x08, 0x03, 0x3B, 0x79, 0x39, 0xBB, 0x91, 0x29, + 0xDA, 0x14, 0x39, 0x8D, 0xFF, 0x81, 0x50, 0x96, +}; + +static const uint8_t ciphertext64_aes192ctr[] = { + 0x4A, 0x6C, 0xC8, 0xCC, 0x96, 0x2A, 0x13, 0x84, + 0x1C, 0x36, 0x88, 0xE9, 0xE5, 0x94, 0x70, 0xB2, + 0x14, 0x5B, 0x13, 0x80, 0xEA, 0xD8, 0x8D, 0x37, + 0xFD, 0x70, 0xA8, 0x83, 0xE8, 0x2B, 0x88, 0x1E, + 0xBA, 0x94, 0x3F, 0xF6, 0xB3, 0x1F, 0xDE, 0x34, + 0xF3, 0x5B, 0x80, 0xE9, 0xAB, 0xF5, 0x1C, 0x29, + 0xB6, 0xD9, 0x76, 0x2B, 0x06, 0xC6, 0x74, 0xF1, + 0x59, 0x5E, 0x9E, 0xA5, 0x7B, 0x2D, 0xD7, 0xF0 +}; + +static const uint8_t plaintext_aes256ctr[] = { + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, + 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, + 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, + 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, + 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, + 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, + 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 +}; + +static const uint8_t ciphertext64_aes256ctr[] = { + 0x60, 0x1E, 0xC3, 0x13, 0x77, 0x57, 0x89, 0xA5, + 0xB7, 0xA7, 0xF5, 0x04, 0xBB, 0xF3, 0xD2, 0x28, + 0xF4, 0x43, 0xE3, 0xCA, 0x4D, 0x62, 0xB5, 0x9A, + 0xCA, 0x84, 0xE9, 0x90, 0xCA, 0xCA, 0xF5, 0xC5, + 0x2B, 0x09, 0x30, 0xDA, 0xA2, 0x3D, 0xE9, 0x4C, + 0xE8, 0x70, 0x17, 0xBA, 0x2D, 0x84, 0x98, 0x8D, + 0xDF, 0xC9, 0xC5, 0x8D, 0xB6, 0x7A, 0xAD, 0xA6, + 0x13, 0xC2, 0xDD, 0x08, 0x45, 0x79, 0x41, 0xA6 +}; + +static const uint8_t plaintext_aes_common[] = { + "What a lousy earth! He wondered how many people " + "were destitute that same night even in his own " + "prosperous country, how many homes were " + "shanties, how many husbands were drunk and " + "wives socked, and how many children were " + "bullied, abused, or abandoned. How many " + "families hungered for food they could not " + "afford to buy? How many hearts were broken? How " + "many suicides would take place that same night, " + "how many people would go insane? How many " + "cockroaches and landlords would triumph? How " + "many winners were losers, successes failures, " + "and rich men poor men? How many wise guys were " + "stupid? How many happy endings were unhappy " + "endings? How many honest men were liars, brave " + "men cowards, loyal men traitors, how many " + "sainted men were corrupt, how many people in " + "positions of trust had sold their souls to " + "bodyguards, how many had never had souls? How " + "many straight-and-narrow paths were crooked " + "paths? How many best families were worst " + "families and how many good people were bad " + "people? When you added them all up and then " + "subtracted, you might be left with only the " + "children, and perhaps with Albert Einstein and " + "an old violinist or sculptor somewhere." +}; + +static const uint8_t ciphertext512_aes128cbc[] = { + 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, + 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, + 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, + 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, + 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, + 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, + 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, + 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, + 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, + 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, + 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, + 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, + 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, + 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, + 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, + 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, + 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, + 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, + 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, + 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, + 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, + 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, + 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, + 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, + 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, + 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, + 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, + 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, + 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, + 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, + 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, + 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, + 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, + 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, + 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, + 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, + 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, + 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, + 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, + 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, + 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, + 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, + 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, + 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, + 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, + 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, + 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, + 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, + 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, + 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, + 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, + 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, + 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, + 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, + 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, + 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, + 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, + 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, + 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, + 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, + 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, + 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C +}; + +/* AES128-CTR-SHA1 test vector */ +static const struct blockcipher_test_data aes_test_data_1 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key = { + .data = { + 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C + }, + .len = 16 + }, + .iv = { + .data = { + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes128ctr, + .len = 64 + }, + .ciphertext = { + .data = ciphertext64_aes128ctr, + .len = 64 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x9B, 0x6F, 0x0C, 0x43, 0xF5, 0xC1, 0x3E, 0xB0, + 0xB1, 0x70, 0xB8, 0x2B, 0x33, 0x09, 0xD2, 0xB2, + 0x56, 0x20, 0xFB, 0xFE + }, + .len = 20, + .truncated_len = 12 + } +}; + +/** AES-192-CTR XCBC test vector */ +static const struct blockcipher_test_data aes_test_data_2 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key = { + .data = { + 0xCB, 0xC5, 0xED, 0x5B, 0xE7, 0x7C, 0xBD, 0x8C, + 0x50, 0xD9, 0x30, 0xF2, 0xB5, 0x6A, 0x0E, 0x5F, + 0xAA, 0xAE, 0xAD, 0xA2, 0x1F, 0x49, 0x52, 0xD4 + }, + .len = 24 + }, + .iv = { + .data = { + 0x3F, 0x69, 0xA8, 0xCD, 0xE8, 0xF0, 0xEF, 0x40, + 0xB8, 0x7A, 0x4B, 0xED, 0x2B, 0xAF, 0xBF, 0x57 + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes192ctr, + .len = 64 + }, + .ciphertext = { + .data = ciphertext64_aes192ctr, + .len = 64 + }, + .auth_algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC, + .auth_key = { + .data = { + 0x87, 0x61, 0x54, 0x53, 0xC4, 0x6D, 0xDD, 0x51, + 0xE1, 0x9F, 0x86, 0x64, 0x39, 0x0A, 0xE6, 0x59 + }, + .len = 16 + }, + .digest = { + .data = { + 0xCA, 0x33, 0xB3, 0x3B, 0x16, 0x94, 0xAA, 0x55, + 0x36, 0x6B, 0x45, 0x46 + }, + .len = 12, + .truncated_len = 12 + } +}; + +/** AES-256-CTR SHA1 test vector */ +static const struct blockcipher_test_data aes_test_data_3 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key = { + .data = { + 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, + 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, + 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, + 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 + }, + .len = 32 + }, + .iv = { + .data = { + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes256ctr, + .len = 64 + }, + .ciphertext = { + .data = ciphertext64_aes256ctr, + .len = 64 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x3B, 0x1A, 0x9D, 0x82, 0x35, 0xD5, 0xDD, 0x64, + 0xCC, 0x1B, 0xA9, 0xC0, 0xEB, 0xE9, 0x42, 0x16, + 0xE7, 0x87, 0xA3, 0xEF + }, + .len = 20, + .truncated_len = 12 + } +}; + +/** AES-128-CBC SHA1 test vector */ +static const struct blockcipher_test_data aes_test_data_4 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60, + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0x18, 0x8C, 0x1D, 0x32 + }, + .len = 20, + .truncated_len = 12 + } +}; + +/** AES-128-CBC SHA256 test vector */ +static const struct blockcipher_test_data aes_test_data_5 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC, + .auth_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, + 0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60 + }, + .len = 32 + }, + .digest = { + .data = { + 0xC8, 0x57, 0x57, 0x31, 0x03, 0xE0, 0x03, 0x55, + 0x07, 0xC8, 0x9E, 0x7F, 0x48, 0x9A, 0x61, 0x9A, + 0x68, 0xEE, 0x03, 0x0E, 0x71, 0x75, 0xC7, 0xF4, + 0x2E, 0x45, 0x26, 0x32, 0x7C, 0x12, 0x15, 0x15 + }, + .len = 32, + .truncated_len = 16 + } +}; + +/** AES-128-CBC SHA512 test vector */ +static const struct blockcipher_test_data aes_test_data_6 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA512_HMAC, + .auth_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 + }, + .len = 64 + }, + .digest = { + .data = { + 0x5D, 0x54, 0x66, 0xC1, 0x6E, 0xBC, 0x04, 0xB8, + 0x46, 0xB8, 0x08, 0x6E, 0xE0, 0xF0, 0x43, 0x48, + 0x37, 0x96, 0x9C, 0xC6, 0x9C, 0xC2, 0x1E, 0xE8, + 0xF2, 0x0C, 0x0B, 0xEF, 0x86, 0xA2, 0xE3, 0x70, + 0x95, 0xC8, 0xB3, 0x06, 0x47, 0xA9, 0x90, 0xE8, + 0xA0, 0xC6, 0x72, 0x69, 0x05, 0xC0, 0x0D, 0x0E, + 0x21, 0x96, 0x65, 0x93, 0x74, 0x43, 0x2A, 0x1D, + 0x2E, 0xBF, 0xC2, 0xC2, 0xEE, 0xCC, 0x2F, 0x0A + }, + .len = 64, + .truncated_len = 32 + } +}; + +/** AES-128-CBC XCBC test vector */ +static const struct blockcipher_test_data aes_test_data_7 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC, + .auth_key = { + .data = { + 0x87, 0x61, 0x54, 0x53, 0xC4, 0x6D, 0xDD, 0x51, + 0xE1, 0x9F, 0x86, 0x64, 0x39, 0x0A, 0xE6, 0x59 + }, + .len = 16 + }, + .digest = { + .data = { + 0xE0, 0xAC, 0x9A, 0xC4, 0x22, 0x64, 0x35, 0x89, + 0x77, 0x1D, 0x8B, 0x75 + }, + .len = 12, + .truncated_len = 12 + } +}; + +/** AES-128-CBC SHA224 test vector */ +static const struct blockcipher_test_data aes_test_data_8 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA224_HMAC, + .auth_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 + }, + .len = 64 + }, + .digest = { + .data = { + 0xA3, 0xCA, 0xC7, 0x1D, 0xA8, 0x61, 0x30, 0x98, + 0x3B, 0x8F, 0x01, 0x19, 0xAE, 0x8D, 0xBD, 0x34, + 0x40, 0x63, 0xA8, 0x2F, 0xDF, 0x85, 0x2B, 0x7F, + 0x63, 0x7C, 0xDD, 0xB7 + }, + .len = 28, + .truncated_len = 14 + } +}; + +/** AES-128-CBC SHA384 test vector */ +static const struct blockcipher_test_data aes_test_data_9 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA384_HMAC, + .auth_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60, + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 + }, + .len = 128 + }, + .digest = { + .data = { + 0x23, 0x60, 0xC8, 0xB1, 0x2D, 0x6C, 0x1E, 0x72, + 0x25, 0xAB, 0xF9, 0xC3, 0x9A, 0xA9, 0x4F, 0x8C, + 0x56, 0x38, 0x65, 0x0E, 0x74, 0xD5, 0x45, 0x9D, + 0xA3, 0xFD, 0x7E, 0x6D, 0x9E, 0x74, 0x88, 0x9D, + 0xA7, 0x12, 0x9D, 0xD8, 0x81, 0x3C, 0x86, 0x2F, + 0x4D, 0xF9, 0x6F, 0x0A, 0xB0, 0xC9, 0xEB, 0x0B + }, + .len = 48, + .truncated_len = 24 + } +}; + +static const struct blockcipher_test_case aes_chain_test_cases[] = { + { + .test_descr = "AES-128-CTR HMAC-SHA1 Encryption Digest", + .test_data = &aes_test_data_1, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CTR HMAC-SHA1 Decryption Digest " + "Verify", + .test_data = &aes_test_data_1, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-192-CTR XCBC Encryption Digest", + .test_data = &aes_test_data_2, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-192-CTR XCBC Decryption Digest Verify", + .test_data = &aes_test_data_2, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-256-CTR HMAC-SHA1 Encryption Digest", + .test_data = &aes_test_data_3, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-256-CTR HMAC-SHA1 Decryption Digest " + "Verify", + .test_data = &aes_test_data_3, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " + "Verify", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA256 Encryption Digest", + .test_data = &aes_test_data_5, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA256 Decryption Digest " + "Verify", + .test_data = &aes_test_data_5, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest", + .test_data = &aes_test_data_6, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest " + "Sessionless", + .test_data = &aes_test_data_6, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB + }, + { + .test_descr = "AES-128-CBC HMAC-SHA512 Decryption Digest " + "Verify", + .test_data = &aes_test_data_6, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC XCBC Encryption Digest", + .test_data = &aes_test_data_7, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC XCBC Decryption Digest Verify", + .test_data = &aes_test_data_7, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest " + "OOP", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " + "Verify OOP", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA224 Encryption Digest", + .test_data = &aes_test_data_8, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA224 Decryption Digest " + "Verify", + .test_data = &aes_test_data_8, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA384 Encryption Digest", + .test_data = &aes_test_data_9, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA384 Decryption Digest " + "Verify", + .test_data = &aes_test_data_9, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, +}; + +#endif /* TEST_CRYPTODEV_AES_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_blockcipher.c b/app/test/test_cryptodev_blockcipher.c new file mode 100644 index 0000000..6661859 --- /dev/null +++ b/app/test/test_cryptodev_blockcipher.c @@ -0,0 +1,509 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2015-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_common.h> +#include <rte_hexdump.h> +#include <rte_mbuf.h> +#include <rte_malloc.h> +#include <rte_memcpy.h> + +#include <rte_crypto.h> +#include <rte_cryptodev.h> +#include <rte_cryptodev_pmd.h> + +#include "test.h" +#include "test_cryptodev_blockcipher.h" +#include "test_cryptodev_aes_test_vectors.h" + +static int +test_blockcipher_one_case(const struct blockcipher_test_case *t, + struct rte_mempool *mbuf_pool, + struct rte_mempool *op_mpool, + uint8_t dev_id, + enum rte_cryptodev_type cryptodev_type, + char *test_msg) +{ + struct rte_mbuf *ibuf = NULL; + struct rte_mbuf *obuf = NULL; + struct rte_mbuf *iobuf; + struct rte_crypto_sym_xform *cipher_xform = NULL; + struct rte_crypto_sym_xform *auth_xform = NULL; + struct rte_crypto_sym_xform *init_xform = NULL; + struct rte_crypto_sym_op *sym_op = NULL; + struct rte_crypto_op *op = NULL; + struct rte_cryptodev_sym_session *sess = NULL; + + int status = TEST_SUCCESS; + const struct blockcipher_test_data *tdata = t->test_data; + uint8_t cipher_key[tdata->cipher_key.len]; + uint8_t auth_key[tdata->auth_key.len]; + uint32_t buf_len = tdata->ciphertext.len; + uint32_t digest_len = 0; + char *buf_p = NULL; + + if (tdata->cipher_key.len) + memcpy(cipher_key, tdata->cipher_key.data, + tdata->cipher_key.len); + if (tdata->auth_key.len) + memcpy(auth_key, tdata->auth_key.data, + tdata->auth_key.len); + + switch (cryptodev_type) { + case RTE_CRYPTODEV_QAT_SYM_PMD: + digest_len = tdata->digest.len; + break; + case RTE_CRYPTODEV_AESNI_MB_PMD: + digest_len = tdata->digest.truncated_len; + break; + default: + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Unsupported PMD type"); + status = TEST_FAILED; + goto error_exit; + } + + /* preparing data */ + ibuf = rte_pktmbuf_alloc(mbuf_pool); + if (!ibuf) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Allocation of rte_mbuf failed"); + status = TEST_FAILED; + goto error_exit; + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) + buf_len += tdata->iv.len; + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) + buf_len += digest_len; + + buf_p = rte_pktmbuf_append(ibuf, buf_len); + if (!buf_p) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "No room to append mbuf"); + status = TEST_FAILED; + goto error_exit; + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { + rte_memcpy(buf_p, tdata->iv.data, tdata->iv.len); + buf_p += tdata->iv.len; + } + + /* only encryption requires plaintext.data input, + * decryption/(digest gen)/(digest verify) use ciphertext.data + * to be computed + */ + if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) { + rte_memcpy(buf_p, tdata->plaintext.data, + tdata->plaintext.len); + buf_p += tdata->plaintext.len; + } else { + rte_memcpy(buf_p, tdata->ciphertext.data, + tdata->ciphertext.len); + buf_p += tdata->ciphertext.len; + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) + rte_memcpy(buf_p, tdata->digest.data, digest_len); + else + memset(buf_p, 0, digest_len); + + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) { + obuf = rte_pktmbuf_alloc(mbuf_pool); + if (!obuf) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "Allocation of rte_mbuf failed"); + status = TEST_FAILED; + goto error_exit; + } + + buf_p = rte_pktmbuf_append(obuf, buf_len); + if (!buf_p) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "No room to append mbuf"); + status = TEST_FAILED; + goto error_exit; + } + memset(buf_p, 0, buf_len); + } + + /* Generate Crypto op data structure */ + op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_SYMMETRIC); + if (!op) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Failed to allocate symmetric crypto " + "operation struct"); + status = TEST_FAILED; + goto error_exit; + } + + sym_op = op->sym; + + sym_op->m_src = ibuf; + + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) { + sym_op->m_dst = obuf; + iobuf = obuf; + } else { + sym_op->m_dst = NULL; + iobuf = ibuf; + } + + /* sessionless op requires allocate xform using + * rte_crypto_op_sym_xforms_alloc(), otherwise rte_zmalloc() + * is used + */ + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) { + uint32_t n_xforms = 0; + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) + n_xforms++; + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) + n_xforms++; + + if (rte_crypto_op_sym_xforms_alloc(op, n_xforms) + == NULL) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, "Failed to " + "allocate space for crypto transforms"); + status = TEST_FAILED; + goto error_exit; + } + } else { + cipher_xform = rte_zmalloc(NULL, + sizeof(struct rte_crypto_sym_xform), 0); + + auth_xform = rte_zmalloc(NULL, + sizeof(struct rte_crypto_sym_xform), 0); + + if (!cipher_xform || !auth_xform) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, "Failed to " + "allocate memory for crypto transforms"); + status = TEST_FAILED; + goto error_exit; + } + } + + /* preparing xform, for sessioned op, init_xform is initialized + * here and later as param in rte_cryptodev_sym_session_create() call + */ + if (t->op_mask == BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN) { + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) { + cipher_xform = op->sym->xform; + auth_xform = cipher_xform->next; + auth_xform->next = NULL; + } else { + cipher_xform->next = auth_xform; + auth_xform->next = NULL; + init_xform = cipher_xform; + } + } else if (t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC) { + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) { + auth_xform = op->sym->xform; + cipher_xform = auth_xform->next; + cipher_xform->next = NULL; + } else { + auth_xform->next = cipher_xform; + cipher_xform->next = NULL; + init_xform = auth_xform; + } + } else if ((t->op_mask == BLOCKCIPHER_TEST_OP_ENCRYPT) || + (t->op_mask == BLOCKCIPHER_TEST_OP_DECRYPT)) { + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) + cipher_xform = op->sym->xform; + else + init_xform = cipher_xform; + cipher_xform->next = NULL; + } else if ((t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_GEN) || + (t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_VERIFY)) { + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) + auth_xform = op->sym->xform; + else + init_xform = auth_xform; + auth_xform->next = NULL; + } else { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Unrecognized operation"); + status = TEST_FAILED; + goto error_exit; + } + + /*configure xforms & sym_op cipher and auth data*/ + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { + cipher_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; + cipher_xform->cipher.algo = tdata->crypto_algo; + if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) + cipher_xform->cipher.op = + RTE_CRYPTO_CIPHER_OP_ENCRYPT; + else + cipher_xform->cipher.op = + RTE_CRYPTO_CIPHER_OP_DECRYPT; + cipher_xform->cipher.key.data = cipher_key; + cipher_xform->cipher.key.length = tdata->cipher_key.len; + + sym_op->cipher.data.offset = tdata->iv.len; + sym_op->cipher.data.length = tdata->ciphertext.len; + sym_op->cipher.iv.data = rte_pktmbuf_mtod(sym_op->m_src, + uint8_t *); + sym_op->cipher.iv.length = tdata->iv.len; + sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys( + sym_op->m_src); + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) { + uint32_t auth_data_offset = 0; + uint32_t digest_offset = tdata->ciphertext.len; + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { + digest_offset += tdata->iv.len; + auth_data_offset += tdata->iv.len; + } + + auth_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; + auth_xform->auth.algo = tdata->auth_algo; + auth_xform->auth.key.length = tdata->auth_key.len; + auth_xform->auth.key.data = auth_key; + auth_xform->auth.digest_length = digest_len; + + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) { + auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; + sym_op->auth.digest.data = rte_pktmbuf_mtod_offset + (iobuf, uint8_t *, digest_offset); + sym_op->auth.digest.phys_addr = + rte_pktmbuf_mtophys_offset(iobuf, + digest_offset); + } else { + auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; + sym_op->auth.digest.data = rte_pktmbuf_mtod_offset + (sym_op->m_src, uint8_t *, digest_offset); + sym_op->auth.digest.phys_addr = + rte_pktmbuf_mtophys_offset(sym_op->m_src, + digest_offset); + } + + sym_op->auth.data.offset = auth_data_offset; + sym_op->auth.data.length = tdata->ciphertext.len; + sym_op->auth.digest.length = digest_len; + } + + /* create session for sessioned op */ + if (!(t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)) { + sess = rte_cryptodev_sym_session_create(dev_id, + init_xform); + if (!sess) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "Session creation failed"); + status = TEST_FAILED; + goto error_exit; + } + + /* attach symmetric crypto session to crypto operations */ + rte_crypto_op_attach_sym_session(op, sess); + } + + /* Process crypto operation */ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Error sending packet for encryption"); + status = TEST_FAILED; + goto error_exit; + } + + op = NULL; + + while (rte_cryptodev_dequeue_burst(dev_id, 0, &op, 1) == 0) + rte_pause(); + + if (!op) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Failed to process sym crypto op"); + status = TEST_FAILED; + goto error_exit; + } + + TEST_HEXDUMP(stdout, "m_src:", + rte_pktmbuf_mtod(sym_op->m_src, uint8_t *), buf_len); + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) + TEST_HEXDUMP(stdout, "m_dst:", + rte_pktmbuf_mtod(sym_op->m_dst, uint8_t *), + buf_len); + + /* Verify results */ + if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) { + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: Digest verification failed " + "(0x%X)", __LINE__, op->status); + else + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: Digest verification failed " + "(0x%X)", __LINE__, op->status); + status = TEST_FAILED; + goto error_exit; + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { + uint8_t *crypto_res; + const uint8_t *compare_ref; + uint32_t compare_len; + + crypto_res = rte_pktmbuf_mtod_offset(iobuf, uint8_t *, + tdata->iv.len); + + if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) { + compare_ref = tdata->ciphertext.data; + compare_len = tdata->ciphertext.len; + } else { + compare_ref = tdata->plaintext.data; + compare_len = tdata->plaintext.len; + } + + if (memcmp(crypto_res, compare_ref, compare_len)) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "Crypto data not as expected"); + status = TEST_FAILED; + goto error_exit; + } + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) { + uint8_t *auth_res; + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) + auth_res = rte_pktmbuf_mtod_offset(iobuf, + uint8_t *, + tdata->iv.len + tdata->ciphertext.len); + else + auth_res = rte_pktmbuf_mtod_offset(iobuf, + uint8_t *, tdata->ciphertext.len); + + if (memcmp(auth_res, tdata->digest.data, digest_len)) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, "Generated " + "digest data not as expected"); + status = TEST_FAILED; + goto error_exit; + } + } + + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "PASS"); + +error_exit: + if (!(t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)) { + if (sess) + rte_cryptodev_sym_session_free(dev_id, sess); + if (cipher_xform) + rte_free(cipher_xform); + if (auth_xform) + rte_free(auth_xform); + } + + if (op) + rte_crypto_op_free(op); + + if (obuf) + rte_pktmbuf_free(obuf); + + if (ibuf) + rte_pktmbuf_free(ibuf); + + return status; +} + +int +test_blockcipher_all_tests(struct rte_mempool *mbuf_pool, + struct rte_mempool *op_mpool, + uint8_t dev_id, + enum rte_cryptodev_type cryptodev_type, + enum blockcipher_test_type test_type) +{ + int status, overall_status = TEST_SUCCESS; + uint32_t i, test_index = 0; + char test_msg[BLOCKCIPHER_TEST_MSG_LEN + 1]; + uint32_t n_test_cases = 0; + uint32_t target_pmd_mask = 0; + const struct blockcipher_test_case *tcs = NULL; + + switch (test_type) { + case BLKCIPHER_AES_CHAIN_TYPE: + n_test_cases = sizeof(aes_chain_test_cases) / + sizeof(aes_chain_test_cases[0]); + tcs = aes_chain_test_cases; + break; + case BLKCIPHER_AES_CIPHERONLY_TYPE: + case BLKCIPHER_3DES_CHAIN_TYPE: + case BLKCIPHER_3DES_CIPHERONLY_TYPE: + case BLKCIPHER_AUTHONLY_TYPE: + default: + break; + } + + switch (cryptodev_type) { + case RTE_CRYPTODEV_AESNI_MB_PMD: + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB; + break; + case RTE_CRYPTODEV_QAT_SYM_PMD: + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT; + break; + default: + TEST_ASSERT(0, "Unrecognized cryptodev type"); + break; + } + + for (i = 0; i < n_test_cases; i++) { + const struct blockcipher_test_case *tc = &tcs[i]; + + if (!(tc->pmd_mask & target_pmd_mask)) + continue; + + status = test_blockcipher_one_case(tc, mbuf_pool, op_mpool, + dev_id, cryptodev_type, test_msg); + + printf(" %u) TestCase %s %s\n", test_index ++, + tc->test_descr, test_msg); + + if (status != TEST_SUCCESS) { + if (overall_status == TEST_SUCCESS) + overall_status = status; + + if (tc->feature_mask & BLOCKCIPHER_TEST_FEATURE_STOPPER) + break; + } + } + + return overall_status; +} diff --git a/app/test/test_cryptodev_blockcipher.h b/app/test/test_cryptodev_blockcipher.h new file mode 100644 index 0000000..686e6fb --- /dev/null +++ b/app/test/test_cryptodev_blockcipher.h @@ -0,0 +1,124 @@ +/*- + * 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 TEST_CRYPTODEV_BLOCKCIPHER_H_ +#define TEST_CRYPTODEV_BLOCKCIPHER_H_ + +#ifndef BLOCKCIPHER_TEST_MSG_LEN +#define BLOCKCIPHER_TEST_MSG_LEN 256 +#endif + +#define BLOCKCIPHER_TEST_OP_ENCRYPT 0x01 +#define BLOCKCIPHER_TEST_OP_DECRYPT 0x02 +#define BLOCKCIPHER_TEST_OP_AUTH_GEN 0x04 +#define BLOCKCIPHER_TEST_OP_AUTH_VERIFY 0x08 + +#define BLOCKCIPHER_TEST_FEATURE_OOP 0x01 +#define BLOCKCIPHER_TEST_FEATURE_SESSIONLESS 0x02 +#define BLOCKCIPHER_TEST_FEATURE_STOPPER 0x04 /* stop upon failing */ + +#define BLOCKCIPHER_TEST_TARGET_PMD_MB 0x0001 /* Multi-buffer flag */ +#define BLOCKCIPHER_TEST_TARGET_PMD_QAT 0x0002 /* QAT flag */ + +#define BLOCKCIPHER_TEST_OP_CIPHER (BLOCKCIPHER_TEST_OP_ENCRYPT | \ + BLOCKCIPHER_TEST_OP_DECRYPT) + +#define BLOCKCIPHER_TEST_OP_AUTH (BLOCKCIPHER_TEST_OP_AUTH_GEN | \ + BLOCKCIPHER_TEST_OP_AUTH_VERIFY) + +#define BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN (BLOCKCIPHER_TEST_OP_ENCRYPT | \ + BLOCKCIPHER_TEST_OP_AUTH_GEN) + +#define BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC (BLOCKCIPHER_TEST_OP_DECRYPT | \ + BLOCKCIPHER_TEST_OP_AUTH_VERIFY) + +enum blockcipher_test_type { + BLKCIPHER_AES_CHAIN_TYPE, /* use aes_chain_test_cases[] */ + BLKCIPHER_AES_CIPHERONLY_TYPE, /* use aes_cipheronly_test_cases[] */ + BLKCIPHER_3DES_CHAIN_TYPE, /* use triple_des_chain_test_cases[] */ + BLKCIPHER_3DES_CIPHERONLY_TYPE, /* triple_des_cipheronly_test_cases[] */ + BLKCIPHER_AUTHONLY_TYPE /* use hash_test_cases[] */ +}; + +struct blockcipher_test_case { + const char *test_descr; /* test description */ + const struct blockcipher_test_data *test_data; + uint8_t op_mask; /* operation mask */ + uint8_t feature_mask; + uint32_t pmd_mask; +}; + +struct blockcipher_test_data { + enum rte_crypto_cipher_algorithm crypto_algo; + + struct { + uint8_t data[64]; + unsigned int len; + } cipher_key; + + struct { + uint8_t data[64] __rte_aligned(16); + unsigned int len; + } iv; + + struct { + const uint8_t *data; + unsigned int len; + } plaintext; + + struct { + const uint8_t *data; + unsigned int len; + } ciphertext; + + enum rte_crypto_auth_algorithm auth_algo; + + struct { + uint8_t data[128]; + unsigned int len; + } auth_key; + + struct { + uint8_t data[128]; + unsigned int len; /* for qat */ + unsigned int truncated_len; /* for mb */ + } digest; +}; + +int +test_blockcipher_all_tests(struct rte_mempool *mbuf_pool, + struct rte_mempool *op_mpool, + uint8_t dev_id, + enum rte_cryptodev_type cryptodev_type, + enum blockcipher_test_type test_type); + +#endif /* TEST_CRYPTODEV_BLOCKCIPHER_H_ */ -- 2.5.0 ^ permalink raw reply [flat|nested] 34+ messages in thread
* [dpdk-dev] [PATCH v4 3/5] app/test: added tests for libcrypto PMD 2016-09-30 16:32 ` [dpdk-dev] [PATCH v4 2/5] app/test: cryptodev AES tests rework Slawomir Mrozowicz @ 2016-09-30 16:32 ` Slawomir Mrozowicz 2016-09-30 16:32 ` [dpdk-dev] [PATCH v4 4/5] app/test: added big data GMAC test for libcrypto Slawomir Mrozowicz 2016-09-30 16:32 ` [dpdk-dev] [PATCH v4 5/5] examples/l2fwd-crypto: updated example for libcrypto PMD Slawomir Mrozowicz 2 siblings, 0 replies; 34+ messages in thread From: Slawomir Mrozowicz @ 2016-09-30 16:32 UTC (permalink / raw) To: dev; +Cc: Slawomir Mrozowicz, Piotr Azarewicz, Marcin Kerlin, Daniel Mrzyglod This patch containes unit tests for libcrypto PMD. User can use app/test application to check how to use this pmd and to verify crypto processing. Test name is cryptodev_libcrypto_autotest. For performance test cryptodev_libcrypto_perftest can be used. Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com> Signed-off-by: Marcin Kerlin <marcinx.kerlin@intel.com> Signed-off-by: Daniel Mrzyglod <danielx.t.mrzyglod@intel.com> --- v2: - rename AES-named functions to blockcipher - replace different test cases with blockcipher functions pattern - add 3DES tests into QuickAssist PMD testsuite v3: - add nagative verification tests - add big data test v4: - move aes test rework to another patch - move big data test to another patch - checking if libcrypto pmd is available --- app/test/test_cryptodev.c | 1493 +++++++++++++++++++++++++-- app/test/test_cryptodev.h | 1 + app/test/test_cryptodev_aes_test_vectors.h | 304 +++++- app/test/test_cryptodev_blockcipher.c | 22 + app/test/test_cryptodev_blockcipher.h | 1 + app/test/test_cryptodev_des_test_vectors.h | 952 +++++++++++++++++ app/test/test_cryptodev_hash_test_vectors.h | 491 +++++++++ app/test/test_cryptodev_perf.c | 689 +++++++++++- 8 files changed, 3861 insertions(+), 92 deletions(-) create mode 100644 app/test/test_cryptodev_des_test_vectors.h create mode 100644 app/test/test_cryptodev_hash_test_vectors.h diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c index c46db94..7679dc4 100644 --- a/app/test/test_cryptodev.c +++ b/app/test/test_cryptodev.c @@ -45,6 +45,8 @@ #include "test_cryptodev_blockcipher.h" #include "test_cryptodev_aes_test_vectors.h" +#include "test_cryptodev_des_test_vectors.h" +#include "test_cryptodev_hash_test_vectors.h" #include "test_cryptodev_kasumi_test_vectors.h" #include "test_cryptodev_kasumi_hash_test_vectors.h" #include "test_cryptodev_snow3g_test_vectors.h" @@ -308,6 +310,26 @@ testsuite_setup(void) } } + /* Create 2 LIBCRYPTO devices if required */ + if (gbl_cryptodev_type == RTE_CRYPTODEV_LIBCRYPTO_PMD) { +#ifndef RTE_LIBRTE_PMD_LIBCRYPTO + RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO must be" + " enabled in config file to run this testsuite.\n"); + return TEST_FAILED; +#endif + nb_devs = rte_cryptodev_count_devtype(RTE_CRYPTODEV_LIBCRYPTO_PMD); + if (nb_devs < 2) { + for (i = nb_devs; i < 2; i++) { + ret = rte_eal_vdev_init( + RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), NULL); + + TEST_ASSERT(ret == 0, + "Failed to create instance %u of pmd : %s", + i, RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD)); + } + } + } + #ifndef RTE_LIBRTE_PMD_QAT if (gbl_cryptodev_type == RTE_CRYPTODEV_QAT_SYM_PMD) { RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_QAT must be enabled " @@ -877,6 +899,315 @@ static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA1_digest[] = { 0x18, 0x8c, 0x1d, 0x32 }; + +/* Multisession Vector context Test */ +/*Begin Session 0 */ +static uint8_t ms_aes_cbc_key0[] = { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static uint8_t ms_aes_cbc_iv0[] = { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static const uint8_t ms_aes_cbc_cipher0[] = { + 0x3C, 0xE4, 0xEE, 0x42, 0xB6, 0x9B, 0xC3, 0x38, + 0x5F, 0xAD, 0x54, 0xDC, 0xA8, 0x32, 0x81, 0xDC, + 0x7A, 0x6F, 0x85, 0x58, 0x07, 0x35, 0xED, 0xEB, + 0xAD, 0x79, 0x79, 0x96, 0xD3, 0x0E, 0xA6, 0xD9, + 0xAA, 0x86, 0xA4, 0x8F, 0xB5, 0xD6, 0x6E, 0x6D, + 0x0C, 0x91, 0x2F, 0xC4, 0x67, 0x98, 0x0E, 0xC4, + 0x8D, 0x83, 0x68, 0x69, 0xC4, 0xD3, 0x94, 0x34, + 0xC4, 0x5D, 0x60, 0x55, 0x22, 0x87, 0x8F, 0x6F, + 0x17, 0x8E, 0x75, 0xE4, 0x02, 0xF5, 0x1B, 0x99, + 0xC8, 0x39, 0xA9, 0xAB, 0x23, 0x91, 0x12, 0xED, + 0x08, 0xE7, 0xD9, 0x25, 0x89, 0x24, 0x4F, 0x8D, + 0x68, 0xF3, 0x10, 0x39, 0x0A, 0xEE, 0x45, 0x24, + 0xDF, 0x7A, 0x9D, 0x00, 0x25, 0xE5, 0x35, 0x71, + 0x4E, 0x40, 0x59, 0x6F, 0x0A, 0x13, 0xB3, 0x72, + 0x1D, 0x98, 0x63, 0x94, 0x89, 0xA5, 0x39, 0x8E, + 0xD3, 0x9C, 0x8A, 0x7F, 0x71, 0x2F, 0xC7, 0xCD, + 0x81, 0x05, 0xDC, 0xC0, 0x8D, 0xCE, 0x6D, 0x18, + 0x30, 0xC4, 0x72, 0x51, 0xF0, 0x27, 0xC8, 0xF6, + 0x60, 0x5B, 0x7C, 0xB2, 0xE3, 0x49, 0x0C, 0x29, + 0xC6, 0x9F, 0x39, 0x57, 0x80, 0x55, 0x24, 0x2C, + 0x9B, 0x0F, 0x5A, 0xB3, 0x89, 0x55, 0x31, 0x96, + 0x0D, 0xCD, 0xF6, 0x51, 0x03, 0x2D, 0x89, 0x26, + 0x74, 0x44, 0xD6, 0xE8, 0xDC, 0xEA, 0x44, 0x55, + 0x64, 0x71, 0x9C, 0x9F, 0x5D, 0xBA, 0x39, 0x46, + 0xA8, 0x17, 0xA1, 0x9C, 0x52, 0x9D, 0xBC, 0x6B, + 0x4A, 0x98, 0xE6, 0xEA, 0x33, 0xEC, 0x58, 0xB4, + 0x43, 0xF0, 0x32, 0x45, 0xA4, 0xC1, 0x55, 0xB7, + 0x5D, 0xB5, 0x59, 0xB2, 0xE3, 0x96, 0xFF, 0xA5, + 0xAF, 0xE1, 0x86, 0x1B, 0x42, 0xE6, 0x3B, 0xA0, + 0x90, 0x4A, 0xE8, 0x8C, 0x21, 0x7F, 0x36, 0x1E, + 0x5B, 0x65, 0x25, 0xD1, 0xC1, 0x5A, 0xCA, 0x3D, + 0x10, 0xED, 0x2D, 0x79, 0xD0, 0x0F, 0x58, 0x44, + 0x69, 0x81, 0xF5, 0xD4, 0xC9, 0x0F, 0x90, 0x76, + 0x1F, 0x54, 0xD2, 0xD5, 0x97, 0xCE, 0x2C, 0xE3, + 0xEF, 0xF4, 0xB7, 0xC6, 0x3A, 0x87, 0x7F, 0x83, + 0x2A, 0xAF, 0xCD, 0x90, 0x12, 0xA7, 0x7D, 0x85, + 0x1D, 0x62, 0xD3, 0x85, 0x25, 0x05, 0xDB, 0x45, + 0x92, 0xA3, 0xF6, 0xA2, 0xA8, 0x41, 0xE4, 0x25, + 0x86, 0x87, 0x67, 0x24, 0xEC, 0x89, 0x23, 0x2A, + 0x9B, 0x20, 0x4D, 0x93, 0xEE, 0xE2, 0x2E, 0xC1, + 0x0B, 0x15, 0x33, 0xCF, 0x00, 0xD1, 0x1A, 0xDA, + 0x93, 0xFD, 0x28, 0x21, 0x5B, 0xCF, 0xD1, 0xF3, + 0x5A, 0x81, 0xBA, 0x82, 0x5E, 0x2F, 0x61, 0xB4, + 0x05, 0x71, 0xB5, 0xF4, 0x39, 0x3C, 0x1F, 0x60, + 0x00, 0x7A, 0xC4, 0xF8, 0x35, 0x20, 0x6C, 0x3A, + 0xCC, 0x03, 0x8F, 0x7B, 0xA2, 0xB6, 0x65, 0x8A, + 0xB6, 0x5F, 0xFD, 0x25, 0xD3, 0x5F, 0x92, 0xF9, + 0xAE, 0x17, 0x9B, 0x5E, 0x6E, 0x9A, 0xE4, 0x55, + 0x10, 0x25, 0x07, 0xA4, 0xAF, 0x21, 0x69, 0x13, + 0xD8, 0xFA, 0x31, 0xED, 0xF7, 0xA7, 0xA7, 0x3B, + 0xB8, 0x96, 0x8E, 0x10, 0x86, 0x74, 0xD8, 0xB1, + 0x34, 0x9E, 0x9B, 0x6A, 0x26, 0xA8, 0xD4, 0xD0, + 0xB5, 0xF6, 0xDE, 0xE7, 0xCA, 0x06, 0xDC, 0xA3, + 0x6F, 0xEE, 0x6B, 0x1E, 0xB5, 0x30, 0x99, 0x23, + 0xF9, 0x76, 0xF0, 0xA0, 0xCF, 0x3B, 0x94, 0x7B, + 0x19, 0x8D, 0xA5, 0x0C, 0x18, 0xA6, 0x1D, 0x07, + 0x89, 0xBE, 0x5B, 0x61, 0xE5, 0xF1, 0x42, 0xDB, + 0xD4, 0x2E, 0x02, 0x1F, 0xCE, 0xEF, 0x92, 0xB1, + 0x1B, 0x56, 0x50, 0xF2, 0x16, 0xE5, 0xE7, 0x4F, + 0xFD, 0xBB, 0x3E, 0xD2, 0xFC, 0x3C, 0xC6, 0x0F, + 0xF9, 0x12, 0x4E, 0xCB, 0x1E, 0x0C, 0x15, 0x84, + 0x2A, 0x14, 0x8A, 0x02, 0xE4, 0x7E, 0x95, 0x5B, + 0x86, 0xDB, 0x9B, 0x62, 0x5B, 0x19, 0xD2, 0x17, + 0xFA, 0x13, 0xBB, 0x6B, 0x3F, 0x45, 0x9F, 0xBF +}; + + +static uint8_t ms_hmac_key0[] = { + 0xFF, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 +}; + +static const uint8_t ms_hmac_digest0[] = { + 0x43, 0x52, 0xED, 0x34, 0xAB, 0x36, 0xB2, 0x51, + 0xFB, 0xA3, 0xA6, 0x7C, 0x38, 0xFC, 0x42, 0x8F, + 0x57, 0x64, 0xAB, 0x81, 0xA7, 0x89, 0xB7, 0x6C, + 0xA0, 0xDC, 0xB9, 0x4D, 0xC4, 0x30, 0xF9, 0xD4, + 0x10, 0x82, 0x55, 0xD0, 0xAB, 0x32, 0xFB, 0x56, + 0x0D, 0xE4, 0x68, 0x3D, 0x76, 0xD0, 0x7B, 0xE4, + 0xA6, 0x2C, 0x34, 0x9E, 0x8C, 0x41, 0xF8, 0x23, + 0x28, 0x1B, 0x3A, 0x90, 0x26, 0x34, 0x47, 0x90 + }; + +/* End Session 0 */ +/* Begin session 1 */ + +static uint8_t ms_aes_cbc_key1[] = { + 0xf1, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static uint8_t ms_aes_cbc_iv1[] = { + 0xf1, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static const uint8_t ms_aes_cbc_cipher1[] = { + 0x5A, 0x7A, 0x67, 0x5D, 0xB8, 0xE1, 0xDC, 0x71, + 0x39, 0xA8, 0x74, 0x93, 0x9C, 0x4C, 0xFE, 0x23, + 0x61, 0xCD, 0xA4, 0xB3, 0xD9, 0xCE, 0x99, 0x09, + 0x2A, 0x23, 0xF3, 0x29, 0xBF, 0x4C, 0xB4, 0x6A, + 0x1B, 0x6B, 0x73, 0x4D, 0x48, 0x0C, 0xCF, 0x6C, + 0x5E, 0x34, 0x9E, 0x7F, 0xBC, 0x8F, 0xCC, 0x8F, + 0x75, 0x1D, 0x3D, 0x77, 0x10, 0x76, 0xC8, 0xB9, + 0x99, 0x6F, 0xD6, 0x56, 0x75, 0xA9, 0xB2, 0x66, + 0xC2, 0x24, 0x2B, 0x9C, 0xFE, 0x40, 0x8E, 0x43, + 0x20, 0x97, 0x1B, 0xFA, 0xD0, 0xCF, 0x04, 0xAB, + 0xBB, 0xF6, 0x5D, 0xF5, 0xA0, 0x19, 0x7C, 0x23, + 0x5D, 0x80, 0x8C, 0x49, 0xF6, 0x76, 0x88, 0x29, + 0x27, 0x4C, 0x59, 0x2B, 0x43, 0xA6, 0xB2, 0x26, + 0x27, 0x78, 0xBE, 0x1B, 0xE1, 0x4F, 0x5A, 0x1F, + 0xFC, 0x68, 0x08, 0xE7, 0xC4, 0xD1, 0x34, 0x68, + 0xB7, 0x13, 0x14, 0x41, 0x62, 0x6B, 0x1F, 0x77, + 0x0C, 0x68, 0x1D, 0x0D, 0xED, 0x89, 0xAA, 0xD8, + 0x97, 0x02, 0xBA, 0x5E, 0xD4, 0x84, 0x25, 0x97, + 0x03, 0xA5, 0xA6, 0x13, 0x66, 0x02, 0xF4, 0xC3, + 0xF3, 0xD3, 0xCC, 0x95, 0xC3, 0x87, 0x46, 0x90, + 0x1F, 0x6E, 0x14, 0xA8, 0x00, 0xF2, 0x6F, 0xD5, + 0xA1, 0xAD, 0xD5, 0x40, 0xA2, 0x0F, 0x32, 0x7E, + 0x99, 0xA3, 0xF5, 0x53, 0xC3, 0x26, 0xA1, 0x45, + 0x01, 0x88, 0x57, 0x84, 0x3E, 0x7B, 0x4E, 0x0B, + 0x3C, 0xB5, 0x3E, 0x9E, 0xE9, 0x78, 0x77, 0xC5, + 0xC0, 0x89, 0xA8, 0xF8, 0xF1, 0xA5, 0x2D, 0x5D, + 0xF9, 0xC6, 0xFB, 0xCB, 0x05, 0x23, 0xBD, 0x6E, + 0x5E, 0x14, 0xC6, 0x57, 0x73, 0xCF, 0x98, 0xBD, + 0x10, 0x8B, 0x18, 0xA6, 0x01, 0x5B, 0x13, 0xAE, + 0x8E, 0xDE, 0x1F, 0xB5, 0xB7, 0x40, 0x6C, 0xC1, + 0x1E, 0xA1, 0x19, 0x20, 0x9E, 0x95, 0xE0, 0x2F, + 0x1C, 0xF5, 0xD9, 0xD0, 0x2B, 0x1E, 0x82, 0x25, + 0x62, 0xB4, 0xEB, 0xA1, 0x1F, 0xCE, 0x44, 0xA1, + 0xCB, 0x92, 0x01, 0x6B, 0xE4, 0x26, 0x23, 0xE3, + 0xC5, 0x67, 0x35, 0x55, 0xDA, 0xE5, 0x27, 0xEE, + 0x8D, 0x12, 0x84, 0xB7, 0xBA, 0xA7, 0x1C, 0xD6, + 0x32, 0x3F, 0x67, 0xED, 0xFB, 0x5B, 0x8B, 0x52, + 0x46, 0x8C, 0xF9, 0x69, 0xCD, 0xAE, 0x79, 0xAA, + 0x37, 0x78, 0x49, 0xEB, 0xC6, 0x8E, 0x76, 0x63, + 0x84, 0xFF, 0x9D, 0x22, 0x99, 0x51, 0xB7, 0x5E, + 0x83, 0x4C, 0x8B, 0xDF, 0x5A, 0x07, 0xCC, 0xBA, + 0x42, 0xA5, 0x98, 0xB6, 0x47, 0x0E, 0x66, 0xEB, + 0x23, 0x0E, 0xBA, 0x44, 0xA8, 0xAA, 0x20, 0x71, + 0x79, 0x9C, 0x77, 0x5F, 0xF5, 0xFE, 0xEC, 0xEF, + 0xC6, 0x64, 0x3D, 0x84, 0xD0, 0x2B, 0xA7, 0x0A, + 0xC3, 0x72, 0x5B, 0x9C, 0xFA, 0xA8, 0x87, 0x95, + 0x94, 0x11, 0x38, 0xA7, 0x1E, 0x58, 0xE3, 0x73, + 0xC6, 0xC9, 0xD1, 0x7B, 0x92, 0xDB, 0x0F, 0x49, + 0x74, 0xC2, 0xA2, 0x0E, 0x35, 0x57, 0xAC, 0xDB, + 0x9A, 0x1C, 0xCF, 0x5A, 0x32, 0x3E, 0x26, 0x9B, + 0xEC, 0xB3, 0xEF, 0x9C, 0xFE, 0xBE, 0x52, 0xAC, + 0xB1, 0x29, 0xDD, 0xFD, 0x07, 0xE2, 0xEE, 0xED, + 0xE4, 0x46, 0x37, 0xFE, 0xD1, 0xDC, 0xCD, 0x02, + 0xF9, 0x31, 0xB0, 0xFB, 0x36, 0xB7, 0x34, 0xA4, + 0x76, 0xE8, 0x57, 0xBF, 0x99, 0x92, 0xC7, 0xAF, + 0x98, 0x10, 0xE2, 0x70, 0xCA, 0xC9, 0x2B, 0x82, + 0x06, 0x96, 0x88, 0x0D, 0xB3, 0xAC, 0x9E, 0x6D, + 0x43, 0xBC, 0x5B, 0x31, 0xCF, 0x65, 0x8D, 0xA6, + 0xC7, 0xFE, 0x73, 0xE1, 0x54, 0xF7, 0x10, 0xF9, + 0x86, 0xF7, 0xDF, 0xA1, 0xA1, 0xD8, 0xAE, 0x35, + 0xB3, 0x90, 0xDC, 0x6F, 0x43, 0x7A, 0x8B, 0xE0, + 0xFE, 0x8F, 0x33, 0x4D, 0x29, 0x6C, 0x45, 0x53, + 0x73, 0xDD, 0x21, 0x0B, 0x85, 0x30, 0xB5, 0xA5, + 0xF3, 0x5D, 0xEC, 0x79, 0x61, 0x9D, 0x9E, 0xB3 + +}; + +static uint8_t ms_hmac_key1[] = { + 0xFE, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 +}; + +static const uint8_t ms_hmac_digest1[] = { + 0xCE, 0x6E, 0x5F, 0x77, 0x96, 0x9A, 0xB1, 0x69, + 0x2D, 0x5E, 0xF3, 0x2F, 0x32, 0x10, 0xCB, 0x50, + 0x0E, 0x09, 0x56, 0x25, 0x07, 0x34, 0xC9, 0x20, + 0xEC, 0x13, 0x43, 0x23, 0x5C, 0x08, 0x8B, 0xCD, + 0xDC, 0x86, 0x8C, 0xEE, 0x0A, 0x95, 0x2E, 0xB9, + 0x8C, 0x7B, 0x02, 0x7A, 0xD4, 0xE1, 0x49, 0xB4, + 0x45, 0xB5, 0x52, 0x37, 0xC6, 0xFF, 0xFE, 0xAA, + 0x0A, 0x87, 0xB8, 0x51, 0xF9, 0x2A, 0x01, 0x8F +}; +/* End Session 1 */ +/* Begin Session 2 */ +static uint8_t ms_aes_cbc_key2[] = { + 0xff, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static uint8_t ms_aes_cbc_iv2[] = { + 0xff, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static const uint8_t ms_aes_cbc_cipher2[] = { + 0xBB, 0x3C, 0x68, 0x25, 0xFD, 0xB6, 0xA2, 0x91, + 0x20, 0x56, 0xF6, 0x30, 0x35, 0xFC, 0x9E, 0x97, + 0xF2, 0x90, 0xFC, 0x7E, 0x3E, 0x0A, 0x75, 0xC8, + 0x4C, 0xF2, 0x2D, 0xAC, 0xD3, 0x93, 0xF0, 0xC5, + 0x14, 0x88, 0x8A, 0x23, 0xC2, 0x59, 0x9A, 0x98, + 0x4B, 0xD5, 0x2C, 0xDA, 0x43, 0xA9, 0x34, 0x69, + 0x7C, 0x6D, 0xDB, 0xDC, 0xCB, 0xC0, 0xA0, 0x09, + 0xA7, 0x86, 0x16, 0x4B, 0xBF, 0xA8, 0xB6, 0xCF, + 0x7F, 0x74, 0x1F, 0x22, 0xF0, 0xF6, 0xBB, 0x44, + 0x8B, 0x4C, 0x9E, 0x23, 0xF8, 0x9F, 0xFC, 0x5B, + 0x9E, 0x9C, 0x2A, 0x79, 0x30, 0x8F, 0xBF, 0xA9, + 0x68, 0xA1, 0x20, 0x71, 0x7C, 0x77, 0x22, 0x34, + 0x07, 0xCD, 0xC6, 0xF6, 0x50, 0x0A, 0x08, 0x99, + 0x17, 0x98, 0xE3, 0x93, 0x8A, 0xB0, 0xEE, 0xDF, + 0xC2, 0xBA, 0x3B, 0x44, 0x73, 0xDF, 0xDD, 0xDC, + 0x14, 0x4D, 0x3B, 0xBB, 0x5E, 0x58, 0xC1, 0x26, + 0xA7, 0xAE, 0x47, 0xF3, 0x24, 0x6D, 0x4F, 0xD3, + 0x6E, 0x3E, 0x33, 0xE6, 0x7F, 0xCA, 0x50, 0xAF, + 0x5D, 0x3D, 0xA0, 0xDD, 0xC9, 0xF3, 0x30, 0xD3, + 0x6E, 0x8B, 0x2E, 0x12, 0x24, 0x34, 0xF0, 0xD3, + 0xC7, 0x8D, 0x23, 0x29, 0xAA, 0x05, 0xE1, 0xFA, + 0x2E, 0xF6, 0x8D, 0x37, 0x86, 0xC0, 0x6D, 0x13, + 0x2D, 0x98, 0xF3, 0x52, 0x39, 0x22, 0xCE, 0x38, + 0xC2, 0x1A, 0x72, 0xED, 0xFB, 0xCC, 0xE4, 0x71, + 0x5A, 0x0C, 0x0D, 0x09, 0xF8, 0xE8, 0x1B, 0xBC, + 0x53, 0xC8, 0xD8, 0x8F, 0xE5, 0x98, 0x5A, 0xB1, + 0x06, 0xA6, 0x5B, 0xE6, 0xA2, 0x88, 0x21, 0x9E, + 0x36, 0xC0, 0x34, 0xF9, 0xFB, 0x3B, 0x0A, 0x22, + 0x00, 0x00, 0x39, 0x48, 0x8D, 0x23, 0x74, 0x62, + 0x72, 0x91, 0xE6, 0x36, 0xAA, 0x77, 0x9C, 0x72, + 0x9D, 0xA8, 0xC3, 0xA9, 0xD5, 0x44, 0x72, 0xA6, + 0xB9, 0x28, 0x8F, 0x64, 0x4C, 0x8A, 0x64, 0xE6, + 0x4E, 0xFA, 0xEF, 0x87, 0xDE, 0x7B, 0x22, 0x44, + 0xB0, 0xDF, 0x2E, 0x5F, 0x0B, 0xA5, 0xF2, 0x24, + 0x07, 0x5C, 0x2D, 0x39, 0xB7, 0x3D, 0x8A, 0xE5, + 0x0E, 0x9D, 0x4E, 0x50, 0xED, 0x03, 0x99, 0x8E, + 0xF0, 0x06, 0x55, 0x4E, 0xA2, 0x24, 0xE7, 0x17, + 0x46, 0xDF, 0x6C, 0xCD, 0xC6, 0x44, 0xE8, 0xF9, + 0xB9, 0x1B, 0x36, 0xF6, 0x7F, 0x10, 0xA4, 0x7D, + 0x90, 0xBD, 0xE4, 0xAA, 0xD6, 0x9E, 0x18, 0x9D, + 0x22, 0x35, 0xD6, 0x55, 0x54, 0xAA, 0xF7, 0x22, + 0xA3, 0x3E, 0xEF, 0xC8, 0xA2, 0x34, 0x8D, 0xA9, + 0x37, 0x63, 0xA6, 0xC3, 0x57, 0xCB, 0x0C, 0x49, + 0x7D, 0x02, 0xBE, 0xAA, 0x13, 0x75, 0xB7, 0x4E, + 0x52, 0x62, 0xA5, 0xC2, 0x33, 0xC7, 0x6C, 0x1B, + 0xF6, 0x34, 0xF6, 0x09, 0xA5, 0x0C, 0xC7, 0xA2, + 0x61, 0x48, 0x62, 0x7D, 0x17, 0x15, 0xE3, 0x95, + 0xC8, 0x63, 0xD2, 0xA4, 0x43, 0xA9, 0x49, 0x07, + 0xB2, 0x3B, 0x2B, 0x62, 0x7D, 0xCB, 0x51, 0xB3, + 0x25, 0x33, 0x47, 0x0E, 0x14, 0x67, 0xDC, 0x6A, + 0x9B, 0x51, 0xAC, 0x9D, 0x8F, 0xA2, 0x2B, 0x57, + 0x8C, 0x5C, 0x5F, 0x76, 0x23, 0x92, 0x0F, 0x84, + 0x46, 0x0E, 0x40, 0x85, 0x38, 0x60, 0xFA, 0x61, + 0x20, 0xC5, 0xE3, 0xF1, 0x70, 0xAC, 0x1B, 0xBF, + 0xC4, 0x2B, 0xC5, 0x67, 0xD1, 0x43, 0xC5, 0x17, + 0x74, 0x71, 0x69, 0x6F, 0x82, 0x89, 0x19, 0x8A, + 0x70, 0x43, 0x92, 0x01, 0xC4, 0x63, 0x7E, 0xB1, + 0x59, 0x4E, 0xCD, 0xEA, 0x93, 0xA4, 0x52, 0x53, + 0x9B, 0x61, 0x5B, 0xD2, 0x3E, 0x19, 0x39, 0xB7, + 0x32, 0xEA, 0x8E, 0xF8, 0x1D, 0x76, 0x5C, 0xB2, + 0x73, 0x2D, 0x91, 0xC0, 0x18, 0xED, 0x25, 0x2A, + 0x53, 0x64, 0xF0, 0x92, 0x31, 0x55, 0x21, 0xA8, + 0x24, 0xA9, 0xD1, 0x02, 0xF6, 0x6C, 0x2B, 0x70, + 0xA9, 0x59, 0xC1, 0xD6, 0xC3, 0x57, 0x5B, 0x92 +}; + +static uint8_t ms_hmac_key2[] = { + 0xFC, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 +}; + +static const uint8_t ms_hmac_digest2[] = { + 0xA5, 0x0F, 0x9C, 0xFB, 0x08, 0x62, 0x59, 0xFF, + 0x80, 0x2F, 0xEB, 0x4B, 0xE1, 0x46, 0x21, 0xD6, + 0x02, 0x98, 0xF2, 0x8E, 0xF4, 0xEC, 0xD4, 0x77, + 0x86, 0x4C, 0x31, 0x28, 0xC8, 0x25, 0x80, 0x27, + 0x3A, 0x72, 0x5D, 0x6A, 0x56, 0x8A, 0xD3, 0x82, + 0xB0, 0xEC, 0x31, 0x6D, 0x8B, 0x6B, 0xB4, 0x24, + 0xE7, 0x62, 0xC1, 0x52, 0xBC, 0x14, 0x1B, 0x8E, + 0xEC, 0x9A, 0xF1, 0x47, 0x80, 0xD2, 0xB0, 0x59 +}; + +/* End Session 2 */ + + static int test_AES_CBC_HMAC_SHA1_encrypt_digest(void) { @@ -1145,6 +1476,38 @@ test_AES_chain_mb_all(void) } static int +test_AES_chain_libcrypto_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_LIBCRYPTO_PMD, + BLKCIPHER_AES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_cipheronly_libcrypto_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_LIBCRYPTO_PMD, + BLKCIPHER_AES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int test_AES_chain_qat_all(void) { struct crypto_testsuite_params *ts_params = &testsuite_params; @@ -1160,6 +1523,22 @@ test_AES_chain_qat_all(void) return TEST_SUCCESS; } +static int +test_authonly_libcrypto_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_LIBCRYPTO_PMD, + BLKCIPHER_AUTHONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + /* ***** SNOW 3G Tests ***** */ static int create_wireless_algo_hash_session(uint8_t dev_id, @@ -3411,6 +3790,70 @@ test_zuc_hash_generate_test_case_5(void) return test_zuc_authentication(&zuc_hash_test_case_5); } +static int +test_3DES_chain_qat_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_QAT_SYM_PMD, + BLKCIPHER_3DES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_cipheronly_qat_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_QAT_SYM_PMD, + BLKCIPHER_3DES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_chain_libcrypto_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_LIBCRYPTO_PMD, + BLKCIPHER_3DES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_cipheronly_libcrypto_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_LIBCRYPTO_PMD, + BLKCIPHER_3DES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + /* ***** AES-GCM Tests ***** */ static int @@ -4103,6 +4546,112 @@ test_multi_session(void) return TEST_SUCCESS; } +struct multi_session_params { + struct crypto_unittest_params ut_params; + uint8_t *cipher_key; + uint8_t *hmac_key; + const uint8_t *cipher; + const uint8_t *digest; + uint8_t *iv; +}; + +#define MB_SESSION_NUMBER 3 + +static int +test_multi_session_random_usage(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_cryptodev_info dev_info; + struct rte_cryptodev_sym_session **sessions; + uint32_t i, j; + struct multi_session_params ut_paramz[] = { + + { + .cipher_key = ms_aes_cbc_key0, + .hmac_key = ms_hmac_key0, + .cipher = ms_aes_cbc_cipher0, + .digest = ms_hmac_digest0, + .iv = ms_aes_cbc_iv0 + }, + { + .cipher_key = ms_aes_cbc_key1, + .hmac_key = ms_hmac_key1, + .cipher = ms_aes_cbc_cipher1, + .digest = ms_hmac_digest1, + .iv = ms_aes_cbc_iv1 + }, + { + .cipher_key = ms_aes_cbc_key2, + .hmac_key = ms_hmac_key2, + .cipher = ms_aes_cbc_cipher2, + .digest = ms_hmac_digest2, + .iv = ms_aes_cbc_iv2 + }, + + }; + + rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info); + + sessions = rte_malloc(NULL, + (sizeof(struct rte_cryptodev_sym_session *) + * dev_info.sym.max_nb_sessions) + 1, 0); + + for (i = 0; i < MB_SESSION_NUMBER; i++) { + rte_memcpy(&ut_paramz[i].ut_params, &testsuite_params, + sizeof(struct crypto_unittest_params)); + + test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( + &ut_paramz[i].ut_params, ut_paramz[i].cipher_key, + ut_paramz[i].hmac_key); + + /* Create multiple crypto sessions*/ + sessions[i] = rte_cryptodev_sym_session_create(ts_params->valid_devs[0], + &ut_paramz[i].ut_params.auth_xform); + + TEST_ASSERT_NOT_NULL(sessions[i], + "Session creation failed at session number %u", i); + + } + + srand(time(NULL)); + for (i = 0; i < 40000; i++) { + + j = rand() % MB_SESSION_NUMBER; + + TEST_ASSERT_SUCCESS( + test_AES_CBC_HMAC_SHA512_decrypt_perform(sessions[j], + &ut_paramz[j].ut_params, ts_params, ut_paramz[j].cipher, + ut_paramz[j].digest, ut_paramz[j].iv), + "Failed to perform decrypt on request number %u.", i); + + if (ut_paramz[j].ut_params.op) + rte_crypto_op_free(ut_paramz[j].ut_params.op); + + /* + * free mbuf - both obuf and ibuf are usually the same, + * so check if they point at the same address is necessary, + * to avoid freeing the mbuf twice. + */ + if (ut_paramz[j].ut_params.obuf) { + rte_pktmbuf_free(ut_paramz[j].ut_params.obuf); + if (ut_paramz[j].ut_params.ibuf == ut_paramz[j].ut_params.obuf) + ut_paramz[j].ut_params.ibuf = 0; + ut_paramz[j].ut_params.obuf = 0; + } + if (ut_paramz[j].ut_params.ibuf) { + rte_pktmbuf_free(ut_paramz[j].ut_params.ibuf); + ut_paramz[j].ut_params.ibuf = 0; + } + } + + for (i = 0; i < MB_SESSION_NUMBER; i++) + rte_cryptodev_sym_session_free(ts_params->valid_devs[0], sessions[i]); + + rte_free(sessions); + + return TEST_SUCCESS; +} + static int test_null_cipher_only_operation(void) { @@ -4706,88 +5255,796 @@ test_AES_GMAC_authentication_verify_test_case_3(void) return test_AES_GMAC_authentication_verify(&gmac_test_case_3); } -static struct unit_test_suite cryptodev_qat_testsuite = { - .suite_name = "Crypto QAT Unit Test Suite", - .setup = testsuite_setup, - .teardown = testsuite_teardown, - .unit_test_cases = { - TEST_CASE_ST(ut_setup, ut_teardown, - test_device_configure_invalid_dev_id), - TEST_CASE_ST(ut_setup, ut_teardown, - test_device_configure_invalid_queue_pair_ids), - TEST_CASE_ST(ut_setup, ut_teardown, - test_queue_pair_descriptor_setup), - TEST_CASE_ST(ut_setup, ut_teardown, - test_multi_session), +struct test_crypto_vector { + enum rte_crypto_cipher_algorithm crypto_algo; - TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_qat_all), - TEST_CASE_ST(ut_setup, ut_teardown, test_stats), + struct { + uint8_t data[64]; + unsigned int len; + } cipher_key; - /** AES GCM Authenticated Encryption */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_7), + struct { + uint8_t data[64]; + unsigned int len; + } iv; - /** AES GCM Authenticated Decryption */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_7), + struct { + const uint8_t *data; + unsigned int len; + } plaintext; - /** AES GMAC Authentication */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_verify_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_verify_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_verify_test_case_3), + struct { + const uint8_t *data; + unsigned int len; + } ciphertext; - /** SNOW 3G encrypt only (UEA2) */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_encryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_encryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_encryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_encryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_encryption_test_case_5), + enum rte_crypto_auth_algorithm auth_algo; - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_encryption_test_case_1_oop), - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_decryption_test_case_1_oop), + struct { + uint8_t data[128]; + unsigned int len; + } auth_key; - /** SNOW 3G decrypt only (UEA2) */ - TEST_CASE_ST(ut_setup, ut_teardown, + struct { + const uint8_t *data; + unsigned int len; + } aad; + + struct { + uint8_t data[128]; + unsigned int len; + } digest; +}; + +static const struct test_crypto_vector +hmac_sha1_test_crypto_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .plaintext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0xC4, 0xB7, 0x0E, 0x6B, 0xDE, 0xD1, 0xE7, 0x77, + 0x7E, 0x2E, 0x8F, 0xFC, 0x48, 0x39, 0x46, 0x17, + 0x3F, 0x91, 0x64, 0x59 + }, + .len = 20 + } +}; + +static const struct test_crypto_vector +aes128_gmac_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_AES_GMAC, + .crypto_algo = RTE_CRYPTO_CIPHER_AES_GCM, + .aad = { + .data = plaintext_hash, + .len = 512 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B + }, + .len = 12 + }, + .cipher_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA + }, + .len = 16 + }, + .digest = { + .data = { + 0xCA, 0x00, 0x99, 0x8B, 0x30, 0x7E, 0x74, 0x56, + 0x32, 0xA7, 0x87, 0xB5, 0xE9, 0xB2, 0x34, 0x5A + }, + .len = 16 + } +}; + +static const struct test_crypto_vector +aes128cbc_hmac_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_hash, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60, + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0x18, 0x8C, 0x1D, 0x32 + }, + .len = 20 + } +}; + +static void +data_corruption(uint8_t *data) +{ + data[0] += 1; +} + +static void +tag_corruption(uint8_t *data, unsigned int tag_offset) +{ + data[tag_offset] += 1; +} + +static int +create_auth_session(struct crypto_unittest_params *ut_params, + uint8_t dev_id, + const struct test_crypto_vector *reference, + enum rte_crypto_auth_operation auth_op) +{ + uint8_t auth_key[reference->auth_key.len + 1]; + + memcpy(auth_key, reference->auth_key.data, reference->auth_key.len); + + /* Setup Authentication Parameters */ + ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; + ut_params->auth_xform.auth.op = auth_op; + ut_params->auth_xform.next = NULL; + ut_params->auth_xform.auth.algo = reference->auth_algo; + ut_params->auth_xform.auth.key.length = reference->auth_key.len; + ut_params->auth_xform.auth.key.data = auth_key; + ut_params->auth_xform.auth.digest_length = reference->digest.len; + ut_params->auth_xform.auth.add_auth_data_length = reference->aad.len; + + /* Create Crypto session*/ + ut_params->sess = rte_cryptodev_sym_session_create(dev_id, + &ut_params->auth_xform); + + TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); + + return 0; +} + +static int +create_auth_cipher_session(struct crypto_unittest_params *ut_params, + uint8_t dev_id, + const struct test_crypto_vector *reference, + enum rte_crypto_auth_operation auth_op, + enum rte_crypto_cipher_operation cipher_op) +{ + uint8_t cipher_key[reference->cipher_key.len + 1]; + uint8_t auth_key[reference->auth_key.len + 1]; + + memcpy(cipher_key, reference->cipher_key.data, reference->cipher_key.len); + memcpy(auth_key, reference->auth_key.data, reference->auth_key.len); + + /* Setup Authentication Parameters */ + ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; + ut_params->auth_xform.auth.op = auth_op; + ut_params->auth_xform.next = &ut_params->cipher_xform; + ut_params->auth_xform.auth.algo = reference->auth_algo; + ut_params->auth_xform.auth.key.length = reference->auth_key.len; + ut_params->auth_xform.auth.key.data = auth_key; + ut_params->auth_xform.auth.digest_length = reference->digest.len; + ut_params->auth_xform.auth.add_auth_data_length = reference->aad.len; + + /* Setup Cipher Parameters */ + ut_params->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; + ut_params->cipher_xform.next = NULL; + ut_params->cipher_xform.cipher.algo = reference->crypto_algo; + ut_params->cipher_xform.cipher.op = cipher_op; + ut_params->cipher_xform.cipher.key.data = cipher_key; + ut_params->cipher_xform.cipher.key.length = reference->cipher_key.len; + + /* Create Crypto session*/ + ut_params->sess = rte_cryptodev_sym_session_create(dev_id, + &ut_params->auth_xform); + + TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); + + return 0; +} + +static int +create_auth_operation(struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int auth_generate) +{ + /* Generate Crypto op data structure */ + ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC); + TEST_ASSERT_NOT_NULL(ut_params->op, + "Failed to allocate pktmbuf offload"); + + /* Set crypto operation data parameters */ + rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); + + struct rte_crypto_sym_op *sym_op = ut_params->op->sym; + + /* set crypto operation source mbuf */ + sym_op->m_src = ut_params->ibuf; + + /* digest */ + sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( + ut_params->ibuf, reference->digest.len); + + TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, + "no room to append auth tag"); + + sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( + ut_params->ibuf, reference->plaintext.len); + sym_op->auth.digest.length = reference->digest.len; + + if (auth_generate) + memset(sym_op->auth.digest.data, 0, reference->digest.len); + else + memcpy(sym_op->auth.digest.data, + reference->digest.data, + reference->digest.len); + + TEST_HEXDUMP(stdout, "digest:", + sym_op->auth.digest.data, + sym_op->auth.digest.length); + + sym_op->auth.data.length = reference->plaintext.len; + sym_op->auth.data.offset = 0; + + return 0; +} + +static int +create_auth_GMAC_operation(struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int auth_generate) +{ + /* Generate Crypto op data structure */ + ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC); + TEST_ASSERT_NOT_NULL(ut_params->op, + "Failed to allocate pktmbuf offload"); + + /* Set crypto operation data parameters */ + rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); + + struct rte_crypto_sym_op *sym_op = ut_params->op->sym; + + /* set crypto operation source mbuf */ + sym_op->m_src = ut_params->ibuf; + + /* aad */ + sym_op->auth.aad.data = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + reference->aad.len); + TEST_ASSERT_NOT_NULL(sym_op->auth.aad.data, "no room to append AAD"); + memcpy(sym_op->auth.aad.data, reference->aad.data, reference->aad.len); + + TEST_HEXDUMP(stdout, "AAD:", sym_op->auth.aad.data, reference->aad.len); + + sym_op->auth.aad.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); + sym_op->auth.aad.length = reference->aad.len; + + /* digest */ + sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( + ut_params->ibuf, reference->digest.len); + + TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, + "no room to append auth tag"); + + sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( + ut_params->ibuf, reference->ciphertext.len); + sym_op->auth.digest.length = reference->digest.len; + + if (auth_generate) + memset(sym_op->auth.digest.data, 0, reference->digest.len); + else + memcpy(sym_op->auth.digest.data, + reference->digest.data, + reference->digest.len); + + TEST_HEXDUMP(stdout, "digest:", + sym_op->auth.digest.data, + sym_op->auth.digest.length); + + sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend( + ut_params->ibuf, reference->iv.len); + TEST_ASSERT_NOT_NULL(sym_op->cipher.iv.data, "no room to prepend iv"); + + sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); + sym_op->cipher.iv.length = reference->iv.len; + + memcpy(sym_op->cipher.iv.data, reference->iv.data, reference->iv.len); + + sym_op->cipher.data.length = 0; + sym_op->cipher.data.offset = 0; + + sym_op->auth.data.length = 0; + sym_op->auth.data.offset = 0; + + return 0; +} + +static int +create_cipher_auth_operation(struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int auth_generate) +{ + /* Generate Crypto op data structure */ + ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC); + TEST_ASSERT_NOT_NULL(ut_params->op, + "Failed to allocate pktmbuf offload"); + + /* Set crypto operation data parameters */ + rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); + + struct rte_crypto_sym_op *sym_op = ut_params->op->sym; + + /* set crypto operation source mbuf */ + sym_op->m_src = ut_params->ibuf; + + /* digest */ + sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( + ut_params->ibuf, reference->digest.len); + + TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, + "no room to append auth tag"); + + sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( + ut_params->ibuf, reference->ciphertext.len); + sym_op->auth.digest.length = reference->digest.len; + + if (auth_generate) + memset(sym_op->auth.digest.data, 0, reference->digest.len); + else + memcpy(sym_op->auth.digest.data, + reference->digest.data, + reference->digest.len); + + TEST_HEXDUMP(stdout, "digest:", + sym_op->auth.digest.data, + sym_op->auth.digest.length); + + sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend( + ut_params->ibuf, reference->iv.len); + TEST_ASSERT_NOT_NULL(sym_op->cipher.iv.data, "no room to prepend iv"); + + sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); + sym_op->cipher.iv.length = reference->iv.len; + + memcpy(sym_op->cipher.iv.data, reference->iv.data, reference->iv.len); + + sym_op->cipher.data.length = reference->ciphertext.len; + sym_op->cipher.data.offset = reference->iv.len; + + sym_op->auth.data.length = reference->ciphertext.len; + sym_op->auth.data.offset = reference->iv.len; + + return 0; +} + +static int +create_auth_verify_operation(struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return create_auth_operation(ts_params, ut_params, reference, 0); +} + +static int +create_auth_verify_GMAC_operation( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return create_auth_GMAC_operation(ts_params, ut_params, reference, 0); +} + +static int +create_cipher_auth_verify_operation(struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return create_cipher_auth_operation(ts_params, ut_params, reference, 0); +} + +static int +test_authentication_verify_fail_when_data_corruption( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int data_corrupted) +{ + int retval; + + uint8_t *plaintext; + + /* Create session */ + retval = create_auth_session(ut_params, + ts_params->valid_devs[0], + reference, + RTE_CRYPTO_AUTH_OP_VERIFY); + if (retval < 0) + return retval; + + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + TEST_ASSERT_NOT_NULL(ut_params->ibuf, + "Failed to allocate input buffer in mempool"); + + /* clear mbuf payload */ + memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->ibuf)); + + plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + reference->plaintext.len); + TEST_ASSERT_NOT_NULL(plaintext, "no room to append plaintext"); + memcpy(plaintext, reference->plaintext.data, reference->plaintext.len); + + TEST_HEXDUMP(stdout, "plaintext:", plaintext, reference->plaintext.len); + + /* Create operation */ + retval = create_auth_verify_operation(ts_params, ut_params, reference); + + if (retval < 0) + return retval; + + if (data_corrupted) + data_corruption(plaintext); + else + tag_corruption(plaintext, reference->plaintext.len); + + ut_params->op = process_crypto_request(ts_params->valid_devs[0], + ut_params->op); + TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process"); + TEST_ASSERT_EQUAL(ut_params->op->status, + RTE_CRYPTO_OP_STATUS_AUTH_FAILED, + "authentication not failed"); + + ut_params->obuf = ut_params->op->sym->m_src; + TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf"); + + return 0; +} + +static int +test_authentication_verify_GMAC_fail_when_corruption( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int data_corrupted) +{ + int retval; + + /* Create session */ + retval = create_auth_cipher_session(ut_params, + ts_params->valid_devs[0], + reference, + RTE_CRYPTO_AUTH_OP_VERIFY, + RTE_CRYPTO_CIPHER_OP_DECRYPT); + if (retval < 0) + return retval; + + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + TEST_ASSERT_NOT_NULL(ut_params->ibuf, + "Failed to allocate input buffer in mempool"); + + /* clear mbuf payload */ + memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->ibuf)); + + /* Create operation */ + retval = create_auth_verify_GMAC_operation(ts_params, + ut_params, + reference); + + if (retval < 0) + return retval; + + if (data_corrupted) + data_corruption(ut_params->op->sym->auth.aad.data); + else + tag_corruption(ut_params->op->sym->auth.aad.data, reference->aad.len); + + ut_params->op = process_crypto_request(ts_params->valid_devs[0], + ut_params->op); + TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process"); + TEST_ASSERT_EQUAL(ut_params->op->status, + RTE_CRYPTO_OP_STATUS_AUTH_FAILED, + "authentication not failed"); + + ut_params->obuf = ut_params->op->sym->m_src; + TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf"); + + return 0; +} + +static int +test_authenticated_decryption_fail_when_corruption( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int data_corrupted) +{ + int retval; + + uint8_t *ciphertext; + + /* Create session */ + retval = create_auth_cipher_session(ut_params, + ts_params->valid_devs[0], + reference, + RTE_CRYPTO_AUTH_OP_VERIFY, + RTE_CRYPTO_CIPHER_OP_DECRYPT); + if (retval < 0) + return retval; + + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + TEST_ASSERT_NOT_NULL(ut_params->ibuf, + "Failed to allocate input buffer in mempool"); + + /* clear mbuf payload */ + memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->ibuf)); + + ciphertext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + reference->ciphertext.len); + TEST_ASSERT_NOT_NULL(ciphertext, "no room to append ciphertext"); + memcpy(ciphertext, reference->ciphertext.data, reference->ciphertext.len); + + /* Create operation */ + retval = create_cipher_auth_verify_operation(ts_params, + ut_params, + reference); + + if (retval < 0) + return retval; + + if (data_corrupted) + data_corruption(ciphertext); + else + tag_corruption(ciphertext, reference->ciphertext.len); + + ut_params->op = process_crypto_request(ts_params->valid_devs[0], + ut_params->op); + + TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process"); + TEST_ASSERT_EQUAL(ut_params->op->status, + RTE_CRYPTO_OP_STATUS_AUTH_FAILED, + "authentication not failed"); + + ut_params->obuf = ut_params->op->sym->m_src; + TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf"); + + return 0; +} + +static int +test_authentication_verify_fail_when_data_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authentication_verify_fail_when_data_corruption( + ts_params, ut_params, reference, 1); +} + +static int +test_authentication_verify_fail_when_tag_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authentication_verify_fail_when_data_corruption( + ts_params, ut_params, reference, 0); +} + +static int +test_authentication_verify_GMAC_fail_when_data_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authentication_verify_GMAC_fail_when_corruption( + ts_params, ut_params, reference, 1); +} + +static int +test_authentication_verify_GMAC_fail_when_tag_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authentication_verify_GMAC_fail_when_corruption( + ts_params, ut_params, reference, 0); +} + +static int +test_authenticated_decryption_fail_when_data_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authenticated_decryption_fail_when_corruption( + ts_params, ut_params, reference, 1); +} + +static int +test_authenticated_decryption_fail_when_tag_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authenticated_decryption_fail_when_corruption( + ts_params, ut_params, reference, 0); +} + +static int +authentication_verify_HMAC_SHA1_fail_when_data_corrupted(void) +{ + return test_authentication_verify_fail_when_data_corrupted( + &testsuite_params, &unittest_params, + &hmac_sha1_test_crypto_vector); +} + +static int +authentication_verify_HMAC_SHA1_fail_when_tag_corrupted(void) +{ + return test_authentication_verify_fail_when_tag_corrupted( + &testsuite_params, &unittest_params, + &hmac_sha1_test_crypto_vector); +} + +static int +authentication_verify_AES128_GMAC_fail_when_data_corrupted(void) +{ + return test_authentication_verify_GMAC_fail_when_data_corrupted( + &testsuite_params, &unittest_params, + &aes128_gmac_test_vector); +} + +static int +authentication_verify_AES128_GMAC_fail_when_tag_corrupted(void) +{ + return test_authentication_verify_GMAC_fail_when_tag_corrupted( + &testsuite_params, &unittest_params, + &aes128_gmac_test_vector); +} + +static int +auth_decryption_AES128CBC_HMAC_SHA1_fail_when_data_corrupted(void) +{ + return test_authenticated_decryption_fail_when_data_corrupted( + &testsuite_params, + &unittest_params, + &aes128cbc_hmac_sha1_test_vector); +} + +static int +auth_decryption_AES128CBC_HMAC_SHA1_fail_when_tag_corrupted(void) +{ + return test_authenticated_decryption_fail_when_tag_corrupted( + &testsuite_params, + &unittest_params, + &aes128cbc_hmac_sha1_test_vector); +} + +static struct unit_test_suite cryptodev_qat_testsuite = { + .suite_name = "Crypto QAT Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, + test_device_configure_invalid_dev_id), + TEST_CASE_ST(ut_setup, ut_teardown, + test_device_configure_invalid_queue_pair_ids), + TEST_CASE_ST(ut_setup, ut_teardown, + test_queue_pair_descriptor_setup), + TEST_CASE_ST(ut_setup, ut_teardown, + test_multi_session), + + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_qat_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_3DES_chain_qat_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_3DES_cipheronly_qat_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_stats), + + /** AES GCM Authenticated Encryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_7), + + /** AES GCM Authenticated Decryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_7), + + /** AES GMAC Authentication */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_3), + + /** SNOW 3G encrypt only (UEA2) */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_encryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_encryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_encryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_encryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_encryption_test_case_5), + + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_encryption_test_case_1_oop), + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_decryption_test_case_1_oop), + + /** SNOW 3G decrypt only (UEA2) */ + TEST_CASE_ST(ut_setup, ut_teardown, test_snow3g_decryption_test_case_1), TEST_CASE_ST(ut_setup, ut_teardown, test_snow3g_decryption_test_case_2), @@ -4862,6 +6119,83 @@ static struct unit_test_suite cryptodev_aesni_mb_testsuite = { } }; +static struct unit_test_suite cryptodev_libcrypto_testsuite = { + .suite_name = "Crypto Device LIBCRYPTO Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, test_multi_session), + TEST_CASE_ST(ut_setup, ut_teardown, test_multi_session_random_usage), + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_libcrypto_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_cipheronly_libcrypto_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_3DES_chain_libcrypto_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_3DES_cipheronly_libcrypto_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_authonly_libcrypto_all), + + /** AES GCM Authenticated Encryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_7), + + /** AES GCM Authenticated Decryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_7), + + /** AES GMAC Authentication */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_3), + + /** Negative tests */ + TEST_CASE_ST(ut_setup, ut_teardown, + authentication_verify_HMAC_SHA1_fail_when_data_corrupted), + TEST_CASE_ST(ut_setup, ut_teardown, + authentication_verify_HMAC_SHA1_fail_when_tag_corrupted), + TEST_CASE_ST(ut_setup, ut_teardown, + authentication_verify_AES128_GMAC_fail_when_data_corrupted), + TEST_CASE_ST(ut_setup, ut_teardown, + authentication_verify_AES128_GMAC_fail_when_tag_corrupted), + TEST_CASE_ST(ut_setup, ut_teardown, + auth_decryption_AES128CBC_HMAC_SHA1_fail_when_data_corrupted), + TEST_CASE_ST(ut_setup, ut_teardown, + auth_decryption_AES128CBC_HMAC_SHA1_fail_when_tag_corrupted), + + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + static struct unit_test_suite cryptodev_aesni_gcm_testsuite = { .suite_name = "Crypto Device AESNI GCM Unit Test Suite", .setup = testsuite_setup, @@ -5105,6 +6439,14 @@ test_cryptodev_aesni_mb(void /*argv __rte_unused, int argc __rte_unused*/) } static int +test_cryptodev_libcrypto(void) +{ + gbl_cryptodev_type = RTE_CRYPTODEV_LIBCRYPTO_PMD; + + return unit_test_suite_runner(&cryptodev_libcrypto_testsuite); +} + +static int test_cryptodev_aesni_gcm(void) { gbl_cryptodev_type = RTE_CRYPTODEV_AESNI_GCM_PMD; @@ -5146,6 +6488,7 @@ test_cryptodev_sw_zuc(void /*argv __rte_unused, int argc __rte_unused*/) REGISTER_TEST_COMMAND(cryptodev_qat_autotest, test_cryptodev_qat); REGISTER_TEST_COMMAND(cryptodev_aesni_mb_autotest, test_cryptodev_aesni_mb); +REGISTER_TEST_COMMAND(cryptodev_libcrypto_autotest, test_cryptodev_libcrypto); REGISTER_TEST_COMMAND(cryptodev_aesni_gcm_autotest, test_cryptodev_aesni_gcm); REGISTER_TEST_COMMAND(cryptodev_null_autotest, test_cryptodev_null); REGISTER_TEST_COMMAND(cryptodev_sw_snow3g_autotest, test_cryptodev_sw_snow3g); diff --git a/app/test/test_cryptodev.h b/app/test/test_cryptodev.h index 3c37c32..a9089aa 100644 --- a/app/test/test_cryptodev.h +++ b/app/test/test_cryptodev.h @@ -63,6 +63,7 @@ #define DIGEST_BYTE_LENGTH_SNOW3G_UIA2 (BYTE_LENGTH(32)) #define DIGEST_BYTE_LENGTH_KASUMI_F9 (BYTE_LENGTH(32)) #define AES_XCBC_MAC_KEY_SZ (16) +#define DIGEST_BYTE_LENGTH_AES_GCM (BYTE_LENGTH(128)) #define TRUNCATED_DIGEST_BYTE_LENGTH_SHA1 (12) #define TRUNCATED_DIGEST_BYTE_LENGTH_SHA224 (16) diff --git a/app/test/test_cryptodev_aes_test_vectors.h b/app/test/test_cryptodev_aes_test_vectors.h index 92c0cc2..ee46f9f 100644 --- a/app/test/test_cryptodev_aes_test_vectors.h +++ b/app/test/test_cryptodev_aes_test_vectors.h @@ -634,12 +634,204 @@ static const struct blockcipher_test_data aes_test_data_9 = { } }; +static const uint8_t ciphertext512_aes192cbc[] = { + 0x45, 0xEE, 0x9A, 0xEA, 0x3C, 0x03, 0xFC, 0x4C, + 0x84, 0x36, 0xB0, 0xDA, 0xB0, 0xDC, 0xF3, 0x5B, + 0x75, 0xA7, 0xBE, 0x0E, 0xC0, 0x8D, 0x6C, 0xF8, + 0xC1, 0x0F, 0xD0, 0x35, 0x1D, 0x82, 0xAE, 0x7C, + 0x57, 0xC5, 0x7A, 0x55, 0x87, 0x1B, 0xD4, 0x03, + 0x0A, 0x64, 0xC9, 0xE0, 0xF4, 0xC7, 0x6F, 0x57, + 0x52, 0xC6, 0x73, 0xBA, 0x84, 0x0B, 0x5B, 0x89, + 0x21, 0xD2, 0x9B, 0x88, 0x68, 0xF5, 0xA9, 0x7F, + 0x3F, 0x49, 0xEB, 0xF4, 0xD4, 0x52, 0xD2, 0x64, + 0x80, 0xB2, 0x53, 0xDA, 0x19, 0xF6, 0x10, 0x24, + 0x23, 0x26, 0x7A, 0x7C, 0x07, 0x57, 0x4B, 0x0E, + 0x58, 0x49, 0x61, 0xD1, 0xDC, 0x9A, 0x32, 0x6B, + 0x0F, 0x43, 0x9E, 0x4D, 0xB4, 0x07, 0x4E, 0xB3, + 0x51, 0x74, 0xDE, 0x29, 0xBC, 0x98, 0xF9, 0xDF, + 0x78, 0x9A, 0x18, 0x9C, 0xD6, 0x7A, 0x55, 0x7C, + 0xE6, 0x1D, 0x5C, 0x1A, 0x99, 0xD2, 0xC3, 0x7B, + 0x9F, 0x96, 0x74, 0x2D, 0xE0, 0xEF, 0xD1, 0xE3, + 0x08, 0x9F, 0xAF, 0xE6, 0xED, 0xCA, 0xE1, 0xEA, + 0x23, 0x6F, 0x7C, 0x81, 0xA8, 0xC0, 0x5B, 0x8B, + 0x53, 0x90, 0x51, 0x2D, 0x0F, 0xF6, 0x7D, 0xA7, + 0x1C, 0xBD, 0x83, 0x84, 0x54, 0xA4, 0x15, 0xFB, + 0x3E, 0x25, 0xA7, 0x3A, 0x0A, 0x73, 0xD9, 0x88, + 0x6F, 0x80, 0x78, 0x95, 0x7F, 0x60, 0xAA, 0x86, + 0x8A, 0xFC, 0xDF, 0xC1, 0xCB, 0xDE, 0xBB, 0x25, + 0x52, 0x20, 0xC6, 0x79, 0xD4, 0x0F, 0x25, 0xE7, + 0xDB, 0xB2, 0x17, 0xA4, 0x6F, 0x3C, 0x6F, 0x91, + 0xF6, 0x44, 0x1E, 0xB6, 0x85, 0xBC, 0x7A, 0x14, + 0x10, 0x72, 0xBD, 0x16, 0x63, 0x39, 0x9E, 0x7B, + 0x84, 0x5B, 0x17, 0x61, 0xB1, 0x5D, 0x82, 0x0B, + 0x6D, 0x37, 0xD7, 0x79, 0xB8, 0x24, 0x91, 0x30, + 0x82, 0x91, 0x02, 0xB1, 0x18, 0x4B, 0xE0, 0xF4, + 0x13, 0x1B, 0xB2, 0x4C, 0xDA, 0xB8, 0x99, 0x96, + 0x83, 0x2F, 0xBE, 0x53, 0x8D, 0xDE, 0xFA, 0xAD, + 0xF6, 0x5C, 0xDB, 0xE5, 0x66, 0x26, 0x8F, 0x13, + 0x2B, 0x76, 0x47, 0x73, 0xDE, 0x1A, 0x74, 0xA6, + 0x30, 0xAF, 0x42, 0xA0, 0xE5, 0xD2, 0x8F, 0xC2, + 0xED, 0x3E, 0x9E, 0x29, 0x54, 0x3C, 0xDE, 0x9F, + 0x5D, 0x30, 0x2B, 0x63, 0xFB, 0xE3, 0xB1, 0x07, + 0xEE, 0x74, 0x4A, 0xAF, 0xB1, 0x20, 0x8D, 0xEC, + 0xE6, 0x78, 0x16, 0x8D, 0xA4, 0x6E, 0x34, 0x7D, + 0x47, 0xFB, 0x0B, 0xC1, 0x32, 0xD7, 0x0D, 0x6C, + 0x6F, 0x93, 0x9C, 0x5E, 0xEF, 0x1F, 0x9C, 0x45, + 0x80, 0x6B, 0x74, 0xA6, 0x81, 0xF2, 0xF6, 0xFA, + 0xAA, 0x9D, 0x4F, 0xCA, 0xB5, 0x90, 0x59, 0xB0, + 0x3B, 0xF2, 0xF0, 0x75, 0xFD, 0x8A, 0xD8, 0x97, + 0x65, 0x88, 0x56, 0x4C, 0x44, 0xDF, 0x73, 0xF7, + 0x56, 0x9C, 0x48, 0x7E, 0xB0, 0x1F, 0x1D, 0x7D, + 0x6A, 0x11, 0xF5, 0xC2, 0xF4, 0x17, 0xEF, 0x58, + 0xD8, 0x2A, 0xAF, 0x56, 0x2F, 0xCF, 0xEC, 0xA4, + 0x58, 0x8B, 0x60, 0xCE, 0xD4, 0x0F, 0x9C, 0x21, + 0xEC, 0x3E, 0x74, 0x7B, 0x81, 0x3D, 0x69, 0xC6, + 0x5E, 0x12, 0x83, 0xE9, 0xEF, 0x81, 0x58, 0x36, + 0x6A, 0x60, 0x0F, 0x54, 0x28, 0x11, 0xF9, 0x64, + 0x36, 0xAD, 0x79, 0xF5, 0x1C, 0x74, 0xD0, 0xC3, + 0x7B, 0x61, 0xE1, 0x92, 0xB0, 0x13, 0x91, 0x87, + 0x32, 0x1F, 0xF2, 0x5A, 0xDA, 0x25, 0x69, 0xEB, + 0xD7, 0x32, 0x7F, 0xF5, 0x23, 0x21, 0x54, 0x47, + 0x7B, 0x1B, 0x33, 0xB0, 0x3D, 0xF6, 0xE2, 0x7E, + 0x3E, 0xA2, 0x9E, 0xCA, 0x48, 0x0B, 0x4A, 0x29, + 0x81, 0xD4, 0x4E, 0xD5, 0x69, 0xFB, 0xCD, 0x37, + 0x8A, 0xC1, 0x5B, 0x50, 0xFF, 0xB5, 0x7D, 0x43, + 0x0F, 0xAE, 0xA6, 0xC2, 0xE5, 0x8F, 0x45, 0xB2, + 0x85, 0x99, 0x02, 0xA2, 0x9B, 0xBE, 0x90, 0x43, + 0x4F, 0x2F, 0x50, 0xE2, 0x77, 0x62, 0xD9, 0xCC +}; + +/** AES-192-CBC test vector */ +static const struct blockcipher_test_data aes_test_data_10 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes192cbc, + .len = 512 + } +}; + +static const uint8_t ciphertext512_aes256cbc[] = { + 0xF3, 0xDD, 0xF0, 0x0B, 0xFF, 0xA2, 0x6A, 0x04, + 0xBE, 0xDA, 0x52, 0xA6, 0xFE, 0x6B, 0xA6, 0xA7, + 0x48, 0x1D, 0x7D, 0x98, 0x65, 0xDB, 0xEF, 0x06, + 0x26, 0xB5, 0x8E, 0xEB, 0x05, 0x0E, 0x77, 0x98, + 0x17, 0x8E, 0xD0, 0xD4, 0x7B, 0x92, 0x8F, 0x5C, + 0xD0, 0x74, 0x5C, 0xA8, 0x4B, 0x54, 0xB6, 0x2F, + 0x83, 0x72, 0x2C, 0xFF, 0x72, 0xE9, 0xE4, 0x15, + 0x4C, 0x32, 0xAF, 0xC8, 0xC9, 0x89, 0x3C, 0x6E, + 0x31, 0xD5, 0xC0, 0x16, 0xC0, 0x31, 0x7D, 0x11, + 0xAB, 0xCB, 0xDE, 0xD2, 0xD6, 0xAA, 0x76, 0x5E, + 0xBA, 0xF6, 0xE2, 0x92, 0xCB, 0x86, 0x07, 0xFA, + 0xD4, 0x9E, 0x83, 0xED, 0xFD, 0xB8, 0x70, 0x54, + 0x6B, 0xBE, 0xEC, 0x72, 0xDD, 0x28, 0x5E, 0x95, + 0x78, 0xA5, 0x28, 0x43, 0x3D, 0x6D, 0xB1, 0xD9, + 0x69, 0x1F, 0xC9, 0x66, 0x0E, 0x32, 0x44, 0x08, + 0xD2, 0xAE, 0x2C, 0x43, 0xF2, 0xD0, 0x7D, 0x26, + 0x70, 0xE5, 0xA1, 0xCA, 0x37, 0xE9, 0x7D, 0xC7, + 0xA3, 0xFA, 0x81, 0x91, 0x64, 0xAA, 0x64, 0x91, + 0x9A, 0x95, 0x2D, 0xC9, 0xF9, 0xCE, 0xFE, 0x9F, + 0xC4, 0xD8, 0x81, 0xBE, 0x57, 0x84, 0xC5, 0x02, + 0xDB, 0x30, 0xC1, 0xD9, 0x0E, 0xA0, 0xA6, 0x00, + 0xD6, 0xF3, 0x52, 0x7E, 0x0D, 0x23, 0x6B, 0x2B, + 0x34, 0x99, 0x1F, 0x70, 0x27, 0x6D, 0x58, 0x84, + 0x93, 0x77, 0xB8, 0x3E, 0xF1, 0x71, 0x58, 0x42, + 0x8B, 0x2B, 0xC8, 0x6D, 0x05, 0x84, 0xFF, 0x4E, + 0x85, 0xEF, 0x4A, 0x9D, 0x91, 0x6A, 0xD5, 0xE1, + 0xAF, 0x01, 0xEB, 0x83, 0x8F, 0x23, 0x7C, 0x7F, + 0x12, 0x91, 0x05, 0xF0, 0x4E, 0xD9, 0x17, 0x62, + 0x75, 0xBB, 0xAC, 0x97, 0xEE, 0x3B, 0x4E, 0xC7, + 0xE5, 0x92, 0xF8, 0x9D, 0x4C, 0xF9, 0xEE, 0x55, + 0x18, 0xBB, 0xCC, 0xB4, 0xF2, 0x59, 0xB9, 0xFC, + 0x7A, 0x0F, 0x98, 0xD4, 0x8B, 0xFE, 0xF7, 0x83, + 0x46, 0xE2, 0x83, 0x33, 0x3E, 0x95, 0x8D, 0x17, + 0x1E, 0x85, 0xF8, 0x8C, 0x51, 0xB0, 0x6C, 0xB5, + 0x5E, 0x95, 0xBA, 0x4B, 0x69, 0x1B, 0x48, 0x69, + 0x0B, 0x8F, 0xA5, 0x18, 0x13, 0xB9, 0x77, 0xD1, + 0x80, 0x32, 0x32, 0x6D, 0x53, 0xA1, 0x95, 0x40, + 0x96, 0x8A, 0xCC, 0xA3, 0x69, 0xF8, 0x9F, 0xB5, + 0x8E, 0xD2, 0x68, 0x07, 0x4F, 0xA7, 0xEC, 0xF8, + 0x20, 0x21, 0x58, 0xF8, 0xD8, 0x9E, 0x5F, 0x40, + 0xBA, 0xB9, 0x76, 0x57, 0x3B, 0x17, 0xAD, 0xEE, + 0xCB, 0xDF, 0x07, 0xC1, 0xDF, 0x66, 0xA8, 0x0D, + 0xC2, 0xCE, 0x8F, 0x79, 0xC3, 0x32, 0xE0, 0x8C, + 0xFE, 0x5A, 0xF3, 0x55, 0x27, 0x73, 0x6F, 0xA1, + 0x54, 0xC6, 0xFC, 0x28, 0x9D, 0xBE, 0x97, 0xB9, + 0x54, 0x97, 0x72, 0x3A, 0x61, 0xAF, 0x6F, 0xDE, + 0xF8, 0x0E, 0xBB, 0x6B, 0x96, 0x84, 0xDD, 0x9B, + 0x62, 0xBA, 0x47, 0xB5, 0xC9, 0x3B, 0x4E, 0x8C, + 0x78, 0x2A, 0xCC, 0x0A, 0x69, 0x54, 0x25, 0x5E, + 0x8B, 0xAC, 0x56, 0xD9, 0xFE, 0x48, 0xBA, 0xCE, + 0xA9, 0xCE, 0xA6, 0x1D, 0xBF, 0x3E, 0x3C, 0x66, + 0x40, 0x71, 0x79, 0xAD, 0x5B, 0x26, 0xAD, 0xBE, + 0x58, 0x13, 0x64, 0x60, 0x7C, 0x05, 0xFC, 0xE3, + 0x51, 0x7A, 0xF2, 0xCC, 0x54, 0x16, 0x2C, 0xA4, + 0xCE, 0x5F, 0x59, 0x12, 0x77, 0xEB, 0xD9, 0x23, + 0xE3, 0x86, 0xFB, 0xD7, 0x48, 0x76, 0x9D, 0xE3, + 0x89, 0x87, 0x39, 0xFA, 0x7B, 0x21, 0x0B, 0x76, + 0xB2, 0xED, 0x1C, 0x27, 0x4B, 0xD5, 0x27, 0x05, + 0x8C, 0x7D, 0x58, 0x6C, 0xCA, 0xA5, 0x54, 0x9A, + 0x0F, 0xCB, 0xE9, 0x88, 0x31, 0xAD, 0x49, 0xEE, + 0x38, 0xFB, 0xC9, 0xFB, 0xB4, 0x7A, 0x00, 0x58, + 0x20, 0x32, 0xD3, 0x53, 0x5A, 0xDD, 0x74, 0x95, + 0x60, 0x59, 0x09, 0xAE, 0x7E, 0xEC, 0x74, 0xA3, + 0xB7, 0x1C, 0x6D, 0xF2, 0xAE, 0x79, 0xA4, 0x7C +}; + +/** AES-256-CBC test vector */ +static const struct blockcipher_test_data aes_test_data_11 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0, + 0x37, 0x07, 0xB8, 0x23, 0xA2, 0xA3, 0xB5, 0x8D + }, + .len = 32 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes256cbc, + .len = 512 + } +}; + static const struct blockcipher_test_case aes_chain_test_cases[] = { { .test_descr = "AES-128-CTR HMAC-SHA1 Encryption Digest", .test_data = &aes_test_data_1, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -648,6 +840,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_1, .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -669,6 +862,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_3, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -677,6 +871,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_3, .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -684,6 +879,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_4, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -692,6 +888,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_4, .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -699,6 +896,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_5, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -707,6 +905,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_5, .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -714,6 +913,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_6, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -722,7 +922,8 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_6, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO }, { .test_descr = "AES-128-CBC HMAC-SHA512 Decryption Digest " @@ -730,6 +931,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_6, .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -752,7 +954,8 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_4, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO }, { .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " @@ -760,13 +963,15 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_4, .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO }, { .test_descr = "AES-128-CBC HMAC-SHA224 Encryption Digest", .test_data = &aes_test_data_8, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -775,6 +980,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_8, .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -782,6 +988,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_9, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -790,8 +997,99 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_9, .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest Sessionless", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = + "AES-128-CBC HMAC-SHA1 Decryption Digest Verify Sessionless", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, +}; + +static const struct blockcipher_test_case aes_cipheronly_test_cases[] = { + { + .test_descr = "AES-128-CBC Encryption", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-128-CBC Decryption", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-192-CBC Encryption", + .test_data = &aes_test_data_10, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-192-CBC Decryption", + .test_data = &aes_test_data_10, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-256-CBC Encryption", + .test_data = &aes_test_data_11, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-256-CBC Decryption", + .test_data = &aes_test_data_11, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-128-CTR Encryption", + .test_data = &aes_test_data_1, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-128-CTR Decryption", + .test_data = &aes_test_data_1, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-192-CTR Encryption", + .test_data = &aes_test_data_2, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-192-CTR Decryption", + .test_data = &aes_test_data_2, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-256-CTR Encryption", + .test_data = &aes_test_data_3, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-256-CTR Decryption", + .test_data = &aes_test_data_3, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, }; #endif /* TEST_CRYPTODEV_AES_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_blockcipher.c b/app/test/test_cryptodev_blockcipher.c index 6661859..6649080 100644 --- a/app/test/test_cryptodev_blockcipher.c +++ b/app/test/test_cryptodev_blockcipher.c @@ -43,6 +43,8 @@ #include "test.h" #include "test_cryptodev_blockcipher.h" #include "test_cryptodev_aes_test_vectors.h" +#include "test_cryptodev_des_test_vectors.h" +#include "test_cryptodev_hash_test_vectors.h" static int test_blockcipher_one_case(const struct blockcipher_test_case *t, @@ -79,6 +81,7 @@ test_blockcipher_one_case(const struct blockcipher_test_case *t, switch (cryptodev_type) { case RTE_CRYPTODEV_QAT_SYM_PMD: + case RTE_CRYPTODEV_LIBCRYPTO_PMD: digest_len = tdata->digest.len; break; case RTE_CRYPTODEV_AESNI_MB_PMD: @@ -465,9 +468,25 @@ test_blockcipher_all_tests(struct rte_mempool *mbuf_pool, tcs = aes_chain_test_cases; break; case BLKCIPHER_AES_CIPHERONLY_TYPE: + n_test_cases = sizeof(aes_cipheronly_test_cases) / + sizeof(aes_cipheronly_test_cases[0]); + tcs = aes_cipheronly_test_cases; + break; case BLKCIPHER_3DES_CHAIN_TYPE: + n_test_cases = sizeof(triple_des_chain_test_cases) / + sizeof(triple_des_chain_test_cases[0]); + tcs = triple_des_chain_test_cases; + break; case BLKCIPHER_3DES_CIPHERONLY_TYPE: + n_test_cases = sizeof(triple_des_cipheronly_test_cases) / + sizeof(triple_des_cipheronly_test_cases[0]); + tcs = triple_des_cipheronly_test_cases; + break; case BLKCIPHER_AUTHONLY_TYPE: + n_test_cases = sizeof(hash_test_cases) / + sizeof(hash_test_cases[0]); + tcs = hash_test_cases; + break; default: break; } @@ -479,6 +498,9 @@ test_blockcipher_all_tests(struct rte_mempool *mbuf_pool, case RTE_CRYPTODEV_QAT_SYM_PMD: target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT; break; + case RTE_CRYPTODEV_LIBCRYPTO_PMD: + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO; + break; default: TEST_ASSERT(0, "Unrecognized cryptodev type"); break; diff --git a/app/test/test_cryptodev_blockcipher.h b/app/test/test_cryptodev_blockcipher.h index 686e6fb..3232a86 100644 --- a/app/test/test_cryptodev_blockcipher.h +++ b/app/test/test_cryptodev_blockcipher.h @@ -48,6 +48,7 @@ #define BLOCKCIPHER_TEST_TARGET_PMD_MB 0x0001 /* Multi-buffer flag */ #define BLOCKCIPHER_TEST_TARGET_PMD_QAT 0x0002 /* QAT flag */ +#define BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO 0x0004 /* SW LIBCRYPTO flag */ #define BLOCKCIPHER_TEST_OP_CIPHER (BLOCKCIPHER_TEST_OP_ENCRYPT | \ BLOCKCIPHER_TEST_OP_DECRYPT) diff --git a/app/test/test_cryptodev_des_test_vectors.h b/app/test/test_cryptodev_des_test_vectors.h new file mode 100644 index 0000000..f3144fe --- /dev/null +++ b/app/test/test_cryptodev_des_test_vectors.h @@ -0,0 +1,952 @@ +/* + * 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 TEST_CRYPTODEV_DES_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_DES_TEST_VECTORS_H_ + +static const uint8_t plaintext_des[] = { + "What a lousy earth! He wondered how many people " + "were destitute that same night even in his own " + "prosperous country, how many homes were " + "shanties, how many husbands were drunk and " + "wives socked, and how many children were " + "bullied, abused, or abandoned. How many " + "families hungered for food they could not " + "afford to buy? How many hearts were broken? How " + "many suicides would take place that same night, " + "how many people would go insane? How many " + "cockroaches and landlords would triumph? How " + "many winners were losers, successes failures, " + "and rich men poor men? How many wise guys were " + "stupid? How many happy endings were unhappy " + "endings? How many honest men were liars, brave " + "men cowards, loyal men traitors, how many " + "sainted men were corrupt, how many people in " + "positions of trust had sold their souls to " + "bodyguards, how many had never had souls? How " + "many straight-and-narrow paths were crooked " + "paths? How many best families were worst " + "families and how many good people were bad " + "people? When you added them all up and then " + "subtracted, you might be left with only the " + "children, and perhaps with Albert Einstein and " + "an old violinist or sculptor somewhere." +}; + +static const uint8_t ciphertext512_des128ctr[] = { + 0x13, 0x39, 0x3B, 0xBC, 0x1D, 0xE3, 0x23, 0x09, + 0x9B, 0x08, 0xD1, 0x09, 0x52, 0x93, 0x78, 0x29, + 0x11, 0x21, 0xBA, 0x01, 0x15, 0xCD, 0xEC, 0xAA, + 0x79, 0x77, 0x58, 0xAE, 0xAE, 0xBC, 0x97, 0x33, + 0x94, 0xA9, 0x2D, 0xC0, 0x0A, 0xA9, 0xA4, 0x4B, + 0x19, 0x07, 0x88, 0x06, 0x7E, 0x81, 0x0F, 0xB5, + 0x60, 0xCF, 0xA7, 0xC3, 0x2A, 0x43, 0xFF, 0x16, + 0x3A, 0x5F, 0x11, 0x2D, 0x11, 0x38, 0x37, 0x94, + 0x2A, 0xC8, 0x3D, 0x20, 0xBB, 0x93, 0x95, 0x54, + 0x12, 0xFF, 0x0C, 0x47, 0x89, 0x7D, 0x73, 0xD1, + 0x2E, 0x3A, 0x80, 0x52, 0xA8, 0x92, 0x93, 0x99, + 0x16, 0xB8, 0x12, 0x1B, 0x8B, 0xA8, 0xC1, 0x81, + 0x95, 0x18, 0x82, 0xD6, 0x5A, 0xA7, 0xFE, 0xCF, + 0xC4, 0xAC, 0x85, 0x91, 0x0C, 0x2F, 0x1D, 0x10, + 0x9A, 0x65, 0x07, 0xB0, 0x2E, 0x5A, 0x2D, 0x48, + 0x26, 0xF8, 0x17, 0x7A, 0x53, 0xD6, 0xB8, 0xDF, + 0xB1, 0x10, 0x48, 0x7E, 0x8F, 0xBE, 0x2E, 0xA1, + 0x0D, 0x9E, 0xA9, 0xF1, 0x3B, 0x3B, 0x33, 0xCD, + 0xDC, 0x52, 0x7E, 0xC0, 0x0E, 0xA0, 0xD8, 0xA7, + 0xC6, 0x34, 0x5A, 0xAA, 0x29, 0x8B, 0xA9, 0xAC, + 0x1F, 0x78, 0xAD, 0xEE, 0x34, 0x59, 0x30, 0xFB, + 0x2A, 0x20, 0x3D, 0x4D, 0x30, 0xA7, 0x7D, 0xD8, + 0xA0, 0xC6, 0xA2, 0xD3, 0x9A, 0xFB, 0x50, 0x97, + 0x4D, 0x25, 0xA2, 0x37, 0x51, 0x54, 0xB7, 0xEB, + 0xED, 0x77, 0xDB, 0x94, 0x35, 0x8B, 0x70, 0x95, + 0x4A, 0x00, 0xA7, 0xF1, 0x8A, 0x66, 0x0E, 0xC6, + 0x05, 0x7B, 0x69, 0x05, 0x42, 0x03, 0x96, 0x2C, + 0x55, 0x00, 0x1B, 0xC0, 0x19, 0x4D, 0x0D, 0x2E, + 0xF5, 0x81, 0x11, 0x64, 0xCA, 0xBB, 0xF2, 0x0F, + 0x9C, 0x60, 0xE2, 0xCC, 0x02, 0x6E, 0x83, 0xD5, + 0x24, 0xF4, 0x12, 0x0E, 0x6A, 0xEA, 0x4F, 0x6C, + 0x79, 0x69, 0x65, 0x67, 0xDB, 0xF7, 0xEA, 0x98, + 0x5D, 0x56, 0x98, 0xB7, 0x88, 0xE7, 0x23, 0xC9, + 0x17, 0x32, 0x92, 0x33, 0x5A, 0x0C, 0x15, 0x20, + 0x3B, 0x1C, 0xF9, 0x0F, 0x4D, 0xD1, 0xE8, 0xE6, + 0x9E, 0x5E, 0x24, 0x1B, 0xA4, 0xB8, 0xB9, 0xE9, + 0x2F, 0xFC, 0x89, 0xB4, 0xB9, 0xF4, 0xA6, 0xAD, + 0x55, 0xF4, 0xDF, 0x58, 0x63, 0x25, 0xE3, 0x41, + 0x70, 0xDF, 0x10, 0xE7, 0x13, 0x87, 0x8D, 0xB3, + 0x62, 0x4F, 0xF5, 0x86, 0x85, 0x8F, 0x59, 0xF0, + 0x21, 0x0E, 0x8F, 0x11, 0xAD, 0xBF, 0xDD, 0x61, + 0x68, 0x3F, 0x54, 0x57, 0x49, 0x38, 0xC8, 0x24, + 0x8E, 0x0A, 0xAC, 0xCA, 0x2C, 0x36, 0x3E, 0x5F, + 0x0A, 0xCE, 0xFD, 0x1A, 0x60, 0x63, 0x5A, 0xE6, + 0x06, 0x64, 0xB5, 0x94, 0x3C, 0xC9, 0xAF, 0x7C, + 0xCD, 0x49, 0x10, 0xCF, 0xAF, 0x0E, 0x2E, 0x79, + 0x27, 0xB2, 0x67, 0x02, 0xED, 0xEE, 0x80, 0x77, + 0x7C, 0x6D, 0x4B, 0xDB, 0xCF, 0x8D, 0x68, 0x00, + 0x2E, 0xD9, 0xF0, 0x8E, 0x08, 0xBF, 0xA6, 0x9B, + 0xFE, 0xA4, 0xFB, 0x19, 0x46, 0xAF, 0x1B, 0xA9, + 0xF8, 0x22, 0x81, 0x21, 0x97, 0xFC, 0xC0, 0x8A, + 0x26, 0x58, 0x13, 0x29, 0xB6, 0x69, 0x94, 0x4B, + 0xAB, 0xB3, 0x88, 0x0D, 0xA9, 0x48, 0x0E, 0xE8, + 0x70, 0xFC, 0xA1, 0x21, 0xC4, 0x2C, 0xE5, 0x99, + 0xB4, 0xF1, 0x6F, 0xB2, 0x4B, 0x4B, 0xCD, 0x48, + 0x15, 0x47, 0x2D, 0x72, 0x39, 0x99, 0x9D, 0x24, + 0x0C, 0x8B, 0xDC, 0xA1, 0xEE, 0xF6, 0xF4, 0x73, + 0xC3, 0xB8, 0x0C, 0x23, 0x0D, 0xA7, 0xC4, 0x7D, + 0x27, 0xE2, 0x14, 0x11, 0x53, 0x19, 0xE7, 0xCA, + 0x94, 0x4E, 0x0D, 0x2C, 0xF7, 0x36, 0x47, 0xDB, + 0x77, 0x3C, 0x22, 0xAC, 0xBE, 0xE1, 0x06, 0x55, + 0xE5, 0xDD, 0x8B, 0x65, 0xE8, 0xE9, 0x91, 0x52, + 0x59, 0x97, 0xFC, 0x8C, 0xEE, 0x96, 0x22, 0x60, + 0xEE, 0xBF, 0x82, 0xF0, 0xCA, 0x14, 0xF9, 0xD3 +}; + +static const struct blockcipher_test_data +triple_des128ctr_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128ctr, + .len = 512 + } +}; + +static const struct blockcipher_test_data +triple_des128ctr_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128ctr, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .digest = { + .data = { + 0xC3, 0x40, 0xD5, 0xD9, 0x8F, 0x8A, 0xC0, 0xF0, + 0x46, 0x28, 0x02, 0x01, 0xB5, 0xC1, 0x87, 0x4D, + 0xAC, 0xFE, 0x48, 0x76 + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +triple_des128ctr_hmac_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128ctr, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0xF1, 0xC1, 0xDB, 0x4D, 0xFA, 0x7F, 0x2F, 0xE5, + 0xF8, 0x49, 0xEA, 0x1D, 0x7F, 0xCB, 0x42, 0x59, + 0xC4, 0x1E, 0xB1, 0x18 + }, + .len = 20 + } +}; + +static const uint8_t ciphertext512_des192ctr[] = { + 0xFF, 0x32, 0x52, 0x97, 0x10, 0xBF, 0x0B, 0x10, + 0x68, 0x0F, 0x4F, 0x56, 0x8B, 0x2C, 0x7B, 0x8E, + 0x39, 0x1E, 0x1A, 0x2F, 0x83, 0xDE, 0x5E, 0x35, + 0xC8, 0x4B, 0xDF, 0xD5, 0xBC, 0x84, 0x50, 0x1A, + 0x02, 0xDF, 0xB3, 0x11, 0xE4, 0xDA, 0xB8, 0x0E, + 0x47, 0xC6, 0x0C, 0x51, 0x09, 0x62, 0x9C, 0x5D, + 0x71, 0x40, 0x49, 0xD8, 0x55, 0xBD, 0x7D, 0x90, + 0x71, 0xC5, 0xF7, 0x07, 0x6F, 0x08, 0x71, 0x2A, + 0xB1, 0x77, 0x9B, 0x0F, 0xA1, 0xB0, 0xD6, 0x10, + 0xB2, 0xE5, 0x31, 0xEC, 0x21, 0x13, 0x89, 0x2A, + 0x09, 0x7E, 0x30, 0xDB, 0xA0, 0xF0, 0xDC, 0xE4, + 0x74, 0x64, 0x39, 0xA3, 0xB0, 0xB1, 0x80, 0x66, + 0x52, 0xD4, 0x4E, 0xC9, 0x5A, 0x52, 0x6A, 0xC7, + 0xB5, 0x2B, 0x61, 0xD5, 0x17, 0xD5, 0xF3, 0xCC, + 0x41, 0x61, 0xD2, 0xA6, 0xF4, 0x51, 0x24, 0x3A, + 0x63, 0x5D, 0x23, 0xB1, 0xF0, 0x22, 0xE7, 0x45, + 0xFA, 0x5F, 0x7E, 0x99, 0x00, 0x11, 0x28, 0x35, + 0xA3, 0xF4, 0x61, 0x94, 0x0E, 0x98, 0xCE, 0x35, + 0xDD, 0x91, 0x1B, 0x0B, 0x4D, 0xEE, 0xFF, 0xFF, + 0x0B, 0xD4, 0xDC, 0x56, 0xFC, 0x71, 0xE9, 0xEC, + 0xE8, 0x36, 0x51, 0xF8, 0x8B, 0x6A, 0xE1, 0x8C, + 0x2B, 0x25, 0x91, 0x91, 0x9B, 0x92, 0x76, 0xB5, + 0x3D, 0x26, 0xA8, 0x53, 0xEA, 0x30, 0x5B, 0x4D, + 0xDA, 0x16, 0xDA, 0x7D, 0x04, 0x88, 0xF5, 0x22, + 0xA8, 0x0C, 0xB9, 0x41, 0xC7, 0x91, 0x64, 0x86, + 0x99, 0x7D, 0x18, 0xB9, 0x67, 0xA2, 0x6E, 0x05, + 0x1A, 0x82, 0x8F, 0xA2, 0xEB, 0x4D, 0x0B, 0x8C, + 0x88, 0x2D, 0xBA, 0x77, 0x87, 0x32, 0x50, 0x3C, + 0x4C, 0xD8, 0xD3, 0x50, 0x39, 0xFA, 0xDF, 0x48, + 0x3E, 0x30, 0xF5, 0x76, 0x06, 0xB0, 0x1A, 0x05, + 0x60, 0x2C, 0xD3, 0xA0, 0x63, 0x1A, 0x19, 0x2D, + 0x6B, 0x76, 0xF2, 0x31, 0x4C, 0xA7, 0xE6, 0x5C, + 0x1B, 0x23, 0x20, 0x41, 0x32, 0xE5, 0x83, 0x47, + 0x04, 0xB6, 0x3E, 0xE0, 0xFD, 0x49, 0x1E, 0x1B, + 0x75, 0x10, 0x11, 0x46, 0xE9, 0xF9, 0x96, 0x9A, + 0xD7, 0x59, 0xFE, 0x38, 0x31, 0xFE, 0x79, 0xC4, + 0xC8, 0x46, 0x88, 0xDE, 0x2E, 0xAE, 0x20, 0xED, + 0x77, 0x50, 0x40, 0x38, 0x26, 0xD3, 0x35, 0xF6, + 0x29, 0x55, 0x6A, 0x6B, 0x38, 0x69, 0xFE, 0x90, + 0x5B, 0xA7, 0xFA, 0x6B, 0x73, 0x4F, 0xB9, 0x5D, + 0xDC, 0x6F, 0x98, 0xC3, 0x6A, 0xC4, 0xB5, 0x09, + 0xC5, 0x84, 0xA5, 0x6A, 0x84, 0xA4, 0xB3, 0x8A, + 0x5F, 0xCA, 0x92, 0x64, 0x9E, 0xC3, 0x0F, 0x84, + 0x8B, 0x2D, 0x48, 0xC6, 0x67, 0xAE, 0x07, 0xE0, + 0x28, 0x38, 0x6D, 0xC4, 0x4D, 0x13, 0x87, 0xE0, + 0xB2, 0x2F, 0xAA, 0xC0, 0xCF, 0x68, 0xD7, 0x9C, + 0xB8, 0x07, 0xE4, 0x51, 0xD7, 0x75, 0x86, 0xFA, + 0x0C, 0x50, 0x74, 0x68, 0x00, 0x64, 0x2A, 0x27, + 0x59, 0xE9, 0x80, 0xEB, 0xC2, 0xA3, 0xFA, 0x58, + 0xCC, 0x03, 0xE7, 0x7B, 0x66, 0x53, 0xFF, 0x90, + 0xA0, 0x85, 0xE2, 0xF8, 0x82, 0xFE, 0xC6, 0x2B, + 0xFF, 0x5E, 0x70, 0x85, 0x34, 0xB7, 0x22, 0x38, + 0xDB, 0xBC, 0x15, 0x30, 0x59, 0xC1, 0x48, 0x42, + 0xE5, 0x38, 0x8D, 0x37, 0x59, 0xDB, 0xA3, 0x20, + 0x17, 0x36, 0x1D, 0x4B, 0xBF, 0x4E, 0xA4, 0x35, + 0xCC, 0xFE, 0xF5, 0x7A, 0x73, 0xB4, 0x6D, 0x20, + 0x1D, 0xC0, 0xE5, 0x21, 0x5C, 0xD2, 0x8A, 0x65, + 0x08, 0xB6, 0x63, 0xAC, 0x9A, 0x1E, 0x3F, 0x3C, + 0xAB, 0xB6, 0x6D, 0x34, 0xB2, 0x3A, 0x08, 0xDA, + 0x29, 0x63, 0xD1, 0xA4, 0x83, 0x52, 0xB0, 0x63, + 0x1B, 0x89, 0x35, 0x57, 0x59, 0x2C, 0x0F, 0x72, + 0x72, 0xFD, 0xA0, 0xAC, 0xDB, 0xB4, 0xA3, 0xA1, + 0x18, 0x10, 0x12, 0x97, 0x99, 0x63, 0x38, 0x98, + 0x96, 0xB5, 0x16, 0x07, 0x4E, 0xE9, 0x2C, 0x97 +}; + +static const struct blockcipher_test_data +triple_des192ctr_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192ctr, + .len = 512 + } +}; + +static const struct blockcipher_test_data +triple_des192ctr_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192ctr, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .digest = { + .data = { + 0xEA, 0x62, 0xB9, 0xB2, 0x78, 0x6C, 0x8E, 0xDB, + 0xA3, 0xB6, 0xFF, 0x23, 0x3A, 0x47, 0xD8, 0xC8, + 0xED, 0x5E, 0x20, 0x1D + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +triple_des192ctr_hmac_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192ctr, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x32, 0xD5, 0x19, 0x8F, 0x79, 0x3A, 0xAA, 0x7B, + 0x70, 0x67, 0x4E, 0x63, 0x88, 0xA3, 0x9A, 0x82, + 0x07, 0x33, 0x12, 0x94 + }, + .len = 20 + } +}; + +static const uint8_t ciphertext512_des128cbc[] = { + 0x28, 0x2a, 0xff, 0x15, 0x5c, 0xdf, 0xd9, 0x6b, + 0x54, 0xbc, 0x7b, 0xfb, 0xc5, 0x64, 0x4d, 0xdd, + 0x3e, 0xf2, 0x9e, 0xb7, 0x53, 0x65, 0x37, 0x05, + 0xe0, 0xdf, 0xae, 0xf7, 0xc9, 0x27, 0xe4, 0xec, + 0x11, 0x27, 0xc2, 0x9e, 0x02, 0x4e, 0x03, 0x3b, + 0x33, 0xf2, 0x66, 0x08, 0x24, 0x5f, 0xab, 0xc2, + 0x7e, 0x21, 0x19, 0x5d, 0x51, 0xc3, 0xe2, 0x97, + 0x6f, 0x2e, 0xb4, 0xaa, 0x34, 0x70, 0x88, 0x78, + 0x4e, 0xe7, 0x3d, 0xe1, 0x9f, 0x87, 0x1c, 0x8b, + 0xac, 0x8d, 0xa1, 0x1a, 0xcd, 0xb0, 0xf8, 0xb6, + 0x24, 0x36, 0xe3, 0x8c, 0x07, 0xe7, 0xe4, 0x92, + 0x13, 0x86, 0x6f, 0x13, 0xec, 0x04, 0x5c, 0xe9, + 0xb9, 0xca, 0x45, 0x8a, 0x2c, 0x46, 0xda, 0x54, + 0x1d, 0xb5, 0x81, 0xb1, 0xcd, 0xf3, 0x7d, 0x11, + 0x6b, 0xb3, 0x0a, 0x45, 0xe5, 0x6e, 0x51, 0x3e, + 0x2c, 0xac, 0x7c, 0xbc, 0xa7, 0x7e, 0x22, 0x4d, + 0xe6, 0x02, 0xe3, 0x3f, 0x77, 0xd7, 0x73, 0x72, + 0x0e, 0xfb, 0x42, 0x85, 0x80, 0xdf, 0xa8, 0x91, + 0x60, 0x40, 0x48, 0xcd, 0x1b, 0xd9, 0xbf, 0x2f, + 0xf2, 0xdf, 0xd0, 0xbd, 0x3f, 0x82, 0xce, 0x15, + 0x9d, 0x6e, 0xc6, 0x59, 0x6f, 0x27, 0x0d, 0xf9, + 0x26, 0xe2, 0x11, 0x29, 0x50, 0xc3, 0x0a, 0xb7, + 0xde, 0x9d, 0xe9, 0x55, 0xa1, 0xe9, 0x01, 0x33, + 0x56, 0x51, 0xa7, 0x3a, 0x9e, 0x63, 0xc5, 0x08, + 0x01, 0x3b, 0x03, 0x4b, 0xc6, 0xc4, 0xa1, 0xc0, + 0xc0, 0xd0, 0x0e, 0x48, 0xe5, 0x4c, 0x55, 0x6b, + 0x4a, 0xc1, 0x0a, 0x24, 0x4b, 0xd0, 0x02, 0xf4, + 0x31, 0x63, 0x11, 0xbd, 0xa6, 0x1f, 0xf4, 0xae, + 0x23, 0x5a, 0x40, 0x7e, 0x0e, 0x4e, 0x63, 0x8b, + 0x66, 0x3d, 0x55, 0x46, 0x6e, 0x5c, 0x76, 0xa7, + 0x68, 0x31, 0xce, 0x5d, 0xca, 0xe2, 0xb4, 0xb0, + 0xc1, 0x1f, 0x66, 0x18, 0x75, 0x64, 0x73, 0xa9, + 0x9e, 0xd5, 0x0e, 0x0e, 0xf7, 0x77, 0x61, 0xf8, + 0x89, 0xc6, 0xcf, 0x0c, 0x41, 0xd3, 0x8f, 0xfd, + 0x22, 0x52, 0x4f, 0x94, 0x5c, 0x19, 0x11, 0x3a, + 0xb5, 0x63, 0xe8, 0x81, 0x33, 0x13, 0x54, 0x3c, + 0x93, 0x36, 0xb5, 0x5b, 0x51, 0xaf, 0x51, 0xa2, + 0x08, 0xae, 0x83, 0x15, 0x77, 0x07, 0x28, 0x0d, + 0x98, 0xe1, 0x2f, 0x69, 0x0e, 0xfb, 0x9a, 0x2e, + 0x27, 0x27, 0xb0, 0xd5, 0xce, 0xf8, 0x16, 0x55, + 0xfd, 0xaa, 0xd7, 0x1a, 0x1b, 0x2e, 0x4c, 0x86, + 0x7a, 0x6a, 0x90, 0xf7, 0x0a, 0x07, 0xd3, 0x81, + 0x4b, 0x75, 0x6a, 0x79, 0xdb, 0x63, 0x45, 0x0f, + 0x31, 0x7e, 0xd0, 0x2a, 0x14, 0xff, 0xee, 0xcc, + 0x97, 0x8a, 0x7d, 0x74, 0xbd, 0x9d, 0xaf, 0x00, + 0xdb, 0x7e, 0xf3, 0xe6, 0x22, 0x76, 0x77, 0x58, + 0xba, 0x1c, 0x06, 0x96, 0xfb, 0x6f, 0x41, 0x71, + 0x66, 0x98, 0xae, 0x31, 0x7d, 0x29, 0x18, 0x71, + 0x0e, 0xe4, 0x98, 0x7e, 0x59, 0x5a, 0xc9, 0x78, + 0x9c, 0xfb, 0x6c, 0x81, 0x44, 0xb4, 0x0f, 0x5e, + 0x18, 0x53, 0xb8, 0x6f, 0xbc, 0x3b, 0x15, 0xf0, + 0x10, 0xdd, 0x0d, 0x4b, 0x0a, 0x36, 0x0e, 0xb4, + 0x76, 0x0f, 0x16, 0xa7, 0x5c, 0x9d, 0xcf, 0xb0, + 0x6d, 0x38, 0x02, 0x07, 0x05, 0xe9, 0xe9, 0x46, + 0x08, 0xb8, 0x52, 0xd6, 0xd9, 0x4c, 0x81, 0x63, + 0x1d, 0xe2, 0x5b, 0xd0, 0xf6, 0x5e, 0x1e, 0x81, + 0x48, 0x08, 0x66, 0x3a, 0x85, 0xed, 0x65, 0xfe, + 0xe8, 0x05, 0x7a, 0xe1, 0xe6, 0x12, 0xf2, 0x52, + 0x83, 0xdd, 0x82, 0xbe, 0xf6, 0x34, 0x8a, 0x6f, + 0xc5, 0x83, 0xcd, 0x3f, 0xbe, 0x58, 0x8b, 0x11, + 0x78, 0xdc, 0x0c, 0x83, 0x72, 0x5d, 0x05, 0x2a, + 0x01, 0x29, 0xee, 0x48, 0x9a, 0x67, 0x00, 0x6e, + 0x14, 0x60, 0x2d, 0x00, 0x52, 0x87, 0x98, 0x5e, + 0x43, 0xfe, 0xf1, 0x10, 0x14, 0xf1, 0x91, 0xcc +}; + +static const struct blockcipher_test_data +triple_des128cbc_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128cbc, + .len = 512 + } +}; + +static const struct blockcipher_test_data +triple_des128cbc_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .digest = { + .data = { + 0x94, 0x45, 0x7B, 0xDF, 0xFE, 0x80, 0xB9, 0xA6, + 0xA0, 0x7A, 0xE8, 0x93, 0x40, 0x7B, 0x85, 0x02, + 0x1C, 0xD7, 0xE8, 0x87 + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +triple_des128cbc_hmac_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x7E, 0xBA, 0xFF, 0x86, 0x8D, 0x65, 0xCD, 0x08, + 0x76, 0x34, 0x94, 0xE9, 0x9A, 0xCD, 0xB2, 0xBB, + 0xBF, 0x65, 0xF5, 0x42 + }, + .len = 20 + } +}; + +static const uint8_t ciphertext512_des192cbc[] = { + 0xd0, 0xc9, 0xdc, 0x51, 0x29, 0x97, 0x03, 0x64, + 0xcd, 0x22, 0xba, 0x3d, 0x2b, 0xbc, 0x21, 0x37, + 0x7b, 0x1e, 0x29, 0x23, 0xeb, 0x51, 0x6e, 0xac, + 0xbe, 0x5b, 0xd3, 0x67, 0xe0, 0x3f, 0xc3, 0xb5, + 0xe3, 0x04, 0x17, 0x42, 0x2b, 0xaa, 0xdd, 0xd6, + 0x0e, 0x69, 0xd0, 0x8f, 0x8a, 0xfc, 0xb4, 0x55, + 0x67, 0x06, 0x51, 0xbb, 0x00, 0x57, 0xee, 0x95, + 0x28, 0x79, 0x3f, 0xd9, 0x97, 0x2b, 0xb0, 0x02, + 0x35, 0x08, 0xce, 0x7a, 0xc3, 0x43, 0x2c, 0x87, + 0xaa, 0x97, 0x6a, 0xad, 0xf0, 0x26, 0xea, 0x1d, + 0xbb, 0x08, 0xe9, 0x52, 0x11, 0xd3, 0xaf, 0x36, + 0x17, 0x14, 0x21, 0xb2, 0xbc, 0x42, 0x51, 0x33, + 0x27, 0x8c, 0xd8, 0x45, 0xb9, 0x76, 0xa0, 0x11, + 0x24, 0x34, 0xde, 0x4d, 0x13, 0x67, 0x1b, 0xc3, + 0x31, 0x12, 0x66, 0x56, 0x59, 0xd2, 0xb1, 0x8f, + 0xec, 0x1e, 0xc0, 0x10, 0x7a, 0x86, 0xb1, 0x60, + 0xc3, 0x01, 0xd6, 0xa8, 0x55, 0xad, 0x58, 0x63, + 0xca, 0x68, 0xa9, 0x33, 0xe3, 0x93, 0x90, 0x7d, + 0x8f, 0xca, 0xf8, 0x1c, 0xc2, 0x9e, 0xfb, 0xde, + 0x9c, 0xc7, 0xf2, 0x6c, 0xff, 0xcc, 0x39, 0x17, + 0x49, 0x33, 0x0d, 0x7c, 0xed, 0x07, 0x99, 0x91, + 0x91, 0x6c, 0x5f, 0x3f, 0x02, 0x09, 0xdc, 0x70, + 0xf9, 0x3b, 0x8d, 0xaa, 0xf4, 0xbc, 0x0e, 0xec, + 0xf2, 0x26, 0xfb, 0xb2, 0x1c, 0x31, 0xae, 0xc6, + 0x72, 0xe8, 0x0b, 0x75, 0x05, 0x57, 0x58, 0x98, + 0x92, 0x37, 0x27, 0x8e, 0x3b, 0x0c, 0x25, 0xfb, + 0xcf, 0x82, 0x02, 0xd5, 0x0b, 0x1f, 0x89, 0x49, + 0xcd, 0x0f, 0xa1, 0xa7, 0x08, 0x63, 0x56, 0xa7, + 0x1f, 0x80, 0x3a, 0xef, 0x24, 0x89, 0x57, 0x1a, + 0x02, 0xdc, 0x2e, 0x51, 0xbd, 0x4a, 0x10, 0x23, + 0xfc, 0x02, 0x1a, 0x3f, 0x34, 0xbf, 0x1c, 0x98, + 0x1a, 0x40, 0x0a, 0x96, 0x8e, 0x41, 0xd5, 0x09, + 0x55, 0x37, 0xe9, 0x25, 0x11, 0x83, 0xf8, 0xf3, + 0xd4, 0xb0, 0xdb, 0x16, 0xd7, 0x51, 0x7e, 0x94, + 0xf7, 0xb4, 0x26, 0xe0, 0xf4, 0x80, 0x01, 0x65, + 0x51, 0xeb, 0xbc, 0xb0, 0x65, 0x8f, 0xdd, 0xb5, + 0xf7, 0x00, 0xec, 0x40, 0xab, 0x7d, 0x96, 0xcc, + 0x8d, 0xec, 0x89, 0x80, 0x31, 0x39, 0xa2, 0x5c, + 0xb0, 0x55, 0x4c, 0xee, 0xdd, 0x15, 0x2b, 0xa9, + 0x86, 0x4e, 0x23, 0x14, 0x36, 0xc5, 0x57, 0xf5, + 0xe3, 0xe8, 0x89, 0xc9, 0xb7, 0xf8, 0xeb, 0x08, + 0xe5, 0x93, 0x12, 0x5c, 0x0f, 0x79, 0xa1, 0x86, + 0xe4, 0xc2, 0xeb, 0xa6, 0xa0, 0x50, 0x6a, 0xec, + 0xd3, 0xce, 0x50, 0x78, 0x4e, 0x4f, 0x93, 0xd8, + 0xdc, 0xb4, 0xec, 0x02, 0xe9, 0xbd, 0x17, 0x99, + 0x1e, 0x16, 0x4e, 0xd7, 0xb0, 0x07, 0x02, 0x55, + 0x63, 0x24, 0x4f, 0x7b, 0x8f, 0xc5, 0x7a, 0x12, + 0x29, 0xff, 0x5d, 0xc1, 0xe7, 0xae, 0x48, 0xc8, + 0x57, 0x53, 0xe7, 0xcd, 0x10, 0x6c, 0x19, 0xfc, + 0xcc, 0xb9, 0xb1, 0xbe, 0x48, 0x9f, 0x2d, 0x3f, + 0x39, 0x2e, 0xdd, 0x71, 0xde, 0x1b, 0x54, 0xee, + 0x7d, 0x94, 0x8f, 0x27, 0x23, 0xe9, 0x74, 0x92, + 0x14, 0x93, 0x84, 0x65, 0xc9, 0x22, 0x7c, 0xa8, + 0x1b, 0x72, 0x73, 0xb1, 0x23, 0xa0, 0x6b, 0xcc, + 0xb5, 0x22, 0x06, 0x15, 0xe5, 0x96, 0x03, 0x4a, + 0x52, 0x8d, 0x1d, 0xbf, 0x3e, 0x82, 0x45, 0x9c, + 0x75, 0x9e, 0xa9, 0x3a, 0x97, 0xb6, 0x5d, 0xc4, + 0x75, 0x67, 0xa1, 0xf3, 0x0f, 0x7a, 0xfd, 0x71, + 0x58, 0x04, 0xf9, 0xa7, 0xc2, 0x56, 0x74, 0x04, + 0x74, 0x68, 0x6d, 0x8a, 0xf6, 0x6c, 0x5d, 0xd8, + 0xb5, 0xed, 0x70, 0x23, 0x32, 0x4d, 0x75, 0x92, + 0x88, 0x7b, 0x39, 0x37, 0x02, 0x4b, 0xb2, 0x1c, + 0x1f, 0x7e, 0x5b, 0x1b, 0x10, 0xfc, 0x17, 0x21, + 0x66, 0x62, 0x63, 0xc2, 0xcd, 0x16, 0x96, 0x3e +}; + +static const struct blockcipher_test_data +triple_des192cbc_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192cbc, + .len = 512 + } +}; + +static const struct blockcipher_test_data +triple_des192cbc_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .digest = { + .data = { + 0x53, 0x27, 0xC0, 0xE6, 0xD6, 0x1B, 0xD6, 0x45, + 0x94, 0x2D, 0xCE, 0x8B, 0x29, 0xA3, 0x52, 0x14, + 0xC1, 0x6B, 0x87, 0x99 + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +triple_des192cbc_hmac_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0xBA, 0xAC, 0x74, 0x19, 0x43, 0xB0, 0x72, 0xB8, + 0x08, 0xF5, 0x24, 0xC4, 0x09, 0xBD, 0x48, 0xC1, + 0x3C, 0x50, 0x1C, 0xDD + }, + .len = 20 + } +}; + +static const struct blockcipher_test_case triple_des_chain_test_cases[] = { + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Encryption Digest", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Decryption Digest Verify", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC SHA1 Encryption Digest", + .test_data = &triple_des128cbc_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-128-CBC SHA1 Decryption Digest Verify", + .test_data = &triple_des128cbc_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-192-CBC HMAC-SHA1 Encryption Digest", + .test_data = &triple_des192cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CBC HMAC-SHA1 Decryption Digest Verify", + .test_data = &triple_des192cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CBC SHA1 Encryption Digest", + .test_data = &triple_des192cbc_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-192-CBC SHA1 Decryption Digest Verify", + .test_data = &triple_des192cbc_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-128-CTR HMAC-SHA1 Encryption Digest", + .test_data = &triple_des128ctr_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CTR HMAC-SHA1 Decryption Digest Verify", + .test_data = &triple_des128ctr_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CTR SHA1 Encryption Digest", + .test_data = &triple_des128ctr_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-128-CTR SHA1 Decryption Digest Verify", + .test_data = &triple_des128ctr_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-192-CTR HMAC-SHA1 Encryption Digest", + .test_data = &triple_des192ctr_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CTR HMAC-SHA1 Decryption Digest Verify", + .test_data = &triple_des192ctr_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CTR SHA1 Encryption Digest", + .test_data = &triple_des192ctr_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-192-CTR SHA1 Decryption Digest Verify", + .test_data = &triple_des192ctr_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Encryption Digest OOP", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Decryption Digest Verify OOP", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Encryption Digest Sessionless", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = + "3DES-128-CBC HMAC-SHA1 Decryption Digest Verify Sessionless", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, +}; + +static const struct blockcipher_test_case triple_des_cipheronly_test_cases[] = { + { + .test_descr = "3DES-128-CBC Encryption", + .test_data = &triple_des128cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC Decryption", + .test_data = &triple_des128cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CBC Encryption", + .test_data = &triple_des192cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CBC Decryption", + .test_data = &triple_des192cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CTR Encryption", + .test_data = &triple_des128ctr_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CTR Decryption", + .test_data = &triple_des128ctr_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CTR Encryption", + .test_data = &triple_des192ctr_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CTR Decryption", + .test_data = &triple_des192ctr_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + } +}; + +#endif /* TEST_CRYPTODEV_DES_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_hash_test_vectors.h b/app/test/test_cryptodev_hash_test_vectors.h new file mode 100644 index 0000000..dfc84db --- /dev/null +++ b/app/test/test_cryptodev_hash_test_vectors.h @@ -0,0 +1,491 @@ +/* + * 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 TEST_CRYPTODEV_HASH_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_HASH_TEST_VECTORS_H_ + +static const uint8_t plaintext_hash[] = { + "What a lousy earth! He wondered how many people " + "were destitute that same night even in his own " + "prosperous country, how many homes were " + "shanties, how many husbands were drunk and " + "wives socked, and how many children were " + "bullied, abused, or abandoned. How many " + "families hungered for food they could not " + "afford to buy? How many hearts were broken? How " + "many suicides would take place that same night, " + "how many people would go insane? How many " + "cockroaches and landlords would triumph? How " + "many winners were losers, successes failures, " + "and rich men poor men? How many wise guys were " + "stupid? How many happy endings were unhappy " + "endings? How many honest men were liars, brave " + "men cowards, loyal men traitors, how many " + "sainted men were corrupt, how many people in " + "positions of trust had sold their souls to " + "bodyguards, how many had never had souls? How " + "many straight-and-narrow paths were crooked " + "paths? How many best families were worst " + "families and how many good people were bad " + "people? When you added them all up and then " + "subtracted, you might be left with only the " + "children, and perhaps with Albert Einstein and " + "an old violinist or sculptor somewhere." +}; + +static const struct blockcipher_test_data +md5_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_MD5, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0xB3, 0xE6, 0xBB, 0x50, 0x41, 0x35, 0x3C, 0x6B, + 0x7A, 0xFF, 0xD2, 0x64, 0xAF, 0xD5, 0x1C, 0xB2 + }, + .len = 16 + } +}; + +static const struct blockcipher_test_data +hmac_md5_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_MD5_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD + }, + .len = 16 + }, + .digest = { + .data = { + 0x50, 0xE8, 0xDE, 0xC5, 0xC1, 0x76, 0xAC, 0xAE, + 0x15, 0x4A, 0xF1, 0x7F, 0x7E, 0x04, 0x42, 0x9B + }, + .len = 16 + } +}; + +static const struct blockcipher_test_data +sha1_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0xA2, 0x8D, 0x40, 0x78, 0xDD, 0x9F, 0xBB, 0xD5, + 0x35, 0x62, 0xFB, 0xFA, 0x93, 0xFD, 0x7D, 0x70, + 0xA6, 0x7D, 0x45, 0xCA + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +hmac_sha1_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0xC4, 0xB7, 0x0E, 0x6B, 0xDE, 0xD1, 0xE7, 0x77, + 0x7E, 0x2E, 0x8F, 0xFC, 0x48, 0x39, 0x46, 0x17, + 0x3F, 0x91, 0x64, 0x59 + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +sha224_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA224, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0x91, 0xE7, 0xCD, 0x75, 0x14, 0x9C, 0xA9, 0xE9, + 0x2E, 0x46, 0x12, 0x20, 0x22, 0xF9, 0x68, 0x28, + 0x39, 0x26, 0xDF, 0xB5, 0x78, 0x62, 0xB2, 0x6E, + 0x5E, 0x8F, 0x25, 0x84 + }, + .len = 28 + } +}; + +static const struct blockcipher_test_data +hmac_sha224_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA224_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92, + 0xFB, 0xBF, 0xB0, 0x8C + }, + .len = 28 + }, + .digest = { + .data = { + 0x70, 0x0F, 0x04, 0x4D, 0x22, 0x02, 0x7D, 0x31, + 0x36, 0xDA, 0x77, 0x19, 0xB9, 0x66, 0x37, 0x7B, + 0xF1, 0x8A, 0x63, 0xBB, 0x5D, 0x1D, 0xE3, 0x9F, + 0x92, 0xF6, 0xAA, 0x19 + }, + .len = 28 + } +}; + +static const struct blockcipher_test_data +sha256_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA256, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0x7F, 0xF1, 0x0C, 0xF5, 0x90, 0x97, 0x19, 0x0F, + 0x00, 0xE4, 0x83, 0x01, 0xCA, 0x59, 0x00, 0x2E, + 0x1F, 0xC7, 0x84, 0xEE, 0x76, 0xA6, 0x39, 0x15, + 0x76, 0x2F, 0x87, 0xF9, 0x01, 0x06, 0xF3, 0xB7 + }, + .len = 32 + } +}; + +static const struct blockcipher_test_data +hmac_sha256_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92, + 0xFB, 0xBF, 0xB0, 0x8C, 0x29, 0x87, 0x90, 0xAC + }, + .len = 32 + }, + .digest = { + .data = { + 0xAF, 0x8F, 0x70, 0x1B, 0x4B, 0xAF, 0x34, 0xCB, + 0x02, 0x24, 0x48, 0x45, 0x83, 0x52, 0x8F, 0x22, + 0x06, 0x4D, 0x64, 0x09, 0x0A, 0xCC, 0x02, 0x77, + 0x71, 0x83, 0x48, 0x71, 0x07, 0x02, 0x25, 0x17 + }, + .len = 32 + } +}; + +static const struct blockcipher_test_data +sha384_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA384, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0x1D, 0xE7, 0x3F, 0x55, 0x86, 0xFE, 0x48, 0x9F, + 0xAC, 0xC6, 0x85, 0x32, 0xFA, 0x8E, 0xA6, 0x77, + 0x25, 0x84, 0xA5, 0x98, 0x8D, 0x0B, 0x80, 0xF4, + 0xEB, 0x2C, 0xFB, 0x6C, 0xEA, 0x7B, 0xFD, 0xD5, + 0xAD, 0x41, 0xAB, 0x15, 0xB0, 0x03, 0x15, 0xEC, + 0x9E, 0x3D, 0xED, 0xCB, 0x80, 0x7B, 0xF4, 0xB6 + }, + .len = 48 + } +}; + +static const struct blockcipher_test_data +hmac_sha384_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA384_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92, + 0xFB, 0xBF, 0xB0, 0x8C, 0x29, 0x87, 0x90, 0xAC, + 0x39, 0x8B, 0x5C, 0x49, 0x68, 0x1E, 0x3A, 0x05, + 0xCC, 0x68, 0x5C, 0x76, 0xCB, 0x3C, 0x71, 0x89 + }, + .len = 48 + }, + .digest = { + .data = { + 0xE2, 0x83, 0x18, 0x55, 0xB5, 0x8D, 0x94, 0x9B, + 0x01, 0xB6, 0xE2, 0x57, 0x7A, 0x62, 0xF5, 0xF4, + 0xAB, 0x39, 0xF3, 0x3C, 0x28, 0xA0, 0x0F, 0xCC, + 0xEE, 0x1C, 0xF1, 0xF8, 0x69, 0xF1, 0x24, 0x3B, + 0x10, 0x90, 0x0A, 0xE3, 0xF0, 0x59, 0xDD, 0xC0, + 0x6F, 0xE6, 0x8C, 0x84, 0xD5, 0x03, 0xF8, 0x9E + }, + .len = 48 + } +}; + +static const struct blockcipher_test_data +sha512_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA512, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0xB9, 0xBA, 0x28, 0x48, 0x3C, 0xC2, 0xD3, 0x65, + 0x4A, 0xD6, 0x00, 0x1D, 0xCE, 0x61, 0x64, 0x54, + 0x45, 0x8C, 0x64, 0x0E, 0xED, 0x0E, 0xD8, 0x1C, + 0x72, 0xCE, 0xD2, 0x44, 0x91, 0xC8, 0xEB, 0xC7, + 0x99, 0xC5, 0xCA, 0x89, 0x72, 0x64, 0x96, 0x41, + 0xC8, 0xEA, 0xB2, 0x4E, 0xD1, 0x21, 0x13, 0x49, + 0x64, 0x4E, 0x15, 0x68, 0x12, 0x67, 0x26, 0x0F, + 0x2C, 0x3C, 0x83, 0x25, 0x27, 0x86, 0xF0, 0xDB + }, + .len = 64 + } +}; + +static const struct blockcipher_test_data +hmac_sha512_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA512_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92, + 0xFB, 0xBF, 0xB0, 0x8C, 0x29, 0x87, 0x90, 0xAC, + 0x39, 0x8B, 0x5C, 0x49, 0x68, 0x1E, 0x3A, 0x05, + 0xCC, 0x68, 0x5C, 0x76, 0xCB, 0x3C, 0x71, 0x89, + 0xDE, 0xAA, 0x36, 0x44, 0x98, 0x93, 0x97, 0x1E, + 0x6D, 0x53, 0x83, 0x87, 0xB3, 0xB7, 0x56, 0x41 + }, + .len = 64 + }, + .digest = { + .data = { + 0xB8, 0x0B, 0x35, 0x97, 0x3F, 0x24, 0x3F, 0x05, + 0x2A, 0x7F, 0x2F, 0xD8, 0xD7, 0x56, 0x58, 0xAD, + 0x6F, 0x8D, 0x1F, 0x4C, 0x30, 0xF9, 0xA8, 0x29, + 0x7A, 0xE0, 0x8D, 0x88, 0xF5, 0x2E, 0x94, 0xF5, + 0x06, 0xF7, 0x5D, 0x57, 0x32, 0xA8, 0x49, 0x29, + 0xEA, 0x6B, 0x6D, 0x95, 0xBD, 0x76, 0xF5, 0x79, + 0x97, 0x37, 0x0F, 0xBE, 0xC2, 0x45, 0xA0, 0x87, + 0xAF, 0x24, 0x27, 0x0C, 0x78, 0xBA, 0xBE, 0x20 + }, + .len = 64 + } +}; + +static const struct blockcipher_test_case hash_test_cases[] = { + { + .test_descr = "MD5 Digest", + .test_data = &md5_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "MD5 Digest Verify", + .test_data = &md5_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-MD5 Digest", + .test_data = &hmac_md5_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-MD5 Digest Verify", + .test_data = &hmac_md5_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA1 Digest", + .test_data = &sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA1 Digest Verify", + .test_data = &sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA1 Digest", + .test_data = &hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA1 Digest Verify", + .test_data = &hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA224 Digest", + .test_data = &sha224_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA224 Digest Verify", + .test_data = &sha224_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA224 Digest", + .test_data = &hmac_sha224_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA224 Digest Verify", + .test_data = &hmac_sha224_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA256 Digest", + .test_data = &sha256_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA256 Digest Verify", + .test_data = &sha256_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA256 Digest", + .test_data = &hmac_sha256_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA256 Digest Verify", + .test_data = &hmac_sha256_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA384 Digest", + .test_data = &sha384_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA384 Digest Verify", + .test_data = &sha384_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA384 Digest", + .test_data = &hmac_sha384_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA384 Digest Verify", + .test_data = &hmac_sha384_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA512 Digest", + .test_data = &sha512_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA512 Digest Verify", + .test_data = &sha512_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA512 Digest", + .test_data = &hmac_sha512_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA512 Digest Verify", + .test_data = &hmac_sha512_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, +}; + +#endif /* TEST_CRYPTODEV_HASH_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_perf.c b/app/test/test_cryptodev_perf.c index 6af0896..6d6b4a1 100644 --- a/app/test/test_cryptodev_perf.c +++ b/app/test/test_cryptodev_perf.c @@ -151,12 +151,28 @@ static struct rte_cryptodev_sym_session * test_perf_create_snow3g_session(uint8_t dev_id, enum chain_mode chain, enum rte_crypto_cipher_algorithm cipher_algo, unsigned cipher_key_len, enum rte_crypto_auth_algorithm auth_algo); +static struct rte_cryptodev_sym_session * +test_perf_create_libcrypto_session(uint8_t dev_id, enum chain_mode chain, + enum rte_crypto_cipher_algorithm cipher_algo, + unsigned int cipher_key_len, enum rte_crypto_auth_algorithm auth_algo); static struct rte_mbuf * test_perf_create_pktmbuf(struct rte_mempool *mpool, unsigned buf_sz); static inline struct rte_crypto_op * test_perf_set_crypto_op_snow3g(struct rte_crypto_op *op, struct rte_mbuf *m, struct rte_cryptodev_sym_session *sess, unsigned data_len, unsigned digest_len); +static inline struct rte_crypto_op * +test_perf_set_crypto_op_aes(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len); +static inline struct rte_crypto_op * +test_perf_set_crypto_op_aes_gcm(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len); +static inline struct rte_crypto_op * +test_perf_set_crypto_op_3des(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len); static uint32_t get_auth_digest_length(enum rte_crypto_auth_algorithm algo); @@ -357,6 +373,26 @@ testsuite_setup(void) } } + /* Create 2 LIBCRYPTO devices if required */ + if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_LIBCRYPTO_PMD) { +#ifndef RTE_LIBRTE_PMD_LIBCRYPTO + RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO must be" + " enabled in config file to run this testsuite.\n"); + return TEST_FAILED; +#endif + nb_devs = rte_cryptodev_count_devtype(RTE_CRYPTODEV_LIBCRYPTO_PMD); + if (nb_devs < 2) { + for (i = nb_devs; i < 2; i++) { + ret = rte_eal_vdev_init( + RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), NULL); + + TEST_ASSERT(ret == 0, + "Failed to create instance %u of pmd : %s", + i, RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD)); + } + } + } + #ifndef RTE_LIBRTE_PMD_QAT if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_QAT_SYM_PMD) { RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_QAT must be enabled " @@ -367,7 +403,7 @@ testsuite_setup(void) nb_devs = rte_cryptodev_count(); if (nb_devs < 1) { - RTE_LOG(ERR, USER1, "No crypto devices found?"); + RTE_LOG(ERR, USER1, "No crypto devices found?\n"); return TEST_FAILED; } @@ -2242,6 +2278,151 @@ test_perf_snow3G_vary_burst_size(void) return 0; } +static int +test_perf_libcrypto_optimise_cyclecount(struct perf_test_params *pparams) +{ + uint32_t num_to_submit = pparams->total_operations; + struct rte_crypto_op *c_ops[num_to_submit]; + struct rte_crypto_op *proc_ops[num_to_submit]; + uint64_t failed_polls, retries, start_cycles, end_cycles, total_cycles = 0; + uint32_t burst_sent = 0, burst_received = 0; + uint32_t i, burst_size, num_sent, num_ops_received; + + struct crypto_testsuite_params *ts_params = &testsuite_params; + + static struct rte_cryptodev_sym_session *sess; + + static struct rte_crypto_op *(*test_perf_set_crypto_op) + (struct rte_crypto_op *, struct rte_mbuf *, + struct rte_cryptodev_sym_session *, unsigned int, + unsigned int); + + unsigned int digest_length = get_auth_digest_length(pparams->auth_algo); + + if (rte_cryptodev_count() == 0) { + printf("\nNo crypto devices found. Is PMD build configured?\n"); + return TEST_FAILED; + } + + /* Create Crypto session*/ + sess = test_perf_create_libcrypto_session(ts_params->dev_id, + pparams->chain, pparams->cipher_algo, + pparams->cipher_key_length, pparams->auth_algo); + TEST_ASSERT_NOT_NULL(sess, "Session creation failed"); + + /* Generate Crypto op data structure(s)*/ + for (i = 0; i < num_to_submit ; i++) { + struct rte_mbuf *m = test_perf_create_pktmbuf( + ts_params->mbuf_mp, + pparams->buf_size); + TEST_ASSERT_NOT_NULL(m, "Failed to allocate tx_buf"); + + struct rte_crypto_op *op = + rte_crypto_op_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC); + TEST_ASSERT_NOT_NULL(op, "Failed to allocate op"); + + switch (pparams->cipher_algo) { + case RTE_CRYPTO_CIPHER_3DES_CBC: + case RTE_CRYPTO_CIPHER_3DES_CTR: + test_perf_set_crypto_op = test_perf_set_crypto_op_3des; + break; + case RTE_CRYPTO_CIPHER_AES_CBC: + case RTE_CRYPTO_CIPHER_AES_CTR: + test_perf_set_crypto_op = test_perf_set_crypto_op_aes; + break; + case RTE_CRYPTO_CIPHER_AES_GCM: + test_perf_set_crypto_op = test_perf_set_crypto_op_aes_gcm; + break; + default: + return TEST_FAILED; + } + + op = test_perf_set_crypto_op(op, m, sess, pparams->buf_size, + digest_length); + TEST_ASSERT_NOT_NULL(op, "Failed to attach op to session"); + + c_ops[i] = op; + } + + printf("\nOn %s dev%u qp%u, %s, cipher algo:%s, cipher key length:%u, " + "auth_algo:%s, Packet Size %u bytes", + pmd_name(gbl_cryptodev_perftest_devtype), + ts_params->dev_id, 0, + chain_mode_name(pparams->chain), + cipher_algo_name(pparams->cipher_algo), + pparams->cipher_key_length, + auth_algo_name(pparams->auth_algo), + pparams->buf_size); + printf("\nOps Tx\tOps Rx\tOps/burst "); + printf("Retries EmptyPolls\tIACycles/CyOp\tIACycles/Burst\tIACycles/Byte"); + + for (i = 2; i <= 128 ; i *= 2) { + num_sent = 0; + num_ops_received = 0; + retries = 0; + failed_polls = 0; + burst_size = i; + total_cycles = 0; + while (num_sent < num_to_submit) { + start_cycles = rte_rdtsc_precise(); + burst_sent = rte_cryptodev_enqueue_burst(ts_params->dev_id, + 0, &c_ops[num_sent], + ((num_to_submit - num_sent) < burst_size) ? + num_to_submit - num_sent : burst_size); + end_cycles = rte_rdtsc_precise(); + if (burst_sent == 0) + retries++; + num_sent += burst_sent; + total_cycles += (end_cycles - start_cycles); + + /* Wait until requests have been sent. */ + rte_delay_ms(1); + + start_cycles = rte_rdtsc_precise(); + burst_received = rte_cryptodev_dequeue_burst( + ts_params->dev_id, 0, proc_ops, burst_size); + end_cycles = rte_rdtsc_precise(); + if (burst_received < burst_sent) + failed_polls++; + num_ops_received += burst_received; + + total_cycles += end_cycles - start_cycles; + } + + while (num_ops_received != num_to_submit) { + /* Sending 0 length burst to flush sw crypto device */ + rte_cryptodev_enqueue_burst(ts_params->dev_id, 0, NULL, 0); + + start_cycles = rte_rdtsc_precise(); + burst_received = rte_cryptodev_dequeue_burst( + ts_params->dev_id, 0, proc_ops, burst_size); + end_cycles = rte_rdtsc_precise(); + + total_cycles += end_cycles - start_cycles; + if (burst_received == 0) + failed_polls++; + num_ops_received += burst_received; + } + + printf("\n%u\t%u\t%u", num_sent, num_ops_received, burst_size); + printf("\t\t%"PRIu64, retries); + printf("\t%"PRIu64, failed_polls); + printf("\t\t%"PRIu64, total_cycles/num_ops_received); + printf("\t\t%"PRIu64, (total_cycles/num_ops_received)*burst_size); + printf("\t\t%"PRIu64, + total_cycles/(num_ops_received*pparams->buf_size)); + } + printf("\n"); + + for (i = 0; i < num_to_submit ; i++) { + rte_pktmbuf_free(c_ops[i]->sym->m_src); + rte_crypto_op_free(c_ops[i]); + } + + return TEST_SUCCESS; +} + static uint32_t get_auth_key_max_length(enum rte_crypto_auth_algorithm algo) { switch (algo) { @@ -2257,6 +2438,8 @@ static uint32_t get_auth_key_max_length(enum rte_crypto_auth_algorithm algo) return 128; case RTE_CRYPTO_AUTH_SHA512_HMAC: return 128; + case RTE_CRYPTO_AUTH_AES_GCM: + return 0; default: return 0; } @@ -2277,23 +2460,35 @@ static uint32_t get_auth_digest_length(enum rte_crypto_auth_algorithm algo) return TRUNCATED_DIGEST_BYTE_LENGTH_SHA384; case RTE_CRYPTO_AUTH_SHA512_HMAC: return TRUNCATED_DIGEST_BYTE_LENGTH_SHA512; + case RTE_CRYPTO_AUTH_AES_GCM: + return DIGEST_BYTE_LENGTH_AES_GCM; default: return 0; } } -static uint8_t aes_cbc_key[] = { +static uint8_t aes_key[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static uint8_t aes_cbc_iv[] = { +static uint8_t aes_iv[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static uint8_t triple_des_key[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static uint8_t triple_des_iv[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + static uint8_t hmac_sha_key[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -2343,7 +2538,7 @@ test_perf_create_aes_sha_session(uint8_t dev_id, enum chain_mode chain, cipher_xform.cipher.algo = cipher_algo; cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; - cipher_xform.cipher.key.data = aes_cbc_key; + cipher_xform.cipher.key.data = aes_key; cipher_xform.cipher.key.length = cipher_key_len; /* Setup HMAC Parameters */ @@ -2421,8 +2616,77 @@ test_perf_create_snow3g_session(uint8_t dev_id, enum chain_mode chain, } } -#define AES_CBC_BLOCK_SIZE 16 -#define AES_CBC_CIPHER_IV_LENGTH 16 +static struct rte_cryptodev_sym_session * +test_perf_create_libcrypto_session(uint8_t dev_id, enum chain_mode chain, + enum rte_crypto_cipher_algorithm cipher_algo, + unsigned int cipher_key_len, + enum rte_crypto_auth_algorithm auth_algo) +{ + struct rte_crypto_sym_xform cipher_xform = { 0 }; + struct rte_crypto_sym_xform auth_xform = { 0 }; + + /* Setup Cipher Parameters */ + cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; + cipher_xform.cipher.algo = cipher_algo; + cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; + + switch (cipher_algo) { + case RTE_CRYPTO_CIPHER_3DES_CBC: + case RTE_CRYPTO_CIPHER_3DES_CTR: + cipher_xform.cipher.key.data = triple_des_key; + break; + case RTE_CRYPTO_CIPHER_AES_CBC: + case RTE_CRYPTO_CIPHER_AES_CTR: + case RTE_CRYPTO_CIPHER_AES_GCM: + cipher_xform.cipher.key.data = aes_key; + break; + default: + return NULL; + } + + cipher_xform.cipher.key.length = cipher_key_len; + + /* Setup Auth Parameters */ + auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; + auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; + auth_xform.auth.algo = auth_algo; + + switch (auth_algo) { + case RTE_CRYPTO_AUTH_SHA1_HMAC: + auth_xform.auth.key.data = hmac_sha_key; + break; + case RTE_CRYPTO_AUTH_AES_GCM: + auth_xform.auth.key.data = NULL; + break; + default: + return NULL; + } + + auth_xform.auth.key.length = get_auth_key_max_length(auth_algo); + auth_xform.auth.digest_length = get_auth_digest_length(auth_algo); + + switch (chain) { + case CIPHER_HASH: + cipher_xform.next = &auth_xform; + auth_xform.next = NULL; + /* Create Crypto session*/ + return rte_cryptodev_sym_session_create(dev_id, &cipher_xform); + case HASH_CIPHER: + auth_xform.next = &cipher_xform; + cipher_xform.next = NULL; + /* Create Crypto session*/ + return rte_cryptodev_sym_session_create(dev_id, &auth_xform); + default: + return NULL; + } +} + +#define AES_BLOCK_SIZE 16 +#define AES_CIPHER_IV_LENGTH 16 + +#define TRIPLE_DES_BLOCK_SIZE 8 +#define TRIPLE_DES_CIPHER_IV_LENGTH 8 + #define SNOW3G_CIPHER_IV_LENGTH 16 static struct rte_mbuf * @@ -2441,7 +2705,7 @@ test_perf_create_pktmbuf(struct rte_mempool *mpool, unsigned buf_sz) } static inline struct rte_crypto_op * -test_perf_set_crypto_op(struct rte_crypto_op *op, struct rte_mbuf *m, +test_perf_set_crypto_op_aes(struct rte_crypto_op *op, struct rte_mbuf *m, struct rte_cryptodev_sym_session *sess, unsigned data_len, unsigned digest_len) { @@ -2455,19 +2719,53 @@ test_perf_set_crypto_op(struct rte_crypto_op *op, struct rte_mbuf *m, (m->data_off + data_len); op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, data_len); op->sym->auth.digest.length = digest_len; - op->sym->auth.aad.data = aes_cbc_iv; - op->sym->auth.aad.length = AES_CBC_CIPHER_IV_LENGTH; + op->sym->auth.aad.data = aes_iv; + op->sym->auth.aad.length = AES_CIPHER_IV_LENGTH; /* Cipher Parameters */ - op->sym->cipher.iv.data = aes_cbc_iv; - op->sym->cipher.iv.length = AES_CBC_CIPHER_IV_LENGTH; + op->sym->cipher.iv.data = aes_iv; + op->sym->cipher.iv.length = AES_CIPHER_IV_LENGTH; /* Data lengths/offsets Parameters */ op->sym->auth.data.offset = 0; op->sym->auth.data.length = data_len; - op->sym->cipher.data.offset = AES_CBC_BLOCK_SIZE; - op->sym->cipher.data.length = data_len - AES_CBC_BLOCK_SIZE; + op->sym->cipher.data.offset = AES_BLOCK_SIZE; + op->sym->cipher.data.length = data_len - AES_BLOCK_SIZE; + + op->sym->m_src = m; + + return op; +} + +static inline struct rte_crypto_op * +test_perf_set_crypto_op_aes_gcm(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len) +{ + if (rte_crypto_op_attach_sym_session(op, sess) != 0) { + rte_crypto_op_free(op); + return NULL; + } + + /* Authentication Parameters */ + op->sym->auth.digest.data = (uint8_t *)m->buf_addr + + (m->data_off + data_len); + op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, data_len); + op->sym->auth.digest.length = digest_len; + op->sym->auth.aad.data = aes_iv; + op->sym->auth.aad.length = AES_CIPHER_IV_LENGTH; + + /* Cipher Parameters */ + op->sym->cipher.iv.data = aes_iv; + op->sym->cipher.iv.length = AES_CIPHER_IV_LENGTH; + + /* Data lengths/offsets Parameters */ + op->sym->auth.data.offset = AES_BLOCK_SIZE; + op->sym->auth.data.length = data_len - AES_BLOCK_SIZE; + + op->sym->cipher.data.offset = AES_BLOCK_SIZE; + op->sym->cipher.data.length = data_len - AES_BLOCK_SIZE; op->sym->m_src = m; @@ -2508,7 +2806,39 @@ test_perf_set_crypto_op_snow3g(struct rte_crypto_op *op, struct rte_mbuf *m, return op; } +static inline struct rte_crypto_op * +test_perf_set_crypto_op_3des(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len) +{ + if (rte_crypto_op_attach_sym_session(op, sess) != 0) { + rte_crypto_op_free(op); + return NULL; + } + + /* Authentication Parameters */ + op->sym->auth.digest.data = (uint8_t *)m->buf_addr + + (m->data_off + data_len); + op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, data_len); + op->sym->auth.digest.length = digest_len; + op->sym->auth.aad.data = triple_des_iv; + op->sym->auth.aad.length = TRIPLE_DES_CIPHER_IV_LENGTH; + + /* Cipher Parameters */ + op->sym->cipher.iv.data = triple_des_iv; + op->sym->cipher.iv.length = TRIPLE_DES_CIPHER_IV_LENGTH; + + /* Data lengths/offsets Parameters */ + op->sym->auth.data.offset = 0; + op->sym->auth.data.length = data_len; + op->sym->cipher.data.offset = TRIPLE_DES_BLOCK_SIZE; + op->sym->cipher.data.length = data_len - TRIPLE_DES_BLOCK_SIZE; + + op->sym->m_src = m; + + return op; +} /* An mbuf set is used in each burst. An mbuf can be used by multiple bursts at * same time, i.e. as they're not dereferenced there's no need to wait until @@ -2579,7 +2909,7 @@ test_perf_aes_sha(uint8_t dev_id, uint16_t queue_id, "and free ops below."); } else { for (i = 0; i < ops_needed; i++) - ops[i] = test_perf_set_crypto_op(ops[i], + ops[i] = test_perf_set_crypto_op_aes(ops[i], mbufs[i + (pparams->burst_size * (j % NUM_MBUF_SETS))], sess, pparams->buf_size, digest_length); @@ -2790,6 +3120,154 @@ test_perf_snow3g(uint8_t dev_id, uint16_t queue_id, return TEST_SUCCESS; } +static int +test_perf_libcrypto(uint8_t dev_id, uint16_t queue_id, + struct perf_test_params *pparams) +{ + uint16_t i, k, l, m; + uint16_t j = 0; + uint16_t ops_unused = 0; + + uint64_t burst_enqueued = 0, total_enqueued = 0, burst_dequeued = 0; + uint64_t processed = 0, failed_polls = 0, retries = 0; + uint64_t tsc_start = 0, tsc_end = 0; + + unsigned int digest_length = get_auth_digest_length(pparams->auth_algo); + + struct rte_crypto_op *ops[pparams->burst_size]; + struct rte_crypto_op *proc_ops[pparams->burst_size]; + + struct rte_mbuf *mbufs[pparams->burst_size * NUM_MBUF_SETS]; + + struct crypto_testsuite_params *ts_params = &testsuite_params; + + static struct rte_cryptodev_sym_session *sess; + + static struct rte_crypto_op *(*test_perf_set_crypto_op) + (struct rte_crypto_op *, struct rte_mbuf *, + struct rte_cryptodev_sym_session *, unsigned int, + unsigned int); + + switch (pparams->cipher_algo) { + case RTE_CRYPTO_CIPHER_3DES_CBC: + case RTE_CRYPTO_CIPHER_3DES_CTR: + test_perf_set_crypto_op = test_perf_set_crypto_op_3des; + break; + case RTE_CRYPTO_CIPHER_AES_CBC: + case RTE_CRYPTO_CIPHER_AES_CTR: + test_perf_set_crypto_op = test_perf_set_crypto_op_aes; + break; + case RTE_CRYPTO_CIPHER_AES_GCM: + test_perf_set_crypto_op = test_perf_set_crypto_op_aes_gcm; + break; + default: + return TEST_FAILED; + } + + if (rte_cryptodev_count() == 0) { + printf("\nNo crypto devices found. Is PMD build configured?\n"); + return TEST_FAILED; + } + + /* Create Crypto session*/ + sess = test_perf_create_libcrypto_session(ts_params->dev_id, + pparams->chain, pparams->cipher_algo, + pparams->cipher_key_length, pparams->auth_algo); + TEST_ASSERT_NOT_NULL(sess, "Session creation failed"); + + /* Generate a burst of crypto operations */ + for (i = 0; i < (pparams->burst_size * NUM_MBUF_SETS); i++) { + mbufs[i] = test_perf_create_pktmbuf( + ts_params->mbuf_mp, + pparams->buf_size); + + if (mbufs[i] == NULL) { + printf("\nFailed to get mbuf - freeing the rest.\n"); + for (k = 0; k < i; k++) + rte_pktmbuf_free(mbufs[k]); + return -1; + } + } + + tsc_start = rte_rdtsc_precise(); + + while (total_enqueued < pparams->total_operations) { + uint16_t burst_size = + total_enqueued + pparams->burst_size <= pparams->total_operations ? + pparams->burst_size : pparams->total_operations - total_enqueued; + uint16_t ops_needed = burst_size - ops_unused; + + if (ops_needed != rte_crypto_op_bulk_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC, ops, ops_needed)){ + printf("\nFailed to alloc enough ops, finish dequeuing " + "and free ops below."); + } else { + for (i = 0; i < ops_needed; i++) + ops[i] = test_perf_set_crypto_op(ops[i], + mbufs[i + (pparams->burst_size * + (j % NUM_MBUF_SETS))], + sess, pparams->buf_size, digest_length); + + /* enqueue burst */ + burst_enqueued = rte_cryptodev_enqueue_burst(dev_id, + queue_id, ops, burst_size); + + if (burst_enqueued < burst_size) + retries++; + + ops_unused = burst_size - burst_enqueued; + total_enqueued += burst_enqueued; + } + + /* dequeue burst */ + burst_dequeued = rte_cryptodev_dequeue_burst(dev_id, queue_id, + proc_ops, pparams->burst_size); + if (burst_dequeued == 0) + failed_polls++; + else { + processed += burst_dequeued; + + for (l = 0; l < burst_dequeued; l++) + rte_crypto_op_free(proc_ops[l]); + } + j++; + } + + /* Dequeue any operations still in the crypto device */ + while (processed < pparams->total_operations) { + /* Sending 0 length burst to flush sw crypto device */ + rte_cryptodev_enqueue_burst(dev_id, queue_id, NULL, 0); + + /* dequeue burst */ + burst_dequeued = rte_cryptodev_dequeue_burst(dev_id, queue_id, + proc_ops, pparams->burst_size); + if (burst_dequeued == 0) + failed_polls++; + else { + processed += burst_dequeued; + + for (m = 0; m < burst_dequeued; m++) + rte_crypto_op_free(proc_ops[m]); + } + } + + tsc_end = rte_rdtsc_precise(); + + double ops_s = ((double)processed / (tsc_end - tsc_start)) + * rte_get_tsc_hz(); + double throughput = (ops_s * pparams->buf_size * NUM_MBUF_SETS) + / 1000000000; + + printf("\t%u\t%6.2f\t%10.2f\t%8"PRIu64"\t%8"PRIu64, pparams->buf_size, + ops_s / 1000000, throughput, retries, failed_polls); + + for (i = 0; i < pparams->burst_size * NUM_MBUF_SETS; i++) + rte_pktmbuf_free(mbufs[i]); + + printf("\n"); + return TEST_SUCCESS; +} + /* perf_test_aes_sha("avx2", HASH_CIPHER, 16, CBC, SHA1); @@ -2937,6 +3415,166 @@ test_perf_snow3G_vary_pkt_size(void) } static int +test_perf_libcrypto_vary_pkt_size(void) +{ + unsigned int total_operations = 1000000; + unsigned int burst_size = { 64 }; + unsigned int buf_lengths[] = { 64, 128, 256, 512, 768, 1024, 1280, 1536, + 1792, 2048 }; + uint8_t i, j; + + struct perf_test_params params_set[] = { + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key_length = 24, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key_length = 32, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key_length = 24, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_GCM, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_AES_GCM + }, + }; + + for (i = 0; i < RTE_DIM(params_set); i++) { + params_set[i].total_operations = total_operations; + params_set[i].burst_size = burst_size; + printf("\n%s. cipher algo: %s auth algo: %s cipher key size=%u." + " burst_size: %d ops\n", + chain_mode_name(params_set[i].chain), + cipher_algo_name(params_set[i].cipher_algo), + auth_algo_name(params_set[i].auth_algo), + params_set[i].cipher_key_length, + burst_size); + printf("\nBuffer Size(B)\tOPS(M)\tThroughput(Gbps)\tRetries\t" + "EmptyPolls\n"); + for (j = 0; j < RTE_DIM(buf_lengths); j++) { + params_set[i].buf_size = buf_lengths[j]; + test_perf_libcrypto(testsuite_params.dev_id, 0, ¶ms_set[i]); + } + } + + return 0; +} + +static int +test_perf_libcrypto_vary_burst_size(void) +{ + unsigned int total_operations = 4096; + uint16_t buf_lengths[] = { 40 }; + uint8_t i, j; + + struct perf_test_params params_set[] = { + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key_length = 24, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key_length = 32, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key_length = 24, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_GCM, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_AES_GCM + }, + }; + + printf("\n\nStart %s.", __func__); + printf("\nThis Test measures the average IA cycle cost using a " + "constant request(packet) size. "); + printf("Cycle cost is only valid when indicators show device is not busy," + " i.e. Retries and EmptyPolls = 0"); + + for (i = 0; i < RTE_DIM(params_set); i++) { + printf("\n"); + params_set[i].total_operations = total_operations; + + for (j = 0; j < RTE_DIM(buf_lengths); j++) { + params_set[i].buf_size = buf_lengths[j]; + test_perf_libcrypto_optimise_cyclecount(¶ms_set[i]); + } + } + + return 0; +} + +static int test_perf_aes_cbc_vary_burst_size(void) { return test_perf_crypto_qp_vary_burst_size(testsuite_params.dev_id); @@ -3377,6 +4015,19 @@ static struct unit_test_suite cryptodev_snow3g_testsuite = { } }; +static struct unit_test_suite cryptodev_libcrypto_testsuite = { + .suite_name = "Crypto Device LIBCRYPTO Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, + test_perf_libcrypto_vary_pkt_size), + TEST_CASE_ST(ut_setup, ut_teardown, + test_perf_libcrypto_vary_burst_size), + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + static int perftest_aesni_gcm_cryptodev(void) { @@ -3417,8 +4068,18 @@ perftest_qat_snow3g_cryptodev(void /*argv __rte_unused, int argc __rte_unused*/) return unit_test_suite_runner(&cryptodev_snow3g_testsuite); } +static int +perftest_libcrypto_cryptodev(void /*argv __rte_unused, int argc __rte_unused*/) +{ + gbl_cryptodev_perftest_devtype = RTE_CRYPTODEV_LIBCRYPTO_PMD; + + return unit_test_suite_runner(&cryptodev_libcrypto_testsuite); +} + REGISTER_TEST_COMMAND(cryptodev_aesni_mb_perftest, perftest_aesni_mb_cryptodev); REGISTER_TEST_COMMAND(cryptodev_qat_perftest, perftest_qat_cryptodev); REGISTER_TEST_COMMAND(cryptodev_sw_snow3g_perftest, perftest_sw_snow3g_cryptodev); REGISTER_TEST_COMMAND(cryptodev_qat_snow3g_perftest, perftest_qat_snow3g_cryptodev); REGISTER_TEST_COMMAND(cryptodev_aesni_gcm_perftest, perftest_aesni_gcm_cryptodev); +REGISTER_TEST_COMMAND(cryptodev_libcrypto_perftest, + perftest_libcrypto_cryptodev); -- 2.5.0 ^ permalink raw reply [flat|nested] 34+ messages in thread
* [dpdk-dev] [PATCH v4 4/5] app/test: added big data GMAC test for libcrypto 2016-09-30 16:32 ` [dpdk-dev] [PATCH v4 2/5] app/test: cryptodev AES tests rework Slawomir Mrozowicz 2016-09-30 16:32 ` [dpdk-dev] [PATCH v4 3/5] app/test: added tests for libcrypto PMD Slawomir Mrozowicz @ 2016-09-30 16:32 ` Slawomir Mrozowicz 2016-09-30 17:18 ` Thomas Monjalon 2016-09-30 16:32 ` [dpdk-dev] [PATCH v4 5/5] examples/l2fwd-crypto: updated example for libcrypto PMD Slawomir Mrozowicz 2 siblings, 1 reply; 34+ messages in thread From: Slawomir Mrozowicz @ 2016-09-30 16:32 UTC (permalink / raw) To: dev; +Cc: Slawomir Mrozowicz, Piotr Azarewicz This patch add big data AES-GMAC test for libcrypto PMD. Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com> --- app/test/test_cryptodev.c | 18 +- app/test/test_cryptodev_gcm_test_vectors.h | 8245 +++++++++++++++++++++++++++- 2 files changed, 8242 insertions(+), 21 deletions(-) diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c index 7679dc4..7af3aa6 100644 --- a/app/test/test_cryptodev.c +++ b/app/test/test_cryptodev.c @@ -169,7 +169,7 @@ testsuite_setup(void) /* Not already created so create */ ts_params->mbuf_pool = rte_pktmbuf_pool_create( "CRYPTO_MBUFPOOL", - NUM_MBUFS, MBUF_CACHE_SIZE, 0, MBUF_SIZE, + NUM_MBUFS, MBUF_CACHE_SIZE, 0, UINT16_MAX, rte_socket_id()); if (ts_params->mbuf_pool == NULL) { RTE_LOG(ERR, USER1, "Can't create CRYPTO_MBUFPOOL\n"); @@ -5196,6 +5196,12 @@ test_AES_GMAC_authentication_test_case_3(void) } static int +test_AES_GMAC_authentication_test_case_4(void) +{ + return test_AES_GMAC_authentication(&gmac_test_case_4); +} + +static int test_AES_GMAC_authentication_verify(const struct gmac_test_data *tdata) { struct crypto_testsuite_params *ts_params = &testsuite_params; @@ -5255,6 +5261,12 @@ test_AES_GMAC_authentication_verify_test_case_3(void) return test_AES_GMAC_authentication_verify(&gmac_test_case_3); } +static int +test_AES_GMAC_authentication_verify_test_case_4(void) +{ + return test_AES_GMAC_authentication_verify(&gmac_test_case_4); +} + struct test_crypto_vector { enum rte_crypto_cipher_algorithm crypto_algo; @@ -6177,6 +6189,10 @@ static struct unit_test_suite cryptodev_libcrypto_testsuite = { test_AES_GMAC_authentication_test_case_3), TEST_CASE_ST(ut_setup, ut_teardown, test_AES_GMAC_authentication_verify_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_4), /** Negative tests */ TEST_CASE_ST(ut_setup, ut_teardown, diff --git a/app/test/test_cryptodev_gcm_test_vectors.h b/app/test/test_cryptodev_gcm_test_vectors.h index deca09d..3c23bb6 100644 --- a/app/test/test_cryptodev_gcm_test_vectors.h +++ b/app/test/test_cryptodev_gcm_test_vectors.h @@ -450,26 +450,8198 @@ static const struct gcm_test_data gcm_test_case_7 = { /** GMAC Test Vectors */ static uint8_t gmac_plaintext[] = { - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x33, 0xF3, 0xE2, 0xF1, 0x9E, 0xC4, 0x34, 0x20, + 0xB5, 0x98, 0x88, 0xA5, 0xDA, 0x6B, 0xAC, 0x5F, + 0x01, 0xDE, 0xBE, 0x28, 0x24, 0x9E, 0xA2, 0x3C, + 0xA2, 0xC4, 0x1D, 0xC6, 0xD3, 0x72, 0x83, 0x16, + 0x5C, 0xBB, 0x94, 0x12, 0xB0, 0x8F, 0xFB, 0x98, + 0xA2, 0x3A, 0x9F, 0x27, 0x7B, 0x99, 0x7C, 0x53, + 0x6D, 0x36, 0xFE, 0xA5, 0xB0, 0x33, 0x22, 0x63, + 0x12, 0xE4, 0x05, 0xAF, 0x33, 0xE4, 0xB6, 0x99, + 0xFC, 0x15, 0x00, 0x9E, 0x4C, 0x87, 0x14, 0xD3, + 0x34, 0x6E, 0xBF, 0x35, 0x2B, 0xEC, 0x8D, 0x45, + 0xF8, 0x36, 0x81, 0x18, 0x72, 0x09, 0x67, 0x91, + 0x2E, 0x75, 0x08, 0xD5, 0x65, 0x41, 0xC1, 0x38, + 0xED, 0xEF, 0x18, 0xC1, 0xEE, 0x48, 0xB4, 0x47, + 0x41, 0x5C, 0x6A, 0x97, 0x14, 0xA2, 0xC8, 0x3A, + 0x9F, 0x4B, 0xFB, 0x66, 0xFB, 0x3F, 0x35, 0x6D, + 0xF1, 0xC8, 0x1D, 0x0B, 0xAC, 0x4A, 0xA1, 0x28, + 0x68, 0x18, 0xF5, 0x54, 0xF8, 0x76, 0xE7, 0xB7, + 0x0B, 0x6C, 0xB1, 0xCA, 0x5D, 0x91, 0x9F, 0x00, + 0x12, 0xFD, 0xA6, 0x5C, 0xF8, 0x88, 0x73, 0xE5, + 0x38, 0x21, 0x50, 0x75, 0xF5, 0x09, 0x56, 0x10, + 0x49, 0x80, 0xB1, 0x27, 0xEF, 0xAC, 0xCD, 0x30, + 0x43, 0x6D, 0x3E, 0xF2, 0x91, 0x76, 0xEA, 0x5F, + 0xB7, 0xDD, 0xC7, 0x21, 0xD1, 0x1F, 0x0D, 0xA2, + 0x68, 0x31, 0xEE, 0x25, 0x9B, 0x67, 0x37, 0x3D, + 0xF2, 0x48, 0x2E, 0x4A, 0x61, 0xD3, 0xB6, 0xA1, + 0x69, 0x02, 0x62, 0xCA, 0x2D, 0xDE, 0x40, 0x7E, + 0x7F, 0xCC, 0x26, 0x53, 0x48, 0x9A, 0x2B, 0x6B, + 0x9B, 0x27, 0xE8, 0x57, 0xD7, 0xD3, 0x9F, 0xE2, + 0xC6, 0x2D, 0xD1, 0xC3, 0x10, 0x12, 0x00, 0x7F, + 0xBB, 0x58, 0x15, 0x11, 0x38, 0x78, 0x22, 0x66, + 0xAB, 0xEE, 0xAC, 0xD0, 0xA3, 0x99, 0x7A, 0x1A, + 0xF3, 0xE9, 0xB8, 0x5E, 0x54, 0x85, 0x93, 0xEB, + 0xB8, 0x10, 0x5D, 0xFE, 0xF3, 0x48, 0x46, 0xDA, + 0x69, 0x26, 0xFF, 0x0C, 0x4E, 0x1C, 0x3C, 0xB8, + 0xEA, 0x14, 0xA0, 0xA6, 0xFE, 0xC4, 0x3A, 0x0B, + 0xAB, 0xB1, 0x71, 0x32, 0x94, 0xB0, 0x9D, 0x49, + 0x91, 0x47, 0x9D, 0xB3, 0xEB, 0x68, 0x8B, 0xB5, + 0x6D, 0x3B, 0xA6, 0xE5, 0x9E, 0x35, 0x5F, 0x3F, + 0x92, 0x48, 0x30, 0x0F, 0xBA, 0x66, 0x65, 0x75, + 0x14, 0x2F, 0x4C, 0x24, 0x1E, 0x7C, 0x92, 0x4C, + 0xEA, 0xFA, 0x2C, 0x6B, 0x60, 0xF0, 0x54, 0xEF, + 0x36, 0x35, 0x2F, 0x89, 0xA4, 0x02, 0xA8, 0xB8, + 0x68, 0x6F, 0xBD, 0xD8, 0x40, 0x1C, 0x93, 0x7B, + 0xA0, 0x04, 0x29, 0x85, 0x2F, 0x3F, 0x9C, 0x0D, + 0x1F, 0x3C, 0xE7, 0xE2, 0xE9, 0x93, 0xBD, 0xEF, + 0x80, 0x94, 0x91, 0x94, 0x7D, 0x31, 0x6E, 0xB3, + 0xDE, 0x7C, 0x71, 0x4C, 0x84, 0x1B, 0x39, 0x3B, + 0x0D, 0x49, 0x4F, 0xB8, 0x16, 0x2A, 0xC8, 0x94, + 0xC7, 0xA0, 0x2E, 0x79, 0xD3, 0x6F, 0xFD, 0xE7, + 0x80, 0x7C, 0xAE, 0xAD, 0xA2, 0xDA, 0x1A, 0x48, + 0xE7, 0x55, 0xC0, 0x88, 0xAE, 0x44, 0xA4, 0x15, + 0x48, 0x32, 0x72, 0xDF, 0x2C, 0x0D, 0x5C, 0xC5, + 0x3B, 0xFA, 0x80, 0xC1, 0x73, 0xB7, 0xFA, 0x85, + 0x02, 0xC2, 0x5C, 0x44, 0xE8, 0x2A, 0x4E, 0xA2, + 0xEA, 0xDB, 0x61, 0x6A, 0x3A, 0x08, 0x05, 0x9A, + 0xC9, 0x0A, 0x24, 0xD7, 0xD4, 0x79, 0x0F, 0xBD, + 0x8C, 0x43, 0x29, 0xAD, 0x97, 0xE7, 0x32, 0x08, + 0x4E, 0xE5, 0xE6, 0x9F, 0xF1, 0x9E, 0xD0, 0x08, + 0x50, 0xB0, 0x7E, 0x60, 0x26, 0xF9, 0x1F, 0xD7, + 0x17, 0x3B, 0x9C, 0xC4, 0x0C, 0x88, 0xEE, 0x00, + 0x8B, 0xDE, 0x52, 0xEE, 0xE3, 0xB9, 0x17, 0x23, + 0x0F, 0xE8, 0x5E, 0xC7, 0x23, 0x9C, 0x1F, 0xB7, + 0xEE, 0x01, 0xE7, 0x53, 0xEB, 0x8E, 0xF9, 0xB1, + 0x2B, 0x75, 0x33, 0x7A, 0xE5, 0x28, 0xBC, 0xC1, + 0x4A, 0x90, 0xBF, 0x5C, 0x2B, 0xF4, 0x22, 0x52, + 0xAB, 0x08, 0x81, 0x5B, 0xCF, 0x72, 0x94, 0xB6, + 0x86, 0x47, 0x35, 0xE3, 0xE7, 0x79, 0x1F, 0x00, + 0xCC, 0x1B, 0xF0, 0xCE, 0x68, 0x52, 0xFE, 0xD3, + 0xFD, 0xB9, 0x65, 0x15, 0xDC, 0x39, 0x48, 0x32, + 0x19, 0x78, 0xD8, 0x0D, 0x4D, 0x5A, 0x86, 0x2A, + 0xF8, 0x6B, 0x1F, 0xAD, 0xBF, 0xA7, 0xC2, 0x14, + 0xFA, 0xE4, 0xF2, 0xB9, 0xD1, 0xD0, 0xA1, 0x19, + 0x04, 0x1B, 0xCE, 0xFE, 0xC8, 0xF2, 0x92, 0xF2, + 0x13, 0xB5, 0x0F, 0x18, 0x66, 0x4E, 0xC4, 0x17, + 0x92, 0xD5, 0x38, 0x5A, 0xC8, 0xC7, 0x60, 0x4D, + 0xB2, 0x5C, 0x99, 0x00, 0xF4, 0xDA, 0x05, 0x89, + 0x5A, 0x04, 0x39, 0xC0, 0xFA, 0x6C, 0x8C, 0x84, + 0x4D, 0x6D, 0xBD, 0x29, 0x30, 0xCC, 0x64, 0x53, + 0x4F, 0x28, 0x47, 0x4A, 0xA6, 0xE8, 0x70, 0x0F, + 0x72, 0x09, 0xE5, 0x67, 0x03, 0xCE, 0x3B, 0x26, + 0x55, 0x27, 0xED, 0xCE, 0xFA, 0x5A, 0x81, 0x44, + 0xBC, 0xB6, 0xFA, 0xF1, 0x43, 0x48, 0x83, 0xBB, + 0xBC, 0xF5, 0x2F, 0x3A, 0xB6, 0xCF, 0xAA, 0xF0, + 0x4D, 0x4F, 0x47, 0x56, 0xAB, 0x2C, 0xC9, 0x59, + 0xE9, 0x0F, 0x1F, 0x55, 0xCF, 0xAF, 0x61, 0x58, + 0x3C, 0xD9, 0x44, 0xDC, 0xD6, 0x3B, 0x21, 0x63, + 0x3D, 0x34, 0xF9, 0x31, 0xC5, 0x39, 0x64, 0x70, + 0x37, 0x5F, 0xC5, 0xFB, 0x4A, 0xC2, 0x39, 0xFE, + 0xC1, 0x55, 0x43, 0xCF, 0xDB, 0xE9, 0xA6, 0x8B, + 0xF5, 0xD8, 0x2B, 0x01, 0x0E, 0x7B, 0x36, 0x14, + 0x5C, 0x66, 0x17, 0x5C, 0x08, 0xEE, 0x1A, 0x1B, + 0x7A, 0xB0, 0x67, 0xBA, 0x39, 0x25, 0x67, 0x35, + 0x1A, 0x85, 0xD0, 0x27, 0x55, 0x6E, 0x2C, 0xDF, + 0x01, 0x38, 0x09, 0x9A, 0xF5, 0x5F, 0x41, 0x30, + 0xAD, 0x44, 0xC9, 0xDC, 0x4C, 0xFD, 0xBA, 0x97, + 0x37, 0x6F, 0x61, 0x15, 0x76, 0xEF, 0x0C, 0x31, + 0x64, 0x6B, 0xE2, 0xD5, 0x71, 0x16, 0x01, 0x14, + 0x51, 0x4E, 0x6E, 0xB0, 0xCF, 0x48, 0x03, 0x5A, + 0x2E, 0x84, 0x0C, 0x9D, 0xFD, 0x66, 0x5B, 0x1E, + 0x49, 0x32, 0xBA, 0x0E, 0x69, 0x0A, 0x74, 0xD8, + 0xD8, 0xA5, 0xFB, 0xC9, 0x20, 0xD0, 0x6D, 0x75, + 0x8D, 0xB4, 0xFE, 0xE7, 0x16, 0xF6, 0xE4, 0x05, + 0x75, 0x0B, 0xDC, 0xD6, 0x46, 0x4D, 0x57, 0x00, + 0xD5, 0x6B, 0xE4, 0xD2, 0x32, 0xBD, 0x4C, 0xAE, + 0x40, 0x37, 0xC6, 0xC7, 0x91, 0xCB, 0x0B, 0x79, + 0x91, 0x07, 0x3D, 0x41, 0x5A, 0x6D, 0xEB, 0x14, + 0xA3, 0x32, 0xE7, 0x62, 0xBB, 0x75, 0x09, 0x62, + 0x7A, 0x30, 0x3D, 0x7A, 0x94, 0x2F, 0x89, 0xB0, + 0x0B, 0x96, 0x7B, 0xB0, 0x0D, 0xFF, 0x12, 0xF0, + 0x3A, 0x8F, 0x2E, 0x23, 0x11, 0xA4, 0x1F, 0xB1, + 0xA4, 0x7D, 0xA9, 0x77, 0xD9, 0x94, 0x19, 0x57, + 0xB1, 0x31, 0x01, 0x6D, 0xA9, 0x8E, 0x47, 0x8C, + 0x67, 0xEF, 0x26, 0xD7, 0xFE, 0x70, 0x42, 0xB3, + 0x2E, 0xBA, 0x0F, 0x51, 0x50, 0x49, 0xA7, 0xB4, + 0xDC, 0x12, 0xB4, 0x04, 0xEB, 0x2D, 0x6F, 0xEF, + 0x48, 0x3B, 0x38, 0x2B, 0x42, 0x3F, 0xF4, 0x0D, + 0x8E, 0x77, 0x12, 0x8D, 0x9E, 0x48, 0x89, 0x68, + 0x2A, 0x98, 0xC9, 0x0F, 0xF9, 0x69, 0xED, 0xD3, + 0x0B, 0x10, 0x67, 0x0F, 0x05, 0xD7, 0xB6, 0x4D, + 0xDE, 0x1D, 0x56, 0xF8, 0x19, 0x1F, 0x91, 0xCD, + 0x40, 0x2C, 0x1F, 0x82, 0x06, 0x76, 0xE0, 0xBB, + 0x82, 0xBE, 0xAE, 0xC0, 0xE0, 0xA7, 0xF3, 0x85, + 0x33, 0xCF, 0xFC, 0x0C, 0x62, 0xDB, 0x2A, 0x55, + 0x9D, 0x66, 0xBA, 0x09, 0x25, 0x02, 0x10, 0x39, + 0xEE, 0x91, 0xCD, 0xF4, 0xB3, 0x81, 0x38, 0xE9, + 0xDC, 0xD2, 0x84, 0xBE, 0xA2, 0x07, 0x2F, 0xE9, + 0xF6, 0xFA, 0x49, 0x32, 0xD3, 0xB5, 0x9E, 0x66, + 0x35, 0x06, 0x00, 0xDF, 0xD1, 0xFA, 0x28, 0xE7, + 0x49, 0x66, 0xEC, 0xD3, 0xE3, 0xA4, 0x4F, 0x4C, + 0x3B, 0x05, 0x2A, 0x0D, 0xD5, 0x6E, 0x5B, 0x34, + 0x2F, 0xDA, 0xE2, 0x5B, 0x47, 0x37, 0xE8, 0xC3, + 0xC3, 0xC2, 0x8F, 0xD2, 0xC4, 0xDF, 0x26, 0xC5, + 0x8A, 0x60, 0xE7, 0x8C, 0x0D, 0x33, 0x44, 0xE3, + 0xA5, 0x3C, 0xDE, 0x47, 0xA3, 0x5F, 0x1D, 0x07, + 0xFF, 0x95, 0xE2, 0xED, 0xF1, 0xF9, 0xEF, 0xB6, + 0x44, 0x01, 0x75, 0x8A, 0x00, 0x7A, 0x0C, 0x22, + 0xCC, 0xE0, 0xBF, 0x1E, 0x7D, 0xA1, 0x44, 0x54, + 0x38, 0x8F, 0xE9, 0x44, 0xB9, 0x5B, 0x88, 0xB8, + 0x0C, 0xFE, 0x1C, 0x8D, 0xC6, 0x80, 0x27, 0x2C, + 0x84, 0x36, 0xFC, 0x6D, 0x38, 0x00, 0xAE, 0xFE, + 0x6C, 0x9A, 0xEF, 0x7D, 0x92, 0xC5, 0x19, 0x95, + 0xD6, 0xCF, 0x91, 0x3E, 0xCC, 0x9C, 0x77, 0x45, + 0x0A, 0x84, 0xF5, 0x1B, 0x45, 0xD2, 0x6B, 0x45, + 0x7F, 0x18, 0xAD, 0x0F, 0xCE, 0x2A, 0xC0, 0x2C, + 0x08, 0x6A, 0x75, 0xD2, 0xAC, 0xB9, 0xC7, 0x82, + 0xF7, 0x11, 0x52, 0x54, 0x63, 0x48, 0x24, 0x74, + 0xCE, 0x13, 0x4F, 0x7A, 0xEC, 0x53, 0x3B, 0xD3, + 0xD1, 0xAC, 0x87, 0x65, 0x03, 0xD8, 0xCD, 0x56, + 0xEC, 0xCD, 0x4B, 0xAC, 0xC0, 0xC6, 0x18, 0x19, + 0x0E, 0xC5, 0x3A, 0xC6, 0xF9, 0xCE, 0x89, 0xEB, + 0x98, 0xFE, 0x23, 0xD8, 0xC3, 0xB1, 0xC4, 0x85, + 0x9B, 0x3A, 0x0A, 0xDE, 0x2C, 0xBE, 0x0F, 0xB6, + 0x41, 0xF7, 0x93, 0x70, 0x8B, 0xFD, 0x67, 0x22, + 0x14, 0xDA, 0x37, 0x5F, 0x04, 0x35, 0xAF, 0x4D, + 0x10, 0x0C, 0x35, 0x8A, 0xC0, 0x73, 0x83, 0x18, + 0x60, 0xB7, 0x4B, 0x1F, 0x4B, 0x5B, 0xAC, 0xE3, + 0xAE, 0x3A, 0x98, 0xD4, 0xC3, 0x6B, 0x92, 0x3D, + 0xEF, 0xD1, 0xD8, 0xBF, 0xA8, 0x66, 0xAB, 0x51, + 0x38, 0x79, 0x4D, 0xAB, 0x63, 0x36, 0xF0, 0x67, + 0x98, 0x77, 0x27, 0x95, 0xC2, 0x67, 0xE4, 0xF4, + 0x3A, 0x72, 0x46, 0x39, 0x0B, 0xC8, 0x18, 0xBF, + 0x0E, 0x71, 0x0B, 0xBE, 0x02, 0x86, 0x62, 0xB0, + 0x98, 0x5A, 0x8B, 0xC7, 0xF8, 0x04, 0xBD, 0x53, + 0xBF, 0x93, 0xC1, 0x8C, 0xAE, 0xEE, 0x97, 0xCB, + 0xB5, 0x72, 0xF6, 0x72, 0x3D, 0x1C, 0x5F, 0xD4, + 0x05, 0xC5, 0xFF, 0x87, 0x63, 0x2A, 0x64, 0x58, + 0xCA, 0xFF, 0x8F, 0x2A, 0x5B, 0xD8, 0x62, 0xE5, + 0x24, 0xF9, 0x39, 0x9E, 0xE5, 0x3A, 0xDE, 0xB4, + 0xA2, 0x5E, 0x45, 0x7E, 0x14, 0x66, 0x56, 0x3F, + 0x9F, 0xCA, 0x2F, 0x49, 0xE0, 0xBE, 0xCE, 0x48, + 0x1E, 0x4F, 0x8E, 0x83, 0x69, 0x0C, 0xEF, 0x58, + 0x6A, 0x09, 0x5A, 0xBB, 0x04, 0x5B, 0x81, 0x65, + 0x4C, 0x73, 0xDE, 0xB5, 0xE6, 0x56, 0x3A, 0x83, + 0x9A, 0x04, 0x80, 0x11, 0x07, 0xC9, 0x05, 0x79, + 0x94, 0x0C, 0x69, 0x9C, 0xB9, 0x25, 0x67, 0xE4, + 0x4C, 0xA4, 0x8A, 0x4B, 0x92, 0x27, 0xB1, 0x0A, + 0x6D, 0x0C, 0xE2, 0x14, 0x33, 0x85, 0x2C, 0x12, + 0x1E, 0x9C, 0xB9, 0xAC, 0x0C, 0xBD, 0xF1, 0x6B, + 0x71, 0xB2, 0x7D, 0x91, 0x6C, 0x6F, 0xE2, 0x22, + 0x3B, 0x93, 0xB2, 0x8F, 0x41, 0x91, 0x1F, 0x1F, + 0x2E, 0x4B, 0x52, 0xE3, 0x44, 0x2A, 0x4A, 0x41, + 0x21, 0xA4, 0xC5, 0x26, 0x34, 0x35, 0x89, 0x47, + 0x3C, 0xED, 0x39, 0x8C, 0x3C, 0x3A, 0x29, 0xCF, + 0x80, 0x58, 0x9C, 0xB9, 0xD7, 0xCD, 0x24, 0xDB, + 0xFE, 0x17, 0xD7, 0x6D, 0x6C, 0x5B, 0x9B, 0xF8, + 0x3B, 0x25, 0xF6, 0x85, 0x3D, 0xA9, 0x59, 0xF9, + 0x16, 0xC5, 0x1C, 0x4E, 0xF7, 0xA5, 0x39, 0x90, + 0x08, 0xD5, 0xA3, 0x14, 0xFD, 0x68, 0xAC, 0x03, + 0x3F, 0x21, 0x4D, 0x94, 0x27, 0xB0, 0x98, 0xD6, + 0xA9, 0x87, 0xF7, 0x2C, 0x17, 0xE9, 0x5A, 0x1B, + 0x09, 0x52, 0x31, 0xD4, 0x0F, 0x43, 0x21, 0x2D, + 0x73, 0x05, 0xB1, 0x9D, 0x6C, 0xBE, 0xF2, 0x65, + 0x91, 0xD4, 0x17, 0xAD, 0x5F, 0x2F, 0xC6, 0xAE, + 0xAC, 0xAF, 0x3B, 0x76, 0x5C, 0xCB, 0x3F, 0xAD, + 0x8A, 0x97, 0xEF, 0xD7, 0x44, 0x6D, 0x1B, 0xD0, + 0x25, 0x79, 0xD1, 0x77, 0x7A, 0x40, 0xF6, 0xBC, + 0x55, 0x66, 0x65, 0x8B, 0x3F, 0x9C, 0xCA, 0x8D, + 0x9A, 0xE2, 0xD0, 0x94, 0xF3, 0x59, 0x20, 0x3F, + 0xED, 0xFD, 0xC2, 0xBF, 0xA8, 0xCB, 0x0B, 0x93, + 0x85, 0x3C, 0xAB, 0x13, 0x82, 0x15, 0x4D, 0x04, + 0xD6, 0x00, 0x38, 0x63, 0x3F, 0x29, 0x82, 0xA4, + 0x2F, 0xDA, 0xB8, 0x0F, 0x8B, 0xA1, 0xCD, 0x61, + 0xA6, 0x7D, 0x86, 0xAC, 0xA9, 0xF7, 0x72, 0xC9, + 0x11, 0xCF, 0xDF, 0xC2, 0x96, 0xDC, 0xFC, 0x2B, + 0x4A, 0xFD, 0xF6, 0xEA, 0x68, 0xDA, 0xEE, 0x08, + 0x1A, 0x15, 0xFD, 0x41, 0xF3, 0x1B, 0xB8, 0xD7, + 0xDA, 0x9D, 0x55, 0x52, 0xCF, 0xC7, 0x17, 0x00, + 0xC7, 0x39, 0x53, 0xA8, 0x5B, 0x6E, 0x62, 0xE7, + 0x57, 0xBC, 0xF1, 0x29, 0x82, 0xD6, 0xED, 0xBE, + 0x1D, 0xEB, 0x79, 0x58, 0xF9, 0x35, 0x20, 0x90, + 0xDB, 0xDC, 0x49, 0x43, 0x97, 0xCA, 0x12, 0x4B, + 0xD1, 0x0E, 0x27, 0x22, 0x67, 0xBB, 0xD7, 0x74, + 0x43, 0xE9, 0x0B, 0xBD, 0x17, 0xAF, 0xCA, 0x18, + 0x9F, 0xCB, 0xFF, 0xB2, 0x66, 0x2C, 0x53, 0x92, + 0xD7, 0x4F, 0xE4, 0xCD, 0x41, 0x4B, 0x9A, 0xBC, + 0x01, 0x56, 0x28, 0x08, 0xF9, 0x97, 0x49, 0xF3, + 0x51, 0x3B, 0xD2, 0xBD, 0xF9, 0x0C, 0xEB, 0xC6, + 0xEB, 0x6E, 0xB1, 0x0D, 0x5E, 0x8C, 0x5C, 0x08, + 0x2B, 0x4E, 0x39, 0xDD, 0x0C, 0x21, 0x93, 0x71, + 0xDC, 0x24, 0x8B, 0xD8, 0x01, 0x3A, 0x14, 0xBF, + 0xC7, 0xEF, 0x13, 0x9B, 0x51, 0xFB, 0x9F, 0x05, + 0xCC, 0x6D, 0xF8, 0x2E, 0xA7, 0x52, 0x5D, 0xE8, + 0x4A, 0xE1, 0xF8, 0x39, 0xD1, 0x8D, 0x8B, 0x44, + 0xD5, 0x6E, 0x9D, 0x9F, 0xF4, 0xCE, 0x55, 0xB4, + 0xA6, 0x6D, 0x2E, 0x7B, 0x41, 0xD5, 0xE8, 0x89, + 0xC8, 0xB6, 0x6A, 0xF3, 0x53, 0x73, 0x9B, 0x5C, + 0x79, 0xBA, 0xEA, 0xED, 0xE1, 0x64, 0x92, 0x16, + 0x6D, 0xB7, 0x39, 0x9E, 0xD8, 0x9A, 0x15, 0x13, + 0xA0, 0xB8, 0xF2, 0xEA, 0x35, 0xFE, 0x17, 0x44, + 0x52, 0x05, 0x02, 0xB9, 0xF5, 0x16, 0xE9, 0x5F, + 0xEF, 0xF4, 0xC6, 0x4D, 0x52, 0x4B, 0x74, 0x80, + 0x9E, 0x41, 0x5B, 0x5C, 0x14, 0x8A, 0xBB, 0xCE, + 0xAC, 0xFC, 0xBD, 0x0B, 0x71, 0x12, 0xF5, 0xBB, + 0xFE, 0x15, 0x5A, 0x1D, 0x22, 0x1C, 0x2C, 0x7C, + 0x11, 0x1B, 0xED, 0x02, 0xAA, 0x49, 0xC4, 0xA0, + 0x71, 0x4F, 0x08, 0x16, 0x55, 0x13, 0xBE, 0xD7, + 0xE9, 0x37, 0x83, 0x70, 0x8A, 0x47, 0x05, 0xC9, + 0xBE, 0x69, 0xB6, 0x54, 0x23, 0xCC, 0x64, 0xDC, + 0x44, 0xC2, 0x2B, 0x06, 0xE2, 0xD4, 0x2A, 0x86, + 0xED, 0xC1, 0xEC, 0x33, 0xCB, 0x71, 0x6C, 0x11, + 0xBB, 0xAF, 0x3E, 0xF2, 0x26, 0xAF, 0x5C, 0x8E, + 0xE6, 0xC9, 0x2F, 0x54, 0xB9, 0x92, 0xF0, 0x75, + 0xB7, 0xE9, 0x0C, 0x69, 0xAC, 0x7F, 0x14, 0xF4, + 0xAE, 0xE7, 0x95, 0xD3, 0xAF, 0x10, 0x91, 0x6C, + 0x38, 0x44, 0x01, 0xA1, 0xD4, 0x7F, 0x31, 0x36, + 0x56, 0x32, 0x9E, 0x2C, 0x37, 0x05, 0x10, 0x2B, + 0xB9, 0x27, 0x6B, 0x88, 0x77, 0x1F, 0xC7, 0x8C, + 0x46, 0xE8, 0x30, 0x62, 0x26, 0x01, 0xFB, 0x53, + 0xEC, 0xCF, 0xEE, 0xD8, 0xB3, 0x01, 0xD5, 0x39, + 0xBA, 0x0E, 0x77, 0x8B, 0x4D, 0xA8, 0x06, 0xDD, + 0x1F, 0x5E, 0x97, 0x0B, 0x88, 0xFE, 0xDB, 0xBB, + 0x08, 0x9F, 0x2D, 0xFF, 0x2A, 0xE9, 0xDA, 0xB9, + 0x74, 0xE6, 0x99, 0xFB, 0xEE, 0xFB, 0xD0, 0x17, + 0x8C, 0x07, 0xF1, 0xAB, 0x07, 0xAC, 0x7B, 0xFD, + 0x13, 0x55, 0x0A, 0x3B, 0xC6, 0xF4, 0x11, 0xD9, + 0x14, 0xB7, 0x6C, 0x49, 0x48, 0x66, 0xC2, 0xFC, + 0xDE, 0x20, 0x19, 0xB5, 0xEC, 0x92, 0x87, 0x08, + 0xE2, 0xA9, 0x73, 0x2D, 0xE2, 0xBF, 0x53, 0x4D, + 0xF2, 0x53, 0x9D, 0x56, 0x5A, 0x05, 0xB2, 0x99, + 0x47, 0xE0, 0xCF, 0xEE, 0xAB, 0x54, 0x7A, 0x9B, + 0x43, 0x10, 0xEC, 0xF9, 0x17, 0x05, 0x08, 0x41, + 0x6C, 0x07, 0x6F, 0xA1, 0x38, 0xFA, 0x6C, 0xE9, + 0xA4, 0xCA, 0x48, 0xC0, 0xED, 0xF9, 0x44, 0xCE, + 0xB0, 0xC9, 0xC1, 0x65, 0xFE, 0xE0, 0x69, 0xC1, + 0xD8, 0xF6, 0x32, 0x0D, 0xAB, 0x1F, 0x46, 0xC9, + 0x53, 0x02, 0xA1, 0xDD, 0x74, 0xFD, 0x44, 0xA7, + 0x08, 0xA6, 0x40, 0xAD, 0xF3, 0x6B, 0xAC, 0xC4, + 0x33, 0x8B, 0xAA, 0xD9, 0x5C, 0x83, 0x2D, 0x6B, + 0x2F, 0x60, 0xC9, 0x38, 0xF6, 0x4D, 0xE2, 0xE6, + 0x47, 0xCE, 0x27, 0x18, 0xCE, 0x1E, 0x53, 0xBA, + 0x6E, 0x85, 0x70, 0xF3, 0xC7, 0x7D, 0x94, 0x26, + 0xB7, 0xB4, 0xAD, 0xE5, 0xC7, 0x98, 0x5A, 0x24, + 0x3C, 0xDF, 0x2A, 0x6F, 0xD3, 0x8B, 0x16, 0xF9, + 0xBA, 0x7D, 0x2E, 0x2B, 0x7C, 0xAF, 0xD5, 0x68, + 0xD9, 0x9A, 0x99, 0x36, 0xC6, 0x5D, 0x9D, 0x9F, + 0x5E, 0x6C, 0x17, 0xEE, 0x58, 0xC2, 0xC7, 0xDF, + 0x5B, 0x6E, 0x04, 0x0A, 0xC2, 0x4E, 0x61, 0xF5, + 0x1D, 0x3A, 0x88, 0xC7, 0x88, 0x5D, 0x43, 0xC5, + 0x70, 0xC9, 0xFA, 0x1F, 0x47, 0xA3, 0x75, 0xEC, + 0x22, 0xBC, 0xDA, 0x71, 0xE9, 0xAB, 0xCA, 0x43, + 0xAB, 0x82, 0xFC, 0x10, 0xAD, 0x69, 0x13, 0x2E, + 0xC5, 0xC4, 0x0B, 0x98, 0x30, 0x66, 0x15, 0xEF, + 0xC8, 0xBD, 0x59, 0x90, 0x44, 0x5B, 0xD2, 0x02, + 0xC6, 0x58, 0x31, 0xC3, 0x87, 0xEE, 0xD9, 0x8D, + 0xF0, 0x60, 0x38, 0x71, 0xFC, 0xF4, 0x83, 0x8C, + 0xC5, 0xB9, 0xAC, 0x94, 0x84, 0x22, 0xE8, 0x8C, + 0xB2, 0xAE, 0xF8, 0xCF, 0x5A, 0x63, 0x58, 0x8E, + 0xB1, 0x0D, 0x02, 0x00, 0x13, 0xAC, 0x9C, 0xAA, + 0x4D, 0x95, 0x32, 0x54, 0xF7, 0x7F, 0xAD, 0x0F, + 0x7D, 0xF5, 0x58, 0xE2, 0x32, 0xE4, 0xFA, 0xC7, + 0x39, 0x37, 0xA9, 0x59, 0x9F, 0x3C, 0xA2, 0x8D, + 0x39, 0x9C, 0x70, 0x22, 0x09, 0x2A, 0x7C, 0xF4, + 0xBF, 0x9A, 0x06, 0xCB, 0xDC, 0x12, 0xE9, 0x2C, + 0x14, 0x50, 0xAF, 0xAC, 0xC9, 0xFB, 0x54, 0xEB, + 0x1B, 0xA0, 0xFC, 0x63, 0xD1, 0x79, 0xF6, 0x6E, + 0xA2, 0xE1, 0x0E, 0xA3, 0xF5, 0xC5, 0x05, 0x53, + 0x24, 0x1C, 0x7C, 0xC5, 0x6C, 0x28, 0xAE, 0x3B, + 0xB9, 0xB5, 0x6E, 0xAA, 0x39, 0xFE, 0x00, 0xD0, + 0xD5, 0x7C, 0x81, 0x42, 0xEC, 0x4D, 0x5F, 0xF1, + 0x17, 0xA1, 0x43, 0x1C, 0x7C, 0xDF, 0x73, 0x64, + 0x1B, 0xD6, 0x2E, 0xB2, 0x12, 0x20, 0xEE, 0xD9, + 0x2A, 0xCA, 0x69, 0xD1, 0x83, 0x2B, 0x07, 0x05, + 0x69, 0xAE, 0x9A, 0xFF, 0x2E, 0x5C, 0x80, 0x3B, + 0xCC, 0x29, 0x1B, 0xED, 0xD9, 0xB5, 0xEF, 0x2C, + 0xD6, 0xCE, 0x42, 0x5A, 0x69, 0x8A, 0x21, 0x1F, + 0x7C, 0xC2, 0x96, 0xD2, 0x29, 0x38, 0xB6, 0x93, + 0x6E, 0x9B, 0xE9, 0xC5, 0x42, 0x31, 0x39, 0x4B, + 0xB0, 0x70, 0x16, 0x04, 0x10, 0x15, 0x2F, 0x10, + 0x48, 0xBF, 0x1B, 0x51, 0x1E, 0x06, 0x8B, 0xA7, + 0x92, 0x82, 0xA7, 0x05, 0xB4, 0xF6, 0xBE, 0x2B, + 0x14, 0xB5, 0x6B, 0xA4, 0xF9, 0x2D, 0xE1, 0x5A, + 0x3C, 0x7C, 0xF7, 0x89, 0x57, 0x2C, 0xED, 0x96, + 0x9C, 0x2A, 0xA4, 0xF3, 0xF6, 0x10, 0xF2, 0x5C, + 0xBB, 0xA3, 0x58, 0x04, 0xB0, 0xD7, 0x99, 0xFE, + 0x5F, 0x6D, 0x36, 0xDE, 0xB1, 0x74, 0xB9, 0x84, + 0x54, 0x0E, 0xAC, 0x54, 0x69, 0x1B, 0x22, 0xB5, + 0xC0, 0xE6, 0x1C, 0xC7, 0x70, 0x6B, 0xBD, 0x30, + 0x48, 0xCF, 0x9C, 0x71, 0x1F, 0xCD, 0xE2, 0xE2, + 0xFE, 0x9D, 0x16, 0xBF, 0xBD, 0x37, 0x67, 0x95, + 0x1C, 0xC8, 0x54, 0x91, 0x8B, 0x8A, 0x75, 0x9F, + 0xBC, 0x30, 0xBD, 0xEF, 0x8A, 0xF3, 0x9D, 0xD2, + 0x06, 0x83, 0xF6, 0xBC, 0xD0, 0xBB, 0x5C, 0xFB, + 0x1D, 0x4B, 0x8F, 0xAA, 0x1A, 0xE7, 0x1B, 0xAE, + 0xF4, 0xB9, 0x75, 0xA1, 0xAE, 0x66, 0xD3, 0x2F, + 0x19, 0x5D, 0x86, 0x07, 0x17, 0x0C, 0x05, 0x58, + 0x58, 0x37, 0x79, 0x40, 0xD7, 0x32, 0x81, 0x48, + 0x22, 0x55, 0xD1, 0xB6, 0x6D, 0x6F, 0x36, 0x4C, + 0x3B, 0x52, 0x25, 0x4B, 0xE9, 0x9C, 0x26, 0xAA, + 0x5B, 0x6D, 0xFA, 0xC0, 0x5C, 0x91, 0x10, 0x23, + 0x10, 0x9E, 0xFE, 0x70, 0xAF, 0xA1, 0x64, 0xB1, + 0x16, 0x13, 0x02, 0x5E, 0x0F, 0x12, 0xA9, 0x0D, + 0xE0, 0x1F, 0xD6, 0xB5, 0x4C, 0x7A, 0x7D, 0xD8, + 0x2A, 0xDF, 0x8A, 0x44, 0x69, 0x5C, 0xCF, 0xBA, + 0x87, 0x9B, 0x1D, 0xC9, 0x9D, 0x38, 0x23, 0x91, + 0xB0, 0xCC, 0x01, 0x18, 0x16, 0xDF, 0x53, 0xC9, + 0x0A, 0x70, 0xA0, 0x0D, 0x15, 0xD5, 0x45, 0x47, + 0xBA, 0xF9, 0x5F, 0xDC, 0x4B, 0xCD, 0x92, 0xFA, + 0x2E, 0xF5, 0xC3, 0x9D, 0x94, 0x9D, 0x4E, 0xA2, + 0x72, 0x4C, 0x80, 0x84, 0xEF, 0xAD, 0x76, 0xDD, + 0x31, 0x03, 0x2C, 0xB3, 0xC1, 0x19, 0x36, 0x0A, + 0x6E, 0xAA, 0x3A, 0xDF, 0x1D, 0xCE, 0x3E, 0x0C, + 0xD6, 0x50, 0xD6, 0xFF, 0xC7, 0x3E, 0xBE, 0xA3, + 0x4A, 0x53, 0xAB, 0xDF, 0xE7, 0xA1, 0x60, 0x4F, + 0xF7, 0x83, 0x07, 0xB8, 0x96, 0xD1, 0x09, 0xA4, + 0x0F, 0xE7, 0x9B, 0xCC, 0xB8, 0xF3, 0x8A, 0x62, + 0x2B, 0x0A, 0xFD, 0x49, 0x52, 0x38, 0xCF, 0x64, + 0xCC, 0xB1, 0x19, 0x03, 0x5C, 0xB6, 0xB1, 0x57, + 0xFE, 0x0F, 0x06, 0x6A, 0x6E, 0x61, 0x27, 0xCC, + 0x35, 0xCF, 0xFA, 0xA3, 0x87, 0xEE, 0xA4, 0x27, + 0x42, 0x52, 0x80, 0xC1, 0x2F, 0x7B, 0xA8, 0x86, + 0xFB, 0x7E, 0x3E, 0xF1, 0xB4, 0x53, 0xF7, 0x8C, + 0x56, 0xD4, 0x9C, 0x9D, 0x3E, 0xE2, 0xDA, 0xCB, + 0x86, 0xF3, 0x5D, 0xB3, 0xAE, 0x78, 0xEA, 0x29, + 0x6B, 0xD9, 0x94, 0x63, 0xB9, 0x88, 0xE8, 0x8B, + 0x55, 0xBB, 0x23, 0x9F, 0xFE, 0xEB, 0x46, 0x00, + 0x41, 0x8A, 0xA0, 0xC8, 0xC5, 0x6D, 0x24, 0x94, + 0x52, 0x8D, 0xEB, 0x27, 0x30, 0x45, 0x98, 0xCD, + 0x6E, 0x07, 0xBD, 0x3F, 0x2E, 0xA3, 0xA9, 0xE9, + 0x4F, 0x68, 0x96, 0xBA, 0x82, 0x28, 0x7A, 0x02, + 0xDA, 0xCD, 0x1F, 0x3F, 0xD8, 0x42, 0x2C, 0xC2, + 0x65, 0xEB, 0xEB, 0xE6, 0x58, 0x95, 0x03, 0x08, + 0x3D, 0x44, 0xC3, 0x75, 0xEF, 0x01, 0x93, 0x4E, + 0x08, 0xE8, 0x66, 0xD1, 0xB1, 0x5D, 0x52, 0x9B, + 0xAD, 0xE6, 0xE0, 0x7C, 0xA2, 0x14, 0xF4, 0x5F, + 0xC2, 0x29, 0xE1, 0x46, 0x74, 0xCC, 0xAA, 0xF8, + 0xA9, 0xE8, 0xE7, 0x5B, 0xD2, 0x3D, 0x48, 0x47, + 0xDB, 0x03, 0x35, 0xC6, 0xAF, 0x2F, 0x89, 0xFB, + 0x07, 0xD2, 0x4D, 0x08, 0xF1, 0x13, 0xF5, 0x13, + 0x61, 0x79, 0x44, 0xBD, 0x72, 0xBB, 0x0C, 0xD9, + 0x59, 0x78, 0x7E, 0xD6, 0x8E, 0x63, 0xF8, 0x8D, + 0x62, 0x59, 0xC0, 0xCB, 0x47, 0x9C, 0x7C, 0x48, + 0xD0, 0xDF, 0xB6, 0x43, 0x48, 0xBC, 0x39, 0xDF, + 0x3A, 0x4A, 0xAE, 0x2E, 0xD6, 0xE3, 0x10, 0x50, + 0x7D, 0x4F, 0x21, 0x6F, 0x0A, 0xB6, 0x77, 0xC2, + 0xDD, 0x06, 0x59, 0x90, 0x8C, 0xD8, 0x15, 0x2E, + 0xFB, 0x68, 0x20, 0xD5, 0x42, 0x88, 0x56, 0xCF, + 0x0E, 0x13, 0x4A, 0x12, 0x89, 0x7D, 0x03, 0xAE, + 0x68, 0xFE, 0xD9, 0x0B, 0x0A, 0xB3, 0xCD, 0x0D, + 0xB8, 0x44, 0x35, 0x5B, 0x1A, 0xF5, 0x6B, 0x10, + 0x8E, 0x02, 0xA9, 0xC1, 0x0C, 0x18, 0x32, 0x0B, + 0x5E, 0x93, 0x6C, 0x40, 0x21, 0xBB, 0x5F, 0xC5, + 0x04, 0xAB, 0xAD, 0xFE, 0x81, 0x3B, 0x66, 0x89, + 0x67, 0x15, 0x13, 0x91, 0x06, 0xCA, 0xCD, 0x6F, + 0xE3, 0x3C, 0x91, 0xDF, 0x89, 0x0A, 0x64, 0xF1, + 0x63, 0xA0, 0x82, 0x1B, 0x71, 0x9E, 0x38, 0x49, + 0x0C, 0x4A, 0xF4, 0xFF, 0x7A, 0xFF, 0x98, 0x21, + 0xE1, 0x2C, 0x45, 0x10, 0x9D, 0xA2, 0x62, 0xE7, + 0xA1, 0xD6, 0x5F, 0xE4, 0x85, 0xCD, 0xB1, 0x7B, + 0xB7, 0x58, 0x6B, 0xEF, 0xA2, 0x95, 0x98, 0xCC, + 0x60, 0x8A, 0xAA, 0xB8, 0x46, 0xB6, 0x47, 0x05, + 0xC8, 0xAE, 0x9F, 0xB7, 0xEA, 0x8A, 0xC5, 0x22, + 0x4A, 0x89, 0x4F, 0xFC, 0xE7, 0xE5, 0xA7, 0xEE, + 0x1B, 0xBF, 0xD5, 0xEE, 0x2B, 0xCC, 0xCD, 0xD7, + 0x79, 0xED, 0x9B, 0xB7, 0xB2, 0xD2, 0xF3, 0x85, + 0x9C, 0xF1, 0xE9, 0xC5, 0x20, 0x81, 0x7D, 0xAE, + 0xA4, 0x99, 0x02, 0x8F, 0xEF, 0x31, 0x0E, 0xFD, + 0x25, 0x3D, 0x97, 0xFA, 0x2F, 0x97, 0x01, 0x07, + 0x6A, 0x2A, 0xBE, 0x24, 0x1A, 0x3B, 0x74, 0x11, + 0xDB, 0x7F, 0xC9, 0xC6, 0xD7, 0xC6, 0xCC, 0xFC, + 0x37, 0x26, 0xAD, 0xD9, 0xBE, 0xE0, 0x5D, 0x17, + 0x6B, 0x25, 0x82, 0x3B, 0x34, 0xF3, 0x52, 0x03, + 0xA8, 0xF2, 0x81, 0x58, 0x44, 0xAB, 0x7D, 0xBD, + 0xD2, 0x7E, 0x19, 0xB4, 0x95, 0xC1, 0x21, 0xC7, + 0x7C, 0x7B, 0xDA, 0x54, 0x07, 0xCC, 0x84, 0xE2, + 0x29, 0xEC, 0xE5, 0x9E, 0xDC, 0x00, 0xCA, 0x4C, + 0x13, 0x7B, 0x30, 0x91, 0x91, 0x95, 0x0C, 0xDB, + 0x9B, 0x19, 0xB2, 0xFB, 0x8C, 0x79, 0x49, 0x87, + 0xFA, 0x56, 0x8F, 0xD1, 0xD4, 0xBD, 0x68, 0x24, + 0x76, 0x8C, 0x71, 0x1A, 0x6B, 0x93, 0xFF, 0x79, + 0x54, 0x74, 0xB0, 0xDD, 0x92, 0x4B, 0x5E, 0x90, + 0x32, 0xE7, 0x79, 0x6D, 0xB7, 0xED, 0x59, 0x1F, + 0xB6, 0xAE, 0x3B, 0x26, 0x2C, 0xB9, 0x50, 0x2C, + 0x03, 0xD6, 0x9F, 0xBF, 0x76, 0x77, 0x90, 0x4C, + 0xCC, 0x1D, 0xC0, 0x43, 0xBF, 0x20, 0xD9, 0x10, + 0xBA, 0x12, 0x7B, 0x8D, 0x11, 0xBD, 0xF5, 0x91, + 0x20, 0x2C, 0x7B, 0x81, 0xC3, 0x64, 0xF6, 0x95, + 0xB6, 0x55, 0x81, 0xAC, 0xDC, 0xF5, 0xBD, 0x7C, + 0xD3, 0x79, 0x80, 0x2B, 0xD8, 0x85, 0x70, 0x8B, + 0x74, 0xDF, 0x20, 0x66, 0xE6, 0x6D, 0x78, 0xAC, + 0x4D, 0x38, 0x02, 0xAF, 0x96, 0x37, 0x6A, 0x17, + 0x4F, 0x1E, 0xAC, 0xC4, 0x57, 0xB0, 0x86, 0x43, + 0xDB, 0xC8, 0x9B, 0xD8, 0x1A, 0xA7, 0x06, 0x9C, + 0xDF, 0xD2, 0x45, 0x3A, 0x23, 0x85, 0xFB, 0x6D, + 0x9B, 0xD2, 0x81, 0x36, 0x29, 0xC4, 0x75, 0x86, + 0x4F, 0x58, 0x8F, 0x18, 0x3D, 0xE1, 0x46, 0xFB, + 0x01, 0x14, 0xB7, 0xA5, 0x7E, 0x12, 0xE3, 0x27, + 0x05, 0x1A, 0xCF, 0x68, 0xC4, 0xBC, 0xE3, 0xF8, + 0x2A, 0x9C, 0xED, 0x41, 0x7A, 0x39, 0x09, 0x6B, + 0xD9, 0xCA, 0xC3, 0x25, 0x3A, 0x43, 0x1E, 0x4A, + 0xFC, 0x88, 0x1E, 0x50, 0x86, 0xFD, 0xDE, 0xF2, + 0xD0, 0x38, 0x07, 0xFB, 0x78, 0x88, 0x1E, 0x33, + 0x7E, 0x91, 0x12, 0xBE, 0x77, 0x85, 0xB2, 0xF6, + 0x53, 0x9A, 0x3B, 0x27, 0xA3, 0x51, 0xC1, 0x86, + 0xBC, 0x5B, 0x8A, 0x45, 0x00, 0x6E, 0xF0, 0x10, + 0x29, 0xC1, 0xF4, 0x12, 0xC4, 0x94, 0xFF, 0x27, + 0x9F, 0xC3, 0xDA, 0xF1, 0xBB, 0x64, 0xD7, 0xC6, + 0xC9, 0x52, 0xC4, 0xEB, 0x04, 0xB8, 0x37, 0x4F, + 0x9E, 0x14, 0x9C, 0x94, 0x84, 0xB5, 0xBD, 0xF1, + 0xB9, 0x29, 0xC1, 0x60, 0xEB, 0x3E, 0x43, 0x0C, + 0x2C, 0x17, 0xC8, 0xDA, 0x96, 0xB4, 0x93, 0xA5, + 0x38, 0x72, 0x9D, 0xEC, 0xDF, 0x2A, 0x7A, 0x7F, + 0x32, 0x3F, 0xC8, 0x47, 0xE2, 0xEB, 0x60, 0x82, + 0xFF, 0xF0, 0x48, 0x28, 0x85, 0xD8, 0x4D, 0x4A, + 0xB2, 0x8D, 0x50, 0xAB, 0x43, 0xE3, 0x8C, 0xA3, + 0xE2, 0x55, 0x24, 0x8A, 0xBF, 0xDA, 0x20, 0x8B, + 0x78, 0x8F, 0x04, 0x79, 0x54, 0xEF, 0x3C, 0x4B, + 0xFA, 0x1C, 0xD9, 0x4E, 0xD2, 0x5B, 0x54, 0xD4, + 0x66, 0x25, 0x4E, 0x1A, 0xB2, 0xC9, 0x63, 0xE2, + 0x31, 0xA4, 0x62, 0x3D, 0xC5, 0xA6, 0x72, 0x61, + 0x11, 0xD2, 0x6E, 0x46, 0xC8, 0x7A, 0xF3, 0xF4, + 0x2D, 0xF8, 0x21, 0xAB, 0xC9, 0x6A, 0x09, 0x64, + 0xC8, 0x94, 0x26, 0xDB, 0xB2, 0xEB, 0x9F, 0x45, + 0x58, 0x4B, 0xC0, 0x3A, 0xF1, 0x0E, 0x5C, 0x9D, + 0x12, 0xB3, 0x51, 0x3A, 0xF5, 0xDF, 0x92, 0xA9, + 0x13, 0xF3, 0x36, 0x1A, 0xB4, 0xAD, 0x7F, 0x65, + 0xA7, 0x76, 0x04, 0xA9, 0xFB, 0x6B, 0x8F, 0x3E, + 0x51, 0x20, 0xE6, 0xA4, 0x96, 0xEC, 0x58, 0x87, + 0xD4, 0x5C, 0xB7, 0xA3, 0x86, 0x48, 0x8C, 0xFC, + 0x9E, 0x09, 0x50, 0x04, 0x27, 0x6C, 0x0C, 0x77, + 0x60, 0x72, 0x0F, 0x96, 0x93, 0x51, 0xC0, 0x17, + 0x38, 0x68, 0xDA, 0x8F, 0x0D, 0xEB, 0x14, 0xF3, + 0x8C, 0x67, 0xBC, 0x6A, 0x5C, 0x04, 0xC8, 0xE5, + 0xD8, 0x54, 0x26, 0x46, 0xE0, 0x83, 0x0E, 0xFF, + 0xB0, 0x1E, 0xA2, 0x47, 0x70, 0xB1, 0xA7, 0xB4, + 0xBA, 0xF6, 0xD2, 0xC3, 0xAA, 0x57, 0x72, 0x64, + 0x22, 0xEE, 0xDF, 0xC7, 0xB0, 0x90, 0x5F, 0x0C, + 0xCD, 0x40, 0x77, 0xCC, 0x4A, 0x62, 0x69, 0xA8, + 0xE6, 0x2F, 0xC5, 0x70, 0x95, 0x4B, 0x3E, 0xB5, + 0xF2, 0x7D, 0x14, 0x74, 0xA6, 0xE6, 0xD3, 0xF2, + 0xB3, 0x38, 0xD9, 0xDC, 0x47, 0xD7, 0xF2, 0x7F, + 0xB8, 0x96, 0x1D, 0x81, 0x81, 0x37, 0xEC, 0x95, + 0xC2, 0xB5, 0xA4, 0xE5, 0xD6, 0xC8, 0x43, 0xF6, + 0x8A, 0xC6, 0xB2, 0x7C, 0xC3, 0x99, 0x75, 0x96, + 0x36, 0xBD, 0x52, 0xC0, 0xA7, 0xA0, 0xC8, 0xA4, + 0x6E, 0xB4, 0xCF, 0xF5, 0x97, 0xF3, 0x91, 0xDC, + 0xB8, 0xE9, 0x2A, 0x0A, 0x1B, 0x1F, 0xAF, 0xED, + 0x97, 0x79, 0x25, 0xEB, 0x40, 0x7E, 0x86, 0x84, + 0x93, 0x45, 0x7A, 0xF4, 0x59, 0xF6, 0xC4, 0x8F, + 0x1B, 0x7F, 0xAC, 0x04, 0x1C, 0x48, 0xF8, 0x38, + 0x5B, 0x6C, 0x1F, 0x69, 0xAA, 0x06, 0xC4, 0x89, + 0x50, 0xCE, 0x48, 0xAD, 0x60, 0xC8, 0x71, 0x93, + 0xF9, 0x8E, 0x04, 0xCB, 0xC7, 0xD2, 0x2C, 0x0B, + 0xC8, 0x48, 0x85, 0x44, 0x71, 0x93, 0x90, 0xDE, + 0xB4, 0x9C, 0x6A, 0xC6, 0x5F, 0x61, 0x07, 0xC5, + 0x53, 0x4B, 0x24, 0x31, 0x30, 0x4A, 0x7D, 0xDD, + 0xF5, 0x18, 0x7E, 0xE1, 0xAA, 0x10, 0xD7, 0x9D, + 0xA0, 0xB1, 0x81, 0x9D, 0xC0, 0x80, 0x37, 0x5A, + 0x70, 0x5F, 0x45, 0xBC, 0x1F, 0xCA, 0x53, 0xB8, + 0xDD, 0x60, 0xF6, 0xAE, 0x2A, 0xC0, 0x70, 0xF1, + 0x00, 0x0A, 0x6F, 0x92, 0xC6, 0xF5, 0x6B, 0x29, + 0x7D, 0xB3, 0xF9, 0x01, 0x8A, 0xBD, 0x8A, 0x92, + 0x33, 0x8D, 0xA2, 0x9C, 0x59, 0x0A, 0xDF, 0x45, + 0xC5, 0x85, 0xE9, 0x8A, 0x32, 0xBC, 0x22, 0x08, + 0x1E, 0x4D, 0xDD, 0x20, 0xD7, 0xAA, 0xBA, 0xEE, + 0x4C, 0xB9, 0xF0, 0xB1, 0xFB, 0xBE, 0x86, 0x81, + 0x1A, 0x0F, 0xBB, 0xD8, 0x7A, 0x65, 0x81, 0xD5, + 0xD3, 0xC5, 0x65, 0x14, 0x82, 0x5B, 0xAD, 0x69, + 0xA6, 0xB2, 0x8D, 0x8D, 0x31, 0xF7, 0x2B, 0xDA, + 0x30, 0x04, 0x3E, 0xF5, 0x56, 0x59, 0x60, 0x52, + 0x89, 0x00, 0x8E, 0x3D, 0x57, 0x2B, 0x7B, 0xB9, + 0xED, 0x0B, 0x0E, 0xC7, 0x17, 0x2E, 0xF4, 0xE1, + 0xA3, 0x14, 0xEF, 0xA5, 0xD4, 0x2E, 0x9C, 0xDD, + 0x6B, 0xD7, 0xA9, 0x94, 0x1F, 0xF8, 0xD7, 0x2B, + 0x50, 0x2B, 0x9E, 0x56, 0xC2, 0x14, 0xB5, 0x63, + 0xEE, 0x79, 0x38, 0xFA, 0xA7, 0x62, 0x6A, 0x32, + 0xC1, 0xFB, 0x8E, 0x82, 0xBD, 0xF7, 0xE4, 0x9F, + 0x3C, 0xA9, 0x25, 0x15, 0x64, 0xA9, 0xD9, 0x4D, + 0x27, 0x42, 0x4B, 0xA4, 0xD1, 0xE4, 0x5D, 0xD3, + 0xFB, 0x14, 0x62, 0xDD, 0xC1, 0xB3, 0xDF, 0x5C, + 0x75, 0x91, 0x0A, 0xC0, 0x03, 0x15, 0xD2, 0x4A, + 0xAB, 0x4C, 0x07, 0x25, 0xB1, 0x90, 0x32, 0x7A, + 0x11, 0xA5, 0xD2, 0xDD, 0x87, 0x1E, 0xC3, 0x53, + 0xA4, 0x0F, 0xC5, 0x12, 0xB7, 0x34, 0x33, 0xD4, + 0xD3, 0x48, 0x81, 0xAF, 0x7F, 0x3B, 0x5A, 0x5E, + 0x8C, 0x12, 0xC6, 0x20, 0xBA, 0x70, 0x84, 0x82, + 0x61, 0x14, 0x1F, 0x56, 0xE2, 0xE2, 0xA8, 0x43, + 0x86, 0x1D, 0x25, 0xCC, 0xF0, 0x32, 0x17, 0x6E, + 0xA7, 0x5D, 0xD9, 0x69, 0x44, 0x4D, 0xE0, 0x02, + 0x55, 0xBB, 0xA5, 0x00, 0x60, 0xD3, 0xAD, 0x46, + 0x06, 0xFF, 0xEA, 0x67, 0xE6, 0x07, 0x33, 0x13, + 0xB1, 0xDE, 0x02, 0x25, 0xBD, 0xBB, 0x38, 0x47, + 0xD2, 0x5E, 0x40, 0xD2, 0x41, 0x19, 0x28, 0x2D, + 0x75, 0x84, 0x69, 0xA1, 0x5C, 0xE5, 0xAF, 0x06, + 0xDC, 0x8A, 0xEE, 0x7E, 0x9C, 0xA4, 0xEB, 0xE5, + 0xFC, 0xF5, 0x39, 0xF5, 0xFE, 0x08, 0xA7, 0x4A, + 0x3F, 0x8E, 0x79, 0x2B, 0x87, 0xDD, 0xF0, 0xE2, + 0x1F, 0x90, 0x08, 0x58, 0xAF, 0x96, 0x50, 0x7D, + 0x35, 0x6F, 0x3F, 0x46, 0xB4, 0xF0, 0xD4, 0x02, + 0x7C, 0x3D, 0xA8, 0xDA, 0x59, 0x4F, 0x00, 0x5C, + 0xCA, 0xE2, 0xAF, 0x79, 0x41, 0xE3, 0xE2, 0x52, + 0x89, 0x9A, 0x92, 0x73, 0x40, 0xF9, 0xD1, 0xAB, + 0x23, 0x8E, 0xB6, 0xDE, 0x10, 0xDF, 0x9C, 0x10, + 0xDB, 0xE5, 0x05, 0x96, 0x83, 0xF9, 0x7E, 0x94, + 0xC8, 0xBB, 0x01, 0x1F, 0xBC, 0xF6, 0x57, 0xB0, + 0x4B, 0xAA, 0xC9, 0xC3, 0xCB, 0x73, 0x76, 0x82, + 0x05, 0xAB, 0xB7, 0x4B, 0x13, 0xC4, 0x5B, 0x3C, + 0xCD, 0x23, 0xA0, 0xE5, 0xA5, 0xAD, 0x64, 0x93, + 0x92, 0xDC, 0x77, 0x53, 0xDF, 0x00, 0x55, 0xA4, + 0xF1, 0x46, 0x3E, 0xED, 0xFA, 0x36, 0x4E, 0xC4, + 0xEB, 0x95, 0xF8, 0x1E, 0x7C, 0x1F, 0x22, 0xA7, + 0x34, 0xB2, 0x44, 0x87, 0xC9, 0xD0, 0x75, 0xCB, + 0x4B, 0x55, 0x3E, 0x77, 0x9A, 0x9C, 0xE2, 0x7A, + 0xB3, 0x8C, 0x4C, 0xA3, 0x04, 0xFB, 0xBD, 0xC8, + 0xFB, 0x70, 0x21, 0x61, 0xCC, 0x95, 0x86, 0xF1, + 0x8F, 0x27, 0x66, 0xC9, 0xCD, 0x4B, 0xE8, 0x0C, + 0xF8, 0xD6, 0xA9, 0x7A, 0x98, 0x87, 0x43, 0x19, + 0x69, 0xB1, 0xFB, 0xEC, 0x54, 0x4E, 0x6F, 0xB8, + 0x29, 0x30, 0x4E, 0xB4, 0xAD, 0x32, 0xB5, 0x40, + 0xF3, 0x6E, 0x2C, 0x47, 0x16, 0xBC, 0x35, 0x59, + 0x2F, 0x92, 0x0D, 0x3D, 0x62, 0x67, 0xF9, 0x07, + 0x22, 0xFB, 0xBD, 0x1A, 0xF2, 0x3A, 0x46, 0x4F, + 0x08, 0xDF, 0xEC, 0x96, 0x31, 0x80, 0xF2, 0x0C, + 0xC9, 0x1E, 0x8F, 0xD2, 0x64, 0xF8, 0xB2, 0xE0, + 0x4C, 0xFD, 0x3A, 0xE6, 0x5E, 0xA7, 0x90, 0x28, + 0xF0, 0x34, 0x67, 0x6B, 0xBA, 0x25, 0x73, 0xBF, + 0x49, 0x5A, 0x7E, 0xFC, 0x6E, 0xCF, 0x00, 0x36, + 0x68, 0x77, 0x44, 0x98, 0x5E, 0x7F, 0x3E, 0xF5, + 0xCC, 0x62, 0xFA, 0xB6, 0xEA, 0xFE, 0x07, 0x76, + 0xFE, 0xB2, 0x65, 0xFD, 0xEF, 0xE8, 0xD8, 0x52, + 0xD2, 0x9A, 0xAE, 0x14, 0x83, 0xDE, 0x11, 0xCA, + 0xAF, 0x9B, 0x22, 0xF4, 0x51, 0xEE, 0xBB, 0xF5, + 0x5E, 0xF1, 0x6C, 0x6E, 0xFB, 0xF9, 0xDB, 0xB1, + 0x01, 0x36, 0xD0, 0xE7, 0x8F, 0xEC, 0x9C, 0x1F, + 0xC5, 0x22, 0x8D, 0xA9, 0x4C, 0xF6, 0xEE, 0x8D, + 0x24, 0xE2, 0xFC, 0xD0, 0x1C, 0xC8, 0xAA, 0x8C, + 0x1E, 0x23, 0xBE, 0xC9, 0xBC, 0x8C, 0x8D, 0xF4, + 0x8F, 0x88, 0xBF, 0x86, 0x47, 0xE1, 0x43, 0x0B, + 0x68, 0x38, 0x1F, 0x64, 0x25, 0x88, 0x37, 0x23, + 0xEA, 0xCD, 0x95, 0xD7, 0xB4, 0xC6, 0x22, 0xDB, + 0x86, 0xA6, 0x34, 0x0B, 0x0F, 0x17, 0x64, 0x35, + 0xAB, 0x40, 0x7A, 0x50, 0x1B, 0xD9, 0x5E, 0x51, + 0xA2, 0x81, 0x8C, 0xEB, 0x7E, 0xFB, 0x13, 0xD1, + 0xD2, 0x28, 0x87, 0x9F, 0x63, 0xE4, 0x0A, 0xC3, + 0x4D, 0xBA, 0xE7, 0x5F, 0x32, 0xE1, 0xDC, 0x12, + 0x17, 0x1A, 0xC8, 0x6C, 0x15, 0x64, 0xC5, 0x0A, + 0xFE, 0x87, 0x83, 0x16, 0x58, 0x42, 0x26, 0x6C, + 0x65, 0xDC, 0xF9, 0x10, 0x1C, 0xA3, 0xC9, 0x80, + 0x68, 0xB2, 0xFB, 0xC7, 0x48, 0xB9, 0xD9, 0x91, + 0x79, 0xFC, 0x13, 0xE4, 0x43, 0xD7, 0x96, 0xE5, + 0x00, 0x30, 0xFF, 0xCC, 0x34, 0x3E, 0x30, 0x6C, + 0x84, 0x6A, 0xF6, 0xDD, 0x65, 0x59, 0xBE, 0x8D, + 0xC1, 0xF4, 0x1F, 0xD3, 0x34, 0x49, 0x77, 0x0F, + 0xDA, 0x92, 0xA6, 0x08, 0x12, 0x15, 0x6E, 0x41, + 0xE5, 0x38, 0x6A, 0x1B, 0x8B, 0xD2, 0x41, 0x2F, + 0x7D, 0xAE, 0x5E, 0xE1, 0x00, 0xB9, 0x0B, 0x9F, + 0x1B, 0x0F, 0x1D, 0xB5, 0x98, 0x4C, 0x28, 0xBC, + 0x42, 0x63, 0x69, 0x49, 0xB6, 0xD4, 0xF9, 0x34, + 0x98, 0x54, 0xFE, 0x81, 0xC6, 0x56, 0x4B, 0x4B, + 0xB2, 0x23, 0x80, 0x6D, 0x5D, 0x17, 0x09, 0x69, + 0x40, 0x28, 0x3B, 0x86, 0x43, 0xDE, 0x3C, 0x44, + 0x38, 0xBD, 0xC3, 0x2D, 0x58, 0xDF, 0xF6, 0x37, + 0xB4, 0x62, 0x48, 0xAC, 0x61, 0xA5, 0x4D, 0xFA, + 0x10, 0xEA, 0x9F, 0xA4, 0x59, 0x08, 0x9C, 0x3B, + 0xF6, 0x39, 0xDE, 0x61, 0x73, 0x73, 0xE3, 0xB3, + 0x3D, 0x1E, 0x36, 0xE0, 0xC0, 0x6C, 0xA6, 0x6F, + 0xEE, 0x24, 0x39, 0x93, 0x3E, 0xB3, 0x6E, 0x0C, + 0x14, 0x8E, 0x83, 0xCF, 0x65, 0x4F, 0x21, 0xCB, + 0x0B, 0x8E, 0xB7, 0xDC, 0x80, 0x2D, 0x50, 0x5D, + 0x7C, 0x8E, 0xC5, 0x1F, 0xA1, 0x3D, 0x28, 0x05, + 0xE3, 0x20, 0x2C, 0x64, 0x1B, 0xD0, 0x51, 0x52, + 0x32, 0x0D, 0xC3, 0x13, 0x83, 0x62, 0x5A, 0xB2, + 0x47, 0xBB, 0x8B, 0xB7, 0x29, 0x0F, 0xFB, 0x7A, + 0xF4, 0xA7, 0xEC, 0x0D, 0xA6, 0xAB, 0x3B, 0x39, + 0x5F, 0x46, 0xFB, 0x98, 0xFA, 0x77, 0x50, 0x23, + 0x3C, 0xBB, 0xED, 0x32, 0x78, 0x1B, 0x46, 0xF1, + 0xF7, 0x6F, 0x26, 0x4E, 0x40, 0x1C, 0xB3, 0x52, + 0xC4, 0x37, 0x35, 0xA2, 0x63, 0x39, 0x2B, 0x9B, + 0xD1, 0x84, 0x46, 0x9A, 0x7A, 0xD0, 0x24, 0x0E, + 0xED, 0xE8, 0xD1, 0xDE, 0xC4, 0xDF, 0xFA, 0xE7, + 0xC7, 0x36, 0xDB, 0x3F, 0xCC, 0x2F, 0x3B, 0xDB, + 0xD5, 0xA0, 0x92, 0x98, 0x85, 0x25, 0x09, 0xF7, + 0xA4, 0x7E, 0x5A, 0x93, 0xC7, 0xD1, 0xC4, 0x88, + 0xD4, 0x64, 0x07, 0xB1, 0x0E, 0x7B, 0x61, 0x92, + 0x45, 0x25, 0xD1, 0x9E, 0x4A, 0xFE, 0x52, 0xE2, + 0x1C, 0x0F, 0xAA, 0xD1, 0x27, 0x18, 0x00, 0x09, + 0x40, 0x66, 0xDC, 0xC7, 0x62, 0x24, 0xE8, 0x2B, + 0xC3, 0xC0, 0xA1, 0x0E, 0x01, 0x55, 0x86, 0x29, + 0x14, 0x90, 0x61, 0x02, 0xA5, 0x41, 0xF2, 0x92, + 0x93, 0x0B, 0x12, 0x36, 0xAE, 0x14, 0x75, 0x17, + 0xBA, 0x2E, 0x2B, 0x92, 0x7C, 0xB4, 0x6C, 0x61, + 0x4B, 0x2D, 0xF6, 0x4B, 0xCB, 0x41, 0xF5, 0x66, + 0xE4, 0x9D, 0xC0, 0x31, 0xB8, 0x2C, 0x39, 0x5E, + 0x65, 0xED, 0xA5, 0x52, 0xB3, 0x45, 0x80, 0xE8, + 0xD6, 0x2C, 0x88, 0x21, 0xE5, 0xD0, 0xD7, 0x06, + 0x91, 0xE9, 0x60, 0xBB, 0xF2, 0xE8, 0xDC, 0x85, + 0xE1, 0xDD, 0x37, 0x3F, 0x69, 0x91, 0xAC, 0xE5, + 0x9F, 0x73, 0x39, 0x6D, 0xEB, 0x12, 0x73, 0x9D, + 0xE1, 0x95, 0x33, 0x5E, 0x3C, 0x91, 0x45, 0x3C, + 0x35, 0xB7, 0xBD, 0xCC, 0x9C, 0x35, 0xA8, 0x42, + 0xB2, 0x5C, 0x5B, 0x1E, 0xB0, 0xC2, 0x0D, 0x5E, + 0x6B, 0x01, 0x20, 0x85, 0xEF, 0x89, 0xFF, 0x8F, + 0xEF, 0x3B, 0xC8, 0x53, 0x6B, 0x3F, 0x5C, 0x9C, + 0x52, 0x8A, 0x29, 0xCC, 0x81, 0xC8, 0xB4, 0x0A, + 0xDC, 0xD9, 0xCF, 0x44, 0xDB, 0x51, 0xF3, 0x34, + 0xC6, 0x3E, 0xB2, 0x88, 0x13, 0xEF, 0x3A, 0xE6, + 0x6B, 0xF4, 0xE2, 0x45, 0x3F, 0x36, 0x22, 0xCD, + 0x32, 0x69, 0xBD, 0xAC, 0xAF, 0xE7, 0x43, 0xD9, + 0xA0, 0x7C, 0xEC, 0xF4, 0x9C, 0x49, 0x94, 0xCD, + 0xDD, 0x8F, 0x9C, 0xE0, 0x95, 0xC7, 0xA0, 0xF8, + 0x41, 0x8B, 0x56, 0x5C, 0x93, 0x87, 0xFC, 0xE5, + 0x65, 0xD1, 0x57, 0xD4, 0xB0, 0x23, 0xE0, 0xC2, + 0x07, 0xD2, 0x54, 0x4C, 0x4B, 0xD1, 0x51, 0x7B, + 0x35, 0x98, 0x8D, 0x62, 0xD0, 0x71, 0xA6, 0x99, + 0xA2, 0x4F, 0x11, 0x4D, 0xE4, 0xDB, 0xC8, 0x5A, + 0x81, 0xC1, 0x40, 0x22, 0x1D, 0xE1, 0x06, 0x44, + 0xB7, 0x5E, 0xFC, 0xDB, 0x6A, 0x80, 0x70, 0x36, + 0x81, 0xD6, 0x3F, 0x99, 0x79, 0x74, 0x2F, 0xE2, + 0x6D, 0x51, 0xB6, 0x4D, 0x76, 0xA3, 0x73, 0x57, + 0x19, 0x94, 0xA9, 0x39, 0x01, 0xD9, 0xC0, 0x21, + 0x8E, 0x11, 0x7F, 0xC4, 0x68, 0xAF, 0x04, 0xC4, + 0x9E, 0x3D, 0x30, 0xD7, 0x1D, 0x6B, 0xC0, 0x76, + 0x0B, 0x2B, 0x48, 0x42, 0x84, 0x27, 0xE6, 0x1A, + 0xC0, 0x46, 0xDD, 0x98, 0x4D, 0x83, 0x05, 0x4A, + 0x55, 0xCC, 0xE6, 0xA4, 0x69, 0x1C, 0x92, 0xFA, + 0x73, 0xB8, 0x68, 0xBA, 0x30, 0x55, 0xD0, 0xDA, + 0x2B, 0xF5, 0x6C, 0xD2, 0x67, 0x64, 0xB1, 0x92, + 0x92, 0xA1, 0x83, 0x57, 0x15, 0xBF, 0x76, 0x9F, + 0x90, 0xA6, 0x34, 0x09, 0x2F, 0x6D, 0x35, 0x12, + 0xC6, 0x73, 0x3A, 0x49, 0xC4, 0x1D, 0x76, 0x01, + 0xFC, 0xC6, 0xEA, 0xE0, 0x0A, 0xE4, 0xCE, 0x6D, + 0x92, 0x5D, 0x1C, 0x24, 0xAE, 0x16, 0x47, 0xA3, + 0x65, 0xE2, 0x81, 0x9F, 0xE5, 0xEB, 0xE1, 0xA7, + 0x0B, 0xBA, 0xF5, 0x96, 0xEA, 0x98, 0xE6, 0xF5, + 0xB4, 0x64, 0x8D, 0xE5, 0x3F, 0xF6, 0xBF, 0xC4, + 0x4F, 0x65, 0x8D, 0x02, 0xA0, 0xCE, 0xE3, 0x96, + 0x14, 0xAE, 0x3D, 0x9E, 0x89, 0xEA, 0x5D, 0x07, + 0xB9, 0x95, 0x98, 0x1A, 0x55, 0xAF, 0xF3, 0xEB, + 0xDC, 0x67, 0xB8, 0xCE, 0x37, 0xBD, 0x2F, 0x11, + 0xD7, 0xB8, 0xF7, 0x45, 0xB2, 0xF7, 0x30, 0x9C, + 0x1D, 0x49, 0x69, 0xFA, 0xBA, 0xF9, 0x8C, 0x04, + 0x99, 0xDD, 0x29, 0xFA, 0x1A, 0x90, 0xD7, 0x90, + 0x2F, 0xD6, 0xBD, 0x05, 0x7F, 0xD5, 0x53, 0xD6, + 0x62, 0xCA, 0xEF, 0x40, 0xA4, 0x78, 0xB1, 0x00, + 0x6B, 0xA6, 0x64, 0x54, 0x93, 0xC3, 0xD2, 0xD1, + 0x12, 0x9D, 0x11, 0x85, 0xD3, 0x81, 0xB3, 0x93, + 0x57, 0xC4, 0x9B, 0xE4, 0x2D, 0x30, 0x5E, 0x1F, + 0xA4, 0x1F, 0x8E, 0xE2, 0x31, 0x72, 0xD2, 0x0B, + 0x68, 0x27, 0x89, 0xE9, 0x7C, 0x11, 0x7A, 0x10, + 0x26, 0x44, 0x01, 0xA0, 0x68, 0x32, 0xEB, 0x00, + 0xE5, 0x7A, 0x17, 0x74, 0xDF, 0x5F, 0x20, 0xCA, + 0x26, 0x43, 0x3E, 0x44, 0x8C, 0xD8, 0xA1, 0xCE, + 0xA2, 0xB7, 0xBB, 0x87, 0xBA, 0x5D, 0xD2, 0x11, + 0x4A, 0xD3, 0x98, 0x1D, 0x25, 0x11, 0x74, 0xA3, + 0x49, 0x40, 0x1D, 0x7D, 0x55, 0x0E, 0xAF, 0x56, + 0x42, 0x77, 0x6C, 0x04, 0x3C, 0x84, 0x61, 0xC6, + 0x28, 0x53, 0x14, 0x8A, 0x86, 0xD6, 0xD2, 0x48, + 0x36, 0xB2, 0xDB, 0x99, 0x72, 0x6F, 0x2F, 0xB8, + 0x51, 0x70, 0xD1, 0x8D, 0x2B, 0x58, 0x74, 0x8A, + 0xA2, 0x1F, 0x6B, 0x2D, 0xBB, 0xA5, 0xFB, 0x21, + 0x11, 0x26, 0xBB, 0xE5, 0x6B, 0xAE, 0x59, 0xDA, + 0xA2, 0xF6, 0xA9, 0x3C, 0x1A, 0x78, 0x95, 0xF9, + 0x9D, 0xFD, 0x55, 0x75, 0x7C, 0xA3, 0xAF, 0x10, + 0x97, 0x0B, 0xBA, 0x4A, 0xC2, 0xE9, 0xF5, 0x3C, + 0x32, 0x0D, 0x78, 0xC9, 0x53, 0xC5, 0x7D, 0x63, + 0x52, 0xA2, 0xA9, 0xE8, 0x64, 0xCC, 0x85, 0xF2, + 0x0E, 0xBE, 0xA9, 0x2A, 0x79, 0x43, 0x55, 0x0A, + 0xC5, 0x11, 0xF5, 0x53, 0x0C, 0x87, 0x48, 0x85, + 0x9A, 0xCF, 0x67, 0xF1, 0xD9, 0x02, 0xC2, 0x45, + 0x4E, 0x72, 0x0B, 0x6F, 0x7D, 0xFE, 0xEB, 0xEA, + 0x32, 0xC7, 0xD9, 0x2F, 0x3D, 0x7E, 0xD9, 0xC5, + 0x40, 0x73, 0xE4, 0x7F, 0x6E, 0x0A, 0x0D, 0x92, + 0xDB, 0x2A, 0x2B, 0x0B, 0x10, 0x0F, 0x44, 0x56, + 0x96, 0x1B, 0x9C, 0xCF, 0x83, 0xF9, 0x0A, 0xB0, + 0xE6, 0x7A, 0xD4, 0xC1, 0x36, 0x3F, 0xE0, 0x17, + 0x4E, 0x82, 0x3E, 0x08, 0xB7, 0xDC, 0xB7, 0x50, + 0x75, 0x47, 0x5A, 0x02, 0x02, 0xB2, 0xC0, 0x82, + 0x8E, 0xD9, 0x12, 0x14, 0x92, 0x8A, 0x9F, 0x6F, + 0x36, 0xF4, 0xAD, 0x12, 0x21, 0xDF, 0xE2, 0x79, + 0xFA, 0xBF, 0xCD, 0x1D, 0xD3, 0x9E, 0x02, 0x8C, + 0xCE, 0x81, 0x27, 0x04, 0xE0, 0xE2, 0x2E, 0x39, + 0x16, 0x5D, 0x0D, 0x4E, 0x11, 0x4E, 0xBF, 0x6D, + 0x0C, 0x1C, 0xF6, 0x1E, 0x58, 0xD5, 0xEC, 0xDC, + 0x78, 0xD8, 0xC8, 0x95, 0x62, 0x95, 0xF8, 0x7A, + 0xEE, 0x59, 0x55, 0x82, 0xBB, 0xC0, 0x8E, 0xDC, + 0x55, 0x6F, 0xF0, 0x8D, 0xEF, 0xC7, 0xE9, 0x23, + 0x42, 0x8E, 0x97, 0x7B, 0xBD, 0x4B, 0x40, 0x6D, + 0x18, 0x74, 0x55, 0xB3, 0x35, 0xCC, 0x04, 0x1C, + 0xA3, 0xC1, 0xCB, 0x29, 0xFF, 0x4D, 0xA0, 0x73, + 0x3A, 0xFA, 0x5B, 0xC2, 0x17, 0x72, 0x2C, 0x8C, + 0xEA, 0x2D, 0xB5, 0x9A, 0x7D, 0x89, 0x99, 0x99, + 0x05, 0x72, 0x6B, 0x93, 0xAF, 0x5F, 0xE9, 0xAD, + 0xCE, 0x14, 0x55, 0xF5, 0x3C, 0xD9, 0x90, 0x54, + 0xAD, 0x24, 0x34, 0x29, 0xDC, 0xB2, 0xAB, 0x87, + 0x88, 0x65, 0x11, 0x5E, 0xD9, 0xA7, 0x7C, 0xFA, + 0x88, 0x0B, 0x00, 0x1C, 0x1C, 0x11, 0xD2, 0x28, + 0x1F, 0xDA, 0xD2, 0x81, 0xD3, 0x8B, 0xF9, 0xC0, + 0x2C, 0xF9, 0xEE, 0xDC, 0xE5, 0xEC, 0x95, 0x80, + 0x12, 0x02, 0xDC, 0x04, 0xB0, 0xA6, 0x74, 0x7E, + 0x01, 0x09, 0xDE, 0xFE, 0xA5, 0x02, 0xD6, 0x5D, + 0xC0, 0xA2, 0x59, 0x8A, 0x09, 0xA1, 0x19, 0x0A, + 0xA2, 0x93, 0xB1, 0xDA, 0x3F, 0x63, 0x21, 0x3A, + 0x97, 0x02, 0xC2, 0xF6, 0xC9, 0x3C, 0xEE, 0xD9, + 0xEA, 0x7D, 0x61, 0x1A, 0x1E, 0x4F, 0x05, 0xB0, + 0x13, 0xFD, 0xF3, 0x58, 0xB5, 0x33, 0x7C, 0xE8, + 0x81, 0xF4, 0xBE, 0x08, 0xAD, 0x01, 0x10, 0x3A, + 0xD9, 0x4B, 0xFE, 0x95, 0xB2, 0x86, 0x69, 0x32, + 0x21, 0x52, 0x59, 0x8B, 0x99, 0x12, 0xB6, 0xD8, + 0x06, 0x79, 0x6F, 0x42, 0x61, 0xEA, 0x48, 0xE7, + 0x00, 0xD4, 0xE0, 0xFE, 0x7B, 0x0E, 0xE1, 0xD9, + 0x09, 0xD1, 0xDF, 0xB6, 0x5F, 0x3A, 0x81, 0x3A, + 0x7D, 0x49, 0x86, 0x65, 0x6B, 0x33, 0xE3, 0xAD, + 0x4A, 0xD0, 0xE7, 0x67, 0xCA, 0xAF, 0x48, 0x54, + 0xAD, 0xEE, 0xAC, 0xC4, 0xB4, 0x0C, 0xE1, 0x87, + 0xD9, 0xB5, 0xE6, 0x90, 0xAD, 0x55, 0x5F, 0xB1, + 0x7A, 0xFA, 0x4B, 0x28, 0xEE, 0x99, 0xE2, 0x35, + 0x73, 0x67, 0xC2, 0x3A, 0x70, 0x7F, 0x6B, 0x5E, + 0x77, 0x34, 0x0B, 0x26, 0x46, 0x63, 0x55, 0xEE, + 0xAF, 0x5D, 0xEA, 0xCB, 0x73, 0xE8, 0xE3, 0xFE, + 0x60, 0xA5, 0xC0, 0xBE, 0xAD, 0x7C, 0xE9, 0x2A, + 0x3D, 0xCB, 0xFE, 0x99, 0x65, 0xC8, 0x61, 0x5D, + 0xE9, 0xBD, 0xCD, 0x44, 0x5E, 0x31, 0x7D, 0xC5, + 0x59, 0x68, 0xDC, 0xCA, 0xAF, 0x66, 0xE1, 0x42, + 0x63, 0x96, 0x43, 0x1E, 0x33, 0xDB, 0x20, 0x77, + 0x1A, 0x4D, 0x04, 0x1D, 0xAB, 0x93, 0x91, 0xE6, + 0x71, 0x32, 0x4E, 0xB7, 0x82, 0x22, 0xB8, 0x1A, + 0x7E, 0x82, 0xFF, 0xB6, 0x64, 0x62, 0xC5, 0x5E, + 0x90, 0x75, 0x18, 0xF2, 0xE9, 0xF0, 0x26, 0xD0, + 0x8E, 0x7C, 0x35, 0x8D, 0xB1, 0x8A, 0xFD, 0x65, + 0xC5, 0x80, 0x36, 0x2B, 0x13, 0xC3, 0x28, 0xB1, + 0xE0, 0x46, 0x43, 0x78, 0x9E, 0xD0, 0xCC, 0x4E, + 0x9C, 0xD0, 0xBE, 0xDC, 0x34, 0x46, 0x98, 0x00, + 0x7C, 0x64, 0xF4, 0x45, 0xE7, 0xD2, 0x89, 0x2D, + 0x75, 0x86, 0x4A, 0xCD, 0x59, 0x88, 0xB8, 0x1D, + 0x5B, 0xCD, 0xFF, 0x94, 0x12, 0x20, 0xE6, 0xD4, + 0x75, 0x81, 0xA3, 0xA2, 0x7D, 0x58, 0x07, 0x74, + 0xEE, 0x35, 0x1A, 0x6C, 0xDA, 0x92, 0xB4, 0x9E, + 0x4A, 0x11, 0xB9, 0x70, 0x8D, 0x26, 0xC9, 0x3E, + 0xC7, 0xE5, 0x13, 0xDD, 0x9B, 0x85, 0x2C, 0xF9, + 0x81, 0x7A, 0xD2, 0xAB, 0xBC, 0xB2, 0x39, 0xFD, + 0x1A, 0xF4, 0x85, 0x33, 0x09, 0x46, 0xE7, 0xF1, + 0x65, 0xFB, 0x23, 0x8B, 0x54, 0x0F, 0xCB, 0x2C, + 0x72, 0x6C, 0xCF, 0xA5, 0xA0, 0xA2, 0xFD, 0x76, + 0xF1, 0x07, 0x5B, 0x77, 0x78, 0x2A, 0xC5, 0xD1, + 0x90, 0xF6, 0xBD, 0x48, 0x93, 0x21, 0x21, 0x83, + 0x72, 0xAC, 0x7F, 0xE6, 0x91, 0x40, 0x45, 0xA4, + 0x17, 0xE3, 0x05, 0xE2, 0xF2, 0x50, 0xA0, 0xEE, + 0xC4, 0x2A, 0xD6, 0xF0, 0x28, 0xBC, 0xEB, 0xF4, + 0xFD, 0xD5, 0xA7, 0x87, 0xBB, 0xD1, 0xF2, 0xFA, + 0x00, 0x6D, 0x47, 0x0B, 0x72, 0x15, 0x14, 0x4C, + 0x68, 0x6D, 0x82, 0x99, 0x42, 0xD3, 0x63, 0xCB, + 0xDB, 0xF5, 0xDE, 0x88, 0x8C, 0x73, 0xEE, 0x37, + 0xFB, 0x4D, 0xD5, 0xF0, 0xCD, 0x6B, 0xDE, 0x1F, + 0xAD, 0x6C, 0x54, 0xEA, 0xF4, 0xD6, 0xFD, 0x70, + 0x2E, 0x1B, 0x28, 0x45, 0xD7, 0x4F, 0x12, 0x41, + 0xDD, 0xE6, 0x47, 0x11, 0x72, 0x04, 0x65, 0x8D, + 0xA6, 0xAB, 0x7B, 0xAC, 0x8D, 0x5F, 0x2C, 0x2A, + 0x39, 0xA2, 0xB1, 0x2C, 0x90, 0xBB, 0x5E, 0x99, + 0xE4, 0xD7, 0x5D, 0x0A, 0xDE, 0x8B, 0x88, 0xB1, + 0x21, 0xF2, 0xF9, 0x6C, 0x3E, 0xA7, 0xA7, 0x67, + 0x86, 0xEE, 0x68, 0x5E, 0xA2, 0x72, 0x2A, 0x57, + 0xFC, 0x2A, 0xE2, 0x81, 0xFF, 0x54, 0xDC, 0x2D, + 0x66, 0x2C, 0xD7, 0x3B, 0x56, 0xCA, 0x5B, 0x1D, + 0xE5, 0x06, 0x16, 0x01, 0x5F, 0x38, 0x33, 0xC2, + 0xAB, 0xE2, 0xD8, 0xFE, 0xE5, 0x46, 0x25, 0x2A, + 0xA4, 0x99, 0xB0, 0xB6, 0xA9, 0xB4, 0x3E, 0xD0, + 0x62, 0x51, 0x2E, 0xF2, 0xC3, 0xAE, 0x66, 0x84, + 0x55, 0x07, 0x57, 0x81, 0x50, 0x07, 0x88, 0xD1, + 0xEB, 0xD5, 0x9B, 0x33, 0xD9, 0x7B, 0x6B, 0xEC, + 0x10, 0xCB, 0x36, 0x19, 0x83, 0x9B, 0x05, 0x11, + 0xAD, 0x34, 0xC3, 0xFA, 0x44, 0xE2, 0xC2, 0x1A, + 0x3E, 0x5A, 0x5C, 0x7C, 0x78, 0xDC, 0xA9, 0x57, + 0x82, 0x60, 0x6D, 0x7D, 0x3E, 0x1E, 0xB2, 0x19, + 0x36, 0xDF, 0xFB, 0x34, 0x16, 0x3B, 0xAE, 0x2D, + 0x63, 0x6B, 0x40, 0x55, 0xED, 0xC3, 0x3B, 0x4B, + 0x14, 0x22, 0x3E, 0x40, 0xE6, 0x22, 0xB1, 0xA4, + 0xDF, 0x9D, 0x67, 0xD5, 0x73, 0x90, 0x76, 0x99, + 0x88, 0xDA, 0x96, 0x0B, 0x39, 0x56, 0x10, 0x87, + 0x5E, 0x1E, 0xDC, 0x8D, 0xB9, 0xFA, 0x67, 0x29, + 0x96, 0x16, 0x24, 0x9B, 0x5B, 0x41, 0x75, 0x21, + 0xFF, 0x26, 0x58, 0x64, 0x3D, 0xC5, 0x74, 0x8D, + 0xD2, 0x1C, 0x4A, 0xCB, 0x58, 0x2B, 0x85, 0xED, + 0x53, 0x4A, 0xA3, 0x1A, 0x65, 0x31, 0xA4, 0x30, + 0x29, 0x7C, 0x16, 0xB4, 0x0C, 0xE9, 0xF0, 0x7B, + 0x3D, 0xAE, 0x5E, 0xB3, 0x44, 0xB5, 0x1E, 0xFB, + 0x7C, 0xBE, 0x3B, 0xFC, 0x09, 0x8A, 0xB2, 0x38, + 0x00, 0xA5, 0x9C, 0x24, 0x85, 0xF1, 0x88, 0xB0, + 0xBB, 0x0A, 0xF2, 0xA3, 0xB8, 0x08, 0x27, 0xB6, + 0x59, 0xDF, 0x48, 0xAF, 0x58, 0xF6, 0x58, 0x15, + 0xDE, 0xD8, 0x71, 0xE4, 0x9C, 0xC8, 0xB1, 0x9B, + 0xC0, 0x26, 0xFB, 0x7B, 0xD1, 0xCD, 0xD1, 0x83, + 0x91, 0xEC, 0x96, 0x23, 0x49, 0x8D, 0xA5, 0x2B, + 0x30, 0x2A, 0x50, 0x46, 0xF7, 0x73, 0x2E, 0x96, + 0x11, 0x92, 0x95, 0xF7, 0x19, 0x13, 0xBF, 0x27, + 0xFA, 0xFB, 0x0E, 0x2E, 0x7A, 0x39, 0x41, 0xB4, + 0x4A, 0x9F, 0xD7, 0x37, 0xF1, 0xC7, 0x71, 0x70, + 0x9E, 0xD8, 0x41, 0x7C, 0x8D, 0x78, 0x7D, 0xCF, + 0x87, 0xC2, 0x89, 0x95, 0xBD, 0x6B, 0x1C, 0x4A, + 0x26, 0xC5, 0x9A, 0xB1, 0xCD, 0x0A, 0x58, 0xB6, + 0xDD, 0x28, 0x88, 0x2C, 0x8B, 0xD9, 0xCD, 0x9E, + 0x9E, 0x8A, 0xDE, 0x57, 0xAE, 0xAB, 0x23, 0xA0, + 0x17, 0xEB, 0x9C, 0x81, 0xAC, 0x13, 0xF7, 0x10, + 0x85, 0xC6, 0x04, 0xC1, 0x76, 0x6D, 0x9B, 0xEF, + 0xA8, 0xD3, 0xF2, 0xE7, 0xB5, 0x49, 0x6D, 0x4E, + 0x55, 0xA8, 0x71, 0x34, 0xD7, 0x9D, 0x40, 0xA4, + 0x22, 0x0D, 0x21, 0xCE, 0xD2, 0x20, 0x97, 0x1A, + 0xCC, 0x90, 0x2C, 0x25, 0xD5, 0x14, 0x56, 0x07, + 0xD2, 0xF9, 0xFD, 0xFA, 0x0C, 0xDC, 0x46, 0x7A, + 0x71, 0xB4, 0xEF, 0x0D, 0x81, 0xD1, 0x13, 0x98, + 0x62, 0xE7, 0xCB, 0xFF, 0xCD, 0x5B, 0x78, 0x0C, + 0x09, 0xB4, 0x1A, 0xB9, 0x65, 0x3C, 0x14, 0xE5, + 0x31, 0x4F, 0x2E, 0x9A, 0x79, 0x93, 0xF0, 0xA0, + 0x4A, 0xAB, 0x01, 0x53, 0x42, 0x12, 0xF1, 0xB5, + 0x80, 0x05, 0x0E, 0xFE, 0xFC, 0x91, 0x54, 0xDC, + 0x31, 0x96, 0x57, 0x95, 0xFF, 0x3B, 0x60, 0x70, + 0x7A, 0xCE, 0x6F, 0x3A, 0x17, 0xA2, 0x8D, 0x56, + 0xC8, 0xF5, 0x6A, 0x39, 0x23, 0xE1, 0xE4, 0x6A, + 0x9C, 0x26, 0xD6, 0xA7, 0x27, 0x7D, 0xA3, 0xEB, + 0x89, 0x38, 0xFA, 0xDC, 0xA4, 0x7F, 0x82, 0xD0, + 0xE4, 0x40, 0x17, 0x15, 0xB2, 0xD8, 0xF7, 0xBE, + 0x55, 0x11, 0x49, 0x68, 0x22, 0xDE, 0x0B, 0xA9, + 0xAE, 0xB0, 0xB3, 0x43, 0x0B, 0x1C, 0xF6, 0xE3, + 0x40, 0x7D, 0xF8, 0xA6, 0x25, 0xF9, 0x6B, 0x2E, + 0xDA, 0x69, 0x4F, 0x03, 0xBA, 0xCE, 0x7D, 0x58, + 0x49, 0x37, 0x19, 0x5D, 0xBB, 0x90, 0xF6, 0xB0, + 0xF6, 0xFA, 0x61, 0xC6, 0xDF, 0x89, 0x82, 0xAF, + 0x0C, 0xBB, 0x68, 0x94, 0x55, 0xDA, 0xF1, 0x8C, + 0x55, 0xC2, 0xC0, 0x5F, 0xF9, 0x52, 0x6A, 0xD3, + 0x99, 0x04, 0xAA, 0xA8, 0x79, 0x01, 0x03, 0x84, + 0x12, 0xB3, 0x1C, 0xEB, 0x61, 0x22, 0x41, 0x88, + 0x9A, 0xB6, 0x5A, 0x15, 0x64, 0x7A, 0x43, 0x40, + 0xBC, 0x42, 0xD3, 0x7E, 0x77, 0x4A, 0xA6, 0x99, + 0x0C, 0x8A, 0xD0, 0x37, 0x53, 0x43, 0xF8, 0x05, + 0xFA, 0x03, 0x70, 0x2F, 0xDE, 0xB8, 0x5B, 0xED, + 0xC1, 0x03, 0x74, 0xEE, 0x91, 0x12, 0xF9, 0x3B, + 0x81, 0x16, 0x5B, 0xB9, 0xD3, 0x17, 0xA0, 0xE7, + 0xB1, 0x19, 0xBC, 0xEB, 0x96, 0x3C, 0x89, 0x9D, + 0x39, 0x6E, 0x2C, 0x5D, 0xD0, 0x12, 0xE2, 0x46, + 0x33, 0x12, 0x3D, 0x3C, 0xC8, 0x82, 0xC6, 0xA1, + 0x12, 0x27, 0xDA, 0xF9, 0xF2, 0x03, 0x61, 0xB4, + 0xA5, 0xD8, 0xF3, 0x1C, 0x71, 0xC5, 0xE5, 0xF6, + 0xA9, 0x9A, 0x7C, 0x83, 0xA6, 0x2D, 0x99, 0x30, + 0xF4, 0xB5, 0x71, 0xA2, 0xD4, 0xB4, 0x14, 0x87, + 0x10, 0x1A, 0x82, 0x89, 0xDF, 0x0D, 0xA7, 0x40, + 0xC4, 0xAC, 0xB3, 0xC2, 0xEF, 0x38, 0xF7, 0x64, + 0x58, 0xE9, 0x3D, 0xF5, 0xD7, 0x13, 0x4F, 0x85, + 0xBE, 0x35, 0x82, 0xEA, 0x25, 0x5E, 0xC3, 0x6F, + 0xDA, 0x7F, 0xEA, 0x9A, 0x84, 0x76, 0x4F, 0xFF, + 0x94, 0x6C, 0x22, 0x88, 0xE5, 0x95, 0xAF, 0x17, + 0xA6, 0x6B, 0x58, 0xAE, 0xB7, 0xBA, 0xB0, 0x32, + 0x32, 0xA9, 0x19, 0x17, 0xBB, 0x37, 0xFD, 0xBA, + 0x0E, 0x7F, 0x76, 0x22, 0xD4, 0xDA, 0xC4, 0x9B, + 0x29, 0xF0, 0x1E, 0x2C, 0xE6, 0x2D, 0xD8, 0x98, + 0xA5, 0x38, 0xB6, 0x2C, 0xCF, 0xC1, 0x4E, 0xBA, + 0x28, 0x4C, 0x15, 0x92, 0x80, 0x37, 0xF6, 0x70, + 0x1D, 0xFB, 0xDA, 0xDE, 0xB4, 0xA0, 0xB2, 0x79, + 0xBB, 0x5A, 0xA8, 0x07, 0x95, 0xBA, 0x45, 0x6E, + 0x23, 0x33, 0x14, 0x01, 0xC5, 0x4A, 0xF4, 0xF4, + 0xEE, 0xEF, 0x62, 0x91, 0x60, 0xD6, 0x9C, 0x8C, + 0xE6, 0x04, 0x63, 0x13, 0x84, 0xD0, 0xF7, 0xFC, + 0xAB, 0x88, 0xD6, 0x66, 0x11, 0xAC, 0x95, 0x62, + 0xE8, 0x28, 0x13, 0x95, 0x41, 0x23, 0x41, 0x7A, + 0x45, 0x3F, 0x84, 0x65, 0xAF, 0x8F, 0xCD, 0xD4, + 0xF2, 0x2D, 0x45, 0x70, 0x02, 0x2E, 0xCD, 0x4F, + 0x9D, 0xD6, 0x0F, 0x74, 0x5F, 0xB6, 0xA5, 0xFF, + 0xF4, 0x37, 0x8A, 0x9F, 0xFB, 0x76, 0xC7, 0xA1, + 0x5B, 0x91, 0xB3, 0xC2, 0xD0, 0x2C, 0xB8, 0xFB, + 0x68, 0xCC, 0xE4, 0x8B, 0x9F, 0xFA, 0xDB, 0x03, + 0x85, 0xD9, 0xC7, 0xBC, 0xA7, 0xD5, 0xFF, 0x61, + 0x4A, 0xCA, 0xB8, 0x9A, 0xBC, 0x8D, 0x8B, 0x73, + 0xC8, 0x3E, 0x4D, 0x4C, 0x6F, 0xB9, 0x75, 0x71, + 0x95, 0x93, 0x43, 0x99, 0x0D, 0xE9, 0xFA, 0x26, + 0x38, 0x93, 0xA6, 0xA9, 0x64, 0x83, 0x15, 0x40, + 0x81, 0x98, 0xA0, 0x1E, 0xCE, 0x33, 0xC3, 0xD1, + 0xE3, 0x55, 0xD0, 0x20, 0xE0, 0xB2, 0x79, 0x5E, + 0x5C, 0x22, 0x23, 0x65, 0xDC, 0x32, 0x87, 0x8D, + 0x68, 0x94, 0x10, 0xC8, 0x9E, 0xED, 0x62, 0x03, + 0x3A, 0x91, 0x94, 0xA6, 0x85, 0x8D, 0x22, 0x26, + 0x5B, 0xB2, 0xB6, 0x10, 0x79, 0x0D, 0xF1, 0xAB, + 0xF0, 0x17, 0x75, 0x42, 0xD4, 0x69, 0xD1, 0xC5, + 0xE6, 0xB5, 0x8C, 0xE3, 0x9F, 0x10, 0x2E, 0x18, + 0x41, 0x9D, 0xEC, 0x16, 0x9F, 0x11, 0xF3, 0x3E, + 0x14, 0xDC, 0x1B, 0x01, 0x12, 0xA5, 0x3C, 0xE8, + 0xAE, 0xCD, 0xF7, 0x00, 0x22, 0x86, 0x51, 0xBB, + 0x84, 0x0F, 0x29, 0x66, 0xB7, 0xCE, 0xDD, 0x87, + 0xDE, 0x81, 0x93, 0xDD, 0x92, 0xE3, 0xAE, 0x3F, + 0xBC, 0x43, 0x88, 0x00, 0xFF, 0x87, 0x42, 0x9B, + 0xC4, 0xD8, 0x76, 0xFE, 0x06, 0x05, 0x6A, 0xF6, + 0xDC, 0x40, 0xB7, 0x5D, 0xEF, 0xF5, 0x84, 0x61, + 0x29, 0xB5, 0x1E, 0xDB, 0x29, 0xFC, 0xE6, 0xBB, + 0xA5, 0x1E, 0x2E, 0x73, 0xF2, 0xE6, 0x66, 0x39, + 0xC6, 0x71, 0xBE, 0x9B, 0x15, 0x32, 0x9B, 0xCF, + 0xFC, 0xF3, 0x1A, 0x39, 0xD8, 0x26, 0x04, 0xC2, + 0x3D, 0x5F, 0xF4, 0xFC, 0xF4, 0x38, 0xE8, 0x04, + 0x37, 0x77, 0xCC, 0xCA, 0x14, 0xD7, 0x43, 0x0F, + 0xD2, 0x4F, 0xC2, 0x23, 0x9D, 0x43, 0x9C, 0xC7, + 0xE8, 0xC2, 0xCF, 0x20, 0x52, 0x8C, 0xF4, 0x6D, + 0xF5, 0x37, 0xF5, 0x05, 0xC8, 0xAA, 0xB2, 0x95, + 0x2E, 0x9D, 0x95, 0x95, 0xBA, 0x46, 0x65, 0x7A, + 0xE1, 0xF9, 0x34, 0x65, 0xE0, 0x56, 0xEC, 0x89, + 0x90, 0x85, 0xA8, 0x23, 0x94, 0xE6, 0xB1, 0x88, + 0xF8, 0x3F, 0xDD, 0xA6, 0x42, 0x47, 0x77, 0xA8, + 0x89, 0x9F, 0x31, 0x66, 0xAF, 0x76, 0xDA, 0x66, + 0xF9, 0x2B, 0xEC, 0x74, 0x27, 0xBC, 0xF1, 0xD5, + 0x04, 0x02, 0x77, 0xD1, 0x02, 0xD5, 0x7E, 0x0C, + 0xE8, 0x4A, 0xDE, 0xF1, 0x86, 0x77, 0xA9, 0xFF, + 0xAD, 0x99, 0x01, 0x17, 0xE0, 0x6A, 0xE2, 0x74, + 0x11, 0x1C, 0xB2, 0x35, 0xFD, 0x45, 0xBB, 0xE9, + 0xBD, 0x2B, 0xCA, 0xEA, 0xFC, 0xDC, 0x14, 0x3C, + 0x46, 0x15, 0xA4, 0x4E, 0x61, 0x0B, 0xA4, 0xE8, + 0xC0, 0x8A, 0xDC, 0x52, 0xBD, 0x8C, 0xF3, 0xF2, + 0x6F, 0x1F, 0x9C, 0x76, 0x46, 0xC9, 0xAA, 0x23, + 0xB0, 0xC4, 0x60, 0x05, 0xC7, 0x88, 0x58, 0x4D, + 0xBC, 0xF5, 0xDD, 0x72, 0xD0, 0xED, 0xBB, 0xB3, + 0x8C, 0xAB, 0xD2, 0xF5, 0xE6, 0x2A, 0xA8, 0x00, + 0x11, 0x74, 0xC4, 0x3F, 0x1A, 0x18, 0xCC, 0x12, + 0x57, 0x83, 0x02, 0xE2, 0xFE, 0x8C, 0x18, 0xAF, + 0xA0, 0x32, 0xCB, 0xF0, 0x8A, 0x65, 0xE2, 0xF3, + 0xB1, 0x79, 0x2E, 0x80, 0x68, 0x34, 0xB5, 0x41, + 0xFB, 0xA0, 0x75, 0x77, 0x72, 0xBA, 0x92, 0xBF, + 0xB9, 0x0A, 0x98, 0x17, 0xDC, 0x25, 0x77, 0x31, + 0x0A, 0xA7, 0xA8, 0x38, 0x9F, 0x1B, 0x62, 0xB0, + 0xC4, 0xCF, 0xE2, 0x1B, 0x0B, 0x0C, 0xFA, 0xBB, + 0xC4, 0x06, 0x19, 0x9D, 0xC9, 0xC8, 0x18, 0x1C, + 0x39, 0x63, 0x50, 0xDA, 0xF5, 0x8A, 0x1F, 0x68, + 0xD2, 0x61, 0xA5, 0xA1, 0x9D, 0xFD, 0xAE, 0xF5, + 0xD8, 0x14, 0xE9, 0x28, 0x55, 0xAB, 0x38, 0x98, + 0x4D, 0xE0, 0x5D, 0xA5, 0xFC, 0x9F, 0x25, 0x81, + 0x50, 0x11, 0xCE, 0x74, 0xF3, 0x6C, 0x66, 0xF5, + 0xED, 0x9C, 0x35, 0xD9, 0xDC, 0xC7, 0x11, 0x24, + 0x27, 0x37, 0xD2, 0x89, 0x51, 0xE8, 0x0E, 0x2C, + 0x35, 0xB6, 0x5B, 0x2B, 0xCE, 0xAB, 0x96, 0xB2, + 0xD4, 0x21, 0xB0, 0x21, 0x6D, 0xF3, 0x72, 0x3F, + 0x96, 0x54, 0x22, 0x74, 0x3C, 0x43, 0xE6, 0x02, + 0xAF, 0xF2, 0xB3, 0xED, 0xF8, 0x47, 0xF4, 0x26, + 0xB4, 0x31, 0x2F, 0xDC, 0x21, 0xBA, 0x9C, 0x39, + 0x86, 0x24, 0xA0, 0x1C, 0xFE, 0xDF, 0x06, 0x54, + 0x17, 0xD9, 0xCD, 0xC0, 0x7C, 0xF4, 0xE2, 0x5C, + 0x0E, 0x18, 0x80, 0xEC, 0x24, 0x7E, 0x00, 0xF1, + 0x53, 0x09, 0xD5, 0xBC, 0x9B, 0xB1, 0x4C, 0x2E, + 0xBD, 0x41, 0x0A, 0x6A, 0xF6, 0x33, 0x0C, 0x9E, + 0xC8, 0x42, 0xBD, 0x84, 0xC5, 0x46, 0x49, 0x1D, + 0x97, 0xAA, 0x42, 0xE7, 0x9E, 0x59, 0xD5, 0x99, + 0x12, 0x1B, 0x7A, 0x8E, 0x39, 0xA4, 0x50, 0xE0, + 0x87, 0x4C, 0x62, 0x4A, 0x80, 0xF5, 0xCF, 0x2B, + 0x61, 0x84, 0x74, 0x4B, 0xE5, 0x05, 0xD9, 0xB5, + 0x62, 0x5B, 0x7E, 0x7E, 0x9A, 0x05, 0x13, 0x35, + 0xB1, 0x3D, 0x85, 0xDA, 0x63, 0x2D, 0x62, 0x36, + 0x93, 0x1A, 0x37, 0x72, 0x6E, 0xFD, 0xEB, 0x2E, + 0x47, 0x37, 0xAF, 0xE7, 0x04, 0xD8, 0x3A, 0x55, + 0x8B, 0xC1, 0xF2, 0xB6, 0x8F, 0xE6, 0x16, 0x18, + 0x3E, 0x00, 0x4A, 0x9A, 0x2C, 0xBD, 0x83, 0xCF, + 0x4C, 0x27, 0xB5, 0xBD, 0xEC, 0x03, 0x1D, 0xD7, + 0x49, 0x0F, 0xED, 0x67, 0xD5, 0xC1, 0xA9, 0x14, + 0x40, 0x29, 0xA1, 0x67, 0x75, 0x7E, 0x3C, 0x97, + 0x7D, 0x22, 0x5E, 0x15, 0xE3, 0x3C, 0xD0, 0x42, + 0xF7, 0x25, 0x41, 0x88, 0x46, 0x94, 0xEA, 0x0D, + 0x2D, 0x3D, 0x50, 0xE2, 0xE6, 0xB9, 0x06, 0x8A, + 0x34, 0xB9, 0x1E, 0xE1, 0x79, 0x40, 0x31, 0xC2, + 0x32, 0x79, 0x6F, 0x3B, 0xCB, 0x9D, 0x08, 0x04, + 0x1A, 0xB5, 0x37, 0x57, 0xFA, 0x72, 0xAC, 0xCB, + 0xF2, 0x0B, 0xD1, 0xEE, 0x20, 0xD9, 0x19, 0x83, + 0x55, 0x81, 0x62, 0xDA, 0x22, 0xDB, 0x62, 0x37, + 0x6D, 0x36, 0x27, 0xFA, 0x45, 0x8D, 0x85, 0x87, + 0x16, 0x88, 0x37, 0x91, 0x67, 0x09, 0x86, 0x71, + 0x64, 0xDE, 0xC4, 0x39, 0x07, 0xD0, 0xF2, 0x8D, + 0x5B, 0x66, 0x8F, 0xC8, 0x3B, 0x7E, 0x45, 0x39, + 0x3A, 0xCC, 0x0A, 0x4E, 0xC1, 0x6D, 0x2D, 0x76, + 0x44, 0x82, 0x9F, 0x10, 0x56, 0xCA, 0x40, 0xBA, + 0xA3, 0x48, 0x86, 0xAF, 0x5E, 0x5B, 0x1F, 0xC0, + 0x0A, 0xB1, 0x52, 0xD3, 0x66, 0x0D, 0x6A, 0xD7, + 0xCB, 0x45, 0x20, 0x10, 0x09, 0xCD, 0x3B, 0xBC, + 0x18, 0xE4, 0xFB, 0x1C, 0x0D, 0x5B, 0x51, 0xCF, + 0x4C, 0x04, 0xC7, 0x17, 0x51, 0xAA, 0x8C, 0x4A, + 0x1C, 0xF6, 0x56, 0x8D, 0xF7, 0x36, 0x33, 0xEB, + 0x44, 0x7A, 0x76, 0x9C, 0x59, 0x60, 0x1B, 0x69, + 0x05, 0xA9, 0xD8, 0x25, 0x3D, 0x68, 0x48, 0x33, + 0x39, 0xD4, 0x72, 0xDF, 0x66, 0xC3, 0x3D, 0x71, + 0xE6, 0xAE, 0x32, 0x28, 0x5F, 0x15, 0x2D, 0x3E, + 0x3B, 0x00, 0xFE, 0x17, 0x18, 0x63, 0xCC, 0xC3, + 0x3F, 0xB9, 0x99, 0x6C, 0x3C, 0xD7, 0x58, 0xAD, + 0xED, 0x0B, 0x78, 0x0C, 0xC2, 0x81, 0xC4, 0x7E, + 0x2D, 0x4C, 0x46, 0x49, 0xC8, 0xF3, 0xA6, 0x52, + 0xCD, 0x4F, 0x9F, 0xF7, 0xAC, 0xF6, 0x02, 0x63, + 0xDE, 0xCF, 0x67, 0xE8, 0x69, 0x31, 0x68, 0xD5, + 0x9A, 0xD4, 0xEA, 0xF5, 0x06, 0x5F, 0xC1, 0x93, + 0x26, 0xEC, 0x01, 0x18, 0x81, 0x15, 0x1A, 0xE8, + 0x71, 0xED, 0x2D, 0x14, 0x9C, 0x8B, 0x74, 0xCA, + 0x65, 0xA5, 0x31, 0x31, 0x0E, 0xDA, 0x13, 0x2C, + 0xCB, 0xB6, 0x0A, 0x3E, 0xCD, 0xBA, 0x35, 0x59, + 0x0D, 0xBC, 0xF5, 0x75, 0x1C, 0x63, 0x95, 0xAD, + 0xC3, 0xAB, 0x81, 0x07, 0x7B, 0xEF, 0xDF, 0x7B, + 0xC9, 0x01, 0xDC, 0xE7, 0x33, 0x6E, 0xFC, 0xF7, + 0xE2, 0x6D, 0x68, 0x04, 0x1B, 0xB3, 0xCF, 0x0A, + 0x30, 0x86, 0xBE, 0x3B, 0x97, 0x75, 0x9A, 0xF9, + 0xA2, 0x2B, 0x02, 0xB0, 0x7C, 0x97, 0xB3, 0xB5, + 0xFB, 0x66, 0x53, 0x6B, 0xB4, 0xE4, 0x55, 0x10, + 0x0E, 0xF8, 0xCD, 0x91, 0x7D, 0x2E, 0x27, 0xD6, + 0xA5, 0x00, 0x44, 0xE1, 0x81, 0xE0, 0x04, 0x9F, + 0x89, 0x15, 0xF8, 0x4F, 0xA3, 0x75, 0x7B, 0x68, + 0x09, 0x2A, 0xBA, 0xAD, 0xCF, 0x1C, 0x44, 0x12, + 0xD4, 0xE3, 0xC2, 0x3E, 0xEA, 0x53, 0x52, 0xE8, + 0x37, 0x11, 0xF7, 0x90, 0xE0, 0xE7, 0x5B, 0x6A, + 0xB7, 0x56, 0xE9, 0x89, 0x9C, 0x5B, 0xE1, 0xE8, + 0x2B, 0xE3, 0x85, 0x3C, 0xA0, 0xA7, 0x11, 0x3D, + 0x95, 0x5D, 0x0C, 0x52, 0x8A, 0x60, 0x25, 0xD6, + 0x6E, 0x9D, 0x37, 0x81, 0x7C, 0x8F, 0xB5, 0x89, + 0x74, 0x13, 0xD6, 0x91, 0x0C, 0xFC, 0x5D, 0x66, + 0xF0, 0x25, 0x5B, 0x67, 0xEF, 0x7C, 0x47, 0x79, + 0x19, 0x02, 0xD4, 0x3C, 0x68, 0xC0, 0x5F, 0xB2, + 0x6A, 0x11, 0x2C, 0xA1, 0xFC, 0xAB, 0xC3, 0x54, + 0xF7, 0xB1, 0xF4, 0x74, 0x62, 0x3C, 0xB2, 0x37, + 0xB2, 0x39, 0xAC, 0xBC, 0x74, 0x2B, 0x51, 0xC2, + 0x8A, 0xD4, 0xAE, 0x60, 0x79, 0x22, 0xEC, 0x0A, + 0xCD, 0x5E, 0xA0, 0xB7, 0x6A, 0x3C, 0x3A, 0x0C, + 0x06, 0x65, 0x3A, 0x66, 0x3F, 0xED, 0x57, 0x4E, + 0xA8, 0x9C, 0x62, 0x63, 0xC6, 0x3D, 0x3F, 0x5D, + 0x0C, 0x11, 0x7D, 0xF2, 0x71, 0x6B, 0xDF, 0xB8, + 0x13, 0x4B, 0x96, 0xE7, 0x6B, 0x2E, 0x06, 0x4D, + 0xC6, 0xFF, 0x98, 0x0E, 0xE5, 0x11, 0x8A, 0x9D, + 0x7C, 0x67, 0x43, 0x18, 0x6B, 0x36, 0x4D, 0x12, + 0x29, 0xC7, 0x87, 0x74, 0xDC, 0xE1, 0x75, 0x62, + 0x27, 0x83, 0x13, 0x2E, 0x46, 0xD6, 0xD1, 0xFE, + 0xD3, 0x35, 0xF2, 0xA0, 0xBB, 0x5B, 0xA6, 0x9E, + 0x74, 0xCA, 0x61, 0x10, 0xB0, 0x6D, 0x36, 0xCC, + 0x29, 0x16, 0x1B, 0xD2, 0x3A, 0xA8, 0xF6, 0xB4, + 0xCA, 0x7C, 0x3D, 0x26, 0xD7, 0x11, 0xF3, 0xE9, + 0x53, 0xFA, 0x71, 0xB6, 0xF9, 0x89, 0x5D, 0xC0, + 0x8D, 0x2D, 0x33, 0x25, 0x2C, 0x0B, 0x50, 0x05, + 0x52, 0x96, 0xFE, 0x23, 0xCA, 0x5C, 0x74, 0xFF, + 0x7C, 0x3B, 0xAB, 0x02, 0xBA, 0x2B, 0x2B, 0x2D, + 0xF7, 0xD8, 0x81, 0x5D, 0x5A, 0x59, 0xF2, 0xCE, + 0x90, 0xBB, 0xEE, 0xFB, 0x4E, 0xE2, 0xA2, 0x72, + 0x18, 0x33, 0xAB, 0xF3, 0x2B, 0xA3, 0x90, 0x25, + 0x6B, 0x20, 0xDF, 0xE8, 0x44, 0x1B, 0x3F, 0x8D, + 0x82, 0xD5, 0x45, 0xAF, 0x97, 0x3F, 0x22, 0x06, + 0xE2, 0xAA, 0x52, 0x35, 0xDE, 0xEE, 0xBB, 0x39, + 0xDC, 0xC3, 0x14, 0x03, 0xEA, 0x19, 0x9F, 0xEF, + 0xAA, 0x81, 0xDA, 0x9B, 0x0A, 0x96, 0x73, 0xDF, + 0x98, 0xED, 0x67, 0x4C, 0x27, 0xAD, 0xC5, 0x4E, + 0x6F, 0x7E, 0xDE, 0x44, 0xEC, 0x7A, 0x24, 0x9C, + 0xF9, 0xB6, 0x9A, 0xDD, 0x19, 0x2E, 0x47, 0xDA, + 0x2D, 0x59, 0x88, 0x95, 0x26, 0x19, 0x37, 0x97, + 0x21, 0x0E, 0x67, 0x8D, 0x40, 0xC1, 0xE5, 0x5D, + 0xBB, 0x28, 0x6D, 0xDA, 0x19, 0xDF, 0xD6, 0x51, + 0x04, 0x10, 0x58, 0x97, 0x4A, 0xD4, 0x3B, 0x31, + 0x38, 0x44, 0x0D, 0x5C, 0xF8, 0xF9, 0xFF, 0xDD, + 0x0D, 0xAA, 0x45, 0x7E, 0xD3, 0x71, 0x2C, 0x93, + 0xCC, 0x41, 0xAF, 0x38, 0x24, 0x73, 0xB9, 0xE7, + 0x83, 0xCA, 0x72, 0x3E, 0x98, 0x76, 0xC1, 0x61, + 0xDA, 0xF2, 0x46, 0x3E, 0x10, 0x15, 0x9A, 0x2C, + 0x7E, 0x0D, 0x18, 0x11, 0x8B, 0x89, 0x51, 0x0E, + 0xE3, 0x85, 0x71, 0x0A, 0xAA, 0x6E, 0x45, 0x92, + 0x53, 0x55, 0xA3, 0xF3, 0xAB, 0xA9, 0xC3, 0x9E, + 0x54, 0x2F, 0x43, 0x40, 0x94, 0xD6, 0xD8, 0x02, + 0x97, 0xDC, 0x40, 0x33, 0x37, 0x0C, 0x1B, 0x86, + 0x32, 0x03, 0x7E, 0xE5, 0x64, 0x12, 0x2C, 0xEE, + 0x87, 0x99, 0xEB, 0xE8, 0x74, 0xAB, 0x80, 0x3B, + 0xB7, 0xB3, 0xA5, 0xCD, 0x93, 0xDF, 0xBD, 0xE4, + 0x4C, 0xE7, 0xAB, 0x14, 0x44, 0xE5, 0x3F, 0xAC, + 0xA8, 0xF4, 0xE0, 0x8F, 0x38, 0x9E, 0x76, 0x48, + 0x94, 0x4C, 0xA8, 0xEB, 0x9F, 0xB1, 0xCA, 0x22, + 0xCF, 0x2B, 0x32, 0x89, 0x53, 0xD5, 0x36, 0x5E, + 0xE0, 0x04, 0xBE, 0x61, 0x3C, 0x3B, 0x25, 0xBF, + 0x62, 0x83, 0xCA, 0xF1, 0x03, 0x90, 0xAF, 0x82, + 0x65, 0x51, 0x18, 0xD1, 0x88, 0x6C, 0x7F, 0xF6, + 0x17, 0xB2, 0x83, 0x13, 0xBD, 0xAC, 0x3F, 0x05, + 0xA7, 0xBB, 0x72, 0xB7, 0x50, 0x0E, 0xA3, 0xC1, + 0x01, 0xD1, 0x1E, 0xB7, 0x5D, 0x88, 0x73, 0xAC, + 0xAC, 0x90, 0xFC, 0xB6, 0x18, 0x3F, 0xC0, 0x42, + 0x9B, 0xF5, 0x20, 0x16, 0xCF, 0x05, 0xC7, 0x9D, + 0xD7, 0xAB, 0x69, 0x1B, 0x8E, 0xDA, 0x41, 0x04, + 0xAD, 0x74, 0xB7, 0x8B, 0x32, 0x11, 0xC0, 0x58, + 0x99, 0x26, 0xE0, 0x36, 0xD2, 0xFE, 0x27, 0xF4, + 0x12, 0x68, 0x11, 0xCC, 0x51, 0x28, 0x7F, 0x3F, + 0x15, 0x54, 0xE2, 0xFD, 0x53, 0x76, 0x94, 0x4F, + 0x16, 0x67, 0xB6, 0x53, 0x1B, 0x43, 0x21, 0x11, + 0x23, 0xBE, 0xCE, 0x97, 0x26, 0x3A, 0x59, 0x7D, + 0xE3, 0xE8, 0x02, 0xFD, 0xCA, 0xF6, 0x1A, 0xE7, + 0xAF, 0x29, 0x15, 0x50, 0x98, 0x3E, 0xD8, 0x18, + 0xD4, 0x43, 0x45, 0x3B, 0xF4, 0x98, 0x48, 0x22, + 0x6A, 0x87, 0x43, 0x79, 0xD4, 0xED, 0xFA, 0x12, + 0x73, 0xB9, 0x67, 0xF7, 0xB8, 0x40, 0x80, 0x8D, + 0x5F, 0xCF, 0xAF, 0xB6, 0xC6, 0xE3, 0xD5, 0x62, + 0xF6, 0x79, 0xF6, 0xBC, 0xAC, 0x98, 0xB7, 0x5C, + 0x04, 0x93, 0x12, 0x59, 0x26, 0x95, 0x6C, 0xF3, + 0xA1, 0x1B, 0xC9, 0x78, 0xF4, 0xF7, 0xBA, 0xEA, + 0xB2, 0x06, 0xA0, 0x81, 0x5D, 0xC6, 0x98, 0x0F, + 0x66, 0x14, 0x55, 0x1F, 0x96, 0x42, 0xAF, 0x7B, + 0xDA, 0x6B, 0x92, 0x81, 0x9A, 0x4D, 0xAA, 0x3A, + 0xF6, 0xBA, 0x30, 0x55, 0x31, 0x5F, 0xB9, 0x37, + 0x64, 0xBB, 0xCE, 0x19, 0x73, 0x43, 0x57, 0xA3, + 0xBD, 0xBC, 0x0B, 0x9E, 0x60, 0xB0, 0x29, 0xFE, + 0xAB, 0xE3, 0xA7, 0x8B, 0xB0, 0xCD, 0x64, 0xD1, + 0x03, 0x37, 0x06, 0xC6, 0x70, 0x55, 0x08, 0xA6, + 0x6F, 0x11, 0x9A, 0x2D, 0xFC, 0x47, 0xBA, 0xB1, + 0x26, 0x63, 0x7C, 0x00, 0xC3, 0x0F, 0x7E, 0xA0, + 0x64, 0x6A, 0xE8, 0x0F, 0x10, 0xEF, 0xCD, 0x4E, + 0x3C, 0xBA, 0x1A, 0x82, 0x8E, 0xFA, 0xFD, 0x98, + 0xDC, 0xF3, 0x19, 0x5E, 0xB0, 0xE2, 0xA7, 0x88, + 0x42, 0x59, 0x77, 0x79, 0xC4, 0x4D, 0x69, 0x84, + 0x80, 0xC8, 0x1A, 0x80, 0xF7, 0x8D, 0x10, 0x8E, + 0x9F, 0xA2, 0x79, 0xA1, 0xD0, 0x6C, 0x47, 0x91, + 0xDA, 0x4C, 0xC6, 0x26, 0x61, 0x9D, 0x41, 0xB0, + 0x96, 0x5F, 0x58, 0x11, 0x21, 0x7F, 0x4A, 0xA4, + 0xF6, 0x4D, 0xF8, 0x11, 0xAA, 0x99, 0x77, 0xF2, + 0xE0, 0xFD, 0xD4, 0xF9, 0xDA, 0xA0, 0x2B, 0xEF, + 0x47, 0x08, 0x50, 0x85, 0x28, 0x55, 0x13, 0xFB, + 0x09, 0xF2, 0xC1, 0x0A, 0x83, 0x14, 0xDE, 0xCE, + 0xEB, 0xDE, 0x5D, 0x0D, 0x66, 0xE1, 0x20, 0x03, + 0x6F, 0x52, 0x47, 0x61, 0xB8, 0x41, 0xEA, 0x0B, + 0x51, 0xC3, 0x21, 0x0F, 0x15, 0x20, 0x4F, 0x5C, + 0x47, 0xC6, 0x1A, 0x16, 0xB5, 0x14, 0x91, 0xB9, + 0x2C, 0x31, 0xFF, 0x46, 0xF9, 0xE4, 0x62, 0x31, + 0xD4, 0x43, 0x9C, 0xE0, 0x03, 0xA4, 0x44, 0xD5, + 0xC0, 0x91, 0xD9, 0x04, 0xF6, 0x35, 0x4C, 0x92, + 0xC5, 0xB1, 0x8B, 0x41, 0x56, 0xCF, 0x1B, 0xB9, + 0x7F, 0x46, 0xE2, 0x32, 0x4E, 0xF2, 0x83, 0x12, + 0x90, 0xEC, 0x43, 0x9E, 0x33, 0x6C, 0x2C, 0xFD, + 0xC0, 0x3B, 0xEF, 0xFB, 0xC7, 0xBF, 0x4C, 0x13, + 0x90, 0x00, 0xEF, 0xFA, 0xEC, 0xED, 0x8C, 0xC5, + 0xB2, 0x15, 0x35, 0x7F, 0x60, 0x09, 0x6C, 0xE0, + 0xCC, 0x70, 0x69, 0xD0, 0xA7, 0xF2, 0x5C, 0xA3, + 0xF0, 0x0C, 0x74, 0xBE, 0x5B, 0x88, 0x10, 0x58, + 0x0B, 0x04, 0xBD, 0x5E, 0x40, 0x5C, 0x8F, 0x00, + 0xCE, 0xB5, 0x34, 0x90, 0xA0, 0xF2, 0x0E, 0x2E, + 0x3E, 0x27, 0xFC, 0xDB, 0x8C, 0x42, 0x5B, 0xFC, + 0x8C, 0x41, 0xAE, 0xDD, 0x92, 0x14, 0x8D, 0x1B, + 0x58, 0x91, 0x5C, 0xA5, 0x32, 0x71, 0x61, 0xA4, + 0xA1, 0x21, 0x89, 0xDA, 0xF2, 0x1E, 0x1B, 0xDB, + 0x31, 0x69, 0x7B, 0xD3, 0xC2, 0xD8, 0x9B, 0x3F, + 0xEE, 0xC7, 0xC5, 0x46, 0xE7, 0x45, 0xE3, 0x26, + 0x04, 0x3A, 0x90, 0xAD, 0x00, 0xF7, 0x97, 0x10, + 0x7B, 0x60, 0xEF, 0xE7, 0x09, 0x7E, 0x29, 0x16, + 0xB7, 0xEF, 0x73, 0xD1, 0x63, 0x95, 0x46, 0x1A, + 0x7C, 0x92, 0xA5, 0xBA, 0xEF, 0xF5, 0x2E, 0xA6, + 0x11, 0x68, 0x5B, 0x86, 0x35, 0xC7, 0xF8, 0x72, + 0xFF, 0xEC, 0x1E, 0x02, 0x2D, 0x8B, 0x59, 0x4E, + 0x37, 0x8E, 0xE3, 0xD8, 0xBA, 0xC7, 0x52, 0x08, + 0x7A, 0x93, 0xEA, 0xCD, 0x90, 0xE8, 0x39, 0x92, + 0x8E, 0x26, 0xAB, 0x43, 0x53, 0xB5, 0xEE, 0x3F, + 0x8E, 0xCE, 0x57, 0x44, 0x4B, 0xF7, 0x23, 0xF4, + 0x4F, 0x9B, 0x08, 0x33, 0x8E, 0x1D, 0x70, 0xF9, + 0x1A, 0xCF, 0x9E, 0x18, 0x06, 0x4E, 0x45, 0xAE, + 0x5A, 0x30, 0x7D, 0x43, 0x4B, 0x15, 0x91, 0xA5, + 0x8C, 0x98, 0xD9, 0x55, 0x29, 0x3B, 0x26, 0x64, + 0x9F, 0x70, 0x35, 0xEE, 0xF9, 0x74, 0x09, 0xE8, + 0x28, 0xD7, 0x32, 0x04, 0x3F, 0xF8, 0x83, 0x01, + 0x2E, 0xC5, 0x9F, 0x2B, 0x88, 0x4B, 0x65, 0xCB, + 0x1D, 0x11, 0xFE, 0x1D, 0x10, 0x4F, 0xCC, 0x6C, + 0x90, 0x90, 0xD9, 0x14, 0xA2, 0x1C, 0xBE, 0x45, + 0x56, 0xF6, 0xEB, 0xF7, 0x11, 0xD5, 0x7C, 0x7D, + 0xBE, 0xAA, 0x2B, 0xCE, 0xC8, 0x3F, 0x05, 0x50, + 0x68, 0x16, 0xE4, 0x9E, 0xF4, 0xE7, 0x33, 0x3D, + 0x8C, 0x22, 0x6B, 0xFE, 0xEE, 0x53, 0xD9, 0xB4, + 0xFF, 0xD3, 0xC5, 0x9E, 0x7E, 0x50, 0x2F, 0x65, + 0x1F, 0x9A, 0x13, 0x97, 0x55, 0x62, 0xA4, 0x7E, + 0xC6, 0xB5, 0xC5, 0x3E, 0xD0, 0x9B, 0x45, 0xF4, + 0x16, 0xC2, 0xFF, 0x15, 0xBE, 0x8A, 0x9E, 0x73, + 0xA1, 0x5E, 0x49, 0x2F, 0x0C, 0x16, 0x2F, 0x9B, + 0xF7, 0xD0, 0x8C, 0xCF, 0xB9, 0xD9, 0xB2, 0x1E, + 0x45, 0xA6, 0xBC, 0x1C, 0xD4, 0x99, 0x8C, 0x8D, + 0x18, 0x60, 0x8F, 0x02, 0x01, 0x65, 0x62, 0x94, + 0xD2, 0x52, 0xA5, 0x81, 0x60, 0xCF, 0x95, 0xAE, + 0x9D, 0xB7, 0xF4, 0xD1, 0x14, 0x0B, 0xA0, 0x90, + 0x2B, 0x50, 0x7E, 0x8F, 0x76, 0xAD, 0xE4, 0x00, + 0x4A, 0x51, 0x73, 0xEA, 0xB9, 0x6C, 0xF6, 0xFB, + 0xA5, 0xD7, 0xD7, 0x5D, 0x2E, 0x3E, 0xE5, 0xFF, + 0xCD, 0x55, 0xBE, 0x37, 0xD3, 0xFB, 0xC2, 0xA8, + 0x4D, 0x1C, 0x59, 0x14, 0x22, 0x7D, 0x65, 0x94, + 0xDF, 0xE6, 0xD4, 0x94, 0x4E, 0x89, 0xF8, 0x5C, + 0xEA, 0x0A, 0xCD, 0xEA, 0x46, 0x13, 0xE2, 0xF4, + 0xEC, 0x8A, 0x54, 0x6C, 0xEE, 0x95, 0x94, 0xB9, + 0x47, 0xF4, 0xE7, 0xB3, 0x21, 0x04, 0x4E, 0x5D, + 0xF2, 0x33, 0x12, 0xF4, 0xC8, 0x53, 0xD4, 0x89, + 0xD9, 0x94, 0x26, 0xDE, 0x48, 0x0A, 0x45, 0x36, + 0x27, 0x95, 0x8C, 0x12, 0x83, 0xE9, 0xA3, 0x09, + 0x33, 0x8A, 0xA6, 0x5F, 0x6C, 0x4C, 0x38, 0xAA, + 0xC2, 0xA9, 0xB1, 0xE2, 0x2A, 0x4C, 0xBF, 0x75, + 0xB9, 0xED, 0xB8, 0xD1, 0x3B, 0xDF, 0x08, 0x36, + 0x7B, 0x31, 0x56, 0x72, 0x20, 0x74, 0xF7, 0xA3, + 0x1E, 0x10, 0x4B, 0x85, 0x34, 0x43, 0x3E, 0xF1, + 0x34, 0x9F, 0x52, 0x56, 0x89, 0xD4, 0x56, 0x38, + 0x83, 0x05, 0x4C, 0x7B, 0x17, 0x1A, 0x60, 0x0D, + 0x82, 0xAA, 0x54, 0x43, 0x42, 0x76, 0x7D, 0xF5, + 0xFA, 0xB7, 0xF2, 0xC0, 0x97, 0xEC, 0x6A, 0x37, + 0xFC, 0x68, 0x5E, 0x71, 0x5C, 0x93, 0xD5, 0x5B, + 0x50, 0x59, 0x31, 0x49, 0x90, 0xD5, 0x16, 0xFD, + 0x71, 0x40, 0xFE, 0xEE, 0x21, 0x69, 0x65, 0x3C, + 0x7C, 0xFF, 0x28, 0x5F, 0xFF, 0xD2, 0x3B, 0x4F, + 0xFA, 0x16, 0x2F, 0x78, 0x2F, 0x98, 0x84, 0x6C, + 0xFD, 0xBC, 0xCA, 0xC0, 0x82, 0xA7, 0xCF, 0x58, + 0x55, 0x28, 0x48, 0x8D, 0x23, 0xB4, 0xE4, 0x59, + 0x24, 0x01, 0x2F, 0xF5, 0x57, 0xA3, 0xD5, 0x64, + 0xE6, 0x78, 0x24, 0xD1, 0x3D, 0x14, 0x93, 0x6E, + 0xB0, 0x43, 0x93, 0xF4, 0x09, 0xE0, 0xA3, 0x1D, + 0xA1, 0x71, 0x9E, 0x98, 0xBE, 0x3C, 0x1C, 0x93, + 0x4B, 0xE3, 0x57, 0x2D, 0x2F, 0x74, 0xCB, 0xA3, + 0x26, 0xFF, 0x7F, 0xAC, 0x1B, 0x28, 0x14, 0x7C, + 0xCA, 0x04, 0xE9, 0xD0, 0x76, 0x20, 0x74, 0xEA, + 0x54, 0xF8, 0x56, 0x8F, 0x93, 0x38, 0x21, 0x7E, + 0xEE, 0x58, 0x21, 0x04, 0x75, 0x2E, 0xA0, 0x05, + 0x0E, 0xB8, 0x91, 0x92, 0x63, 0xD7, 0x40, 0x13, + 0xEB, 0xE7, 0xD3, 0x20, 0x77, 0xB0, 0xC6, 0x65, + 0x29, 0x84, 0x87, 0x62, 0x2C, 0xFB, 0xD3, 0x76, + 0x55, 0xC8, 0xF2, 0x27, 0x82, 0x28, 0xD3, 0xDC, + 0x75, 0x8B, 0x00, 0xB4, 0xE4, 0xC1, 0x81, 0x53, + 0x49, 0x1D, 0x7A, 0x47, 0xA9, 0x30, 0x62, 0x94, + 0x63, 0xC6, 0x25, 0x7D, 0xE4, 0x74, 0xDD, 0x68, + 0x93, 0x1C, 0xFF, 0x09, 0xB9, 0xE0, 0x0A, 0x8F, + 0xCB, 0x7A, 0x71, 0x68, 0x42, 0x94, 0x06, 0x70, + 0x69, 0x45, 0x06, 0x24, 0x95, 0xF4, 0x53, 0x4D, + 0xA5, 0xAC, 0xED, 0xAE, 0xFD, 0xC1, 0xA5, 0x6B, + 0xD6, 0xB1, 0xAA, 0x8A, 0x2B, 0x72, 0x38, 0x3E, + 0x74, 0xF0, 0xA1, 0x0C, 0x01, 0xC5, 0xDC, 0xB5, + 0xF5, 0xCB, 0x0E, 0x55, 0xCB, 0x22, 0xDE, 0xA3, + 0xE1, 0xF4, 0x12, 0xC0, 0x4B, 0xFC, 0x5B, 0x55, + 0x8B, 0xC3, 0x8D, 0xCE, 0x1E, 0x8D, 0x0C, 0x51, + 0x22, 0xD2, 0x9C, 0xBE, 0x9D, 0x88, 0xF3, 0xB4, + 0x22, 0xDD, 0x4F, 0xCB, 0x62, 0x7C, 0x17, 0x47, + 0x3E, 0x16, 0x92, 0xFF, 0x21, 0x51, 0x12, 0xB7, + 0x2D, 0xEA, 0x5D, 0x7A, 0xA4, 0xBC, 0xDC, 0x97, + 0xD2, 0x73, 0x7C, 0x97, 0xEA, 0x21, 0x57, 0xBD, + 0x19, 0xC0, 0xD9, 0x50, 0xEE, 0x75, 0x8E, 0x2D, + 0xAF, 0x6A, 0x9D, 0x8D, 0x5A, 0xCA, 0x60, 0xF6, + 0xF2, 0x8E, 0xB5, 0xC2, 0xB4, 0x9C, 0x14, 0x2F, + 0x39, 0xDB, 0x2C, 0x88, 0x33, 0x06, 0x1F, 0xAA, + 0x17, 0x22, 0x7F, 0xC6, 0xD5, 0xFD, 0x30, 0xCC, + 0xEC, 0x02, 0xD1, 0x38, 0x7E, 0x1E, 0xB9, 0x6E, + 0x20, 0x47, 0x34, 0x1C, 0x74, 0x2B, 0xFD, 0x44, + 0x30, 0x3D, 0x65, 0xA3, 0x60, 0x20, 0xDD, 0x55, + 0x02, 0x06, 0x9D, 0x30, 0x71, 0x4C, 0x89, 0x54, + 0x24, 0x6B, 0xC7, 0x6A, 0x94, 0x52, 0xDE, 0x63, + 0xF6, 0x03, 0x54, 0x42, 0xCC, 0xC8, 0x31, 0xFE, + 0xDC, 0x87, 0x74, 0x5C, 0x6C, 0x42, 0x3E, 0x3A, + 0x82, 0x8D, 0x20, 0x81, 0xA2, 0x23, 0xF1, 0x32, + 0x62, 0xB6, 0xC6, 0xE4, 0x60, 0x33, 0xB4, 0x17, + 0x5A, 0x1F, 0x14, 0x57, 0x9F, 0xD6, 0x70, 0xA4, + 0x7D, 0xD4, 0xBA, 0xC1, 0xB3, 0xE4, 0x1A, 0x88, + 0x06, 0x6E, 0x54, 0x57, 0xAA, 0x8E, 0x70, 0x0E, + 0x9E, 0xDD, 0xF1, 0x3D, 0x3B, 0xF4, 0xCD, 0x12, + 0x9A, 0x94, 0xE3, 0x62, 0x87, 0x9C, 0x9D, 0x42, + 0x19, 0xE8, 0xED, 0x2D, 0xAA, 0x85, 0x34, 0x5E, + 0xAE, 0x0F, 0x97, 0x36, 0x06, 0x8A, 0x30, 0x4A, + 0x63, 0x75, 0x75, 0xA6, 0x4B, 0x2F, 0x81, 0xEF, + 0x3B, 0x4B, 0x07, 0xB8, 0x02, 0x82, 0x76, 0xCE, + 0x4B, 0x10, 0x59, 0x85, 0x49, 0xEE, 0xED, 0x85, + 0x53, 0x81, 0xDB, 0xCA, 0x47, 0x78, 0x57, 0x59, + 0xAE, 0x46, 0x98, 0xB2, 0x85, 0x1C, 0x4F, 0x59, + 0xC1, 0xB4, 0x7E, 0xBE, 0xA9, 0xEB, 0xA3, 0x9B, + 0xE1, 0xFA, 0xB7, 0x1D, 0xB3, 0x46, 0xF8, 0x97, + 0xE5, 0x44, 0x37, 0x19, 0x1A, 0xE6, 0xE5, 0xC1, + 0x76, 0x08, 0x9C, 0x48, 0xE2, 0xF5, 0x66, 0x1A, + 0x6E, 0x73, 0x8E, 0x21, 0xF7, 0x0F, 0xB2, 0x94, + 0xAC, 0xA8, 0xCE, 0x5D, 0x11, 0x40, 0x50, 0x26, + 0xB9, 0xB6, 0x6A, 0x48, 0xBD, 0x69, 0xF6, 0xCF, + 0x99, 0xCA, 0x76, 0xBD, 0x74, 0xCA, 0xEB, 0xBE, + 0x86, 0x0C, 0x89, 0x5F, 0xAE, 0x83, 0xA6, 0xB2, + 0x30, 0x38, 0x06, 0xEC, 0xA3, 0x71, 0x4F, 0x56, + 0x2B, 0xB4, 0xD9, 0x9D, 0xDE, 0x6D, 0x3C, 0x27, + 0xFA, 0xBB, 0x07, 0xD3, 0x1D, 0x5A, 0xDD, 0xEF, + 0x35, 0xCF, 0x17, 0x0B, 0xA1, 0x5A, 0x1E, 0x69, + 0x4E, 0x38, 0x62, 0x20, 0x8E, 0xDB, 0x9A, 0x1C, + 0xB6, 0x83, 0x4D, 0xA6, 0x12, 0x36, 0x6E, 0x18, + 0x7A, 0xDF, 0xC0, 0x29, 0x89, 0x98, 0x40, 0xBD, + 0x66, 0x49, 0xE2, 0xC0, 0xC5, 0xE7, 0x55, 0x37, + 0x97, 0x8F, 0xAC, 0xB2, 0xC4, 0x19, 0x4C, 0x89, + 0xA7, 0x9B, 0x07, 0x50, 0x87, 0x5D, 0x8D, 0x39, + 0xFF, 0x7C, 0x30, 0x9D, 0x69, 0xEF, 0x72, 0x55, + 0xA9, 0x94, 0x76, 0xB7, 0xEB, 0xF1, 0xA0, 0xBD, + 0xDC, 0x98, 0x91, 0xF7, 0x09, 0x30, 0x68, 0xC5, + 0x29, 0xEC, 0xC1, 0xFE, 0x66, 0x7A, 0x6E, 0xF1, + 0x09, 0x25, 0x39, 0xA0, 0x01, 0x88, 0xCA, 0x56, + 0xCD, 0x92, 0xFB, 0x5E, 0x59, 0xF0, 0xDF, 0x25, + 0x7E, 0x89, 0x3A, 0x80, 0xE1, 0x93, 0x44, 0x52, + 0x36, 0xC0, 0xE8, 0x2C, 0xD1, 0x9E, 0xC4, 0xA1, + 0x3F, 0x37, 0x5B, 0xC7, 0x99, 0x59, 0x11, 0xAC, + 0x22, 0xCD, 0x14, 0xB5, 0x0D, 0x5E, 0xAB, 0x8E, + 0xB5, 0x76, 0x19, 0xA9, 0xE3, 0xA3, 0xAE, 0xF0, + 0x24, 0x4E, 0xF4, 0xE2, 0x3C, 0x36, 0x6F, 0x35, + 0x73, 0x59, 0x23, 0x83, 0x22, 0xBB, 0x61, 0xC0, + 0xCA, 0x82, 0x4D, 0x8E, 0xC9, 0x16, 0x5F, 0x6D, + 0x0A, 0x28, 0xF9, 0x90, 0xB7, 0x5C, 0x6A, 0x49, + 0x68, 0x9E, 0xF3, 0xA0, 0x46, 0xF7, 0x47, 0x52, + 0xB7, 0xCA, 0x5B, 0xB1, 0xAB, 0x74, 0x45, 0xD5, + 0xB2, 0x9C, 0xAF, 0x68, 0xE7, 0xF0, 0x80, 0x5C, + 0xDD, 0xA4, 0xA5, 0x7B, 0x57, 0xFA, 0xE1, 0xE7, + 0x61, 0xC1, 0x8A, 0xAE, 0x21, 0x50, 0x64, 0x00, + 0x85, 0x92, 0xE6, 0x19, 0xB7, 0x5E, 0x66, 0xB0, + 0xF8, 0x2D, 0x16, 0xCA, 0x16, 0x18, 0x25, 0x4D, + 0x02, 0x79, 0x37, 0x36, 0x3A, 0x73, 0x47, 0x37, + 0x0C, 0x2C, 0xD3, 0xE4, 0xEE, 0x00, 0x41, 0x4B, + 0xBB, 0x90, 0x06, 0x76, 0x31, 0xA2, 0x1B, 0x08, + 0x1D, 0x6B, 0x71, 0xF6, 0xD4, 0xAB, 0x9C, 0xE8, + 0x08, 0xD5, 0x1E, 0xE9, 0x1F, 0x12, 0xF4, 0x7F, + 0x3B, 0x40, 0x47, 0x5D, 0xAB, 0x6E, 0xA2, 0x26, + 0x7C, 0x59, 0xFD, 0x11, 0x0C, 0x53, 0x11, 0x2E, + 0x40, 0x4E, 0xA9, 0x31, 0x1E, 0x5D, 0xD3, 0x17, + 0x5E, 0xF6, 0xAB, 0x60, 0x6B, 0xBF, 0x3B, 0x35, + 0x05, 0xD8, 0x81, 0xF6, 0x39, 0x7A, 0x2F, 0x59, + 0xF8, 0x13, 0x2C, 0x40, 0xB0, 0x24, 0x06, 0xAD, + 0xB1, 0x0F, 0x6F, 0xB6, 0x40, 0xBB, 0xDE, 0xFA, + 0xC2, 0xDE, 0x17, 0x06, 0xB9, 0xC1, 0x3F, 0x9C, + 0x62, 0x2C, 0xD8, 0xFB, 0x9C, 0x28, 0x3E, 0x48, + 0x8B, 0x7A, 0xE4, 0x7E, 0x68, 0x79, 0x9C, 0xFB, + 0x3E, 0xD0, 0xB0, 0xCC, 0xCB, 0xF3, 0x89, 0x0E, + 0xB4, 0x0B, 0xA1, 0x69, 0x8F, 0xE9, 0xE7, 0x97, + 0xF0, 0x93, 0x18, 0xD9, 0x88, 0x28, 0xE4, 0x0B, + 0x31, 0x32, 0xEB, 0x68, 0xD2, 0x70, 0x23, 0xDB, + 0x13, 0x89, 0x2F, 0xA4, 0xBF, 0xD4, 0x12, 0x78, + 0xB2, 0x56, 0x4C, 0x74, 0x36, 0x82, 0x4E, 0xC6, + 0xD2, 0xA1, 0x85, 0x00, 0xB2, 0x5C, 0xF7, 0x64, + 0xB5, 0xFB, 0x27, 0xCC, 0x8E, 0x5F, 0xDB, 0x32, + 0x4F, 0x07, 0xAE, 0x6C, 0x6F, 0x6D, 0xF4, 0xAE, + 0x53, 0x5A, 0x0F, 0x8C, 0x06, 0x2F, 0x3B, 0x9E, + 0xB1, 0xAB, 0x98, 0x23, 0xF3, 0xCB, 0x8E, 0x75, + 0xB7, 0x54, 0x81, 0xBD, 0x78, 0x9B, 0x98, 0xE8, + 0x0B, 0xCF, 0x15, 0xDE, 0xF8, 0xEF, 0xCA, 0x87, + 0xD4, 0x49, 0xBA, 0x5C, 0x56, 0x03, 0x03, 0x44, + 0x7E, 0x00, 0xA3, 0x1E, 0x74, 0xFE, 0xEB, 0xEC, + 0x5A, 0x5C, 0x32, 0x25, 0x10, 0x68, 0x3F, 0x69, + 0xBC, 0x7A, 0x1A, 0x5F, 0x46, 0x79, 0x10, 0xF6, + 0x78, 0x7D, 0x18, 0x98, 0x23, 0xCD, 0xE0, 0x1A, + 0x5F, 0x24, 0xF0, 0xB5, 0xB6, 0x6F, 0xAD, 0x7E, + 0x55, 0xC6, 0x0F, 0x43, 0x8F, 0xF3, 0x38, 0xDE, + 0x91, 0x00, 0x60, 0x1D, 0x24, 0x92, 0x68, 0xD1, + 0x9D, 0x85, 0x08, 0xC4, 0x74, 0x69, 0xE5, 0xA9, + 0x61, 0xEB, 0xB6, 0x38, 0x65, 0x28, 0x10, 0x8C, + 0x86, 0x3F, 0xA8, 0x12, 0x72, 0xC9, 0x96, 0x53, + 0x83, 0xC7, 0x81, 0xAE, 0x99, 0xB9, 0x68, 0xDF, + 0xFA, 0x04, 0x34, 0x8B, 0x70, 0xA7, 0xE6, 0xEC, + 0xD8, 0xBA, 0x8A, 0x20, 0xA5, 0x37, 0xC0, 0x2A, + 0x8E, 0x12, 0x70, 0x95, 0xDC, 0x87, 0x2E, 0x96, + 0x7A, 0x01, 0x89, 0x9B, 0x86, 0x8B, 0x7D, 0x52, + 0x75, 0x32, 0x15, 0x31, 0xD0, 0x0E, 0xD5, 0x35, + 0x74, 0xE2, 0x90, 0x86, 0x56, 0x46, 0x12, 0x12, + 0xD8, 0xA8, 0x0E, 0x60, 0xC3, 0x67, 0xBF, 0x35, + 0x9E, 0x45, 0x7E, 0xFA, 0x7A, 0xB3, 0x75, 0xF9, + 0x17, 0x9E, 0xA1, 0xF7, 0xEB, 0x3F, 0xF4, 0x55, + 0x4E, 0x31, 0xD7, 0xB8, 0xEE, 0xB4, 0x54, 0x03, + 0x90, 0x80, 0xDD, 0xE4, 0xB9, 0x09, 0x2E, 0x7C, + 0x6A, 0xF5, 0xB4, 0x22, 0x11, 0x60, 0x19, 0x5C, + 0x28, 0x5A, 0x42, 0xDB, 0xF7, 0xA7, 0xBF, 0xCA, + 0x53, 0x5A, 0xDA, 0x81, 0x91, 0xF8, 0xB5, 0x45, + 0xF2, 0x2B, 0x47, 0xAA, 0xAE, 0x87, 0x96, 0xC8, + 0xEB, 0x14, 0x0C, 0x7B, 0x35, 0x49, 0xA9, 0x21, + 0x6E, 0x93, 0xF5, 0x27, 0x4E, 0x7B, 0xD2, 0x2F, + 0x24, 0x54, 0x6F, 0xBB, 0x0F, 0x42, 0xD8, 0x08, + 0x21, 0x6D, 0x7E, 0xB8, 0x10, 0x0C, 0xFB, 0xA8, + 0xCB, 0x3A, 0x96, 0x7C, 0x56, 0x8D, 0xE5, 0x0D, + 0xA9, 0x47, 0x5C, 0xB6, 0x26, 0x4D, 0x87, 0x99, + 0x70, 0x47, 0x35, 0xBE, 0x02, 0x34, 0xF0, 0x8D, + 0x1E, 0x86, 0x25, 0xDC, 0xC3, 0xC6, 0xE3, 0x0B, + 0x01, 0x1A, 0x4D, 0x80, 0x05, 0xC2, 0xC3, 0xA6, + 0x63, 0xAE, 0x72, 0x2D, 0x60, 0x76, 0x8E, 0x7C, + 0xE9, 0xB8, 0x72, 0xD4, 0xCC, 0x8C, 0x19, 0xD2, + 0xA7, 0x5F, 0x97, 0xEE, 0x25, 0xFC, 0x01, 0x4E, + 0x3B, 0xF3, 0x09, 0x93, 0x32, 0xBF, 0xF1, 0xEE, + 0x2F, 0x0B, 0x38, 0xC6, 0xB1, 0xA4, 0x8C, 0x5B, + 0xA0, 0x17, 0xEF, 0xAA, 0x9C, 0x14, 0xD3, 0x0C, + 0x8B, 0x1B, 0x9E, 0x5A, 0x17, 0x32, 0x5F, 0xFD, + 0xE0, 0xCE, 0xAB, 0xB4, 0xCC, 0xD3, 0x6B, 0xF2, + 0x48, 0x0A, 0x3E, 0x09, 0x00, 0xD5, 0xDC, 0x74, + 0xA4, 0x52, 0xF8, 0x4A, 0x4F, 0x6B, 0x83, 0xFB, + 0x86, 0xEA, 0x7F, 0x7E, 0xCE, 0x13, 0x0E, 0xD6, + 0x89, 0xAA, 0xBF, 0x3A, 0x61, 0xD3, 0x5F, 0xF6, + 0x4A, 0x46, 0x6F, 0xC9, 0xED, 0xC3, 0xCA, 0xAB, + 0xDA, 0x66, 0xD5, 0x21, 0x96, 0x7C, 0x29, 0xF0, + 0x8C, 0x6F, 0x24, 0x4E, 0x3B, 0x24, 0xAB, 0x1E, + 0x97, 0xD6, 0xBE, 0xBF, 0xB9, 0x48, 0xFC, 0x79, + 0xA5, 0x80, 0xBF, 0x78, 0x11, 0xF9, 0x7A, 0x14, + 0x02, 0xC2, 0xEC, 0x65, 0x6E, 0x72, 0xB9, 0xDC, + 0xC1, 0xBD, 0x6C, 0x88, 0xCB, 0x41, 0xD5, 0x80, + 0x32, 0xC0, 0x89, 0x39, 0xDA, 0x2E, 0xAC, 0xAF, + 0xFE, 0x9C, 0xB7, 0x95, 0x70, 0x2D, 0x58, 0xBD, + 0x4E, 0x89, 0x3D, 0x29, 0x30, 0xF4, 0x01, 0x48, + 0xFF, 0x79, 0x8C, 0x9A, 0x69, 0x66, 0x24, 0x8B, + 0x83, 0x16, 0xF2, 0x95, 0xD5, 0x09, 0x6F, 0x7E, + 0xEA, 0x75, 0x32, 0x4C, 0xB2, 0x0E, 0xE2, 0xA9, + 0x8C, 0x09, 0x0E, 0xFF, 0xC6, 0x2D, 0x65, 0x56, + 0x10, 0x9C, 0x65, 0x0A, 0x63, 0x33, 0xB9, 0x07, + 0x27, 0x63, 0x95, 0xC3, 0xEB, 0x8E, 0xC7, 0x97, + 0x41, 0xF4, 0x97, 0xEE, 0xE1, 0x6C, 0x07, 0x6F, + 0xB2, 0x28, 0x9C, 0x8E, 0x5E, 0x9E, 0x0B, 0x28, + 0x22, 0xCA, 0x79, 0x36, 0x7A, 0x56, 0xDA, 0x24, + 0x82, 0xDB, 0xC3, 0x41, 0xDE, 0x82, 0xA1, 0x73, + 0x50, 0x06, 0x5E, 0x83, 0xEE, 0x18, 0x15, 0x43, + 0x1B, 0xB5, 0xC2, 0xB6, 0x22, 0x24, 0x2E, 0xDF, + 0x6C, 0x99, 0xAF, 0x5D, 0xF6, 0xC3, 0x19, 0xD9, + 0x18, 0x13, 0xA1, 0x6B, 0x07, 0xCD, 0xE2, 0x58, + 0x5B, 0x01, 0xFD, 0x50, 0x32, 0x34, 0x03, 0xE4, + 0x84, 0x3F, 0x2E, 0x08, 0x21, 0x91, 0x8F, 0xFC, + 0xD6, 0x5E, 0xFB, 0x4E, 0x86, 0x69, 0x84, 0xCB, + 0x48, 0xCC, 0x54, 0x85, 0xC3, 0x13, 0x6E, 0x5D, + 0x64, 0x17, 0x05, 0xE3, 0xC8, 0xE9, 0x75, 0x51, + 0xB3, 0x21, 0xD1, 0xAC, 0x40, 0x75, 0x1B, 0x47, + 0x2C, 0x96, 0xAC, 0x00, 0x20, 0xF8, 0x9E, 0xBA, + 0x55, 0x70, 0x7B, 0x39, 0xEE, 0x9A, 0x86, 0xCD, + 0x95, 0x77, 0x84, 0xEC, 0xAF, 0xAB, 0x27, 0xC3, + 0xBF, 0xA8, 0x9E, 0x94, 0x13, 0x52, 0x95, 0xF6, + 0x40, 0xB1, 0x57, 0xD8, 0x4D, 0xB2, 0xA8, 0xBF, + 0x47, 0x06, 0x4A, 0x2F, 0x90, 0x4F, 0x07, 0xA1, + 0x71, 0xDF, 0x1E, 0x20, 0x25, 0xA4, 0x74, 0x53, + 0xA6, 0x65, 0x99, 0x5B, 0x90, 0x2C, 0xEA, 0x1A, + 0xE9, 0x70, 0xD8, 0x2B, 0x2E, 0x74, 0x0A, 0x50, + 0x97, 0xBB, 0x7E, 0xFD, 0x08, 0x00, 0x39, 0x05, + 0x02, 0x73, 0xB2, 0xEF, 0x5D, 0xDE, 0xCE, 0x02, + 0x0F, 0xE1, 0x26, 0x76, 0x2B, 0x23, 0x17, 0x90, + 0xF8, 0xC2, 0x29, 0x68, 0xD0, 0x9B, 0xC2, 0xAB, + 0x33, 0x61, 0x05, 0x03, 0x35, 0xD4, 0x6B, 0xA5, + 0x33, 0x8C, 0x35, 0xFC, 0x9E, 0x96, 0xA8, 0xAF, + 0x04, 0x3F, 0x02, 0x3E, 0xCF, 0xE0, 0x57, 0x3C, + 0xEB, 0x06, 0xEE, 0xCB, 0x65, 0x02, 0xFF, 0x84, + 0x72, 0x37, 0x74, 0xF0, 0x5B, 0xA2, 0xDA, 0x0E, + 0x32, 0x3C, 0xAE, 0xA8, 0x01, 0xA2, 0xCA, 0x32, + 0xA2, 0x0A, 0x4B, 0x2E, 0xE8, 0xCE, 0xB6, 0x7E, + 0x07, 0x3A, 0x04, 0xDA, 0xD8, 0x1D, 0x32, 0x0D, + 0xD9, 0xEC, 0xF6, 0x81, 0xCB, 0x14, 0x78, 0xB7, + 0xC0, 0xE8, 0x61, 0x78, 0x43, 0xAF, 0xCC, 0x90, + 0x1F, 0x26, 0x16, 0xC2, 0x2F, 0xC8, 0xBA, 0x09, + 0xEF, 0x18, 0x10, 0x6F, 0x00, 0x14, 0xCD, 0x22, + 0xE5, 0x01, 0xE0, 0x1B, 0xF2, 0xD7, 0x48, 0xD1, + 0x32, 0x5A, 0x1D, 0xB9, 0xFB, 0xC9, 0x6F, 0xC4, + 0xE6, 0x74, 0xC9, 0x66, 0x1B, 0x7D, 0x2A, 0x31, + 0x2D, 0x3D, 0x7F, 0xF2, 0xD1, 0xC2, 0xB4, 0x0E, + 0x8A, 0x4A, 0x6A, 0x16, 0xA5, 0xDC, 0xFE, 0x3B, + 0xB5, 0x78, 0x6F, 0x1A, 0x64, 0xB5, 0x3D, 0x2C, + 0x45, 0xD8, 0x3C, 0x84, 0xF7, 0xD4, 0xE5, 0x38, + 0xB9, 0xEA, 0xFA, 0xD7, 0x08, 0x20, 0x4A, 0xBA, + 0x3C, 0x36, 0x4F, 0x86, 0xCF, 0x12, 0xAA, 0x45, + 0x83, 0x6B, 0x28, 0xB9, 0x1D, 0x68, 0x61, 0x4C, + 0x54, 0x2F, 0x7A, 0xAB, 0x41, 0x95, 0x9E, 0x28, + 0xEB, 0x93, 0x2E, 0xA9, 0x49, 0x7F, 0x5B, 0xB4, + 0x0A, 0xCE, 0x7A, 0x07, 0x6D, 0xA9, 0x96, 0xA5, + 0x6B, 0x40, 0x3C, 0xB4, 0x5A, 0x93, 0x4C, 0xFB, + 0x1D, 0x32, 0x41, 0x05, 0x28, 0x70, 0x2C, 0x34, + 0x36, 0x7B, 0x75, 0xB9, 0xD1, 0x0B, 0x6C, 0x1D, + 0xD1, 0x8A, 0xD6, 0xA9, 0xD9, 0xE2, 0x90, 0xA6, + 0xA3, 0x49, 0xBA, 0x76, 0xA2, 0x46, 0x93, 0xA2, + 0x2D, 0xAC, 0x6F, 0x1E, 0x25, 0x98, 0xA3, 0xE4, + 0x1C, 0x90, 0xAD, 0x44, 0x1F, 0x77, 0x5E, 0x66, + 0x62, 0x12, 0x1F, 0xDC, 0x96, 0xD3, 0x9A, 0xB2, + 0x5C, 0xDA, 0xBB, 0x51, 0x60, 0x70, 0x81, 0x40, + 0xDB, 0x0D, 0xDA, 0x09, 0xCA, 0x64, 0xB4, 0x83, + 0x0A, 0x01, 0xBB, 0xE1, 0x79, 0xBB, 0x24, 0xE8, + 0xA1, 0x92, 0x5C, 0x77, 0x77, 0x99, 0xC5, 0xBE, + 0x2E, 0x51, 0x97, 0x4E, 0x52, 0x3A, 0xAF, 0xE5, + 0x43, 0x22, 0xE9, 0x7E, 0xDC, 0x5D, 0x82, 0xF5, + 0xB3, 0x63, 0xEB, 0x03, 0x6B, 0xCC, 0x3A, 0x7F, + 0x70, 0x33, 0x7B, 0x6A, 0x0C, 0x85, 0x72, 0xDF, + 0x31, 0x9E, 0x9C, 0xED, 0xB9, 0xB9, 0x82, 0xED, + 0xEB, 0xB5, 0x10, 0x3B, 0x33, 0x30, 0xD0, 0x66, + 0xF2, 0xF6, 0xB9, 0x8F, 0x44, 0xA8, 0x21, 0xE0, + 0x5D, 0x92, 0xC8, 0xC6, 0x02, 0x2E, 0x0C, 0xF6, + 0x86, 0xB5, 0x51, 0x6E, 0x39, 0xA5, 0x87, 0x4C, + 0x2C, 0x9A, 0x04, 0x20, 0x70, 0xC5, 0xB4, 0x20, + 0xB7, 0xCF, 0x72, 0x50, 0x95, 0x66, 0x11, 0xBC, + 0x10, 0xBB, 0x4F, 0xF6, 0xFD, 0xE2, 0x78, 0xFF, + 0x00, 0x17, 0x8C, 0xF0, 0xBB, 0xA1, 0xAA, 0x52, + 0x49, 0xAC, 0x83, 0x0B, 0x9B, 0xAF, 0x07, 0x17, + 0x7E, 0xD1, 0x50, 0x1E, 0xC2, 0x1E, 0xD6, 0x3E, + 0x41, 0x99, 0x84, 0xEC, 0x9A, 0x31, 0x4A, 0x84, + 0xD4, 0x71, 0xFC, 0x5E, 0x5E, 0xF9, 0xC6, 0x4D, + 0x25, 0x86, 0x0F, 0xF3, 0x85, 0xFA, 0xF1, 0x4F, + 0x76, 0xCB, 0x2E, 0x97, 0x69, 0xA7, 0x80, 0xE9, + 0x8A, 0xCA, 0x74, 0x58, 0x1A, 0x0A, 0x3B, 0x88, + 0x56, 0x18, 0x6C, 0x4C, 0x44, 0x91, 0xE6, 0xD7, + 0x49, 0x59, 0xF6, 0xF0, 0xE0, 0x7A, 0x75, 0x3F, + 0x08, 0x67, 0x6A, 0x1D, 0x63, 0x97, 0x8C, 0x62, + 0x6C, 0x97, 0x07, 0xB9, 0x1B, 0x2B, 0xF4, 0x24, + 0x7D, 0x53, 0xB0, 0x6E, 0x76, 0x0D, 0xF3, 0x36, + 0x77, 0xE1, 0xA5, 0x18, 0x0F, 0x29, 0xE8, 0x8B, + 0x5D, 0x26, 0xEA, 0x7B, 0xA4, 0x16, 0x37, 0x92, + 0x1C, 0xD7, 0x46, 0x76, 0x30, 0x30, 0x98, 0x47, + 0xFB, 0x79, 0xD7, 0xC9, 0xE3, 0x1C, 0xAE, 0x3F, + 0x0C, 0x04, 0xC6, 0x5D, 0x78, 0xA6, 0xAF, 0x34, + 0x28, 0x60, 0x53, 0x34, 0x57, 0x94, 0xA5, 0x90, + 0x6E, 0x82, 0xFC, 0xFF, 0x56, 0x64, 0xE8, 0x30, + 0xEC, 0x9F, 0x54, 0x32, 0x74, 0x4F, 0x29, 0x42, + 0xFE, 0x0A, 0x75, 0xFD, 0x99, 0xCC, 0x88, 0x4F, + 0x2F, 0xFB, 0x93, 0xAE, 0x0B, 0xA1, 0x37, 0xD5, + 0xCD, 0x58, 0xAD, 0xF4, 0xFC, 0x14, 0xC9, 0xDB, + 0xCC, 0x3B, 0x62, 0xF6, 0xF1, 0xFD, 0x52, 0xBE, + 0xE7, 0xB5, 0x04, 0x08, 0x49, 0xF0, 0xBE, 0x88, + 0x18, 0x0A, 0x68, 0xC0, 0xCC, 0x1F, 0x42, 0x65, + 0xED, 0x53, 0x0D, 0xD4, 0xE1, 0xE6, 0x5E, 0xBF, + 0x47, 0xF1, 0xCE, 0x97, 0xE3, 0x69, 0xDD, 0x77, + 0x21, 0xA5, 0x3D, 0x07, 0x9C, 0xEC, 0x3C, 0x3C, + 0x2F, 0x62, 0xBF, 0xA8, 0xB4, 0x3F, 0x89, 0x94, + 0x94, 0xBE, 0xB8, 0xE9, 0x56, 0xFF, 0x6D, 0x7A, + 0x75, 0xCD, 0xEA, 0xB4, 0xC6, 0xAE, 0xFC, 0x26, + 0x13, 0x99, 0x62, 0x3E, 0x33, 0x83, 0xEE, 0xB7, + 0xCC, 0x90, 0x7D, 0xB4, 0x17, 0x05, 0x7D, 0x80, + 0xEE, 0x6A, 0xF7, 0x0A, 0xC7, 0x7A, 0x1F, 0xE0, + 0xA2, 0xBA, 0x6A, 0x0A, 0x9D, 0xCF, 0xA7, 0x63, + 0x56, 0x3B, 0x2D, 0x56, 0x36, 0x3B, 0x61, 0xBD, + 0x9B, 0x9E, 0x80, 0x02, 0xA0, 0xD2, 0x03, 0xA9, + 0x28, 0x41, 0xC5, 0xEB, 0x5A, 0xEE, 0x1D, 0xE7, + 0x5D, 0xC8, 0xE9, 0xDB, 0xFF, 0xCA, 0x58, 0x17, + 0xD1, 0x2D, 0xFE, 0x90, 0x5F, 0x63, 0x6F, 0x7F, + 0x62, 0xD0, 0xC8, 0x8D, 0x23, 0xB0, 0x17, 0xAF, + 0x97, 0x42, 0xD0, 0x7D, 0x3D, 0x25, 0x33, 0x30, + 0xDD, 0xA2, 0xAF, 0x83, 0x80, 0x35, 0x47, 0xA5, + 0x21, 0x9D, 0x31, 0xF8, 0xE8, 0xE3, 0x55, 0x45, + 0x9F, 0xDE, 0x80, 0x9B, 0xFF, 0x87, 0x72, 0x08, + 0xEB, 0x49, 0xF6, 0x11, 0xE0, 0x7B, 0xC8, 0x02, + 0x83, 0xBE, 0x55, 0x86, 0x29, 0x4B, 0x5F, 0x42, + 0xFA, 0xDD, 0x14, 0xFC, 0xCB, 0x90, 0xC1, 0xBC, + 0xDC, 0x99, 0x0E, 0x0E, 0x7F, 0xD0, 0x5C, 0xAD, + 0xE8, 0x64, 0x0A, 0xD6, 0x6F, 0xE0, 0x06, 0xB7, + 0x42, 0xAE, 0xCD, 0x07, 0x63, 0x5F, 0x17, 0xA9, + 0x54, 0x0A, 0xCB, 0x31, 0x51, 0xE8, 0xD3, 0x43, + 0xF5, 0xFC, 0xBE, 0xFB, 0x49, 0xA9, 0xF9, 0x4B, + 0x72, 0xBF, 0xA4, 0x8D, 0xFF, 0x01, 0xA8, 0x1F, + 0xF0, 0x80, 0xED, 0xEB, 0xB0, 0x1C, 0xB3, 0x09, + 0xD4, 0xB5, 0x39, 0xD5, 0x33, 0xCC, 0x58, 0xDA, + 0xE7, 0x6C, 0xCA, 0x91, 0xAE, 0x5D, 0x54, 0xA7, + 0xB3, 0xAD, 0x9C, 0x2B, 0x4B, 0x81, 0x34, 0xFE, + 0xFA, 0x8A, 0x43, 0x0B, 0xDA, 0x26, 0xDA, 0x98, + 0x0F, 0xB0, 0x6E, 0x1E, 0x4F, 0xD6, 0xB3, 0x2F, + 0x07, 0x64, 0xEB, 0xB9, 0xE5, 0x03, 0x24, 0xAE, + 0xDD, 0xB5, 0x4B, 0x1E, 0x3F, 0xE9, 0x1F, 0xA6, + 0x96, 0xF3, 0xFA, 0x10, 0xC5, 0x03, 0xB4, 0xC8, + 0x6B, 0x33, 0x3C, 0x0E, 0xFD, 0xEB, 0xC7, 0x6B, + 0xDD, 0x9C, 0xA3, 0x15, 0x42, 0xF0, 0xE1, 0xC1, + 0x7B, 0xDF, 0x35, 0x94, 0xB1, 0xA1, 0x99, 0xDE, + 0x7D, 0xF4, 0x2A, 0xE9, 0x90, 0x8C, 0x17, 0x10, + 0xE4, 0x71, 0x4F, 0xE7, 0x99, 0x81, 0x98, 0x81, + 0xAE, 0xD8, 0x8A, 0x7E, 0xD8, 0xD0, 0xBE, 0xD5, + 0x18, 0x32, 0x1F, 0xCD, 0x24, 0x8F, 0x1B, 0x0D, + 0x75, 0xD7, 0xFD, 0x44, 0xE5, 0x4A, 0x67, 0x49, + 0xFC, 0x0A, 0xA3, 0x32, 0x40, 0x7C, 0xF9, 0x22, + 0x35, 0x47, 0xED, 0x23, 0x34, 0x9B, 0x36, 0xEC, + 0x50, 0xCE, 0x5B, 0x9D, 0x16, 0x3E, 0xD9, 0xE5, + 0x52, 0xCB, 0x02, 0x7F, 0xDC, 0x7E, 0x2B, 0xEF, + 0x01, 0x6F, 0xA6, 0x0D, 0x92, 0xD5, 0x25, 0x6F, + 0x32, 0x81, 0xF7, 0x32, 0xB7, 0x44, 0x54, 0x80, + 0xA2, 0x58, 0x2B, 0xD4, 0xDE, 0x22, 0x26, 0x3B, + 0xB8, 0xD5, 0xA2, 0x50, 0x9C, 0x17, 0x93, 0x92, + 0x51, 0xC8, 0x9B, 0x14, 0x2F, 0xC9, 0xC0, 0x6C, + 0xFD, 0xC5, 0xAB, 0x02, 0x75, 0x2D, 0x91, 0x3C, + 0x33, 0xCB, 0xA5, 0x51, 0x68, 0x2C, 0xF5, 0x2B, + 0x8A, 0xF8, 0x40, 0xB9, 0x3F, 0x2F, 0xC7, 0x94, + 0x43, 0x9A, 0xE2, 0xB3, 0xA2, 0xE2, 0xA4, 0x35, + 0x20, 0x41, 0x47, 0xD7, 0xBF, 0xAB, 0xEF, 0x1E, + 0x05, 0x8C, 0xAF, 0x4D, 0xB1, 0x2A, 0xC6, 0x68, + 0x29, 0x15, 0xDA, 0xB4, 0x75, 0xF8, 0x5C, 0xE4, + 0xFE, 0x97, 0x4C, 0x18, 0xE9, 0x50, 0x0B, 0x34, + 0x90, 0x58, 0x3E, 0x8A, 0x0C, 0xE9, 0x38, 0x5E, + 0x2C, 0x0E, 0x69, 0x58, 0x05, 0x1D, 0xFB, 0xF1, + 0x5B, 0xBF, 0x02, 0xED, 0xDA, 0x37, 0xE8, 0x1D, + 0x83, 0xCD, 0x49, 0x35, 0x27, 0xB7, 0x50, 0xCD, + 0xBF, 0x32, 0xCD, 0xE1, 0x9D, 0xE1, 0x45, 0xCF, + 0x67, 0xD3, 0xF1, 0xF4, 0x8B, 0x1B, 0xAF, 0x36, + 0x6C, 0x85, 0xB8, 0x5C, 0x66, 0xCA, 0x32, 0x26, + 0x53, 0xE7, 0xD5, 0x76, 0xF7, 0x4F, 0x5F, 0x8A, + 0xA5, 0x93, 0x69, 0xAB, 0x81, 0x80, 0xAB, 0xFE, + 0x98, 0x08, 0x7F, 0x35, 0xB9, 0x01, 0x49, 0xD3, + 0x44, 0xFA, 0xD6, 0x1D, 0xE2, 0xB4, 0x13, 0x9D, + 0xB5, 0xCE, 0x08, 0xCB, 0x99, 0xA2, 0x0A, 0xCE, + 0xBA, 0xAB, 0x97, 0xE9, 0x1C, 0xFE, 0xCD, 0xEC, + 0x3E, 0xFA, 0x17, 0x76, 0x8E, 0x6B, 0x0B, 0x50, + 0x6A, 0x65, 0x67, 0x7D, 0x5E, 0x22, 0xA1, 0xA0, + 0x44, 0x05, 0x70, 0x2A, 0xBC, 0xB9, 0x0E, 0x87, + 0x7B, 0xA0, 0x61, 0x5E, 0xBC, 0x8B, 0x2C, 0x64, + 0xCA, 0x51, 0x10, 0x08, 0xA2, 0xDF, 0xB0, 0x0A, + 0x30, 0xD9, 0x6F, 0xA5, 0x57, 0xB1, 0x13, 0x6B, + 0xD9, 0xDD, 0x57, 0x37, 0x90, 0x35, 0xED, 0x9F, + 0x46, 0xCA, 0x7D, 0x3B, 0xBC, 0x56, 0x92, 0x28, + 0xDE, 0x5B, 0xD9, 0xBA, 0x76, 0xB5, 0xA7, 0x1E, + 0x32, 0x9A, 0xCB, 0x7D, 0x52, 0x3A, 0xA7, 0xC3, + 0xB7, 0xAF, 0x5C, 0x4F, 0x76, 0xC3, 0xAD, 0xD6, + 0x57, 0x16, 0x26, 0x29, 0x34, 0xED, 0xC8, 0xAD, + 0xFF, 0xC6, 0xE8, 0xBE, 0x49, 0x58, 0xE3, 0x4D, + 0x61, 0xE8, 0x4F, 0x10, 0x46, 0x55, 0x39, 0xB2, + 0x6A, 0x6D, 0x12, 0x6B, 0xBA, 0x55, 0xB9, 0x19, + 0x72, 0xC0, 0x49, 0x2B, 0x5C, 0x95, 0xDF, 0x6A, + 0xA2, 0x7A, 0xCB, 0x6E, 0x32, 0xC1, 0x59, 0x86, + 0x15, 0xFA, 0x09, 0xA4, 0x24, 0x28, 0x21, 0x42, + 0x6F, 0x91, 0xCF, 0x5E, 0x49, 0x53, 0xBF, 0xC1, + 0xB2, 0xB3, 0xF9, 0x53, 0x39, 0x7B, 0xC0, 0x2F, + 0xDF, 0x02, 0xF2, 0xAC, 0x9C, 0x7F, 0xA6, 0x96, + 0x87, 0x5C, 0x2E, 0x61, 0xAE, 0xB2, 0x5B, 0xA6, + 0x31, 0xA0, 0xDF, 0x1B, 0x2B, 0xF6, 0xDF, 0x5C, + 0x2F, 0x2A, 0x03, 0x13, 0xA0, 0x60, 0xBA, 0xE1, + 0x83, 0xF7, 0x0E, 0x85, 0x48, 0x0B, 0xBC, 0xCB, + 0x81, 0xCA, 0x1D, 0x7A, 0x11, 0xB6, 0xF3, 0x9B, + 0xAC, 0x51, 0x80, 0xB7, 0x85, 0x58, 0xB7, 0xED, + 0x85, 0xF2, 0x5D, 0xD4, 0x70, 0xE3, 0xE4, 0x40, + 0x46, 0xCD, 0xD0, 0xF1, 0x40, 0x2E, 0xAC, 0x86, + 0xF9, 0xCB, 0x21, 0xD3, 0xFC, 0x52, 0x23, 0x0D, + 0x67, 0x06, 0x0B, 0x63, 0x1E, 0x8B, 0x36, 0x47, + 0x39, 0x16, 0xDB, 0xBA, 0xE7, 0x07, 0x18, 0xEE, + 0x6B, 0x65, 0xFF, 0x2B, 0xF3, 0xF3, 0xC9, 0x4C, + 0x31, 0xC9, 0xD2, 0x73, 0x03, 0x8E, 0x79, 0x4C, + 0xD7, 0x67, 0x23, 0x5C, 0xDC, 0xA5, 0x55, 0xB8, + 0x34, 0xCA, 0x7D, 0x2A, 0x5C, 0x4D, 0x0F, 0x42, + 0xC2, 0xAB, 0x30, 0x7D, 0xBC, 0x96, 0x61, 0x8E, + 0x93, 0xA5, 0xE5, 0x88, 0xDF, 0xC0, 0xD5, 0xC1, + 0x86, 0xD2, 0x04, 0xE0, 0x26, 0x77, 0x27, 0xD0, + 0x77, 0xC6, 0x18, 0x10, 0x58, 0x6E, 0xCF, 0x9E, + 0x41, 0xE7, 0x0D, 0xBB, 0xB8, 0xA9, 0x09, 0x58, + 0xCC, 0x01, 0x49, 0xCD, 0xE7, 0x70, 0x7E, 0x02, + 0x22, 0xD7, 0x50, 0x2F, 0x76, 0x79, 0xB4, 0xD5, + 0x94, 0x67, 0x33, 0x56, 0x90, 0x5E, 0x8F, 0x00, + 0xFF, 0xFD, 0x59, 0x32, 0x82, 0xF3, 0x08, 0xA9, + 0x24, 0x84, 0xFE, 0xBB, 0x9D, 0xE4, 0x65, 0x43, + 0x15, 0xF5, 0xEA, 0xDB, 0x18, 0xA3, 0x30, 0x3F, + 0x5E, 0x27, 0x24, 0x18, 0xDF, 0x84, 0xD8, 0xF1, + 0x7B, 0x3C, 0xB3, 0xC1, 0xF5, 0xA4, 0x42, 0x13, + 0x3F, 0x1A, 0xD2, 0x0F, 0x04, 0x2C, 0x92, 0x22, + 0x4F, 0x0C, 0x0A, 0xF0, 0x3E, 0xF4, 0x4A, 0xF0, + 0xBF, 0xB0, 0xBD, 0x72, 0xC2, 0xC6, 0xFF, 0x62, + 0x3A, 0x3D, 0x1F, 0x09, 0x38, 0x3B, 0xEE, 0x9C, + 0xE1, 0x21, 0xE5, 0xF2, 0x8C, 0x49, 0x31, 0xA2, + 0x2A, 0x7D, 0xBE, 0x7D, 0x45, 0x4A, 0x88, 0xDC, + 0x49, 0xDE, 0x95, 0x7B, 0xA8, 0x83, 0x98, 0xC7, + 0xF0, 0x8D, 0x96, 0xB5, 0x75, 0x5C, 0xFF, 0x08, + 0x04, 0xC5, 0x3C, 0x5C, 0x43, 0xC1, 0xFD, 0x9E, + 0xE5, 0xB5, 0x6E, 0x29, 0x3F, 0x3C, 0x0E, 0xE1, + 0x48, 0xD9, 0xC7, 0x80, 0x59, 0x6D, 0xFE, 0x34, + 0x4C, 0x11, 0xF9, 0xDC, 0xA0, 0x82, 0x90, 0x1E, + 0x8F, 0x01, 0x44, 0x12, 0x30, 0x1F, 0x4B, 0x10, + 0xDE, 0x0D, 0x65, 0x6A, 0xA1, 0x05, 0xC2, 0x03, + 0xD0, 0x69, 0xAB, 0xB4, 0x49, 0x10, 0x1F, 0x37, + 0x55, 0xE2, 0x83, 0x1D, 0x4B, 0x1F, 0x85, 0x64, + 0xB6, 0xA4, 0xAA, 0x4A, 0x38, 0xF3, 0xDE, 0x1F, + 0xF2, 0xA3, 0xC3, 0x14, 0xAA, 0xC4, 0xE2, 0x9F, + 0x6E, 0xCE, 0x42, 0xC2, 0xA7, 0x1A, 0xAB, 0xC0, + 0x56, 0xFB, 0xFD, 0x02, 0x5A, 0x12, 0xF9, 0xE8, + 0x81, 0xBB, 0x4E, 0x35, 0x9E, 0x5B, 0x1E, 0xD3, + 0xF9, 0x17, 0x1C, 0x07, 0x79, 0xAB, 0x18, 0xAD, + 0x80, 0xF8, 0xFA, 0x96, 0xB9, 0x6E, 0xD2, 0xB2, + 0xA2, 0x7B, 0x97, 0xCF, 0x67, 0x52, 0x4C, 0x84, + 0x8E, 0xB7, 0xAA, 0x48, 0xC1, 0x25, 0xF7, 0x73, + 0xE4, 0xE3, 0xB9, 0xE0, 0x0B, 0xC8, 0x55, 0x54, + 0xA2, 0x66, 0x8A, 0x51, 0x06, 0x42, 0xCF, 0x04, + 0xF3, 0xFC, 0x64, 0xDE, 0x4D, 0x55, 0x82, 0xC5, + 0x6D, 0x91, 0x1E, 0x81, 0x90, 0x57, 0x9F, 0x47, + 0x3B, 0x07, 0x91, 0xFD, 0xFD, 0xA3, 0x82, 0x58, + 0x4B, 0xC2, 0x04, 0xAB, 0xC2, 0x66, 0xD6, 0x39, + 0xCE, 0x69, 0xF9, 0x9D, 0x7F, 0xB5, 0x77, 0x4B, + 0xBE, 0xE1, 0x97, 0x46, 0xC7, 0xE4, 0xFE, 0xD2, + 0xD4, 0x52, 0x3E, 0x4B, 0x15, 0xED, 0x0D, 0xBA, + 0xD9, 0x41, 0xC6, 0xF6, 0x71, 0x23, 0xD2, 0x57, + 0x62, 0xF7, 0x9B, 0xFB, 0xBF, 0x36, 0x8A, 0xB1, + 0xD5, 0x26, 0xE1, 0x51, 0xF3, 0x2F, 0x14, 0xD2, + 0xED, 0xDD, 0x66, 0x46, 0xCB, 0xF0, 0x50, 0x34, + 0x4C, 0xCC, 0x12, 0x07, 0x52, 0x8E, 0x75, 0xB2, + 0x08, 0x74, 0xEB, 0x62, 0x74, 0xD8, 0x53, 0x2D, + 0x62, 0x9C, 0x29, 0x29, 0xF7, 0xC7, 0x5E, 0x45, + 0x59, 0x7C, 0xB1, 0xA5, 0x64, 0x75, 0xD0, 0xA6, + 0xA0, 0xD2, 0x36, 0xAE, 0xB8, 0x1A, 0x6B, 0xC8, + 0x44, 0x53, 0x32, 0x75, 0x9C, 0x1F, 0xEB, 0xAF, + 0x5A, 0xC2, 0x88, 0x0F, 0xBF, 0x89, 0x8E, 0xDA, + 0xFC, 0x47, 0x49, 0x5A, 0x9E, 0x5C, 0x6D, 0x7B, + 0xF7, 0xAA, 0x5C, 0x68, 0x08, 0x27, 0xDF, 0x24, + 0x38, 0x99, 0x7B, 0xF6, 0x48, 0xD0, 0x8C, 0xB8, + 0xE0, 0x4E, 0x73, 0x84, 0x9C, 0xAE, 0x26, 0xFD, + 0x05, 0x45, 0xF5, 0x7A, 0xDD, 0x7D, 0x3B, 0xBE, + 0x74, 0xDE, 0xA6, 0xC0, 0x59, 0x7F, 0xD9, 0xFD, + 0xD4, 0xCF, 0xB0, 0x6E, 0xB2, 0x42, 0x70, 0x95, + 0x55, 0x11, 0x8F, 0x6F, 0x7C, 0x8F, 0xD8, 0x23, + 0xEF, 0xB9, 0x8C, 0x46, 0x51, 0x13, 0xD7, 0xEB, + 0x34, 0xAB, 0x2B, 0x23, 0x96, 0x1D, 0x4A, 0x01, + 0xA6, 0x55, 0x6F, 0x7F, 0xD3, 0x67, 0x23, 0xBA, + 0x79, 0x7E, 0xB8, 0x7D, 0xA3, 0xBA, 0x0D, 0x5F, + 0x81, 0x51, 0x52, 0x6F, 0x39, 0xB2, 0xF7, 0x70, + 0x5B, 0x3A, 0x17, 0x31, 0xBA, 0x17, 0x0D, 0xF4, + 0x77, 0x87, 0xD8, 0x24, 0x0A, 0x0E, 0xBA, 0x8A, + 0xD0, 0xDB, 0x6E, 0xF9, 0xF6, 0x3B, 0xE4, 0x29, + 0x2A, 0x46, 0x53, 0xDA, 0x30, 0x11, 0xD6, 0x68, + 0x95, 0x4C, 0xD4, 0x38, 0x55, 0xD0, 0xD7, 0xBE, + 0xE2, 0x86, 0x08, 0x68, 0xBA, 0xE7, 0x61, 0xBD, + 0x31, 0x18, 0x24, 0xA7, 0x84, 0x0A, 0xC0, 0x11, + 0x85, 0x69, 0x04, 0x09, 0xF4, 0x2E, 0xF5, 0x65, + 0x08, 0x60, 0x91, 0x98, 0x07, 0xC3, 0xFB, 0xA5, + 0x39, 0xD6, 0xC0, 0x08, 0x59, 0xBA, 0x93, 0x40, + 0x98, 0xD0, 0x81, 0x80, 0x8D, 0x29, 0x19, 0x1C, + 0x28, 0xA1, 0x9F, 0xE5, 0x7B, 0x4D, 0x15, 0xFA, + 0x4E, 0x64, 0x04, 0x1A, 0x10, 0x32, 0x27, 0x78, + 0x21, 0xB9, 0x15, 0x36, 0x96, 0xC6, 0x65, 0xAE, + 0xFB, 0x97, 0x27, 0xA2, 0xD0, 0x1C, 0x43, 0xB7, + 0xCF, 0x0B, 0xEE, 0x49, 0x97, 0xD6, 0xAF, 0x9D, + 0x8A, 0x17, 0xB8, 0xC3, 0xD8, 0x15, 0x5A, 0x54, + 0x1E, 0x69, 0x3C, 0xA5, 0x19, 0xF6, 0x86, 0x69, + 0x57, 0x3A, 0xE9, 0x5B, 0xB1, 0x2D, 0xCA, 0xA6, + 0xE8, 0xEB, 0x30, 0x67, 0xC5, 0x20, 0x05, 0xAC, + 0x84, 0xC8, 0xEB, 0xEF, 0x62, 0x80, 0xBC, 0xBE, + 0xD2, 0xED, 0xFE, 0x48, 0x1E, 0xC0, 0xEE, 0x12, + 0xA6, 0x7A, 0x83, 0x43, 0x46, 0x4E, 0xD6, 0xCE, + 0x05, 0xE6, 0xE2, 0xA0, 0x6D, 0x65, 0xAE, 0xA4, + 0xF2, 0xEF, 0xB5, 0xEC, 0x52, 0x3C, 0x5D, 0x88, + 0x4C, 0x03, 0x87, 0xC0, 0xD6, 0xE0, 0x17, 0xC1, + 0x1F, 0xAA, 0x6B, 0xB7, 0xDD, 0x73, 0x2E, 0x5D, + 0xB4, 0x87, 0x61, 0x87, 0xD9, 0x4A, 0xEA, 0x14, + 0xE0, 0x1A, 0x96, 0x19, 0x4C, 0x59, 0xA8, 0x4D, + 0x79, 0x5B, 0xBB, 0xDC, 0xA4, 0xBA, 0xB3, 0xF5, + 0x5B, 0x1A, 0x86, 0x5E, 0xEC, 0xD6, 0xAC, 0x0A, + 0xCF, 0x01, 0xF6, 0x1C, 0xDD, 0xC7, 0xD1, 0x91, + 0x19, 0x8E, 0x3C, 0xDC, 0xAF, 0x65, 0xF5, 0x71, + 0x30, 0xF8, 0xD1, 0x59, 0x33, 0x1D, 0x4B, 0xD4, + 0x9D, 0xBD, 0xB4, 0x47, 0x19, 0x42, 0xA2, 0xDE, + 0x77, 0xDC, 0xE4, 0xF2, 0xE4, 0x8B, 0xE5, 0xC3, + 0x0D, 0x74, 0xBF, 0xA1, 0x94, 0x4F, 0x75, 0x63, + 0x49, 0x97, 0x46, 0xF1, 0xE2, 0x29, 0xF5, 0x8B, + 0x1A, 0x7A, 0xDF, 0x6D, 0x84, 0xFD, 0x14, 0x1C, + 0x77, 0x63, 0xEB, 0xE5, 0xD1, 0x9E, 0xC2, 0xCA, + 0x72, 0x8E, 0x58, 0xE1, 0xB6, 0xF7, 0xB4, 0xB1, + 0xFF, 0x3A, 0xB8, 0xB0, 0xFA, 0x71, 0xD1, 0x86, + 0x59, 0x4D, 0x91, 0xE5, 0xC7, 0x9C, 0x93, 0x24, + 0xE1, 0x37, 0xFF, 0x69, 0x85, 0x66, 0xA9, 0x74, + 0x12, 0x82, 0xE8, 0xA5, 0x27, 0x38, 0x71, 0x39, + 0xF6, 0xDA, 0x04, 0x64, 0x10, 0xFD, 0x10, 0x6B, + 0x44, 0x69, 0x4F, 0xAF, 0xE6, 0xBD, 0x9A, 0xAE, + 0x4D, 0xBD, 0xCE, 0xDB, 0x47, 0x0B, 0x0C, 0xDC, + 0x3A, 0xD5, 0x8E, 0x73, 0x33, 0x7B, 0x3E, 0xDB, + 0x37, 0x14, 0x51, 0x1E, 0xF7, 0xB8, 0x99, 0xF3, + 0x1F, 0xAB, 0x63, 0x80, 0x47, 0x94, 0xED, 0xE9, + 0x56, 0x66, 0x81, 0xF5, 0xDF, 0xCB, 0x48, 0xA0, + 0x27, 0x3C, 0x17, 0x82, 0x27, 0xBA, 0x27, 0xE1, + 0x11, 0x70, 0x46, 0x0A, 0x21, 0x5E, 0x87, 0x6C, + 0x7D, 0x89, 0x81, 0xC3, 0x25, 0x7E, 0x77, 0x23, + 0x37, 0xE6, 0xC6, 0xDC, 0xF3, 0xF3, 0x14, 0x82, + 0xD6, 0x55, 0x64, 0x17, 0x2A, 0x39, 0x87, 0xD5, + 0x1D, 0x1B, 0xEA, 0xB4, 0x52, 0xB3, 0x49, 0xBE, + 0xC5, 0xC5, 0xBC, 0x2E, 0xE8, 0xAF, 0xD4, 0xCB, + 0xC4, 0xCB, 0x47, 0xB4, 0x56, 0x0C, 0xF6, 0x7A, + 0xD0, 0x52, 0x17, 0xEE, 0x8D, 0x42, 0x0A, 0xEC, + 0xAC, 0xEE, 0x2E, 0x70, 0xCC, 0x99, 0xDB, 0xE3, + 0x1C, 0x90, 0x8D, 0x9B, 0x11, 0x9A, 0x19, 0x2C, + 0x17, 0xA3, 0x45, 0x05, 0xD0, 0xCF, 0x1F, 0x4A, + 0x03, 0x57, 0x81, 0x48, 0x20, 0xC4, 0xBB, 0xD9, + 0xE5, 0x0D, 0xCA, 0xF8, 0xFE, 0xA4, 0x6A, 0x35, + 0xD2, 0xD8, 0xED, 0x34, 0x17, 0xE2, 0x12, 0x30, + 0x15, 0xE0, 0x7E, 0xD8, 0x56, 0x63, 0x6B, 0x39, + 0x18, 0x15, 0x92, 0x07, 0x92, 0xFA, 0x08, 0xEB, + 0x96, 0xBA, 0x6F, 0x08, 0x34, 0x88, 0xF5, 0x77, + 0x92, 0xA7, 0xB6, 0x33, 0x39, 0x36, 0xDD, 0x1D, + 0xBC, 0x84, 0x31, 0x5B, 0xE1, 0x81, 0x74, 0x31, + 0x07, 0x5F, 0xAD, 0x7B, 0x3C, 0xFA, 0x6F, 0xEC, + 0xBA, 0x62, 0xBB, 0xD1, 0x3D, 0x22, 0xD2, 0xA0, + 0xD0, 0xEB, 0x8C, 0xA6, 0xE5, 0xBF, 0xF2, 0xBD, + 0xAF, 0x31, 0xC0, 0xA6, 0xE1, 0x0C, 0x6F, 0x28, + 0xAF, 0x13, 0xC1, 0x1B, 0x83, 0x9F, 0x0D, 0xA8, + 0xA1, 0xF6, 0xC8, 0x8F, 0x06, 0x4C, 0x4D, 0xA6, + 0xDC, 0x02, 0x78, 0x78, 0x66, 0x92, 0x5B, 0x63, + 0xFD, 0xF8, 0xA6, 0x4F, 0x6D, 0xFD, 0x90, 0x61, + 0x61, 0xCE, 0x6C, 0xB1, 0x59, 0x21, 0xC5, 0x84, + 0xAE, 0x52, 0x56, 0xFC, 0xEE, 0x63, 0xE0, 0x0F, + 0x81, 0xFF, 0x0C, 0x7C, 0xD3, 0x83, 0x4A, 0x96, + 0xFC, 0x97, 0xFF, 0x7C, 0x6E, 0x34, 0x4A, 0xCD, + 0x51, 0xB9, 0x3D, 0xFE, 0x51, 0x5B, 0xBC, 0xDF, + 0x07, 0x7F, 0x8E, 0xF4, 0x3F, 0x9A, 0xCD, 0xE8, + 0x5F, 0x08, 0x1D, 0x40, 0x3D, 0xFC, 0xA7, 0x00, + 0x4B, 0xCC, 0xE6, 0xDE, 0x33, 0x0E, 0x45, 0x70, + 0x8C, 0x30, 0x32, 0xA9, 0x7D, 0xBE, 0x16, 0xA3, + 0x71, 0x3E, 0xDB, 0x22, 0xA9, 0x98, 0xC9, 0x40, + 0x18, 0x41, 0xF1, 0xB6, 0x09, 0x08, 0x81, 0x73, + 0xCB, 0x20, 0xA4, 0xE7, 0xCD, 0x33, 0xA3, 0x64, + 0x07, 0xE3, 0x96, 0x14, 0xA8, 0x6C, 0x86, 0xE2, + 0x18, 0x70, 0x59, 0x28, 0xEE, 0xF3, 0x0F, 0x2A, + 0x5E, 0x67, 0x6F, 0xBD, 0x1E, 0x62, 0x4F, 0xC8, + 0x12, 0x24, 0x7D, 0x94, 0x1E, 0x90, 0xCF, 0xED, + 0x51, 0xBF, 0xFE, 0xDE, 0xC5, 0xFE, 0x72, 0x44, + 0x22, 0x2D, 0xBD, 0x9D, 0xAF, 0xCE, 0x7C, 0x36, + 0x89, 0x2A, 0x2B, 0x4B, 0xE0, 0x22, 0x86, 0x6F, + 0x7B, 0x72, 0x6F, 0x2D, 0x5B, 0x8D, 0x5B, 0xA7, + 0xC1, 0xD9, 0xF2, 0x1F, 0xE6, 0x61, 0x24, 0x11, + 0x25, 0x9C, 0xCB, 0xC7, 0xC8, 0x3F, 0xEE, 0x4B, + 0x1A, 0x6C, 0x28, 0x11, 0x42, 0x10, 0xEB, 0xF2, + 0x61, 0x33, 0xF5, 0x81, 0xF8, 0x31, 0x55, 0xE1, + 0x47, 0x33, 0x59, 0x0D, 0x55, 0x24, 0x02, 0xC3, + 0xD3, 0x8F, 0x19, 0x23, 0x9B, 0x0D, 0xA2, 0xB6, + 0xEF, 0x2D, 0x99, 0x88, 0x0D, 0xC7, 0x0D, 0x49, + 0xC2, 0x63, 0xF1, 0x1B, 0x70, 0xB6, 0x48, 0x6E, + 0x5E, 0x3E, 0x6D, 0x64, 0xD2, 0xC0, 0xC1, 0x50, + 0x7E, 0x80, 0x60, 0xAA, 0x5E, 0x4E, 0x2E, 0xBD, + 0x6D, 0xD3, 0x42, 0xA9, 0x1E, 0xD9, 0x3F, 0xC8, + 0x2E, 0x55, 0xCF, 0x93, 0x12, 0xF5, 0x60, 0x13, + 0xC1, 0xC1, 0x2F, 0xA4, 0x1C, 0x84, 0x7B, 0x43, + 0x06, 0x34, 0x7B, 0xB6, 0xCB, 0x6A, 0x49, 0x72, + 0xD9, 0x47, 0x61, 0xF3, 0x39, 0xB1, 0x05, 0x64, + 0x7A, 0x40, 0x9F, 0xA4, 0x37, 0xEE, 0xEC, 0xE1, + 0x76, 0x2E, 0xEA, 0x97, 0xBD, 0x20, 0xFD, 0xC1, + 0x0A, 0xD1, 0xE4, 0x28, 0x30, 0x15, 0xE0, 0xEE, + 0xA2, 0xA1, 0xE9, 0x39, 0x12, 0x1E, 0xF8, 0xA5, + 0xEB, 0xF3, 0x53, 0xC8, 0x92, 0xCC, 0x9D, 0x85, + 0xFC, 0x13, 0x5B, 0xFD, 0x48, 0x7C, 0xB7, 0xDB, + 0xE5, 0xD7, 0x86, 0x9F, 0x57, 0x6B, 0xBB, 0xA5, + 0x18, 0xA1, 0x58, 0xE5, 0x2F, 0xD0, 0x66, 0x13, + 0xC3, 0x35, 0xF5, 0xCE, 0xC1, 0x7A, 0x0A, 0x62, + 0xB8, 0x72, 0xF6, 0x25, 0x7B, 0x46, 0xD3, 0x3D, + 0x77, 0xD3, 0x02, 0x75, 0xDC, 0x5A, 0x71, 0x4B, + 0x88, 0x0F, 0x13, 0x7A, 0x68, 0xD4, 0x79, 0xCB, + 0x9F, 0x64, 0x24, 0x9F, 0x96, 0x6D, 0x18, 0x1C, + 0x28, 0x5F, 0x13, 0x1B, 0x3C, 0xC2, 0x18, 0x4E, + 0xDD, 0x9A, 0x20, 0x9F, 0x46, 0xD9, 0xAD, 0x2A, + 0x05, 0x3B, 0xB2, 0x80, 0x35, 0xF7, 0x4D, 0x5F, + 0x1E, 0xA3, 0x16, 0x20, 0xC9, 0x66, 0xA4, 0xE1, + 0xAD, 0x07, 0x38, 0x82, 0xE4, 0x97, 0x46, 0xDE, + 0xBF, 0x56, 0x2B, 0xB8, 0xBA, 0xED, 0xC8, 0xA7, + 0x46, 0x44, 0xDC, 0xC3, 0x41, 0x23, 0x0D, 0x42, + 0x86, 0x7D, 0x17, 0xEE, 0x61, 0xCA, 0x2C, 0x1C, + 0x78, 0x9A, 0xCD, 0x32, 0xAA, 0xAA, 0xDA, 0x11, + 0x19, 0x52, 0xDA, 0xD4, 0x7E, 0xA3, 0x06, 0x30, + 0x50, 0x54, 0x5A, 0x52, 0x56, 0x53, 0xE0, 0x80, + 0xCB, 0xA2, 0x41, 0x23, 0xBB, 0x68, 0x66, 0x72, + 0xC7, 0x83, 0x8A, 0xCA, 0x38, 0x75, 0xB8, 0x7F, + 0xAC, 0xDC, 0x85, 0xEA, 0xC0, 0x1A, 0x8F, 0xA9, + 0x1C, 0xDE, 0xE5, 0x9C, 0xD8, 0xFC, 0x55, 0xD1, + 0x34, 0x33, 0x63, 0x2D, 0x31, 0x08, 0xFD, 0x4D, + 0x12, 0x8A, 0xCB, 0x24, 0xC4, 0x33, 0x28, 0x82, + 0x85, 0x41, 0x91, 0x2C, 0x60, 0xAE, 0x7A, 0x18, + 0x33, 0x43, 0xA2, 0x6A, 0xC3, 0x52, 0xA5, 0x25, + 0x2C, 0xCF, 0x93, 0xDB, 0x21, 0x01, 0xE5, 0xAC, + 0x40, 0x6B, 0x3B, 0x7D, 0x98, 0x43, 0x29, 0x64, + 0xBC, 0x24, 0x13, 0x70, 0xFC, 0x5E, 0xD8, 0xD0, + 0xDB, 0x68, 0x02, 0x12, 0xD5, 0x29, 0xDF, 0xB8, + 0xC3, 0xAB, 0x4A, 0xEE, 0xB9, 0x35, 0x69, 0x88, + 0x77, 0x7D, 0x49, 0x54, 0x55, 0xF3, 0x22, 0x62, + 0x90, 0xB0, 0x2E, 0x67, 0xA1, 0xB7, 0x84, 0x63, + 0xAF, 0x5C, 0x85, 0x3A, 0x60, 0xDC, 0x8A, 0x5D, + 0xBE, 0x47, 0x39, 0x3F, 0xE5, 0x83, 0x32, 0x5B, + 0x10, 0x6D, 0xD1, 0xD6, 0x20, 0x14, 0x18, 0xBF, + 0x50, 0x60, 0x40, 0x76, 0x7B, 0xE2, 0xA3, 0xE7, + 0xC2, 0x15, 0x66, 0xD2, 0xAF, 0x2E, 0x40, 0x67, + 0x32, 0x56, 0x9A, 0x7B, 0x6C, 0xB9, 0xAC, 0x06, + 0x08, 0xFF, 0x6B, 0x5C, 0xC7, 0x53, 0x6E, 0x9F, + 0x29, 0xC9, 0xEF, 0x95, 0x57, 0x08, 0xE0, 0xD2, + 0x51, 0x02, 0x81, 0x06, 0x28, 0xBC, 0x9F, 0x36, + 0x8A, 0x27, 0xCF, 0x17, 0x97, 0xB6, 0x2E, 0x2E, + 0x5C, 0xFE, 0x0D, 0x01, 0xB6, 0x14, 0xE5, 0xEB, + 0xE5, 0x1C, 0x0B, 0x44, 0xB7, 0xD0, 0x6B, 0xB6, + 0xD2, 0x57, 0x6E, 0x85, 0xC3, 0xE5, 0xA1, 0x06, + 0xDD, 0xB7, 0x5D, 0x18, 0x27, 0xE8, 0x03, 0x23, + 0xEB, 0xE8, 0x20, 0xC0, 0x5A, 0xA6, 0x0D, 0x4F, + 0xDE, 0xE0, 0x14, 0x9D, 0xF1, 0xD3, 0xC6, 0xB4, + 0x57, 0xBA, 0x9C, 0x29, 0xA6, 0x74, 0x0B, 0x86, + 0x78, 0xBB, 0x20, 0x18, 0xAF, 0x06, 0x08, 0xCB, + 0x1D, 0x6A, 0x09, 0x56, 0xE3, 0x0F, 0xA3, 0x7A, + 0x5F, 0x45, 0x69, 0xEE, 0x87, 0xD7, 0xD2, 0xB0, + 0x98, 0x34, 0xBF, 0x44, 0xE1, 0xF0, 0x24, 0xE7, + 0x28, 0x1D, 0xD0, 0xD5, 0x6B, 0x19, 0xF6, 0x3B, + 0x10, 0xDA, 0x80, 0x7F, 0x44, 0x76, 0x13, 0x39, + 0x68, 0x73, 0x78, 0x44, 0xA6, 0x6D, 0x79, 0xEB, + 0x99, 0xF3, 0x19, 0x57, 0x98, 0x89, 0xD2, 0x1A, + 0x07, 0xEA, 0x5E, 0xBD, 0x9B, 0xC5, 0xA7, 0x8A, + 0x6F, 0xEF, 0xF1, 0x86, 0x74, 0x4E, 0xFE, 0xF7, + 0x49, 0x57, 0x36, 0x9A, 0xE5, 0x9E, 0xCB, 0x36, + 0x70, 0x72, 0xD4, 0xAC, 0x5D, 0xEF, 0x58, 0x93, + 0x7D, 0xBB, 0xDD, 0xC8, 0x55, 0x32, 0xB5, 0x55, + 0x57, 0x60, 0xD1, 0x27, 0x0D, 0xA8, 0x27, 0x34, + 0xA3, 0x90, 0x4F, 0x8D, 0x1A, 0x3D, 0x53, 0x43, + 0x0A, 0x9A, 0x5C, 0x5C, 0x05, 0x10, 0xDF, 0x01, + 0xCE, 0xAD, 0x23, 0xB6, 0xF6, 0x86, 0xF5, 0xC3, + 0x90, 0x3D, 0xB3, 0xA1, 0xE8, 0xEA, 0x86, 0xF6, + 0x9E, 0xD4, 0x30, 0x42, 0x9A, 0xA2, 0xC6, 0xEC, + 0x64, 0xD9, 0x34, 0x49, 0x26, 0x0C, 0xC6, 0x0E, + 0x76, 0x07, 0xCD, 0x21, 0x35, 0xCE, 0xB1, 0x91, + 0x52, 0x5E, 0x19, 0x6B, 0x4D, 0xB2, 0x2A, 0xDF, + 0xDC, 0x5C, 0x24, 0x16, 0x3A, 0xCC, 0xD1, 0xA8, + 0x04, 0xBA, 0x04, 0xB4, 0x3A, 0xE3, 0xF1, 0x0A, + 0x58, 0x5A, 0xA5, 0x6F, 0xDB, 0x14, 0xA3, 0x30, + 0xE5, 0x25, 0xB9, 0xB6, 0x05, 0x9A, 0x52, 0xAC, + 0x29, 0x58, 0xA3, 0x2C, 0x68, 0x5C, 0x33, 0x3C, + 0x4C, 0x96, 0x15, 0x0C, 0xF4, 0xC6, 0x26, 0xC0, + 0xFE, 0x3B, 0x7F, 0x1F, 0x86, 0x82, 0xBA, 0x59, + 0xC8, 0x69, 0x5D, 0x4D, 0x1F, 0xC1, 0xAF, 0x71, + 0xD8, 0xCF, 0x72, 0x9F, 0x7F, 0x34, 0x14, 0xFE, + 0x81, 0xA7, 0xA4, 0x5E, 0x54, 0xFE, 0xC7, 0xB0, + 0x72, 0xA1, 0x32, 0x1F, 0xC6, 0x90, 0x97, 0xD2, + 0xD4, 0x81, 0xBC, 0x35, 0xF7, 0x49, 0xE1, 0xBC, + 0x68, 0xB1, 0x1B, 0x76, 0x2E, 0x3D, 0x1C, 0x73, + 0x17, 0xE6, 0x19, 0xCA, 0x96, 0xB8, 0x93, 0x9B, + 0x8D, 0xEC, 0xDC, 0x29, 0xDA, 0x14, 0x63, 0x0F, + 0x59, 0x99, 0x2B, 0x01, 0xC5, 0xA4, 0xC5, 0x77, + 0xE9, 0xC0, 0x83, 0xF3, 0x7D, 0x06, 0x8B, 0x6D, + 0xEC, 0x8A, 0x9B, 0x4B, 0x15, 0x70, 0x4C, 0x8D, + 0x66, 0x92, 0x29, 0xC9, 0x8B, 0x1A, 0xA9, 0xC0, + 0x18, 0x12, 0x0A, 0x0E, 0x47, 0xD5, 0x6A, 0xF8, + 0x30, 0xD2, 0x50, 0x25, 0x50, 0xA4, 0x4C, 0x19, + 0x13, 0xA0, 0x7F, 0xD9, 0xC7, 0xF3, 0x13, 0xC8, + 0x48, 0xCC, 0x84, 0x2F, 0xB7, 0x5B, 0xDE, 0x4B, + 0x29, 0xC8, 0x92, 0x82, 0x35, 0x92, 0x7C, 0xB1, + 0x2E, 0xF6, 0x73, 0xBD, 0x67, 0x4D, 0x8A, 0x92, + 0xF4, 0x74, 0xF2, 0xAB, 0x5B, 0x18, 0x7B, 0xAF, + 0xBA, 0x25, 0xDA, 0xF4, 0xBC, 0x99, 0x8D, 0x9F, + 0x3B, 0x5C, 0xC1, 0xF9, 0x38, 0x8F, 0xFD, 0x0A, + 0x98, 0xE8, 0x22, 0xC6, 0x5A, 0x8B, 0x97, 0x6F, + 0xEA, 0x37, 0xBE, 0x6A, 0xBC, 0x25, 0x54, 0x4C, + 0x16, 0x05, 0x98, 0x6F, 0x6E, 0x02, 0xFB, 0x44, + 0xD5, 0x3B, 0xC0, 0xE3, 0x49, 0x1F, 0x3D, 0xF0, + 0x50, 0xC6, 0xBC, 0xA3, 0xFE, 0x3C, 0xA7, 0x04, + 0x12, 0x37, 0x74, 0x45, 0xCD, 0x44, 0xC7, 0xA1, + 0xAA, 0xDF, 0xCB, 0xF3, 0xBF, 0x6E, 0x32, 0xB0, + 0xBD, 0x77, 0xB1, 0xED, 0xAB, 0x81, 0x54, 0x8B, + 0xFB, 0x97, 0x6C, 0x53, 0x3C, 0xCC, 0x4B, 0x8C, + 0x1A, 0x68, 0xE8, 0x12, 0x8B, 0xD4, 0x82, 0x11, + 0xD5, 0xB2, 0x10, 0xA3, 0x06, 0x95, 0xD5, 0xB9, + 0xC5, 0x3C, 0xA5, 0xE7, 0x47, 0xC8, 0x7C, 0xC3, + 0x91, 0x64, 0xB7, 0xE3, 0x37, 0x87, 0x63, 0xEF, + 0x8B, 0x14, 0x45, 0xD3, 0x76, 0xB6, 0x87, 0x56, + 0x98, 0x5D, 0xF0, 0x7C, 0xB1, 0xFB, 0x7E, 0xFD, + 0x4C, 0x7A, 0x03, 0xB9, 0x0B, 0x91, 0x3F, 0xEF, + 0x27, 0x78, 0x44, 0xA2, 0x89, 0xCF, 0x21, 0xDD, + 0x5C, 0x67, 0xBD, 0x27, 0x3C, 0x77, 0xAE, 0x45, + 0xC2, 0x00, 0x3D, 0xB3, 0xE8, 0xE1, 0x29, 0x16, + 0xC7, 0x75, 0x4F, 0x90, 0x87, 0xCB, 0x94, 0x40, + 0x8C, 0x61, 0x1A, 0xDB, 0x20, 0x3B, 0xAF, 0x30, + 0x9F, 0x7A, 0x9D, 0x4E, 0xE0, 0x34, 0xCF, 0x4D, + 0x47, 0xEF, 0x0F, 0xE0, 0x82, 0xB4, 0xA8, 0xCE, + 0xC5, 0x0B, 0xE5, 0xAC, 0xD0, 0x91, 0xC5, 0x07, + 0xFB, 0x7D, 0x8A, 0x11, 0x62, 0x63, 0x89, 0xC9, + 0x32, 0xA7, 0x8C, 0x02, 0xA7, 0x7C, 0x20, 0x94, + 0xF2, 0x4C, 0x63, 0x1A, 0xB8, 0xBC, 0x71, 0x75, + 0x51, 0xE9, 0x96, 0x57, 0xD7, 0xFD, 0xE9, 0x42, + 0xBC, 0x9E, 0xA9, 0x96, 0xA7, 0x3B, 0x64, 0x74, + 0x51, 0x1A, 0xB7, 0x2D, 0x43, 0x85, 0x43, 0xF1, + 0xF0, 0xEF, 0x8D, 0x0F, 0xBC, 0xB1, 0x2A, 0xB6, + 0xA2, 0x54, 0x92, 0x8A, 0xDE, 0x7C, 0xE6, 0xD6, + 0x5D, 0x77, 0xFF, 0x2C, 0x35, 0xA2, 0xA5, 0x9E, + 0xB4, 0xB0, 0xBB, 0x12, 0x4C, 0x0A, 0xFC, 0x92, + 0x23, 0xF3, 0xEE, 0x73, 0xD7, 0x68, 0x96, 0x74, + 0xE9, 0x07, 0x31, 0xA6, 0x11, 0xE5, 0x14, 0x68, + 0xA8, 0x5B, 0x7A, 0x2F, 0x5F, 0x5E, 0xC6, 0x6A, + 0xC6, 0x80, 0xF9, 0x05, 0xDC, 0x43, 0xF5, 0xB0, + 0x39, 0x19, 0x93, 0x5A, 0x14, 0x38, 0x77, 0x3E, + 0x92, 0x4A, 0x59, 0x53, 0x2C, 0xBE, 0x3B, 0xF4, + 0xA5, 0xE9, 0x6F, 0xF8, 0x6C, 0x78, 0x00, 0xAC, + 0x99, 0x4F, 0x1A, 0xCB, 0x26, 0xEA, 0xAC, 0x09, + 0x37, 0xEB, 0xC5, 0x4B, 0x04, 0xD6, 0x75, 0x61, + 0x4B, 0xC2, 0xAF, 0x69, 0x20, 0xEB, 0x6D, 0x0C, + 0x73, 0xA0, 0x98, 0x7C, 0x10, 0xE6, 0x22, 0xA4, + 0xAD, 0xEF, 0x91, 0x29, 0xA7, 0xE0, 0xEA, 0x61, + 0x7D, 0x7D, 0x05, 0x46, 0x60, 0x2F, 0xB3, 0xEB, + 0xA5, 0x5B, 0xFF, 0xF6, 0xEB, 0xDF, 0x1A, 0xD1, + 0xB5, 0x5D, 0x99, 0x4A, 0x86, 0xE9, 0xBB, 0xD8, + 0x7F, 0x23, 0xCF, 0xD1, 0xC5, 0x4D, 0x85, 0x34, + 0xF9, 0x7E, 0x9F, 0xE4, 0xA3, 0xC1, 0x62, 0xFF, + 0xC4, 0x30, 0x39, 0xF0, 0x53, 0xE6, 0x63, 0xEF, + 0xEF, 0xC5, 0x9C, 0x09, 0x7F, 0x14, 0x2A, 0x03, + 0x93, 0x6A, 0xDD, 0xCB, 0x94, 0xB6, 0xAC, 0x84, + 0x0D, 0xCD, 0xA2, 0x21, 0xAE, 0x46, 0xAF, 0xD8, + 0x5D, 0x4B, 0xA5, 0xFB, 0xD4, 0x47, 0x89, 0x32, + 0xF2, 0xC1, 0xDB, 0x95, 0x09, 0xEF, 0x95, 0xD5, + 0xFF, 0x8F, 0xD9, 0x89, 0x35, 0xC9, 0x86, 0x0F, + 0x62, 0x18, 0xC5, 0x80, 0xBD, 0x27, 0x71, 0xA4, + 0x40, 0x79, 0x52, 0x01, 0x37, 0x93, 0x77, 0x02, + 0x7E, 0xC4, 0xDD, 0xCD, 0x2D, 0xC4, 0x89, 0xC3, + 0x09, 0x4F, 0xBC, 0x6F, 0x4C, 0x4A, 0xB3, 0xE6, + 0xFD, 0x6A, 0x45, 0x1A, 0x7A, 0x37, 0x6D, 0x3C, + 0xB8, 0x0F, 0x1B, 0x43, 0x70, 0x5A, 0x81, 0xD0, + 0xC7, 0x63, 0xC7, 0x9E, 0x63, 0xEF, 0x8C, 0x52, + 0x60, 0x7A, 0x2E, 0x94, 0xCF, 0x26, 0x49, 0xE5, + 0x12, 0xB1, 0xB1, 0x27, 0xD0, 0x38, 0xB1, 0x40, + 0x60, 0xF8, 0x7B, 0x37, 0x80, 0x95, 0xB5, 0x13, + 0xCA, 0x83, 0x7E, 0x27, 0xA8, 0x5E, 0x30, 0x27, + 0x20, 0x57, 0x1D, 0x45, 0x5F, 0xA8, 0xA6, 0xDC, + 0xF3, 0x53, 0xAA, 0x7B, 0x59, 0xC2, 0xAE, 0x60, + 0x09, 0x5A, 0xE3, 0x59, 0x5E, 0xC8, 0x28, 0xBC, + 0x4B, 0x49, 0xE0, 0xDA, 0xAC, 0x74, 0xF0, 0x8B, + 0x20, 0xFF, 0x4F, 0x0E, 0x7E, 0x6A, 0x4E, 0xF3, + 0x00, 0x22, 0x0C, 0xD0, 0x16, 0x23, 0x03, 0x17, + 0x83, 0x66, 0xC1, 0x5E, 0xFC, 0x5E, 0xEA, 0xE6, + 0x9D, 0xCD, 0xF1, 0x6C, 0x8C, 0xC5, 0xD5, 0x08, + 0xA2, 0xA1, 0x9F, 0xE1, 0x1B, 0x9D, 0xEA, 0x2E, + 0x0A, 0x57, 0x2E, 0xCC, 0x9A, 0x66, 0x18, 0x31, + 0x66, 0xF4, 0x77, 0x14, 0x93, 0x6E, 0xB0, 0x5B, + 0x08, 0x30, 0x4A, 0x7D, 0xAA, 0x7B, 0x9B, 0xF1, + 0xC7, 0x80, 0x11, 0xAD, 0x0B, 0x25, 0x95, 0xF3, + 0x20, 0x5A, 0x69, 0x34, 0xFC, 0x08, 0x62, 0x3B, + 0x8F, 0x82, 0xC6, 0xC6, 0x47, 0x39, 0x94, 0x06, + 0xAB, 0x13, 0x11, 0x3A, 0x0C, 0xCC, 0x15, 0x08, + 0x90, 0xCF, 0x4A, 0xDD, 0x22, 0x9C, 0x5A, 0x8D, + 0x5C, 0x46, 0x07, 0x3A, 0xAE, 0x85, 0x90, 0xE2, + 0xA0, 0xA0, 0xB8, 0x0B, 0x62, 0x59, 0xCF, 0x08, + 0xD4, 0x72, 0xD4, 0xB8, 0xA2, 0xFD, 0x86, 0x64, + 0xAE, 0xB6, 0xC1, 0xC2, 0xB6, 0xB2, 0xF1, 0x03, + 0xEE, 0x57, 0x13, 0xAB, 0x60, 0x87, 0xDD, 0xD4, + 0x93, 0x9F, 0x09, 0x0A, 0xA6, 0xE5, 0x44, 0xAB, + 0x7D, 0x6B, 0xE5, 0x7F, 0xC7, 0x81, 0x33, 0x0F, + 0x74, 0xE4, 0x33, 0x8E, 0x9C, 0x99, 0x8C, 0x93, + 0xB6, 0x62, 0x18, 0xAE, 0xDD, 0x5B, 0x6E, 0x17, + 0xD3, 0xDA, 0xF8, 0x3B, 0x37, 0x68, 0xB2, 0xC6, + 0x83, 0x0A, 0xB6, 0xAE, 0x9C, 0xE6, 0x1E, 0x7B, + 0xAC, 0xB2, 0x39, 0x28, 0x33, 0x95, 0xB2, 0xB1, + 0x80, 0x48, 0xA6, 0x3D, 0x96, 0x5F, 0x9E, 0x01, + 0xDA, 0x1A, 0xEC, 0xA6, 0x85, 0x07, 0x35, 0xA7, + 0xF5, 0x84, 0x91, 0xDB, 0x23, 0xD7, 0x1F, 0x81, + 0xA1, 0xC6, 0xF4, 0x6B, 0x98, 0xA7, 0x1A, 0x81, + 0x98, 0xED, 0xB4, 0x15, 0x7C, 0x10, 0xD2, 0x33, + 0xE1, 0x24, 0x7C, 0xEF, 0x99, 0xE1, 0x1F, 0x81, + 0x3E, 0x31, 0xC6, 0x1E, 0x84, 0x61, 0x6B, 0x79, + 0x40, 0x9E, 0x2C, 0xFF, 0x70, 0x25, 0xA8, 0xCA, + 0x1C, 0x6B, 0xAE, 0x46, 0xC7, 0x5C, 0x32, 0x62, + 0x6F, 0xE4, 0x88, 0x73, 0xAD, 0x1D, 0xB2, 0x23, + 0xE9, 0xFB, 0x89, 0x82, 0xC2, 0x78, 0xC1, 0xAF, + 0xFB, 0x9F, 0x94, 0x05, 0xF3, 0x9C, 0x66, 0xE5, + 0x2E, 0x50, 0xAF, 0xE8, 0x6B, 0xB1, 0x6E, 0x5A, + 0x8D, 0xD7, 0xC0, 0x5B, 0xE2, 0xF9, 0xAE, 0xED, + 0x16, 0x41, 0x21, 0x10, 0x12, 0x9B, 0x96, 0x20, + 0xF1, 0x18, 0x8F, 0x3E, 0xA9, 0x08, 0x7D, 0x7E, + 0xB0, 0x90, 0xC8, 0xD9, 0xF3, 0x4A, 0x34, 0x16, + 0x6C, 0x0A, 0xF3, 0x27, 0x85, 0x7F, 0x79, 0xFE, + 0x67, 0xA7, 0x01, 0x2D, 0x1F, 0x65, 0x6C, 0xE1, + 0x6E, 0x37, 0x33, 0x32, 0x1B, 0x80, 0x7A, 0x3F, + 0x5B, 0x5D, 0xA6, 0x8A, 0xE5, 0x1F, 0x31, 0xE9, + 0xB1, 0x01, 0x97, 0x90, 0x74, 0x65, 0x9E, 0x94, + 0xBB, 0xCC, 0x96, 0x39, 0x57, 0x6D, 0xD6, 0x80, + 0xD7, 0xA6, 0x93, 0x4C, 0x71, 0xEC, 0x08, 0x38, + 0xE4, 0x58, 0x77, 0x23, 0x6A, 0x64, 0xC9, 0x47, + 0x3A, 0xFB, 0x6D, 0x94, 0x93, 0x2F, 0xDA, 0xF1, + 0xAE, 0x04, 0x2D, 0x77, 0x88, 0x8F, 0x55, 0xC9, + 0x07, 0x83, 0xC8, 0x5F, 0xD9, 0x8E, 0x41, 0xA6, + 0x81, 0x14, 0x67, 0xE0, 0x2F, 0xB1, 0x51, 0xE4, + 0x09, 0xF9, 0x5E, 0x58, 0xAD, 0x80, 0xB1, 0xF3, + 0x99, 0x54, 0x39, 0x87, 0xCF, 0x6E, 0xC3, 0xB3, + 0xA7, 0xCF, 0xF2, 0xA9, 0xA5, 0x90, 0x9A, 0xED, + 0x04, 0xB8, 0x6B, 0xFA, 0xD3, 0x9C, 0x3F, 0x78, + 0x7D, 0x58, 0x16, 0x7A, 0x3C, 0x33, 0xF1, 0x31, + 0x9C, 0xAC, 0x2A, 0x99, 0x4C, 0x23, 0x68, 0x44, + 0xB7, 0x98, 0x79, 0x51, 0xD1, 0x93, 0x0D, 0x49, + 0x62, 0x54, 0x3B, 0x27, 0xE6, 0x39, 0x75, 0x33, + 0xBA, 0x32, 0xC2, 0x00, 0x55, 0x29, 0x36, 0x09, + 0x30, 0x1C, 0x01, 0x27, 0xEE, 0x54, 0x24, 0x09, + 0x44, 0xFA, 0xE0, 0x05, 0x79, 0x65, 0x41, 0xE3, + 0x23, 0x88, 0x61, 0x7F, 0x9F, 0x6A, 0xBD, 0x81, + 0xDF, 0x14, 0x28, 0xC6, 0x5E, 0x97, 0x21, 0x39, + 0x26, 0xCB, 0x91, 0x01, 0xC6, 0x0E, 0x59, 0x83, + 0x38, 0xC3, 0x73, 0xD3, 0xB9, 0x2A, 0x9A, 0x70, + 0xF1, 0x8D, 0x19, 0xDE, 0x1A, 0xEE, 0x76, 0xC3, + 0x94, 0x27, 0x44, 0x12, 0xB7, 0x1E, 0x41, 0xEA, + 0x2A, 0xCD, 0x4A, 0xEB, 0xF7, 0xFE, 0x47, 0xAB, + 0x8B, 0x13, 0xB3, 0x2F, 0xDA, 0xBE, 0x78, 0x1D, + 0xDF, 0x53, 0xF6, 0x03, 0xE3, 0x8E, 0xE6, 0xAE, + 0x40, 0xB6, 0xFE, 0x72, 0x49, 0xF0, 0xF0, 0x15, + 0xE9, 0x8E, 0xDF, 0x7D, 0xFB, 0x68, 0xEB, 0x0F, + 0xE5, 0xC2, 0xC7, 0xF6, 0x2F, 0x6E, 0xDE, 0xA6, + 0x49, 0xE0, 0x02, 0xA9, 0x13, 0x71, 0x4F, 0xEF, + 0x1F, 0x41, 0x29, 0x67, 0xC0, 0xA1, 0x92, 0xFC, + 0x6B, 0x2E, 0x84, 0x42, 0xA2, 0x14, 0x96, 0x5C, + 0x44, 0xEF, 0xD4, 0x12, 0xE9, 0xED, 0x0B, 0xC2, + 0x94, 0xE2, 0x80, 0x18, 0x08, 0xFB, 0xB9, 0x00, + 0x14, 0x95, 0x0F, 0x47, 0xDC, 0xE3, 0xB4, 0x4A, + 0xFE, 0x58, 0x7A, 0x75, 0x42, 0xD0, 0xB5, 0x5C, + 0xD3, 0xD7, 0xC1, 0x52, 0xC9, 0xBD, 0xDA, 0x53, + 0x73, 0x8C, 0x08, 0x84, 0xCD, 0x37, 0x78, 0x4F, + 0x8B, 0x04, 0xD1, 0x3A, 0x72, 0xAB, 0x3E, 0xBE, + 0x8D, 0x61, 0x8F, 0x0E, 0xD2, 0xE6, 0x63, 0x69, + 0x94, 0xB1, 0xA9, 0xEC, 0x0B, 0xE3, 0x73, 0xC8, + 0xFB, 0xC2, 0x8C, 0x7B, 0x59, 0xEB, 0x92, 0x5B, + 0x56, 0x35, 0x94, 0xD2, 0x29, 0xBD, 0xFA, 0xF7, + 0xB2, 0xD2, 0x20, 0x8D, 0xE4, 0xE6, 0x32, 0x06, + 0x0D, 0x7F, 0xA8, 0x29, 0x12, 0x78, 0x04, 0xEE, + 0xF7, 0x51, 0x99, 0xC5, 0x1B, 0x21, 0x48, 0x47, + 0xE0, 0xAA, 0x42, 0x23, 0xA5, 0xB1, 0x83, 0xE7, + 0x80, 0xEE, 0x52, 0x93, 0xE9, 0xAD, 0xDB, 0x3A, + 0x6E, 0xDA, 0x59, 0xF3, 0x54, 0x5D, 0x44, 0x0B, + 0xD5, 0xB6, 0x9E, 0xB2, 0xCD, 0xA6, 0x83, 0x8D, + 0xA5, 0x59, 0xE8, 0x59, 0xCC, 0xBA, 0xB8, 0x99, + 0x7B, 0xDF, 0x3B, 0x01, 0x91, 0x45, 0xA8, 0xEF, + 0x21, 0x8D, 0x2A, 0xCD, 0xD3, 0x56, 0x17, 0xF4, + 0x60, 0xF5, 0x79, 0xB5, 0x3D, 0x52, 0xC9, 0xED, + 0xE8, 0xCD, 0xBF, 0xF3, 0x2F, 0xA8, 0x70, 0x5C, + 0x04, 0xBB, 0x3D, 0xB5, 0x3A, 0x9F, 0x1F, 0xDB, + 0xA7, 0xDB, 0xCD, 0xD3, 0x47, 0xD3, 0x51, 0xFC, + 0xC3, 0x19, 0xF7, 0x5E, 0xFB, 0x85, 0xE3, 0x2F, + 0x16, 0x7E, 0x01, 0x59, 0x6A, 0x5A, 0x02, 0x33, + 0x58, 0xA3, 0x9A, 0xDF, 0x92, 0xAF, 0xCC, 0xF1, + 0x60, 0xB1, 0xDC, 0x92, 0x5F, 0x73, 0xEB, 0xAE, + 0xFF, 0xA6, 0x67, 0x06, 0xF6, 0xAC, 0x19, 0xB0, + 0x73, 0x90, 0xB1, 0x7D, 0xC0, 0xB8, 0x8C, 0x38, + 0xED, 0xED, 0xAC, 0xDE, 0x5D, 0x10, 0x6F, 0xA2, + 0xB1, 0x8C, 0x3C, 0x7D, 0xFC, 0x81, 0x3D, 0xE3, + 0x7B, 0x92, 0xCF, 0x12, 0x77, 0xE4, 0xE1, 0xAB, + 0x15, 0x6A, 0xBB, 0xE9, 0x64, 0xA6, 0xB7, 0x79, + 0x0F, 0x84, 0x22, 0xF1, 0x59, 0xA3, 0x84, 0xAC, + 0x4A, 0x16, 0x0C, 0xF0, 0x57, 0x1E, 0x9F, 0x28, + 0x8D, 0x48, 0x72, 0x89, 0x68, 0xFF, 0xCE, 0x23, + 0xF5, 0x78, 0x76, 0xF0, 0x3B, 0x23, 0x9F, 0x70, + 0x1E, 0x22, 0x03, 0x03, 0x6E, 0x7A, 0x80, 0xB6, + 0xF0, 0xB1, 0xC3, 0x41, 0xF5, 0x40, 0x42, 0x1D, + 0x1A, 0x55, 0xCD, 0xDA, 0xB5, 0xF8, 0x8D, 0xC7, + 0x31, 0x71, 0xAE, 0x16, 0x9B, 0xBA, 0x3E, 0x4B, + 0xD9, 0xBB, 0x93, 0x69, 0xD7, 0x53, 0x9B, 0x90, + 0xBC, 0xB5, 0x8D, 0x95, 0x0A, 0x5A, 0xBC, 0xA2, + 0x7F, 0xD8, 0x93, 0x8D, 0xBB, 0xB4, 0xF7, 0xBD, + 0xD1, 0xB5, 0xA0, 0x2F, 0x10, 0x71, 0xB9, 0xBE, + 0x74, 0x2C, 0x41, 0x79, 0x8B, 0x1C, 0xC4, 0x1F, + 0x38, 0x8C, 0xCD, 0xBC, 0x9F, 0xCB, 0x3B, 0x75, + 0xF0, 0x65, 0x6F, 0x65, 0x8F, 0x00, 0x51, 0x50, + 0x22, 0x54, 0x79, 0xCC, 0x2E, 0x34, 0xA0, 0x56, + 0xE9, 0x0E, 0xE4, 0x12, 0x54, 0x18, 0x85, 0x7E, + 0xD6, 0x35, 0xFC, 0xF3, 0x63, 0x79, 0x26, 0x0E, + 0x1F, 0x03, 0x57, 0x6B, 0xAE, 0x2E, 0x15, 0x53, + 0x52, 0xB1, 0x3A, 0x94, 0xF8, 0xB9, 0x16, 0x1A, + 0x2F, 0x9D, 0x40, 0x93, 0x47, 0xF7, 0xB9, 0x19, + 0x81, 0x19, 0xDF, 0x7B, 0x1D, 0x96, 0xF4, 0xF6, + 0x99, 0x78, 0x80, 0x31, 0x4F, 0x88, 0x1F, 0x04, + 0x00, 0xBA, 0x07, 0x50, 0x1D, 0xDE, 0xF1, 0xA7, + 0x6A, 0x8C, 0x0D, 0xA3, 0x64, 0xBE, 0x6E, 0x0E, + 0xBB, 0x17, 0xDB, 0x7F, 0xA4, 0x03, 0x32, 0xD0, + 0xDE, 0x48, 0x95, 0x91, 0xD0, 0x31, 0x76, 0x85, + 0x17, 0x9A, 0x3F, 0x3E, 0x14, 0xB5, 0x63, 0x6B, + 0x85, 0xE8, 0x68, 0x6F, 0xB1, 0x56, 0x3E, 0x14, + 0x31, 0xE1, 0x26, 0x7A, 0x49, 0x5A, 0xD0, 0x25, + 0x87, 0xF2, 0x99, 0xAE, 0x8A, 0x89, 0xCF, 0x1A, + 0xD5, 0x21, 0x9F, 0x47, 0x2E, 0x10, 0x94, 0x0D, + 0x8F, 0x89, 0x16, 0xAB, 0x21, 0x54, 0xB0, 0xC3, + 0x23, 0xCE, 0x77, 0x5D, 0x69, 0x59, 0x28, 0xD1, + 0x81, 0x82, 0x98, 0xC0, 0x4B, 0x69, 0xFF, 0xC6, + 0x42, 0x7E, 0xB8, 0xF7, 0x9E, 0x61, 0x70, 0xA4, + 0xAB, 0xC1, 0xE8, 0x5D, 0x14, 0x09, 0x13, 0x04, + 0x7B, 0x41, 0x56, 0x60, 0x91, 0x46, 0xA7, 0x16, + 0x40, 0x53, 0x80, 0x2B, 0x7B, 0x6C, 0x55, 0x56, + 0xF5, 0x52, 0x1B, 0xB2, 0x42, 0x49, 0xCC, 0x33, + 0x9A, 0x75, 0xE9, 0x70, 0xC2, 0x49, 0x38, 0xCC, + 0x2F, 0x0C, 0x21, 0x8F, 0xA4, 0xAA, 0xE7, 0x7B, + 0xFA, 0x2E, 0x79, 0x4D, 0x07, 0xDB, 0xB0, 0xBD, + 0xB4, 0x02, 0x57, 0x77, 0xE8, 0x30, 0x24, 0x60, + 0x3C, 0x6A, 0x3E, 0xBB, 0x08, 0x41, 0x24, 0xB8, + 0x75, 0x49, 0x3A, 0xE1, 0x28, 0x0F, 0xA4, 0xB1, + 0xAF, 0x06, 0x95, 0x86, 0x44, 0x43, 0x39, 0x25, + 0x95, 0xD2, 0x84, 0x65, 0x12, 0xC1, 0xE0, 0xDD, + 0x5D, 0x62, 0x16, 0xE4, 0x41, 0x3A, 0xDD, 0x8D, + 0x29, 0x63, 0x26, 0x85, 0x66, 0x2B, 0xAD, 0xF6, + 0x89, 0x62, 0x31, 0x2F, 0x57, 0xAD, 0xCE, 0x8C, + 0x5C, 0x07, 0x9F, 0xAF, 0x3F, 0xBD, 0x2D, 0xE5, + 0xC4, 0xD4, 0xEF, 0x33, 0x4D, 0xED, 0x56, 0x87, + 0xC0, 0x09, 0xD3, 0x6F, 0xF6, 0x26, 0xF0, 0x6F, + 0x40, 0x34, 0x19, 0x22, 0x60, 0xBD, 0xBB, 0x72, + 0x02, 0xFE, 0x66, 0x06, 0x7F, 0xE3, 0x06, 0xC9, + 0x3B, 0x74, 0x91, 0xBC, 0xE6, 0x76, 0x72, 0x34, + 0x08, 0xA9, 0x7A, 0x63, 0x41, 0xDA, 0x0F, 0x9B, + 0x37, 0xD6, 0xD2, 0xC1, 0x38, 0xD3, 0xBF, 0x1D, + 0x72, 0xBA, 0x32, 0xFD, 0xAE, 0xDA, 0x9B, 0xB3, + 0x96, 0x1F, 0x5D, 0x07, 0x4F, 0x47, 0xF7, 0xDA, + 0xF7, 0x19, 0x82, 0xB9, 0xDF, 0xD4, 0xD0, 0x00, + 0x8D, 0x47, 0x7B, 0x05, 0x0E, 0xD6, 0x77, 0x68, + 0xCA, 0xA5, 0xAF, 0x91, 0x6F, 0x8A, 0xCD, 0xEE, + 0xC8, 0x48, 0x21, 0x6D, 0xEE, 0xC5, 0xA1, 0x49, + 0xC5, 0xED, 0xF3, 0x3D, 0xF3, 0xB3, 0x84, 0x65, + 0x4B, 0x40, 0x3B, 0xB2, 0x01, 0x23, 0x0E, 0xAE, + 0x31, 0xBF, 0x4B, 0x81, 0x43, 0x6E, 0x1E, 0x9B, + 0xAD, 0x37, 0x1C, 0x11, 0xFA, 0x7E, 0xC6, 0x55, + 0x1C, 0xE3, 0x2F, 0xAB, 0x3F, 0xEC, 0x27, 0x0E, + 0x7D, 0xC7, 0x9D, 0x74, 0xCC, 0x96, 0x39, 0xA5, + 0xA8, 0x26, 0xE7, 0xDA, 0xF8, 0x14, 0xB7, 0x3B, + 0xFB, 0x29, 0x6F, 0x3A, 0x6C, 0x68, 0x3A, 0x84, + 0xCE, 0xAB, 0x77, 0x69, 0x96, 0x55, 0x1C, 0xDF, + 0x23, 0x8F, 0xEB, 0xF4, 0xE3, 0x2B, 0x7A, 0xC6, + 0xEF, 0xF5, 0x61, 0xFA, 0x44, 0xBB, 0xE4, 0x6A, + 0x25, 0x5E, 0xC1, 0xA2, 0x6B, 0x15, 0x62, 0xFC, + 0x46, 0x23, 0xE1, 0x78, 0x0E, 0xC9, 0xE6, 0x1D, + 0xF9, 0xD9, 0x6F, 0x5C, 0x37, 0x45, 0x76, 0x5A, + 0x0F, 0x01, 0x8B, 0x53, 0xD4, 0xD8, 0x61, 0x63, + 0xC9, 0xA2, 0xAE, 0xA9, 0xBF, 0xA4, 0xEA, 0x3E, + 0x1B, 0xF8, 0x56, 0x63, 0xAE, 0x6D, 0xAF, 0x94, + 0xFB, 0x30, 0x6B, 0x4F, 0x2C, 0x89, 0xCD, 0x4E, + 0x96, 0xF1, 0xD0, 0xF1, 0x8E, 0x2A, 0x67, 0x41, + 0xE3, 0x9F, 0x4C, 0x99, 0x0E, 0x7D, 0xD8, 0x78, + 0xE2, 0x58, 0x51, 0x52, 0x84, 0x35, 0x99, 0xEB, + 0x20, 0xBB, 0x82, 0x02, 0x47, 0x2E, 0xEB, 0x2D, + 0x73, 0x45, 0x7E, 0x23, 0xD3, 0x16, 0xA8, 0xCA, + 0xF4, 0xD4, 0x85, 0x9B, 0x01, 0xE2, 0x1A, 0x2C, + 0xB5, 0xCD, 0x73, 0x29, 0xFD, 0xB3, 0x8A, 0x86, + 0x0B, 0x23, 0x77, 0x4D, 0x37, 0xF2, 0x43, 0x28, + 0xEE, 0xF7, 0xC7, 0xC1, 0x3C, 0x5C, 0x3B, 0xD2, + 0x7D, 0x52, 0xA2, 0x6A, 0x07, 0x09, 0x51, 0x34, + 0x4E, 0x0F, 0x87, 0xF5, 0x54, 0x6F, 0x60, 0x15, + 0x37, 0x48, 0x8D, 0x4A, 0x51, 0x24, 0x06, 0xF3, + 0xD5, 0x54, 0xCC, 0x96, 0xCA, 0x12, 0xFC, 0xB1, + 0xFD, 0x37, 0x16, 0x94, 0x23, 0x87, 0xAA, 0x08, + 0x9C, 0x76, 0xDE, 0x43, 0x8B, 0x0B, 0x47, 0xD7, + 0x8B, 0x2F, 0x1D, 0x8A, 0xCE, 0xC8, 0xCE, 0xBA, + 0xA8, 0x8E, 0x3A, 0x5F, 0xE3, 0x21, 0xD3, 0xBD, + 0xAF, 0x37, 0x74, 0x1D, 0x1B, 0xB5, 0xC7, 0x49, + 0x64, 0x35, 0xDE, 0x71, 0x91, 0x58, 0xF9, 0x32, + 0xAF, 0x0E, 0x37, 0xAA, 0xF5, 0xCA, 0x2E, 0xC5, + 0xF3, 0xF3, 0x57, 0xE8, 0xC6, 0x77, 0xB9, 0xE7, + 0xFE, 0xDC, 0xF2, 0xAD, 0x2F, 0x43, 0x46, 0x48, + 0x1D, 0x99, 0x70, 0x1C, 0xC1, 0x64, 0x94, 0xFF, + 0xEF, 0x43, 0xDF, 0xCE, 0x1E, 0xC5, 0x9C, 0xA3, + 0x34, 0x4A, 0x9A, 0xB5, 0x7F, 0x9D, 0xD8, 0x45, + 0x3C, 0x4E, 0xE8, 0x4A, 0xE8, 0x5F, 0x86, 0xEC, + 0x91, 0x97, 0xD5, 0xCE, 0xDA, 0x89, 0x9B, 0x9B, + 0x5C, 0xF0, 0xF5, 0xA0, 0x8F, 0xAC, 0x45, 0x8B, + 0xCA, 0x0F, 0x10, 0xEF, 0x7A, 0xE2, 0x6A, 0x6C, + 0xB1, 0x4E, 0xCA, 0xDA, 0x58, 0x32, 0x33, 0x94, + 0xBD, 0x40, 0x9F, 0x50, 0x75, 0xFD, 0xBF, 0x9F, + 0x74, 0x16, 0x90, 0x32, 0x29, 0xA0, 0x03, 0x5B, + 0xD1, 0x16, 0xDB, 0x2F, 0x76, 0x03, 0x16, 0xDD, + 0x6D, 0xEA, 0x22, 0xE9, 0x5A, 0x92, 0x04, 0xFE, + 0xD5, 0xAA, 0x89, 0xFF, 0x27, 0x14, 0xFD, 0x1C, + 0x20, 0x39, 0x0D, 0x1C, 0x7E, 0x9A, 0xE2, 0x9D, + 0x0F, 0x0C, 0x83, 0xC1, 0x6C, 0x72, 0x18, 0x45, + 0xFA, 0x01, 0x0C, 0xC5, 0x25, 0xF1, 0xF0, 0xC4, + 0x93, 0x40, 0x16, 0x3C, 0x1A, 0xE4, 0x6F, 0xFE, + 0x3D, 0x00, 0x4E, 0x14, 0x32, 0x40, 0x06, 0xA6, + 0x0A, 0x1C, 0x6B, 0xE7, 0x15, 0x35, 0xFD, 0xFD, + 0xF8, 0xC5, 0x6D, 0x6F, 0xD3, 0x60, 0x51, 0x7F, + 0x00, 0x40, 0x69, 0xCA, 0xE7, 0x52, 0x07, 0x0E, + 0xCC, 0x02, 0x56, 0x05, 0x43, 0x8D, 0xE0, 0x64, + 0x79, 0x5B, 0xDB, 0x38, 0xDF, 0x02, 0x67, 0xDC, + 0x7A, 0x81, 0xF8, 0x10, 0x26, 0x84, 0x87, 0x2B, + 0x4F, 0xDD, 0x9A, 0xFE, 0xCB, 0x32, 0x39, 0xDF, + 0x5D, 0xFF, 0x77, 0xC9, 0xD3, 0x5F, 0x8C, 0x8D, + 0x07, 0x89, 0xA4, 0xA3, 0x32, 0xC9, 0xC7, 0x4C, + 0x8F, 0x42, 0xE2, 0x4F, 0x4F, 0xF6, 0x10, 0x5B, + 0x9C, 0x7D, 0x41, 0x98, 0x48, 0x84, 0x9A, 0x48, + 0xFB, 0x7D, 0xAF, 0x8C, 0x19, 0xB2, 0xFE, 0xAA, + 0x8D, 0x73, 0xE6, 0x92, 0x87, 0xAE, 0xDA, 0x1B, + 0xB3, 0x0C, 0x87, 0x3D, 0x25, 0x1A, 0x19, 0xE1, + 0x7C, 0x5F, 0x56, 0xE8, 0x1E, 0xC2, 0xE7, 0x9B, + 0xF6, 0xAD, 0x63, 0x6B, 0x6B, 0x03, 0x9D, 0x19, + 0x1E, 0x0B, 0xA9, 0x7D, 0x02, 0xD4, 0xB7, 0x87, + 0xC7, 0xC7, 0x90, 0x49, 0xA6, 0x71, 0x0E, 0x4B, + 0x3A, 0xA6, 0x0E, 0x2C, 0xAE, 0x31, 0xC0, 0x66, + 0xEF, 0xB6, 0xC6, 0xE8, 0x04, 0xC8, 0x93, 0x32, + 0xAA, 0xD1, 0x61, 0x36, 0xB1, 0xF5, 0xCE, 0x21, + 0xAA, 0x49, 0x8D, 0x9F, 0xF4, 0x5D, 0x45, 0x20, + 0x48, 0xC8, 0xDA, 0x69, 0xA7, 0xFB, 0x2A, 0x31, + 0x94, 0x83, 0xF2, 0x13, 0xEB, 0xED, 0x98, 0x97, + 0x80, 0x89, 0x44, 0x61, 0xF1, 0xE6, 0x72, 0xD5, + 0x18, 0xF9, 0xB3, 0x26, 0xC7, 0x7D, 0xE1, 0x71, + 0xAD, 0xFD, 0x69, 0x12, 0x4F, 0x71, 0x96, 0x7B, + 0x70, 0xF3, 0x2B, 0xDD, 0xCD, 0x87, 0x60, 0x50, + 0xA9, 0x37, 0xE5, 0x4D, 0xDE, 0xA4, 0x86, 0xE7, + 0x86, 0x97, 0xA0, 0x24, 0x36, 0xF4, 0xF0, 0xA4, + 0xA4, 0xD3, 0x9D, 0x32, 0xB1, 0x36, 0x08, 0x50, + 0xE6, 0x47, 0x1C, 0xFD, 0x3A, 0xA9, 0x25, 0xC5, + 0xE7, 0xA8, 0xF1, 0xAD, 0x9D, 0x3A, 0x71, 0x20, + 0x67, 0x92, 0x63, 0xAF, 0x0A, 0x78, 0xDD, 0x00, + 0xF4, 0xE1, 0xFA, 0xC8, 0x07, 0x70, 0xC1, 0xEE, + 0x14, 0xAD, 0xFF, 0xE5, 0xB3, 0x73, 0xB1, 0xB8, + 0x7A, 0x37, 0xAF, 0xCE, 0x84, 0x17, 0x08, 0x29, + 0x0F, 0x70, 0xDD, 0x1E, 0x83, 0x1F, 0x0B, 0xAA, + 0xBF, 0x23, 0x5A, 0x16, 0xAD, 0x14, 0x1B, 0xA6, + 0x64, 0x66, 0xE6, 0x0A, 0xB3, 0x9E, 0x3F, 0x60, + 0x79, 0x57, 0xDD, 0x5F, 0xAB, 0x64, 0x5B, 0xC5, + 0x51, 0x53, 0x82, 0x46, 0x5B, 0x3D, 0xCC, 0x38, + 0xBC, 0xA6, 0xC1, 0x92, 0x52, 0xC0, 0xD1, 0xB8, + 0x69, 0x52, 0x76, 0x75, 0x4A, 0x96, 0x04, 0x60, + 0xA8, 0xDA, 0xD3, 0xD0, 0xA0, 0x05, 0x23, 0xCC, + 0x6F, 0x02, 0x36, 0x2E, 0xC8, 0x56, 0x13, 0x92, + 0x05, 0x61, 0xDD, 0xEF, 0xA6, 0x45, 0x61, 0x4E, + 0x97, 0xEF, 0x1D, 0x16, 0x8C, 0x5D, 0xBF, 0x60, + 0x43, 0xFE, 0x94, 0x64, 0xF0, 0xE2, 0x83, 0xCF, + 0xDE, 0xF7, 0x94, 0xEA, 0x49, 0x1B, 0x92, 0x91, + 0xA8, 0x9D, 0x2F, 0xEF, 0x87, 0xDE, 0xE8, 0xCC, + 0xC7, 0xA3, 0x77, 0xD7, 0x32, 0xF4, 0x1E, 0x86, + 0x32, 0xC7, 0xFD, 0x78, 0x09, 0x77, 0x81, 0x2B, + 0x1F, 0x7B, 0xA1, 0xF4, 0x29, 0x17, 0xD7, 0x2D, + 0x58, 0x53, 0xCC, 0x9C, 0x8E, 0xC5, 0x12, 0x81, + 0xEA, 0xE2, 0x7C, 0xAA, 0x70, 0x57, 0xDA, 0xEB, + 0x69, 0xD8, 0x0D, 0x32, 0xBA, 0x88, 0xDC, 0x5D, + 0x31, 0x96, 0xB5, 0x40, 0x91, 0x99, 0x53, 0x83, + 0xFD, 0xFD, 0x91, 0xAD, 0xC7, 0x56, 0x87, 0x49, + 0xEC, 0x04, 0xFE, 0x66, 0x3D, 0x3A, 0x06, 0x65, + 0xDD, 0x35, 0x9D, 0xE4, 0xC7, 0x18, 0xB7, 0xD1, + 0x9F, 0x6F, 0x69, 0xAD, 0x99, 0x27, 0xE5, 0xA3, + 0x1A, 0x70, 0x26, 0xBF, 0x82, 0xD6, 0xFA, 0x23, + 0x55, 0xF0, 0xC4, 0x01, 0x69, 0x60, 0x58, 0xBF, + 0xB8, 0x98, 0x7C, 0x90, 0x10, 0x79, 0x16, 0x16, + 0x7F, 0x0E, 0xB4, 0xD5, 0xAB, 0x20, 0x0A, 0x61, + 0x05, 0xB5, 0x4D, 0xFF, 0xE9, 0xC8, 0x94, 0x0F, + 0xEA, 0xD8, 0x62, 0x3F, 0x52, 0x5C, 0x0B, 0xD1, + 0x33, 0x3A, 0x59, 0xD1, 0x30, 0xBE, 0x5A, 0x58, + 0x5C, 0x0F, 0xBE, 0x63, 0xFB, 0xAC, 0x1A, 0xF4, + 0xC8, 0xFD, 0xCF, 0x26, 0x95, 0x17, 0xD8, 0xBB, + 0x38, 0x78, 0xB4, 0xCF, 0xA4, 0x9F, 0x44, 0xA6, + 0xB8, 0xA3, 0xD9, 0xFE, 0x30, 0xFB, 0x7A, 0x96, + 0xDF, 0x34, 0x86, 0xBE, 0xA5, 0x87, 0x40, 0x7A, + 0x69, 0x6E, 0xB7, 0xAD, 0x99, 0x9C, 0x9D, 0xBE, + 0x7F, 0x2E, 0xE5, 0x14, 0x12, 0x1F, 0xEA, 0x0D, + 0x24, 0x42, 0x08, 0xA2, 0x14, 0xA6, 0x25, 0xC7, + 0x59, 0x59, 0x29, 0xF8, 0x7B, 0xC5, 0x05, 0x02, + 0x5C, 0x22, 0x80, 0xB2, 0x6D, 0x5F, 0x85, 0x65, + 0x35, 0x24, 0x13, 0xF7, 0x28, 0xA0, 0x52, 0x9D, + 0xBE, 0x1B, 0x8E, 0xC1, 0x79, 0xE8, 0xA2, 0xDE, + 0x02, 0xDE, 0x2E, 0x23, 0xAE, 0x14, 0xA4, 0x59, + 0xCB, 0x24, 0x77, 0x9B, 0xCA, 0xA9, 0xAC, 0xAB, + 0xE0, 0xD5, 0xF1, 0xEE, 0xE3, 0x1D, 0x69, 0xB7, + 0xF5, 0x50, 0x47, 0x06, 0x93, 0xCE, 0x20, 0x88, + 0x37, 0xD1, 0xA5, 0xCD, 0xF7, 0xCA, 0x81, 0xFE, + 0x5C, 0x55, 0x7A, 0xCD, 0xED, 0xC3, 0x53, 0x0F, + 0x40, 0x03, 0x01, 0x20, 0xA7, 0x26, 0xED, 0x5A, + 0xE9, 0xB0, 0x64, 0xB2, 0x0E, 0x39, 0x44, 0xA2, + 0x78, 0xF0, 0x10, 0x8B, 0x3B, 0x02, 0x81, 0x9D, + 0x40, 0x6D, 0xAF, 0xC1, 0x29, 0x3A, 0x25, 0x06, + 0x12, 0x80, 0xA5, 0xD7, 0x66, 0xD9, 0xE7, 0x7C, + 0xA2, 0x5D, 0x1A, 0x14, 0x15, 0x7A, 0x6A, 0x9D, + 0x2D, 0x70, 0x8D, 0x62, 0xAE, 0x27, 0x8D, 0x36, + 0x43, 0x5D, 0xD5, 0x51, 0xA4, 0x0B, 0x53, 0x43, + 0x11, 0xAE, 0x9B, 0x39, 0x37, 0x22, 0x6D, 0xA2, + 0xDB, 0x17, 0x8C, 0xFC, 0x8A, 0x00, 0x20, 0xE8, + 0xB0, 0x42, 0xCB, 0xBF, 0x1C, 0x91, 0x8D, 0xB9, + 0x7A, 0x7A, 0x66, 0x61, 0xA8, 0x5E, 0x13, 0x17, + 0x05, 0x18, 0x23, 0x52, 0x10, 0x9B, 0x87, 0x72, + 0x51, 0xB8, 0x89, 0x14, 0x1E, 0x61, 0x8B, 0x1C, + 0x82, 0x92, 0xEC, 0xBF, 0xA8, 0x9A, 0xE2, 0xA5, + 0x9A, 0xEC, 0xA2, 0xDB, 0xB4, 0xAC, 0x8D, 0xCA, + 0x45, 0xB9, 0x9D, 0xB8, 0x51, 0xFF, 0x56, 0xEA, + 0xFD, 0xD4, 0x90, 0xA2, 0x48, 0x13, 0x67, 0xC2, + 0x18, 0xAA, 0x8E, 0xBD, 0xB3, 0xED, 0xEF, 0xA7, + 0x98, 0x0C, 0xBB, 0x8B, 0x64, 0xAC, 0x5B, 0x72, + 0x22, 0x49, 0xCA, 0x50, 0x23, 0xFD, 0xC7, 0x5C, + 0x43, 0xA4, 0x14, 0xE3, 0xDD, 0x55, 0xC1, 0x45, + 0xB7, 0x43, 0x03, 0xC5, 0x5F, 0xD0, 0xF8, 0x96, + 0xC3, 0x5C, 0x51, 0xBF, 0x54, 0xD1, 0xC7, 0xA2, + 0x1C, 0xF7, 0xCC, 0x4A, 0xC3, 0xD4, 0x1E, 0x54, + 0xEE, 0x60, 0x1D, 0xDB, 0xA5, 0x2E, 0x1B, 0xC0, + 0x78, 0x59, 0x5E, 0xEB, 0x86, 0xBC, 0x58, 0xA4, + 0x71, 0x45, 0xE9, 0xA8, 0x48, 0x16, 0xC4, 0x0C, + 0x0E, 0x21, 0x4E, 0xD7, 0x59, 0xAA, 0xD1, 0xFD, + 0xDE, 0x27, 0x7C, 0xDA, 0x07, 0x5E, 0xEA, 0x1C, + 0xB1, 0xFA, 0xC5, 0x1F, 0x07, 0x69, 0xAC, 0x23, + 0x48, 0x94, 0x37, 0x1A, 0xF5, 0x5B, 0xB2, 0x6C, + 0xA9, 0x5E, 0x13, 0x0C, 0x44, 0x81, 0xC3, 0x84, + 0x07, 0xCE, 0x8C, 0x39, 0x63, 0x91, 0x3B, 0x4D, + 0x3C, 0xBE, 0x9F, 0xEE, 0xAB, 0x5F, 0x94, 0x9E, + 0x17, 0xD2, 0x9F, 0x0A, 0x2E, 0x77, 0x8C, 0xEF, + 0x47, 0x66, 0x4B, 0x36, 0x97, 0xD8, 0xC6, 0x80, + 0x7F, 0x4D, 0x1E, 0x5E, 0x3F, 0xF8, 0xC8, 0xE8, + 0x45, 0xB6, 0xE0, 0x44, 0xA1, 0xE3, 0xD3, 0x14, + 0xD4, 0x44, 0x90, 0x94, 0x34, 0xFB, 0x40, 0xF9, + 0x7F, 0xEA, 0xAC, 0x2E, 0x34, 0xB9, 0x10, 0x9B, + 0x8E, 0x2D, 0x82, 0xD2, 0xD4, 0xF4, 0x5E, 0xE3, + 0x63, 0xFB, 0x25, 0x5B, 0x1C, 0x65, 0x73, 0x6D, + 0x4E, 0x4B, 0x8D, 0xB2, 0xFE, 0x9D, 0xFA, 0x0D, + 0xAE, 0x5C, 0xC5, 0xB2, 0xA8, 0x9E, 0x83, 0x34, + 0xE5, 0xC9, 0x72, 0x4B, 0x2C, 0xA5, 0xD2, 0x0C, + 0x0D, 0x15, 0x05, 0xFB, 0x8B, 0x96, 0xC4, 0xD3, + 0x32, 0x97, 0x2D, 0xB1, 0xAF, 0xC5, 0x27, 0x38, + 0x37, 0x1D, 0xE5, 0xDF, 0xAF, 0x32, 0x62, 0xD1, + 0x88, 0x2F, 0x40, 0x77, 0xEB, 0xCA, 0xEA, 0x4B, + 0xB2, 0x37, 0xFF, 0xAA, 0xFD, 0x17, 0x2A, 0x7F, + 0x60, 0x7C, 0xD2, 0x47, 0x78, 0x29, 0xD5, 0x51, + 0xE6, 0xC0, 0xBB, 0x58, 0x30, 0x4C, 0xF0, 0x33, + 0x07, 0x10, 0x66, 0xC8, 0x41, 0xE8, 0xB9, 0x41, + 0x40, 0x97, 0xAE, 0xD3, 0xD9, 0x9D, 0xCA, 0x93, + 0xA9, 0x57, 0x89, 0x5D, 0x45, 0x71, 0xCF, 0xD6, + 0xCE, 0xB2, 0x7D, 0xC8, 0x6B, 0x05, 0xE5, 0x33, + 0x98, 0x90, 0x26, 0x12, 0xD6, 0x03, 0xBC, 0xC1, + 0xE5, 0xFA, 0x81, 0x5C, 0x6B, 0xFF, 0x14, 0xB2, + 0xCD, 0xF2, 0x19, 0x26, 0xC2, 0xB1, 0x98, 0x48, + 0xCA, 0x41, 0x08, 0x14, 0x9F, 0xC3, 0x3B, 0xFD, + 0xD6, 0xFA, 0xE5, 0xA2, 0x9E, 0x65, 0xF8, 0x71, + 0x4A, 0x00, 0x77, 0x5F, 0x41, 0x62, 0xD7, 0xFB, + 0x95, 0x2C, 0x6B, 0xE9, 0xF1, 0xA2, 0x16, 0x26, + 0xBF, 0x9A, 0x67, 0xF6, 0x4F, 0xAA, 0xF0, 0xC2, + 0x9C, 0xE6, 0xD2, 0x68, 0x46, 0x67, 0xDC, 0xE5, + 0x92, 0x10, 0x13, 0x53, 0x88, 0xC1, 0xD3, 0x1A, + 0xEB, 0x4D, 0x37, 0xDE, 0x29, 0x6A, 0xBD, 0xB3, + 0xFD, 0xCD, 0x41, 0xD7, 0xEB, 0xEA, 0xCA, 0x0D, + 0xFD, 0x49, 0x2C, 0xE1, 0xB8, 0xEB, 0x82, 0xB2, + 0x76, 0x56, 0xC6, 0xDD, 0x74, 0x8A, 0x89, 0xBD, + 0xF7, 0xCC, 0xA6, 0x54, 0xF6, 0x35, 0xB7, 0xED, + 0xAC, 0x0B, 0xB3, 0x9D, 0x0A, 0x46, 0x7F, 0xCC, + 0x01, 0x3B, 0x28, 0x77, 0xC6, 0x48, 0x13, 0xB3, + 0x1E, 0x9B, 0xAE, 0x80, 0x93, 0x62, 0xA2, 0xEC, + 0x1E, 0xEA, 0x6D, 0x2D, 0xB9, 0xEF, 0x33, 0x29, + 0x80, 0x9E, 0x54, 0x7C, 0xF0, 0xA8, 0xD0, 0x5D, + 0x65, 0x11, 0xE5, 0x97, 0x6C, 0xF8, 0xED, 0xCB, + 0x50, 0x03, 0xF6, 0x0C, 0x77, 0xCD, 0xAD, 0x62, + 0x8F, 0x17, 0xE2, 0x2A, 0x9E, 0x2E, 0x50, 0xEC, + 0x6A, 0x56, 0x59, 0xEB, 0x8C, 0xB5, 0xE6, 0xB1, + 0x48, 0x5F, 0x2B, 0x4B, 0x16, 0x5E, 0x46, 0x49, + 0xA8, 0x2E, 0xC8, 0xFB, 0xDC, 0x20, 0x37, 0x8D, + 0xE6, 0xF9, 0x42, 0x78, 0x83, 0x27, 0x59, 0x15, + 0xE0, 0x0A, 0x63, 0x8F, 0x9F, 0xCC, 0x0B, 0x09, + 0x75, 0xC4, 0x47, 0x4D, 0x05, 0x03, 0x44, 0x87, + 0x92, 0x09, 0x00, 0x90, 0xA8, 0x68, 0xC9, 0x3D, + 0x3A, 0xDB, 0x45, 0x66, 0x71, 0xD9, 0xDF, 0xEE, + 0xDC, 0x06, 0xC2, 0x52, 0x20, 0x86, 0xDB, 0x85, + 0x2B, 0x43, 0xD9, 0x57, 0x04, 0x17, 0x8F, 0x32, + 0x51, 0x92, 0x2E, 0x23, 0x90, 0x0A, 0x70, 0x73, + 0xC1, 0xA1, 0x1D, 0x40, 0xF5, 0x5F, 0x84, 0x1A, + 0xE8, 0x0E, 0xEA, 0x72, 0x22, 0x1D, 0xCF, 0xE2, + 0x5B, 0xEB, 0x84, 0x7F, 0x93, 0xFD, 0x04, 0x15, + 0x9B, 0x9B, 0xEB, 0x15, 0xE5, 0x18, 0x2F, 0x04, + 0xB2, 0xB0, 0x1A, 0x35, 0xD4, 0xD5, 0xC5, 0x55, + 0x74, 0xC8, 0x35, 0x25, 0xA9, 0xF9, 0x68, 0x35, + 0x25, 0x41, 0x64, 0x84, 0xBA, 0xF5, 0x9D, 0xDF, + 0x95, 0x3F, 0x49, 0x9E, 0xC1, 0xC7, 0x01, 0x03, + 0xA3, 0x96, 0x6B, 0x94, 0xBD, 0x7C, 0x5E, 0x11, + 0x8C, 0xFA, 0x47, 0x92, 0x50, 0x24, 0xC1, 0x17, + 0xF0, 0xF6, 0x5A, 0x87, 0x38, 0x24, 0x0E, 0xC1, + 0x1A, 0xC8, 0x48, 0x6F, 0xEE, 0x62, 0x52, 0xED, + 0x75, 0x65, 0xD7, 0x57, 0xBD, 0x06, 0x17, 0x80, + 0x33, 0xBB, 0x3D, 0x0C, 0x0A, 0xA2, 0xA2, 0x07, + 0x6B, 0xCD, 0xF5, 0x4E, 0xB1, 0x8C, 0x74, 0x19, + 0x06, 0x81, 0xB5, 0x4C, 0x61, 0x9F, 0xC5, 0x90, + 0xE0, 0xCB, 0xC2, 0xEB, 0xDB, 0x9E, 0x3E, 0xC8, + 0xC5, 0xEF, 0x2D, 0xFB, 0x67, 0x2F, 0x27, 0xFB, + 0x26, 0x3E, 0x3B, 0xF5, 0x6C, 0x5A, 0x2C, 0xFA, + 0xD0, 0xB2, 0xC1, 0xAA, 0x88, 0x1D, 0x64, 0xBC, + 0x46, 0xC6, 0x3C, 0x98, 0x69, 0x25, 0x3F, 0xC0, + 0x7F, 0xC0, 0xD9, 0x1B, 0xE7, 0xFF, 0xC6, 0xC7, + 0xE1, 0x66, 0x11, 0x8C, 0x6F, 0x88, 0xAD, 0x40, + 0x15, 0x38, 0xE7, 0x58, 0xC5, 0x4E, 0x28, 0xCB, + 0x67, 0xC5, 0x28, 0x65, 0xA4, 0x05, 0x6D, 0x4E, + 0xED, 0x84, 0x10, 0x0E, 0xF7, 0x7A, 0x0A, 0x07, + 0x21, 0x49, 0x54, 0x48, 0x91, 0x7E, 0xB5, 0xA8, + 0xBF, 0xBA, 0x18, 0x1A, 0xD9, 0x82, 0x49, 0x82, + 0x76, 0x4F, 0x8F, 0x6F, 0xC7, 0x84, 0xF9, 0x49, + 0x28, 0xCE, 0x12, 0xBB, 0xF0, 0x34, 0xBD, 0xAA, + 0x4F, 0xE8, 0x39, 0x6C, 0xB2, 0xB6, 0x95, 0xA0, + 0x2E, 0xEA, 0x90, 0x22, 0xE4, 0x88, 0x82, 0xE5, + 0x54, 0x38, 0x5A, 0xDA, 0x85, 0xAA, 0x78, 0xC8, + 0x88, 0x98, 0xDC, 0x7E, 0xB7, 0x24, 0x8A, 0x7B, + 0x16, 0x93, 0xC7, 0x95, 0x5D, 0x53, 0x52, 0x85, + 0x2A, 0x8C, 0x8B, 0x76, 0xA9, 0x5C, 0x02, 0x72, + 0xBB, 0x88, 0xE6, 0x11, 0x33, 0x64, 0x17, 0x82, + 0x27, 0x9B, 0x5C, 0x21, 0x90, 0xA0, 0x4C, 0x7A, + 0x92, 0xF2, 0x80, 0x23, 0x9D, 0xCE, 0x90, 0xD3, + 0x45, 0x43, 0xA0, 0xDC, 0xD9, 0x06, 0xFC, 0x92, + 0x8A, 0x11, 0x68, 0x47, 0xC5, 0x18, 0xD6, 0x20, + 0x01, 0xF8, 0xCA, 0x89, 0x2D, 0xE7, 0x52, 0x3D, + 0x9C, 0xD8, 0xA6, 0xDB, 0x3E, 0x3E, 0xAF, 0xE7, + 0x21, 0x8D, 0x9F, 0xA4, 0xEF, 0xBC, 0x62, 0xEA, + 0xC7, 0x5E, 0xD3, 0x8F, 0xAF, 0xB3, 0xA5, 0x8F, + 0xE1, 0xF6, 0x2A, 0xAC, 0x53, 0x03, 0x26, 0x8E, + 0x11, 0xF7, 0x76, 0xB3, 0x30, 0x0D, 0x7D, 0xB0, + 0x12, 0xA8, 0x35, 0xB9, 0x44, 0x02, 0x02, 0x79, + 0xEF, 0xBC, 0xD2, 0x32, 0x34, 0x8C, 0x10, 0x58, + 0x7E, 0xDA, 0x41, 0x3E, 0xC4, 0x5C, 0x82, 0x5E, + 0x57, 0xC4, 0x92, 0x7E, 0x10, 0x3B, 0xAB, 0x58, + 0xDC, 0xCB, 0xA7, 0x6C, 0x89, 0x2E, 0x32, 0x23, + 0xF6, 0x76, 0x30, 0xA6, 0x12, 0xCB, 0x00, 0x85, + 0x65, 0xC9, 0x1A, 0x4D, 0xE7, 0xF5, 0x4B, 0xC9, + 0xFD, 0x50, 0x00, 0xAE, 0xD2, 0x07, 0xFE, 0x7D, + 0xD6, 0x02, 0x18, 0x69, 0x01, 0x41, 0x3B, 0xE8, + 0x32, 0xB5, 0x09, 0xAD, 0x3A, 0x27, 0xF4, 0x1A, + 0x9A, 0x7D, 0x62, 0xE2, 0x7F, 0xB7, 0xBD, 0x50, + 0xA5, 0xC5, 0x3E, 0x12, 0x30, 0x01, 0x7E, 0x5D, + 0xB0, 0xE5, 0x3D, 0xF8, 0xF9, 0xFB, 0x4E, 0xB5, + 0x9B, 0x96, 0x9A, 0xE8, 0x91, 0x06, 0x8D, 0x73, + 0x9F, 0xC3, 0x10, 0x87, 0xEB, 0xCD, 0xBA, 0xB5, + 0xBA, 0xE5, 0x10, 0x01, 0x45, 0xDE, 0x86, 0x65, + 0xFD, 0xFA, 0xF1, 0x6F, 0xA4, 0x0E, 0xF0, 0x3D, + 0xC5, 0x45, 0x26, 0xFE, 0xFF, 0x19, 0x0A, 0xAF, + 0x5C, 0x7A, 0xDF, 0x23, 0x67, 0xDE, 0xB8, 0xA1, + 0x09, 0x4F, 0xC7, 0x6D, 0x69, 0x38, 0xA5, 0xBC, + 0x16, 0xFD, 0xF4, 0x9E, 0xFC, 0xB0, 0xA8, 0x48, + 0x35, 0x7B, 0x80, 0xBF, 0x35, 0xF2, 0x7A, 0x5F, + 0xF6, 0xD9, 0x82, 0xCF, 0xE8, 0x3E, 0x3A, 0x0F, + 0x40, 0xCF, 0x4E, 0x2F, 0x01, 0x45, 0x0B, 0xBF, + 0xC1, 0x12, 0xBA, 0xA4, 0xE5, 0x18, 0x1D, 0x91, + 0xDD, 0xC0, 0x3D, 0xB8, 0x8B, 0x6F, 0xD4, 0xE4, + 0x56, 0xBB, 0x5C, 0xC2, 0xAA, 0xE1, 0xA7, 0xDF, + 0xE4, 0xC9, 0x48, 0xB9, 0xD1, 0x75, 0x35, 0x69, + 0x31, 0xE9, 0x03, 0x35, 0xE4, 0x2A, 0x18, 0x54, + 0x54, 0xC4, 0xEB, 0x86, 0x82, 0x8A, 0x8A, 0x18, + 0x2F, 0x37, 0x57, 0x8C, 0x76, 0x0B, 0x36, 0x44, + 0x4B, 0xBD, 0xF0, 0xA0, 0x6A, 0x5C, 0x4D, 0x97, + 0xEA, 0x38, 0xE8, 0xF5, 0x07, 0xE4, 0xF8, 0x71, + 0xAB, 0x94, 0x78, 0x92, 0xCD, 0xA4, 0x84, 0x64, + 0x8F, 0xA0, 0x6E, 0xB2, 0x72, 0xA8, 0x10, 0x2D, + 0xB5, 0x66, 0x04, 0xEC, 0xFE, 0x2E, 0x92, 0x1A, + 0xB5, 0x52, 0xDC, 0x02, 0x2D, 0xF8, 0xFA, 0x93, + 0xA9, 0xE9, 0xF7, 0xA7, 0x71, 0x65, 0x27, 0x7E, + 0x18, 0x16, 0x60, 0xFC, 0xC5, 0x42, 0x0B, 0x69, + 0xBA, 0x50, 0x89, 0x3B, 0x4C, 0x69, 0x38, 0x1F, + 0x94, 0x6A, 0x89, 0x3D, 0xEA, 0x46, 0x0C, 0xB5, + 0x4B, 0x00, 0x04, 0x5A, 0x58, 0xCA, 0x4D, 0x7E, + 0x22, 0x29, 0x3F, 0x1D, 0xC8, 0xD2, 0xDF, 0x80, + 0x63, 0xAB, 0x4A, 0x98, 0x53, 0xE5, 0x3E, 0x9C, + 0xF4, 0x37, 0xBB, 0x72, 0x6A, 0xD7, 0xF6, 0x22, + 0xE1, 0xE3, 0xB5, 0x59, 0x0D, 0xE0, 0x3A, 0xFD, + 0x8B, 0x95, 0xAB, 0x83, 0xA9, 0xF9, 0x78, 0xCF, + 0x38, 0xA7, 0x73, 0xD5, 0xFA, 0x18, 0xA3, 0xA0, + 0xDB, 0x10, 0x82, 0xB4, 0x46, 0x8E, 0xA8, 0x1A, + 0xC8, 0x91, 0x97, 0x92, 0xE2, 0x93, 0xE7, 0x75, + 0x4A, 0xC7, 0x54, 0xFD, 0x94, 0x7B, 0xB1, 0xB3, + 0x88, 0x8A, 0x26, 0x9F, 0x88, 0x01, 0x10, 0x52, + 0xBE, 0xE5, 0x48, 0x1B, 0x96, 0xCD, 0x9D, 0xB8, + 0xB0, 0x02, 0x47, 0x46, 0xDB, 0x90, 0xC6, 0x6E, + 0x7A, 0x53, 0xE5, 0x0E, 0xE9, 0xFA, 0xC3, 0x0F, + 0x17, 0xE0, 0xD5, 0x9F, 0x6A, 0x6F, 0xC9, 0xC5, + 0xE6, 0x5B, 0x75, 0xEA, 0xAF, 0x4A, 0xDC, 0x63, + 0xF5, 0x6B, 0x2F, 0xDF, 0xF0, 0xA8, 0x4F, 0xD9, + 0x6B, 0x77, 0x8F, 0x3E, 0x17, 0x7F, 0x97, 0xB0, + 0x8B, 0x15, 0x1E, 0xA2, 0x9B, 0x3B, 0x07, 0x02, + 0xD3, 0xC9, 0xD3, 0x71, 0x65, 0x81, 0x56, 0x33, + 0x60, 0x0D, 0x32, 0x63, 0xBD, 0x62, 0x2B, 0x66, + 0x19, 0x41, 0x0B, 0x10, 0x91, 0x7B, 0xD0, 0xA7, + 0x00, 0xEF, 0xE7, 0x2D, 0xC0, 0xCF, 0x93, 0x5D, + 0x78, 0xE8, 0x3B, 0xF5, 0x3F, 0xD3, 0xA5, 0x3F, + 0xF3, 0xB8, 0xC6, 0xFD, 0x55, 0xB3, 0xEA, 0x4E, + 0x6F, 0x24, 0x5A, 0x3D, 0x33, 0x53, 0x83, 0x40, + 0xC7, 0x1B, 0xF3, 0x69, 0x07, 0x26, 0xB8, 0x46, + 0xA3, 0xC8, 0xE4, 0x9F, 0x23, 0xC1, 0x5A, 0xAD, + 0x77, 0x3E, 0x38, 0x93, 0xBF, 0xB9, 0xB9, 0x2B, + 0xB3, 0xBC, 0x2E, 0xC2, 0x69, 0x1A, 0x5C, 0x4B, + 0xAA, 0x37, 0x78, 0x14, 0xB9, 0x58, 0x37, 0xE2, + 0xFD, 0x63, 0xD9, 0xED, 0xE0, 0x25, 0x23, 0xA6, + 0xF5, 0xC2, 0xB4, 0x06, 0xFD, 0xB1, 0x83, 0xA6, + 0xE9, 0x76, 0x9B, 0x9D, 0xF9, 0x17, 0x07, 0xD7, + 0x2F, 0x2D, 0xB9, 0x7F, 0x81, 0x31, 0x5D, 0x76, + 0x89, 0x67, 0xAF, 0x97, 0xCD, 0xB0, 0xA0, 0x1C, + 0x04, 0x86, 0xAF, 0xE7, 0x5E, 0xBC, 0xB2, 0x97, + 0x8F, 0x43, 0x8D, 0x5F, 0xBD, 0x21, 0x13, 0x0B, + 0x2C, 0x39, 0x00, 0x48, 0x16, 0xF9, 0xEF, 0x93, + 0xF1, 0xF8, 0x95, 0x39, 0x3B, 0x44, 0xAF, 0x57, + 0x80, 0xF7, 0x0C, 0xE8, 0xFE, 0x50, 0x2E, 0xAC, + 0x70, 0x36, 0x1F, 0xA8, 0xE4, 0x33, 0x34, 0x7E, + 0xDF, 0xDE, 0x71, 0xD2, 0xB2, 0x5A, 0xF9, 0x21, + 0x3B, 0x5C, 0xD3, 0x34, 0xFF, 0x96, 0xF9, 0xB2, + 0x9C, 0x26, 0xF4, 0xDB, 0x52, 0x0F, 0xD9, 0xEF, + 0xB4, 0xDD, 0xD1, 0xA8, 0xB4, 0x6E, 0x27, 0x12, + 0x79, 0x22, 0x84, 0x0A, 0x20, 0x1D, 0x6E, 0x7F, + 0x09, 0xC6, 0x31, 0xD3, 0x2E, 0x98, 0xC9, 0x08, + 0xBD, 0xAA, 0xC3, 0x65, 0x38, 0xD8, 0xC7, 0x13, + 0xF1, 0xCF, 0x18, 0xC3, 0x7B, 0x7E, 0xE5, 0x7C, + 0x5E, 0x22, 0x36, 0x88, 0x71, 0x5C, 0xB7, 0xCC, + 0x4D, 0xA4, 0xF7, 0x83, 0xE0, 0x1E, 0xC2, 0x4F, + 0xEA, 0x2C, 0xFF, 0xF7, 0x1C, 0xBF, 0x84, 0x31, + 0x70, 0x75, 0x12, 0xC8, 0xFB, 0xC6, 0xFE, 0x5A, + 0x14, 0x91, 0x3B, 0xD8, 0x36, 0x67, 0x1E, 0xF9, + 0xF4, 0x29, 0x6F, 0xA1, 0xEA, 0x46, 0x27, 0xA0, + 0xC1, 0x34, 0xAE, 0x09, 0xEA, 0xDA, 0x0E, 0xBB, + 0x83, 0x20, 0x4E, 0x2A, 0x0B, 0x59, 0xF4, 0x1D, + 0xC7, 0x62, 0x47, 0x3A, 0x0E, 0xA0, 0x92, 0xEA, + 0x8E, 0x00, 0x63, 0x70, 0x92, 0x18, 0xF9, 0x78, + 0x8C, 0xED, 0xEE, 0x9D, 0x70, 0x50, 0x58, 0x12, + 0xAB, 0x9C, 0xC8, 0xA6, 0x71, 0x46, 0x94, 0xDD, + 0xC5, 0xE4, 0xE6, 0x87, 0x84, 0x88, 0xFB, 0x77, + 0x4A, 0x79, 0x62, 0x5B, 0x9E, 0x27, 0xD4, 0x85, + 0x1A, 0x33, 0xE4, 0x5A, 0x2E, 0x4C, 0x29, 0xA0, + 0x3D, 0x47, 0xA2, 0x6B, 0xEE, 0x08, 0xFD, 0xB5, + 0xCE, 0xE5, 0xC9, 0x8E, 0x18, 0x1C, 0x04, 0x01, + 0xD1, 0xB3, 0xF4, 0x01, 0x90, 0xB3, 0x2E, 0x70, + 0x85, 0xBE, 0x47, 0x13, 0xD9, 0xBC, 0x00, 0xFE, + 0xA1, 0x9A, 0x72, 0x7B, 0x59, 0x98, 0x75, 0xCC, + 0xDB, 0xA1, 0xB5, 0x5C, 0xF4, 0x8A, 0x19, 0xDF, + 0x5B, 0x1D, 0xC2, 0xCF, 0x3B, 0x82, 0x3C, 0xDB, + 0x67, 0x40, 0x4F, 0xA9, 0xBA, 0x3E, 0xF8, 0xA3, + 0xD1, 0x1B, 0xA0, 0x64, 0x24, 0xED, 0xD0, 0x22, + 0xDF, 0x6D, 0xE5, 0x38, 0xDB, 0x2C, 0x10, 0x49, + 0x86, 0x11, 0xAC, 0x7C, 0xFC, 0xCF, 0xAE, 0x41, + 0x0C, 0x36, 0x05, 0x63, 0x0C, 0x27, 0x08, 0x9E, + 0xED, 0xEB, 0x25, 0x41, 0xFA, 0xB2, 0x8E, 0x12, + 0x79, 0x64, 0x52, 0x80, 0xF5, 0x55, 0x62, 0xBB, + 0x2F, 0x95, 0xE9, 0x41, 0x8D, 0x6E, 0xE7, 0x37, + 0xCA, 0x71, 0xF9, 0xC7, 0x36, 0xE5, 0x6D, 0xA5, + 0x38, 0xB2, 0x90, 0xBB, 0xEA, 0x1F, 0xAF, 0x57, + 0x69, 0x01, 0xD6, 0x3A, 0xA1, 0xC8, 0xF6, 0xBC, + 0x82, 0x1D, 0xF6, 0xE1, 0x0D, 0x5B, 0xE0, 0x30, + 0xB9, 0x87, 0xE5, 0x7F, 0xB9, 0xDB, 0x76, 0x2F, + 0x5A, 0xE8, 0xFA, 0xF2, 0xC9, 0x27, 0x61, 0x87, + 0xFE, 0xA3, 0xC0, 0x1B, 0xA7, 0x99, 0xD7, 0x20, + 0x95, 0x80, 0x45, 0x0E, 0xE3, 0x11, 0xE1, 0x4B, + 0x83, 0xA5, 0xC5, 0xED, 0x53, 0xF3, 0xFD, 0xD2, + 0x34, 0x8F, 0xD1, 0x2B, 0x7A, 0xB5, 0x6F, 0x5F, + 0xEA, 0x55, 0x0D, 0xBB, 0x74, 0x06, 0x85, 0xD7, + 0x07, 0xDC, 0x25, 0x94, 0xB5, 0xBD, 0x22, 0x85, + 0x9F, 0xE1, 0xD8, 0xD5, 0xA6, 0xC9, 0x60, 0x11, + 0x41, 0x8D, 0x5B, 0x60, 0xE5, 0x8A, 0x57, 0xC8, + 0x8C, 0x41, 0x3A, 0xC0, 0x17, 0x99, 0xA5, 0xE4, + 0x0E, 0x90, 0x53, 0x3D, 0xE2, 0xFB, 0x6A, 0x58, + 0x64, 0x37, 0xD5, 0xD9, 0xB5, 0x0A, 0x3E, 0x0B, + 0x86, 0xFD, 0x2B, 0x2C, 0x52, 0x35, 0xE7, 0x9A, + 0xCA, 0x54, 0xD4, 0x3E, 0x75, 0x5B, 0xA9, 0xB7, + 0x2E, 0xF9, 0x2D, 0x5C, 0xF8, 0x8B, 0xB5, 0x22, + 0xD9, 0xEE, 0xE7, 0x20, 0x6C, 0x7D, 0x25, 0x14, + 0x0E, 0x7D, 0xC4, 0x1C, 0x58, 0xB2, 0xF3, 0xF6, + 0x9C, 0xE3, 0x81, 0x74, 0xD5, 0x97, 0xAB, 0x97, + 0x35, 0x71, 0x81, 0xA1, 0x83, 0x4A, 0xBF, 0x3F, + 0x1A, 0x97, 0xDE, 0x65, 0xD6, 0xD8, 0xAD, 0x8A, + 0xDE, 0x10, 0x25, 0xCC, 0xF2, 0xD1, 0x0C, 0xA5, + 0x31, 0xA9, 0x3C, 0xC8, 0x3E, 0x23, 0xD1, 0x4D, + 0x4F, 0x94, 0x99, 0x0B, 0xAC, 0x03, 0xDD, 0x3D, + 0xF3, 0x50, 0xF5, 0xEB, 0x86, 0x4E, 0x4F, 0xD0, + 0x09, 0x52, 0x79, 0x2C, 0x8C, 0xF4, 0x4A, 0x55, + 0xB3, 0x49, 0x51, 0x6E, 0x57, 0x14, 0xF9, 0x7E, + 0x5B, 0x9F, 0xA9, 0xBC, 0x71, 0x48, 0xD6, 0xBD, + 0xA4, 0xC9, 0x5A, 0x6D, 0xC4, 0x1A, 0x02, 0xE2, + 0xB9, 0xC7, 0x64, 0x0E, 0xA2, 0x37, 0x00, 0x3B, + 0xC9, 0x73, 0x21, 0x4E, 0xF1, 0x45, 0x8E, 0x5B, + 0xFD, 0xE1, 0x9A, 0x48, 0x77, 0x1B, 0xC8, 0xD3, + 0x36, 0xC5, 0xEE, 0x47, 0x8D, 0x16, 0x55, 0x4C, + 0x44, 0x3F, 0x82, 0x6E, 0x57, 0x18, 0x70, 0xFD, + 0x65, 0xE3, 0x43, 0x65, 0x36, 0xB0, 0xAF, 0x45, + 0xC7, 0x53, 0xD0, 0xD9, 0x28, 0xB1, 0xE1, 0xD4, + 0x1B, 0x95, 0x77, 0x7E, 0x26, 0x86, 0x68, 0x62, + 0xFA, 0x57, 0x2E, 0x88, 0xB9, 0x2C, 0x95, 0x00, + 0x92, 0xE1, 0x5D, 0x7C, 0x16, 0x47, 0x06, 0x09, + 0x19, 0xF3, 0xD8, 0x87, 0xDE, 0xC7, 0x0B, 0xDB, + 0x89, 0xF4, 0x36, 0x97, 0xF5, 0x1C, 0xE3, 0x46, + 0x31, 0x1B, 0xC7, 0xC4, 0xE3, 0x9B, 0xC7, 0x1C, + 0x4C, 0x04, 0xA8, 0xDA, 0xBC, 0x66, 0x5F, 0xA2, + 0x26, 0x5C, 0xE8, 0xDB, 0x41, 0xF3, 0x0F, 0x33, + 0x5E, 0x9F, 0x5A, 0xBD, 0x92, 0x58, 0xA9, 0xEA, + 0xBA, 0x19, 0xFB, 0x21, 0x04, 0x41, 0xAD, 0xED, + 0x3A, 0xBC, 0xBE, 0xDA, 0xC2, 0x15, 0xCE, 0x4A, + 0x29, 0x7A, 0xCE, 0x35, 0x51, 0x42, 0x4C, 0x20, + 0x52, 0x8A, 0x5F, 0xFB, 0x2C, 0xB6, 0x5D, 0x0F, + 0xAE, 0x09, 0x7C, 0x66, 0x3D, 0x80, 0x62, 0x90, + 0x86, 0x17, 0x61, 0xEF, 0xF4, 0x1A, 0x59, 0x85, + 0xAD, 0x27, 0x0C, 0x6A, 0xE0, 0xF3, 0x18, 0xBF, + 0xEF, 0x2D, 0xAA, 0x80, 0x18, 0xA7, 0x8F, 0xF0, + 0xAB, 0x8A, 0x2C, 0x28, 0x93, 0xBC, 0xD5, 0x3C, + 0xED, 0xBF, 0x02, 0xE9, 0x9B, 0x1F, 0x46, 0xFD, + 0x96, 0x5D, 0xE8, 0x0E, 0xAC, 0xF4, 0x6A, 0xA7, + 0xEB, 0x4A, 0xC7, 0xBA, 0xE1, 0x5D, 0x9E, 0x9B, + 0xB1, 0x5C, 0x13, 0x3A, 0xCF, 0xC9, 0x41, 0x35, + 0x0D, 0xA4, 0xFB, 0x47, 0x1F, 0x42, 0xE3, 0x37, + 0x19, 0xC4, 0x13, 0x56, 0x81, 0xE3, 0xF2, 0x89, + 0xE7, 0x24, 0x80, 0x54, 0xD8, 0xF4, 0x6D, 0xCC, + 0x72, 0x22, 0xC7, 0xDE, 0xB6, 0x06, 0xDF, 0xB7, + 0x4C, 0xB6, 0x31, 0x09, 0xC3, 0x27, 0x29, 0xEA, + 0xFB, 0xEA, 0x40, 0xB9, 0x60, 0xD6, 0x50, 0x11, + 0x01, 0xA2, 0xB1, 0xB2, 0x14, 0x9F, 0x5F, 0x08, + 0xD7, 0x5B, 0x95, 0xF8, 0xD1, 0xA8, 0x94, 0x27, + 0x5F, 0xF7, 0xD7, 0x3F, 0xA5, 0xFF, 0x9A, 0x4C, + 0x86, 0xDF, 0x07, 0xB0, 0x80, 0x05, 0x5D, 0x21, + 0x12, 0xFE, 0xC4, 0x55, 0xFF, 0x10, 0xC8, 0x24, + 0x7F, 0xB3, 0xB1, 0xB2, 0x2D, 0x8F, 0xC7, 0x68, + 0xE2, 0x0F, 0xE1, 0xB4, 0x07, 0xF2, 0xA2, 0x81, + 0x7E, 0xD3, 0xDA, 0x3A, 0x1A, 0xFF, 0xF5, 0x2E, + 0xAE, 0xB1, 0x66, 0x6B, 0x57, 0xE2, 0xE6, 0xE1, + 0xE5, 0xC4, 0x84, 0x18, 0xB8, 0xDC, 0x78, 0x45, + 0xB6, 0x2B, 0xD9, 0x61, 0xEB, 0xCA, 0x30, 0x81, + 0x69, 0x6B, 0xD7, 0xD7, 0xB4, 0x94, 0xD4, 0x68, + 0xB0, 0xF5, 0xA0, 0xA4, 0xF0, 0xD7, 0x94, 0xCE, + 0x09, 0x9C, 0x8B, 0x7C, 0x6D, 0x4F, 0x91, 0x0F, + 0x60, 0x87, 0xA7, 0x4D, 0x3A, 0x05, 0x8A, 0x30, + 0x2E, 0x1B, 0x6F, 0xF2, 0xF4, 0xE9, 0x14, 0xF4, + 0xC2, 0x0B, 0x9D, 0x70, 0x4E, 0xB1, 0xE8, 0xAC, + 0xE4, 0x7E, 0x79, 0x52, 0x85, 0x24, 0x53, 0xFF, + 0x21, 0x68, 0x9A, 0x7A, 0xA2, 0x6A, 0x4E, 0x3D, + 0x57, 0xC8, 0xAB, 0xB8, 0xF3, 0xA0, 0xB4, 0xD6, + 0x33, 0x5E, 0x6A, 0x26, 0xE2, 0x5A, 0xE7, 0x01, + 0x7C, 0x7D, 0x1E, 0x76, 0x05, 0xB0, 0x49, 0xD9, + 0x63, 0x95, 0x40, 0xF2, 0x48, 0xD2, 0xC4, 0x78, + 0x77, 0xA2, 0x29, 0xB0, 0x63, 0x46, 0xE6, 0x2F, + 0x09, 0x5B, 0xB5, 0xE1, 0xE2, 0x10, 0xD2, 0x43, + 0x82, 0x8F, 0x92, 0x51, 0xEA, 0x4E, 0x01, 0x66, + 0xB7, 0xED, 0x43, 0x84, 0x20, 0x5A, 0xE1, 0xD0, + 0x18, 0xBF, 0xBB, 0xC7, 0x76, 0x76, 0xCC, 0xA2, + 0xDC, 0xDC, 0x81, 0xF3, 0xEC, 0xE2, 0x27, 0x5E, + 0x1E, 0x76, 0x0B, 0xE7, 0x59, 0xBA, 0x13, 0xE8, + 0x9B, 0x4D, 0x2D, 0x4A, 0xD7, 0x7F, 0x13, 0x7A, + 0x0B, 0x3E, 0xBB, 0xE3, 0x7A, 0xF9, 0xB3, 0xBE, + 0x65, 0x0A, 0x45, 0xD2, 0xA7, 0x38, 0x0E, 0xFE, + 0x69, 0xF3, 0x85, 0x54, 0x16, 0x08, 0xE7, 0x33, + 0x9A, 0x35, 0x8B, 0x2E, 0xE8, 0x39, 0x9C, 0xE9, + 0x4D, 0xE8, 0x54, 0x6B, 0xF5, 0x00, 0x31, 0xEB, + 0x15, 0x84, 0x22, 0xE8, 0x0C, 0x63, 0xF3, 0x01, + 0x32, 0x92, 0x26, 0x80, 0xAA, 0x9D, 0xE8, 0x16, + 0x32, 0x43, 0x72, 0x6B, 0xB7, 0x51, 0xFF, 0xDD, + 0x01, 0x9A, 0x64, 0xFF, 0x0D, 0xF9, 0x5D, 0xD4, + 0xA7, 0x5B, 0x19, 0xDF, 0x8A, 0x23, 0xC3, 0xBC, + 0x11, 0x99, 0xA9, 0x4D, 0xC1, 0x84, 0x43, 0x65, + 0x8D, 0x72, 0x9E, 0xF3, 0x1E, 0x0B, 0x51, 0xB0, + 0x3D, 0xDF, 0x0B, 0x88, 0x45, 0xB4, 0xFA, 0x44, + 0xE1, 0x53, 0x14, 0xEC, 0xDE, 0x6E, 0xA5, 0x09, + 0x11, 0xA1, 0xEF, 0x09, 0x39, 0x28, 0x12, 0x7E, + 0x75, 0x1D, 0xAA, 0x10, 0xC2, 0x7B, 0xB5, 0xD6, + 0xC1, 0x61, 0x93, 0x84, 0xDA, 0x83, 0xD8, 0x7D, + 0x84, 0xE2, 0x12, 0xAD, 0xAD, 0x5F, 0x0C, 0x63, + 0xD4, 0xD4, 0xA0, 0x4E, 0x0E, 0x03, 0x0D, 0x20, + 0x16, 0x4C, 0x62, 0xD6, 0x42, 0x62, 0xC4, 0x7A, + 0x61, 0x7F, 0xF4, 0xB3, 0xCD, 0xF9, 0x47, 0x6A, + 0x95, 0xA4, 0x33, 0xB8, 0xC3, 0x23, 0x05, 0x18, + 0x46, 0x1E, 0xEA, 0x5F, 0xAD, 0x4A, 0x34, 0x7A, + 0x33, 0x69, 0xF0, 0x26, 0x5C, 0xD0, 0x25, 0x5E, + 0x20, 0x3F, 0x39, 0x13, 0xFF, 0xCA, 0x5B, 0x1D, + 0x88, 0x85, 0x27, 0xE9, 0x94, 0xE1, 0x63, 0x32, + 0x79, 0x99, 0xD7, 0xDC, 0x1A, 0xE0, 0xB4, 0x05, + 0x49, 0x0E, 0x09, 0x88, 0x03, 0xC0, 0xAC, 0x75, + 0xC9, 0x35, 0x7A, 0xEC, 0xB4, 0x14, 0x09, 0x55, + 0x9D, 0xEE, 0x4C, 0xCD, 0xB3, 0x48, 0x55, 0x2D, + 0x5C, 0x92, 0x31, 0x5D, 0xE4, 0x11, 0xA1, 0x3C, + 0x48, 0xAA, 0x44, 0x28, 0x98, 0x98, 0x66, 0xE9, + 0xF7, 0xC3, 0xE4, 0x12, 0x61, 0x19, 0xD8, 0x1F, + 0x37, 0x6D, 0x57, 0xA7, 0x5F, 0xA3, 0xD0, 0x9F, + 0x3D, 0xD3, 0xC3, 0x8B, 0x5D, 0x93, 0xA1, 0xBA, + 0x51, 0xBB, 0x6A, 0x73, 0x86, 0x0D, 0xC8, 0xF1, + 0x39, 0xC1, 0xD8, 0x0F, 0x51, 0x94, 0xFA, 0xA4, + 0x1E, 0x95, 0x46, 0xED, 0x62, 0xEA, 0x23, 0x35, + 0x92, 0xA0, 0xDC, 0xA5, 0x65, 0x60, 0xD3, 0x85, + 0xC7, 0x30, 0xB4, 0x88, 0x5D, 0xC6, 0x50, 0x35, + 0x35, 0x95, 0x8C, 0x17, 0x95, 0xDC, 0xC2, 0x7E, + 0xA4, 0xD9, 0x72, 0x07, 0xCA, 0x70, 0xBF, 0xF4, + 0x2E, 0x0C, 0x54, 0x43, 0xE3, 0xE3, 0x77, 0xA2, + 0x90, 0xFC, 0x9D, 0x93, 0xF8, 0xB5, 0xA8, 0x17, + 0xFD, 0x27, 0xF6, 0x7E, 0x63, 0x5D, 0x1E, 0x0C, + 0xD1, 0x04, 0x47, 0x7B, 0x1C, 0x98, 0x87, 0x81, + 0x85, 0x44, 0xCE, 0x40, 0x3F, 0xD9, 0xFC, 0x5E, + 0x92, 0x60, 0xC2, 0x5C, 0xC3, 0x3F, 0xF4, 0xCA, + 0x01, 0x51, 0x46, 0xDF, 0x96, 0x12, 0x81, 0x0D, + 0x52, 0x4C, 0xBA, 0xD4, 0x57, 0xA0, 0x15, 0xDB, + 0x98, 0xBB, 0x39, 0x30, 0xB3, 0xB9, 0x4D, 0xF8, + 0x0F, 0xD3, 0x6B, 0xAC, 0x04, 0x9D, 0xD9, 0xD9, + 0x7F, 0xA8, 0xE0, 0x9D, 0x71, 0xB1, 0xE7, 0x87, + 0x3C, 0x53, 0x32, 0x8D, 0xB3, 0x15, 0xEB, 0x38, + 0x10, 0xB4, 0x83, 0x9F, 0x8F, 0xC8, 0xB1, 0x41, + 0xCB, 0xA1, 0x87, 0xBB, 0x88, 0xCA, 0x2B, 0x81, + 0x7C, 0xC3, 0x8F, 0x68, 0xC7, 0x1B, 0x98, 0x9E, + 0x59, 0xF2, 0x9B, 0xC7, 0x8D, 0x07, 0x49, 0xFA, + 0x43, 0x73, 0x3F, 0x7A, 0x62, 0xF6, 0x89, 0x8A, + 0xA4, 0xDE, 0x16, 0xC3, 0x67, 0xA9, 0xFE, 0x1D, + 0x3B, 0x00, 0x9B, 0xA4, 0x82, 0x1D, 0xBE, 0x0A, + 0xD4, 0xE5, 0x47, 0x7E, 0xCB, 0x3A, 0x91, 0x35, + 0xA4, 0x3C, 0xF0, 0x12, 0x79, 0x72, 0x76, 0xC3, + 0xA8, 0x27, 0x95, 0x81, 0x8B, 0xF8, 0x4A, 0xD4, + 0x51, 0xB4, 0xD8, 0x1A, 0x41, 0x6F, 0x77, 0x75, + 0xEF, 0x6D, 0xDB, 0x70, 0x07, 0xF3, 0xC8, 0x70, + 0xCD, 0x9C, 0x96, 0x1C, 0xE1, 0x50, 0xEE, 0xE3, + 0x5D, 0x3A, 0x79, 0xE6, 0xD4, 0xE7, 0x32, 0x85, + 0x00, 0x3A, 0xDF, 0xD6, 0x4D, 0x4A, 0x62, 0x7C, + 0x1E, 0xEE, 0xD1, 0x44, 0xF0, 0xBC, 0x7E, 0x60, + 0x76, 0x3C, 0xC6, 0x31, 0x40, 0x08, 0xFC, 0x37, + 0xFF, 0x6C, 0x23, 0x42, 0x92, 0xE7, 0x4C, 0xD7, + 0x0F, 0x53, 0x37, 0x58, 0x2E, 0x93, 0xF2, 0x93, + 0x92, 0x65, 0x69, 0xF1, 0x30, 0x8C, 0xEF, 0x1D, + 0x71, 0x3C, 0x81, 0x32, 0x65, 0x87, 0xB6, 0x63, + 0xC2, 0x8E, 0x05, 0x38, 0xF7, 0xE2, 0xDA, 0x21, + 0x26, 0x1D, 0xD4, 0x8E, 0xF5, 0x4D, 0x63, 0x47, + 0xAE, 0x10, 0x16, 0x42, 0x64, 0xC1, 0xBD, 0xEC, + 0xCB, 0xE4, 0x43, 0xEC, 0xB3, 0x7F, 0x15, 0x97, + 0x10, 0xD4, 0x1A, 0x0C, 0x98, 0x2E, 0x7D, 0x05, + 0x10, 0x33, 0x38, 0xDE, 0xA1, 0x40, 0x27, 0xC8, + 0xC0, 0xE7, 0xD8, 0x12, 0x07, 0xC7, 0xD5, 0x05, + 0x0A, 0xBE, 0x69, 0x89, 0x9F, 0x9B, 0xEC, 0xB2, + 0x7B, 0x44, 0x81, 0x5D, 0xE9, 0x92, 0xFD, 0x94, + 0x86, 0x24, 0x14, 0xC8, 0xCF, 0xA6, 0xB3, 0xA6, + 0xAA, 0xE4, 0x17, 0xC0, 0x08, 0x05, 0x68, 0xC7, + 0x7D, 0xC0, 0x42, 0x58, 0xC4, 0xAF, 0x02, 0xFB, + 0xF0, 0x1F, 0xF6, 0x9F, 0xBC, 0xE9, 0x5B, 0xBA, + 0xD6, 0x75, 0xB4, 0x15, 0x53, 0x88, 0x30, 0xD8, + 0xDA, 0x39, 0xE3, 0x9B, 0x12, 0x9E, 0x91, 0x06, + 0x30, 0xD2, 0x35, 0xF8, 0xCC, 0x75, 0xBA, 0x0A, + 0x66, 0x25, 0x35, 0x2B, 0xC9, 0x27, 0x91, 0x9F, + 0x65, 0x39, 0xFA, 0x21, 0x74, 0xC3, 0x85, 0xC7, + 0xE7, 0x23, 0x80, 0x04, 0x2C, 0x84, 0x90, 0x52, + 0x6D, 0x7E, 0x4B, 0x67, 0xE2, 0x49, 0xCE, 0x02, + 0x44, 0xC5, 0x71, 0xBD, 0x50, 0x58, 0x72, 0x21, + 0xC9, 0x1B, 0x03, 0x42, 0xA8, 0xEC, 0xF5, 0x00, + 0x2F, 0x5F, 0x49, 0x4A, 0x91, 0x9F, 0x24, 0x5E, + 0xBE, 0xC8, 0x70, 0xEE, 0xD5, 0xFA, 0xA2, 0x32, + 0x84, 0x89, 0xFE, 0x9A, 0x34, 0xA6, 0x50, 0x35, + 0x2E, 0xF8, 0x47, 0xD5, 0xDC, 0xDB, 0x36, 0x97, + 0xE4, 0x2B, 0xB9, 0xCA, 0xCB, 0x8B, 0x46, 0xA9, + 0x67, 0x5A, 0x68, 0xD8, 0x97, 0x13, 0x68, 0x20, + 0xEC, 0x6A, 0x56, 0x50, 0x6A, 0x87, 0xFB, 0xF5, + 0xD8, 0x5D, 0x76, 0x6B, 0x57, 0xE0, 0x2B, 0x5A, + 0xD6, 0xF1, 0x48, 0x92, 0x9F, 0xC4, 0x17, 0xE4, + 0x32, 0xE5, 0xB4, 0x08, 0x20, 0x8B, 0x63, 0x38, + 0xC6, 0x83, 0x6B, 0x9D, 0x2E, 0x20, 0x60, 0x85, + 0x2C, 0x3E, 0x15, 0xFB, 0x6C, 0x5D, 0x0A, 0xB0, + 0x8B, 0xC6, 0xAE, 0xE3, 0x36, 0xCF, 0xF5, 0x94, + 0xB6, 0x42, 0x24, 0x3A, 0x7E, 0xAA, 0x38, 0x27, + 0x20, 0xAE, 0x98, 0x13, 0x36, 0x3E, 0x32, 0x43, + 0x63, 0x83, 0x96, 0x8C, 0x5F, 0xF1, 0xD2, 0x81, + 0x4C, 0x57, 0xDF, 0xC7, 0x7B, 0xBC, 0x18, 0x0D, + 0xE1, 0xE3, 0x92, 0x9F, 0x8B, 0x3D, 0x80, 0x05, + 0x76, 0xAA, 0x89, 0x48, 0x71, 0xA4, 0xBB, 0x68, + 0x84, 0x6E, 0xE1, 0x44, 0x39, 0x74, 0xF6, 0xBD, + 0x3E, 0x48, 0x07, 0x15, 0xCD, 0xBD, 0xCF, 0x47, + 0xBF, 0x3A, 0x57, 0x57, 0x6C, 0x0C, 0x3C, 0xC0, + 0xF2, 0xB1, 0x02, 0xC1, 0xA5, 0x14, 0x21, 0xDC, + 0x6E, 0xC5, 0x16, 0xC5, 0xBF, 0xD2, 0x6E, 0x4F, + 0x97, 0x4E, 0x76, 0x87, 0x3A, 0x66, 0xF9, 0xAA, + 0x64, 0x77, 0x19, 0x36, 0xA0, 0x11, 0x05, 0x5D, + 0xD4, 0x2B, 0x1D, 0x83, 0x45, 0xFD, 0xB3, 0xF3, + 0xCB, 0x68, 0x80, 0x02, 0xD4, 0xF9, 0x55, 0x64, + 0x55, 0xC1, 0xDD, 0x31, 0xF8, 0x47, 0x5B, 0x07, + 0xD5, 0x0B, 0xBC, 0x00, 0x13, 0xC6, 0x34, 0x55, + 0x08, 0xD7, 0xD8, 0x71, 0xF9, 0x5A, 0x51, 0xD6, + 0x8C, 0xE1, 0x66, 0x27, 0x99, 0x67, 0x5C, 0x95, + 0x77, 0x14, 0x17, 0x28, 0xD8, 0xD0, 0x22, 0xDD, + 0xDC, 0x3E, 0x5C, 0x69, 0xCE, 0x39, 0x9D, 0x2D, + 0xE2, 0x19, 0x1E, 0x2B, 0xE8, 0x72, 0x22, 0xCF, + 0x13, 0x6F, 0x52, 0xE9, 0x36, 0xE1, 0x51, 0x16, + 0xAD, 0x2E, 0xCF, 0x19, 0x3A, 0x5A, 0xB0, 0xCD, + 0xC9, 0xD1, 0x69, 0x3A, 0x4E, 0x1D, 0xEA, 0x24, + 0xFB, 0x7B, 0x10, 0x84, 0x33, 0x7A, 0xED, 0x81, + 0x76, 0x74, 0x4E, 0x72, 0xB1, 0xEC, 0xE1, 0x3D, + 0x32, 0x35, 0xDC, 0x0A, 0x28, 0x17, 0xCF, 0x42, + 0x92, 0x81, 0x17, 0xF7, 0x2A, 0x46, 0x84, 0xF7, + 0xC4, 0xB4, 0xB1, 0x63, 0xAE, 0xF0, 0x13, 0xFE, + 0x00, 0xA9, 0x93, 0xC7, 0x72, 0x95, 0x8D, 0xE3, + 0x71, 0x4C, 0xAE, 0x74, 0x17, 0xB4, 0x6A, 0x4C, + 0xDF, 0x8E, 0x1E, 0x05, 0x9D, 0xF4, 0x59, 0x56, + 0xCB, 0xCF, 0x02, 0xE6, 0x4A, 0xC0, 0xE6, 0xC3, + 0x6B, 0xA6, 0x6B, 0xC7, 0x92, 0xA1, 0xAE, 0x3C, + 0xFD, 0x57, 0x93, 0x37, 0x8E, 0x9C, 0x49, 0xA1, + 0x8C, 0x81, 0xF7, 0x7F, 0x42, 0xB8, 0x44, 0xE1, + 0x95, 0xB0, 0x9D, 0x16, 0xA8, 0x10, 0x9D, 0xA6, + 0x09, 0x1B, 0x56, 0x5C, 0x64, 0x82, 0x54, 0x3E, + 0xD1, 0xCD, 0xF1, 0x35, 0x4C, 0xF7, 0xBD, 0xD2, + 0xC1, 0x97, 0xAD, 0xEE, 0xDD, 0xA9, 0xAD, 0x8B, + 0x79, 0x08, 0xDD, 0x24, 0x58, 0x2D, 0x28, 0x09, + 0xB2, 0xF0, 0x52, 0x25, 0xF1, 0xC4, 0x1E, 0x7C, + 0xE2, 0x99, 0x6C, 0xB5, 0x14, 0xE2, 0x67, 0x93, + 0x8C, 0x84, 0x56, 0x0E, 0x85, 0x84, 0xBA, 0x52, + 0x70, 0xB3, 0xBE, 0x2F, 0x19, 0x4F, 0xFC, 0xD9, + 0xB3, 0xF3, 0x02, 0xD5, 0x7F, 0x93, 0xF1, 0xBB, + 0xA2, 0x53, 0x93, 0x36, 0x3E, 0x6A, 0x44, 0xE3, + 0x5A, 0x2B, 0x32, 0x1D, 0x38, 0x65, 0x0A, 0x3E, + 0xED, 0x40, 0x0E, 0xFC, 0x2C, 0xCF, 0x95, 0xAA, + 0x36, 0x3E, 0x70, 0xF9, 0x45, 0xB9, 0x99, 0xED, + 0x9D, 0x5F, 0x68, 0x9F, 0x53, 0xA6, 0xDA, 0x4C, + 0xB4, 0x95, 0x6A, 0x9E, 0x64, 0xE3, 0x46, 0x24, + 0x59, 0xDD, 0x80, 0x9A, 0xE4, 0x2C, 0x2A, 0x8B, + 0xAF, 0x36, 0x10, 0x82, 0xDF, 0x7D, 0xD8, 0xAF, + 0xEE, 0xBB, 0xE6, 0x92, 0xFC, 0x2C, 0x98, 0xEF, + 0x67, 0x3F, 0xCF, 0xD0, 0xED, 0xC4, 0x51, 0x84, + 0xB7, 0x8F, 0x46, 0x73, 0x9E, 0x56, 0xE4, 0x8F, + 0x1D, 0x93, 0x87, 0x83, 0xFF, 0xC9, 0x14, 0x4F, + 0xEC, 0x5A, 0xAD, 0xE4, 0x0A, 0x76, 0x61, 0xF0, + 0x17, 0x37, 0xA0, 0xF1, 0x36, 0x3A, 0x72, 0x2E, + 0x6A, 0xF8, 0x4D, 0xD4, 0x9C, 0xA8, 0x09, 0x8C, + 0x6E, 0x26, 0xFD, 0x0D, 0x2D, 0xAF, 0xC0, 0x17, + 0x8E, 0x93, 0xC4, 0xBE, 0x1C, 0xBA, 0x7E, 0xC5, + 0x87, 0x73, 0x17, 0x70, 0x8D, 0xE6, 0xF1, 0xF6, + 0xBB, 0x1E, 0x68, 0xE8, 0x81, 0xF5, 0x99, 0xC0, + 0x35, 0x4B, 0x2B, 0xE0, 0x90, 0xD4, 0x55, 0xC0, + 0xBA, 0x67, 0xA7, 0xFA, 0x08, 0x63, 0xCD, 0xBC, + 0x98, 0xDB, 0x05, 0x56, 0x17, 0xD7, 0x90, 0xB7, + 0x22, 0x5A, 0x42, 0x5A, 0x21, 0x9D, 0xA4, 0xAF, + 0x9A, 0x20, 0x16, 0x30, 0x22, 0xF9, 0xF9, 0xBB, + 0x75, 0x7F, 0x62, 0xBB, 0xF5, 0xEB, 0x47, 0xEA, + 0x16, 0x88, 0x38, 0xEE, 0xE9, 0x1C, 0xF9, 0x0D, + 0x81, 0x2C, 0xE6, 0x1A, 0x51, 0x4C, 0x08, 0xBE, + 0xA2, 0xDF, 0x55, 0xA4, 0x6A, 0xD4, 0xF1, 0x1A, + 0x46, 0xF6, 0xE8, 0xC5, 0x61, 0xC8, 0xB7, 0xF7, + 0xAF, 0xA6, 0xF2, 0x56, 0xC3, 0xAF, 0x3F, 0x44, + 0x7D, 0xA7, 0xC7, 0xC3, 0x90, 0x6D, 0x87, 0x64, + 0x4F, 0xE9, 0x62, 0xE2, 0x87, 0x2D, 0xE5, 0x43, + 0x85, 0x36, 0x34, 0x37, 0x36, 0x20, 0x21, 0x0F, + 0xB6, 0x3E, 0xAC, 0x97, 0x4E, 0xF5, 0x85, 0x34, + 0x3E, 0x4C, 0xBE, 0xFA, 0xA9, 0xBB, 0xE2, 0x13, + 0x36, 0x52, 0x92, 0x51, 0x65, 0x18, 0xCA, 0xEA, + 0x83, 0x90, 0x7A, 0x04, 0xE6, 0xA7, 0xE2, 0xA7, + 0xD1, 0xC5, 0xCD, 0xF5, 0x55, 0xB4, 0x42, 0x1E, + 0x9B, 0x23, 0xC3, 0x01, 0x40, 0xFD, 0x24, 0xC0, + 0x07, 0x3B, 0xCE, 0x39, 0x9F, 0xAD, 0xD2, 0xE5, + 0x11, 0x77, 0xD0, 0x34, 0x96, 0x31, 0xBB, 0x8B, + 0xBD, 0xF7, 0xF9, 0x45, 0x17, 0xBB, 0x2F, 0x6D, + 0x8D, 0xF3, 0xC0, 0x04, 0xE1, 0xE1, 0x7F, 0x3F, + 0x09, 0xF0, 0xF3, 0x64, 0x48, 0xF8, 0xC6, 0x8A, + 0x97, 0x6E, 0x1E, 0x00, 0xB6, 0xC2, 0x9D, 0x10, + 0x41, 0xBC, 0x40, 0x5F, 0x2A, 0xFB, 0xC6, 0x4B, + 0x5D, 0x2D, 0xE8, 0x57, 0xF5, 0x08, 0x2B, 0xD3, + 0x38, 0x5A, 0x49, 0x6E, 0xF7, 0x8A, 0xFB, 0x49, + 0x27, 0xE2, 0x17, 0x68, 0x11, 0x0F, 0x5D, 0x6D, + 0xC3, 0xC5, 0x5C, 0x37, 0xE5, 0xBF, 0xF2, 0x8F, + 0xCF, 0xCA, 0xF9, 0x49, 0xED, 0x94, 0x2B, 0x53, + 0x11, 0x8A, 0xD7, 0x7E, 0x16, 0x0C, 0x0D, 0x4F, + 0xE4, 0x8B, 0x76, 0x98, 0xFD, 0x20, 0xEB, 0x6A, + 0x3E, 0x44, 0x0E, 0x79, 0x7C, 0x9F, 0xE1, 0xC1, + 0xDC, 0xE1, 0x54, 0x83, 0x7C, 0xDB, 0x0E, 0xE1, + 0x88, 0xB4, 0x30, 0xB0, 0x58, 0x72, 0x80, 0x05, + 0xA8, 0x19, 0x7B, 0x91, 0xFD, 0x94, 0x04, 0x66, + 0xBB, 0xC9, 0x9A, 0x7D, 0xB7, 0x91, 0x2D, 0xBC, + 0xE7, 0x48, 0xCF, 0x01, 0xE3, 0xCD, 0x2F, 0x2D, + 0x47, 0xDC, 0x66, 0x7C, 0xF9, 0x4B, 0x75, 0x53, + 0xBA, 0x04, 0x55, 0x7D, 0x93, 0xB8, 0xA7, 0xA5, + 0x95, 0xE8, 0x85, 0x97, 0x59, 0x70, 0xDD, 0xB0, + 0x1D, 0x50, 0x38, 0x06, 0xB8, 0xFA, 0xFF, 0xA5, + 0x83, 0x6F, 0xF9, 0x96, 0xF6, 0x7C, 0x4D, 0x88, + 0x7E, 0x0C, 0x1D, 0xC5, 0x5E, 0x71, 0x6B, 0x2E, + 0x27, 0x39, 0x19, 0xFA, 0xD0, 0x2F, 0xC5, 0x3F, + 0x1F, 0xDF, 0xE3, 0x64, 0xD5, 0x0E, 0xC3, 0xBD, + 0x1D, 0xE7, 0x0B, 0xF7, 0x69, 0x25, 0x2F, 0x75, + 0xB3, 0xF8, 0xD8, 0xD1, 0x59, 0xDF, 0x7B, 0x77, + 0x81, 0x76, 0x87, 0xA7, 0xF0, 0x7C, 0xDF, 0xEE, + 0xFC, 0xE0, 0x5B, 0x8E, 0xAF, 0x65, 0x80, 0x89, + 0xBF, 0x28, 0x7C, 0x2A, 0xDF, 0x7C, 0xD3, 0xE0, + 0x83, 0x20, 0xD5, 0x78, 0x82, 0xB8, 0x24, 0x4C, + 0x58, 0x40, 0xAB, 0xE0, 0xDB, 0x11, 0x5C, 0x65, + 0x03, 0xF2, 0x0F, 0xAF, 0x80, 0x9B, 0x40, 0x1C, + 0x95, 0x94, 0xE3, 0xE2, 0x83, 0xF8, 0xF5, 0x04, + 0xC9, 0x5A, 0xE9, 0x88, 0x96, 0x90, 0x8D, 0xE0, + 0x57, 0x19, 0x8E, 0xB5, 0x07, 0xA3, 0xBE, 0xBE, + 0x92, 0xB7, 0x5B, 0x87, 0x9F, 0x77, 0x36, 0x2C, + 0x2C, 0x39, 0xDE, 0x10, 0x8D, 0x88, 0x88, 0x41, + 0xA9, 0xB9, 0x4E, 0xC9, 0x6E, 0x54, 0xDF, 0x26, + 0xFC, 0xDB, 0xF2, 0xED, 0x2B, 0x89, 0x40, 0xE0, + 0x0C, 0x9F, 0xE5, 0xD0, 0x09, 0x4E, 0x26, 0xA8, + 0x46, 0x23, 0xC6, 0x73, 0x52, 0x9D, 0xB1, 0xE4, + 0x00, 0xE4, 0x17, 0x6C, 0x43, 0x23, 0xAD, 0x2B, + 0xF2, 0xF1, 0xD6, 0xE3, 0x4F, 0x7A, 0xE8, 0xCA, + 0x93, 0xFB, 0x8D, 0x01, 0xE2, 0xF7, 0x1C, 0x3E, + 0xB5, 0x36, 0xD8, 0x90, 0xEB, 0x15, 0xD6, 0x3B, + 0x47, 0x1B, 0xD1, 0xDE, 0xC3, 0xBC, 0xD0, 0x1D, + 0x8A, 0x06, 0xD4, 0x4A, 0xB6, 0x6D, 0x0B, 0xEC, + 0x54, 0xA7, 0xF4, 0xCF, 0xBA, 0x87, 0xEE, 0xB3, + 0x49, 0x3F, 0x72, 0x14, 0x88, 0xA1, 0xB8, 0x99, + 0xCE, 0x71, 0xF6, 0xD8, 0x44, 0x94, 0x08, 0x12, + 0xD9, 0xC1, 0xB3, 0x3B, 0x24, 0xB3, 0x67, 0xB2, + 0x84, 0x46, 0xC1, 0x77, 0x44, 0x9B, 0xF1, 0x3B, + 0x52, 0xA2, 0x1E, 0xF7, 0x72, 0xDB, 0x98, 0x3C, + 0xDF, 0xB4, 0xD8, 0x31, 0xC7, 0x8D, 0x50, 0x6F, + 0x9B, 0x81, 0x0B, 0x65, 0xC0, 0xE1, 0xB7, 0x4A, + 0x49, 0x9B, 0x66, 0x4B, 0x24, 0xDE, 0xFB, 0x64, + 0xAA, 0xEB, 0xCE, 0xF1, 0x46, 0x4E, 0x58, 0x82, + 0x70, 0x9D, 0xF2, 0x09, 0x56, 0x66, 0x61, 0x01, + 0x02, 0xE0, 0x12, 0xD8, 0xDE, 0x2D, 0x4B, 0xAE, + 0x93, 0xBD, 0x6E, 0x19, 0xA5, 0x4B, 0x0D, 0xD9, + 0x02, 0x2F, 0xD3, 0x6E, 0xF1, 0xB2, 0x6E, 0x77, + 0x55, 0xA4, 0xBD, 0x75, 0x88, 0x68, 0x0C, 0x51, + 0xB9, 0x48, 0x50, 0x9C, 0x94, 0x64, 0x79, 0xFA, + 0xD3, 0xC4, 0x54, 0x42, 0x04, 0x74, 0xC3, 0x08, + 0x10, 0x90, 0xE9, 0x83, 0x13, 0x4F, 0x4D, 0xE4, + 0x88, 0x43, 0x9B, 0x56, 0x8D, 0xB7, 0x64, 0xB2, + 0x70, 0xF8, 0xC1, 0x4B, 0x98, 0xF9, 0xFC, 0x83, + 0x04, 0xA3, 0x46, 0xE4, 0xC2, 0x93, 0xD3, 0x0A, + 0x11, 0xD1, 0x93, 0xF3, 0x09, 0x2D, 0x01, 0xD7, + 0xA3, 0x3A, 0x85, 0xD4, 0xD7, 0xD8, 0xA2, 0x32, + 0xC3, 0xD9, 0xA2, 0x50, 0xDD, 0xE5, 0xC1, 0x41, + 0x55, 0x6E, 0xC6, 0x1C, 0x67, 0x28, 0xA2, 0xE2, + 0x99, 0x20, 0x9E, 0x1C, 0x9A, 0x88, 0x29, 0x46, + 0x46, 0x78, 0x6D, 0xEC, 0x48, 0x87, 0xF9, 0x5B, + 0xA7, 0xAC, 0xE7, 0x94, 0x0F, 0xFC, 0x69, 0x5D, + 0xC8, 0x40, 0xA3, 0x5C, 0xB4, 0x5B, 0x59, 0x61, + 0x83, 0x65, 0xBC, 0xB9, 0x7A, 0xC7, 0xFF, 0xED, + 0xA0, 0xA4, 0x3C, 0xC0, 0x15, 0x27, 0x30, 0x46, + 0xAD, 0x34, 0x5C, 0x7D, 0x94, 0x5C, 0x4E, 0xEB, + 0x1E, 0x9D, 0x51, 0xAF, 0xF5, 0xA3, 0xA6, 0x0C, + 0x08, 0xDA, 0xDB, 0x7E, 0x43, 0x72, 0xDF, 0xAF, + 0x39, 0x1D, 0x29, 0x2E, 0x15, 0xC9, 0xBE, 0x1E, + 0x07, 0x1D, 0x11, 0xD3, 0xAC, 0x79, 0xE5, 0xFF, + 0x19, 0xB2, 0xFA, 0xD6, 0x44, 0x69, 0xB6, 0xBC, + 0x39, 0x4B, 0x8B, 0x3D, 0x81, 0x22, 0xB5, 0x37, + 0x3F, 0x7F, 0xD6, 0x29, 0x13, 0xA2, 0x01, 0x3A, + 0xB0, 0xC6, 0xE0, 0x57, 0x33, 0x2B, 0x70, 0xFF, + 0xB2, 0x2C, 0xD1, 0xC9, 0xCB, 0x04, 0xE3, 0x8C, + 0x04, 0x07, 0x81, 0xF6, 0xEB, 0x16, 0x1E, 0xDA, + 0xA1, 0x0A, 0xB8, 0x7E, 0xE8, 0xAB, 0x48, 0xF7, + 0x55, 0xFA, 0xED, 0xD1, 0xC1, 0x17, 0x7A, 0x22, + 0x42, 0x6C, 0x8F, 0x76, 0x65, 0x66, 0x21, 0xEB, + 0xB5, 0x2B, 0x40, 0x12, 0x37, 0xD3, 0xFC, 0x59, + 0x26, 0x1A, 0x49, 0xF1, 0xB2, 0x29, 0xB7, 0xA3, + 0xBB, 0x5A, 0xB3, 0x9C, 0x6B, 0x5B, 0x2B, 0x84, + 0xA8, 0x25, 0xF9, 0x95, 0x7A, 0xDD, 0xAA, 0x6F, + 0x04, 0xC8, 0x02, 0xA4, 0x57, 0xA3, 0x6C, 0xEC, + 0xB5, 0x68, 0x5B, 0xBF, 0x4A, 0x23, 0xB0, 0xCC, + 0x91, 0x21, 0xDA, 0x32, 0x8F, 0x24, 0x93, 0xF3, + 0x4B, 0xC3, 0xCA, 0xAF, 0xB0, 0xD7, 0x59, 0x5B, + 0x70, 0x79, 0x48, 0x84, 0x51, 0xC1, 0x0F, 0xF7, + 0xAC, 0x37, 0x8F, 0xA6, 0x8E, 0x0E, 0x71, 0xE3, + 0xAB, 0xA5, 0x80, 0x18, 0x07, 0xE7, 0x8A, 0x95, + 0x2E, 0x2E, 0xC5, 0xD0, 0xAD, 0x11, 0x7D, 0x9B, + 0xA5, 0xBD, 0x6E, 0x74, 0x61, 0x17, 0xFA, 0x89, + 0x9C, 0x53, 0x7A, 0xB8, 0xC1, 0x8E, 0x26, 0xF3, + 0x5B, 0xC3, 0x10, 0x05, 0x72, 0x5A, 0x04, 0x6D, + 0x57, 0xD6, 0x15, 0x48, 0xBA, 0x4C, 0xAF, 0x9C, + 0xCC, 0x8F, 0x2C, 0xC4, 0x02, 0x6C, 0xF8, 0xF5, + 0x02, 0x03, 0x96, 0x5E, 0xF6, 0x04, 0xB7, 0x8E, + 0xF7, 0x1D, 0x31, 0x39, 0x27, 0xAA, 0x30, 0xF3, + 0xEA, 0xED, 0x8C, 0x04, 0xFF, 0x6A, 0x22, 0x94, + 0x0A, 0x50, 0x14, 0x2F, 0x6B, 0xF4, 0xFF, 0x97, + 0xAB, 0x1A, 0xCF, 0x82, 0x02, 0x47, 0x58, 0x55, + 0xF8, 0xE7, 0x87, 0x82, 0xFE, 0x1F, 0x39, 0xCF, + 0xF9, 0x96, 0x11, 0x7D, 0xE4, 0xA9, 0x3F, 0x18, + 0xA0, 0x54, 0xEB, 0xEC, 0x23, 0x10, 0x72, 0x77, + 0x98, 0xF7, 0x9C, 0xFF, 0x19, 0xB0, 0x2E, 0x34, + 0x38, 0xC3, 0x40, 0x53, 0x3B, 0xCA, 0xC6, 0xF8, + 0x2A, 0xCC, 0xC1, 0x0D, 0x31, 0x7B, 0xB9, 0x39, + 0xB1, 0x3C, 0xEC, 0x1D, 0xC4, 0x81, 0x86, 0x80, + 0x09, 0x86, 0xF5, 0x26, 0x0F, 0x83, 0x79, 0xA3, + 0xAF, 0x93, 0x3B, 0x6F, 0x7A, 0xCD, 0xBD, 0x40, + 0x6C, 0xCA, 0x48, 0x54, 0x30, 0xB3, 0x2B, 0xA6, + 0x06, 0x8B, 0x41, 0xF4, 0x5D, 0x7B, 0x78, 0xDF, + 0x6C, 0x36, 0x6F, 0x59, 0x82, 0x67, 0xCA, 0x81, + 0x94, 0x01, 0xBB, 0x97, 0x98, 0x25, 0xF5, 0x1D, + 0x23, 0xAC, 0xAE, 0x04, 0x43, 0x8D, 0xE5, 0xBE, + 0xD5, 0xAF, 0xEC, 0x31, 0x5E, 0x0A, 0xCD, 0xE3, + 0x55, 0x53, 0xCF, 0x2A, 0x87, 0x45, 0x1B, 0x94, + 0xAB, 0x55, 0x4D, 0x7B, 0x32, 0xB2, 0x01, 0xB6, + 0xEC, 0x19, 0xE7, 0xA0, 0xFC, 0x31, 0xD9, 0x10, + 0x8A, 0x0F, 0xDA, 0xC2, 0x9F, 0x46, 0xBF, 0x75, + 0x86, 0x30, 0x29, 0x33, 0xF4, 0x27, 0xE6, 0xC9, + 0xA2, 0x3F, 0x49, 0xF0, 0x4C, 0xFE, 0x30, 0x9D, + 0x03, 0x76, 0x4A, 0x63, 0xF2, 0x34, 0x1E, 0x10, + 0x97, 0xB1, 0x10, 0x40, 0xFC, 0x4F, 0x79, 0x98, + 0x50, 0xC4, 0xA3, 0x93, 0xBE, 0x4D, 0xC7, 0xB9, + 0xBE, 0xB4, 0x6E, 0x8A, 0xF4, 0x00, 0xDE, 0x64, + 0x5A, 0xD4, 0xB9, 0xCB, 0xCC, 0x9B, 0xD9, 0xC3, + 0x98, 0x07, 0x48, 0xB5, 0x15, 0xD5, 0x6C, 0x82, + 0x42, 0x56, 0x6C, 0x9D, 0x03, 0x39, 0xE6, 0x36, + 0x5D, 0xE9, 0xA1, 0x97, 0x3E, 0x88, 0xB0, 0xBA, + 0x9E, 0xF9, 0x60, 0xAC, 0x68, 0x81, 0x97, 0x3D, + 0xFC, 0xF5, 0x42, 0x24, 0x07, 0x0D, 0xE2, 0xC0, + 0xCC, 0x99, 0x2E, 0x2C, 0x69, 0xFA, 0xC8, 0x6F, + 0x24, 0xEB, 0xEA, 0xCB, 0x05, 0x45, 0xF9, 0x2D, + 0x65, 0x50, 0x7C, 0x60, 0xFB, 0x21, 0xBD, 0xB8, + 0x53, 0x34, 0x36, 0x8B, 0x03, 0xB0, 0x31, 0x03, + 0x9F, 0x78, 0xC6, 0x68, 0x07, 0x2E, 0x62, 0xF2, + 0xF7, 0x99, 0xCE, 0xC3, 0x0E, 0x5A, 0xCB, 0xD3, + 0x19, 0x22, 0xBC, 0xA4, 0x45, 0xF5, 0x25, 0xA2, + 0xCE, 0x21, 0xE9, 0x4E, 0x0D, 0x86, 0x98, 0xE8, + 0x7F, 0xAD, 0x18, 0x84, 0x7C, 0x30, 0x60, 0x62, + 0x98, 0x74, 0xA2, 0x39, 0x0F, 0x18, 0x22, 0xAD, + 0xCE, 0xE8, 0x97, 0xBB, 0x51, 0x3D, 0x92, 0x7E, + 0x63, 0x96, 0x22, 0xC1, 0xF3, 0x7E, 0x0A, 0x12, + 0x1F, 0xDD, 0x12, 0x20, 0xD8, 0x89, 0x4C, 0x92, + 0x0C, 0x13, 0x4F, 0xB2, 0x04, 0x90, 0xF0, 0x19, + 0x6A, 0x41, 0x97, 0x4B, 0xA2, 0xC5, 0x0C, 0x13, + 0x1D, 0xEC, 0x04, 0x46, 0xFB, 0xAE, 0xD9, 0x0E, + 0x1E, 0x93, 0x94, 0x66, 0x95, 0x78, 0x05, 0x98, + 0xC0, 0x29, 0x2F, 0x43, 0x50, 0xD7, 0x08, 0xB5, + 0x20, 0x14, 0xFE, 0x5F, 0xAC, 0x9E, 0xA3, 0xFD, + 0xF2, 0x22, 0x85, 0x26, 0x2E, 0x47, 0x60, 0xA9, + 0xE7, 0xA2, 0xB8, 0x7E, 0xB0, 0x47, 0x4D, 0x0E, + 0xD7, 0x15, 0x2E, 0xF6, 0x4B, 0x69, 0x78, 0xE1, + 0xDF, 0xD9, 0xDA, 0x54, 0x0E, 0x45, 0x13, 0xC3, + 0xBC, 0x3F, 0x98, 0x93, 0xD7, 0xBD, 0x3E, 0xA8, + 0xC4, 0x06, 0x80, 0x88, 0x2D, 0x1D, 0x7D, 0x78, + 0x0B, 0x7E, 0x12, 0x20, 0xBD, 0xB3, 0x73, 0xD5, + 0xD7, 0xBF, 0xC7, 0x78, 0x9E, 0xD4, 0x12, 0xF5, + 0x8A, 0x29, 0x87, 0x10, 0x7A, 0xD3, 0x68, 0x3D, + 0xC4, 0xA6, 0x96, 0x6E, 0xBC, 0x8C, 0x41, 0xE2, + 0x3B, 0x36, 0xDB, 0x30, 0xCE, 0x8D, 0x28, 0x5C, + 0x88, 0x68, 0x13, 0xC3, 0xAE, 0xC5, 0xC4, 0x07, + 0xA3, 0x57, 0x26, 0x93, 0x17, 0x98, 0xF9, 0xDA, + 0x55, 0xEF, 0xD3, 0x95, 0xC8, 0x23, 0xA0, 0x2E, + 0x3A, 0x94, 0xE8, 0xF4, 0x16, 0x30, 0x1D, 0x0B, + 0x0F, 0x45, 0x05, 0x98, 0x55, 0x5F, 0xAF, 0xA1, + 0xCF, 0x66, 0x24, 0x9C, 0xCD, 0x75, 0xFD, 0xE2, + 0xEA, 0xED, 0x35, 0x8D, 0x79, 0xE9, 0x01, 0xCA, + 0xD2, 0x32, 0x63, 0x9C, 0xB2, 0x9B, 0x5E, 0x37, + 0xAA, 0xA1, 0x2C, 0x29, 0xFB, 0x1B, 0xA3, 0x62, + 0x2D, 0x43, 0x1E, 0x65, 0xD3, 0x94, 0xAA, 0xD6, + 0x06, 0xA1, 0xE4, 0x82, 0xE4, 0x45, 0x59, 0x90, + 0x60, 0x31, 0x2B, 0x7A, 0x40, 0x2E, 0xD4, 0x2A, + 0x95, 0x96, 0x5F, 0x37, 0x4A, 0xA8, 0xF1, 0xF2, + 0xCA, 0x49, 0x58, 0x09, 0xC7, 0xDC, 0xC3, 0x30, + 0x1A, 0xBF, 0x2F, 0x70, 0x20, 0x54, 0xF3, 0x06, + 0xCD, 0x16, 0x3C, 0xC1, 0x27, 0x23, 0x1D, 0x7C, + 0x2D, 0x39, 0x2E, 0x72, 0xEF, 0xBD, 0xAF, 0x1D, + 0x56, 0xD9, 0x32, 0xFE, 0x86, 0xD0, 0x78, 0x95, + 0x83, 0xA1, 0x95, 0x26, 0xEB, 0x30, 0xD6, 0xF9, + 0x00, 0xDB, 0x50, 0xBC, 0x71, 0xAE, 0x8C, 0xE5, + 0xDD, 0xB1, 0xB8, 0xA1, 0x9D, 0xC7, 0x34, 0x65, + 0x55, 0x16, 0xE8, 0xD1, 0x1D, 0x9C, 0x9B, 0x83, + 0x7B, 0x77, 0x9B, 0x60, 0x0E, 0xD5, 0xBE, 0xF4, + 0xD6, 0xC1, 0xC9, 0xA0, 0x06, 0x27, 0x00, 0xFB, + 0xBE, 0xC9, 0x1A, 0x5A, 0xF6, 0xC7, 0xF5, 0x1D, + 0xC9, 0x95, 0x46, 0x6B, 0x43, 0xDA, 0x1B, 0x51, + 0x55, 0x91, 0xB4, 0x85, 0xF4, 0xBA, 0x3A, 0xC1, + 0x59, 0x41, 0x0F, 0xF0, 0x37, 0x36, 0x3D, 0x11, + 0x8D, 0x72, 0xCA, 0xB0, 0xCE, 0xAD, 0xF5, 0xDC, + 0xB3, 0x9D, 0xD2, 0xB5, 0x39, 0x97, 0xD6, 0x10, + 0x8A, 0x68, 0x30, 0x4B, 0xD2, 0xB5, 0xC6, 0xD9, + 0xCB, 0x32, 0xAB, 0xA2, 0x19, 0xE1, 0xC9, 0x55, + 0x65, 0x3C, 0x0E, 0x5B, 0x32, 0x4D, 0x2A, 0xA6, + 0x8F, 0xEF, 0xA0, 0x72, 0x6F, 0xC7, 0x23, 0x4A, + 0xE2, 0x36, 0x70, 0xA6, 0xE0, 0xB9, 0xA9, 0x4D, + 0xBC, 0x96, 0x95, 0x20, 0xE3, 0x3D, 0xE4, 0x45, + 0x5F, 0x96, 0x9E, 0x54, 0x96, 0x06, 0x84, 0xE6, + 0xDA, 0x10, 0xA7, 0x14, 0x9F, 0x87, 0xE1, 0xDE, + 0xD0, 0x78, 0x8A, 0x2F, 0x32, 0x3A, 0xBD, 0x9E, + 0x72, 0xFD, 0x7D, 0xA9, 0xF2, 0x9E, 0x21, 0x19, + 0xFD, 0x2B, 0x26, 0x2E, 0xB9, 0x65, 0xE0, 0xA0, + 0x51, 0xC0, 0x50, 0x7D, 0xED, 0xFD, 0x64, 0x7F, + 0xC0, 0x12, 0xCA, 0x61, 0xC0, 0x1D, 0xD4, 0x06, + 0x47, 0xDF, 0x79, 0x61, 0x70, 0xE3, 0x99, 0x62, + 0xBE, 0x6B, 0x60, 0xC3, 0x01, 0x5B, 0x98, 0xE4, + 0x9B, 0xF1, 0x8E, 0x91, 0xF3, 0x14, 0x01, 0x01, + 0xDB, 0x4A, 0xC7, 0xFB, 0x56, 0x70, 0xBF, 0x93, + 0xE3, 0xB1, 0x05, 0x02, 0x9E, 0x77, 0x8A, 0xBA, + 0xF8, 0x72, 0x3C, 0x0C, 0x6E, 0xC8, 0x9B, 0x7A, + 0x90, 0x0D, 0x98, 0xF8, 0x84, 0xC0, 0x41, 0x54, + 0x35, 0x00, 0x7D, 0xE9, 0x7D, 0x40, 0xC8, 0x66, + 0x4F, 0x7C, 0xA1, 0xBE, 0x2C, 0xD0, 0x08, 0x12, + 0xFB, 0x3C, 0x62, 0xB9, 0x6C, 0xA0, 0x5E, 0xCE, + 0x70, 0xBE, 0xE4, 0x6B, 0x05, 0xBD, 0x16, 0x76, + 0x1B, 0x16, 0xCD, 0x38, 0x15, 0xB0, 0x16, 0x2D, + 0x18, 0x44, 0x40, 0xF2, 0x43, 0xFE, 0x72, 0x34, + 0xA9, 0xAA, 0x28, 0x23, 0xAA, 0xA5, 0xEC, 0xB2, + 0x1A, 0xD6, 0x83, 0xAD, 0x86, 0x0A, 0x58, 0x13, + 0x72, 0x0F, 0x16, 0xD0, 0x39, 0xE4, 0x17, 0x78, + 0x09, 0xDC, 0xC0, 0xB5, 0xFD, 0xCC, 0x32, 0xD9, + 0x52, 0x92, 0xBF, 0x9A, 0xE3, 0xE9, 0xA6, 0xC8, + 0x62, 0x9D, 0xCC, 0x20, 0xE9, 0x9A, 0xF2, 0x4E, + 0xE0, 0x3B, 0x8B, 0x87, 0x36, 0x38, 0x97, 0x89, + 0xE8, 0x7E, 0xC2, 0x74, 0x54, 0x56, 0xB8, 0x3E, + 0x34, 0xDC, 0xC2, 0xCB, 0x99, 0x85, 0x5E, 0x8E, + 0xF5, 0xD3, 0xEE, 0x14, 0x6F, 0x46, 0x4F, 0x0E, + 0x8A, 0x11, 0x51, 0x43, 0x77, 0xAA, 0x0C, 0x2B, + 0xD2, 0xE2, 0xF7, 0x32, 0x39, 0x96, 0x2A, 0x7B, + 0x23, 0xE2, 0x02, 0xF8, 0xFA, 0x8C, 0xE9, 0xDB, + 0x5C, 0x94, 0x64, 0xD0, 0xD1, 0x9C, 0xC6, 0xE5, + 0x73, 0x2C, 0x0D, 0x60, 0xB3, 0x15, 0x35, 0x63, + 0x6D, 0xC2, 0xCA, 0xA1, 0x1B, 0x4F, 0x48, 0x0B, + 0x72, 0x69, 0xE7, 0x56, 0x1D, 0x07, 0x50, 0xAC, + 0x77, 0xD1, 0x95, 0x5A, 0xAB, 0x6D, 0x78, 0x00, + 0x8D, 0xE3, 0x5C, 0x47, 0x69, 0x3B, 0x78, 0x01, + 0x2C, 0x63, 0x55, 0xDF, 0x90, 0xAD, 0xAF, 0xF8, + 0xD4, 0x73, 0xDD, 0x5A, 0xD7, 0x26, 0x37, 0xF2, + 0x4B, 0x5B, 0x19, 0xCF, 0x6C, 0xD3, 0xEE, 0x54, + 0xA6, 0x04, 0x3A, 0x26, 0x13, 0xF0, 0xCA, 0x2C, + 0xA3, 0x2D, 0x05, 0x65, 0x84, 0xB5, 0x41, 0x84, + 0x71, 0x15, 0xEF, 0xEB, 0x10, 0xF9, 0xD2, 0x17, + 0x7D, 0x21, 0xFD, 0x52, 0x4A, 0xC0, 0x43, 0x0E, + 0xCB, 0xFF, 0xD7, 0x4E, 0x82, 0xCE, 0x89, 0x8E, + 0xCF, 0x57, 0x60, 0x0C, 0xC6, 0xFC, 0xA6, 0x03, + 0x9F, 0x43, 0x59, 0xFF, 0x26, 0x87, 0xD1, 0x38, + 0xD0, 0x36, 0x83, 0xEB, 0x8E, 0x30, 0x86, 0x19, + 0xB1, 0x17, 0x3C, 0x81, 0xAF, 0xF4, 0xDE, 0xE3, + 0x71, 0x3A, 0xE5, 0x9A, 0xFC, 0x02, 0x54, 0xF7, + 0xF5, 0x0D, 0x64, 0x4A, 0x2A, 0xB7, 0xA1, 0x56, + 0xDB, 0x23, 0xE0, 0x12, 0xD9, 0xA4, 0x9E, 0x97, + 0x36, 0xDA, 0x65, 0x5B, 0x1A, 0xF1, 0x77, 0x4D, + 0x25, 0x35, 0x13, 0xE8, 0x55, 0xEC, 0x43, 0x99, + 0x76, 0x96, 0x02, 0xBC, 0x0B, 0x34, 0x26, 0xC3, + 0x25, 0x75, 0x6D, 0x38, 0x52, 0x2A, 0x9F, 0x6B, + 0x69, 0xB8, 0xCD, 0x87, 0x8A, 0x2B, 0xFF, 0x2F, + 0xDD, 0xE7, 0x69, 0xF6, 0x8E, 0x86, 0x27, 0xFA, + 0xCC, 0x2F, 0xDC, 0x66, 0x92, 0xE9, 0x15, 0x2B, + 0x65, 0xF3, 0x86, 0xF1, 0x51, 0x67, 0x55, 0xA0, + 0x58, 0x88, 0x08, 0xC9, 0x43, 0x29, 0xBB, 0x08, + 0xBF, 0x5C, 0x19, 0x98, 0xB9, 0x58, 0x78, 0xF2, + 0x3B, 0x20, 0xDA, 0x1F, 0x8C, 0x78, 0xAC, 0x13, + 0xF0, 0xDA, 0xFA, 0x42, 0x05, 0xFF, 0x19, 0x73, + 0x7D, 0x1A, 0xB1, 0x4A, 0x53, 0xDC, 0x0E, 0xE0, + 0x1C, 0x93, 0xD5, 0x7A, 0x14, 0x9A, 0xD3, 0x1E, + 0x6D, 0x00, 0x51, 0xC5, 0x1B, 0xEC, 0xFD, 0x23, + 0x41, 0xD3, 0xDF, 0x47, 0xF5, 0x8F, 0x82, 0xF5, + 0x17, 0xA6, 0x7D, 0x19, 0xB1, 0x00, 0xFF, 0x01, + 0xE2, 0x7A, 0xBF, 0xF4, 0x64, 0xC6, 0x3C, 0xBA, + 0x67, 0xA8, 0x71, 0x59, 0xF7, 0xFD, 0x90, 0xCC, + 0x9F, 0x60, 0x99, 0x47, 0x13, 0x7B, 0xDF, 0x2B, + 0xFA, 0xD8, 0xBB, 0x1E, 0x0D, 0x34, 0x5B, 0x16, + 0x83, 0x32, 0x60, 0x5E, 0x47, 0xE0, 0x62, 0x0A, + 0xB2, 0x14, 0x58, 0x77, 0x7B, 0xF9, 0x30, 0x79, + 0x66, 0x30, 0xB2, 0x5D, 0x42, 0xA1, 0x31, 0xA1, + 0xAA, 0x18, 0xE2, 0xFE, 0x73, 0x78, 0x8A, 0x47, + 0xDA, 0xDB, 0xA9, 0x05, 0x75, 0xEE, 0xAE, 0x74, + 0x85, 0x55, 0xC4, 0x4C, 0x3A, 0x47, 0x13, 0xD8, + 0xCA, 0x82, 0x66, 0x0A, 0x6E, 0x6B, 0x42, 0xD5, + 0x95, 0x4D, 0xF1, 0x79, 0x80, 0x13, 0x14, 0x4F, + 0xDA, 0x44, 0x49, 0x47, 0x71, 0x7A, 0x5A, 0xF1, + 0x61, 0xB9, 0x9C, 0xB1, 0x52, 0xDE, 0x3C, 0xC9, + 0xAE, 0x80, 0x9E, 0xC0, 0x3C, 0xD0, 0x74, 0x42, + 0x17, 0xAE, 0x4C, 0x04, 0x3A, 0x0B, 0xAA, 0x31, + 0x24, 0x12, 0xBB, 0x4E, 0x21, 0x8E, 0x36, 0x41, + 0xA0, 0x3A, 0xCA, 0xCF, 0x8B, 0xC6, 0x64, 0x25, + 0xDE, 0x55, 0x75, 0xEA, 0x23, 0x8F, 0x16, 0x37, + 0x78, 0x16, 0xC7, 0xB5, 0xA0, 0xB1, 0xB3, 0x70, + 0x0D, 0xB2, 0x90, 0xB9, 0x51, 0x27, 0x96, 0xF2, + 0x86, 0xBD, 0x3C, 0x8C, 0xBD, 0x47, 0x36, 0xC5, + 0xE7, 0xB6, 0xF0, 0x13, 0x74, 0xA9, 0x77, 0x63, + 0x33, 0x5D, 0xF3, 0x35, 0xA9, 0x9F, 0x47, 0x1A, + 0x37, 0x4B, 0x06, 0x0F, 0xFA, 0x06, 0xFD, 0x28, + 0x09, 0x96, 0x33, 0xEE, 0x6E, 0xC2, 0x44, 0xCA, + 0x26, 0x8D, 0xC1, 0x3D, 0x09, 0x23, 0x79, 0xCB, + 0x28, 0xEB, 0x58, 0x3B, 0x6B, 0xEC, 0x69, 0xF1, + 0x29, 0x30, 0x15, 0x26, 0x2F, 0xAE, 0x0C, 0x61, + 0xF6, 0xF0, 0x43, 0x34, 0x9F, 0xAA, 0xB8, 0xA2, + 0xE6, 0x40, 0x10, 0x74, 0xF7, 0x25, 0x70, 0xD3, + 0x95, 0xF3, 0x3C, 0x11, 0x91, 0x72, 0x2C, 0xF7, + 0xE9, 0x49, 0xA6, 0x7A, 0x8A, 0x42, 0xCC, 0x78, + 0xE0, 0x09, 0x04, 0x50, 0x7A, 0x8E, 0x6E, 0x08, + 0xEB, 0x46, 0xB5, 0x9B, 0x21, 0xD3, 0x2D, 0x98, + 0x73, 0x62, 0x48, 0x5A, 0x07, 0x82, 0x94, 0xDD, + 0xF6, 0x35, 0x0E, 0xD8, 0xCC, 0x05, 0x5B, 0x21, + 0xBB, 0x3A, 0x4B, 0x6B, 0x78, 0xCB, 0x6B, 0x7B, + 0xD6, 0x4B, 0xE7, 0x0F, 0x8A, 0xD3, 0x65, 0x19, + 0xF0, 0x62, 0xD8, 0xBB, 0x57, 0xFB, 0x87, 0x27, + 0xA6, 0x03, 0x4E, 0xC1, 0x5D, 0x99, 0x4B, 0x0D, + 0x77, 0x4A, 0x2C, 0xB7, 0x3B, 0x71, 0x44, 0x62, + 0x37, 0x43, 0x3B, 0xC5, 0xA0, 0x26, 0xC8, 0x50, + 0xEE, 0x7D, 0x0D, 0x8C, 0xAF, 0x5D, 0xE1, 0x24, + 0xF1, 0x41, 0xED, 0x60, 0x50, 0x1B, 0x4B, 0xC7, + 0xEB, 0x5F, 0x94, 0x9E, 0xAC, 0xBA, 0x93, 0x02, + 0x0B, 0x09, 0x2C, 0x2D, 0x7B, 0x2D, 0x6F, 0x4E, + 0xEA, 0x3F, 0x2B, 0x57, 0x0B, 0x90, 0x11, 0xDA, + 0xF2, 0xA3, 0x97, 0x84, 0x78, 0x78, 0x7C, 0x80, + 0x16, 0xEE, 0x5D, 0x10, 0xA5, 0xB9, 0xF2, 0xFB, + 0xB3, 0x77, 0x92, 0xB8, 0xD4, 0x8B, 0xCD, 0x01, + 0x5E, 0x57, 0xBF, 0xA4, 0x21, 0x30, 0x1C, 0xF0, + 0xCB, 0xCE, 0x0D, 0x8D, 0x0D, 0xA2, 0x31, 0x4C, + 0xF9, 0xAA, 0xC7, 0x12, 0x03, 0xA3, 0x68, 0x58, + 0x7E, 0x90, 0x3C, 0xF9, 0xF6, 0x4E, 0x30, 0x7C, + 0xDB, 0x7D, 0x62, 0x56, 0xB7, 0xE2, 0x0A, 0x3C, + 0x59, 0xB3, 0xD0, 0x20, 0x08, 0xF6, 0x62, 0x18, + 0x4F, 0xF8, 0xF4, 0xD6, 0x14, 0xE5, 0xB3, 0x28, + 0xA8, 0xD3, 0x1E, 0xFD, 0xC2, 0x5E, 0x74, 0x7C, + 0xF2, 0x30, 0xE2, 0x9A, 0xA1, 0x7D, 0x33, 0xA3, + 0xCA, 0xF1, 0x1C, 0x92, 0x91, 0xF6, 0xEF, 0xB2, + 0x40, 0xBF, 0x41, 0x65, 0xEF, 0x4E, 0xE8, 0x41, + 0xFA, 0xA9, 0x13, 0xB9, 0x7A, 0xC5, 0xBC, 0xDA, + 0x79, 0xBD, 0x8C, 0xFC, 0x5F, 0x05, 0x30, 0x47, + 0xAE, 0x38, 0x6B, 0x8E, 0x00, 0x76, 0xA5, 0x6F, + 0x42, 0x57, 0x71, 0xA7, 0xE3, 0x07, 0xBB, 0x30, + 0x0D, 0x8F, 0x9E, 0xE5, 0x94, 0xBC, 0xB3, 0x16, + 0xF5, 0x10, 0x92, 0xDE, 0x9F, 0xDC, 0x99, 0x55, + 0xB6, 0xD6, 0xFE, 0xD6, 0x15, 0x2F, 0xEE, 0x24, + 0xAF, 0xE3, 0xDE, 0x5F, 0x91, 0xC6, 0xAA, 0x4A, + 0xD2, 0x0C, 0x39, 0x00, 0x12, 0x52, 0xED, 0x5F, + 0x07, 0xE3, 0x65, 0x92, 0xA4, 0x7B, 0x33, 0x7A, + 0x0F, 0x4B, 0x2D, 0xE7, 0x4E, 0x69, 0x6A, 0x51, + 0x73, 0x1A, 0x50, 0x37, 0x6E, 0x5C, 0x16, 0x50, + 0xBC, 0x5A, 0x22, 0x8B, 0x2B, 0xCD, 0x2C, 0xFD, + 0x69, 0x37, 0x42, 0x30, 0x44, 0x51, 0x88, 0x85, + 0xB5, 0xD5, 0x67, 0xE1, 0xA5, 0x88, 0x00, 0xBB, + 0x85, 0x92, 0x0C, 0x07, 0x8E, 0xC0, 0x5E, 0x06, + 0x08, 0xCB, 0x3E, 0x32, 0x3D, 0x6A, 0xB0, 0xF6, + 0x98, 0x20, 0xF8, 0xBF, 0xF4, 0x40, 0x08, 0xF5, + 0x28, 0x1E, 0x50, 0x36, 0x55, 0xA3, 0xCD, 0xE5, + 0xE3, 0x83, 0xFB, 0xD7, 0x29, 0x3E, 0x75, 0x1B, + 0x87, 0xC6, 0x77, 0xF5, 0x2B, 0xFE, 0x3D, 0x18, + 0xC1, 0x06, 0x92, 0x44, 0x2A, 0xFC, 0x28, 0x93, + 0x28, 0x99, 0xBB, 0x42, 0x6A, 0x9B, 0xC6, 0x6F, + 0xE6, 0xC0, 0xD5, 0x81, 0x3D, 0x78, 0x51, 0x5A, + 0x33, 0xF4, 0xD5, 0x29, 0x49, 0x79, 0x9E, 0xBF, + 0xF1, 0x7D, 0xB2, 0xAF, 0xC0, 0xB5, 0x30, 0xE0, + 0x36, 0x75, 0x82, 0x45, 0x19, 0x76, 0xDA, 0xA1, + 0x62, 0xB6, 0x3C, 0x8E, 0x30, 0xB5, 0x05, 0xF7, + 0x4D, 0x7A, 0x18, 0xFC, 0x51, 0xB0, 0xB1, 0x35, + 0x82, 0xBE, 0x97, 0xAB, 0x94, 0x4D, 0x2F, 0xD6, + 0x72, 0xAF, 0x2C, 0xDD, 0x95, 0x8A, 0x6B, 0x61, + 0xD6, 0x18, 0x89, 0xDD, 0x72, 0x6D, 0x8F, 0x71, + 0xFB, 0x68, 0xA4, 0x9C, 0xD0, 0x6C, 0x7D, 0x79, + 0xAF, 0xC9, 0xE9, 0x95, 0x08, 0xC9, 0xF6, 0x91, + 0x3B, 0x84, 0xE7, 0x97, 0x93, 0x49, 0x40, 0x15, + 0x19, 0xB4, 0xB3, 0x13, 0x75, 0x55, 0xB9, 0x0B, + 0xC1, 0x53, 0x15, 0x84, 0x69, 0xEE, 0x94, 0x1C, + 0x44, 0x7D, 0xCD, 0x7C, 0xC8, 0xD9, 0xC5, 0xFD, + 0x20, 0xCF, 0x74, 0xAD, 0x12, 0xA9, 0x23, 0xDD, + 0x97, 0x21, 0x0D, 0xB6, 0x49, 0x96, 0x12, 0x01, + 0x62, 0x0D, 0x9F, 0xAA, 0x61, 0x01, 0xB3, 0xB6, + 0x25, 0x81, 0x3B, 0x91, 0x60, 0x22, 0x7E, 0x32, + 0x1C, 0x5D, 0x1E, 0x59, 0x1F, 0x58, 0x7A, 0x75, + 0xD9, 0x34, 0xF7, 0xF9, 0xA7, 0xB9, 0xAA, 0x91, + 0x8F, 0xC6, 0x0C, 0xCE, 0x0D, 0x74, 0xDB, 0x11, + 0x70, 0x43, 0xD4, 0xB1, 0x07, 0x1E, 0x17, 0x54, + 0xF6, 0x35, 0x73, 0x30, 0xC2, 0xD0, 0x78, 0xE9, + 0x39, 0x3B, 0x5C, 0xF6, 0x8A, 0x68, 0x8F, 0x98, + 0x08, 0x49, 0x4A, 0x27, 0x60, 0x77, 0x19, 0x81, + 0x3C, 0x13, 0x19, 0x6F, 0x02, 0x5F, 0x3B, 0xB2, + 0x8A, 0x62, 0xE8, 0x06, 0x1A, 0x93, 0x78, 0x95, + 0x85, 0xF8, 0xFD, 0x0B, 0xC2, 0x90, 0xFA, 0x24, + 0x27, 0x0D, 0xB4, 0x49, 0x01, 0xFF, 0x86, 0xEB, + 0x72, 0xF6, 0x8E, 0xEE, 0x8D, 0x93, 0x12, 0x79, + 0x1C, 0x79, 0x9A, 0x3B, 0x44, 0xA7, 0x6F, 0x02, + 0x5E, 0x7B, 0xC2, 0x66, 0x69, 0x96, 0x62, 0x93, + 0xFA, 0x05, 0xEE, 0xA8, 0x3E, 0xC8, 0xC3, 0x37, + 0xBA, 0x88, 0xB8, 0xEC, 0x63, 0x7E, 0x75, 0x5D, + 0x91, 0xDC, 0x17, 0x25, 0xDC, 0x26, 0xA5, 0x0C, + 0x9C, 0x79, 0xF3, 0x59, 0xA7, 0x17, 0xA0, 0xB3, + 0xFD, 0xFA, 0xCA, 0x77, 0x63, 0xE5, 0x0E, 0xA4, + 0xE6, 0xEF, 0x6D, 0x04, 0x31, 0xD6, 0x57, 0xC9, + 0xC4, 0xE4, 0x20, 0x0D, 0x4F, 0x5A, 0x63, 0x45, + 0x99, 0xB1, 0xB4, 0x79, 0x93, 0x3F, 0xA6, 0xF1, + 0x13, 0x04, 0x91, 0xEB, 0x30, 0x5F, 0xF1, 0xD7, + 0x61, 0x1B, 0x6C, 0x98, 0xAE, 0x1E, 0x8B, 0xB6, + 0xE6, 0x88, 0xC9, 0xF9, 0xCE, 0x3D, 0xDE, 0xEB, + 0xAD, 0xAE, 0x2E, 0x48, 0x78, 0x9B, 0x79, 0x42, + 0xC3, 0x7E, 0x58, 0x9E, 0x8B, 0x4E, 0xCF, 0xC2, + 0xA7, 0xFF, 0xA3, 0x8C, 0x43, 0x66, 0xBC, 0x9F, + 0x57, 0x70, 0x1E, 0x90, 0xEB, 0xF4, 0x21, 0x3F, + 0x16, 0xB0, 0x3F, 0x74, 0xAF, 0x44, 0xE9, 0xEF, + 0x1C, 0x5B, 0x2C, 0x01, 0x65, 0xFB, 0x10, 0x3E, + 0xC1, 0xF0, 0x11, 0xC5, 0xAD, 0x4B, 0x68, 0x3F, + 0x48, 0xBF, 0xAF, 0x2D, 0x96, 0x6A, 0xEF, 0xE3, + 0x43, 0x85, 0xB9, 0x24, 0xAF, 0xC2, 0xDA, 0x69, + 0xB0, 0x3B, 0xC8, 0x52, 0x79, 0x72, 0x77, 0x0C, + 0xDE, 0xFF, 0x80, 0x5D, 0xC3, 0xD8, 0x3F, 0x0A, + 0x63, 0x92, 0x27, 0xFA, 0x2B, 0x26, 0x02, 0x94, + 0x90, 0x5F, 0x00, 0x1E, 0xCE, 0xFC, 0xCD, 0x2D, + 0xB7, 0xAA, 0x2B, 0x6D, 0xF7, 0x67, 0xD6, 0xF4, + 0x1E, 0x55, 0xE8, 0x39, 0x76, 0x71, 0x9D, 0x1E, + 0x31, 0xC2, 0x4A, 0xB1, 0x68, 0xDE, 0x2A, 0x7F, + 0x14, 0x89, 0xC0, 0x69, 0xF1, 0x3F, 0x9E, 0x66, + 0x6A, 0xA5, 0xA5, 0x1F, 0x28, 0x65, 0x0F, 0xE1, + 0x14, 0x3E, 0xC7, 0x10, 0xB0, 0xFD, 0xBC, 0xA9, + 0xE4, 0xE2, 0xF4, 0x05, 0x8F, 0x74, 0xF1, 0x6B, + 0xC1, 0xC8, 0x8E, 0xD7, 0x3B, 0xAF, 0xDD, 0xA4, + 0x7B, 0xC5, 0xC2, 0x54, 0x34, 0x86, 0x21, 0x88, + 0xB5, 0x95, 0x53, 0x9D, 0xB4, 0x67, 0xB0, 0x0D, + 0x35, 0xE0, 0x49, 0x90, 0xB0, 0xCC, 0x33, 0x42, + 0x77, 0x1C, 0x72, 0x1A, 0xCB, 0x3A, 0xF4, 0x59, + 0x01, 0x1B, 0x41, 0x58, 0x78, 0x75, 0x90, 0x38, + 0x9A, 0x8C, 0x32, 0x43, 0xF9, 0x6B, 0xBA, 0x62, + 0x60, 0x0A, 0x85, 0x2E, 0xA4, 0xE4, 0xD2, 0x0B, + 0x0E, 0x37, 0x49, 0xFD, 0x31, 0x14, 0x33, 0x47, + 0x00, 0x57, 0xD0, 0x1A, 0x1C, 0x64, 0x6D, 0x51, + 0xD1, 0x5F, 0x2B, 0x5F, 0x5D, 0x84, 0xED, 0x1B, + 0x59, 0xEA, 0xB4, 0x13, 0x48, 0xD4, 0x5D, 0x0A, + 0xA0, 0xF3, 0x6A, 0x9C, 0x09, 0x9A, 0xB5, 0xBE, + 0xF4, 0x0C, 0x84, 0x95, 0xE8, 0x68, 0x9C, 0x32, + 0x39, 0x0F, 0xD7, 0xE2, 0x39, 0x77, 0xAB, 0xBC, + 0x40, 0xB7, 0x12, 0xC7, 0x69, 0xD5, 0xB3, 0x46, + 0x2F, 0x1A, 0xAB, 0x56, 0x98, 0xC0, 0x5C, 0x2D, + 0x94, 0x94, 0xCB, 0xE1, 0x00, 0x67, 0xBE, 0xBE, + 0xB8, 0xC4, 0xFE, 0x20, 0x08, 0x79, 0xBC, 0x3F, + 0xE3, 0xD6, 0xC0, 0x3E, 0x8E, 0x76, 0xF0, 0x63, + 0xC9, 0xD0, 0x9C, 0x0E, 0x31, 0x18, 0x4A, 0x9F, + 0x9F, 0xFB, 0xB6, 0xBC, 0xD9, 0x56, 0x1D, 0x9A, + 0xDE, 0x4F, 0x16, 0xDF, 0x8E, 0xA6, 0xEF, 0x29, + 0x23, 0xB1, 0xD6, 0x8B, 0xC6, 0x02, 0x1F, 0x62, + 0xE1, 0xB8, 0x13, 0x3A, 0xC4, 0x6D, 0x52, 0xBB, + 0xA7, 0x08, 0x2F, 0x52, 0x49, 0x97, 0xED, 0x14, + 0x22, 0x81, 0xB1, 0x8B, 0x5B, 0x3C, 0xCD, 0x20, + 0x33, 0x49, 0x2B, 0xA4, 0x0F, 0x8A, 0x41, 0x81, + 0x0E, 0x04, 0x3B, 0x4C, 0xB1, 0x73, 0x19, 0x09, + 0xA7, 0x0F, 0xF5, 0xEA, 0xE7, 0x6B, 0x11, 0x30, + 0xB7, 0x22, 0x87, 0x1F, 0x36, 0x1F, 0xA7, 0x0C, + 0x23, 0x25, 0xB8, 0xC5, 0x2F, 0xDC, 0x65, 0x48, + 0x53, 0xF1, 0x20, 0x20, 0x33, 0xD0, 0xCA, 0xA4, + 0xE3, 0xE3, 0x8D, 0xC1, 0x65, 0x55, 0xBE, 0x0B, + 0x6E, 0x15, 0x45, 0xCA, 0x04, 0x03, 0x53, 0xBD, + 0xEF, 0x3D, 0x89, 0xAD, 0x74, 0x68, 0x87, 0xAA, + 0x63, 0xD6, 0x2E, 0x35, 0x95, 0x72, 0xBB, 0x16, + 0x65, 0x4D, 0x3E, 0x38, 0x83, 0xFE, 0x76, 0x52, + 0xEE, 0xA1, 0x26, 0xA9, 0x16, 0x7B, 0x76, 0x4F, + 0x14, 0x4E, 0x02, 0x5E, 0xF9, 0xC0, 0x04, 0x27, + 0xBB, 0xF1, 0x9F, 0xA2, 0x63, 0xD7, 0xC2, 0x48, + 0xC7, 0xF1, 0x12, 0x5E, 0x06, 0xC5, 0x43, 0xEE, + 0x3A, 0xEA, 0x66, 0x33, 0xCF, 0x86, 0xFD, 0x97, + 0x50, 0xE7, 0x61, 0x1B, 0xE3, 0x9E, 0xE7, 0x08, + 0x65, 0x76, 0x35, 0x88, 0x52, 0xD2, 0x58, 0xF5, + 0xCB, 0x34, 0xFB, 0x17, 0x86, 0x97, 0xE5, 0x72, + 0x1F, 0x6A, 0x93, 0x35, 0xF4, 0xDA, 0x9D, 0x13, + 0x44, 0x89, 0xE7, 0xFD, 0xBE, 0x81, 0xCA, 0x6B, + 0x33, 0x31, 0xDE, 0x79, 0x1D, 0x72, 0x44, 0xDF, + 0x07, 0x61, 0x2B, 0x49, 0xBD, 0x87, 0xBF, 0x6E, + 0x3A, 0x04, 0x28, 0xCB, 0x62, 0x70, 0x9F, 0x7D, + 0x31, 0x18, 0xD9, 0x79, 0xAF, 0x04, 0x31, 0x0A, + 0x4B, 0xEC, 0xB1, 0x79, 0xD1, 0xC5, 0x8E, 0x9F, + 0xB9, 0xB9, 0xCA, 0xC8, 0xD7, 0x04, 0xF5, 0x45, + 0x19, 0x2E, 0xFE, 0x75, 0xB1, 0x30, 0xD3, 0x5B, + 0xF4, 0x32, 0xA1, 0x92, 0xF0, 0x22, 0x73, 0x3C, + 0xC9, 0xAE, 0x4F, 0x80, 0xC5, 0x22, 0x5A, 0xD7, + 0x13, 0xC2, 0xF0, 0xBB, 0x26, 0x11, 0xAD, 0x7D, + 0x89, 0x6A, 0x17, 0xD5, 0x85, 0x49, 0x7F, 0x8D, + 0xC4, 0x6B, 0x28, 0xF2, 0xF3, 0xF5, 0x76, 0xE5, + 0xC3, 0x46, 0x44, 0x60, 0x22, 0xB7, 0xAD, 0x92, + 0x67, 0x3A, 0x35, 0x79, 0x79, 0x9D, 0xF4, 0xCD, + 0xE0, 0x73, 0x5C, 0x31, 0xAF, 0x7B, 0x8D, 0x9C, + 0x9D, 0xC4, 0x8A, 0x17, 0xB0, 0x8E, 0x3C, 0x02, + 0x6B, 0x7C, 0x4A, 0xA5, 0xE5, 0x30, 0x2D, 0x93, + 0xF8, 0x91, 0x50, 0xCB, 0xDF, 0x7D, 0x57, 0x6F, + 0x7D, 0x70, 0x1E, 0x68, 0xBF, 0x50, 0x09, 0xDC, + 0x9E, 0x70, 0x1A, 0xC5, 0xC3, 0x4D, 0x79, 0x69, + 0xCE, 0x9C, 0x03, 0xCF, 0x3A, 0x73, 0xAB, 0x7D, + 0xAC, 0x12, 0x29, 0x61, 0xAC, 0x20, 0x84, 0x4B, + 0x2C, 0xDE, 0xA1, 0xCD, 0x45, 0xB8, 0x92, 0x74, + 0x3C, 0x2B, 0xA6, 0xAF, 0xD0, 0x40, 0xE4, 0x72, + 0x77, 0x09, 0x61, 0xE8, 0x56, 0x2F, 0xA8, 0x1F, + 0x28, 0x32, 0x0B, 0xC1, 0x51, 0xF2, 0x17, 0xF7, + 0x54, 0x6F, 0x4F, 0xB6, 0x1B, 0xEC, 0x2C, 0xC9, + 0x86, 0xDE, 0xA8, 0xC5, 0x14, 0x56, 0x63, 0x1F, + 0x1E, 0x7F, 0x3B, 0x99, 0xB5, 0xF5, 0x95, 0x38, + 0xC8, 0x5D, 0xE6, 0xD5, 0x7C, 0xA7, 0xC3, 0xFD, + 0x82, 0xA8, 0x2B, 0x8E, 0xDC, 0xC5, 0x94, 0xA6, + 0x06, 0x6D, 0x46, 0xAC, 0x63, 0x5B, 0x6F, 0x20, + 0xBF, 0xD4, 0x9A, 0x0B, 0xB8, 0x5A, 0x52, 0x84, + 0x2C, 0xA6, 0x21, 0x81, 0x27, 0x94, 0x70, 0x55, + 0x47, 0x15, 0x34, 0x01, 0x94, 0xB6, 0x2D, 0x3D, + 0x3E, 0xEB, 0xFD, 0xB3, 0x04, 0xCA, 0xF5, 0x53, + 0x92, 0x14, 0x42, 0xC7, 0x80, 0xFC, 0x38, 0xEA, + 0x32, 0x13, 0x42, 0x73, 0x7A, 0x14, 0x7B, 0x2B, + 0xB4, 0x97, 0xB6, 0xE1, 0x19, 0xEE, 0x07, 0x6B, + 0xC6, 0xB2, 0x3A, 0xF0, 0x32, 0x1A, 0x95, 0x6A, + 0xE2, 0xFD, 0xAF, 0x0B, 0x72, 0x28, 0x6B, 0xC4, + 0x5F, 0x40, 0xD0, 0xCA, 0x1A, 0x5D, 0x20, 0x20, + 0x2C, 0x73, 0x64, 0xBE, 0xA9, 0x87, 0x59, 0x8C, + 0x36, 0x5C, 0x23, 0x7E, 0x99, 0xC5, 0xB8, 0xE8, + 0xBD, 0x80, 0xD0, 0x89, 0xD9, 0x75, 0xB3, 0x9B, + 0x27, 0xB7, 0xE9, 0xC3, 0x1B, 0x71, 0x40, 0x25, + 0x33, 0x8B, 0x2A, 0x32, 0x51, 0x72, 0x44, 0x16, + 0x69, 0xFC, 0xD9, 0x13, 0xDD, 0xCF, 0xEE, 0x89, + 0x19, 0xE1, 0x49, 0x47, 0x18, 0xCD, 0x30, 0xE6, + 0xE9, 0xA7, 0x61, 0x64, 0x31, 0x8D, 0xBF, 0xC7, + 0xAE, 0x88, 0x8F, 0x30, 0x27, 0xC9, 0xA9, 0x53, + 0xE4, 0x64, 0xE9, 0x43, 0x62, 0x0B, 0x9B, 0x93, + 0xE0, 0xC5, 0xE5, 0x95, 0x15, 0x6B, 0x05, 0x4F, + 0xC0, 0xD8, 0x02, 0xA0, 0xD6, 0x4C, 0xF7, 0x94, + 0x85, 0x54, 0x11, 0x3F, 0x28, 0xF3, 0xA5, 0x11, + 0x2F, 0x3C, 0xC2, 0x3D, 0x3D, 0x6D, 0x9B, 0xEE, + 0x3D, 0x6E, 0x17, 0xE5, 0x18, 0x4E, 0x1A, 0xB4, + 0x0A, 0x37, 0x47, 0xB3, 0x88, 0x7B, 0x21, 0xC6, + 0xC7, 0x59, 0x74, 0x6A, 0xD3, 0xE9, 0x40, 0xC2, + 0x1A, 0xAA, 0x8E, 0xDE, 0x15, 0xAA, 0x98, 0x06, + 0x09, 0xD9, 0xAA, 0x67, 0x00, 0x32, 0x13, 0x99, + 0x8F, 0x04, 0x29, 0x25, 0xB2, 0x75, 0x71, 0xFE, + 0x21, 0x6F, 0x9E, 0xAA, 0x35, 0x20, 0xD6, 0x60, + 0x49, 0x81, 0x89, 0xA5, 0x51, 0x7B, 0x34, 0xAD, + 0x49, 0x82, 0xED, 0x31, 0xDE, 0xCA, 0x37, 0xF3, + 0x36, 0x06, 0x00, 0x85, 0x10, 0xE0, 0xE7, 0xFE, + 0xBD, 0xDC, 0xD9, 0x99, 0x2F, 0x42, 0xC5, 0x86, + 0xB3, 0xB2, 0x1E, 0x81, 0x7E, 0xB8, 0x38, 0xDB, + 0x40, 0xE4, 0x8D, 0x77, 0x1C, 0xAD, 0xBD, 0x82, + 0x71, 0x5B, 0x12, 0xD5, 0x07, 0x60, 0x45, 0xDC, + 0x1A, 0xDD, 0xEB, 0xD1, 0xFC, 0x1C, 0x6B, 0x6A, + 0x10, 0x67, 0x33, 0x12, 0x0D, 0x4E, 0xDD, 0xCB, + 0x3C, 0x10, 0x27, 0x80, 0xC7, 0x75, 0xD3, 0x3B, + 0x0A, 0x16, 0xE5, 0x97, 0x48, 0x66, 0x93, 0x3F, + 0x25, 0x53, 0x24, 0x3D, 0x44, 0xAF, 0x66, 0xF0, + 0xF3, 0x3D, 0x36, 0x50, 0x1D, 0xED, 0x3F, 0x3B, + 0x58, 0x2E, 0x9F, 0x7D, 0x6B, 0xD1, 0x84, 0x56, + 0x0D, 0x88, 0x5B, 0x95, 0x5A, 0xBF, 0x18, 0xCA, + 0x9C, 0xE5, 0x13, 0x0E, 0xFD, 0x43, 0x88, 0xB9, + 0x21, 0xD2, 0xF1, 0x81, 0xA1, 0xA5, 0x66, 0x3B, + 0x73, 0xE8, 0x56, 0x86, 0x40, 0x21, 0x67, 0x6A, + 0xB8, 0xF2, 0xE7, 0x8D, 0x32, 0x2B, 0xD5, 0x82, + 0x50, 0xDE, 0xEE, 0x75, 0xA9, 0x65, 0x6D, 0x5F, + 0x14, 0x25, 0x01, 0xC4, 0x5A, 0xA8, 0xDA, 0x10, + 0xA2, 0x07, 0xDE, 0x65, 0xB4, 0xDA, 0x84, 0xBB, + 0x15, 0x89, 0xDB, 0x64, 0xA1, 0x88, 0x6A, 0x15, + 0x73, 0xB8, 0x0D, 0x6A, 0x90, 0xA6, 0x31, 0xD4, + 0x78, 0xB1, 0x5E, 0xC7, 0x32, 0xF2, 0x51, 0x2A, + 0x5C, 0x8D, 0x85, 0xFB, 0x2A, 0xF9, 0xC9, 0xD6, + 0x85, 0x5F, 0xD9, 0x6F, 0x37, 0xB0, 0x4B, 0xA9, + 0x6F, 0xD5, 0x7A, 0x17, 0xDB, 0x0A, 0xFD, 0x33, + 0x25, 0x1B, 0x2A, 0x9C, 0x62, 0x57, 0xBF, 0x5D, + 0x58, 0xBF, 0x7A, 0x64, 0x2D, 0x4C, 0x26, 0x2B, + 0xAC, 0x26, 0xE8, 0xBF, 0x40, 0x60, 0x06, 0xBD, + 0xD7, 0xB1, 0x59, 0xB8, 0x96, 0xAB, 0x0A, 0xD2, + 0x50, 0x6C, 0x25, 0x53, 0x85, 0xBA, 0x69, 0x8B, + 0x8C, 0x22, 0x10, 0xCE, 0x02, 0x2D, 0x33, 0x5A, + 0xC8, 0xDB, 0x61, 0x23, 0x49, 0x1A, 0x94, 0x18, + 0x27, 0x19, 0x06, 0x58, 0x74, 0x4C, 0x75, 0x7F, + 0x08, 0x23, 0x89, 0xBE, 0x64, 0xF0, 0x3D, 0x1D, + 0x86, 0xC1, 0x10, 0xB9, 0xDC, 0xC4, 0x74, 0x04, + 0xED, 0x27, 0x76, 0xC1, 0xAA, 0x95, 0xDF, 0x4E, + 0xDE, 0x46, 0x41, 0xC2, 0x51, 0x8F, 0x7A, 0x2D, + 0xD8, 0xB0, 0x92, 0x44, 0x39, 0xA9, 0xF6, 0xAE, + 0x57, 0x80, 0xE1, 0xE3, 0x28, 0x8E, 0x91, 0xDA, + 0xA2, 0x2B, 0x11, 0x10, 0x89, 0xDB, 0x4E, 0x39, + 0x7E, 0xA0, 0x0C, 0xF3, 0x27, 0xF6, 0x8A, 0x7A, + 0x86, 0xE7, 0xE6, 0x6D, 0x06, 0x2A, 0xE5, 0xF0, + 0x59, 0xBD, 0x9C, 0xE1, 0x93, 0x87, 0x29, 0x74, + 0x28, 0x6B, 0x6B, 0x6E, 0x14, 0x64, 0x85, 0x60, + 0x79, 0xDA, 0x8D, 0xDD, 0x76, 0xF9, 0xBF, 0x68, + 0x80, 0x4A, 0xC8, 0x5C, 0xCB, 0xC9, 0x99, 0xC3, + 0xBD, 0x4B, 0xA4, 0x10, 0xBE, 0x70, 0x76, 0x40, + 0xFE, 0x7F, 0xD7, 0x43, 0x52, 0xDC, 0xBA, 0x4B, + 0x7B, 0x1D, 0xCD, 0xCE, 0x99, 0x36, 0xB1, 0x64, + 0x17, 0x87, 0xC0, 0x70, 0xF7, 0x5B, 0x58, 0x62, + 0x0C, 0x6D, 0x63, 0x29, 0x93, 0xC8, 0x00, 0xD8, + 0x13, 0xC8, 0xB1, 0x04, 0xB3, 0xEE, 0x51, 0x78, + 0x40, 0xAF, 0xA5, 0x75, 0xD6, 0xC5, 0xBE, 0xEE, + 0x3C, 0x97, 0x77, 0x37, 0x56, 0x4E, 0x02, 0x8F, + 0xB4, 0x0E, 0xE5, 0x5D, 0xC0, 0xA2, 0x8B, 0x6B, + 0xC6, 0x82, 0x66, 0xBC, 0x37, 0x91, 0x91, 0xE5, + 0x3D, 0xFE, 0x0C, 0x2E, 0xAE, 0xB7, 0x12, 0xAA, + 0xE1, 0xA3, 0xC3, 0x5F, 0x6F, 0x68, 0x45, 0xF2, + 0x3D, 0xA0, 0x73, 0x46, 0x97, 0x68, 0x54, 0x63, + 0xF7, 0x63, 0x6D, 0xE2, 0x15, 0x69, 0x72, 0x80, + 0x49, 0x5C, 0x62, 0x83, 0x82, 0xCE, 0xB5, 0x33, + 0x4E, 0x63, 0x04, 0x79, 0x4E, 0x43, 0x6B, 0x78, + 0xB4, 0xEF, 0xB0, 0x02, 0x3F, 0xA2, 0x88, 0xF8, + 0x3D, 0xFF, 0x31, 0xF9, 0x25, 0xAB, 0x8E, 0x6A, + 0x9A, 0x7E, 0xCC, 0xBC, 0xD9, 0x05, 0xA3, 0xA5, + 0x2C, 0x29, 0xA5, 0x6F, 0xF3, 0x31, 0xAF, 0x27, + 0xE2, 0x38, 0x3E, 0x5C, 0x5B, 0x19, 0x3D, 0xDB, + 0x86, 0x35, 0x09, 0x8C, 0x5D, 0xEF, 0x1C, 0x4E, + 0x79, 0x0D, 0xAA, 0x1C, 0xA6, 0x49, 0x7D, 0x01, + 0xFB, 0x3B, 0xF6, 0xCC, 0x94, 0xA6, 0xF4, 0x8E, + 0xA7, 0xCA, 0xB5, 0xD9, 0xA1, 0xCD, 0xDB, 0xA5, + 0x93, 0xEC, 0xD6, 0x1B, 0xE1, 0xE7, 0x35, 0x94, + 0xB0, 0x66, 0x1F, 0x96, 0xA4, 0xE0, 0x48, 0x03, + 0xCD, 0xF2, 0xB5, 0x70, 0x86, 0xD5, 0x78, 0x3A, + 0x17, 0xBE, 0x84, 0x30, 0x67, 0x81, 0xB6, 0xB2, + 0xAD, 0x1F, 0x87, 0x62, 0x60, 0x87, 0xF8, 0x09, + 0x39, 0x02, 0x08, 0xF9, 0x34, 0x67, 0xF8, 0x45, + 0xD2, 0xBE, 0xA2, 0x84, 0x3A, 0xFF, 0xA0, 0xA9, + 0x33, 0xDC, 0x4C, 0xAE, 0x7D, 0x4B, 0xDC, 0x5F, + 0xEB, 0x25, 0xA2, 0x1A, 0x18, 0xAE, 0x7A, 0x07, + 0x24, 0x0C, 0xA3, 0x74, 0x5D, 0xC3, 0x72, 0x5E, + 0x02, 0x6D, 0x86, 0x40, 0x88, 0x4A, 0xD1, 0x9F, + 0xD1, 0x6B, 0x04, 0xBE, 0xB8, 0x35, 0x9A, 0xA0, + 0x23, 0x2E, 0x20, 0x1C, 0x2E, 0x1A, 0x4A, 0x01, + 0xA7, 0x1D, 0xCC, 0x64, 0xCA, 0xEF, 0x54, 0x83, + 0xF2, 0x50, 0xEC, 0x92, 0xE5, 0x49, 0x84, 0xDC, + 0xA8, 0x38, 0xAB, 0x9A, 0xA4, 0x36, 0xA9, 0x59, + 0x15, 0xF9, 0x73, 0xCB, 0x97, 0x1A, 0x6E, 0x65, + 0x4A, 0x42, 0x11, 0x28, 0x79, 0xFE, 0xC5, 0xE0, + 0xC3, 0x03, 0xBF, 0xE1, 0xDD, 0xC0, 0x82, 0x64, + 0xC5, 0x9D, 0xF0, 0x2A, 0x8A, 0x62, 0x25, 0x56, + 0x84, 0x92, 0xE5, 0xDF, 0x3F, 0x71, 0xC8, 0xFF, + 0xF4, 0x9A, 0xC5, 0x17, 0x06, 0x8A, 0x02, 0xF0, + 0x3C, 0x76, 0x53, 0xD0, 0xA2, 0x28, 0x1A, 0xE0, + 0x12, 0xB1, 0x9F, 0x03, 0x43, 0x10, 0x0F, 0xEE, + 0xA9, 0x35, 0x9A, 0x53, 0x7E, 0x9B, 0x4C, 0x64, + 0xE1, 0xCF, 0x5A, 0x07, 0x34, 0x06, 0xA3, 0x8E, + 0xAC, 0x10, 0x63, 0xB3, 0xF2, 0xB0, 0xE3, 0x63, + 0x6A, 0x62, 0x0B, 0xA0, 0x02, 0x8C, 0x03, 0x96, + 0xDC, 0x0B, 0xDB, 0x57, 0x34, 0x7B, 0xA9, 0xEF, + 0x4C, 0x46, 0x80, 0x4D, 0x58, 0x78, 0x19, 0x3C, + 0x03, 0x87, 0x26, 0xB3, 0x58, 0xFF, 0x01, 0x22, + 0x1D, 0x41, 0xFA, 0xBE, 0xC1, 0xBD, 0x79, 0x1D, + 0x6F, 0xDE, 0x8B, 0xEC, 0x25, 0x1F, 0xD2, 0xE9, + 0xCA, 0x81, 0x3B, 0xC4, 0x8C, 0xB2, 0x77, 0xDD, + 0x7C, 0xB5, 0x47, 0x04, 0xED, 0xB5, 0x71, 0xE0, + 0xDA, 0x2E, 0xA4, 0xF8, 0xA2, 0x13, 0x3C, 0x90, + 0x48, 0xC5, 0xC0, 0x6C, 0xD2, 0x6D, 0x82, 0x63, + 0x44, 0x98, 0xC1, 0x3C, 0x07, 0x55, 0x8E, 0x0F, + 0xC6, 0xD6, 0x3A, 0xF2, 0xCE, 0x79, 0x4E, 0x39, + 0xA4, 0xB8, 0x07, 0x5F, 0x7B, 0x1D, 0xB1, 0x83, + 0x72, 0xAB, 0x2E, 0x05, 0x04, 0x32, 0x49, 0xC8, + 0x05, 0x41, 0xEA, 0xEB, 0xF8, 0x15, 0x9A, 0x01, + 0x08, 0xB8, 0xED, 0x4F, 0x33, 0x6E, 0x04, 0x0C, + 0xAD, 0xC3, 0xE5, 0x4D, 0x30, 0x2D, 0xFE, 0x54, + 0xC6, 0xA3, 0xAE, 0xA4, 0x6C, 0xBE, 0x44, 0x23, + 0x06, 0x96, 0x4A, 0x97, 0x5B, 0xB6, 0x35, 0x37, + 0x58, 0x51, 0xEE, 0xDE, 0x80, 0xAA, 0x1E, 0xA8, + 0x1C, 0xEA, 0x64, 0xF0, 0xF8, 0x21, 0x83, 0x64, + 0x7D, 0x43, 0xF5, 0x69, 0x99, 0xF4, 0x05, 0x22, + 0xAB, 0xD9, 0xD3, 0x2F, 0xD2, 0x24, 0x48, 0xDA, + 0xCA, 0x6D, 0xE7, 0xE3, 0x32, 0x87, 0xD7, 0x9C, + 0xC1, 0x39, 0x4C, 0x23, 0x18, 0xBE, 0x41, 0xA4, + 0x34, 0xEC, 0x9D, 0xBD, 0x04, 0xF5, 0x92, 0xF4, + 0x43, 0xA8, 0xED, 0xF2, 0x7B, 0x29, 0x77, 0xA7, + 0x17, 0x6B, 0xB1, 0x0C, 0x96, 0x67, 0xD7, 0x82, + 0x15, 0x2E, 0xB0, 0x5F, 0x29, 0x79, 0x0E, 0x18, + 0x76, 0xBA, 0x82, 0x94, 0x3A, 0xC7, 0xE5, 0x01, + 0xCB, 0x63, 0xCD, 0x62, 0x67, 0x6F, 0xD9, 0xE0, + 0x75, 0x26, 0x3F, 0x2D, 0xC4, 0x5D, 0xD1, 0x9D, + 0xEF, 0x41, 0x11, 0xD8, 0x62, 0x1B, 0x41, 0x4E, + 0xBF, 0xBE, 0xCB, 0xC7, 0x48, 0x8D, 0x08, 0xD8, + 0xC3, 0xF0, 0x13, 0xE6, 0xC3, 0xD9, 0x0E, 0x49, + 0xE2, 0x00, 0x1F, 0xF6, 0xD8, 0x4F, 0xFF, 0xE5, + 0x03, 0x32, 0x6D, 0x3A, 0x57, 0x4D, 0x50, 0xDF, + 0x89, 0x1F, 0x3A, 0xB3, 0xD0, 0x5A, 0x9A, 0xBE, + 0x02, 0x31, 0xDA, 0xF4, 0xA1, 0xB6, 0x06, 0x2C, + 0x2F, 0xBB, 0xCF, 0x28, 0xA8, 0xB1, 0x06, 0x63, + 0x52, 0x47, 0x64, 0xA5, 0xBB, 0x23, 0x5A, 0x6A, + 0x87, 0xC1, 0xF6, 0x8D, 0x2B, 0xA4, 0x0C, 0xB6, + 0xF3, 0x97, 0x6A, 0x92, 0x8B, 0xA8, 0x7D, 0xCF, + 0xF0, 0xF1, 0xDE, 0x3C, 0x12, 0x48, 0x48, 0x7F, + 0x5D, 0xE6, 0xF3, 0x71, 0xC7, 0x57, 0xD6, 0xC2, + 0xCB, 0x20, 0x03, 0x38, 0xB2, 0xBA, 0xDD, 0x54, + 0x00, 0xD9, 0x98, 0x11, 0x63, 0x48, 0xC2, 0xF9, + 0x51, 0x78, 0x2C, 0xBC, 0x23, 0xC1, 0x8C, 0xA7, + 0x39, 0xFE, 0xAA, 0xFB, 0x59, 0x7C, 0xB6, 0x7A, + 0x26, 0x1B, 0x64, 0xB0, 0xC4, 0xEB, 0x58, 0xB3, + 0xA9, 0xCF, 0x74, 0x14, 0x72, 0x5A, 0x8F, 0x92, + 0xF9, 0x1A, 0xCF, 0x7C, 0x8F, 0xE7, 0x49, 0xAD, + 0x10, 0x6E, 0xD5, 0xE6, 0xFF, 0x7A, 0xE2, 0x7E, + 0xE2, 0x89, 0xEE, 0x7F, 0xB0, 0xD0, 0xD0, 0x67, + 0x8B, 0x0C, 0x44, 0x0A, 0xF6, 0x6B, 0x47, 0x4E, + 0x7D, 0xF0, 0x22, 0xA7, 0xA9, 0xC9, 0x08, 0x9A, + 0x30, 0xD1, 0x3B, 0xE2, 0x10, 0x23, 0x41, 0x66, + 0x45, 0x39, 0x2A, 0x8C, 0xCA, 0xB3, 0x6C, 0x58, + 0xCC, 0xA2, 0xFC, 0x47, 0x7D, 0x50, 0xF1, 0xF4, + 0xD5, 0x23, 0x32, 0x1B, 0xDA, 0x1D, 0x0A, 0x42, + 0xFC, 0x49, 0x34, 0x49, 0x89, 0xF2, 0x5B, 0x8A, + 0x93, 0xAE, 0xE3, 0x29, 0x4C, 0xDB, 0x7E, 0xCA, + 0x42, 0xCE, 0xE3, 0xA4, 0xE9, 0x7E, 0xC1, 0xF6, + 0x73, 0x78, 0x89, 0x19, 0x3A, 0xD8, 0xDF, 0xDE, + 0x69, 0xC8, 0x7F, 0x61, 0xD7, 0x21, 0xDB, 0x90, + 0x08, 0x13, 0x08, 0x71, 0x87, 0x47, 0x40, 0x67, + 0xBD, 0x86, 0x8A, 0xC2, 0x36, 0x8A, 0x1F, 0xC1, + 0xF7, 0x51, 0x59, 0xAB, 0xCA, 0xDC, 0x60, 0x6A, + 0x98, 0xF8, 0x50, 0xA9, 0x31, 0xCE, 0xB0, 0x91, + 0xC7, 0x19, 0xFC, 0x1C, 0xBC, 0x78, 0x34, 0x56, + 0x8E, 0x34, 0xD1, 0x96, 0x7B, 0x3A, 0xB9, 0x18, + 0xBB, 0xA6, 0x28, 0x0A, 0x77, 0xFF, 0x0B, 0x26, + 0xB1, 0x3A, 0x88, 0x06, 0x2A, 0x28, 0xE0, 0x11, + 0xAF, 0xC2, 0x47, 0x6E, 0xC5, 0xA2, 0x13, 0x98, + 0x15, 0xD7, 0x86, 0x79, 0x8A, 0xEE, 0xB3, 0x30, + 0x66, 0x18, 0x9C, 0xE5, 0x44, 0xF0, 0xA1, 0x25, + 0xB6, 0x2F, 0x5E, 0x85, 0xE0, 0x73, 0xAD, 0x40, + 0x92, 0xDE, 0x19, 0x2A, 0x05, 0x34, 0xB0, 0xC1, + 0x39, 0x4D, 0xC1, 0xFF, 0x39, 0x76, 0xC3, 0xDA, + 0x5D, 0x3C, 0x44, 0x41, 0xAC, 0xB7, 0x29, 0x38, + 0x81, 0x55, 0x20, 0x7A, 0xA0, 0xCF, 0xE0, 0xE6, + 0x75, 0xC9, 0x14, 0x3B, 0x3D, 0xA5, 0xE6, 0x78, + 0xDD, 0xA1, 0x43, 0x29, 0x8E, 0x74, 0x3F, 0xFD, + 0x27, 0xA9, 0xCE, 0x82, 0xF3, 0xA9, 0x7D, 0xE0, + 0xAE, 0xD3, 0xB8, 0x84, 0xB8, 0xAB, 0x49, 0x34, + 0x8D, 0x4A, 0xEB, 0x7D, 0xBD, 0x55, 0x02, 0x61, + 0x42, 0x57, 0x4F, 0x22, 0x55, 0x31, 0x57, 0x18, + 0x7F, 0x08, 0x49, 0x0D, 0xEB, 0x6E, 0x46, 0x44, + 0x87, 0x5A, 0x52, 0xC4, 0xDC, 0x7C, 0xE3, 0x70, + 0x49, 0xBF, 0x62, 0x8A, 0xBD, 0xC9, 0x2C, 0x45, + 0xF1, 0x5E, 0x43, 0x33, 0xF2, 0x83, 0x0D, 0x5F, + 0xF8, 0x4C, 0x45, 0xE6, 0x11, 0x55, 0x28, 0x92, + 0xBB, 0x9E, 0x1C, 0xEC, 0x9F, 0x5F, 0x75, 0x5F, + 0xD8, 0x56, 0x7D, 0x8B, 0xE0, 0x8A, 0x97, 0x77, + 0xAA, 0x43, 0x8C, 0x29, 0x77, 0xE1, 0x8E, 0x06, + 0x39, 0xA4, 0x98, 0xD4, 0x74, 0xDA, 0xF8, 0x52, + 0x51, 0xB6, 0x97, 0x1D, 0xBB, 0x31, 0x81, 0x4B, + 0x06, 0x2D, 0x5E, 0x67, 0xEE, 0x0D, 0x58, 0x01, + 0xB6, 0x1A, 0xAE, 0xBA, 0x16, 0xF5, 0x3E, 0x86, + 0xD9, 0x1E, 0x0C, 0xBB, 0x48, 0x5E, 0x56, 0xC4, + 0x94, 0xD1, 0xCB, 0xD7, 0x8B, 0x21, 0xED, 0xE6, + 0x9F, 0x4B, 0x25, 0x42, 0x33, 0x5A, 0xF1, 0x3B, + 0x65, 0x76, 0x2F, 0x24, 0x85, 0x48, 0x75, 0x71, + 0x7B, 0x3E, 0xDF, 0xAF, 0x85, 0x6C, 0x96, 0x01, + 0x21, 0xEF, 0x27, 0x36, 0x0B, 0x7B, 0xE7, 0x28, + 0x36, 0x91, 0x0D, 0x8A, 0xA4, 0xB7, 0xD9, 0x64, + 0x5D, 0x99, 0xAF, 0x43, 0x09, 0xBE, 0xD2, 0xD8, + 0x28, 0xC0, 0x30, 0x1D, 0x0E, 0xF1, 0x53, 0xEB, + 0xF0, 0x77, 0xE7, 0x37, 0x63, 0x22, 0x8B, 0xB1, + 0x67, 0x92, 0x54, 0x30, 0x69, 0x75, 0x23, 0x97, + 0x33, 0x3F, 0xA1, 0xF4, 0x2E, 0x71, 0x67, 0x9F, + 0x2E, 0x91, 0xE3, 0x16, 0x66, 0x09, 0x8B, 0x2C, + 0x72, 0x60, 0xA2, 0xDB, 0x38, 0x1C, 0xF8, 0xE4, + 0x30, 0xDB, 0x1E, 0x95, 0x28, 0x2D, 0x27, 0xB8, + 0xD2, 0xC0, 0x64, 0x9A, 0x5F, 0xD7, 0x5A, 0x71, + 0xD2, 0xF2, 0xAD, 0x58, 0x35, 0x72, 0x55, 0xCF, + 0x2D, 0xD5, 0x9F, 0x39, 0x3D, 0x92, 0x4E, 0x3D, + 0x03, 0x1B, 0x68, 0x4A, 0xC8, 0x12, 0x2C, 0x91, + 0xAA, 0x5C, 0x1D, 0xE7, 0x4C, 0x41, 0x1A, 0x42, + 0xAC, 0xFC, 0x2A, 0x98, 0x18, 0x7D, 0x65, 0xB4, + 0x6B, 0x19, 0x6F, 0x6A, 0x1D, 0x4F, 0xD8, 0x69, + 0x23, 0xF4, 0xF9, 0x40, 0xF4, 0xD1, 0x91, 0xB2, + 0xB6, 0x0F, 0xA4, 0x3F, 0xED, 0x61, 0x4B, 0xEA, + 0xD2, 0x00, 0x49, 0xCB, 0xC5, 0x25, 0x42, 0xCD, + 0x97, 0xC2, 0x93, 0x13, 0x6D, 0x34, 0x7B, 0x22, + 0xFC, 0xB8, 0xC9, 0x5F, 0x4F, 0x0A, 0xB7, 0xE2, + 0x91, 0x4E, 0x4D, 0x55, 0xB3, 0x53, 0x65, 0xB6, + 0xB9, 0xD5, 0x06, 0xB4, 0x01, 0x85, 0x7C, 0x0A, + 0x53, 0x33, 0xA2, 0x0A, 0x65, 0xFC, 0x96, 0xA4, + 0xC5, 0x66, 0xCA, 0xD8, 0x5D, 0x01, 0x1F, 0x5B, + 0xFD, 0x1F, 0x94, 0xF8, 0xAE, 0xD9, 0x36, 0x58, + 0x54, 0x12, 0xB4, 0xD2, 0xAD, 0xCC, 0xC1, 0x4E, + 0x87, 0xF3, 0xB4, 0xDA, 0x20, 0x9F, 0xBA, 0xFF, + 0x0D, 0x44, 0x3B, 0x6C, 0x47, 0x01, 0xF3, 0x60, + 0x54, 0x6F, 0xCF, 0x8A, 0x7F, 0xF7, 0xE4, 0x2E, + 0x15, 0xB6, 0x80, 0xE1, 0x03, 0x5A, 0x0B, 0x91, + 0xC6, 0x90, 0x05, 0x6A, 0xCD, 0x06, 0xCA, 0x1C, + 0x02, 0xC3, 0x51, 0x12, 0x06, 0x8F, 0xB8, 0x1C, + 0xA7, 0xA2, 0xB0, 0xEC, 0x92, 0x82, 0x8A, 0x50, + 0x2E, 0xB5, 0x8A, 0x99, 0x70, 0x2F, 0x47, 0xFF, + 0x0D, 0xCD, 0x60, 0x53, 0x65, 0x56, 0x6F, 0x43, + 0xCB, 0x6E, 0x0C, 0xCC, 0xB4, 0x2A, 0xE0, 0x45, + 0x65, 0x24, 0x5C, 0x3B, 0x00, 0xB2, 0x9F, 0x41, + 0x3E, 0x4A, 0xCE, 0xBD, 0x41, 0x85, 0xB9, 0x90, + 0x35, 0x53, 0xEE, 0x6B, 0x32, 0x73, 0x45, 0xAD, + 0xFB, 0x4B, 0xA7, 0xFD, 0xA4, 0xCC, 0xFF, 0xF2, + 0xAB, 0xD6, 0x45, 0x9C, 0x7A, 0x30, 0x73, 0x9A, + 0x32, 0x54, 0xE7, 0x9E, 0xA5, 0xFB, 0x7B, 0x1D, + 0x19, 0x77, 0xE7, 0xBF, 0xC8, 0x3B, 0x6D, 0x3E, + 0xBA, 0x90, 0x1A, 0xA4, 0x27, 0xBD, 0x7B, 0x4B, + 0x91, 0xC0, 0xFF, 0x9D, 0x83, 0xAE, 0x71, 0xC6, + 0x2E, 0x34, 0xEA, 0xBA, 0x3E, 0x23, 0x2A, 0x1E, + 0xED, 0x62, 0x52, 0x31, 0x70, 0x45, 0x0C, 0xFB, + 0xC0, 0xEE, 0xA4, 0xA9, 0x30, 0x7D, 0xCE, 0x2A, + 0xD6, 0x1D, 0xBE, 0x01, 0xF1, 0x8F, 0xF7, 0x3E, + 0x19, 0x30, 0x00, 0x33, 0xFA, 0xC8, 0x04, 0xFA, + 0xCB, 0xB3, 0x59, 0x34, 0xB2, 0x83, 0x17, 0xAE, + 0x2A, 0xD9, 0xEC, 0xD2, 0x6E, 0xD8, 0x0B, 0x68, + 0x7D, 0x36, 0x2D, 0x30, 0x31, 0x75, 0xEA, 0x7B, + 0x76, 0x13, 0x24, 0xC1, 0x59, 0x5F, 0xFA, 0x89, + 0x16, 0xF1, 0x1A, 0xC1, 0xCC, 0xED, 0xBD, 0xE0, + 0x56, 0x70, 0xBA, 0x4F, 0x49, 0x80, 0x35, 0x18, + 0x6F, 0x23, 0x4C, 0x7C, 0x3E, 0xEA, 0x00, 0x68, + 0xD3, 0xF4, 0xA6, 0x09, 0x76, 0x70, 0x62, 0x4E, + 0xB6, 0xDB, 0x83, 0xA6, 0x54, 0x0E, 0x28, 0x5D, + 0xE7, 0x15, 0x87, 0x49, 0xE2, 0xA4, 0x3A, 0x00, + 0x3D, 0x72, 0x94, 0x3E, 0xC0, 0x8E, 0xAE, 0x27, + 0xC9, 0x7A, 0xF0, 0x4A, 0xEE, 0xFB, 0xC3, 0x72, + 0xEF, 0x42, 0x15, 0x0F, 0xA2, 0x9B, 0xB0, 0xFF, + 0xE5, 0x61, 0xD5, 0x15, 0x17, 0xA1, 0xFB, 0x59, + 0x62, 0x34, 0x59, 0x76, 0xCA, 0xCD, 0xDD, 0xB0, + 0x6B, 0x54, 0x7C, 0xCD, 0xAB, 0xFE, 0xF4, 0x52, + 0x67, 0xE1, 0x20, 0xE2, 0x33, 0x3D, 0x7A, 0xD9, + 0x63, 0xE9, 0x92, 0x5D, 0x05, 0xC5, 0x44, 0x2C, + 0xE2, 0x92, 0x70, 0xE8, 0xF3, 0x7E, 0xB6, 0x11, + 0x75, 0x8D, 0x42, 0x01, 0xD3, 0xD8, 0x5A, 0xCE, + 0xF8, 0xE1, 0xFC, 0x49, 0x8B, 0x15, 0x20, 0xA9, + 0xE5, 0x27, 0x5D, 0x73, 0xC0, 0xD7, 0x73, 0xB2, + 0xF9, 0xF6, 0x23, 0x93, 0x35, 0xF6, 0x64, 0x3F, + 0xBB, 0xE4, 0x65, 0x46, 0x0C, 0xAB, 0x8D, 0xDE, + 0x0A, 0x17, 0xBA, 0x94, 0x87, 0xB3, 0x52, 0xE9, + 0x1E, 0xBF, 0x6B, 0x04, 0x64, 0x67, 0x63, 0x86, + 0x72, 0x1A, 0x97, 0xF3, 0xBD, 0xEF, 0x68, 0x77, + 0xE8, 0x3C, 0x68, 0xCB, 0x3B, 0x06, 0xF3, 0x54, + 0x4F, 0x6C, 0x1A, 0xC4, 0xC3, 0x0A, 0xDE, 0xEA, + 0x8C, 0x7E, 0x65, 0xFA, 0x25, 0x3E, 0x65, 0xF0, + 0xA4, 0x92, 0xCD, 0x69, 0xA4, 0xE9, 0xB8, 0x20, + 0x00, 0xE4, 0xF7, 0x80, 0x64, 0x75, 0xA1, 0xD2, + 0x32, 0xA4, 0x5E, 0xC3, 0xE1, 0x20, 0x34, 0x5B, + 0x49, 0xB8, 0x59, 0x2E, 0xE8, 0x51, 0xC7, 0x5A, + 0xB8, 0x9E, 0x2C, 0x3D, 0x8F, 0xC0, 0x46, 0x23, + 0x4E, 0x8A, 0x1B, 0xEB, 0x04, 0xCF, 0xFF, 0x77, + 0x98, 0x5E, 0x0D, 0xFA, 0x27, 0x4A, 0x11, 0x15, + 0x67, 0x7E, 0x63, 0x94, 0x30, 0x71, 0x15, 0x18, + 0xAE, 0x64, 0x9B, 0x44, 0x66, 0xA2, 0x24, 0x72, + 0x7C, 0x3A, 0x74, 0xC4, 0x50, 0x0F, 0x50, 0x4E, + 0x39, 0x04, 0x4D, 0x8C, 0x72, 0x75, 0x9B, 0x18, + 0x48, 0xE6, 0x04, 0x01, 0xD6, 0xDF, 0xE0, 0x64, + 0x38, 0x90, 0x88, 0xA2, 0x9F, 0x7B, 0x7B, 0x7F, + 0xEF, 0xD9, 0xDB, 0xF5, 0x4C, 0x70, 0xDC, 0xAF, + 0x38, 0x45, 0x59, 0x14, 0x53, 0x1C, 0xDD, 0x4E, + 0xAF, 0x9D, 0x3A, 0x61, 0xFC, 0xBC, 0x82, 0x88, + 0xC2, 0x43, 0x16, 0x5F, 0x53, 0xCE, 0x27, 0xE6, + 0x61, 0xD6, 0x4D, 0x40, 0x86, 0xD0, 0x2A, 0x99, + 0x60, 0xAA, 0x0D, 0x4E, 0x5A, 0x17, 0x75, 0xD3, + 0xD0, 0xCD, 0x05, 0x10, 0x07, 0xB0, 0xE3, 0x28, + 0xD8, 0x02, 0xBF, 0x0B, 0x0B, 0x7B, 0x8C, 0x74, + 0xCA, 0x38, 0x90, 0x62, 0x97, 0x25, 0x3C, 0x9C, + 0x72, 0x8D, 0xDA, 0xC6, 0xC7, 0xAA, 0xC9, 0xB4, + 0x29, 0x4B, 0xE5, 0xCD, 0x59, 0x62, 0x1B, 0x3C, + 0x5C, 0x5D, 0xB4, 0x32, 0x03, 0x12, 0x19, 0x26, + 0xC4, 0x90, 0xFB, 0xB4, 0xA7, 0x41, 0xD1, 0x03, + 0x4D, 0x2C, 0x60, 0x62, 0xE2, 0x15, 0x8D, 0xDD, + 0x4E, 0x48, 0x43, 0x46, 0x23, 0x55, 0xBE, 0x92, + 0x87, 0xAD, 0x16, 0x7B, 0xC6, 0x5C, 0xA0, 0xE2, + 0xE9, 0x18, 0x10, 0xB4, 0x2F, 0x92, 0xE5, 0xDA, + 0xC0, 0xA8, 0x29, 0x08, 0x22, 0x40, 0x34, 0x61, + 0x69, 0x84, 0xB3, 0x75, 0xFD, 0xAC, 0xEC, 0x81, + 0xA8, 0x2A, 0x20, 0x6C, 0xE7, 0x91, 0xA0, 0x22, + 0xC0, 0x62, 0xB2, 0xAE, 0x7C, 0x01, 0x1E, 0xFB, + 0x20, 0x7A, 0x61, 0x40, 0x71, 0x44, 0xC5, 0xA9, + 0xEB, 0x9C, 0x42, 0xF2, 0xC1, 0x4D, 0x93, 0xC7, + 0x1C, 0xA8, 0x65, 0x03, 0xD4, 0x04, 0x58, 0x57, + 0xDC, 0xF6, 0x2B, 0x10, 0x28, 0xF3, 0x80, 0x6D, + 0x89, 0xEC, 0x9D, 0xDB, 0x21, 0x87, 0x65, 0xD6, + 0x13, 0xD1, 0x8D, 0xF4, 0x0A, 0x29, 0x25, 0x75, + 0xCC, 0xE1, 0x2F, 0x96, 0xD4, 0xD0, 0x2C, 0x6C, + 0x25, 0x0F, 0x65, 0x8F, 0xFB, 0x62, 0x82, 0x22, + 0x0D, 0x69, 0xEE, 0x12, 0xA5, 0x76, 0x43, 0x56, + 0xCA, 0x47, 0xAA, 0xDD, 0x04, 0x17, 0xBF, 0x3F, + 0x76, 0xE6, 0xF9, 0x77, 0xA6, 0xFA, 0x46, 0x09, + 0x41, 0xEB, 0x03, 0x72, 0xB9, 0xF3, 0x87, 0xA5, + 0xA7, 0xEA, 0x74, 0xBE, 0x49, 0xD9, 0xCA, 0x01, + 0x19, 0x34, 0x77, 0x88, 0x4F, 0x5B, 0xA8, 0x4C, + 0xF5, 0xF2, 0x75, 0xE0, 0xD2, 0x05, 0xF1, 0x00, + 0xC7, 0xAA, 0x8D, 0x5C, 0x09, 0xEE, 0xEF, 0xAA, + 0xEC, 0x82, 0x3E, 0x4F, 0xCE, 0x95, 0x39, 0x8C, + 0xCD, 0x36, 0x83, 0xD0, 0x8B, 0x30, 0x87, 0xED, + 0x1E, 0x97, 0x6D, 0x72, 0x38, 0xD5, 0x30, 0x8F, + 0x84, 0xDF, 0xF3, 0x9C, 0xB1, 0x94, 0x8E, 0x92, + 0xD6, 0xB8, 0xBD, 0x25, 0x57, 0x45, 0x42, 0x21, + 0x66, 0xAF, 0xBB, 0xF2, 0xE0, 0x46, 0x02, 0x73, + 0x97, 0x9C, 0x62, 0x7C, 0x7F, 0xA9, 0x79, 0x86, + 0xD9, 0x9C, 0x64, 0xF0, 0x45, 0xC8, 0x23, 0x9A, + 0xB5, 0x1B, 0xB9, 0xCD, 0x98, 0x21, 0x5F, 0x36, + 0x16, 0x70, 0x94, 0x75, 0xAB, 0x3C, 0x4C, 0xCC, + 0x42, 0xBB, 0xC6, 0xEF, 0x45, 0x7E, 0x84, 0xE5, + 0x35, 0x87, 0xD3, 0x12, 0x36, 0xA4, 0x85, 0xD0, + 0x5F, 0x89, 0xE5, 0xDA, 0xA8, 0xCC, 0xD1, 0xC5, + 0xC3, 0x1B, 0xB3, 0x12, 0x96, 0x9A, 0x2D, 0x92, + 0x10, 0xD1, 0x3B, 0x7F, 0x54, 0xA3, 0xAE, 0x78, + 0xA6, 0x5B, 0x07, 0x4D, 0x06, 0xEC, 0xB4, 0x56, + 0x12, 0x9D, 0xA0, 0x3C, 0x31, 0x51, 0x2A, 0x4A, + 0xA9, 0x46, 0xBF, 0x08, 0xBE, 0xF0, 0x03, 0x71, + 0xD3, 0xAA, 0xE2, 0x57, 0xC7, 0x05, 0xA8, 0x5E, + 0x1B, 0x9E, 0xF4, 0x35, 0x69, 0xF0, 0xEC, 0x31, + 0x41, 0xCD, 0xB8, 0x7B, 0xA5, 0xF5, 0x63, 0x48, + 0x60, 0x70, 0x6C, 0x33, 0x2E, 0x60, 0xAF, 0x41, + 0xFE, 0x87, 0xFA, 0x80, 0xF7, 0x0F, 0x78, 0x80, + 0x74, 0xBB, 0x6A, 0xAC, 0x64, 0x7E, 0x9F, 0x65, + 0x70, 0x11, 0xB6, 0xEA, 0x83, 0x3B, 0x9E, 0xE1, + 0xB6, 0xE3, 0x7F, 0x6D, 0xC1, 0x7E, 0xBA, 0x16, + 0xE5, 0xA2, 0x9E, 0x8A, 0x67, 0x46, 0x90, 0xE6, + 0x00, 0x79, 0x5F, 0x9A, 0x6F, 0xEA, 0x22, 0xB8, + 0x68, 0xC4, 0xB5, 0x22, 0x94, 0x60, 0xE8, 0x49, + 0x22, 0x9F, 0x23, 0xDE, 0x14, 0x63, 0xB2, 0x92, + 0xA7, 0xC2, 0x6C, 0xCF, 0x1D, 0xA8, 0x87, 0x68, + 0x50, 0xD3, 0x59, 0xC5, 0xA9, 0xEF, 0xD1, 0x16, + 0xCB, 0x0A, 0xC9, 0x4C, 0x61, 0x8A, 0xCC, 0xAF, + 0x85, 0x5A, 0x64, 0x78, 0x4F, 0x15, 0x2C, 0xFD, + 0xAC, 0x63, 0x9D, 0x92, 0x80, 0x6E, 0xA6, 0x7B, + 0xD5, 0x40, 0x3A, 0xD9, 0x1A, 0x94, 0x6C, 0x6A, + 0xDD, 0xA1, 0xD1, 0xC2, 0xA5, 0x07, 0xBB, 0x31, + 0xED, 0xFF, 0xCB, 0x88, 0x21, 0x94, 0x0D, 0x78, + 0x1D, 0x7C, 0xB8, 0xDD, 0xEA, 0x0B, 0x9C, 0x47, + 0xC1, 0xEB, 0xC9, 0x55, 0x3F, 0xBB, 0x2C, 0xFF, + 0x10, 0xD4, 0xF0, 0x80, 0xB9, 0x06, 0xA7, 0x5C, + 0x43, 0x5F, 0xB8, 0xDB, 0x88, 0x0D, 0x01, 0xF9, + 0xEC, 0x18, 0xDD, 0x2D, 0x37, 0x00, 0x95, 0x38, + 0xDD, 0x92, 0x0A, 0x56, 0xC4, 0x9E, 0xE8, 0x20, + 0xDF, 0xEC, 0xB3, 0x64, 0x79, 0x7D, 0x5D, 0xCD, + 0x45, 0x72, 0xC9, 0x52, 0x17, 0xFB, 0x29, 0xC1, + 0xF4, 0xB1, 0x89, 0x38, 0x97, 0x60, 0xBD, 0x5D, + 0xBF, 0x5D, 0x71, 0x53, 0x10, 0xB1, 0x7B, 0xEB, + 0xEF, 0xEE, 0xCF, 0x76, 0x5E, 0x66, 0xC0, 0x5D, + 0xD5, 0xC3, 0xB2, 0x02, 0x9F, 0x7F, 0xA4, 0xE7, + 0x57, 0x9E, 0xD9, 0xD3, 0xA6, 0x51, 0x03, 0xF1, + 0xE1, 0xB3, 0x59, 0x03, 0xE2, 0x30, 0x82, 0xAA, + 0xC3, 0x7A, 0xF8, 0x04, 0xFA, 0xE1, 0xF5, 0x8B, + 0x0B, 0x93, 0x5C, 0xD3, 0x2D, 0x83, 0x0A, 0x8E, + 0x8A, 0x9D, 0x35, 0xBA, 0xF3, 0x49, 0x5A, 0x7A, + 0x4F, 0x05, 0xB3, 0xF8, 0x3D, 0xF6, 0x37, 0x36, + 0x62, 0xD5, 0x48, 0x15, 0xFA, 0x6D, 0x00, 0xB9, + 0x49, 0xE3, 0x70, 0x95, 0x3C, 0xF7, 0x56, 0xF6, + 0xE2, 0xB7, 0x49, 0xDD, 0x3A, 0x94, 0x71, 0xC4, + 0x40, 0x1E, 0x9F, 0x74, 0xC9, 0x84, 0xE0, 0x2F, + 0x17, 0x2A, 0x6C, 0xD9, 0x9A, 0x17, 0x39, 0x7E, + 0x09, 0xC8, 0x22, 0x16, 0x63, 0x3B, 0x5A, 0xB5, + 0x24, 0xB0, 0xE4, 0xA5, 0xB2, 0x90, 0x70, 0xB0, + 0xEC, 0xB6, 0xB3, 0xFF, 0x18, 0x70, 0xF6, 0x07, + 0xFA, 0xCA, 0x9A, 0x15, 0x3D, 0x62, 0xB9, 0x5F, + 0x50, 0xD7, 0x3B, 0xA8, 0x19, 0xD2, 0xA1, 0x07, + 0x11, 0xC7, 0x9F, 0x92, 0xEA, 0x9B, 0xAD, 0xB3, + 0x32, 0xCE, 0xB7, 0xF3, 0xE2, 0x1D, 0x92, 0x83, + 0xCC, 0xD1, 0x73, 0x03, 0x19, 0xA5, 0x51, 0x08, + 0xE8, 0x2B, 0x74, 0x00, 0x87, 0xD2, 0x39, 0x0A, + 0x46, 0x9C, 0xE7, 0x7F, 0x24, 0x71, 0x51, 0x61, + 0x9D, 0x1B, 0x9F, 0x1E, 0xB3, 0x29, 0x8E, 0x26, + 0x25, 0x7B, 0x46, 0xD9, 0xA8, 0x43, 0x2A, 0x21, + 0xCE, 0x2F, 0x93, 0x3C, 0xC0, 0x32, 0x9D, 0x7B, + 0xE3, 0x93, 0xE4, 0xE1, 0xD8, 0x5E, 0x31, 0x74, + 0xBB, 0x08, 0x4D, 0x78, 0x1D, 0x5A, 0x87, 0x1D, + 0xDC, 0x4A, 0xBD, 0x05, 0xD4, 0x42, 0x3A, 0x05, + 0x02, 0xA9, 0x70, 0xD0, 0x49, 0x18, 0x26, 0xCD, + 0xDA, 0xAC, 0x9C, 0x97, 0xEA, 0xDD, 0x72, 0x9D, + 0x61, 0x4E, 0xB6, 0xE4, 0x9B, 0xE0, 0xE5, 0xB1, + 0x11, 0xE3, 0x2F, 0x26, 0xC1, 0x91, 0xE4, 0x6B, + 0x92, 0xAE, 0x8E, 0xE1, 0xF2, 0x76, 0x35, 0x1D, + 0x90, 0x3B, 0x0B, 0x22, 0x15, 0x39, 0x19, 0xF4, + 0x89, 0x6E, 0xAB, 0xA7, 0xC6, 0xB5, 0xBB, 0x86, + 0x40, 0x0D, 0x88, 0xE2, 0x2A, 0x31, 0xA5, 0xC3, + 0x1C, 0x22, 0x4C, 0x01, 0x4F, 0xAD, 0xDD, 0xC0, + 0xBD, 0x03, 0x5A, 0xB1, 0xC3, 0x93, 0xDF, 0xE9, + 0x75, 0xCA, 0xB1, 0xBF, 0xC9, 0x58, 0xC8, 0x53, + 0x41, 0x6E, 0x12, 0xAC, 0x6A, 0xD4, 0x00, 0x94, + 0xFF, 0xB2, 0x66, 0xDA, 0x98, 0xB4, 0xEF, 0x6D, + 0x58, 0x85, 0xB9, 0xE2, 0x11, 0x80, 0xB4, 0xBA, + 0x82, 0x1F, 0x4D, 0x7D, 0x23, 0x35, 0xE3, 0x70, + 0x0F, 0xF1, 0xBF, 0x5D, 0x05, 0xBF, 0xCB, 0xDF, + 0x3B, 0x32, 0x02, 0xAA, 0x35, 0xFA, 0x72, 0xC1, + 0x5D, 0x71, 0x6C, 0xE5, 0x77, 0xAA, 0x44, 0x26, + 0xF1, 0x73, 0xF4, 0x47, 0x3D, 0xB5, 0x5B, 0xED, + 0xEF, 0x00, 0x21, 0x3A, 0x72, 0x7A, 0x17, 0x10, + 0xE0, 0xE6, 0x7D, 0xB9, 0x4B, 0x8E, 0xA2, 0x75, + 0xB4, 0xD6, 0x13, 0xE3, 0xB8, 0xB5, 0x76, 0x8F, + 0xB4, 0xC6, 0xEE, 0xB6, 0x30, 0x72, 0x27, 0xA9, + 0x6B, 0x36, 0x93, 0x2D, 0x8D, 0x19, 0xB0, 0xFE, + 0x3D, 0x2F, 0x5C, 0xE9, 0xAC, 0x23, 0x4E, 0xA1, + 0xE7, 0xA1, 0x5F, 0x52, 0xAB, 0x2A, 0xA2, 0x81, + 0x4F, 0x42, 0xA6, 0x8D, 0x0E, 0xA6, 0x99, 0x21, + 0xBA, 0xD6, 0xF8, 0x79, 0x14, 0x65, 0x23, 0x90, + 0xE7, 0x11, 0xD9, 0xC7, 0xE7, 0x39, 0x22, 0x4A, + 0x2E, 0xD6, 0xA7, 0xAA, 0x60, 0x21, 0x3F, 0xDF, + 0x30, 0x09, 0x87, 0x5F, 0x79, 0x3D, 0x04, 0x99, + 0x36, 0x1E, 0xCF, 0xDB, 0x79, 0xF3, 0xA4, 0xBC, + 0xD7, 0x5F, 0x2E, 0x3D, 0x84, 0x74, 0x2C, 0x70, + 0xB5, 0xF5, 0xE8, 0xF4, 0x80, 0x6F, 0xB5, 0x4B, + 0xFB, 0xB7, 0xC9, 0x0E, 0xF2, 0xC5, 0x1B, 0xB4, + 0x41, 0x48, 0xFE, 0x33, 0xC1, 0xC6, 0xBA, 0x64, + 0x9A, 0x35, 0xDF, 0x20, 0x5E, 0x5B, 0x4C, 0xCD, + 0xE3, 0xA3, 0x43, 0xA6, 0x87, 0x86, 0x9B, 0xB4, + 0x69, 0x8C, 0xB4, 0xFA, 0x2E, 0xB2, 0xFA, 0x67, + 0xDE, 0xF4, 0xF4, 0x15, 0x42, 0x74, 0xBB, 0xEF, + 0xAE, 0x65, 0x7F, 0x1D, 0x14, 0xA6, 0x66, 0x8A, + 0xEA, 0xB6, 0xDE, 0x02, 0x98, 0x70, 0x34, 0x40, + 0x09, 0xF2, 0xB8, 0x6B, 0xA9, 0x5E, 0xC1, 0x0C, + 0x39, 0x94, 0xB2, 0x21, 0xA4, 0x7F, 0x80, 0xF5, + 0xF7, 0xE5, 0x9C, 0x6D, 0xCE, 0x4E, 0x59, 0x76, + 0x0E, 0x20, 0xBB, 0x04, 0x41, 0xD2, 0xEB, 0x91, + 0x19, 0x14, 0x43, 0xF0, 0xE8, 0xD4, 0xC3, 0x76, + 0x49, 0x7D, 0xE4, 0x52, 0xF1, 0x8F, 0x2F, 0x90, + 0x64, 0xCA, 0x84, 0x89, 0xC1, 0x6D, 0x50, 0x7C, + 0x24, 0x07, 0x6A, 0x44, 0x23, 0x6E, 0x46, 0x56, + 0x63, 0x47, 0x6D, 0xAC, 0x12, 0x94, 0xD2, 0xCC, + 0x70, 0x95, 0x23, 0x88, 0xA0, 0xB4, 0x4D, 0x2F, + 0xC5, 0x44, 0x58, 0x67, 0x59, 0x8C, 0xFA, 0x94, + 0x4C, 0xCE, 0xD5, 0x0F, 0x6F, 0xE2, 0x37, 0x92, + 0xEF, 0x8E, 0xA9, 0x5F, 0xB7, 0x8C, 0x47, 0x2D, + 0xD3, 0xBD, 0x88, 0x73, 0xEF, 0xF7, 0x6D, 0xA7, + 0xE0, 0xBE, 0xC7, 0xE8, 0x6A, 0x70, 0x95, 0xD4, + 0x03, 0x0D, 0x72, 0x4A, 0x47, 0xD7, 0x52, 0x92, + 0xE2, 0x12, 0xB3, 0xE9, 0xDA, 0x3A, 0x73, 0xCD, + 0x2C, 0xD2, 0x68, 0x69, 0x7C, 0x03, 0x36, 0xDB, + 0x5E, 0x9D, 0x9B, 0xEB, 0x2C, 0xCB, 0xE0, 0x0C, + 0x2C, 0x3D, 0xB8, 0xBD, 0x2C, 0x22, 0xD5, 0x0A, + 0x97, 0xF2, 0x7E, 0x35, 0xB7, 0xC7, 0xC3, 0x93, + 0xBC, 0x73, 0xF2, 0x19, 0x07, 0xE8, 0xE6, 0x9B, + 0x0C, 0x15, 0x44, 0xC1, 0xDB, 0x4C, 0x4A, 0xA8, + 0x36, 0x92, 0x3A, 0xD2, 0xED, 0xD7, 0xE4, 0x2B, + 0x49, 0x46, 0x49, 0x89, 0x4C, 0x7F, 0x93, 0xEE, + 0x47, 0x5F, 0x04, 0x36, 0x2D, 0x0A, 0x34, 0xD8, + 0x7C, 0xB3, 0xC6, 0xE6, 0x0F, 0x22, 0xD8, 0x6C, + 0x45, 0xA9, 0x0E, 0x13, 0x24, 0x1D, 0xB4, 0xE9, + 0xB8, 0x3E, 0x28, 0x4F, 0xCC, 0x16, 0xC1, 0x71, + 0xBD, 0x29, 0xA6, 0x00, 0xF7, 0x3B, 0x3D, 0xB4, + 0xA9, 0xD7, 0x1E, 0x2B, 0x66, 0x28, 0x10, 0xBD, + 0xFA, 0x00, 0xA9, 0x98, 0x7D, 0x34, 0x82, 0xBD, + 0x04, 0xD2, 0x79, 0x86, 0x37, 0x0A, 0x97, 0x98, + 0x9A, 0x16, 0xF1, 0xE3, 0xE2, 0x54, 0x68, 0x88, + 0xC6, 0x60, 0x05, 0xED, 0x21, 0x11, 0x32, 0xC4, + 0x83, 0xD1, 0x9A, 0x27, 0xA2, 0xE0, 0x9E, 0x76, + 0x6A, 0xE6, 0x50, 0x6D, 0xE8, 0xE6, 0xB2, 0xA7, + 0xD1, 0x73, 0xBB, 0x4A, 0xFD, 0x53, 0x8F, 0xA4, + 0x3F, 0x87, 0x59, 0xB8, 0x51, 0xA3, 0xF7, 0xD7, + 0xB8, 0x86, 0xB9, 0x30, 0xCF, 0xE2, 0xEB, 0x8A, + 0xAF, 0x74, 0xEB, 0x8F, 0x50, 0xB0, 0xA7, 0xCD, + 0x31, 0xF0, 0x16, 0x8D, 0x00, 0x25, 0x05, 0xE4, + 0x35, 0x3C, 0x79, 0xE3, 0x2F, 0xA6, 0x4C, 0x5A, + 0xD5, 0xE4, 0x05, 0x3A, 0xB3, 0x5B, 0x77, 0x73, + 0x32, 0x31, 0x16, 0x6E, 0x43, 0x28, 0x58, 0xF8, + 0xEB, 0x02, 0xE3, 0xBF, 0xFD, 0x85, 0x6C, 0xAC, + 0x14, 0x5B, 0x73, 0x7A, 0x57, 0x57, 0x60, 0x2B, + 0xEC, 0xA7, 0x8C, 0xC3, 0xA9, 0x8D, 0xD8, 0x80, + 0x78, 0x56, 0x90, 0xB8, 0x7F, 0x42, 0xD1, 0xBD, + 0xAB, 0x17, 0xC5, 0x66, 0x3F, 0xED, 0xB4, 0xB9, + 0x5B, 0xB6, 0x23, 0xFA, 0xCA, 0x83, 0xE1, 0x7F, + 0x0C, 0xD4, 0xE3, 0x19, 0xCF, 0x38, 0x88, 0x00, + 0xC3, 0x1D, 0x92, 0x10, 0xC7, 0x43, 0x50, 0xC7, + 0x29, 0x31, 0x04, 0x4B, 0xB4, 0x93, 0x68, 0x66, + 0x84, 0x46, 0x56, 0xDB, 0x80, 0x87, 0x1F, 0xE0, + 0x33, 0xF2, 0x3E, 0x7B, 0x43, 0x07, 0x8F, 0x68, + 0x3A, 0x8E, 0x95, 0x3B, 0x8B, 0xE8, 0xC2, 0x50, + 0xD4, 0x8C, 0x33, 0x3C, 0x64, 0xCC, 0x4F, 0x2F, + 0xE2, 0x91, 0x36, 0xDB, 0xEE, 0xA1, 0x54, 0xB4, + 0x89, 0x3F, 0xBC, 0xB2, 0xF4, 0xA6, 0x13, 0x63, + 0xA5, 0xFF, 0x71, 0xAE, 0x7E, 0x29, 0x41, 0xD9, + 0x12, 0x24, 0xDB, 0xEB, 0xD3, 0x6B, 0x4B, 0x7F, + 0x6B, 0x6C, 0x78, 0x8E, 0x5E, 0x34, 0x7D, 0x9E, + 0x10, 0xEA, 0xD4, 0x2A, 0x9A, 0xC3, 0xAF, 0x14, + 0x87, 0xFC, 0x4B, 0x00, 0x7F, 0x1D, 0x68, 0x90, + 0xCA, 0x01, 0xA8, 0x48, 0x87, 0xA0, 0x7D, 0x4E, + 0xFB, 0xF8, 0x70, 0xAB, 0x3F, 0x82, 0x53, 0x28, + 0xE4, 0x17, 0x48, 0xEA, 0xFB, 0xBC, 0x4E, 0x7D, + 0x45, 0x83, 0x85, 0x0D, 0x16, 0x32, 0x93, 0x36, + 0x78, 0xE2, 0x73, 0x07, 0x81, 0xEF, 0x98, 0x26, + 0x7A, 0xED, 0x85, 0x4D, 0x00, 0x04, 0xC6, 0xF4, + 0xAD, 0x5D, 0x86, 0xA8, 0xBC, 0x71, 0x5D, 0x63, + 0x86, 0x1E, 0x2F, 0x89, 0x8E, 0xE0, 0x7D, 0xCF, + 0xD1, 0x79, 0xA1, 0x81, 0x00, 0x18, 0xDD, 0x72, + 0xCA, 0xDA, 0x2A, 0x90, 0x60, 0xD2, 0x3D, 0x1A, + 0x44, 0xB0, 0x74, 0x97, 0xAD, 0x71, 0x3C, 0x70, + 0xAD, 0x26, 0xB3, 0x4F, 0x1F, 0xE9, 0x90, 0x99, + 0xBD, 0x4B, 0x3C, 0xD6, 0xD9, 0x9A, 0xC0, 0x8B, + 0x45, 0xB2, 0x07, 0x71, 0xFA, 0xAE, 0x5C, 0x21, + 0x10, 0xBB, 0xFB, 0x2E, 0x6F, 0xDE, 0x78, 0xF1, + 0x6E, 0x84, 0x60, 0x52, 0x9E, 0xC4, 0xBC, 0x0A, + 0x20, 0xB3, 0xD1, 0xE6, 0xD2, 0x13, 0x5B, 0xCF, + 0xF6, 0x51, 0x7C, 0x41, 0x07, 0xA9, 0xBE, 0xB6, + 0x2B, 0xD2, 0x05, 0x24, 0xCC, 0xDA, 0xAD, 0xA2, + 0x94, 0xA6, 0x0A, 0xF5, 0xA9, 0x97, 0x95, 0xA5, + 0xBB, 0x6C, 0x50, 0x85, 0x94, 0x88, 0xB0, 0x15, + 0xB1, 0xB3, 0x9C, 0xC3, 0x2D, 0x97, 0x08, 0xDF, + 0x37, 0x66, 0x81, 0xBE, 0x9C, 0x85, 0xBC, 0x1C, + 0xA8, 0xE3, 0xAA, 0xA0, 0x5B, 0x61, 0xF0, 0x79, + 0x5E, 0xFE, 0xCD, 0xBE, 0x59, 0x8A, 0xAA, 0x4E, + 0xBD, 0x4D, 0x53, 0xBD, 0xB2, 0x8E, 0x51, 0xEE, + 0xBA, 0xC2, 0xA4, 0x8D, 0xBA, 0xC3, 0xA1, 0xC8, + 0x74, 0x29, 0x7E, 0x8E, 0x11, 0x4E, 0x2D, 0xF8, + 0x7C, 0xCB, 0xE9, 0x9A, 0x5A, 0x4A, 0x8B, 0xCF, + 0xD2, 0x85, 0xA3, 0xD9, 0x99, 0xC5, 0x20, 0x60, + 0xF9, 0x87, 0xCC, 0x31, 0xB7, 0x73, 0x51, 0xEA, + 0xE3, 0x7E, 0xEB, 0xFF, 0xAA, 0x52, 0xA9, 0xE2, + 0xE1, 0x26, 0xC8, 0x45, 0xFC, 0x66, 0x01, 0x25, + 0xF4, 0x27, 0xA4, 0x16, 0xCF, 0x62, 0x15, 0x83, + 0xF6, 0xA8, 0x46, 0xB9, 0xA1, 0x57, 0x3A, 0xC3, + 0x45, 0x8B, 0x71, 0x89, 0x85, 0x4F, 0x71, 0x22, + 0x54, 0xB2, 0x46, 0x38, 0x5D, 0x85, 0xE4, 0x7E, + 0x0D, 0x37, 0x2D, 0x60, 0x35, 0x45, 0xE5, 0x31, + 0x8F, 0x18, 0x53, 0xF7, 0x0C, 0x1C, 0x09, 0xD4, + 0xCC, 0x6A, 0xAD, 0x89, 0x66, 0x4D, 0xB1, 0x0E, + 0xD0, 0x2A, 0x5D, 0x7B, 0x6E, 0xF7, 0xD8, 0x10, + 0xB1, 0x7B, 0xAE, 0x8E, 0xD5, 0xB2, 0xBD, 0x80, + 0xBE, 0x34, 0x02, 0x39, 0xDA, 0xCA, 0xFC, 0x60, + 0x89, 0x3F, 0x44, 0x11, 0x99, 0x76, 0xFD, 0x0D, + 0x52, 0xBB, 0x39, 0x19, 0x66, 0xBC, 0x64, 0xDB, + 0x51, 0xB3, 0x4B, 0xD7, 0x68, 0xCA, 0xE4, 0x65, + 0xDF, 0x0E, 0x3F, 0x2B, 0x26, 0x4A, 0xB3, 0x45, + 0x79, 0x77, 0xAC, 0x43, 0x68, 0x40, 0x4F, 0x8F, + 0x2F, 0xA8, 0x2D, 0xDE, 0x2A, 0x9D, 0x5E, 0xE3, + 0x01, 0x87, 0x2B, 0x40, 0xB0, 0x35, 0x2C, 0x0A, + 0x14, 0x19, 0x8E, 0x85, 0x24, 0x35, 0xD7, 0x2C, + 0x5D, 0x59, 0xC2, 0xF0, 0xCE, 0xCE, 0xCD, 0x07, + 0xD8, 0x9B, 0x96, 0xEF, 0x32, 0xF6, 0xA0, 0x7E, + 0x78, 0xF7, 0xFF, 0x6E, 0x94, 0xFE, 0x8B, 0x47, + 0xB7, 0x96, 0xA3, 0x38, 0x8F, 0x94, 0xAD, 0x3F, + 0x84, 0x7E, 0x3E, 0x0C, 0x58, 0x41, 0x4D, 0x0A, + 0xA1, 0xA8, 0xEC, 0x4C, 0x0E, 0x87, 0x7C, 0x71, + 0x86, 0xE0, 0x97, 0x92, 0x7E, 0xBD, 0x56, 0x07, + 0x8C, 0x36, 0x1C, 0x57, 0xF2, 0x00, 0xA0, 0xD3, + 0x5A, 0x47, 0x52, 0x8C, 0xA1, 0x4C, 0x08, 0x7D, + 0xC2, 0x14, 0xF0, 0x78, 0x16, 0x61, 0x4E, 0xF5, + 0x85, 0xAB, 0x42, 0xE9, 0x97, 0x52, 0x49, 0xBD, + 0x30, 0xD6, 0xC3, 0xEC, 0x86, 0xE5, 0x5E, 0xCD, + 0x61, 0xC8, 0x90, 0x2E, 0x28, 0xED, 0x88, 0xC7, + 0x07, 0x5C, 0xC6, 0x82, 0x7A, 0xA3, 0x2A, 0xFC, + 0x18, 0x10, 0x4D, 0x31, 0x84, 0xC3, 0x19, 0x11, + 0x7D, 0xD5, 0xC9, 0x67, 0x87, 0x6C, 0x9C, 0xD5, + 0x65, 0xB1, 0x7D, 0xA0, 0x1F, 0x74, 0x9B, 0xB2, + 0xB1, 0xF9, 0xDC, 0xBF, 0xBF, 0xC1, 0xC2, 0xB5, + 0x62, 0x87, 0x1C, 0x5C, 0xE0, 0x4F, 0x48, 0x39, + 0x23, 0x23, 0x34, 0x26, 0x22, 0x07, 0xC3, 0xD4, + 0xCE, 0x33, 0xD2, 0x9C, 0x2C, 0x4E, 0xA2, 0xB5, + 0xB4, 0xAB, 0x5C, 0xE6, 0x35, 0x96, 0x3E, 0x8B, + 0x26, 0x88, 0xDA, 0x20, 0x75, 0x60, 0xE3, 0xA3, + 0x9F, 0x95, 0xFA, 0x91, 0x9C, 0xB9, 0xD3, 0xBF, + 0xE0, 0x14, 0xF0, 0x08, 0x18, 0x9E, 0xF7, 0x86, + 0xCC, 0x54, 0xF4, 0x86, 0x0F, 0x28, 0xAA, 0x4C, + 0xD6, 0x51, 0xCD, 0xCF, 0x0F, 0x56, 0x10, 0x7D, + 0xC2, 0x95, 0xB5, 0xB9, 0x9E, 0x5C, 0x25, 0x64, + 0x85, 0xFD, 0x57, 0xF1, 0x9D, 0xC1, 0x2B, 0x6B, + 0x29, 0x6C, 0x03, 0x16, 0x35, 0x33, 0x11, 0xD5, + 0xA4, 0x40, 0xA0, 0xC3, 0xC3, 0xC1, 0xDB, 0x2A, + 0xA1, 0x85, 0x49, 0x22, 0x49, 0x73, 0xAB, 0x5E, + 0xAA, 0x77, 0x22, 0x3F, 0x27, 0xCE, 0x20, 0x64, + 0xE3, 0x34, 0x4A, 0x10, 0x65, 0xFD, 0x51, 0x28, + 0x38, 0x5E, 0xE8, 0x2B, 0xC2, 0xBC, 0x70, 0x9C, + 0x97, 0x23, 0xC1, 0xAA, 0xA4, 0x5B, 0xB8, 0x34, + 0x0E, 0x9E, 0x36, 0x60, 0x28, 0xC7, 0xFA, 0xA3, + 0x98, 0xD3, 0x80, 0xAB, 0x03, 0xAB, 0xED, 0x72, + 0x2F, 0x89, 0x40, 0x74, 0x51, 0xDC, 0x09, 0x65, + 0x9B, 0x04, 0x3B, 0x87, 0xA4, 0x75, 0xD6, 0xF9, + 0xE8, 0xD3, 0xE6, 0xFE, 0x3F, 0x1B, 0xD4, 0x35, + 0x93, 0x21, 0xC3, 0x4E, 0x79, 0x6F, 0xD9, 0x2C, + 0x87, 0x2B, 0xDA, 0xAB, 0x54, 0xDD, 0x32, 0x49, + 0xD1, 0xC5, 0xD3, 0x70, 0xA7, 0x03, 0xA4, 0x42, + 0xC1, 0x4A, 0xF6, 0x37, 0xD7, 0xC2, 0x46, 0x58, + 0xB6, 0xA7, 0x02, 0xC0, 0x4B, 0x8C, 0xFB, 0x58, + 0x9F, 0x5F, 0x49, 0x0F, 0x6A, 0x34, 0x8C, 0xE7, + 0x39, 0x29, 0x7C, 0x31, 0x5B, 0xE2, 0xC8, 0x11, + 0x1B, 0xB7, 0xFE, 0x21, 0x40, 0x75, 0x8E, 0x54, + 0xF6, 0xEE, 0x6C, 0x98, 0x21, 0x1D, 0x6D, 0xA0, + 0xCD, 0x9E, 0x93, 0xB0, 0xF2, 0x57, 0xD9, 0x17, + 0x90, 0x41, 0x7E, 0xA7, 0xF6, 0x13, 0x1D, 0x5D, + 0x8B, 0x07, 0x0C, 0xAA, 0x59, 0xCC, 0xE8, 0xFB, + 0xBE, 0x7E, 0x7A, 0x3D, 0x19, 0xF6, 0x84, 0x79, + 0xC2, 0xCC, 0xCF, 0x60, 0x3F, 0x99, 0x73, 0xF3, + 0xEA, 0xB4, 0x55, 0xE2, 0x44, 0xFE, 0x2C, 0x89, + 0xF8, 0x55, 0xE2, 0xE0, 0xF9, 0x4A, 0x9D, 0xD7, + 0xE4, 0x40, 0x0E, 0x25, 0x76, 0x79, 0xB3, 0xBD, + 0x1A, 0x74, 0xC6, 0x81, 0xF5, 0x60, 0x3E, 0xF0, + 0xB7, 0x53, 0xF0, 0xB7, 0x1A, 0x19, 0xC8, 0x9C, + 0x68, 0x75, 0xBC, 0xA9, 0x96, 0x87, 0xBF, 0xFA, + 0x5A, 0x60, 0x8B, 0xEC, 0x46, 0x19, 0x00, 0xB2, + 0x48, 0x25, 0xE2, 0x45, 0xBA, 0xB6, 0xD6, 0xFA, + 0x56, 0xEE, 0x0B, 0xCD, 0xE7, 0x77, 0x16, 0x56, + 0x04, 0xD1, 0x62, 0x89, 0x30, 0x7C, 0x19, 0xF2, + 0x4C, 0x43, 0xAB, 0x60, 0x5D, 0x10, 0x9D, 0x1A, + 0xEA, 0x09, 0x54, 0x09, 0xD4, 0xFC, 0x4D, 0x90, + 0x35, 0x68, 0xF1, 0xA5, 0x1F, 0xC1, 0x77, 0x45, + 0x27, 0x94, 0x47, 0x8F, 0x05, 0x6D, 0xEC, 0xD7, + 0x50, 0x2C, 0xD7, 0xE1, 0x01, 0x15, 0x44, 0x9E, + 0x95, 0x4C, 0xE9, 0x2E, 0xD6, 0x9B, 0x5F, 0xF7, + 0x4D, 0xF1, 0x7B, 0x3A, 0x87, 0xF7, 0xDC, 0x89, + 0xA7, 0x96, 0x08, 0xCE, 0x5F, 0x04, 0x95, 0x00, + 0x29, 0x8E, 0x04, 0x37, 0x01, 0x6D, 0xEB, 0x95, + 0x64, 0x04, 0x46, 0xD9, 0xC5, 0xCB, 0x40, 0x74, + 0x97, 0xCD, 0x37, 0xE4, 0x93, 0x98, 0x42, 0x39, + 0xDB, 0xAB, 0xC9, 0x15, 0xE5, 0x2F, 0x96, 0xCB, + 0xF4, 0xF0, 0x18, 0x45, 0x25, 0xF2, 0x67, 0xDB, + 0x8D, 0xCD, 0x7F, 0xB1, 0x5C, 0xDC, 0x0E, 0xA2, + 0x06, 0xC0, 0x11, 0x41, 0x14, 0xB3, 0x4F, 0x8C, + 0x62, 0x5F, 0x69, 0x5C, 0xE6, 0x1F, 0xF2, 0x0F, + 0x50, 0x05, 0xF2, 0xAF, 0x2D, 0x7D, 0xDF, 0x4E, + 0xF1, 0xC2, 0x40, 0xB6, 0x5E, 0xB4, 0x84, 0x63, + 0xF0, 0x08, 0xEC, 0xCF, 0xDB, 0x78, 0x58, 0xA2, + 0xD8, 0xEE, 0x67, 0xAA, 0x1D, 0x62, 0xFD, 0x33, + 0x5C, 0xD0, 0x77, 0x91, 0xC5, 0xF9, 0xC8, 0xBD, + 0x74, 0x0F, 0x7E, 0x74, 0x26, 0x57, 0x18, 0x25, + 0x89, 0x04, 0x19, 0xB2, 0x43, 0x6E, 0x05, 0xF7, + 0x76, 0x8C, 0xC1, 0x33, 0x0C, 0xE4, 0x3B, 0x0B, + 0x11, 0x99, 0x35, 0x5D, 0x24, 0xFE, 0x16, 0x3E, + 0x93, 0x3A, 0x47, 0x30, 0xAA, 0x85, 0x37, 0x4A, + 0xD0, 0x6C, 0x80, 0x5B, 0xD1, 0xF7, 0xAB, 0x91, + 0x5E, 0xB7, 0x8B, 0x6D, 0x56, 0x19, 0xBD, 0xEC, + 0x8B, 0x85, 0xE8, 0x41, 0x7D, 0xAD, 0x24, 0x74, + 0x2B, 0x07, 0xF6, 0xE8, 0x4F, 0xCE, 0x1E, 0xDC, + 0x27, 0xD3, 0x22, 0x98, 0xE3, 0x09, 0x9A, 0x19, + 0x04, 0xFE, 0x49, 0x28, 0x62, 0xEA, 0x98, 0x90, + 0x7F, 0x23, 0x46, 0xCE, 0x39, 0x58, 0xE5, 0x5A, + 0x93, 0x5A, 0x85, 0xED, 0xAB, 0x56, 0xC8, 0x7C, + 0xE2, 0x48, 0x9D, 0x82, 0x67, 0x29, 0x8D, 0x56, + 0xF4, 0xB7, 0x3F, 0x69, 0x56, 0x0B, 0x21, 0x9B, + 0x81, 0x6B, 0xB1, 0x45, 0xC1, 0x4F, 0x0B, 0xE2, + 0x78, 0xA4, 0x93, 0x07, 0xD4, 0x69, 0x62, 0xC0, + 0x33, 0x3A, 0x5B, 0x59, 0x35, 0x17, 0xC3, 0xED, + 0xB6, 0xF7, 0x02, 0x0A, 0x97, 0x88, 0x39, 0xFE, + 0x11, 0x82, 0x88, 0xE4, 0xD4, 0xB3, 0xE8, 0x0C, + 0xD7, 0x5C, 0xE4, 0x68, 0x74, 0xBC, 0xE5, 0xA7, + 0x1F, 0x8C, 0x26, 0x1F, 0xFE, 0x31, 0x00, 0xDA, + 0x42, 0x9C, 0x4E, 0xAB, 0x36, 0x90, 0x31, 0x36, + 0xDC, 0x78, 0x63, 0x69, 0xF6, 0xA2, 0x0C, 0xC7, + 0x89, 0x76, 0x28, 0x0F, 0x14, 0x9C, 0x5A, 0x8D, + 0x26, 0x87, 0xC1, 0x8D, 0x57, 0xBB, 0x4C, 0x79, + 0x35, 0x4A, 0xA5, 0xFD, 0x7F, 0x79, 0x1A, 0x60, + 0x00, 0xF9, 0xF7, 0x9D, 0x81, 0x92, 0x00, 0x2A, + 0xE0, 0xA1, 0x01, 0xCC, 0x27, 0xB1, 0xA8, 0xA5, + 0xC3, 0xE8, 0xF2, 0xBC, 0xD1, 0x37, 0x60, 0x11, + 0x2D, 0x86, 0xB2, 0x3A, 0xE0, 0x17, 0x52, 0x63, + 0x98, 0x01, 0x47, 0xA4, 0xE6, 0x54, 0x64, 0xA8, + 0x7C, 0xDB, 0x17, 0x02, 0xCC, 0xBE, 0x3B, 0x3A, + 0xD9, 0x06, 0x1E, 0xD4, 0xAD, 0x08, 0xEF, 0x74, + 0x30, 0xFC, 0x81, 0x52, 0x33, 0x57, 0xF3, 0x51, + 0x56, 0x34, 0xAE, 0x4B, 0x64, 0x4F, 0xC5, 0x6E, + 0x56, 0x86, 0x6F, 0xD9, 0xD8, 0x63, 0x5F, 0xF5, + 0x05, 0x83, 0xC9, 0xA5, 0x30, 0xD3, 0x4F, 0xF3, + 0x7F, 0x81, 0xBB, 0x68, 0x5F, 0x43, 0x20, 0x98, + 0x4F, 0x07, 0xDF, 0xE8, 0x29, 0x58, 0x2E, 0x68, + 0x90, 0x54, 0xA7, 0x65, 0xA7, 0x55, 0xC5, 0x11, + 0xBF, 0x49, 0xE2, 0x80, 0x8C, 0x51, 0x5C, 0xB7, + 0xAA, 0x16, 0x22, 0x1F, 0xB0, 0xCB, 0xF9, 0x7F, + 0x8B, 0x5B, 0x90, 0xD7, 0x27, 0x57, 0x41, 0xAA, + 0x74, 0x24, 0x4E, 0xDD, 0xCB, 0x50, 0x75, 0xBA, + 0xB1, 0x4C, 0x38, 0x2D, 0x93, 0x2B, 0x96, 0xC3, + 0x24, 0xC1, 0xF7, 0xA6, 0x1C, 0xD5, 0x10, 0x9E, + 0x36, 0x3B, 0xD8, 0x6F, 0xB4, 0x7D, 0xF3, 0x41, + 0xEB, 0x80, 0x1D, 0x1F, 0xE9, 0xC2, 0xE2, 0x95, + 0xB9, 0xDC, 0x45, 0x0D, 0xD1, 0x89, 0x68, 0x92, + 0x7F, 0x04, 0x34, 0x42, 0xF1, 0xEF, 0xFC, 0x7B, + 0x97, 0x2E, 0xD2, 0x97, 0x49, 0x50, 0xA4, 0x09, + 0xA1, 0x13, 0xB0, 0x69, 0xCE, 0x06, 0x7C, 0xB5, + 0xE9, 0x1A, 0x40, 0xAB, 0xFE, 0xFF, 0x16, 0xBD, + 0x7C, 0x08, 0xB1, 0x78, 0x24, 0x99, 0xA3, 0xB9, + 0xAE, 0x18, 0x46, 0xD0, 0x23, 0xF6, 0xE8, 0x0E, + 0x9B, 0x1C, 0xCA, 0xEF, 0x52, 0x4F, 0x09, 0xD8, + 0x26, 0x47, 0x7E, 0xDE, 0xCF, 0x18, 0xE6, 0xEC, + 0xD2, 0xBC, 0xB4, 0x01, 0x13, 0xE6, 0xC2, 0x70, + 0xA7, 0xD3, 0xC7, 0xFB, 0x59, 0x5C, 0x91, 0x6B, + 0x71, 0xBB, 0xA6, 0xB6, 0x50, 0x0A, 0xF0, 0xDC, + 0x5C, 0x62, 0x37, 0x42, 0x4C, 0x80, 0xBE, 0x0D, + 0x1F, 0xD7, 0xE5, 0x7A, 0x84, 0xC4, 0x6E, 0xCF, + 0x55, 0x88, 0xA1, 0x63, 0x66, 0x6F, 0x74, 0xC3, + 0xD7, 0x0D, 0xAE, 0xC6, 0x69, 0x2D, 0xA8, 0xF8, + 0x51, 0x74, 0x33, 0xE6, 0xB4, 0x52, 0x08, 0x40, + 0x49, 0x74, 0x10, 0x2F, 0x9B, 0x3C, 0x17, 0x5A, + 0x64, 0x22, 0x73, 0xBE, 0x24, 0xB6, 0x73, 0x84, + 0xCF, 0x5A, 0xE8, 0x3E, 0x3C, 0x58, 0x7F, 0x48, + 0x7D, 0x50, 0x62, 0xCF, 0x5C, 0xA9, 0x9B, 0xAC, + 0xFB, 0xDB, 0x34, 0x1F, 0x73, 0x97, 0xF9, 0xF5, + 0x4D, 0x34, 0x36, 0x59, 0x03, 0xBE, 0xE1, 0x05, + 0xC6, 0xBE, 0x62, 0xD6, 0x28, 0x63, 0x52, 0xB2, + 0xEF, 0x7B, 0x26, 0xEA, 0x3D, 0xE5, 0x89, 0x96, + 0xC1, 0xA1, 0xA0, 0xE8, 0x23, 0xC8, 0x66, 0x9F, + 0xBF, 0xE3, 0x39, 0xF4, 0x02, 0xEA, 0x35, 0xCB, + 0xDD, 0x2D, 0xE0, 0xF0, 0x98, 0x09, 0x94, 0xD3, + 0xB8, 0x21, 0x00, 0xDA, 0x8E, 0x10, 0xBD, 0xB2, + 0xCC, 0x88, 0xC1, 0x80, 0x5D, 0x79, 0xDE, 0xC7, + 0x6C, 0x38, 0xF4, 0xEE, 0x96, 0xF1, 0xA4, 0x07, + 0x84, 0x0D, 0x5C, 0xC6, 0xF1, 0xF5, 0x5E, 0x45, + 0x7F, 0x38, 0xBC, 0x5E, 0xF3, 0xD4, 0xE4, 0x94, + 0xA0, 0x36, 0x7D, 0x24, 0xC5, 0xB7, 0xC6, 0x4D, + 0xB0, 0x23, 0x97, 0xD2, 0xDC, 0xE5, 0x29, 0x88, + 0x0D, 0x55, 0xA1, 0x4F, 0x2C, 0x1A, 0x70, 0x8E, + 0x15, 0xDF, 0xE5, 0x44, 0xB2, 0x03, 0xEE, 0xFE, + 0x05, 0x26, 0xFB, 0xCA, 0xD2, 0xAA, 0x18, 0xFD, + 0x46, 0xAD, 0x05, 0x10, 0xD9, 0x50, 0x79, 0xBC, + 0x9C, 0xC5, 0x58, 0x83, 0x1E, 0x62, 0x84, 0x5F, + 0x52, 0x8C, 0xF3, 0x8A, 0x52, 0x37, 0xBF, 0xAA, + 0x8D, 0x09, 0xC7, 0x74, 0x25, 0x6E, 0xA4, 0xA8, + 0x39, 0x72, 0x5E, 0x76, 0x6F, 0x91, 0xF2, 0x10, + 0x50, 0x85, 0x21, 0x80, 0x50, 0xC4, 0xBA, 0x46, + 0x04, 0x92, 0xC9, 0x3B, 0x5F, 0x0E, 0xC7, 0x5B, + 0xB5, 0x98, 0xF3, 0x5C, 0x54, 0xFB, 0x49, 0x6F, + 0xB0, 0x9A, 0xBD, 0x93, 0x22, 0x8A, 0xE5, 0xFF, + 0x46, 0x58, 0xA0, 0x3A, 0x8F, 0x71, 0xB8, 0xCF, + 0xDA, 0xA9, 0x15, 0xFC, 0x98, 0x9A, 0x64, 0x39, + 0x2C, 0x6C, 0x95, 0x9E, 0x00, 0x73, 0x9A, 0x90, + 0x98, 0x80, 0x53, 0x9F, 0xF7, 0xE3, 0xD4, 0x6D, + 0xC8, 0x69, 0x76, 0x60, 0x5B, 0xEE, 0xBC, 0x8A, + 0x3B, 0x0B, 0x2E, 0xCD, 0xA6, 0x30, 0x1E, 0xBB, + 0x6E, 0x67, 0x1B, 0x98, 0xB6, 0x3A, 0xC4, 0xCD, + 0xA1, 0x94, 0x89, 0x22, 0x92, 0x5D, 0x47, 0x5E, + 0xFA, 0xF4, 0x0A, 0xCB, 0x28, 0x4F, 0x2D, 0x4D, + 0xE8, 0x6B, 0x29, 0x07, 0xE0, 0xB6, 0xD6, 0x0F, + 0x4E, 0x5D, 0x3F, 0xDC, 0x31, 0x83, 0x1D, 0xD9, + 0x2C, 0xC0, 0x9F, 0x48, 0x1E, 0xB6, 0x36, 0x7B, + 0x3F, 0x29, 0xBE, 0x75, 0x35, 0x97, 0x6E, 0xCD, + 0x82, 0xA6, 0x6A, 0xF0, 0x58, 0x12, 0xD2, 0x8F, + 0x6E, 0xC8, 0x94, 0x06, 0x09, 0x18, 0xE5, 0x57, + 0xE3, 0xC1, 0xF8, 0x14, 0x2B, 0x19, 0x62, 0x9E, + 0xA0, 0xC2, 0xF8, 0xF2, 0x7F, 0x8B, 0xB2, 0x8B, + 0x14, 0x62, 0xBA, 0xDC, 0xE9, 0xE2, 0x5B, 0x62, + 0x96, 0xF9, 0x11, 0x82, 0x43, 0xC8, 0x46, 0x05, + 0x0E, 0xA0, 0x03, 0x8F, 0x45, 0x3F, 0x3D, 0x68, + 0x6D, 0xBB, 0x71, 0x07, 0x62, 0x19, 0x2D, 0xA6, + 0x2B, 0xD9, 0x45, 0xEE, 0xD6, 0xD0, 0xA5, 0xD5, + 0xE2, 0x77, 0x9E, 0x04, 0x62, 0x09, 0xBE, 0xA8, + 0x12, 0x91, 0xDA, 0xCE, 0x15, 0xB6, 0x3B, 0xAD, + 0xA7, 0x72, 0x43, 0x49, 0x10, 0xE6, 0x55, 0x33, + 0x09, 0xDE, 0x8A, 0xFC, 0x94, 0xF1, 0x5A, 0x51, + 0x1E, 0xDA, 0x45, 0x22, 0xAE, 0x92, 0x3B, 0xBD, + 0xA8, 0xE9, 0x75, 0x3D, 0x4A, 0xBE, 0x12, 0xEB, + 0x1C, 0xC7, 0xE3, 0xD7, 0xFC, 0x2E, 0x03, 0x3E, + 0x5A, 0x3D, 0x9F, 0x6E, 0x1D, 0xC7, 0xAE, 0xDD, + 0x54, 0x8D, 0xF4, 0x23, 0xA7, 0x66, 0xA1, 0x7D, + 0x2F, 0x41, 0x07, 0xA9, 0xDB, 0xE7, 0x03, 0x42, + 0xAE, 0x9A, 0xCA, 0x6F, 0xD8, 0xD8, 0xCE, 0x47, + 0xA0, 0xE3, 0x3B, 0x76, 0x06, 0xB8, 0xD5, 0x87, + 0x78, 0x4F, 0x69, 0x8F, 0x1B, 0x81, 0x8A, 0xF1, + 0x5F, 0x5D, 0xEA, 0xA3, 0x6B, 0xB8, 0xB2, 0x8E, + 0x13, 0xE9, 0x6B, 0x5A, 0xAF, 0x7D, 0x3B, 0xBE, + 0x13, 0x66, 0x86, 0x37, 0x4E, 0xE2, 0xBC, 0x62, + 0xFD, 0x5A, 0xB5, 0xC8, 0xB6, 0x52, 0x3A, 0xDA, + 0x0F, 0x39, 0x7E, 0xD4, 0x73, 0x12, 0xDC, 0x91, + 0x11, 0x3A, 0x57, 0x13, 0xC9, 0x74, 0x5E, 0xFF, + 0xC9, 0x9A, 0xDA, 0x80, 0x03, 0xBF, 0xDC, 0x79, + 0xC1, 0xBA, 0x5A, 0x24, 0x4A, 0xFA, 0xBF, 0x21, + 0x7A, 0x58, 0x91, 0x6D, 0x73, 0x2D, 0xBD, 0x7C, + 0xA5, 0x00, 0x7F, 0x10, 0x0A, 0xF6, 0x07, 0x6E, + 0xE8, 0xB5, 0x8C, 0x1C, 0x61, 0x7F, 0x54, 0x0A, + 0x5C, 0x98, 0x63, 0xCA, 0xAA, 0x10, 0x9F, 0x4C, + 0x5F, 0x1E, 0xD2, 0xAD, 0xB2, 0x8C, 0xC7, 0x5A, + 0xC7, 0xEF, 0xE5, 0x1E, 0xFB, 0x15, 0xBB, 0xB6, + 0x8D, 0x61, 0x64, 0x91, 0x69, 0xEC, 0x24, 0x8B, + 0x1D, 0xB9, 0xE8, 0x6F, 0xBB, 0x36, 0x2F, 0x5A, + 0x09, 0xBC, 0xF7, 0x56, 0x0A, 0x42, 0x19, 0x3F, + 0x10, 0xC8, 0x15, 0x1B, 0xCC, 0xCE, 0x9D, 0x07, + 0x44, 0xD9, 0xFD, 0x21, 0x0E, 0x70, 0xA8, 0x42, + 0xD4, 0xB1, 0xDB, 0xEA, 0x70, 0xAD, 0xCD, 0xF5, + 0xDA, 0xB1, 0x0C, 0x3E, 0x40, 0x74, 0x3D, 0xEA, + 0x28, 0x37, 0x6B, 0x40, 0xEA, 0x61, 0x6F, 0x8C, + 0x6E, 0x7B, 0x23, 0x42, 0x96, 0xB3, 0xF0, 0xFF, + 0x6C, 0x32, 0xF3, 0x65, 0x17, 0x9F, 0x48, 0xF1, + 0x08, 0xC6, 0x0B, 0xD9, 0xFF, 0x72, 0x95, 0xB9, + 0x8F, 0x5C, 0x68, 0x10, 0xD4, 0x38, 0x32, 0x4F, + 0xB0, 0x07, 0xB5, 0x23, 0xE9, 0x3A, 0x12, 0x3A, + 0x84, 0xB3, 0xA7, 0x74, 0x85, 0x20, 0x85, 0x86, + 0x25, 0xBD, 0x32, 0x55, 0x27, 0x49, 0xBB, 0xCD, + 0xF2, 0xF0, 0x40, 0x27, 0x09, 0x50, 0x14, 0x5A, + 0x45, 0x1C, 0xD2, 0xB5, 0xC3, 0xEB, 0x46, 0x2C, + 0x45, 0x96, 0x16, 0x4A, 0x16, 0x68, 0xD9, 0x1B, + 0x22, 0x9C, 0x8C, 0x00, 0xFF, 0x3B, 0x01, 0xFD, + 0xC3, 0x08, 0xB2, 0x02, 0xD1, 0xFD, 0xA8, 0x27, + 0x0B, 0x47, 0x62, 0x1B, 0xE0, 0x26, 0xA2, 0xAD, + 0x39, 0x30, 0xC1, 0x8E, 0x84, 0x9C, 0x0D, 0x84, + 0xAC, 0x5B, 0x74, 0xC8, 0x17, 0x76, 0xE0, 0x97, + 0xF1, 0x46, 0x8C, 0x29, 0x1E, 0xA0, 0x1A, 0xBB, + 0xB5, 0x7E, 0xAE, 0xDF, 0x2B, 0xED, 0x04, 0x0D, + 0xE7, 0xF9, 0x6E, 0xB5, 0x2C, 0xA6, 0x3F, 0x4C, + 0x7B, 0x3D, 0x68, 0xCF, 0x1C, 0xB9, 0xCE, 0xF6, + 0xF5, 0xE8, 0x43, 0xC4, 0xA6, 0x89, 0x71, 0x88, + 0x8C, 0x90, 0x14, 0xA9, 0x92, 0x01, 0x09, 0xE1, + 0xEB, 0x24, 0xCE, 0x1A, 0x32, 0xD4, 0xAB, 0x0E, + 0xE9, 0x92, 0x27, 0xD0, 0xAC, 0x5E, 0x46, 0x0B, + 0xD3, 0x94, 0x29, 0xCC, 0x3E, 0x4B, 0x0D, 0xBA, + 0x12, 0x04, 0x7B, 0x30, 0xEA, 0xAF, 0x17, 0x77, + 0x8C, 0x7F, 0x1E, 0xB3, 0x53, 0x18, 0xA7, 0x6B, + 0x8A, 0x7C, 0xA4, 0x05, 0x4A, 0xA0, 0x00, 0x38, + 0x13, 0x33, 0x0E, 0x20, 0x3E, 0xEE, 0x0F, 0xD7, + 0x06, 0x16, 0xD3, 0x62, 0x97, 0x72, 0x43, 0xF9, + 0x07, 0x13, 0x9A, 0x4E, 0x74, 0x36, 0x76, 0x08, + 0x6C, 0x57, 0xA6, 0x12, 0xC4, 0xE8, 0x8F, 0x93, + 0xBB, 0x1D, 0x8A, 0x91, 0x48, 0x6C, 0x83, 0x63, + 0x58, 0x1C, 0x6E, 0x93, 0xAA, 0xB1, 0x2C, 0x3C, + 0x6D, 0x54, 0x38, 0xA6, 0x59, 0xC1, 0x0E, 0x78, + 0xEF, 0xDF, 0x01, 0x73, 0x3D, 0x31, 0xC2, 0x14, + 0x73, 0xCE, 0x52, 0x57, 0x42, 0xB9, 0xE8, 0x3E, + 0xBD, 0x9A, 0x42, 0xF6, 0xE4, 0x5A, 0x15, 0x1F, + 0xCE, 0x92, 0x36, 0x99, 0x0F, 0xC3, 0xAF, 0x5F, + 0x82, 0x58, 0x4B, 0x71, 0x29, 0xFB, 0xB5, 0xF2, + 0xEB, 0xA9, 0xF0, 0x93, 0x98, 0xF5, 0x3B, 0x21, + 0x67, 0x9C, 0xB6, 0xC9, 0x0D, 0x4B, 0x31, 0x28, + 0x54, 0x51, 0xF4, 0x6B, 0xB1, 0x17, 0x95, 0x39, + 0xC9, 0xFF, 0xE4, 0x29, 0x05, 0x40, 0xD3, 0x40, + 0xD5, 0x87, 0x78, 0xE8, 0xA8, 0xF6, 0x08, 0x95, + 0x8E, 0x82, 0xA5, 0x8E, 0xC3, 0xC0, 0x4D, 0x60, + 0x7F, 0xCF, 0x61, 0xD2, 0x3F, 0xEB, 0x34, 0xD9, + 0x70, 0xEC, 0x54, 0x93, 0x32, 0x30, 0x69, 0x0F, + 0x5F, 0x46, 0xF8, 0x4F, 0xF6, 0x39, 0x35, 0x71, + 0xC9, 0xF2, 0xF5, 0x8A, 0x31, 0x2E, 0xD5, 0xE0, + 0xC9, 0xAD, 0x2A, 0xC5, 0x81, 0x55, 0x7B, 0xF9, + 0x78, 0x74, 0x9B, 0xB8, 0x9B, 0xC8, 0x62, 0xB3, + 0x87, 0x26, 0x17, 0x6A, 0x09, 0xDD, 0x9C, 0x3A, + 0xB6, 0x1C, 0x00, 0x59, 0xCA, 0xA0, 0xF1, 0xA1, + 0x15, 0xE0, 0x60, 0x0F, 0xD9, 0x89, 0xBE, 0x2F, + 0xCF, 0x39, 0xB7, 0x5D, 0xDA, 0x46, 0x80, 0x67, + 0x14, 0x92, 0x19, 0x17, 0xC1, 0x45, 0x29, 0x09, + 0x8F, 0x4A, 0x65, 0x12, 0xDB, 0xD8, 0xF7, 0xC5, + 0x14, 0xE7, 0x47, 0xCC, 0x33, 0xE0, 0x9A, 0xBC, + 0x74, 0x8A, 0x67, 0xF9, 0x35, 0xD1, 0xED, 0x30, + 0x77, 0xDB, 0x64, 0x96, 0x50, 0x27, 0xF4, 0x75, + 0x25, 0xCB, 0x9D, 0xBD, 0xAA, 0x2D, 0xDA, 0x6E, + 0x32, 0x16, 0x00, 0x18, 0xD3, 0x97, 0x2C, 0xD5, + 0xDD, 0xF8, 0x51, 0xCE, 0x55, 0xFE, 0x41, 0x52, + 0x09, 0xB9, 0xDC, 0xAC, 0xC3, 0x7C, 0x75, 0xD0, + 0x26, 0x09, 0x93, 0x04, 0xF2, 0xC5, 0x52, 0xE4, + 0x31, 0x5C, 0xAD, 0x44, 0xEA, 0xDC, 0x09, 0x16, + 0x61, 0x09, 0x9E, 0xDB, 0xB5, 0xD2, 0x04, 0xD5, + 0x94, 0x2E, 0x0E, 0x4A, 0xBA, 0x4E, 0xCD, 0x67, + 0xF1, 0xD7, 0x52, 0x7C, 0xCD, 0x0F, 0xE7, 0x2F, + 0xEB, 0xA2, 0xB4, 0x26, 0xBB, 0xF8, 0x0B, 0x1F, + 0x26, 0x65, 0x14, 0xB3, 0xF3, 0x61, 0xBB, 0xD0, + 0x1C, 0xAA, 0x21, 0xEB, 0x11, 0x9F, 0x81, 0x80, + 0x7B, 0x7C, 0x3B, 0xE8, 0xFA, 0xF4, 0x2A, 0xB0, + 0x8B, 0x20, 0x58, 0x4D, 0xF9, 0xB3, 0x0D, 0xB3, + 0x6C, 0x66, 0xF3, 0xFB, 0xB6, 0x81, 0xF8, 0x7D, + 0xCE, 0x6B, 0x89, 0x72, 0x10, 0x76, 0x4D, 0x23, + 0xF2, 0xD2, 0xDF, 0xF2, 0xAA, 0x11, 0x45, 0x0E, + 0x71, 0x4D, 0xED, 0x0D, 0x53, 0x01, 0xA5, 0xE5, + 0x17, 0xCE, 0xB3, 0x1F, 0x28, 0xE8, 0x18, 0x7C, + 0x3D, 0xEF, 0xA4, 0x74, 0x8C, 0x41, 0x51, 0xF9, + 0x98, 0x87, 0x11, 0x92, 0x74, 0x73, 0xE9, 0xD8, + 0x31, 0xBB, 0xBF, 0xF9, 0x60, 0x23, 0x3D, 0x8E, + 0x7F, 0xAD, 0x7F, 0x22, 0xAF, 0xFB, 0xCD, 0x07, + 0x35, 0xED, 0x3B, 0xB9, 0xD5, 0x3B, 0xBF, 0x6B, + 0xC0, 0xC3, 0xD0, 0x99, 0xC7, 0x58, 0xB8, 0xAA, + 0x4F, 0xDD, 0x5C, 0x42, 0x48, 0x8E, 0x06, 0x79, + 0x06, 0x31, 0x65, 0x60, 0x19, 0x28, 0x8F, 0x62, + 0xAE, 0x1D, 0x0B, 0x7F, 0x6C, 0x48, 0x53, 0xC9, + 0x02, 0x4C, 0xE7, 0x37, 0xF2, 0x7D, 0xFD, 0x8C, + 0xDB, 0xC7, 0xA0, 0x4A, 0x4B, 0x8C, 0xE6, 0x0C, + 0x90, 0x8C, 0x54, 0x89, 0x56, 0x86, 0xDF, 0x04, + 0x23, 0x27, 0x16, 0x90, 0xCC, 0xEC, 0x64, 0x4F, + 0x66, 0x5B, 0x1E, 0x55, 0x33, 0x76, 0xFE, 0x47, + 0x8D, 0xDE, 0x2F, 0xBC, 0xBC, 0xC4, 0x04, 0xF8, + 0xDC, 0xE8, 0xDD, 0xDD, 0x37, 0x46, 0x86, 0x53, + 0x9E, 0x2C, 0x23, 0x7D, 0xEC, 0xF5, 0x37, 0xDA, + 0x26, 0x22, 0x21, 0x85, 0x16, 0x98, 0x16, 0x84, + 0xE3, 0xC3, 0xFA, 0x9D, 0x7F, 0xC5, 0x80, 0x97, + 0x45, 0xAA, 0xB6, 0x4C, 0x39, 0xBF, 0xD0, 0x28, + 0x23, 0xC3, 0x1C, 0x19, 0x92, 0xBD, 0x1B, 0x2B, + 0x96, 0x1F, 0xBA, 0xF3, 0x8E, 0xB1, 0x23, 0x0F, + 0x57, 0xAE, 0x3D, 0x47, 0x03, 0xB3, 0x77, 0xF9, + 0xEC, 0x45, 0x47, 0x3E, 0x3C, 0x91, 0x87, 0x1B, + 0x70, 0x2B, 0x1E, 0x83, 0x9C, 0xCB, 0xC4, 0x36, + 0x5E, 0x45, 0x7A, 0x4D, 0x07, 0x6E, 0x35, 0x37, + 0xA4, 0xDE, 0xD9, 0x66, 0xBB, 0xF8, 0x69, 0x02, + 0xFA, 0x88, 0xD6, 0x2C, 0xED, 0x0F, 0x4B, 0x74, + 0xAB, 0xFD, 0xA1, 0x23, 0x62, 0xFB, 0x03, 0xDD, + 0xF9, 0x50, 0xEB, 0x86, 0x00, 0xC5, 0xDE, 0x0D, + 0x85, 0x84, 0x63, 0x08, 0xCA, 0x77, 0xB1, 0x44, + 0x2F, 0xF3, 0xA9, 0xDB, 0x38, 0x94, 0x82, 0x9B, + 0x5C, 0x90, 0xD4, 0x9E, 0x4E, 0xA7, 0xFC, 0xBB, + 0x1B, 0x26, 0xA8, 0xBA, 0xBE, 0x2F, 0x2F, 0xC1, + 0x84, 0x79, 0x71, 0x76, 0xE0, 0x94, 0x4F, 0x65, + 0x00, 0x69, 0x08, 0x88, 0xF2, 0xEA, 0x9F, 0x69, + 0x3B, 0x07, 0x3F, 0x30, 0x00, 0x51, 0xFB, 0xDB, + 0xA5, 0xF3, 0xF4, 0xF2, 0x6D, 0x6E, 0x24, 0xC1, + 0xC0, 0x66, 0x2A, 0x1B, 0x7D, 0x5A, 0x61, 0x2A, + 0x99, 0x71, 0xD1, 0xD1, 0x8C, 0x1B, 0x30, 0xFD, + 0xC3, 0xA9, 0x9F, 0x60, 0x84, 0xF2, 0x73, 0x7D, + 0x50, 0xEF, 0xF6, 0x50, 0x78, 0x2F, 0xC8, 0xBC, + 0x07, 0x95, 0x95, 0x7A, 0xC9, 0xBA, 0xCD, 0xD4, + 0x27, 0xBA, 0xC8, 0x3E, 0x88, 0x7E, 0x49, 0xEF, + 0xDE, 0x55, 0x69, 0xC9, 0xB8, 0x69, 0xD9, 0xD0, + 0x92, 0x79, 0x9C, 0x40, 0x84, 0xD8, 0xD0, 0x08, + 0x98, 0xFB, 0x79, 0x75, 0x59, 0x47, 0xFE, 0x37, + 0xCB, 0x0B, 0x43, 0x73, 0x77, 0x21, 0x2F, 0xA0, + 0x86, 0x09, 0x24, 0x6E, 0x27, 0x95, 0x80, 0x9D, + 0x0A, 0xB1, 0x3C, 0x01, 0x8C, 0xCC, 0x3F, 0xEB, + 0x3A, 0xD2, 0x4A, 0xD1, 0xA1, 0x82, 0x6D, 0x14, + 0x2F, 0xC4, 0x64, 0x0C, 0x8E, 0x28, 0xF8, 0x62, + 0x55, 0x85, 0xA0, 0x4C, 0xBB, 0x8E, 0x66, 0x89, + 0xA2, 0xAA, 0xF4, 0x70, 0xE0, 0xB0, 0x88, 0xC7, + 0x26, 0xA0, 0xA9, 0xC4, 0x6C, 0xD2, 0xF1, 0x7B, + 0x9D, 0x43, 0x24, 0xD5, 0x79, 0x8A, 0x6D, 0x0A, + 0xBA, 0xFC, 0x1A, 0xD0, 0x55, 0x38, 0xBE, 0x75, + 0x7C, 0xB4, 0xAA, 0xA2, 0x0C, 0x36, 0x6D, 0x2A, + 0x85, 0xA3, 0x3F, 0x69, 0x3D, 0xCC, 0x0D, 0xF0, + 0xE1, 0x77, 0x20, 0x86, 0x14, 0x77, 0x76, 0x24, + 0x48, 0xEB, 0xAB, 0x02, 0xB4, 0x01, 0x41, 0x42, + 0x1C, 0x9E, 0xF4, 0xB2, 0x51, 0xB9, 0x62, 0xA6, + 0x64, 0x88, 0x8C, 0xAF, 0x99, 0x15, 0xA3, 0x9B, + 0x8A, 0xB5, 0x22, 0x88, 0x9B, 0x2F, 0xAF, 0x5F, + 0x3B, 0x5D, 0x79, 0x4E, 0xD4, 0xA8, 0x65, 0xFA, + 0x74, 0x73, 0x58, 0x09, 0x57, 0xD8, 0x35, 0x75, + 0xB6, 0x19, 0x53, 0xDF, 0x89, 0x1A, 0xB3, 0x81, + 0x2B, 0xF5, 0x89, 0xD4, 0x29, 0xEC, 0xC0, 0xA6, + 0x29, 0xCF, 0x2F, 0x6B, 0x44, 0x97, 0xA5, 0x79, + 0xBA, 0xC9, 0x52, 0x0C, 0x23, 0xBC, 0x6F, 0xDF, + 0x5E, 0xB6, 0xD7, 0xEE, 0xC3, 0x19, 0x60, 0x13, + 0x2D, 0x9D, 0x01, 0x45, 0x67, 0xEF, 0x4F, 0xEB, + 0x57, 0x51, 0x1F, 0x9D, 0x9F, 0xB7, 0x1C, 0xE1, + 0x30, 0xC8, 0x55, 0x9A, 0x3D, 0x9A, 0x55, 0x32, + 0x9A, 0x0D, 0x81, 0x24, 0x72, 0x00, 0x82, 0x6D, + 0xAC, 0x95, 0xB1, 0x04, 0x59, 0xD5, 0x58, 0x4B, + 0x64, 0x48, 0xF3, 0x96, 0xE5, 0xB9, 0x80, 0xDB, + 0x69, 0x80, 0x58, 0x49, 0x91, 0xF8, 0xEE, 0xA6, + 0xE1, 0xEC, 0x62, 0x2E, 0x36, 0x6D, 0x54, 0x1E, + 0x3E, 0xF4, 0xFA, 0x4A, 0x6D, 0x35, 0xE1, 0xDF, + 0x25, 0x46, 0x00, 0xBF, 0xDA, 0x5E, 0xAC, 0x67, + 0xBF, 0xF1, 0xFE, 0xC3, 0x23, 0x39, 0x70, 0xA7, + 0x3D, 0x02, 0x9B, 0x30, 0x9F, 0xAA, 0xF9, 0x59, + 0x7A, 0x7C, 0x16, 0xD4, 0xDB, 0x5E, 0x75, 0xCF, + 0x77, 0x85, 0xF5, 0x5C, 0x1B, 0xC1, 0x64, 0x97, + 0x03, 0x2D, 0x0C, 0x5A, 0x3A, 0x1C, 0xB7, 0xD6, + 0xD7, 0x98, 0xEA, 0x83, 0x6D, 0xB2, 0xDC, 0x9C, + 0x26, 0x67, 0x37, 0x56, 0xA6, 0xA4, 0x4D, 0xEF, + 0xAD, 0x98, 0x6A, 0xEE, 0xAE, 0x14, 0x24, 0x93, + 0xA2, 0x81, 0x55, 0xF5, 0x52, 0xFE, 0x45, 0x9A, + 0xCF, 0x4F, 0x65, 0xD0, 0xCE, 0xB6, 0xE0, 0xE6, + 0xCE, 0x9E, 0x3E, 0x94, 0x02, 0xA3, 0x00, 0x54, + 0x50, 0x93, 0x1C, 0xE3, 0x6C, 0xE2, 0xD2, 0x8B, + 0xE4, 0x51, 0xDA, 0x44, 0xFD, 0x01, 0x10, 0x34, + 0x0E, 0xA8, 0x5D, 0x45, 0x54, 0xE6, 0xBD, 0x1A, + 0xD2, 0xB8, 0xB9, 0xA1, 0xA7, 0xD8, 0x40, 0x67, + 0x7E, 0x9B, 0xFC, 0xC9, 0xEA, 0xD8, 0x30, 0x40, + 0x35, 0x33, 0xFE, 0x3F, 0x69, 0x15, 0x0C, 0x2C, + 0xF9, 0x58, 0x58, 0x79, 0x3C, 0x5F, 0x4D, 0x2C, + 0xCE, 0xFE, 0xFA, 0x99, 0xB6, 0x03, 0xED, 0xEF, + 0x9A, 0x48, 0x23, 0x35, 0xF5, 0x1A, 0xA0, 0x38, + 0x84, 0x91, 0xD7, 0xF1, 0x84, 0x98, 0xB3, 0xA8, + 0x27, 0xD9, 0xEB, 0xAD, 0x42, 0x04, 0xA9, 0x79, + 0x6B, 0x50, 0xD1, 0xF2, 0x3F, 0x87, 0x75, 0x4F, + 0x8C, 0x70, 0x64, 0x7F, 0x9A, 0xB1, 0x90, 0x5D, + 0x13, 0x8D, 0x25, 0x04, 0x8D, 0x08, 0x87, 0x0E, + 0xE7, 0xAC, 0x61, 0x17, 0x68, 0x1B, 0xB4, 0xB0, + 0x17, 0x5E, 0x66, 0x72, 0x13, 0xEA, 0xE6, 0x29, + 0xB0, 0xFD, 0xA5, 0xDF, 0x97, 0x5C, 0xB7, 0xBA, + 0x79, 0x09, 0x6C, 0xAB, 0xFA, 0x6E, 0xD5, 0xCD, + 0x77, 0x54, 0xCC, 0x18, 0x87, 0x0D, 0x92, 0x22, + 0x41, 0x2F, 0x4D, 0xD8, 0x56, 0xD4, 0x4D, 0xF0, + 0x09, 0x3A, 0xEF, 0xB0, 0xFD, 0xE4, 0xB2, 0x85, + 0x1A, 0x1C, 0xE2, 0xA2, 0x16, 0x63, 0x24, 0xB6, + 0xC7, 0x7E, 0xC5, 0xB6, 0x33, 0x8F, 0x4D, 0xE1, + 0x18, 0xC5, 0x9A, 0x7B, 0x78, 0x4D, 0x42, 0x66, + 0x24, 0x93, 0x90, 0x89, 0x9A, 0x53, 0xDF, 0xA2, + 0xC5, 0x32, 0x91, 0x0A, 0x59, 0x03, 0x98, 0x80, + 0x35, 0x6F, 0x83, 0x45, 0x13, 0xF8, 0xA1, 0xBB, + 0xFC, 0xC6, 0xA8, 0xBD, 0x4C, 0xEA, 0x66, 0xC8, + 0x2E, 0xB2, 0xE3, 0x83, 0x05, 0x5A, 0xB7, 0xBB, + 0x4C, 0x54, 0x18, 0x55, 0x3F, 0xA0, 0x17, 0x26, + 0xB6, 0x15, 0x50, 0x65, 0x93, 0xB1, 0x80, 0x91, + 0xBF, 0xC8, 0x00, 0x25, 0x33, 0x60, 0xDA, 0x8A, + 0x79, 0xDA, 0x1E, 0x25, 0xA9, 0x70, 0xB3, 0xFA, + 0xC2, 0x98, 0x3A, 0x64, 0x62, 0xF2, 0xDF, 0xC6, + 0x0D, 0x32, 0x19, 0x18, 0x6A, 0x7F, 0xAA, 0x6F, + 0xDF, 0x8E, 0x59, 0x61, 0xC1, 0x55, 0xDA, 0x92, + 0x02, 0x9B, 0x56, 0x16, 0x81, 0x6C, 0x6D, 0x7E, + 0x91, 0x83, 0x0F, 0x15, 0xF0, 0x39, 0xC3, 0x91, + 0x76, 0xD7, 0x44, 0x0B, 0x95, 0x96, 0xD3, 0x1D, + 0x25, 0x2C, 0x89, 0x8F, 0x27, 0x75, 0xAA, 0xCA, + 0x0F, 0x13, 0x1B, 0x7C, 0x9E, 0xD5, 0xB6, 0x18, + 0x0D, 0xB2, 0x92, 0x98, 0xFE, 0x69, 0x21, 0x4A, + 0x0A, 0x3C, 0x6F, 0x55, 0x02, 0xB7, 0xDB, 0x17, + 0xE4, 0x29, 0x1E, 0x35, 0x75, 0xFF, 0x77, 0x9D, + 0x47, 0x93, 0xAA, 0x4A, 0x75, 0x1B, 0xDF, 0xE0, + 0x93, 0x8A, 0x31, 0x0B, 0x1D, 0x6A, 0x9E, 0x95, + 0xE6, 0x54, 0x64, 0x7D, 0x93, 0x2D, 0x07, 0x58, + 0x82, 0xF3, 0x0C, 0x32, 0x21, 0x7A, 0xEB, 0x10, + 0xC5, 0x11, 0x78, 0x38, 0xD6, 0x79, 0xE3, 0xCF, + 0x04, 0x53, 0x45, 0xE6, 0xCD, 0xA5, 0x4C, 0xD9, + 0x9B, 0x35, 0x19, 0x79, 0x60, 0x95, 0x79, 0xEA, + 0x59, 0xE7, 0x64, 0x86, 0x66, 0xE2, 0x3B, 0xD2, + 0xFB, 0xD3, 0xF0, 0x36, 0xAA, 0xF7, 0xE1, 0xA2, + 0xB5, 0xA4, 0x80, 0xC3, 0xB7, 0x76, 0x99, 0xD3, + 0xB7, 0x4A, 0x3D, 0x8E, 0x8F, 0x49, 0xFB, 0x5C, + 0x2D, 0xA2, 0x2A, 0xF4, 0x76, 0x33, 0xC2, 0xFD, + 0x7A, 0xB7, 0x5D, 0x19, 0x80, 0x97, 0x3F, 0xF4, + 0x38, 0x93, 0x02, 0x32, 0xCA, 0xED, 0xCB, 0x12, + 0x2C, 0xA7, 0xCF, 0x83, 0xFA, 0x35, 0xEE, 0xBC, + 0xAF, 0xBA, 0x58, 0xDB, 0xDE, 0xC2, 0xB6, 0x49, + 0x1F, 0x12, 0xFC, 0x61, 0x63, 0x54, 0x33, 0x65, + 0x30, 0x1B, 0x5A, 0x2D, 0x57, 0x64, 0x6F, 0xED, + 0xE7, 0x6E, 0x46, 0x7D, 0x58, 0xDD, 0x66, 0x3C, + 0xD1, 0x99, 0x32, 0x86, 0x6A, 0x2B, 0x58, 0x21, + 0x30, 0x78, 0x90, 0xBF, 0x39, 0x57, 0x32, 0xB7, + 0xAF, 0xCC, 0x88, 0xD1, 0x8A, 0x1D, 0xD3, 0x2D, + 0xC4, 0x3F, 0xBB, 0x8B, 0x74, 0xB5, 0xAD, 0x49, + 0xC8, 0xAF, 0x97, 0x7F, 0x84, 0xC0, 0x51, 0x4F, + 0xA5, 0x5A, 0x5E, 0x17, 0x56, 0x41, 0x73, 0xFB, + 0x77, 0x30, 0xEB, 0xED, 0x7E, 0x23, 0xFA, 0x6A, + 0xC2, 0x57, 0x61, 0x83, 0xDE, 0x18, 0xB0, 0xAA, + 0xD1, 0x83, 0x07, 0x94, 0xFD, 0x99, 0x13, 0xE3, + 0xA3, 0x5A, 0x4A, 0x6F, 0x8E, 0xD2, 0xF3, 0x29, + 0xC7, 0x45, 0xD4, 0x44, 0x98, 0x4F, 0x77, 0xA1, + 0xA7, 0xDC, 0xE4, 0x67, 0x09, 0x9B, 0xE9, 0x0D, + 0x33, 0xBA, 0x76, 0xE8, 0x47, 0x54, 0xC2, 0x93, + 0x31, 0x1A, 0x36, 0x60, 0xE4, 0x7A, 0xE2, 0x54, + 0x04, 0x64, 0x35, 0xD5, 0xAC, 0x66, 0xA1, 0x42, + 0x1C, 0x11, 0x57, 0x39, 0x3E, 0x12, 0x12, 0xB8, + 0x48, 0xCF, 0x36, 0x0F, 0x2A, 0xE7, 0x27, 0x2F, + 0x85, 0xD6, 0x02, 0xDD, 0x59, 0x9D, 0xAA, 0x24, + 0xAB, 0xB6, 0x42, 0x6B, 0x78, 0xFA, 0xE2, 0x26, + 0x95, 0x56, 0x5A, 0xEB, 0x53, 0x64, 0xF4, 0x8D, + 0xD3, 0xC6, 0xC9, 0xDB, 0x01, 0x9B, 0x65, 0xED, + 0x6A, 0x1A, 0xD9, 0x4C, 0x21, 0x0F, 0xAA, 0x9E, + 0xB1, 0x22, 0x0E, 0xD1, 0x39, 0x87, 0x96, 0xC8, + 0x56, 0x6D, 0xF5, 0x26, 0x15, 0xB9, 0x05, 0x88, + 0xF1, 0x27, 0x09, 0x91, 0xD8, 0x6F, 0x36, 0x0A, + 0x9D, 0xFC, 0x80, 0x61, 0xD0, 0x51, 0xAF, 0xC2, + 0x1E, 0x0D, 0xF1, 0x98, 0xCD, 0x2C, 0xCB, 0xBB, + 0xA6, 0x55, 0x90, 0x61, 0xCA, 0xC8, 0xA3, 0x14, + 0xD3, 0xED, 0x58, 0xA3, 0xAF, 0x4A, 0xB0, 0x79, + 0x82, 0x10, 0x59, 0xB9, 0x1A, 0xA5, 0x2E, 0xF0, + 0x33, 0x0C, 0x04, 0xEF, 0x6F, 0xE3, 0x80, 0xF8, + 0x68, 0x1B, 0xA5, 0x24, 0xF5, 0x53, 0x8B, 0x12, + 0x51, 0x5D, 0x0B, 0xF1, 0x73, 0x18, 0x02, 0xBC, + 0x22, 0x27, 0x7A, 0x0B, 0x53, 0x0F, 0x44, 0x61, + 0x3F, 0xCF, 0x98, 0x7F, 0x8A, 0xAE, 0xBD, 0xD1, + 0xB9, 0x79, 0x70, 0x7B, 0xA8, 0xCF, 0x48, 0x60, + 0xDA, 0x48, 0x76, 0x71, 0x7E, 0x42, 0xFC, 0xDF, + 0xCD, 0xAF, 0xDA, 0x0E, 0x09, 0xDB, 0xFE, 0xFC, + 0xE9, 0x42, 0xEF, 0xCF, 0x7D, 0xBD, 0xAC, 0xE8, + 0xE5, 0xF9, 0x2F, 0x8B, 0x5C, 0x1F, 0x7B, 0x97, + 0x55, 0x3B, 0xAC, 0x01, 0x93, 0x1B, 0x6F, 0xA8, + 0xF0, 0x8C, 0xB5, 0x52, 0xDC, 0xA8, 0x98, 0x2E, + 0xA8, 0x47, 0xA8, 0xB8, 0x1F, 0x30, 0xD0, 0xA1, + 0x2E, 0xBF, 0x7A, 0x88, 0x9C, 0xDF, 0x1E, 0xE2, + 0x31, 0x84, 0xB9, 0x9A, 0xB9, 0x9A, 0xA5, 0xCC, + 0xFF, 0x1C, 0x72, 0xB7, 0x6C, 0xA8, 0x56, 0x94, + 0x28, 0xF7, 0xC1, 0x41, 0x3C, 0xFF, 0x8A, 0x85, + 0x08, 0xC5, 0x30, 0xC7, 0x53, 0x19, 0x29, 0x6C, + 0x18, 0x58, 0x88, 0x1C, 0x5C, 0x7B, 0x33, 0xE3, + 0x86, 0xBA, 0x8F, 0x5C, 0xCF, 0x98, 0xF9, 0xBB, + 0xC6, 0x29, 0xA1, 0xFF, 0xCA, 0x6F, 0xD8, 0xF4, + 0x79, 0x99, 0xB2, 0x74, 0x37, 0x98, 0x92, 0x84, + 0x4B, 0xB0, 0x85, 0x07, 0xCA, 0xFF, 0x87, 0xC5, + 0xD6, 0xC7, 0xB9, 0xE7, 0x6F, 0x60, 0xA0, 0xCC, + 0x24, 0x78, 0x3D, 0x83, 0x37, 0x80, 0x44, 0x0F, + 0x87, 0xD0, 0xD8, 0x5D, 0xD3, 0x89, 0x21, 0x53, + 0xE5, 0x3E, 0x90, 0x4D, 0x3A, 0x6B, 0x60, 0x31, + 0x88, 0x2B, 0x1B, 0x5E, 0x40, 0xA4, 0x65, 0x24, + 0x07, 0xE9, 0x0A, 0x50, 0x79, 0xCA, 0x52, 0x81, + 0x6C, 0x4B, 0x61, 0xE0, 0x4B, 0xA3, 0x4A, 0x49, + 0xD2, 0xFA, 0x8D, 0x90, 0x39, 0xFD, 0xD6, 0xE1, + 0xF4, 0xED, 0xBA, 0x3D, 0x2F, 0xDD, 0x65, 0x07, + 0xF3, 0x29, 0x6C, 0x94, 0x6D, 0x38, 0xA4, 0xAC, + 0x2A, 0x44, 0xF7, 0xF6, 0x90, 0x35, 0x66, 0x84, + 0x4C, 0xC1, 0x78, 0x81, 0xF5, 0x4C, 0xBC, 0x0C, + 0xB6, 0x14, 0x4C, 0x63, 0x3F, 0x94, 0xAF, 0x5A, + 0xEC, 0xC8, 0x64, 0xC3, 0xD4, 0xE8, 0xC0, 0x94, + 0xC2, 0xFD, 0x3E, 0xE1, 0xDC, 0x11, 0x55, 0xBF, + 0xF6, 0x9C, 0x18, 0xE3, 0x16, 0x23, 0x0D, 0xF8, + 0x72, 0xEF, 0xE1, 0x01, 0xE7, 0x93, 0x2E, 0xD1, + 0xEE, 0x61, 0x98, 0xC9, 0x81, 0xFD, 0xC5, 0xF1, + 0xAC, 0x0A, 0x76, 0xAE, 0x44, 0x80, 0x8D, 0xA8, + 0x54, 0x3C, 0x2C, 0x14, 0x64, 0x9B, 0xF2, 0xD2, + 0x78, 0xCA, 0x76, 0xAF, 0x79, 0x48, 0x2D, 0xAD, + 0xE1, 0x80, 0xDB, 0xC0, 0x70, 0x9F, 0xFA, 0xE0, + 0x77, 0x5B, 0x20, 0x1F, 0x55, 0xEC, 0xA3, 0x88, + 0x06, 0xA5, 0xBB, 0xE2, 0x37, 0x51, 0x80, 0xCA, + 0xCE, 0x18, 0xE9, 0x96, 0x89, 0x2E, 0x63, 0xB6, + 0xA6, 0x40, 0x71, 0xBA, 0xA9, 0x63, 0x22, 0xEA, + 0xCC, 0xAC, 0x82, 0xBE, 0x3C, 0x27, 0x99, 0x5B, + 0x7A, 0xC2, 0x94, 0x12, 0x5B, 0x06, 0x27, 0x22, + 0x2F, 0xB4, 0xD7, 0x5D, 0x00, 0xD2, 0xBF, 0xCA, + 0x03, 0x1B, 0xB9, 0x96, 0x15, 0xB3, 0x1D, 0x83, + 0x1F, 0xDC, 0xAE, 0xBE, 0x5C, 0x3F, 0x81, 0x2D, + 0x2F, 0x21, 0x07, 0xB7, 0xA6, 0xEE, 0xA1, 0x72, + 0x0F, 0xBC, 0xC1, 0xF7, 0x38, 0xAB, 0xE7, 0x0F, + 0x21, 0x5C, 0x98, 0xFB, 0xCA, 0x43, 0xA4, 0xF1, + 0xCA, 0xE2, 0xE2, 0x00, 0x52, 0x3C, 0xD9, 0x56, + 0x5E, 0xFA, 0x15, 0x6D, 0x17, 0x54, 0xD9, 0xED, + 0x69, 0x00, 0x86, 0x37, 0xAE, 0xFD, 0xF3, 0xA4, + 0xEB, 0xD4, 0x7E, 0x80, 0x75, 0xEF, 0x5B, 0xCB, + 0xB4, 0x96, 0x75, 0x3C, 0x2A, 0xBC, 0x43, 0x0B, + 0x97, 0xA5, 0xC8, 0x6D, 0x41, 0x4D, 0x38, 0x6C, + 0xAB, 0x7A, 0x05, 0x05, 0x73, 0x0E, 0xD8, 0x4C, + 0x3D, 0xBB, 0xC3, 0x3E, 0xE5, 0xB7, 0x21, 0xB9, + 0x47, 0x4E, 0x52, 0x73, 0xF3, 0x05, 0x43, 0xFB, + 0x2D, 0x84, 0x0E, 0x5C, 0x0C, 0xB2, 0x47, 0x61, + 0x2A, 0x30, 0xA5, 0xA3, 0x37, 0x86, 0x76, 0x74, + 0xFD, 0x47, 0x5F, 0x94, 0x78, 0x3F, 0x13, 0xCB, + 0x1D, 0x43, 0x50, 0x36, 0xCD, 0x47, 0xED, 0xEB, + 0x40, 0x18, 0x11, 0x53, 0x83, 0xA9, 0x24, 0xFC, + 0x04, 0x7C, 0x52, 0x68, 0xFB, 0xF2, 0xF6, 0x01, + 0x26, 0xBD, 0xDA, 0x6B, 0xE6, 0xE0, 0x5A, 0xD0, + 0xD3, 0x6F, 0x11, 0xBE, 0x13, 0xC9, 0x9E, 0x37, + 0x19, 0x9D, 0x5E, 0x68, 0x01, 0x4E, 0x8C, 0xC3, + 0x32, 0x42, 0xBC, 0x37, 0x7D, 0xC5, 0x95, 0x42, + 0xF1, 0x8D, 0x18, 0x9C, 0xC3, 0xBE, 0x01, 0x0E, + 0x5B, 0x1E, 0x4B, 0xF4, 0x28, 0xD4, 0x10, 0xD3, + 0x07, 0x98, 0x90, 0x23, 0x8C, 0x93, 0xF8, 0x02, + 0x23, 0x73, 0xBD, 0x96, 0x85, 0xD6, 0xFD, 0x9F, + 0xEC, 0x57, 0xBF, 0x03, 0x4E, 0x28, 0x0E, 0xEA, + 0xA5, 0xCC, 0x12, 0xF6, 0x77, 0xC6, 0x2B, 0x8A, + 0x62, 0x77, 0xA5, 0x5D, 0x96, 0x1E, 0x1F, 0xDA, + 0xE2, 0x3D, 0xA6, 0x24, 0xB5, 0x86, 0x3D, 0xBC, + 0x2B, 0x8B, 0xC2, 0x0A, 0xD5, 0x24, 0x7B, 0x90, + 0x5B, 0x16, 0xEA, 0xA8, 0xF1, 0xFC, 0x13, 0x47, + 0xEF, 0x42, 0x59, 0x01, 0xEF, 0xDE, 0xE8, 0x75, + 0x58, 0x7F, 0x32, 0x92, 0xD6, 0xA7, 0xFF, 0xFC, + 0x04, 0xC5, 0x59, 0x72, 0x83, 0x90, 0xAF, 0x4F, + 0x12, 0xB2, 0x33, 0xA0, 0xE0, 0xD7, 0x2B, 0xF8, + 0x2F, 0x29, 0x43, 0x4A, 0xBB, 0x63, 0x0B, 0xD0, + 0xD7, 0xDE, 0x1F, 0x75, 0x9F, 0x78, 0x81, 0x23, + 0x47, 0x39, 0x49, 0x5D, 0x26, 0x53, 0xF1, 0xDE, + 0x6C, 0x02, 0xC2, 0xC1, 0xD8, 0x44, 0xF5, 0x35, + 0xDB, 0xE9, 0x3A, 0xD6, 0x19, 0x2C, 0x5A, 0xAA, + 0xF9, 0x78, 0x65, 0x71, 0x00, 0xD8, 0x9E, 0xDD, + 0xE1, 0x73, 0x63, 0x75, 0x64, 0x83, 0x03, 0xD7, + 0x60, 0x4E, 0x0B, 0xF9, 0xB9, 0xE2, 0x66, 0x4F, + 0xE2, 0xE6, 0x59, 0x06, 0xDB, 0xA7, 0xB4, 0x05, + 0x03, 0x22, 0xE0, 0x1F, 0xAE, 0x30, 0xEE, 0x4A, + 0x10, 0x6A, 0x38, 0xAA, 0xF3, 0x7F, 0xD1, 0xA2, + 0x29, 0x47, 0x65, 0x67, 0x17, 0x92, 0xB4, 0xDF, + 0x62, 0xA9, 0xA1, 0x30, 0xFB, 0x52, 0x54, 0xBC, + 0xEB, 0x42, 0xEA, 0x78, 0x53, 0xEE, 0x50, 0x91, + 0x95, 0x73, 0xFC, 0x81, 0x3C, 0x6B, 0x9A, 0x11, + 0x94, 0xB6, 0x5D, 0xCB, 0xF4, 0xA9, 0x3C, 0x0E, + 0xBC, 0x8B, 0x95, 0x17, 0xCC, 0xB7, 0x76, 0x59, + 0x81, 0x57, 0x2C, 0x88, 0xD3, 0x53, 0x7F, 0x88, + 0x51, 0x80, 0x16, 0x03, 0x98, 0x7F, 0x7B, 0xE9, + 0x83, 0xF1, 0x29, 0xA7, 0x0A, 0x1C, 0x15, 0x84, + 0xAA, 0x7B, 0x9C, 0x6D, 0x35, 0xFF, 0x9B, 0x77, + 0xE6, 0x2D, 0x46, 0x92, 0x2A, 0x4C, 0x90, 0x4F, + 0xEB, 0xFF, 0xCA, 0xD7, 0xE9, 0x2B, 0x95, 0x2A, + 0x82, 0x88, 0x03, 0xA2, 0x94, 0x61, 0xA7, 0x44, + 0xA2, 0x74, 0x08, 0xC0, 0xAA, 0x7A, 0x10, 0xBA, + 0x14, 0xB0, 0x85, 0xFA, 0x60, 0x8F, 0x9C, 0xC1, + 0xF4, 0xB7, 0x23, 0x71, 0x96, 0x23, 0x58, 0x58, + 0x29, 0xBA, 0x34, 0x6A, 0x95, 0xFF, 0xD8, 0x6B, + 0x74, 0x4C, 0x1C, 0xD7, 0x4D, 0x68, 0xCE, 0x72, + 0x8C, 0x36, 0xFC, 0x61, 0x8E, 0xF0, 0x55, 0x8F, + 0x53, 0x14, 0x54, 0xD7, 0x43, 0x45, 0x50, 0x68, + 0x1F, 0xC0, 0x4C, 0xC2, 0xA1, 0x60, 0x34, 0x6E, + 0xCE, 0x69, 0x61, 0x94, 0x69, 0x47, 0x36, 0xD1, + 0x12, 0xBB, 0x63, 0x2A, 0x8B, 0x95, 0xB7, 0x10, + 0x65, 0x87, 0xFE, 0xBE, 0xE1, 0x6D, 0x69, 0x78, + 0xB0, 0xFC, 0xDB, 0xD0, 0xCE, 0xE1, 0x8C, 0x89, + 0x37, 0x8A, 0x54, 0xA6, 0x43, 0xEA, 0xDA, 0x42, + 0x6E, 0x59, 0x25, 0xAB, 0x7E, 0xF7, 0xAD, 0x95, + 0x8D, 0x8F, 0x0F, 0x27, 0x29, 0xAE, 0xAD, 0xCB, + 0x8D, 0x8D, 0xDB, 0x86, 0x76, 0xAD, 0xE9, 0x65, + 0x90, 0x7B, 0xB2, 0x55, 0xB8, 0x76, 0x70, 0x3C, + 0xFE, 0x12, 0x96, 0xB8, 0x24, 0x74, 0xD7, 0x09, + 0x13, 0x1A, 0x57, 0x7F, 0xD4, 0xE9, 0xB5, 0x9C, + 0xE3, 0x24, 0x71, 0xCC, 0x9B, 0xCD, 0xD1, 0xF4, + 0x8B, 0xC0, 0x7F, 0x6C, 0xEB, 0x73, 0x50, 0x57, + 0xAE, 0xF6, 0xF5, 0xA3, 0x87, 0x2E, 0x84, 0x9D, + 0x96, 0xA0, 0xD9, 0x56, 0x05, 0x04, 0x06, 0x3B, + 0x38, 0x1D, 0x9D, 0x2C, 0x33, 0x7A, 0x1C, 0x70, + 0x2E, 0x19, 0x25, 0xB8, 0xEB, 0xC2, 0x6F, 0x02, + 0xF2, 0x5D, 0x66, 0xA5, 0x81, 0xF5, 0x69, 0x36, + 0x3C, 0x34, 0x73, 0xCE, 0x4D, 0x4D, 0xA5, 0x35, + 0x4E, 0xBA, 0x40, 0x71, 0x09, 0xAE, 0x3E, 0x9B, + 0x4A, 0x3C, 0x75, 0x4E, 0x29, 0x31, 0x4D, 0x4C, + 0x2F, 0x88, 0x80, 0x4F, 0xBA, 0xF0, 0xAD, 0x18, + 0xD5, 0xA0, 0x3D, 0x1A, 0x52, 0xCA, 0x86, 0x29, + 0x26, 0xF0, 0xC1, 0xF7, 0x9C, 0x7A, 0x55, 0xDE, + 0xCA, 0x76, 0x73, 0x92, 0x54, 0x15, 0x16, 0x91, + 0xFD, 0x3C, 0xB5, 0x73, 0xA8, 0xDC, 0x56, 0x90, + 0xFA, 0x16, 0xE4, 0xE6, 0x0A, 0x7E, 0x91, 0xD1, + 0x03, 0xA1, 0xE1, 0x06, 0x88, 0x5E, 0xFB, 0xD8, + 0x61, 0x15, 0xE7, 0x89, 0xE8, 0x49, 0xCB, 0x18, + 0x8E, 0x13, 0x86, 0x6C, 0xAE, 0xBE, 0x3D, 0xB2, + 0x72, 0xEE, 0xC5, 0x3F, 0xC3, 0x6D, 0x14, 0x35, + 0x3E, 0x60, 0x92, 0x8C, 0x7F, 0x51, 0x79, 0xB7, + 0xA0, 0xEF, 0xD1, 0x02, 0x8E, 0x96, 0x7D, 0xAF, + 0x0D, 0x73, 0xC4, 0x17, 0x7E, 0xB1, 0xD9, 0xCB, + 0xCA, 0x94, 0x88, 0x56, 0xD2, 0xD5, 0x3E, 0x75, + 0x0D, 0xDA, 0x2A, 0x10, 0xFB, 0xEF, 0xFE, 0x93, + 0xF7, 0x01, 0x5B, 0x71, 0xD2, 0x2C, 0xCE, 0xB3, + 0x41, 0x2D, 0xBE, 0xA6, 0xA3, 0x63, 0x5F, 0xC0, + 0x53, 0xC2, 0xD4, 0xB7, 0xFD, 0xCA, 0x6A, 0x62, + 0x0F, 0x9F, 0x9D, 0x00, 0xBA, 0xE9, 0x58, 0xE7, + 0xB3, 0x19, 0xF6, 0x90, 0x3C, 0x62, 0xF3, 0xEC, + 0x55, 0x2A, 0x84, 0xCC, 0x91, 0x86, 0x0E, 0x5A, + 0x39, 0x8F, 0x24, 0x71, 0x40, 0xFD, 0x45, 0xBA, + 0x24, 0xB2, 0x0A, 0xD7, 0xE0, 0xE1, 0xF3, 0xAE, + 0x38, 0x07, 0xD4, 0xE7, 0x76, 0xD2, 0xEA, 0x7C, + 0xDC, 0x04, 0xD0, 0x48, 0xE1, 0x43, 0x56, 0xFE, + 0x43, 0xAA, 0xE5, 0xDA, 0x19, 0xB5, 0x80, 0xAF, + 0x7C, 0xDB, 0xFA, 0xEA, 0xE0, 0x8A, 0x38, 0x67, + 0x02, 0xC8, 0x71, 0x3A, 0x1B, 0x12, 0x56, 0x76, + 0x7A, 0x0C, 0x91, 0x18, 0x18, 0x4B, 0xBD, 0xDB, + 0xE9, 0x0F, 0xA1, 0xEC, 0x54, 0xC0, 0x92, 0xF8, + 0x4E, 0xF7, 0xCF, 0x69, 0xFA, 0xF3, 0x6D, 0xB6, + 0xAD, 0xA3, 0xCA, 0xAA, 0x25, 0x13, 0xDA, 0x97, + 0x04, 0x2A, 0xC7, 0xCC, 0x60, 0x7E, 0x65, 0x1D, + 0x57, 0x58, 0xB4, 0x96, 0x53, 0x9A, 0x00, 0xE4, + 0x72, 0xB5, 0x99, 0x1F, 0x7C, 0xDB, 0x3C, 0xB4, + 0x1A, 0x71, 0x38, 0xA3, 0x8B, 0x49, 0x9A, 0xF5, + 0xE7, 0x8D, 0x74, 0xAA, 0x88, 0x66, 0x56, 0x04, + 0xBA, 0xEF, 0xE8, 0x37, 0x56, 0xC2, 0x18, 0x7E, + 0x60, 0xCF, 0x63, 0xCF, 0x1A, 0xEF, 0x28, 0xA9, + 0xDF, 0x2D, 0x3C, 0xAD, 0xC3, 0x5A, 0xDD, 0x7C, + 0xD4, 0x19, 0xDF, 0xDE, 0x80, 0xC2, 0x61, 0xB5, + 0x49, 0x8A, 0x89, 0xB9, 0xB9, 0x72, 0xBF, 0x8B, + 0xF6, 0x04, 0xAA, 0xF5, 0x3E, 0xC1, 0xDC, 0xA8, + 0x86, 0x97, 0x97, 0x0F, 0x29, 0x41, 0x5C, 0x47, + 0xC7, 0x23, 0x48, 0x69, 0xD1, 0xBC, 0x9F, 0x8E, + 0xDD, 0xEA, 0xB6, 0xA6, 0x37, 0x1E, 0x4A, 0x00, + 0xFF, 0xF6, 0x14, 0xC5, 0x42, 0xEF, 0x9F, 0x1D, + 0xE7, 0xCE, 0xD4, 0x31, 0xBC, 0xC3, 0x0E, 0x00, + 0x01, 0xF2, 0xC8, 0xB5, 0x40, 0x82, 0x68, 0x2C, + 0xD0, 0xFA, 0x8B, 0xAC, 0xB4, 0x32, 0xA6, 0x97, + 0xCC, 0x5E, 0x0F, 0x75, 0x45, 0x0A, 0xBA, 0xE5, + 0x5A, 0x84, 0x5F, 0x7E, 0x85, 0x0D, 0x4A, 0x62, + 0x49, 0x3D, 0x12, 0xC0, 0xCE, 0x51, 0x87, 0xB1, + 0x21, 0x1F, 0x6E, 0x1B, 0xDA, 0xEF, 0x12, 0xCC, + 0x18, 0x5A, 0xA9, 0xD9, 0x86, 0x89, 0x06, 0x56, + 0x14, 0x1B, 0xDC, 0xD7, 0x74, 0xFF, 0x71, 0xC6, + 0xE3, 0xEA, 0xF3, 0x0C, 0x20, 0x42, 0xE9, 0x0C, + 0xDE, 0xE8, 0xAC, 0xFD, 0xDA, 0x19, 0x67, 0x7A, + 0x9C, 0xE5, 0xF6, 0x12, 0x5B, 0x20, 0xA4, 0xCE, + 0x4C, 0x34, 0xEE, 0x01, 0xC8, 0xEF, 0x7D, 0xD4, + 0x0D, 0x21, 0xA0, 0x3C, 0xCB, 0xAF, 0x09, 0x6F, + 0x95, 0xF4, 0x76, 0x28, 0x4A, 0x0E, 0x21, 0x5E, + 0xBB, 0x93, 0xA0, 0xD6, 0x33, 0x9E, 0xA7, 0xD3, + 0xF8, 0x65, 0xAD, 0x52, 0xD4, 0x1C, 0x96, 0x33, + 0xC7, 0x8D, 0x67, 0x83, 0xA8, 0xCD, 0x77, 0xD6, + 0xD4, 0xE4, 0xC8, 0x70, 0xAB, 0x85, 0xC9, 0xFE, + 0xB2, 0x47, 0x74, 0x0F, 0xC6, 0x39, 0xB1, 0x6C, + 0x47, 0xEC, 0xB9, 0x26, 0x9A, 0xD3, 0xDE, 0x5E, + 0xB8, 0x0C, 0x14, 0xC7, 0x19, 0x29, 0x47, 0x99, + 0x84, 0x03, 0x80, 0x87, 0xCD, 0xD5, 0xC3, 0x8E, + 0x49, 0x2A, 0xE2, 0xAA, 0x6C, 0x4C, 0x55, 0x20, + 0xCA, 0xF2, 0xD1, 0xA1, 0x04, 0x99, 0x00, 0x62, + 0x00, 0xD1, 0x10, 0x98, 0x68, 0x55, 0xFC, 0x4D, + 0x04, 0x6B, 0xFF, 0xE1, 0x19, 0x82, 0x5F, 0xDB, + 0x7E, 0x47, 0x77, 0xEC, 0x16, 0x14, 0xF8, 0xDC, + 0x01, 0x45, 0xCC, 0x1B, 0x29, 0xC5, 0x4E, 0x38, + 0xE0, 0x07, 0x31, 0xAD, 0x99, 0x65, 0x57, 0x73, + 0xD4, 0x14, 0xD6, 0xA9, 0x6D, 0x63, 0xE4, 0x44, + 0x27, 0x95, 0xCB, 0x43, 0x0C, 0x6B, 0x48, 0xDF, + 0x16, 0x12, 0x3A, 0x00, 0x9B, 0x44, 0x65, 0xD9, + 0xCF, 0x64, 0xCC, 0x59, 0x0D, 0x4D, 0x8F, 0x01, + 0x34, 0x4C, 0x9A, 0xC0, 0x42, 0x59, 0x1E, 0xA8, + 0x28, 0x50, 0x69, 0x4E, 0xD5, 0xC6, 0x6E, 0x16, + 0xDA, 0x2C, 0x58, 0x36, 0xEA, 0x7D, 0x72, 0x19, + 0x3C, 0x96, 0xDD, 0x3C, 0xDC, 0x65, 0xA1, 0x51, + 0x9C, 0xA7, 0x29, 0xBB, 0x34, 0x92, 0x14, 0x52, + 0x57, 0xC7, 0xDD, 0x19, 0x2E, 0x88, 0x25, 0x93, + 0x30, 0xA4, 0x39, 0x1B, 0x05, 0x79, 0x1E, 0xF1, + 0x20, 0x98, 0x80, 0x99, 0x74, 0x2D, 0xB6, 0xE2, + 0x69, 0xD5, 0x68, 0xC7, 0x94, 0xEF, 0x28, 0xE0, + 0x46, 0x62, 0x0F, 0xBE, 0x9D, 0x46, 0xD5, 0xB7, + 0xF7, 0xD1, 0x08, 0x63, 0x0E, 0x7E, 0x29, 0xF7, + 0xAE, 0x61, 0x9E, 0x5B, 0x70, 0x68, 0x3D, 0xEE, + 0x7C, 0xDD, 0xAC, 0xBA, 0xDF, 0xC4, 0x1D, 0xC4, + 0x67, 0x28, 0x6B, 0x6F, 0x20, 0x58, 0x04, 0x1C, + 0x5A, 0x00, 0xD1, 0xC5, 0x40, 0xBC, 0x70, 0xBF, + 0x0F, 0xBC, 0x02, 0xCE, 0x46, 0xBA, 0x42, 0xF6, + 0x21, 0xA0, 0x1F, 0x5F, 0x9E, 0x73, 0xF9, 0x09, + 0x82, 0x7B, 0x75, 0x34, 0x8C, 0x85, 0xBC, 0x25, + 0xDC, 0xE0, 0x50, 0xBA, 0x3D, 0xCD, 0x6E, 0xEF, + 0xA8, 0xB6, 0x86, 0xC9, 0xFB, 0x3C, 0xB1, 0xD1, + 0x7D, 0x3C, 0xBF, 0xFE, 0xA7, 0x98, 0x1F, 0x9F, + 0xD6, 0xBE, 0x05, 0xEC, 0x59, 0x14, 0xD1, 0x54, + 0x1F, 0x44, 0x82, 0xF8, 0x6C, 0x48, 0x23, 0x62, + 0x1C, 0xB1, 0x74, 0x84, 0x99, 0x09, 0x8F, 0x31, + 0x46, 0xEB, 0xF6, 0x19, 0xD6, 0x03, 0x58, 0x46, + 0x26, 0xE5, 0xA9, 0xED, 0x5A, 0xCF, 0x68, 0x07, + 0xFD, 0x49, 0x9E, 0xE5, 0x1E, 0x22, 0x7A, 0xAE, + 0x07, 0x55, 0xA8, 0xF3, 0x5F, 0xB1, 0x5F, 0xFA, + 0xFE, 0x16, 0x55, 0x8F, 0xCA, 0xED, 0x07, 0x17, + 0x76, 0x95, 0xC8, 0xDC, 0x2C, 0x28, 0x00, 0xC3, + 0xA5, 0x29, 0x94, 0x60, 0xAD, 0xDB, 0x91, 0x6A, + 0xE1, 0x1B, 0x91, 0xAF, 0xDC, 0x75, 0xE7, 0xC5, + 0x92, 0x9A, 0x76, 0x15, 0x0F, 0x19, 0xF7, 0xD6, + 0xAE, 0x35, 0x3C, 0x56, 0x39, 0x4B, 0x27, 0xA6, + 0xE0, 0x93, 0xC3, 0x39, 0x09, 0x15, 0x43, 0x39, + 0xC3, 0xEC, 0xC5, 0xBE, 0xF7, 0x8F, 0x28, 0x82, + 0xB9, 0xFE, 0xD4, 0x34, 0x7C, 0x5C, 0xCA, 0x5F, + 0x8D, 0x6B, 0x4B, 0xEF, 0xB9, 0x45, 0x89, 0x48, + 0x85, 0x45, 0xEC, 0x19, 0xEB, 0x0A, 0x62, 0x71, + 0x23, 0x8A, 0x8A, 0x9B, 0x27, 0xE4, 0xA8, 0x86, + 0x55, 0x11, 0xC4, 0xC2, 0xF1, 0x4D, 0x1B, 0x0C, + 0x4F, 0x7D, 0xCA, 0xCA, 0x50, 0x88, 0x98, 0xC9, + 0x86, 0xB9, 0xBD, 0x86, 0x7F, 0x18, 0xAE, 0x5B, + 0xFE, 0x5F, 0x88, 0xF5, 0xBE, 0x69, 0xB4, 0x49, + 0x1A, 0x08, 0xB8, 0x0C, 0x01, 0x3C, 0xD6, 0xB0, + 0xB4, 0x0E, 0xF0, 0x4D, 0xEC, 0x60, 0x90, 0x9A, + 0xFA, 0xF5, 0x18, 0x63, 0x2C, 0x10, 0x12, 0xC8, + 0x1A, 0x5D, 0xAC, 0xD3, 0xA8, 0x42, 0xA1, 0x0D, + 0x4D, 0x6F, 0x4E, 0x57, 0xE5, 0x51, 0x93, 0x50, + 0x00, 0xFB, 0x16, 0xA5, 0x4E, 0x25, 0x62, 0xD6, + 0x21, 0x9C, 0xC9, 0x65, 0x48, 0xC7, 0xDE, 0x69, + 0x83, 0xF7, 0x17, 0x66, 0xE0, 0x4B, 0x7D, 0x8E, + 0xFE, 0xE9, 0x78, 0xDF, 0x49, 0x21, 0xD7, 0x8A, + 0x41, 0xAC, 0xE8, 0xEC, 0x91, 0x75, 0x9E, 0xA4, + 0xC6, 0x72, 0x61, 0xF0, 0xF8, 0x51, 0xD5, 0xDC, + 0x45, 0xCA, 0x6A, 0xC3, 0x64, 0xB9, 0x96, 0x73, + 0x3B, 0xF0, 0xC7, 0x2A, 0x7E, 0x88, 0x4E, 0x17, + 0x20, 0xC0, 0x8B, 0x8A, 0x5C, 0x6F, 0xFB, 0xAD, + 0x2D, 0x3D, 0x86, 0xC6, 0x4E, 0xDB, 0x39, 0x7D, + 0x01, 0x84, 0x28, 0xF5, 0xF0, 0x73, 0x05, 0xE4, + 0x7B, 0x22, 0xF8, 0xD9, 0xD4, 0x0F, 0x17, 0xC0, + 0xC8, 0xA0, 0x2F, 0x62, 0x21, 0xE7, 0xCF, 0x91, + 0x46, 0xAC, 0x84, 0x95, 0x0C, 0x26, 0xDC, 0x3F, + 0x11, 0x2A, 0xE7, 0x60, 0x15, 0x8A, 0x50, 0x6F, + 0x31, 0x22, 0x49, 0x69, 0xDA, 0x16, 0x74, 0x35, + 0x72, 0x8D, 0xC0, 0x94, 0xB6, 0x15, 0x6B, 0x27, + 0xF6, 0x0C, 0x33, 0x69, 0x16, 0x3E, 0x14, 0xC5, + 0x5E, 0xF9, 0xF4, 0x97, 0x75, 0x02, 0x24, 0x3E, + 0x00, 0x9A, 0x4C, 0x01, 0x7D, 0xDB, 0xFE, 0xE0, + 0xE8, 0xBD, 0xBF, 0x27, 0x3E, 0x7F, 0x04, 0xA8, + 0x54, 0x06, 0xF9, 0xE5, 0x9C, 0xB9, 0x67, 0xEF, + 0x2C, 0x03, 0xCC, 0xCE, 0x8F, 0xD5, 0x70, 0x3E, + 0x3E, 0xD1, 0xBB, 0xC4, 0x62, 0x2B, 0x58, 0x46, + 0xA7, 0x76, 0x95, 0x78, 0x96, 0x91, 0xF8, 0x16, + 0xBA, 0xE7, 0x15, 0x63, 0xCE, 0xD4, 0x74, 0x63, + 0x35, 0x26, 0x4B, 0x3A, 0x9A, 0xEF, 0xCB, 0xCA, + 0xA3, 0x26, 0x8C, 0x75, 0x45, 0x42, 0xFF, 0x0E, + 0xE1, 0xFE, 0x7F, 0xCB, 0x5F, 0x58, 0xA8, 0xD5, + 0x8B, 0x88, 0x53, 0x6A, 0x29, 0xCE, 0xA2, 0x25, + 0x49, 0xDD, 0x9D, 0xDD, 0x97, 0xD1, 0xE8, 0x79, + 0x56, 0xDA, 0x32, 0xBB, 0xF7, 0x83, 0xF3, 0xD4, + 0x61, 0x4D, 0x2E, 0xBA, 0x95, 0x83, 0xD2, 0x16, + 0xF7, 0x83, 0x07, 0x7E, 0x01, 0x07, 0x6D, 0x90, + 0x6B, 0x0B, 0x63, 0xC7, 0xE5, 0x31, 0x07, 0x93, + 0x35, 0xA4, 0xC1, 0x1A, 0xB1, 0x12, 0x5A, 0x7D, + 0x5E, 0xD0, 0xB9, 0xD4, 0xDB, 0x4F, 0x8B, 0x18, + 0xF9, 0xE5, 0xC8, 0x29, 0x40, 0xD0, 0x95, 0x3C, + 0x32, 0x8D, 0x77, 0x8B, 0x55, 0x54, 0xC6, 0x65, + 0xB2, 0xE4, 0xEC, 0xE0, 0x21, 0xE2, 0xBD, 0x13, + 0xB7, 0xB5, 0xD8, 0xC1, 0x4A, 0x3B, 0xFE, 0x4D, + 0xF8, 0x46, 0x99, 0x7F, 0xA5, 0x3F, 0x3B, 0x51, + 0xA2, 0x9F, 0x9C, 0x64, 0xFE, 0x7B, 0xB3, 0x22, + 0x2A, 0xC3, 0xD2, 0x24, 0x83, 0xC1, 0x66, 0xD5, + 0x41, 0x04, 0x4C, 0xC3, 0xFC, 0x58, 0x75, 0xD9, + 0xBA, 0xC9, 0x1A, 0x9C, 0xDA, 0x8F, 0xFB, 0x15, + 0x01, 0x14, 0xE3, 0x8E, 0x3C, 0xBF, 0xCD, 0xB6, + 0x87, 0xCA, 0x37, 0x03, 0xCC, 0x65, 0xEF, 0x5A, + 0xBF, 0x4F, 0x26, 0xD7, 0xEA, 0x20, 0x05, 0x0C, + 0x09, 0x1D, 0xC7, 0xB7, 0xA7, 0xA7, 0xA9, 0x8A, + 0xA6, 0x1F, 0x52, 0x53, 0x62, 0x80, 0x56, 0x17, + 0x1D, 0x53, 0x12, 0x45, 0x71, 0x0C, 0xE4, 0x8A, + 0x40, 0xAD, 0x9F, 0x59, 0x2A, 0xDE, 0x12, 0x72, + 0xED, 0x5E, 0x54, 0x1D, 0xE4, 0xE9, 0x24, 0x4B, + 0xCF, 0x32, 0x80, 0x6C, 0xEA, 0xE7, 0xA2, 0x19, + 0x2E, 0x32, 0x86, 0x06, 0xB1, 0x95, 0x35, 0xC7, + 0x0E, 0x45, 0x22, 0xB7, 0x2B, 0xE9, 0x70, 0x61, + 0x66, 0xA8, 0xD2, 0x2A, 0x1C, 0xE9, 0x29, 0x08, + 0x95, 0xCF, 0x14, 0x9D, 0x40, 0x2B, 0x23, 0xFA, + 0x3A, 0xF0, 0xBC, 0x32, 0x9C, 0xF0, 0xA6, 0x1A, + 0x0F, 0x42, 0xC9, 0xA2, 0xAF, 0x20, 0xF9, 0xA9, + 0x2A, 0x05, 0x50, 0x9D, 0xDF, 0x9C, 0xB4, 0x5A, + 0x3B, 0x49, 0x3A, 0x2E, 0x71, 0xC7, 0x3E, 0xC1, + 0xC3, 0x84, 0x7E, 0x9E, 0x2C, 0xA8, 0xDD, 0x0F, + 0x1A, 0x94, 0x13, 0x1A, 0xB1, 0xC4, 0x34, 0x57, + 0xE3, 0xA2, 0x68, 0x5B, 0x04, 0x05, 0x81, 0xC8, + 0x5D, 0x7D, 0x8D, 0x0F, 0x35, 0x67, 0xFC, 0x4D, + 0x25, 0xDE, 0xF4, 0x69, 0xB0, 0x24, 0xCF, 0xFB, + 0xE7, 0xD9, 0x5C, 0x39, 0xE9, 0x96, 0xE3, 0x63, + 0x33, 0x75, 0x0B, 0x3C, 0x72, 0xC3, 0xA0, 0x83, + 0x97, 0xF8, 0xA5, 0x30, 0x7C, 0x8C, 0x70, 0x9E, + 0x50, 0x1D, 0xD9, 0x7F, 0xBE, 0x7B, 0x32, 0x81, + 0xBE, 0x62, 0x4D, 0xA6, 0x1B, 0x4F, 0x2D, 0x6A, + 0x24, 0xC8, 0xF6, 0x59, 0x19, 0x77, 0x83, 0x0D, + 0x18, 0x3A, 0x06, 0x96, 0x1F, 0xA1, 0x42, 0x6C, + 0x99, 0x66, 0x0B, 0x8E, 0xC1, 0xD6, 0x51, 0xD9, + 0x1A, 0x37, 0x2C, 0x95, 0xE8, 0xB5, 0xA3, 0xFF, + 0xAD, 0x80, 0x32, 0xF6, 0x7F, 0xC9, 0xC6, 0xDA, + 0x1B, 0x49, 0x60, 0xDD, 0x76, 0xC5, 0xDF, 0x97, + 0x90, 0x58, 0xB2, 0x22, 0x80, 0xD6, 0x50, 0x4E, + 0xBB, 0x51, 0x3D, 0x78, 0x76, 0x24, 0x5E, 0xD3, + 0xB0, 0x55, 0xC8, 0x09, 0xCE, 0xD5, 0x89, 0x4E, + 0x26, 0x26, 0x6E, 0x10, 0x8E, 0x46, 0xEC, 0xA3, + 0xAB, 0x0A, 0xFC, 0x22, 0x75, 0xCF, 0x80, 0x58, + 0x5F, 0x12, 0xC7, 0x25, 0x81, 0xDD, 0xBA, 0x5F, + 0x0D, 0xBE, 0x92, 0xDD, 0x33, 0x85, 0xE7, 0xE5, + 0x24, 0xCD, 0xF4, 0x64, 0xAE, 0xFC, 0x52, 0xE0, + 0x6E, 0x21, 0xA0, 0xB4, 0x21, 0xFC, 0xE9, 0xAF, + 0x68, 0xE8, 0x00, 0xF8, 0x9A, 0xCF, 0xDE, 0xAA, + 0xF5, 0xBC, 0xA6, 0xE3, 0xAC, 0xBF, 0xB2, 0x32, + 0x69, 0x9F, 0x59, 0x3A, 0x5E, 0xAB, 0xA2, 0x07, + 0xD1, 0xEE, 0x1C, 0xB1, 0x0E, 0x08, 0xF9, 0xB7, + 0xBD, 0x06, 0xB0, 0x82, 0x66, 0x41, 0x75, 0xB9, + 0x1E, 0xB0, 0xF9, 0x94, 0xB8, 0x2F, 0x7E, 0x72, + 0xC6, 0x0D, 0x88, 0x06, 0x67, 0x17, 0x5E, 0x21, + 0x7E, 0x35, 0xC1, 0x44, 0x59, 0xE8, 0x6C, 0x65, + 0x7A, 0x7D, 0x30, 0x34, 0x96, 0xB6, 0x9D, 0x41, + 0x7D, 0x25, 0x82, 0x6C, 0xE9, 0xA9, 0x28, 0xE7, + 0xBA, 0x3E, 0x20, 0x7B, 0xF0, 0x9A, 0xE7, 0xF2, + 0x7D, 0x79, 0x20, 0x7E, 0xA3, 0x64, 0x88, 0x19, + 0xCF, 0x2D, 0x81, 0xEA, 0x4B, 0x6C, 0xD0, 0xEB, + 0xEC, 0xC7, 0x70, 0x54, 0xDE, 0x45, 0x7C, 0x42, + 0xAF, 0x11, 0x43, 0x10, 0xFD, 0xFB, 0xE7, 0xD6, + 0x2B, 0x14, 0x9D, 0x97, 0x5A, 0x82, 0x12, 0xC2, + 0x37, 0x03, 0x0C, 0x48, 0x9A, 0x09, 0xB6, 0xE9, + 0xC3, 0x2A, 0xFC, 0xF5, 0x20, 0x10, 0x73, 0xED, + 0x47, 0x3F, 0xFA, 0xEB, 0x0C, 0xB0, 0xE0, 0x79, + 0xD7, 0xDB, 0x29, 0x34, 0x0F, 0x4D, 0xBF, 0x16, + 0x72, 0xBD, 0x5B, 0x88, 0xE3, 0x48, 0x33, 0x75, + 0x54, 0x6F, 0x1E, 0x49, 0x7A, 0x8B, 0x2B, 0xFA, + 0x4C, 0x52, 0xC4, 0x9C, 0xC5, 0x84, 0xB2, 0x2D, + 0xCD, 0xCD, 0x05, 0x48, 0xC4, 0xEB, 0x5E, 0xA8, + 0x7A, 0x1E, 0xA6, 0x9A, 0x5A, 0x42, 0x3B, 0xDE, + 0xB3, 0xD2, 0xBC, 0x83, 0x7D, 0xF0, 0x0C, 0xD8, + 0x6A, 0x4A, 0xF8, 0x49, 0xAC, 0xD0, 0xA1, 0x21, + 0xCD, 0x3F, 0x5D, 0x65, 0xB8, 0x25, 0x90, 0x61, + 0x04, 0xD8, 0xA1, 0x74, 0x29, 0x9E, 0x31, 0x2D, + 0x8C, 0x5F, 0x38, 0xAD, 0x57, 0x84, 0x93, 0x74, + 0xCD, 0x4E, 0x8D, 0x5D, 0x8F, 0xCF, 0xA0, 0x8E, + 0xE6, 0x2D, 0x2B, 0xED, 0x7F, 0xC0, 0x0F, 0x69, + 0xED, 0x2E, 0x2A, 0xF4, 0x5D, 0xD3, 0x16, 0xD4, + 0xED, 0x9A, 0xBF, 0x59, 0x53, 0x0C, 0x5E, 0x99, + 0x88, 0xB9, 0xF4, 0x00, 0x5B, 0xAC, 0xC7, 0x59, + 0x71, 0xCB, 0xE9, 0xE0, 0x6D, 0xEC, 0x1A, 0xCD, + 0xB9, 0xAA, 0xB2, 0xB4, 0x56, 0x1D, 0x4F, 0x0A, + 0xB2, 0xF5, 0x53, 0x9D, 0x6B, 0xE1, 0xE2, 0xE8, + 0x27, 0x70, 0x50, 0xF5, 0xBC, 0xF2, 0x20, 0x34, + 0xDA, 0x86, 0xF4, 0x11, 0xD7, 0x80, 0xEF, 0xC8, + 0xC3, 0xF0, 0xF0, 0x4E, 0x38, 0xE9, 0x07, 0xCC, + 0x61, 0x6B, 0xE4, 0xA2, 0x2C, 0x13, 0x0A, 0xD0, + 0x81, 0x8A, 0x4A, 0xCC, 0x6F, 0x93, 0x41, 0x5F, + 0x6D, 0x6B, 0xF0, 0x2A, 0x6B, 0x0D, 0x51, 0x0B, + 0x24, 0x30, 0xDA, 0x26, 0x78, 0xD5, 0x84, 0x25, + 0x90, 0x4C, 0x41, 0xF9, 0x83, 0x14, 0x15, 0x20, + 0xCC, 0x8C, 0xAE, 0x4E, 0x3E, 0x99, 0xE6, 0xED, + 0x39, 0x63, 0x04, 0x13, 0x2C, 0xD7, 0x9F, 0x84, + 0x83, 0xD3, 0x49, 0xC6, 0x82, 0x7B, 0x34, 0xA0, + 0xA0, 0x60, 0x1B, 0x2B, 0x57, 0xF2, 0x4C, 0xAB, + 0x80, 0x3B, 0x33, 0x11, 0xE8, 0x55, 0x97, 0x5A, + 0xED, 0xC3, 0xE4, 0x6B, 0x05, 0xA9, 0x83, 0xA0, + 0x5C, 0x83, 0xD4, 0x3A, 0x9D, 0x3B, 0xA2, 0x05, + 0x48, 0xFA, 0xD7, 0x01, 0x46, 0x1F, 0x1F, 0xAC, + 0xF1, 0xF7, 0x1A, 0xB0, 0xD2, 0xF1, 0xEC, 0x8B, + 0x67, 0xCD, 0x98, 0x90, 0x9E, 0xC7, 0x70, 0xDC, + 0x43, 0xAA, 0x56, 0xE9, 0x17, 0xCF, 0x81, 0x72, + 0x45, 0xD3, 0x47, 0x40, 0xF7, 0x38, 0x04, 0xE7, + 0x67, 0x93, 0x5B, 0x4D, 0xE3, 0xE7, 0xDA, 0x77, + 0xA7, 0xC9, 0x1C, 0x26, 0xDF, 0xA2, 0x03, 0xE9, + 0x47, 0x41, 0x35, 0x71, 0xA5, 0xBE, 0x67, 0xA8, + 0xD8, 0x74, 0x47, 0x39, 0xE3, 0xCC, 0xC9, 0x19, + 0xB9, 0xA3, 0x8D, 0xB1, 0x2B, 0xDE, 0xBF, 0xFE, + 0x8E, 0x81, 0xC2, 0x89, 0x30, 0x1D, 0xF7, 0xF0, + 0x47, 0xB9, 0x7C, 0x73, 0xB4, 0xB3, 0x17, 0x10, + 0x8E, 0x7D, 0x68, 0x5A, 0x14, 0x6C, 0x81, 0x7C, + 0x23, 0xAB, 0x8E, 0x45, 0x39, 0x08, 0x34, 0x00, + 0x92, 0xD7, 0x75, 0xE7, 0x64, 0x3E, 0xDC, 0x56, + 0x96, 0xDC, 0x51, 0x9D, 0x63, 0x4C, 0xE4, 0xF2, + 0x75, 0xD2, 0x03, 0x9E, 0xFB, 0x39, 0x1D, 0xCC, + 0x70, 0x9E, 0xB8, 0x03, 0xF1, 0x14, 0xCD, 0x10, + 0x39, 0x66, 0x18, 0xCE, 0xAD, 0xAC, 0xAB, 0x56, + 0x83, 0x06, 0xCF, 0xDB, 0x2B, 0x80, 0x06, 0x39, + 0x97, 0xC7, 0x15, 0x85, 0x48, 0x64, 0x6F, 0xEF, + 0x78, 0x34, 0x01, 0x84, 0xBF, 0x1D, 0xD7, 0xAE, + 0xE0, 0xEE, 0x6C, 0x66, 0x0B, 0x8E, 0xDF, 0xB6, + 0x45, 0xA2, 0x59, 0xBB, 0xAD, 0x3F, 0xC4, 0xC0, + 0x8A, 0x88, 0xA5, 0x54, 0xE0, 0xEE, 0xBD, 0xB4, + 0x4D, 0x74, 0xDC, 0x6F, 0xBC, 0x0E, 0xF1, 0x7E, + 0xA8, 0x32, 0x10, 0x60, 0x89, 0x0D, 0xC3, 0x47, + 0x9F, 0xDE, 0x6C, 0x0B, 0x9D, 0x48, 0x8C, 0x11, + 0x2B, 0x52, 0x61, 0x7E, 0x87, 0xDD, 0x81, 0xC8, + 0xE3, 0x3E, 0x46, 0xBB, 0x1F, 0xFF, 0x67, 0x5F, + 0xF8, 0x24, 0x90, 0x8F, 0x52, 0x11, 0x7E, 0x5B, + 0x59, 0x76, 0xBC, 0x51, 0xAE, 0x3F, 0x39, 0xE7, + 0xAF, 0x99, 0x54, 0x0A, 0x85, 0xDD, 0xCD, 0x0C, + 0x63, 0xA7, 0xA0, 0x99, 0x3E, 0xF9, 0x79, 0xE1, + 0xE8, 0x5A, 0xD7, 0x7D, 0x81, 0x39, 0x9B, 0xFA, + 0x50, 0xC2, 0xAB, 0xF0, 0xAC, 0xC4, 0xA9, 0x00, + 0xAF, 0x3C, 0x63, 0xF1, 0x25, 0x22, 0xA8, 0x53, + 0x47, 0x1C, 0x0F, 0xF6, 0x64, 0x8C, 0x7F, 0x83, + 0x29, 0xF8, 0x9A, 0xF5, 0x6E, 0x3F, 0x32, 0xE5, + 0xE1, 0x31, 0x89, 0xD3, 0xA3, 0x58, 0xA8, 0xEB, + 0x8D, 0x56, 0xE3, 0x79, 0xA7, 0xF6, 0x6C, 0xEF, + 0x79, 0x91, 0x8B, 0xB6, 0x58, 0xF1, 0xBB, 0xA1, + 0xF1, 0x4D, 0x60, 0x4F, 0xBA, 0xF0, 0x5A, 0x4F, + 0x9A, 0xC0, 0x0F, 0x38, 0x17, 0x85, 0xD9, 0xA5, + 0x63, 0x9B, 0x45, 0x2D, 0x1F, 0x58, 0xF8, 0xEF, + 0x92, 0x0A, 0x07, 0xEE, 0xC8, 0x7E, 0x67, 0x62, + 0xB6, 0xD9, 0x34, 0x71, 0xC2, 0xC6, 0x9C, 0xDD, + 0xB3, 0x64, 0xBC, 0x80, 0x4B, 0x46, 0xCE, 0xC0, + 0x4F, 0xD3, 0x6C, 0xAC, 0x47, 0x93, 0x5F, 0x86, + 0x48, 0x79, 0x1A, 0x4F, 0x6C, 0x5D, 0x90, 0x84, + 0x49, 0xD4, 0x82, 0xAF, 0x29, 0xD6, 0xAE, 0x13, + 0x90, 0x07, 0xDB, 0xB8, 0xFB, 0xF1, 0x37, 0x2A, + 0xC6, 0x2D, 0x8E, 0xA6, 0xCF, 0xAE, 0x7B, 0xBD, + 0xD9, 0x00, 0x80, 0xA2, 0xBD, 0x0B, 0xEF, 0xC7, + 0x33, 0xF9, 0x8C, 0x4C, 0x42, 0x7C, 0x68, 0x4E, + 0x54, 0x61, 0x06, 0x1E, 0x23, 0x93, 0x03, 0x76, + 0xF7, 0xD4, 0xC5, 0xBE, 0x89, 0x6E, 0x6C, 0x48, + 0x11, 0xAD, 0xC6, 0xFF, 0xAB, 0x58, 0x10, 0x43, + 0xD7, 0xC5, 0xBF, 0x73, 0x8E, 0x57, 0x0A, 0xCF, + 0xD0, 0x08, 0xE3, 0x24, 0x6B, 0x97, 0x4C, 0x87, + 0x00, 0xB9, 0x45, 0x52, 0x62, 0xF7, 0xEF, 0xAA, + 0xA4, 0xB8, 0x98, 0x5C, 0xC7, 0xF0, 0xE7, 0x2C, + 0xED, 0x26, 0x0F, 0x4C, 0x93, 0x8D, 0x27, 0x08, + 0xB1, 0xC1, 0x7D, 0xC6, 0xB1, 0xE8, 0x25, 0x0F, + 0x8F, 0xD1, 0x71, 0x4A, 0x85, 0x3A, 0xCC, 0x20, + 0xFA, 0x06, 0x98, 0x5A, 0x4F, 0x3F, 0x13, 0x78, + 0xEB, 0x99, 0x80, 0x42, 0xA1, 0x02, 0x90, 0x96, + 0x1F, 0xC9, 0x07, 0xBF, 0x61, 0xCA, 0x2D, 0x98, + 0xA0, 0x0F, 0x5B, 0x84, 0x76, 0x28, 0x5B, 0x4F, + 0x81, 0x14, 0xEE, 0x28, 0x8B, 0x62, 0x01, 0xBD, + 0x34, 0xE9, 0x45, 0x5B, 0x91, 0x1C, 0xEA, 0xAD, + 0x00, 0xD5, 0x23, 0x92, 0x28, 0x4A, 0xA9, 0x89, + 0x3F, 0x57, 0x24, 0xBE, 0xFF, 0x4F, 0xD6, 0x99, + 0x6B, 0x92, 0xF7, 0xB0, 0x1B, 0x9E, 0x9C, 0xB4, + 0xDB, 0x42, 0x65, 0xEB, 0xDD, 0x54, 0x56, 0xE9, + 0x3F, 0xD5, 0x3D, 0x9A, 0x4F, 0xD9, 0xDA, 0xD6, + 0x27, 0x2D, 0x83, 0xF0, 0xF1, 0x33, 0x22, 0x51, + 0x81, 0xF9, 0x00, 0x74, 0xB1, 0x2F, 0xE0, 0x35, + 0x3A, 0x1A, 0x92, 0x27, 0xE5, 0x24, 0x9C, 0x6A, + 0x00, 0x74, 0xFF, 0x52, 0x7A, 0xB8, 0xD5, 0x42, + 0xBF, 0x4E, 0xA2, 0x4D, 0x1E, 0x16, 0x31, 0x41, + 0x0A, 0xEE, 0x89, 0xE4, 0x86, 0x70, 0xCE, 0x85, + 0xCF, 0xB6, 0xE6, 0x7A, 0xF3, 0x56, 0xE9, 0xEB, + 0xE5, 0xDC, 0x0B, 0xCE, 0x5C, 0x3C, 0xEC, 0x92, + 0xA7, 0x7F, 0x12, 0xB5, 0x48, 0x43, 0xD6, 0x68, + 0xB4, 0x0B, 0x4C, 0xA0, 0xD5, 0xEE, 0xD9, 0x7E, + 0xE4, 0xC3, 0xCC, 0x54, 0x93, 0x1A, 0xD3, 0xF8, + 0x91, 0xF7, 0xF3, 0x6D, 0x14, 0x12, 0x40, 0x40, + 0xC0, 0x26, 0xAD, 0xE9, 0x45, 0xFA, 0x9C, 0xCB, + 0x5D, 0x85, 0xBE, 0xE7, 0x52, 0xDD, 0xC2, 0x8D, + 0xBF, 0xA2, 0x0A, 0x33, 0x49, 0x61, 0x5B, 0x2A, + 0x23, 0x12, 0xDF, 0x4E, 0xAF, 0x66, 0x6F, 0x6B, + 0xCE, 0xAB, 0x03, 0x8E, 0x75, 0x08, 0x32, 0x77, + 0xD3, 0x27, 0x45, 0x8D, 0x87, 0xA4, 0x2E, 0x1A, + 0xC5, 0xEC, 0x08, 0x64, 0xF5, 0x0B, 0xAA, 0x63, + 0x00, 0x24, 0x04, 0x2C, 0xD6, 0xD8, 0x6D, 0x5B, + 0x3D, 0xDD, 0x80, 0xD9, 0xF9, 0x68, 0x0C, 0xDF, + 0x98, 0x00, 0x38, 0xF5, 0x59, 0xBD, 0x13, 0xF2, + 0xDC, 0xB1, 0x86, 0x7F, 0x70, 0x6C, 0xFB, 0x7D, + 0x5B, 0x04, 0xAD, 0x53, 0x72, 0xC1, 0xF1, 0x3D, + 0xB2, 0x7E, 0xFD, 0x25, 0xA9, 0x80, 0x10, 0x4F, + 0x98, 0xB3, 0x6A, 0xD8, 0xBD, 0x08, 0x91, 0xC9, + 0x0F, 0x43, 0x09, 0x86, 0x2A, 0x82, 0xB9, 0x27, + 0x78, 0xCE, 0xD4, 0xBC, 0x9E, 0x1E, 0xD9, 0x25, + 0x12, 0x75, 0x7A, 0xD4, 0x03, 0xE7, 0x0C, 0xB1, + 0xCB, 0xF8, 0x04, 0x9C, 0xF4, 0x09, 0x9D, 0x63, + 0x09, 0x8F, 0x1F, 0x95, 0x75, 0x21, 0x12, 0x84, + 0xF9, 0xA1, 0x30, 0x75, 0x70, 0xDA, 0xFD, 0x38, + 0x5D, 0x56, 0x49, 0x7E, 0xCA, 0x53, 0xED, 0x4B, + 0x7D, 0xD5, 0xFE, 0xE7, 0x8F, 0x09, 0x57, 0xAF, + 0x2A, 0x67, 0x0C, 0xDB, 0x55, 0xCB, 0x0E, 0x4C, + 0xA1, 0xC7, 0xE0, 0xC7, 0xEF, 0x2A, 0x77, 0x0B, + 0x55, 0x17, 0xB2, 0xFA, 0x70, 0x88, 0xC2, 0xF0, + 0xB6, 0xD0, 0x24, 0x96, 0xCA, 0x60, 0x01, 0xB3, + 0x99, 0xFB, 0x59, 0x0B, 0xF4, 0x22, 0xDB, 0x32, + 0x8E, 0x01, 0x17, 0x60, 0x96, 0xE5, 0xBF, 0xB7, + 0x40, 0x3F, 0xD6, 0x2E, 0x7F, 0xC5, 0x25, 0x16, + 0xE2, 0x3A, 0xCB, 0x64, 0xFE, 0x97, 0xAA, 0xDD, + 0xB8, 0x88, 0x81, 0x81, 0x7A, 0x4C, 0xE0, 0xCF, + 0x4E, 0xBD, 0x32, 0x80, 0x50, 0x8D, 0xED, 0x82, + 0xAE, 0x68, 0xC4, 0x0C, 0x17, 0x55, 0x67, 0xCE, + 0x99, 0xD6, 0x1E, 0xEA, 0x19, 0x3B, 0x4C, 0xCC, + 0x4E, 0x03, 0x06, 0xB9, 0xDF, 0x98, 0xDA, 0xB1, + 0x2E, 0xB9, 0x8E, 0xFD, 0x3D, 0xA0, 0x9B, 0xD4, + 0xA7, 0x66, 0x3F, 0x6E, 0xE6, 0x99, 0xD3, 0x2E, + 0x4E, 0x78, 0xDF, 0x73, 0xA2, 0x4B, 0xA0, 0x15, + 0x90, 0x9A, 0x2C, 0x1A, 0xB0, 0x5E, 0xE7, 0xB0, + 0xFE, 0x69, 0xD4, 0x6F, 0x34, 0x9F, 0xEA, 0x47, + 0x3B, 0x72, 0x99, 0xD3, 0xA4, 0xA1, 0xDC, 0xD5, + 0xDC, 0x0C, 0x7E, 0x24, 0x31, 0x6B, 0x6D, 0x19, + 0x47, 0x1C, 0x02, 0x3F, 0x3C, 0x8A, 0xF7, 0xA4, + 0x3D, 0xF3, 0x08, 0x36, 0xC0, 0x7A, 0xD1, 0x18, + 0x15, 0x54, 0xDC, 0xFF, 0xF3, 0xFF, 0xAC, 0x76, + 0x56, 0x02, 0x7A, 0x72, 0xAC, 0x8A, 0x59, 0xE4, + 0x7E, 0x7A, 0xC4, 0x4C, 0x37, 0x5D, 0x9C, 0xFF, + 0x97, 0x64, 0x5E, 0x77, 0xC5, 0x2A, 0xE0, 0xD7, + 0x67, 0xAD, 0xE6, 0x2E, 0x92, 0xF9, 0x21, 0x48, + 0x07, 0x26, 0xAB, 0xA7, 0xD3, 0xE9, 0xA1, 0x8D, + 0x27, 0x89, 0xE9, 0x90, 0x2D, 0x4E, 0x33, 0xDE, + 0xDD, 0xB1, 0x41, 0xC6, 0x58, 0x30, 0xA8, 0x55, + 0x9A, 0x06, 0xFF, 0xE2, 0x96, 0x7A, 0x52, 0x3B, + 0xC5, 0x20, 0xDA, 0x43, 0x58, 0xC1, 0x9F, 0x8C, + 0xA1, 0x6F, 0xA8, 0x37, 0xA4, 0xDE, 0xE5, 0x96, + 0x8C, 0x37, 0x08, 0xB7, 0x84, 0xFF, 0x47, 0x8E, + 0xA1, 0x69, 0x4A, 0x20, 0x0C, 0x6E, 0x2F, 0x7D, + 0xEE, 0x9B, 0x25, 0x29, 0xCE, 0x3F, 0x5B, 0xF6, + 0x20, 0x79, 0xC9, 0x1E, 0xFE, 0xB5, 0xA8, 0x98, + 0x33, 0x43, 0x86, 0x5C, 0xDD, 0xDC, 0xBD, 0x8A, + 0x3C, 0xC1, 0xCE, 0x60, 0x22, 0x5D, 0x76, 0xBF, + 0xAF, 0x9D, 0x91, 0x7D, 0x68, 0x22, 0xD5, 0xE5, + 0xC1, 0x37, 0xA8, 0x87, 0xA4, 0x61, 0xD5, 0x2C, + 0x7A, 0xDD, 0xAF, 0xF0, 0x95, 0x8C, 0xB4, 0xB0, + 0x25, 0x58, 0x35, 0x6C, 0x0E, 0xF4, 0xDC, 0x73, + 0xDB, 0xAC, 0x9E, 0xEE, 0x4E, 0x5B, 0x4F, 0xEB, + 0x33, 0xCB, 0x4A, 0xC3, 0x68, 0x3A, 0x6D, 0xCD, + 0x38, 0xCE, 0xD1, 0x3B, 0x17, 0x29, 0x1C, 0x66, + 0xF0, 0x3B, 0x2E, 0x36, 0xFF, 0x14, 0xF6, 0x3C, + 0x58, 0xF5, 0xEB, 0xF3, 0x46, 0x23, 0x66, 0x19, + 0x36, 0xA6, 0x2B, 0x93, 0x7C, 0x35, 0x71, 0x75, + 0xA3, 0x7A, 0x61, 0x00, 0x03, 0xAE, 0x8C, 0x53, + 0xDB, 0xBA, 0xC7, 0x52, 0x2C, 0x01, 0x65, 0xBA, + 0xF5, 0x5D, 0xFD, 0xEF, 0xA5, 0xDB, 0x6F, 0x1F, + 0x83, 0x10, 0xAB, 0x50, 0xF1, 0x7A, 0xBD, 0xF9, + 0x8D, 0xBF, 0x8B, 0xBB, 0x9E, 0x4F, 0x18, 0xA3, + 0xC1, 0x79, 0x36, 0x97, 0xF9, 0xA1, 0x39, 0x4A, + 0x7B, 0x34, 0xD2, 0x48, 0x4F, 0x1B, 0xE6, 0xFB, + 0x93, 0x67, 0x28, 0xA8, 0x28, 0xF8, 0xFF, 0xED, + 0x31, 0x65, 0xA3, 0x47, 0x55, 0xAB, 0x5F, 0x43, + 0x05, 0xAB, 0x54, 0x5C, 0xED, 0x4C, 0x1A, 0x20, + 0xA4, 0x5A, 0x5B, 0x39, 0xBA, 0x5C, 0x5D, 0x5A, + 0x38, 0x78, 0x71, 0x76, 0x66, 0xB3, 0x53, 0x4A, + 0xE5, 0xE2, 0x90, 0xE4, 0xD7, 0x76, 0x84, 0x87, + 0xF7, 0xB5, 0xF4, 0xDD, 0x59, 0xAA, 0xFB, 0x44, + 0xA0, 0x5C, 0x7D, 0x56, 0x04, 0x59, 0xF2, 0x0E, + 0xDD, 0xE9, 0xBF, 0xE3, 0x06, 0xB9, 0x6A, 0x3E, + 0xD3, 0x41, 0xE5, 0xC5, 0xFB, 0xA5, 0x9B, 0x89, + 0x55, 0x1A, 0x2D, 0x27, 0xFF, 0x2E, 0x2E, 0xCA, + 0x95, 0x94, 0x9F, 0x3D, 0x95, 0x7E, 0x27, 0xA3, + 0x47, 0x04, 0xA1, 0x1F, 0xCB, 0xDD, 0xB3, 0xA3, + 0x30, 0x96, 0x4C, 0x78, 0xCE, 0x9B, 0x00, 0xA3, + 0x22, 0xAF, 0xB7, 0x9D, 0x52, 0x5C, 0xB5, 0x40, + 0xFA, 0xC0, 0xA7, 0x20, 0x60, 0xC4, 0x33, 0xD4, + 0xDF, 0x24, 0xBE, 0x9A, 0x7E, 0xE7, 0xC5, 0x21, + 0x37, 0xF1, 0x62, 0x8F, 0x0F, 0x01, 0xB3, 0xF4, + 0x06, 0xC7, 0xBC, 0x21, 0x78, 0x8F, 0x18, 0x89, + 0x03, 0xB5, 0x75, 0x88, 0x28, 0x74, 0x55, 0xA8, + 0xDB, 0xD1, 0x04, 0x01, 0xA0, 0x84, 0x84, 0x27, + 0xE0, 0x6F, 0x19, 0x8F, 0xE5, 0xA6, 0xE3, 0x61, + 0x75, 0x92, 0xE1, 0x25, 0x82, 0x5E, 0x8D, 0x79, + 0x5E, 0x9C, 0x3B, 0x14, 0xAC, 0x51, 0x06, 0x3D, + 0x13, 0xB9, 0x3D, 0xDD, 0xE5, 0x65, 0xFC, 0xBC, + 0x19, 0xD3, 0xA6, 0x1F, 0x3E, 0xB4, 0xA3, 0x08, + 0xEA, 0x67, 0x26, 0x0B, 0x11, 0x9E, 0x8D, 0xC8, + 0xF1, 0x1B, 0x0F, 0x6C, 0x5E, 0x6C, 0xBD, 0xD3, + 0x41, 0xEF, 0x1E, 0xFD, 0xD3, 0x31, 0x0D, 0x41, + 0xAF, 0x9A, 0xD0, 0xAD, 0xC1, 0x31, 0xE3, 0x2E, + 0x81, 0xE9, 0x43, 0x3B, 0xEB, 0x3D, 0x40, 0xF9, + 0x60, 0x29, 0xE7, 0xA1, 0x89, 0xDD, 0x0E, 0xF2, + 0x14, 0x1F, 0x0D, 0xD5, 0xC0, 0x76, 0xFF, 0x72, + 0x4B, 0x09, 0xD5, 0x1A, 0x9A, 0x1D, 0x7F, 0xBA, + 0x24, 0x17, 0x40, 0xC1, 0x72, 0xA8, 0x0A, 0xFF, + 0xEA, 0x3B, 0x33, 0x84, 0xFD, 0xA2, 0xD8, 0xA5, + 0x76, 0x0A, 0x74, 0x15, 0x3B, 0x72, 0x80, 0x94, + 0x24, 0x0F, 0xBB, 0xE1, 0x2C, 0x6E, 0x65, 0xC1, + 0xBA, 0x7B, 0xC9, 0x75, 0x8C, 0x5C, 0x5B, 0xC9, + 0x69, 0x72, 0xFD, 0x62, 0x80, 0x1F, 0x6A, 0x83, + 0xCE, 0xD8, 0x50, 0x6F, 0x43, 0x8D, 0x49, 0x32, + 0x5B, 0x9A, 0xCE, 0xD0, 0x45, 0x90, 0xBD, 0xF6, + 0x21, 0x3C, 0xED, 0x50, 0xC2, 0xA1, 0x69, 0x72, + 0x65, 0x68, 0x78, 0xCA, 0x22, 0xD5, 0xC4, 0xA5, + 0x0B, 0x00, 0x8A, 0x62, 0x88, 0xE9, 0x32, 0xEC, + 0x41, 0x56, 0x76, 0x99, 0x51, 0xD0, 0x96, 0x62, + 0x4E, 0x72, 0xA9, 0x95, 0xA1, 0xDF, 0xBC, 0x75, + 0x47, 0x34, 0x48, 0x72, 0x5C, 0xEF, 0x79, 0x0D, + 0xB4, 0x87, 0xEC, 0x88, 0xE0, 0x87, 0xA7, 0x1C, + 0x8C, 0xC4, 0x9E, 0x8F, 0xC0, 0x6B, 0x7B, 0x69, + 0xF8, 0xE0, 0x75, 0xF3, 0xB5, 0xC5, 0xCA, 0x5E, + 0xE9, 0xBA, 0x42, 0x03, 0x59, 0x21, 0xB8, 0x6C, + 0xEE, 0xAF, 0xE2, 0xD3, 0x5D, 0x55, 0x2D, 0xDE, + 0x29, 0xC5, 0x59, 0x92, 0xA9, 0x8F, 0xC7, 0x81, + 0x2F, 0x74, 0x40, 0x7A, 0xE3, 0x9A, 0xF6, 0x30, + 0x6F, 0x1A, 0xBC, 0xB4, 0x1D, 0xCA, 0x65, 0x0A, + 0x8A, 0x6C, 0x0A, 0x38, 0x9D, 0xD3, 0xCB, 0x24, + 0x96, 0xBD, 0x62, 0xC7, 0xC2, 0xF4, 0x0A, 0x36, + 0x99, 0x33, 0x8B, 0xC8, 0xEC, 0x4C, 0xF2, 0xB6, + 0xA9, 0x60, 0xAD, 0xB2, 0xB8, 0xFF, 0xC8, 0x13, + 0xEE, 0x09, 0xB4, 0x6E, 0xC5, 0x08, 0xF4, 0x28, + 0x6D, 0x1F, 0x59, 0x39, 0x1F, 0x68, 0x9B, 0x7F, + 0xBA, 0x3E, 0xA3, 0x93, 0xCD, 0x51, 0x90, 0x3E, + 0xA6, 0x1A, 0x34, 0x6D, 0x03, 0x1E, 0xBB, 0x40, + 0x63, 0xCF, 0x5D, 0xA2, 0xEA, 0x9A, 0x36, 0x39, + 0x26, 0x23, 0x52, 0x4E, 0xE1, 0x02, 0x65, 0x0D, + 0x27, 0x0E, 0x27, 0xC7, 0xC2, 0x32, 0x3F, 0x4E, + 0x52, 0xF8, 0x81, 0x42, 0x83, 0x98, 0x71, 0x47, + 0x26, 0xA2, 0xB2, 0x29, 0x64, 0x72, 0x97, 0x27, + 0xC0, 0xFF, 0x8F, 0x35, 0x41, 0xD7, 0x0A, 0xDA, + 0x11, 0x43, 0x2A, 0x04, 0x60, 0xF8, 0x97, 0x77, + 0x73, 0x26, 0xC3, 0x53, 0x09, 0xFD, 0x95, 0x55, + 0x78, 0x16, 0x6E, 0xC9, 0x09, 0x00, 0x64, 0x4A, + 0xF3, 0x46, 0xDF, 0x8B, 0xAD, 0x3A, 0x26, 0x9A, + 0x24, 0xE9, 0xE9, 0x38, 0xA1, 0x5A, 0x4E, 0x72, + 0x7A, 0xF4, 0xEF, 0xE1, 0x61, 0x01, 0x24, 0x53, + 0xB0, 0x26, 0x19, 0xB8, 0x9D, 0x21, 0x10, 0xDC, + 0x56, 0x40, 0x86, 0x66, 0x6B, 0xAA, 0x3C, 0x73, + 0x30, 0xF4, 0x0E, 0x10, 0x20, 0x02, 0xC6, 0x86, + 0xB3, 0xCA, 0xDF, 0x57, 0xAE, 0xBC, 0xB1, 0x3F, + 0x12, 0x31, 0x74, 0xE7, 0x63, 0x52, 0xD2, 0x74, + 0x95, 0x1F, 0x7B, 0x5E, 0xE2, 0x4F, 0x4D, 0xF9, + 0x36, 0xC8, 0xF9, 0x05, 0x03, 0x22, 0x44, 0x16, + 0x24, 0x4E, 0x30, 0x6B, 0xAA, 0x67, 0xF1, 0xCD, + 0x99, 0x3E, 0x55, 0xCF, 0x43, 0xC0, 0x69, 0x97, + 0xB4, 0x76, 0x87, 0xB5, 0xD5, 0x92, 0x32, 0x42, + 0xFA, 0xC9, 0x77, 0x2B, 0x33, 0xEA, 0x10, 0xBE, + 0x5F, 0x31, 0x65, 0xBA, 0xD2, 0xBC, 0x49, 0x2A, + 0x9F, 0x93, 0x5B, 0xAD, 0x04, 0x63, 0x2A, 0xE4, + 0x6F, 0x51, 0x0B, 0xB4, 0x5C, 0x0A, 0xD2, 0x07, + 0x95, 0xB8, 0xC8, 0xB7, 0x55, 0xC6, 0x09, 0xE4, + 0xB5, 0xF2, 0x89, 0x68, 0x6D, 0x65, 0x4C, 0xB4, + 0x02, 0xD5, 0xB5, 0xB3, 0x9A, 0x2D, 0xED, 0xE5, + 0x43, 0xE8, 0x64, 0x65, 0xFE, 0xD7, 0xDC, 0x92, + 0x9F, 0xF4, 0x92, 0xA7, 0x38, 0xD5, 0xA1, 0xCB, + 0xCF, 0x32, 0xAD, 0xD2, 0x4A, 0x3F, 0xF5, 0x13, + 0x73, 0x06, 0x3D, 0x0F, 0xCB, 0xF7, 0xA0, 0xA2, + 0x2A, 0x54, 0x60, 0xC7, 0xEA, 0x08, 0xFE, 0x56, + 0x4B, 0xEB, 0x65, 0x7B, 0x7E, 0xD6, 0xD4, 0x71, + 0xC6, 0xF6, 0x5D, 0x27, 0x13, 0x8C, 0x89, 0x2C, + 0x44, 0xD9, 0xE4, 0x3F, 0x5E, 0xC4, 0x90, 0xEA, + 0x33, 0xE6, 0xE1, 0x6F, 0xFF, 0x9E, 0x89, 0xF1, + 0x2C, 0xFF, 0x5D, 0xC0, 0x94, 0x2C, 0xBC, 0xCA, + 0x4D, 0x9A, 0xC4, 0xCA, 0x78, 0x45, 0xC3, 0x3A, + 0x61, 0xD7, 0xA1, 0xF7, 0x8E, 0x26, 0xB4, 0xF6, + 0x9E, 0x75, 0x20, 0x18, 0x1A, 0xAA, 0x35, 0x4F, + 0xAC, 0xA9, 0x82, 0xFE, 0xF8, 0xCA, 0x6D, 0x79, + 0xFD, 0xE1, 0x2C, 0xB5, 0xB1, 0x3B, 0xAB, 0xCC, + 0x5C, 0x55, 0x73, 0x47, 0x8F, 0xB6, 0x04, 0x1A, + 0x49, 0x64, 0x27, 0xC8, 0x88, 0x7D, 0xFD, 0x2F, + 0x78, 0x40, 0x9D, 0xDB, 0x9D, 0x76, 0x25, 0x05, + 0x72, 0xC1, 0x7B, 0x9B, 0xD5, 0x86, 0xD3, 0x62, + 0x91, 0xCF, 0x39, 0xAD, 0x31, 0x9E, 0x5A, 0x36, + 0x37, 0x6D, 0x79, 0xE6, 0xDB, 0x02, 0x3D, 0xD5, + 0x67, 0xB2, 0xC9, 0xE3, 0x09, 0x00, 0x01, 0xBC, + 0xC8, 0x2D, 0x70, 0xB8, 0x03, 0x54, 0x8F, 0xF8, + 0x63, 0x27, 0x43, 0x29, 0x84, 0xDD, 0xB0, 0xC5, + 0xD3, 0x4B, 0x60, 0x2C, 0xB1, 0xF4, 0x47, 0xA5, + 0xD4, 0xC5, 0x88, 0x56, 0x44, 0xBC, 0x3C, 0x63, + 0x87, 0xF3, 0xD4, 0xAE, 0x76, 0xAA, 0x4E, 0x58, + 0x76, 0x65, 0x41, 0xD7, 0xC6, 0x08, 0xB6, 0x39, + 0x54, 0xD9, 0x0B, 0xF2, 0x5C, 0x8B, 0xB2, 0xEA, + 0x0F, 0x90, 0x13, 0xB5, 0x17, 0xA1, 0xAB, 0x7A, + 0xBD, 0xB2, 0x84, 0x8C, 0xB4, 0x17, 0x30, 0x7A, + 0x30, 0xEA, 0x32, 0x8F, 0x67, 0x7A, 0xC6, 0xCC, + 0x8A, 0xB7, 0x32, 0xB0, 0x0B, 0x3D, 0x91, 0x67, + 0x5D, 0x23, 0xDB, 0x7C, 0x87, 0x5F, 0x31, 0xF6, + 0xBD, 0xD5, 0x20, 0x62, 0xE0, 0xAE, 0xA1, 0xB3, + 0xDE, 0xA8, 0x14, 0x5C, 0x27, 0x7A, 0x23, 0x84, + 0x8C, 0x52, 0x14, 0x94, 0x46, 0x3E, 0x6D, 0xAD, + 0xB6, 0xB6, 0xFE, 0x78, 0xD6, 0x1A, 0xF5, 0xCC, + 0x32, 0xE9, 0x16, 0x24, 0xF5, 0xFD, 0xF5, 0x8D, + 0xDE, 0x3D, 0xB6, 0xAD, 0xAC, 0x22, 0x31, 0xAF, + 0x55, 0xA4, 0x50, 0x1F, 0x9E, 0x34, 0x57, 0x06, + 0x45, 0x6B, 0x58, 0x5A, 0xD4, 0x85, 0x56, 0x88, + 0x3F, 0x0F, 0x05, 0x30, 0xF5, 0x3E, 0x82, 0x59, + 0x93, 0xFB, 0xA3, 0x41, 0x5F, 0x54, 0xFD, 0x43, + 0x76, 0x62, 0xB9, 0x23, 0x1A, 0x0A, 0x11, 0xF9, + 0x11, 0x41, 0xA0, 0x75, 0x96, 0x21, 0xFA, 0x60, + 0xC6, 0x9E, 0xF7, 0x2F, 0x45, 0x95, 0x30, 0x24, + 0xA9, 0x02, 0x59, 0xB5, 0x79, 0x01, 0x15, 0x7A, + 0xD2, 0x24, 0x41, 0xEF, 0x1B, 0x31, 0x62, 0x99, + 0x25, 0x21, 0x6B, 0x3E, 0xC7, 0x71, 0xC3, 0x77, + 0x50, 0x7A, 0x0C, 0xDB, 0xEE, 0x82, 0x93, 0x64, + 0xC1, 0x57, 0xD4, 0x1E, 0xF0, 0x02, 0xAA, 0x1A, + 0x7B, 0x65, 0x3F, 0xED, 0x71, 0x6B, 0x1D, 0x81, + 0x78, 0x65, 0x60, 0xCC, 0xC7, 0xF8, 0xD8, 0x77, + 0x86, 0x61, 0xC8, 0x7F, 0x2E, 0x9D, 0xCC, 0xFC, + 0x22, 0x79, 0xE5, 0x9D, 0xE8, 0x87, 0xBB, 0x47, + 0x78, 0xD5, 0xA7, 0xAD, 0x3F, 0xC8, 0x77, 0x80, + 0x61, 0xD8, 0x60, 0x48, 0x9D, 0x7F, 0x6B, 0xB1, + 0x95, 0x2D, 0xE8, 0xD2, 0xDC, 0x77, 0x25, 0x93, + 0xB1, 0xB1, 0x9D, 0x52, 0x91, 0x8F, 0xFD, 0x09, + 0x9B, 0x46, 0x9A, 0x45, 0x6D, 0xA0, 0x1B, 0x49, + 0x2E, 0xA1, 0xED, 0xF4, 0x78, 0xE6, 0xC8, 0x70, + 0xA5, 0xD7, 0xC3, 0x13, 0x3C, 0xE4, 0x9A, 0xDF, + 0xE9, 0x4A, 0xB9, 0x56, 0x0B, 0x75, 0x32, 0x23, + 0x98, 0x60, 0x20, 0xE9, 0xC5, 0xB5, 0xB2, 0x7B, + 0x83, 0x29, 0xA3, 0x29, 0xAE, 0x64, 0xB4, 0x2F, + 0xA3, 0xB5, 0x75, 0xD8, 0x54, 0xA2, 0x94, 0x26, + 0x2C, 0xB9, 0xD4, 0xCA, 0x79, 0x78, 0x1C, 0xF1, + 0xA1, 0x3A, 0x29, 0xB0, 0xE2, 0x8A, 0x62, 0xA6, + 0x55, 0x87, 0x2C, 0x44, 0x3C, 0x6C, 0x5E, 0xD9, + 0x2E, 0x1A, 0xC3, 0x97, 0x20, 0x32, 0xF8, 0x65, + 0x45, 0xF0, 0x87, 0x93, 0x03, 0x93, 0x0D, 0xD1, + 0x6F, 0x2A, 0xD7, 0x28, 0x99, 0xE1, 0x72, 0xA1, + 0x5B, 0x86, 0x7C, 0xD0, 0x12, 0xFE, 0xF5, 0x28, + 0xE1, 0x17, 0x50, 0xE8, 0xE6, 0x08, 0x38, 0xDC, + 0xAB, 0xB5, 0x78, 0x51, 0x9C, 0x19, 0x41, 0xAE, + 0x4F, 0xD4, 0x7F, 0x25, 0x61, 0xEF, 0x53, 0x85, + 0xA2, 0x8C, 0x4E, 0x3E, 0x65, 0x37, 0x06, 0x66, + 0x45, 0xE6, 0x74, 0x11, 0x24, 0x40, 0x46, 0xE4, + 0x25, 0x4D, 0x18, 0xCA, 0x6A, 0x85, 0xC8, 0x2A, + 0x01, 0xD3, 0x26, 0x45, 0x48, 0x78, 0x6C, 0xC7, + 0x01, 0xC0, 0x94, 0xDB, 0x0B, 0x94, 0x23, 0x50, + 0xB1, 0x14, 0xBF, 0x67, 0x4F, 0x61, 0xB3, 0xC7, + 0x89, 0x39, 0xB7, 0x37, 0xF2, 0xCC, 0x72, 0x47, + 0x73, 0x67, 0xA6, 0x29, 0x29, 0x4D, 0x9A, 0x17, + 0xA6, 0x17, 0x7A, 0xFC, 0x2C, 0x9C, 0xE2, 0x91, + 0x40, 0x00, 0xA2, 0x13, 0xA7, 0x8B, 0x6A, 0x98, + 0x2C, 0xB5, 0x2C, 0x4A, 0xCB, 0x4C, 0x1E, 0x98, + 0x49, 0xC9, 0x56, 0x55, 0x1E, 0xF6, 0x40, 0x55, + 0xE3, 0x7F, 0xEB, 0x36, 0x51, 0xF1, 0x17, 0xCE, + 0x98, 0x70, 0x96, 0xAC, 0xBE, 0x3D, 0x34, 0x25, + 0xBA, 0x39, 0x43, 0x5B, 0xDD, 0x6F, 0xE7, 0x48, + 0xCB, 0xE9, 0x9D, 0xF4, 0x88, 0x1E, 0xA0, 0xDF, + 0x4C, 0x25, 0x52, 0x60, 0xF0, 0xCA, 0x54, 0x66, + 0x0D, 0xAD, 0x99, 0x15, 0x02, 0x15, 0xE3, 0x73, + 0x59, 0x24, 0xBB, 0xEA, 0x32, 0x11, 0xB0, 0x3F, + 0xC1, 0xEC, 0x46, 0xBB, 0x6A, 0x60, 0x24, 0x80, + 0x20, 0x2D, 0x86, 0xAA, 0xDD, 0xF1, 0x63, 0xEC, + 0x34, 0xCE, 0xBC, 0x70, 0xAE, 0xA7, 0xA7, 0xE8, + 0xA6, 0xAF, 0x3A, 0x9E, 0xF2, 0xED, 0x13, 0x68, + 0xC7, 0xF8, 0x2B, 0xE7, 0x89, 0x3E, 0xB2, 0x21, + 0x42, 0x63, 0x12, 0x83, 0xCA, 0xBE, 0x7A, 0x95, + 0x75, 0x9C, 0xEA, 0x74, 0xA6, 0x1C, 0x99, 0x15, + 0xB9, 0x0E, 0x6E, 0x1F, 0x9B, 0xB5, 0xA2, 0x4D, + 0x85, 0x08, 0x32, 0xF3, 0xE7, 0x9A, 0x7C, 0x84, + 0x9B, 0x2A, 0x32, 0xEC, 0x29, 0x4F, 0xEA, 0xAD, + 0x44, 0xDB, 0x2D, 0xC8, 0xB7, 0x26, 0x00, 0x65, + 0x0A, 0xA0, 0x05, 0x07, 0x73, 0xC0, 0xAE, 0x01, + 0x08, 0x88, 0x86, 0xD8, 0x0D, 0xC8, 0xC5, 0x4C, + 0x70, 0x13, 0x6A, 0x3F, 0x79, 0x0A, 0x11, 0x12, + 0x0D, 0xC5, 0xAA, 0x22, 0xD3, 0x9B, 0x45, 0x62, + 0xA2, 0x5C, 0xA7, 0x49, 0x5C, 0x7B, 0xF8, 0x22, + 0x3E, 0x98, 0xD3, 0xE0, 0x2C, 0x0E, 0x9A, 0x1E, + 0x2E, 0x19, 0x7A, 0x2D, 0xD9, 0x48, 0x7F, 0xA8, + 0x10, 0x8F, 0x01, 0x07, 0x98, 0x79, 0x1E, 0x5F, + 0xEB, 0x7E, 0xD0, 0x79, 0x35, 0xB6, 0xE2, 0x4D, + 0xA7, 0xE5, 0x34, 0x46, 0x1D, 0x77, 0xE0, 0xE7, + 0xA5, 0xBD, 0x3E, 0xFE, 0xEC, 0xA8, 0x6A, 0xCA, + 0x9A, 0x0B, 0x45, 0xC3, 0x19, 0xAE, 0xF0, 0xA5, + 0x91, 0x72, 0x7D, 0x1B, 0x2D, 0xCD, 0xE6, 0x43, + 0x05, 0x33, 0x87, 0x42, 0x34, 0x76, 0xCD, 0xB0, + 0x04, 0x8B, 0x85, 0x59, 0xD2, 0xB6, 0x01, 0xE7, + 0x92, 0xFB, 0x99, 0x08, 0x74, 0x39, 0xD7, 0x32, + 0xA7, 0xEE, 0x23, 0x3E, 0x3F, 0xBE, 0x8E, 0xDE, + 0x19, 0xC0, 0x38, 0xC3, 0x08, 0x26, 0x2A, 0x22, + 0x75, 0xF7, 0xE4, 0xC5, 0x67, 0x62, 0x10, 0x3D, + 0x16, 0x3F, 0x97, 0x3C, 0x86, 0x27, 0x6D, 0x98, + 0x98, 0xF1, 0x25, 0xE0, 0x85, 0x15, 0x1D, 0xC8, + 0x26, 0x8B, 0x64, 0x8F, 0xB8, 0x89, 0xB7, 0xB7, + 0xB4, 0x58, 0xC4, 0x45, 0x2F, 0x73, 0x12, 0x19, + 0xDD, 0xB3, 0xC9, 0x44, 0xCA, 0xA6, 0xB1, 0xD1, + 0x6F, 0x2C, 0xB9, 0x8C, 0xDE, 0x4B, 0xBE, 0x00, + 0x1B, 0x22, 0x7C, 0x9D, 0x46, 0xEE, 0x36, 0x73, + 0x9E, 0xA5, 0x14, 0x8F, 0x9A, 0xC9, 0x9A, 0xAC, + 0x6A, 0x90, 0xFD, 0x36, 0x8C, 0x7B, 0x32, 0x3A, + 0xDE, 0x04, 0x5D, 0xD7, 0xD7, 0xA7, 0x2D, 0xF3, + 0x9C, 0xAC, 0x6C, 0x75, 0xE7, 0xBC, 0x1E, 0xD7, + 0xC0, 0x96, 0x7F, 0x52, 0xDC, 0xA0, 0xDA, 0xA0, + 0xCC, 0xBF, 0x30, 0x48, 0x8C, 0x7B, 0x21, 0xC4, + 0xB4, 0x2B, 0x8A, 0x27, 0x3E, 0x7F, 0xE3, 0x8D, + 0x1D, 0xF4, 0xF0, 0xC3, 0x50, 0xB0, 0x28, 0x2E, + 0xDA, 0x10, 0xE2, 0x84, 0x78, 0x45, 0xE2, 0xD1, + 0xF6, 0xA8, 0x22, 0xEE, 0xAD, 0x33, 0x39, 0x15, + 0x85, 0x11, 0x82, 0xC7, 0xDB, 0xF3, 0xB3, 0x6D, + 0xF9, 0x48, 0xB3, 0xA0, 0xC5, 0x02, 0x09, 0xF2, + 0xEB, 0x65, 0xF2, 0x3F, 0xFC, 0x56, 0x2F, 0x15, + 0xBB, 0xB3, 0x6C, 0xDD, 0x2A, 0x7B, 0x64, 0xCE, + 0x21, 0x58, 0xD0, 0x9B, 0xEE, 0xC7, 0x2B, 0x96, + 0xD3, 0x13, 0x35, 0xC5, 0x78, 0x46, 0x31, 0xD4, + 0xF2, 0x0E, 0x2C, 0x24, 0xAC, 0x7E, 0x7E, 0x45, + 0x6D, 0xEB, 0x5D, 0xF1, 0x00, 0xAF, 0x1C, 0x97, + 0x20, 0x1C, 0xEB, 0x54, 0x75, 0x17, 0xD0, 0x33, + 0x0C, 0x00, 0x92, 0x3F, 0xD1, 0xF6, 0x81, 0x10, + 0xE6, 0x48, 0x09, 0x33, 0x67, 0xF5, 0x2F, 0x51, + 0xE1, 0xE2, 0x99, 0x85, 0x17, 0xB3, 0xD6, 0x33, + 0x30, 0x9D, 0x23, 0xE2, 0x8A, 0x36, 0xE6, 0xE1, + 0x47, 0x2A, 0x12, 0x3A, 0xF4, 0xE2, 0x7C, 0xAB, + 0xF4, 0xC0, 0xCC, 0xF8, 0xE3, 0x2B, 0x30, 0x7A, + 0x9F, 0x9D, 0xCB, 0x21, 0x86, 0x4B, 0x76, 0x73, + 0x27, 0xA2, 0x96, 0x65, 0x95, 0x48, 0xBB, 0x28, + 0xA7, 0x6C, 0xA3, 0x1B, 0xB7, 0xD5, 0x26, 0xD7, + 0xEA, 0x61, 0xFC, 0xFD, 0xB2, 0xB1, 0x80, 0xEA, + 0x1F, 0x1C, 0x2B, 0x5F, 0x07, 0x5B, 0xBA, 0x4C, + 0x2F, 0xE5, 0x67, 0x1C, 0x2B, 0x3F, 0x30, 0x9D, + 0xBC, 0xB1, 0x0E, 0x43, 0x9D, 0x4C, 0x97, 0xD5, + 0x0F, 0x87, 0x1B, 0xD6, 0x3D, 0xC1, 0x45, 0x06, + 0xE4, 0x2B, 0xE4, 0xA5, 0xB1, 0x47, 0x63, 0xCF, + 0x68, 0x74, 0x41, 0x44, 0x58, 0x76, 0xC3, 0x68, + 0x6D, 0xB0, 0xBC, 0xF8, 0x84, 0x75, 0x18, 0xF5, + 0x0B, 0xB4, 0x42, 0xEC, 0x6B, 0xA6, 0x10, 0xAB, + 0x80, 0x1A, 0x6C, 0x26, 0x55, 0xC7, 0x4E, 0x1E, + 0xD1, 0x6F, 0x71, 0x97, 0xDB, 0x3C, 0x63, 0x63, + 0x7B, 0x0B, 0xD4, 0x17, 0x11, 0xD1, 0xC2, 0xF4, + 0x13, 0xF9, 0x0D, 0xEB, 0x27, 0xE2, 0xB4, 0xB6, + 0x0C, 0x4D, 0xAD, 0xAB, 0x9A, 0x69, 0x79, 0x9E, + 0x07, 0xAB, 0x36, 0xBA, 0xC2, 0x51, 0x81, 0xA1, + 0x70, 0x3F, 0xDA, 0x7B, 0xFE, 0xCD, 0xFF, 0x1C, + 0xF9, 0xD1, 0x71, 0x92, 0x3F, 0xE9, 0xF6, 0x8D, + 0x2B, 0x37, 0xF3, 0xBB, 0x48, 0x6A, 0x51, 0xBD, + 0xA5, 0xBA, 0xC7, 0x84, 0xD0, 0xF8, 0x36, 0x0E, + 0xC4, 0xCF, 0xEE, 0x73, 0x8F, 0x6D, 0x48, 0x1E, + 0x80, 0x19, 0x42, 0x32, 0x2A, 0x37, 0xCD, 0x7A, + 0x03, 0x6B, 0x76, 0x91, 0xDD, 0x81, 0xC5, 0x0F, + 0x23, 0x42, 0x88, 0xB0, 0x6A, 0x9E, 0xDE, 0xC6, + 0x4E, 0xBF, 0xD3, 0x99, 0xA1, 0x8E, 0xF3, 0x8C, + 0x1B, 0x4D, 0x86, 0x15, 0x28, 0x45, 0x71, 0x6A, + 0xF4, 0x71, 0xFA, 0x42, 0x5C, 0xF6, 0x29, 0x90, + 0x4E, 0xE4, 0xA3, 0x3E, 0xFE, 0x2C, 0x45, 0x22, + 0x69, 0xAA, 0x8F, 0xFE, 0xB2, 0x82, 0x7C, 0x67, + 0x74, 0x20, 0xCA, 0x28, 0x29, 0x06, 0xED, 0x41, + 0xF6, 0x8A, 0x6D, 0xEA, 0xDA, 0xB4, 0xDF, 0x89, + 0xBC, 0xA6, 0xFE, 0x09, 0x98, 0x57, 0x28, 0xE1, + 0x37, 0xCC, 0x31, 0x4C, 0xBE, 0xD1, 0x3B, 0x82, + 0x97, 0xE3, 0xE5, 0xEE, 0x9F, 0x0D, 0x1D, 0x09, + 0x6B, 0x35, 0xE6, 0x08, 0x32, 0x77, 0x4C, 0xF0, + 0x12, 0xBD, 0xEF, 0x8B, 0x92, 0x0A, 0x53, 0x71, + 0x70, 0xB7, 0x5D, 0xCA, 0x40, 0x31, 0x66, 0x81, + 0x89, 0x11, 0xED, 0x6F, 0xB2, 0xA3, 0x11, 0x50, + 0x82, 0x12, 0x0A, 0x09, 0x09, 0xF2, 0x90, 0x5A, + 0xDE, 0x1C, 0x82, 0xF3, 0xB7, 0xF8, 0x30, 0x15, + 0x48, 0x8D, 0x9E, 0xF9, 0x5E, 0x9A, 0x12, 0x52, + 0x77, 0xBF, 0x32, 0x9F, 0xC9, 0xF0, 0x73, 0x3C, + 0x6B, 0x79, 0x76, 0xAE, 0xFB, 0x6D, 0xB0, 0xCD, + 0x84, 0x91, 0xA8, 0x33, 0x5A, 0x5F, 0xC7, 0x05, + 0x64, 0xFE, 0xB6, 0xBF, 0x90, 0xBF, 0x9E, 0xA8, + 0x2B, 0x5D, 0x29, 0xB9, 0xD8, 0x3E, 0x5F, 0x9C, + 0xA0, 0x37, 0xE0, 0xD8, 0xC2, 0x4C, 0xF0, 0x09, + 0xB6, 0x96, 0x54, 0x3F, 0x1C, 0xF6, 0x70, 0x19, + 0xE5, 0xB9, 0x99, 0x88, 0x5D, 0xFA, 0xB6, 0x64, + 0xF1, 0xA4, 0x6E, 0xCD, 0x22, 0xAE, 0xE0, 0xCF, + 0x99, 0x3C, 0xB0, 0xD2, 0x09, 0xFA, 0xC7, 0xD9, + 0xAA, 0xFA, 0x1C, 0xA0, 0x60, 0xA8, 0x15, 0x9C, + 0x6E, 0xF6, 0xED, 0xD6, 0x69, 0xCE, 0x40, 0x8B, + 0xA1, 0xEB, 0xCC, 0xD2, 0xF7, 0x34, 0x21, 0x84, + 0xFB, 0xC3, 0xB0, 0x50, 0x58, 0x77, 0xD9, 0x83, + 0x22, 0x0A, 0x81, 0x88, 0x2E, 0xDE, 0xEB, 0xBE, + 0x46, 0x7E, 0xD2, 0x1D, 0x37, 0xC1, 0x98, 0x4A, + 0x40, 0x87, 0x76, 0x4F, 0x14, 0x55, 0x10, 0x70, + 0x91, 0xA3, 0xFA, 0xA2, 0x93, 0xF1, 0xDE, 0x05, + 0x7E, 0xBF, 0x0B, 0xDC, 0x66, 0x04, 0x7F, 0xB5, + 0xA3, 0x4E, 0x19, 0xB7, 0x2D, 0xAB, 0x8A, 0x2E, + 0x7E, 0x5C, 0xC3, 0x80, 0x11, 0x66, 0x0D, 0x96, + 0xCE, 0xD8, 0xFA, 0x48, 0x32, 0xDF, 0x78, 0x1C, + 0x6B, 0xD3, 0xFA, 0x1C, 0xA5, 0xCA, 0x99, 0xF4, + 0xB8, 0x3F, 0xB3, 0x84, 0xB6, 0xD9, 0x5F, 0xBF, + 0x2E, 0x62, 0x1B, 0xBD, 0x03, 0x12, 0x7B, 0x68, + 0x8E, 0x48, 0x72, 0xB5, 0x8A, 0xB9, 0x92, 0xA2, + 0x1E, 0x3A, 0x60, 0x31, 0x47, 0x89, 0x3F, 0xF5, + 0x4B, 0xEE, 0x3B, 0xEF, 0xA3, 0xC4, 0x9C, 0xB5, + 0x69, 0xCD, 0x17, 0xD8, 0x6C, 0x53, 0x7D, 0x9F, + 0xA5, 0x59, 0x1E, 0x60, 0x84, 0x53, 0x2D, 0x94, + 0x7B, 0x6A, 0xAE, 0x49, 0x6F, 0x39, 0x5E, 0x78, + 0x60, 0x73, 0x73, 0xF7, 0xF7, 0xC1, 0xBE, 0x98, + 0xE3, 0x1B, 0xAB, 0xB0, 0xB1, 0xF4, 0x10, 0x0A, + 0x65, 0x76, 0x83, 0x6E, 0x50, 0xE9, 0x45, 0x26, + 0x8A, 0x09, 0x2B, 0xDA, 0xF5, 0xB2, 0x17, 0xDE, + 0xD9, 0x46, 0xB8, 0xE2, 0x8B, 0x3D, 0x19, 0xD8, + 0x1D, 0xA6, 0x9C, 0xF3, 0x56, 0x71, 0xC1, 0xD1, + 0x1A, 0x91, 0xC0, 0x6D, 0xE4, 0x94, 0x55, 0x62, + 0x89, 0x87, 0xEA, 0xD0, 0xDA, 0x56, 0x83, 0x3E, + 0x6B, 0xBC, 0x14, 0x46, 0xD5, 0xE5, 0x7F, 0x11, + 0xBC, 0x38, 0x52, 0xB9, 0x37, 0x5B, 0xE8, 0xAD, + 0x8F, 0xC2, 0x03, 0x7B, 0xB2, 0x3B, 0x5A, 0xA7, + 0x01, 0xE0, 0x8B, 0x8D, 0xD2, 0xA0, 0x8E, 0xD6, + 0xC8, 0x79, 0xA1, 0xF8, 0x6C, 0x5B, 0xE9, 0x38, + 0xD8, 0x20, 0x3B, 0x96, 0xBB, 0x5C, 0x17, 0xE4, + 0xE3, 0x81, 0x15, 0x4A, 0xC5, 0x79, 0xFA, 0xAA, + 0xD5, 0x68, 0x52, 0x11, 0x17, 0xBA, 0xE9, 0xDB, + 0x4C, 0xE0, 0x28, 0x63, 0xD0, 0x22, 0x4F, 0x70, + 0xE6, 0x28, 0xDD, 0xD2, 0x06, 0x76, 0x0B, 0x57, + 0xC8, 0xB1, 0x0B, 0x7E, 0x16, 0x41, 0xB2, 0xDC, + 0xD6, 0xA3, 0xC0, 0xD3, 0x83, 0x0B, 0x53, 0x95, + 0x7D, 0x30, 0x5B, 0x4B, 0xC8, 0xB7, 0x2D, 0xC5, + 0xB2, 0xE8, 0x0D, 0x38, 0x2B, 0x13, 0x96, 0x78, + 0xA0, 0xC2, 0x55, 0xA3, 0xF1, 0x92, 0xF1, 0xA3, + 0x98, 0x33, 0xAB, 0x52, 0x5D, 0xE1, 0xFF, 0x2B, + 0x49, 0x64, 0x2C, 0x26, 0xDE, 0x2C, 0x7E, 0xB5, + 0x30, 0x99, 0xEC, 0xD5, 0x23, 0x75, 0x64, 0x72, + 0xA5, 0xA0, 0x53, 0xDB, 0xC2, 0x5D, 0x62, 0x27, + 0xD3, 0x42, 0x1B, 0x8D, 0x09, 0x78, 0xB9, 0x44, + 0x6E, 0xBF, 0x2C, 0xD6, 0x95, 0x43, 0x80, 0x79, + 0xBF, 0x53, 0x8F, 0xA2, 0x62, 0xA0, 0x26, 0x73, + 0x18, 0xE1, 0x1B, 0x5C, 0x24, 0xA8, 0x25, 0x37, + 0x09, 0x2C, 0xB8, 0x85, 0xEF, 0x0C, 0x4A, 0xDD, + 0xEF, 0x26, 0x27, 0x30, 0xAD, 0xC7, 0xA0, 0x62, + 0x2B, 0x00, 0xEB, 0xF9, 0x78, 0x22, 0xB0, 0x86, + 0xCB, 0x70, 0x4B, 0xBA, 0x96, 0xB6, 0xCC, 0x32, + 0x7E, 0x2D, 0xA2, 0x7E, 0x2A, 0x71, 0xD8, 0xE1, + 0xAE, 0xC3, 0x50, 0x7E, 0x6A, 0xD2, 0xAD, 0xC4, + 0x26, 0x45, 0xE0, 0xE9, 0x4D, 0xEC, 0x20, 0x13, + 0xC0, 0xC6, 0x02, 0xF4, 0x87, 0x5B, 0x95, 0xF6, + 0xFC, 0x80, 0x04, 0x6B, 0xEE, 0x68, 0xE5, 0x1A, + 0x3F, 0xDF, 0x98, 0x9C, 0x73, 0x71, 0xAD, 0x30, + 0x49, 0xD3, 0xC8, 0x7C, 0xBD, 0x5D, 0x32, 0x02, + 0x77, 0x5C, 0x54, 0xF5, 0xA5, 0xB9, 0x2F, 0xAC, + 0x89, 0x2E, 0x44, 0x40, 0x79, 0x71, 0xD8, 0xAF, + 0x45, 0xBE, 0x4A, 0x08, 0x9E, 0x32, 0x58, 0x4F, + 0xAD, 0xE6, 0xF0, 0x8A, 0x0B, 0xEB, 0xFE, 0xFC, + 0xD5, 0xF4, 0x6E, 0x9E, 0x55, 0xF7, 0xB1, 0x78, + 0xF2, 0x6E, 0xEA, 0xFF, 0xC9, 0x9B, 0xEB, 0x9C, + 0x08, 0xDE, 0xB3, 0xAD, 0xC2, 0x0B, 0x96, 0xEB, + 0x1D, 0x60, 0xC9, 0xBE, 0x92, 0x71, 0xBB, 0xB2, + 0xCB, 0x1C, 0x86, 0x78, 0xE8, 0x58, 0xA0, 0x40, + 0xEF, 0x52, 0xFF, 0x14, 0x2D, 0xFF, 0x72, 0x4C, + 0x4C, 0xB3, 0xF3, 0xE9, 0x75, 0xA1, 0xBE, 0x52, + 0x26, 0x79, 0x38, 0x4B, 0x8B, 0x36, 0x57, 0xA7, + 0x39, 0x27, 0x01, 0x8A, 0x81, 0x59, 0x4A, 0xE9, + 0x86, 0x90, 0xE8, 0x08, 0x32, 0x48, 0xCA, 0x54, + 0xC8, 0xD0, 0x72, 0x56, 0x88, 0xAE, 0xC1, 0x31, + 0xCB, 0xC3, 0x37, 0xE0, 0xEA, 0x79, 0x9E, 0x75, + 0x4F, 0xA8, 0xCC, 0x33, 0xC3, 0x50, 0x24, 0x86, + 0x57, 0x79, 0x4B, 0x27, 0xB9, 0x06, 0x13, 0xCE, + 0xFF, 0x67, 0x84, 0x1C, 0x93, 0xDF, 0xF9, 0x0B, + 0xAB, 0x4C, 0x98, 0xDB, 0xE3, 0x6E, 0x06, 0xF6, + 0x88, 0xF7, 0xB0, 0x3E, 0x07, 0xBC, 0xFC, 0xB7, + 0xC3, 0x04, 0x58, 0xD8, 0x57, 0x34, 0x11, 0xFC, + 0xBE, 0x28, 0x45, 0x24, 0xF1, 0x3B, 0x2C, 0x71, + 0x96, 0x56, 0x7C, 0xD1, 0xE8, 0x97, 0x8C, 0x8C, + 0x81, 0x6E, 0xBD, 0x19, 0x62, 0xB1, 0x24, 0xE6, + 0xA7, 0x14, 0x47, 0x3B, 0x93, 0x49, 0x22, 0x51, + 0x6F, 0x97, 0xD6, 0x29, 0x78, 0xE3, 0xE1, 0x8B, + 0xEA, 0x46, 0xF5, 0xEC, 0xF6, 0x81, 0x56, 0xF3, + 0xCD, 0x4C, 0x6E, 0x15, 0x37, 0xFB, 0x11, 0x86, + 0x8F, 0x37, 0x6B, 0x78, 0x3E, 0x8B, 0x51, 0x45, + 0xE0, 0xC7, 0xC0, 0x03, 0x87, 0x8B, 0x7E, 0x71, + 0xD8, 0x34, 0xC1, 0x5D, 0xB3, 0x62, 0x12, 0x70, + 0xA8, 0x58, 0xE3, 0x5E, 0x78, 0xD5, 0xE4, 0x78, + 0xC0, 0xAE, 0xC2, 0xF7, 0xED, 0xBF, 0x71, 0xF6, + 0x26, 0x91, 0x60, 0x15, 0x6C, 0xF4, 0x68, 0x78, + 0x56, 0x4E, 0x87, 0x50, 0x2C, 0x20, 0x7F, 0x91, + 0xCF, 0x76, 0x90, 0xD6, 0x13, 0xB1, 0x77, 0x8D, + 0xBB, 0x15, 0xF7, 0xB7, 0x94, 0x19, 0x88, 0x5C, + 0xC7, 0x6B, 0xB3, 0x20, 0x00, 0xCF, 0x1D, 0x10, + 0xFC, 0xE8, 0xF1, 0x37, 0x19, 0x42, 0xC3, 0xFD, + 0xA0, 0x5E, 0x0E, 0x6D, 0xD5, 0x18, 0x66, 0xD3, + 0xBC, 0xF1, 0x75, 0xEF, 0xD6, 0xF4, 0x9B, 0xE2, + 0x1D, 0x0A, 0x6B, 0x4B, 0x00, 0xFB, 0xA7, 0x73, + 0xD6, 0x68, 0xC3, 0x83, 0xF7, 0xA7, 0xCE, 0xD1, + 0xD8, 0xDC, 0x82, 0xF1, 0xC7, 0x7A, 0xB1, 0xA4, + 0x20, 0xA1, 0x59, 0x70, 0xE4, 0x6E, 0x91, 0x4E, + 0xD7, 0xA7, 0x93, 0x0B, 0x09, 0x86, 0x54, 0xE1, + 0x1A, 0x4A, 0xC3, 0xE2, 0xDD, 0xA2, 0x62, 0x64, + 0x00, 0xDC, 0x14, 0xFF, 0x03, 0x37, 0x82, 0x44, + 0x6B, 0xCF, 0x1F, 0xC1, 0xAD, 0x3E, 0x3F, 0x05, + 0xAA, 0x15, 0x60, 0xA4, 0x9D, 0x95, 0x37, 0xC8, + 0x2D, 0x12, 0x6B, 0x20, 0xEA, 0xD7, 0xF2, 0xAF, + 0x3A, 0x23, 0x3E, 0x1C, 0x9D, 0x05, 0x5B, 0xD3, + 0x86, 0x74, 0x91, 0xBB, 0xE5, 0x93, 0x04, 0xEA, + 0x96, 0xF9, 0xB7, 0x5B, 0xD8, 0xBB, 0x8E, 0x29, + 0x8B, 0xCE, 0x56, 0x88, 0x3C, 0xF1, 0xE5, 0x5D, + 0x05, 0xB0, 0x16, 0xBB, 0xB6, 0xD0, 0xA8, 0x30, + 0xE0, 0x6C, 0xCC, 0x12, 0x95, 0xEF, 0x02, 0x75, + 0xA9, 0xC4, 0x4A, 0x69, 0xBB, 0xB7, 0xE4, 0xA0, + 0x54, 0xDF, 0x21, 0x7B, 0xC7, 0xA5, 0x3C, 0xBB, + 0xC4, 0x7C, 0x64, 0x47, 0xB1, 0x0C, 0x9F, 0x99, + 0xEE, 0x61, 0x56, 0x11, 0xEC, 0x13, 0xF7, 0xF8, + 0x29, 0x01, 0x07, 0x5A, 0x71, 0x7B, 0x0D, 0x8D, + 0xF3, 0xF4, 0x07, 0x40, 0xA3, 0xB6, 0x33, 0xED, + 0x56, 0x28, 0x10, 0xF2, 0xC7, 0x43, 0x7E, 0x36, + 0xC9, 0x7C, 0x5A, 0xEC, 0x1B, 0x9D, 0xB2, 0x44, + 0x72, 0xB8, 0x42, 0x92, 0x95, 0x93, 0xAF, 0xE7, + 0xA3, 0xEA, 0x31, 0x19, 0x31, 0x6F, 0xC7, 0x4F, + 0xA4, 0x5D, 0xB9, 0x9C, 0x54, 0x86, 0x43, 0x16, + 0x3B, 0xF1, 0x6D, 0x8A, 0x84, 0xEC, 0x4E, 0x98, + 0xC6, 0xBC, 0x86, 0x4A, 0x82, 0x61, 0x61, 0x0D, + 0x73, 0xDF, 0xAF, 0x2D, 0x23, 0x89, 0x5D, 0x14, + 0x7F, 0xE6, 0x7B, 0x8D, 0x3A, 0xFE, 0xD6, 0xF0, + 0xDA, 0x87, 0x1A, 0x0C, 0x3E, 0xCA, 0xCA, 0x84, + 0xE0, 0x72, 0x2D, 0x50, 0x19, 0x4D, 0xCC, 0x5F, + 0x3B, 0x63, 0x78, 0xF8, 0x51, 0x30, 0x3F, 0x80, + 0x60, 0x8B, 0xE4, 0xE2, 0xC0, 0xE6, 0xF3, 0x42, + 0xFA, 0xB0, 0xA7, 0x07, 0x57, 0x8E, 0xC8, 0x5D, + 0x1D, 0xFD, 0x39, 0x30, 0xA7, 0x2C, 0xCB, 0xEC, + 0xEB, 0x6A, 0x16, 0xCF, 0x82, 0x36, 0xFB, 0x1E, + 0xEE, 0x76, 0xED, 0xD6, 0xDC, 0x85, 0xBF, 0x71, + 0xC5, 0x26, 0x79, 0x19, 0x46, 0xB9, 0x92, 0x99, + 0xDB, 0x95, 0x5B, 0x78, 0xCF, 0xA7, 0x74, 0xD5, + 0x17, 0x97, 0x54, 0xE5, 0xAE, 0xE4, 0x23, 0xC1, + 0x21, 0xF8, 0xAC, 0x12, 0xFB, 0x1D, 0x6E, 0xF9, + 0xC7, 0x94, 0x0A, 0x7A, 0x60, 0x1B, 0xA0, 0x49, + 0xB4, 0xD2, 0x3B, 0xC9, 0x10, 0x4E, 0x58, 0x37, + 0x56, 0xAE, 0x8D, 0xDD, 0xBF, 0xB5, 0xCF, 0xC0, + 0x10, 0xC3, 0x73, 0x1D, 0x58, 0x97, 0x78, 0x58, + 0xFF, 0x87, 0xC5, 0xF3, 0x31, 0xFE, 0x39, 0xCC, + 0x70, 0x33, 0xA5, 0xF2, 0x20, 0xDF, 0x8A, 0x04, + 0xE0, 0xBE, 0x5D, 0x94, 0x9D, 0x21, 0x62, 0x7F, + 0x47, 0xAC, 0x6F, 0xE8, 0x5E, 0x31, 0xBC, 0x11, + 0xA6, 0x2E, 0xA2, 0x5D, 0xA1, 0xD4, 0x48, 0x58, + 0x7C, 0x1B, 0xA0, 0x80, 0x76, 0x19, 0x5A, 0xDA, + 0xB4, 0x81, 0x6D, 0x42, 0xB4, 0xD0, 0xDF, 0xB5, + 0x41, 0x73, 0x2E, 0x3A, 0x4F, 0x26, 0xCA, 0x90, + 0xB8, 0xC7, 0x22, 0x2D, 0x1F, 0x95, 0x52, 0x09, + 0x19, 0x23, 0x7F, 0x82, 0x5B, 0x9C, 0xC2, 0xE3, + 0xA7, 0xC7, 0x20, 0x03, 0x7D, 0x0D, 0x6E, 0x1C, + 0xA5, 0xDC, 0xF8, 0xED, 0xE7, 0x45, 0x72, 0x71, + 0x1B, 0x69, 0xFB, 0x07, 0x49, 0x5C, 0x54, 0xE2, + 0xF6, 0x59, 0xA8, 0xCD, 0x1D, 0xE9, 0x65, 0x17, + 0x49, 0x12, 0x14, 0xBF, 0x36, 0x58, 0x0C, 0x7B, + 0xE7, 0xF3, 0xFB, 0x8F, 0x9E, 0x2D, 0xE9, 0x17, + 0x5A, 0x25, 0xE5, 0x5F, 0x66, 0xA0, 0x1B, 0xC4, + 0x70, 0x0F, 0x8A, 0x33, 0xE2, 0x9C, 0x68, 0xB6, + 0x52, 0xCD, 0x0C, 0xB4, 0x45, 0x50, 0x73, 0x97, + 0x51, 0x04, 0xF4, 0xE2, 0x92, 0x83, 0x5F, 0xED, + 0xE6, 0xD0, 0x98, 0x58, 0x90, 0xC4, 0xDA, 0x71, + 0xF6, 0xF2, 0xDE, 0x0D, 0xA9, 0x50, 0x70, 0x20, + 0x03, 0x6A, 0x96, 0x07, 0x0D, 0xEC, 0x16, 0x51, + 0x77, 0xEE, 0x90, 0xBD, 0xFB, 0xFF, 0xA8, 0x0D, + 0xDF, 0xDE, 0xD5, 0x08, 0xF8, 0x4D, 0x37, 0x77, + 0x61, 0xB4, 0x74, 0x08, 0x45, 0x75, 0xF6, 0xF7, + 0x42, 0x01, 0xCE, 0xB6, 0x5D, 0xE9, 0xAA, 0xBB, + 0x68, 0x7D, 0xDB, 0x6C, 0xC9, 0xE9, 0xD0, 0xB6, + 0xA2, 0x2A, 0x4D, 0xA7, 0x87, 0x7E, 0xE7, 0xA3, + 0x8E, 0x43, 0xFD, 0x07, 0x3A, 0x64, 0x9C, 0xAB, + 0xFE, 0x7E, 0x93, 0xB6, 0x0C, 0xE3, 0x93, 0x3F, + 0xED, 0x92, 0x38, 0x94, 0xBE, 0xE9, 0x8D, 0x76, + 0xA4, 0xA4, 0x49, 0x0D, 0xEE, 0xF3, 0xE9, 0xD0, + 0xED, 0x6F, 0x1F, 0xCC, 0x16, 0x75, 0xC8, 0x95, + 0xF8, 0x21, 0xA1, 0x76, 0xA9, 0x22, 0x03, 0x90, + 0x23, 0x3C, 0x50, 0x49, 0x79, 0x6E, 0xD0, 0xC0, + 0x54, 0x7B, 0x0E, 0x93, 0x30, 0xEE, 0x7C, 0x68, + 0x2D, 0x53, 0x9B, 0x4D, 0x4B, 0xCF, 0x0C, 0x11, + 0x4C, 0xF3, 0x70, 0x58, 0x08, 0x8C, 0xDA, 0x7B, + 0x63, 0x1D, 0x29, 0xB3, 0xBF, 0x6E, 0x42, 0x1D, + 0x95, 0x9E, 0x7D, 0xD1, 0x11, 0x5B, 0x7D, 0xDE, + 0xFC, 0x06, 0x85, 0x81, 0x30, 0x76, 0x67, 0x6A, + 0x14, 0x4F, 0xD1, 0x5E, 0x97, 0x52, 0x2D, 0x8D, + 0x82, 0x37, 0x71, 0x1D, 0x2B, 0x05, 0x90, 0x9B, + 0xC8, 0x66, 0xAE, 0xAB, 0x6E, 0xAC, 0x25, 0x68, + 0x6A, 0x12, 0x1F, 0x57, 0x7F, 0xB2, 0x72, 0x9E, + 0x8B, 0x13, 0x95, 0x1E, 0x70, 0x5A, 0xEE, 0x77, + 0x51, 0x73, 0xC8, 0x89, 0xEA, 0xCB, 0x35, 0x3B, + 0x9C, 0xA5, 0x9D, 0xEC, 0x9F, 0x63, 0xC4, 0x86, + 0x48, 0x93, 0xD2, 0x9C, 0x3E, 0x4F, 0x10, 0x93, + 0xFA, 0xA2, 0x89, 0x35, 0x30, 0x40, 0x07, 0x33, + 0x7E, 0x7E, 0x7A, 0x31, 0x63, 0x41, 0x01, 0xFC, + 0x50, 0xFD, 0xBE, 0xE5, 0xD3, 0x4F, 0xC1, 0xB0, + 0xD6, 0xAF, 0x87, 0x18, 0xBF, 0x30, 0x31, 0x0F, + 0x74, 0xCD, 0x6C, 0xFF, 0x0A, 0xA9, 0x72, 0x3B, + 0x63, 0xC9, 0xFB, 0x95, 0x09, 0xD5, 0xE5, 0x9E, + 0x6E, 0x62, 0x8F, 0x50, 0x65, 0xEF, 0xC5, 0x4E, + 0x66, 0x8A, 0x77, 0xBC, 0x21, 0x7C, 0x96, 0x11, + 0xE9, 0xD8, 0xB5, 0x79, 0x7E, 0x6A, 0xB8, 0x10, + 0x65, 0xAB, 0xA9, 0x7E, 0x46, 0xA6, 0x46, 0xA5, + 0x26, 0x83, 0xDA, 0x4D, 0x38, 0xB4, 0x2D, 0xA6, + 0xDB, 0xBF, 0x29, 0x7D, 0xAB, 0x46, 0x97, 0xFE, + 0xEE, 0xF0, 0x93, 0xB8, 0x96, 0xFB, 0xD8, 0x91, + 0xF9, 0xAE, 0x99, 0x7B, 0x90, 0x07, 0x5D, 0xA5, + 0x3B, 0xBF, 0x8A, 0x24, 0x26, 0x93, 0xE3, 0x60, + 0xA5, 0xEB, 0x13, 0xF8, 0xFB, 0x24, 0x42, 0xDA, + 0x78, 0xEC, 0xB9, 0xF3, 0xCC, 0x7D, 0x08, 0xBF, + 0x9A, 0x6E, 0xD4, 0xD6, 0xB7, 0xA0, 0xF5, 0xA3, + 0xDB, 0xA9, 0x5E, 0xF5, 0x7F, 0xD4, 0xAA, 0xA7, + 0xB7, 0xE9, 0xF0, 0xF7, 0x7E, 0xC0, 0x43, 0x3F, + 0xFE, 0xBA, 0x3A, 0xED, 0x9C, 0xB4, 0x01, 0x6C, + 0x28, 0x6B, 0xD6, 0xEE, 0xCE, 0x14, 0xE7, 0x9B, + 0xAD, 0xB2, 0xC1, 0x71, 0xA3, 0x5E, 0x73, 0x23, + 0x18, 0xF0, 0x54, 0x2A, 0x88, 0xAC, 0xFA, 0x44, + 0x29, 0x7A, 0x71, 0xE3, 0x07, 0xD5, 0xF5, 0x07, + 0xD8, 0x31, 0xB6, 0x84, 0xF7, 0x3C, 0x6B, 0xF7, + 0xAE, 0x63, 0x0E, 0x61, 0x03, 0xFA, 0x76, 0xFD, + 0x01, 0x42, 0x32, 0x1B, 0xEF, 0x98, 0xE9, 0xF8, + 0xE6, 0x15, 0xAC, 0x46, 0xE3, 0xDE, 0xBE, 0x3F, + 0x55, 0x46, 0x2E, 0xD6, 0x4B, 0xD9, 0x70, 0x75, + 0xF4, 0x06, 0xA2, 0x8B, 0xA2, 0xC3, 0xE4, 0xEF, + 0x5F, 0x51, 0x6D, 0x6A, 0x7D, 0x23, 0x01, 0x8B, + 0x2E, 0x20, 0xE5, 0xAD, 0x9E, 0x43, 0x20, 0x53, + 0x62, 0x62, 0xF4, 0x77, 0xBA, 0xEA, 0x81, 0x13, + 0xF5, 0xB4, 0x0C, 0x3F, 0x7F, 0xC3, 0x07, 0xDC, + 0xBD, 0xAC, 0xB7, 0x80, 0x30, 0x4E, 0xB2, 0xF7, + 0xB3, 0x32, 0x09, 0x87, 0xFE, 0xCB, 0xA8, 0x45, + 0x1F, 0x3C, 0x54, 0x15, 0x0E, 0x87, 0xBC, 0xFB, + 0x33, 0x33, 0x5D, 0x51, 0xEB, 0x4F, 0xF6, 0xB9, + 0xE3, 0x30, 0x3B, 0x80, 0xA6, 0xA2, 0xD5, 0xAC, + 0x82, 0x29, 0x28, 0x2D, 0x74, 0x69, 0x9D, 0x0A, + 0x30, 0x5D, 0x21, 0xC5, 0xFD, 0x8D, 0xD1, 0xED, + 0xD6, 0x63, 0xEC, 0x51, 0x06, 0x31, 0xBF, 0xEA, + 0x1F, 0xD6, 0x44, 0x41, 0xED, 0x06, 0xD0, 0xFF, + 0xB5, 0x77, 0x96, 0x60, 0x7D, 0x2F, 0x35, 0xC9, + 0xB1, 0x63, 0xA9, 0xD9, 0x88, 0x03, 0x46, 0x29, + 0x0B, 0x0C, 0x33, 0xDA, 0x78, 0xB9, 0xF1, 0x97, + 0x33, 0x01, 0xD8, 0x4F, 0xD0, 0x6B, 0x3F, 0xCD, + 0x3D, 0x43, 0x36, 0xA7, 0xD2, 0x2D, 0x18, 0x84, + 0xD9, 0x54, 0x3D, 0x4E, 0x0D, 0x38, 0x8B, 0xE4, + 0xA3, 0xEB, 0x6B, 0x12, 0xAE, 0x41, 0x3A, 0x9B, + 0xB4, 0x04, 0x38, 0xEA, 0x1F, 0x06, 0x04, 0xB6, + 0x05, 0x33, 0xDD, 0x6D, 0xDC, 0xBE, 0xA6, 0xD2, + 0x7A, 0xB5, 0x41, 0xB0, 0x46, 0x01, 0x05, 0x55, + 0xAD, 0x58, 0xD8, 0x49, 0x53, 0x2A, 0x5F, 0x79, + 0x90, 0xB5, 0xBC, 0x75, 0x2B, 0x1F, 0x15, 0x19, + 0x84, 0x81, 0x2D, 0x07, 0xBD, 0x92, 0x2D, 0x35, + 0x93, 0xE9, 0xF6, 0x55, 0x68, 0xA3, 0xBB, 0xAE, + 0x99, 0x2D, 0x23, 0x2E, 0x84, 0xFA, 0x86, 0x92, + 0x66, 0x5F, 0x79, 0x97, 0xB6, 0xA0, 0x2F, 0xCD, + 0x36, 0x61, 0x38, 0xF8, 0x4B, 0xF5, 0x8F, 0x34, + 0xB5, 0xB2, 0x64, 0xE2, 0x0B, 0xD0, 0xA0, 0x7C, + 0xE3, 0xAB, 0x45, 0x3F, 0xB2, 0xD0, 0x10, 0xE3, + 0xC7, 0x8A, 0x67, 0x78, 0x23, 0x21, 0x85, 0xE5, + 0xBB, 0x86, 0xC0, 0xD9, 0xF3, 0x54, 0xF9, 0x28, + 0x7E, 0x26, 0x9F, 0x4D, 0x67, 0x67, 0x14, 0x72, + 0xF3, 0xD5, 0xCF, 0x39, 0xDB, 0x3D, 0xDE, 0x1D, + 0xF1, 0xBC, 0xE6, 0x2B, 0x0A, 0xEC, 0x96, 0xC0, + 0x47, 0xAD, 0x42, 0x9A, 0x83, 0x8E, 0x56, 0x22, + 0x6A, 0x2C, 0x8E, 0xA8, 0xA4, 0x95, 0x01, 0x60, + 0xA4, 0x00, 0x00, 0xE9, 0x01, 0x5F, 0x37, 0x29, + 0xF4, 0xC0, 0x93, 0x73, 0x8F, 0xC0, 0xD4, 0xB3, + 0x9A, 0xC1, 0xFB, 0x11, 0x1D, 0xF9, 0x18, 0xDE, + 0xEA, 0xC6, 0x39, 0xB7, 0x2A, 0xBA, 0xAA, 0xF7, + 0x66, 0x87, 0x5C, 0x1E, 0xAB, 0x02, 0x75, 0xF7, + 0x6E, 0xDA, 0x3E, 0x60, 0x79, 0x8D, 0xE6, 0x1A, + 0xD3, 0x87, 0x59, 0xEF, 0xB3, 0xE4, 0xEC, 0x2E, + 0x41, 0x96, 0xFC, 0x7A, 0x5F, 0xF0, 0x90, 0x5E, + 0x29, 0xEE, 0xA1, 0xD2, 0x72, 0xC0, 0x51, 0x72, + 0x24, 0xB9, 0x9D, 0x3F, 0xE1, 0xE4, 0xD7, 0xBE, + 0x21, 0x33, 0x06, 0xA7, 0x21, 0xFF, 0xE5, 0x63, + 0x39, 0xCD, 0x85, 0x5C, 0xE3, 0xB5, 0xAE, 0xB0, + 0x20, 0xD9, 0x46, 0x5B, 0xA0, 0xA1, 0x45, 0x09, + 0xD5, 0xF9, 0x92, 0x26, 0xEA, 0xB1, 0xCC, 0xAF, + 0x70, 0x68, 0x5B, 0x35, 0x62, 0xB5, 0xC0, 0xB5, + 0x7E, 0x15, 0x61, 0x1A, 0x0D, 0x31, 0xD0, 0xCC, + 0x33, 0x60, 0x00, 0x21, 0xE1, 0xC5, 0xDC, 0xB6, + 0xFA, 0xF9, 0xEB, 0x20, 0x5D, 0x6E, 0xEF, 0x97, + 0x11, 0x0D, 0xEC, 0x2B, 0x4A, 0x49, 0x29, 0x37, + 0xB4, 0xE6, 0x4F, 0x73, 0xC7, 0x14, 0xF4, 0x46, + 0x7F, 0xE7, 0x8A, 0x3E, 0xD0, 0xC2, 0x5F, 0xE2, + 0x5F, 0x1E, 0x09, 0x80, 0xFC, 0xA5, 0x19, 0x34, + 0xDD, 0x0B, 0xFA, 0x30, 0x9A, 0xC8, 0xE7, 0x6C, + 0x66, 0x26, 0x53, 0x0E, 0xC2, 0x8E, 0xE7, 0x1E, + 0x50, 0xDB, 0xED, 0xB8, 0x67, 0x2D, 0x53, 0xEF, + 0x74, 0x1C, 0x9A, 0xFC, 0x7B, 0x0A, 0xFE, 0x1C, + 0x40, 0x3E, 0xBA, 0xD1, 0x0E, 0xE3, 0xB6, 0xA9, + 0x09, 0x1D, 0x10, 0xD5, 0x26, 0x35, 0xBC, 0xC9, + 0x0A, 0x22, 0xA1, 0x1F, 0xC0, 0x5A, 0x59, 0xB7, + 0x77, 0x18, 0x39, 0x31, 0x0A, 0xB6, 0xDC, 0xB6, + 0xAD, 0xB0, 0x37, 0x21, 0xD4, 0x08, 0x14, 0x5A, + 0x4A, 0xD9, 0xE3, 0x4B, 0xF7, 0xAE, 0x28, 0xCE, + 0x38, 0x0B, 0x2F, 0x12, 0x5D, 0xCF, 0xC5, 0xB1, + 0x9B, 0x76, 0xD1, 0x96, 0x7A, 0x56, 0xCE, 0x90, + 0x8C, 0x21, 0x09, 0x00, 0x41, 0x7A, 0xCF, 0x43, + 0xF8, 0x7A, 0xF2, 0xFF, 0xDB, 0xE7, 0x23, 0xFD, + 0xDD, 0x03, 0xA2, 0x72, 0x9E, 0x4A, 0x83, 0x94, + 0x73, 0x0C, 0x2D, 0xB5, 0x2B, 0xF8, 0xF9, 0x13, + 0x9E, 0x9B, 0x82, 0x44, 0xB3, 0xF7, 0x56, 0xF6, + 0xF2, 0x8A, 0xDC, 0x5B, 0xF1, 0x6B, 0xA1, 0xF6, + 0x5D, 0x75, 0x29, 0x59, 0xD8, 0xB9, 0x29, 0x0B, + 0x4F, 0x45, 0x17, 0x31, 0x5F, 0x4F, 0x2E, 0x23, + 0x95, 0xBD, 0x36, 0x27, 0x29, 0x71, 0x9D, 0xE4, + 0x02, 0x96, 0x30, 0x00, 0xA0, 0xBE, 0x82, 0x80, + 0x76, 0x77, 0x8B, 0x6F, 0x4B, 0x88, 0x94, 0x98, + 0x5B, 0x5A, 0x29, 0xF1, 0xBF, 0x49, 0xEC, 0xD7, + 0xCE, 0xD8, 0x02, 0x20, 0x1A, 0x55, 0x54, 0x7B, + 0x8C, 0x6B, 0xB6, 0x6A, 0xEA, 0xCE, 0x1B, 0xA6, + 0x74, 0x52, 0xB4, 0x55, 0x7F, 0xB1, 0x3D, 0x10, + 0xCA, 0xE6, 0xF8, 0x28, 0x21, 0x99, 0x06, 0xFF, + 0x19, 0xF8, 0x0A, 0xB8, 0xF3, 0x14, 0x99, 0xDC, + 0xE5, 0x52, 0xA5, 0x68, 0xCA, 0x3B, 0x4D, 0xED, + 0x50, 0x09, 0x73, 0xE5, 0xAB, 0x51, 0x9E, 0x44, + 0x55, 0x80, 0x10, 0x59, 0x3A, 0x08, 0x63, 0x14, + 0x7E, 0xD2, 0x83, 0x4D, 0x6A, 0xB3, 0x8A, 0x1C, + 0xDF, 0x69, 0x95, 0x93, 0xB7, 0x5B, 0x4C, 0xF0, + 0x5E, 0xA2, 0xD6, 0xAE, 0x77, 0xA4, 0x75, 0x91, + 0x0F, 0x6B, 0x94, 0x81, 0x5A, 0x87, 0x1D, 0x24, + 0xD1, 0x6E, 0xC5, 0xB3, 0x82, 0x4D, 0x3A, 0x0F, + 0x71, 0x93, 0xF5, 0x32, 0xE2, 0x87, 0x3C, 0xDD, + 0xF5, 0x84, 0x80, 0x1C, 0x2D, 0x8D, 0x4D, 0xEE, + 0x4E, 0x25, 0x33, 0x51, 0x6C, 0x9E, 0xE4, 0x5C, + 0x54, 0x7B, 0xB6, 0xA3, 0x40, 0xE9, 0xA7, 0x56, + 0xC1, 0x9C, 0xBC, 0x96, 0x9C, 0xD4, 0x02, 0x80, + 0xC4, 0x01, 0x35, 0x6E, 0x7C, 0xCB, 0x84, 0xC2, + 0x73, 0x57, 0x45, 0xC2, 0x67, 0xA3, 0x57, 0xDB, + 0x03, 0x49, 0xB1, 0x21, 0x5B, 0xDA, 0x7D, 0x51, + 0xBE, 0x30, 0xF0, 0xB6, 0x3A, 0x72, 0x0C, 0x32, + 0x8A, 0xC2, 0x47, 0xEF, 0x00, 0x98, 0xC5, 0xAA, + 0xFE, 0x6C, 0x9A, 0xF6, 0xE4, 0xD9, 0x7B, 0x7F, + 0xA0, 0x38, 0x36, 0xF1, 0x44, 0x37, 0xE1, 0xEC, + 0x5E, 0xD3, 0x49, 0xC2, 0xB3, 0x3F, 0xAF, 0xD6, + 0xAD, 0xB1, 0x6A, 0x44, 0xF8, 0x0C, 0x07, 0x20, + 0xA1, 0x5B, 0x50, 0x9D, 0x05, 0x37, 0xEC, 0x06, + 0x2E, 0x34, 0xE5, 0x8F, 0x1A, 0x24, 0xC8, 0x5C, + 0x99, 0x94, 0xD1, 0xE4, 0xE5, 0x88, 0x70, 0x74, + 0x6B, 0x5F, 0xB1, 0xAB, 0x50, 0x73, 0xED, 0x4B, + 0x34, 0x10, 0xCB, 0x87, 0x36, 0x57, 0x4E, 0xFD, + 0x24, 0x5F, 0xB4, 0xA8, 0x64, 0x77, 0x7C, 0x88, + 0x81, 0x51, 0x95, 0xA5, 0x88, 0xC8, 0x25, 0x09, + 0x9F, 0x3E, 0xA2, 0x30, 0x3F, 0x9C, 0x1F, 0x8D, + 0xFE, 0x23, 0xD4, 0x4B, 0x0D, 0x77, 0x0A, 0xC4, + 0xFA, 0x60, 0x8C, 0xAE, 0x1D, 0x07, 0x0A, 0x0F, + 0x1F, 0xA4, 0xF9, 0x63, 0x42, 0xF7, 0xAB, 0xD2, + 0xB2, 0x4A, 0xEB, 0xBA, 0xE1, 0xF9, 0x6E, 0x52, + 0x24, 0x2B, 0xCD, 0xC5, 0x04, 0xDD, 0x3F, 0x44, + 0xFD, 0x3F, 0x29, 0xBD, 0xF1, 0x49, 0x7B, 0xBC, + 0xF0, 0x8E, 0xBA, 0x32, 0xD4, 0x3D, 0xD9, 0xA8, + 0x8D, 0xBF, 0x44, 0x8B, 0xD2, 0x0B, 0x55, 0x0F, + 0x6E, 0x9B, 0x66, 0xFA, 0xAC, 0x73, 0xDD, 0xC5, + 0x64, 0xCA, 0x7E, 0xA4, 0xEA, 0x5A, 0x03, 0x1C, + 0x08, 0x76, 0x7A, 0xA0, 0x66, 0x1E, 0xDE, 0x4C, + 0x9B, 0x9A, 0x17, 0xCD, 0xF9, 0xE8, 0xDE, 0x1B, + 0xA5, 0x0D, 0xD6, 0x68, 0xCD, 0xEA, 0x20, 0xEA, + 0xAC, 0x38, 0xE5, 0xA1, 0x20, 0xF9, 0xC9, 0xB9, + 0x78, 0x17, 0xC3, 0xDA, 0xA7, 0xD8, 0x09, 0x46, + 0xF4, 0xD7, 0x76, 0x2D, 0x16, 0x75, 0x7B, 0x46, + 0x9A, 0x24, 0x5C, 0x1A, 0x1A, 0x57, 0xD3, 0x1A, + 0x55, 0xA1, 0x0F, 0xF1, 0x3E, 0xA4, 0x86, 0xD2, + 0x56, 0x1B, 0x4B, 0xAD, 0xB7, 0xF5, 0x0A, 0xA9, + 0x5E, 0x8F, 0x61, 0x2B, 0xF4, 0x43, 0x83, 0x16, + 0x3E, 0x27, 0x2B, 0x65, 0x22, 0xAA, 0xB0, 0x07, + 0xEA, 0xF7, 0x84, 0x80, 0xEF, 0x81, 0xC1, 0x49, + 0xD5, 0xA9, 0xA3, 0xB6, 0xF8, 0x87, 0x5B, 0x24, + 0xF0, 0xC4, 0x80, 0xD1, 0x17, 0x51, 0x1E, 0xE7, + 0xE5, 0x36, 0x89, 0x0D, 0x3F, 0x10, 0x86, 0xC5, + 0x16, 0x1B, 0xAD, 0xD0, 0x67, 0xEA, 0x08, 0xD9, + 0x0C, 0x37, 0x15, 0x4D, 0xA4, 0x22, 0xE6, 0x0A, + 0x29, 0x7A, 0x75, 0xC2, 0xEE, 0x5F, 0x45, 0x2B, + 0x64, 0xDA, 0x08, 0xBC, 0x60, 0x16, 0x9A, 0xDC, + 0xF9, 0x2E, 0x3A, 0xE3, 0x12, 0x8B, 0x90, 0x8D, + 0x42, 0x79, 0x6B, 0x11, 0xB2, 0xA7, 0x12, 0x0D, + 0x20, 0xA4, 0x99, 0x99, 0x02, 0xED, 0x09, 0xB3, + 0x1E, 0x9E, 0xDF, 0xA4, 0x8D, 0xAC, 0xB3, 0xC4, + 0x89, 0xFD, 0xD1, 0x96, 0x21, 0xC5, 0x3D, 0x0F, + 0xB2, 0x14, 0xC0, 0xAD, 0xD8, 0x81, 0xB6, 0xB4, + 0x17, 0x78, 0xB0, 0x34, 0x2A, 0xCD, 0xC3, 0x29, + 0xFA, 0x7B, 0xE4, 0xD9, 0x3C, 0x71, 0xAD, 0x12, + 0x56, 0xB9, 0x6D, 0x70, 0x1A, 0xC8, 0x17, 0x7B, + 0xAE, 0x56, 0x25, 0x87, 0x82, 0xCB, 0xB6, 0x5C, + 0xF9, 0x81, 0x7B, 0x64, 0x6F, 0x43, 0x95, 0x38, + 0x0B, 0xC0, 0x38, 0xDF, 0x5C, 0x1C, 0x98, 0x42, + 0xE5, 0x3A, 0x28, 0x98, 0x59, 0xC9, 0x2A, 0xB8, + 0xCA, 0x9B, 0xAF, 0x3B, 0x24, 0xAE, 0xD1, 0xE1, + 0x50, 0x1A, 0x80, 0x38, 0xD4, 0xF9, 0x18, 0xFD, + 0x19, 0x57, 0x39, 0x00, 0xB5, 0xA7, 0x84, 0xC0, + 0x57, 0xA7, 0xE8, 0xBE, 0x30, 0x8C, 0x33, 0x2D, + 0xCF, 0x06, 0x23, 0x99, 0x2C, 0x24, 0x89, 0x8C, + 0x31, 0x18, 0xB9, 0x31, 0x34, 0x72, 0xE6, 0xA7, + 0xC8, 0x11, 0xEF, 0x3C, 0x1D, 0x66, 0x16, 0xA0, + 0xA3, 0xA2, 0x85, 0xA9, 0x9B, 0x09, 0x62, 0x11, + 0x10, 0x07, 0x8F, 0x2C, 0xFC, 0xA7, 0x24, 0xB8, + 0xF8, 0x93, 0xEE, 0xA6, 0x4F, 0x6D, 0xFA, 0xF6, + 0xA4, 0x17, 0x19, 0x14, 0xC1, 0x8F, 0xF8, 0x5C, + 0x7C, 0x8A, 0x3C, 0xAE, 0xD8, 0x5A, 0xBA, 0xE6, + 0x32, 0x04, 0x78, 0xDC, 0xC3, 0xA1, 0x54, 0xE2, + 0xD1, 0x25, 0x93, 0x0A, 0x8C, 0x85, 0xE9, 0xBB, + 0x1E, 0x73, 0xDF, 0xEB, 0xD2, 0xAC, 0x38, 0xE9, + 0xEB, 0xFF, 0x4A, 0x6F, 0xEF, 0x4E, 0x48, 0x20, + 0x0D, 0x04, 0x7A, 0x13, 0x74, 0x07, 0x3B, 0x85, + 0x2A, 0x36, 0x59, 0x4E, 0x54, 0x28, 0xDC, 0xA2, + 0xF8, 0x7E, 0xB2, 0xC5, 0x8C, 0x11, 0x9C, 0x64, + 0x25, 0xCE, 0x3E, 0xB2, 0xD8, 0x5C, 0x4C, 0xB7, + 0x88, 0x24, 0xEF, 0x02, 0x52, 0x27, 0x39, 0xFB, + 0xA4, 0x7A, 0x24, 0x57, 0xEC, 0x0B, 0xB4, 0x95, + 0x0B, 0x48, 0xD4, 0x13, 0x93, 0xA1, 0x60, 0x13, + 0x2F, 0x18, 0xD3, 0xDF, 0x1B, 0xA7, 0x91, 0x39, + 0x55, 0x33, 0xC7, 0x88, 0x00, 0xFA, 0x97, 0x3C, + 0x45, 0xD3, 0xFD, 0x5C, 0xD6, 0x46, 0x54, 0x4B, + 0xE1, 0x62, 0x7C, 0xFF, 0x67, 0x4E, 0x33, 0xD9, + 0x8B, 0x6C, 0x3C, 0x5D, 0xA2, 0xBA, 0x2A, 0x06, + 0x42, 0xCB, 0x78, 0x62, 0x94, 0xDA, 0xD9, 0x4F, + 0xA8, 0x35, 0xAB, 0x49, 0x54, 0x9F, 0x88, 0x05, + 0x48, 0x5F, 0xEE, 0x13, 0x97, 0xD3, 0xE6, 0x37, + 0x3D, 0x8A, 0x29, 0xC1, 0xE6, 0xF4, 0x0F, 0x09, + 0x23, 0x15, 0x83, 0x63, 0x21, 0x8F, 0xBD, 0x32, + 0xC2, 0x72, 0xF2, 0x7F, 0x75, 0x74, 0x50, 0x47, + 0xF6, 0x98, 0x58, 0x91, 0xE7, 0xE9, 0x90, 0xA5, + 0xD1, 0xF3, 0x17, 0x0A, 0x5E, 0xAA, 0x6A, 0x10, + 0x46, 0x84, 0xB7, 0xD4, 0x8E, 0xDD, 0x54, 0x7E, + 0xAD, 0x4A, 0xEF, 0x45, 0x93, 0x63, 0x5C, 0x8E, + 0xCE, 0xD2, 0xB4, 0xB4, 0x0D, 0x68, 0xB9, 0xE7, + 0x2B, 0x46, 0x32, 0x04, 0xCF, 0x43, 0x0A, 0xE8, + 0x56, 0x7A, 0xA4, 0x39, 0xEE, 0x40, 0xA7, 0x87, + 0x8C, 0xC0, 0x2C, 0xCF, 0x9F, 0x53, 0xA3, 0x0E, + 0x2E, 0x03, 0xB8, 0xAB, 0x5A, 0xC1, 0x45, 0x50, + 0xE8, 0xD9, 0xD8, 0x32, 0x49, 0x4C, 0xFF, 0x83, + 0x8F, 0x99, 0x94, 0x35, 0xB3, 0xFD, 0xEC, 0xCE, + 0x03, 0x11, 0x2C, 0x17, 0x98, 0xC3, 0xD9, 0x2D, + 0x00, 0x59, 0xE0, 0x35, 0x11, 0x3F, 0x13, 0xE3, + 0xF8, 0x66, 0xF4, 0xB6, 0xAC, 0x7B, 0xC1, 0xE1, + 0x53, 0xD6, 0xAC, 0x0C, 0x7E, 0xB4, 0xE6, 0xBB, + 0x13, 0x01, 0xE6, 0x84, 0xCC, 0x9B, 0xC7, 0x6C, + 0x21, 0x0F, 0xD7, 0x63, 0xB8, 0xA6, 0x01, 0x64, + 0xAE, 0x0F, 0x2E, 0x9B, 0x32, 0x68, 0xB2, 0x89, + 0xA5, 0xA8, 0xEB, 0xE9, 0x62, 0x83, 0xBB, 0x61, + 0x32, 0xF6, 0x5F, 0xEA, 0x4E, 0x23, 0x53, 0x3A, + 0xE3, 0x41, 0xF6, 0xFC, 0x65, 0x45, 0x86, 0x86, + 0x59, 0xF0, 0x72, 0x06, 0xD9, 0x68, 0xB6, 0x59, + 0xB6, 0x55, 0x53, 0x4E, 0xA0, 0x5B, 0x27, 0xFB, + 0x58, 0x25, 0x7E, 0x0B, 0x9A, 0x30, 0x92, 0xCA, + 0xE6, 0x74, 0x5E, 0x6B, 0xFA, 0xFF, 0xFE, 0xB8, + 0x22, 0xD8, 0x3C, 0xA1, 0xC9, 0x46, 0xE3, 0x19, + 0x40, 0xC2, 0xBF, 0x89, 0xA2, 0x8D, 0x5D, 0x77, + 0xF5, 0xF3, 0xE9, 0x32, 0x1D, 0xB0, 0x29, 0x2D, + 0x44, 0x1C, 0x8B, 0xAF, 0x4E, 0x52, 0xCC, 0xB6, + 0x86, 0x79, 0xF7, 0x27, 0x82, 0xAA, 0xBE, 0x53, + 0xC1, 0x1E, 0x59, 0xC6, 0x29, 0x96, 0x10, 0xDF, + 0xD4, 0x55, 0x91, 0x19, 0x57, 0x89, 0x89, 0x54, + 0xA1, 0x26, 0x63, 0x82, 0xAA, 0x65, 0xBA, 0xDB, + 0xBD, 0x74, 0xB1, 0xDC, 0x77, 0x73, 0xA7, 0xBF, + 0x21, 0xA1, 0x88, 0x36, 0xB6, 0x23, 0x56, 0x2D, + 0x81, 0x25, 0xAA, 0x82, 0xF1, 0x72, 0xAF, 0x76, + 0x32, 0xAB, 0xA8, 0x7E, 0xB9, 0x2B, 0xB3, 0x32, + 0x23, 0x3E, 0x88, 0xB5, 0x8A, 0x21, 0xDC, 0x21, + 0xDD, 0x01, 0x23, 0xFE, 0x5B, 0xC3, 0x9A, 0x11, + 0xB7, 0x47, 0x8C, 0x93, 0x12, 0x1C, 0x00, 0x3A, + 0x98, 0xF5, 0x7F, 0xD1, 0xB6, 0xBE, 0xC1, 0x16, + 0x4C, 0x2B, 0xBD, 0xFC, 0x87, 0xDD, 0xCC, 0x37, + 0x0B, 0x5E, 0x8D, 0xA3, 0x77, 0x78, 0x52, 0x05, + 0x3B, 0xFE, 0x3C, 0x6E, 0x5C, 0x2E, 0x98, 0x34, + 0x65, 0xCC, 0xF6, 0xCF, 0x8C, 0x82, 0x99, 0x05, + 0xFD, 0xD3, 0x8C, 0x4A, 0xE6, 0xF1, 0x73, 0xE0, + 0xB6, 0x00, 0x79, 0x53, 0xD1, 0xE4, 0xCF, 0xF1, + 0x3C, 0xC3, 0x9F, 0x21, 0x06, 0x18, 0xC8, 0xB8, + 0x95, 0x4F, 0xFE, 0x56, 0x18, 0x78, 0x95, 0x68, + 0x2D, 0x6C, 0xC9, 0x9E, 0xBC, 0xEB, 0xFE, 0x27, + 0x52, 0x27, 0xC7, 0xAE, 0x45, 0xB8, 0x94, 0xFA, + 0x2E, 0xF1, 0xC3, 0x75, 0xC7, 0xA2, 0x92, 0x24, + 0x6B, 0x83, 0xA8, 0xED, 0xC3, 0x56, 0x8C, 0xEB, + 0x4E, 0x2C, 0xED, 0x7C, 0x1F, 0x43, 0xD3, 0x9F, + 0x59, 0xFE, 0xE2, 0x86, 0xB8, 0x42, 0xFE, 0x39, + 0x0F, 0x19, 0xB2, 0x89, 0xA2, 0xF7, 0x86, 0x86, + 0xB4, 0xA4, 0xDB, 0x82, 0x83, 0x68, 0xE5, 0x2A, + 0x9A, 0xFE, 0x27, 0x0C, 0x12, 0xF3, 0x9C, 0x2F, + 0xD3, 0x8A, 0x34, 0x75, 0xE5, 0x6F, 0xCB, 0xFA, + 0x65, 0xBF, 0x60, 0xE9, 0xE5, 0x7C, 0x2C, 0xEC, + 0xD4, 0x29, 0x6C, 0x8E, 0x96, 0x52, 0x9C, 0x7A, + 0xE4, 0x17, 0x4F, 0x13, 0x1C, 0xE7, 0x09, 0x45, + 0xCA, 0x63, 0xCB, 0x2B, 0x04, 0x1A, 0xCB, 0x5C, + 0xF8, 0x3C, 0x83, 0x9C, 0x16, 0x6D, 0xFF, 0x43, + 0xAD, 0xF0, 0xF2, 0x31, 0x66, 0x37, 0x00, 0xFF, + 0x66, 0x40, 0xDE, 0xCD, 0xEF, 0x67, 0xB9, 0x5E, + 0x1E, 0x71, 0xA5, 0x48, 0xB1, 0xFA, 0x22, 0xBC, + 0x55, 0xE9, 0x80, 0x64, 0x8E, 0xA3, 0xE6, 0x7D, + 0x8F, 0xF5, 0xAA, 0x13, 0xFA, 0xC8, 0x80, 0x27, + 0x3E, 0x75, 0x67, 0x0B, 0x9E, 0x79, 0x8D, 0x24, + 0x27, 0xE0, 0xE3, 0x80, 0x5B, 0x00, 0xB9, 0xD1, + 0x3E, 0x95, 0x47, 0x27, 0xE9, 0xD7, 0xBF, 0x2B, + 0x17, 0xC3, 0xE0, 0xD8, 0xD5, 0x54, 0x98, 0xF9, + 0xF3, 0x0E, 0x96, 0x52, 0x45, 0x50, 0xE0, 0x64, + 0x95, 0xC8, 0xB9, 0x84, 0x4E, 0xB0, 0x08, 0x6A, + 0x38, 0x49, 0x92, 0x18, 0xFB, 0xDF, 0x95, 0xD4, + 0xB9, 0xBA, 0x1F, 0x07, 0x72, 0x18, 0x0E, 0x92, + 0xB8, 0xA0, 0x49, 0xBF, 0x93, 0x88, 0x31, 0xFE, + 0xA9, 0xAB, 0xA6, 0x8F, 0x4F, 0xF2, 0xA8, 0x84, + 0xCB, 0xB0, 0x75, 0x72, 0x5B, 0x49, 0x7D, 0x79, + 0x5D, 0x67, 0x58, 0x1F, 0x38, 0xA2, 0x89, 0x99, + 0x2A, 0xF3, 0xD8, 0x63, 0x77, 0x15, 0x30, 0x6D, + 0x11, 0x90, 0xD1, 0x5C, 0x26, 0xCC, 0xAF, 0x3C, + 0x78, 0xD3, 0xC3, 0x4C, 0xA2, 0x74, 0x3F, 0xE0, + 0xE3, 0x55, 0x21, 0xC5, 0x9A, 0x7F, 0xAE, 0x96, + 0xCC, 0x49, 0x27, 0x3C, 0x53, 0xFA, 0x73, 0xAB, + 0x02, 0xA1, 0xAC, 0xD4, 0x13, 0xB3, 0xC8, 0x60, + 0x44, 0xAC, 0x80, 0xB4, 0x11, 0xE1, 0x03, 0xCF, + 0x36, 0xD1, 0x80, 0x3F, 0xB4, 0x74, 0xFF, 0x0E, + 0xFD, 0x77, 0xF1, 0xB1, 0x05, 0x50, 0xF4, 0x3D, + 0x94, 0x0E, 0x1F, 0x09, 0x93, 0xB8, 0xE9, 0xC6, + 0x6B, 0x8F, 0x5E, 0x84, 0xC5, 0x2D, 0x89, 0x49, + 0xDD, 0x0C, 0x57, 0xFB, 0x75, 0x5E, 0x74, 0x60, + 0x1E, 0x54, 0xBF, 0x89, 0xD4, 0x3C, 0x81, 0x29, + 0x3B, 0x06, 0xF8, 0x8F, 0x25, 0xC8, 0xCF, 0xE5, + 0xB5, 0x7C, 0x01, 0x55, 0xFC, 0x7C, 0xE8, 0xDD, + 0xBC, 0x9D, 0x85, 0x49, 0x16, 0xCE, 0xF7, 0xA4, + 0x94, 0xB7, 0x48, 0xA3, 0xC4, 0x10, 0x0A, 0x13, + 0x58, 0xD9, 0xEF, 0x0C, 0x6C, 0x14, 0xD4, 0xA0, + 0x44, 0xB8, 0xF1, 0xA9, 0xB2, 0x6E, 0xDF, 0x91, + 0xDF, 0x2B, 0x32, 0x4E, 0xC3, 0x5A, 0x7A, 0xED, + 0xFF, 0x63, 0x10, 0xDB, 0x8B, 0x4A, 0xC7, 0xD1, + 0xBB, 0x7D, 0x43, 0x06, 0xB1, 0x4C, 0x01, 0x7B, + 0x61, 0x78, 0xEB, 0x4D, 0xD7, 0x6A, 0x5E, 0x71, + 0x6F, 0xB8, 0xA2, 0x6E, 0xC2, 0xBC, 0x65, 0x1D, + 0xD8, 0xDB, 0xDA, 0xCF, 0x60, 0x69, 0x41, 0x4E, + 0x2C, 0x13, 0x9B, 0xF8, 0x58, 0xB1, 0x18, 0x3E, + 0xD2, 0xBD, 0xC2, 0x18, 0xA3, 0xDE, 0xE9, 0x3F, + 0xCD, 0xD8, 0x0C, 0x4E, 0x48, 0xB1, 0x0D, 0xED, + 0x9D, 0x53, 0x68, 0xB9, 0x71, 0x13, 0x51, 0x2A, + 0x53, 0x54, 0x2D, 0x29, 0x4A, 0xA8, 0x86, 0xA1, + 0x83, 0x0B, 0x94, 0x4D, 0x14, 0x50, 0xA6, 0x99, + 0x9F, 0xDD, 0x16, 0x64, 0x15, 0xE7, 0xA0, 0x20, + 0x57, 0x94, 0x53, 0xA0, 0x28, 0x32, 0x6E, 0x13, + 0x92, 0x7A, 0x11, 0x5B, 0x8B, 0xDE, 0x9C, 0xE8, + 0x85, 0x1C, 0x7C, 0x6B, 0xBF, 0x39, 0x95, 0x3D, + 0xC6, 0xAD, 0x3C, 0xCA, 0x63, 0x82, 0x75, 0x11, + 0xBA, 0x71, 0x22, 0x97, 0x08, 0x9C, 0x2E, 0x15, + 0x96, 0x58, 0xCE, 0x14, 0x7C, 0x03, 0x66, 0x78, + 0x7B, 0xC6, 0xE5, 0x54, 0xB9, 0xAA, 0x58, 0xDE, + 0x72, 0xD2, 0x8C, 0x19, 0x7E, 0xED, 0xB6, 0x79, + 0x51, 0x44, 0x9F, 0x8F, 0xB5, 0x5F, 0xBA, 0x3A, + 0x07, 0x71, 0x6A, 0xD2, 0xEA, 0x91, 0xAC, 0xEB, + 0x60, 0x8C, 0xE4, 0xD5, 0x83, 0x47, 0x21, 0x2E, + 0xBB, 0x43, 0x54, 0x93, 0xD6, 0x23, 0x8A, 0xA3, + 0x89, 0x2B, 0xA2, 0xBE, 0xFF, 0x69, 0x9B, 0xD7, + 0x8E, 0x01, 0x54, 0x9C, 0x25, 0x1D, 0x5B, 0x36, + 0x00, 0x60, 0x88, 0xAC, 0x9D, 0xCD, 0x85, 0x2B, + 0x21, 0xA4, 0xF7, 0xDA, 0x7A, 0x02, 0xD1, 0x39, + 0x11, 0xF3, 0x40, 0x3A, 0x1D, 0x9C, 0x85, 0x86, + 0x8A, 0xB0, 0xD4, 0x54, 0x8A, 0xCF, 0xFC, 0x96, + 0x2A, 0xE9, 0x66, 0x2B, 0x33, 0xD4, 0x7D, 0xBC, + 0xEE, 0xCC, 0x40, 0xAE, 0xBA, 0x49, 0x99, 0x82, + 0xF5, 0xF4, 0xD5, 0x52, 0x7B, 0xDF, 0x35, 0x62, + 0xF2, 0x27, 0x04, 0x5F, 0xC6, 0x60, 0xB6, 0x4F, + 0xC2, 0x81, 0x71, 0x78, 0x3D, 0x4E, 0x26, 0x1D, + 0xA4, 0x9B, 0xC1, 0x24, 0x18, 0x61, 0x09, 0x4C, + 0x0C, 0xF2, 0xF0, 0x15, 0x62, 0x4D, 0xEF, 0x9A, + 0x52, 0x02, 0x16, 0x20, 0x09, 0x6B, 0x53, 0xEA, + 0xA5, 0xF1, 0x67, 0x2E, 0x59, 0x77, 0x01, 0x1F, + 0xE1, 0x5C, 0xD2, 0xF5, 0x79, 0x2F, 0xEC, 0xFF, + 0xF2, 0xA4, 0x8A, 0xB5, 0x1E, 0x15, 0x38, 0x42, + 0x98, 0x82, 0x32, 0x7E, 0x05, 0x16, 0xE6, 0xA7, + 0x8F, 0x95, 0x1B, 0x19, 0x1A, 0x6E, 0x98, 0x17, + 0x04, 0x42, 0xF8, 0x37, 0xED, 0x93, 0x99, 0x85, + 0xDC, 0x67, 0x44, 0x4E, 0x19, 0x6E, 0x64, 0xA6, + 0xC7, 0xF5, 0x58, 0x94, 0x0A, 0xD7, 0xC2, 0xC5, + 0x80, 0xDE, 0xC6, 0x31, 0x10, 0x09, 0xC7, 0x17, + 0x92, 0xDA, 0x3E, 0x7E, 0x37, 0x68, 0xDE, 0x34, + 0xCE, 0x02, 0x3F, 0x06, 0xA8, 0x5B, 0x36, 0x10, + 0x52, 0x73, 0x8A, 0xCB, 0x00, 0x36, 0x63, 0x1F, + 0x48, 0x0E, 0xD4, 0x9C, 0x42, 0x2B, 0xD2, 0xBD, + 0x1C, 0x4F, 0xD1, 0x33, 0x58, 0xF6, 0x48, 0xAA, + 0x29, 0xD9, 0xCD, 0xE2, 0x72, 0xFA, 0x13, 0xC1, + 0xDC, 0x8D, 0xA7, 0x1D, 0xB0, 0xCE, 0x66, 0x58, + 0xD1, 0xF9, 0xC8, 0x0A, 0x68, 0xA8, 0x09, 0x36, + 0x8B, 0xFD, 0xFD, 0xE0, 0x25, 0xEA, 0x57, 0x2D, + 0x59, 0x87, 0x62, 0x8A, 0x5D, 0x22, 0x25, 0x6F, + 0x20, 0x02, 0xDB, 0x77, 0xFB, 0xB3, 0xF0, 0xDA, + 0x43, 0xED, 0x25, 0x8E, 0xCB, 0xA5, 0x5F, 0xF3, + 0xC6, 0xFE, 0x96, 0x55, 0x20, 0x2A, 0x66, 0x1B, + 0x5F, 0x54, 0x45, 0xDF, 0x2C, 0x68, 0x75, 0x0E, + 0xF0, 0x57, 0x59, 0xB4, 0xFF, 0x2A, 0xFC, 0x0D, + 0xF0, 0x34, 0xFD, 0xD2, 0xD4, 0xD4, 0xD1, 0x12, + 0x0F, 0x50, 0x5F, 0xC0, 0x4E, 0x7A, 0x5E, 0x5B, + 0xFB, 0x78, 0x25, 0x69, 0xB0, 0xDA, 0x5E, 0x0C, + 0x9C, 0x17, 0x43, 0xCD, 0xE3, 0x69, 0xED, 0x00, + 0xE1, 0xDC, 0x4A, 0x29, 0xFD, 0x1C, 0x0F, 0x47, + 0x34, 0x5C, 0x40, 0x93, 0xCC, 0xDF, 0x42, 0xA0, + 0x80, 0x7E, 0x72, 0x9A, 0x34, 0xA6, 0x40, 0x22, + 0xAC, 0xF7, 0xAD, 0x02, 0xF2, 0x42, 0x2C, 0x67, + 0xD2, 0x5B, 0x4E, 0x3A, 0xF6, 0xD9, 0xC2, 0xBD, + 0x72, 0xAA, 0x2F, 0xA0, 0x0B, 0x22, 0x45, 0x72, + 0x83, 0x94, 0xD3, 0x10, 0x28, 0x43, 0xCE, 0x47, + 0x39, 0x36, 0xD0, 0x44, 0xA0, 0x7A, 0x82, 0x90, + 0x43, 0xBB, 0x9F, 0x6A, 0x0C, 0xD9, 0xEF, 0xE4, + 0x7C, 0xAF, 0x2E, 0xFD, 0x0B, 0x47, 0xD4, 0x40, + 0x32, 0x0F, 0x8F, 0x62, 0x1B, 0x6A, 0x0A, 0x61, + 0x6D, 0x25, 0x65, 0x62, 0x50, 0xD3, 0x39, 0x42, + 0x3B, 0xE6, 0x68, 0xFD, 0xB7, 0xCE, 0x6D, 0x48, + 0x8D, 0xFE, 0x30, 0xAB, 0xDE, 0x62, 0x04, 0xEC, + 0x75, 0x66, 0x82, 0x76, 0x90, 0x47, 0x66, 0x7A, + 0x1F, 0x9C, 0x00, 0x18, 0xCA, 0x5C, 0xE9, 0xF8, + 0x8B, 0x1F, 0x14, 0x64, 0x9B, 0x5E, 0x0B, 0xF9, + 0x86, 0xFA, 0xC1, 0x88, 0x13, 0x23, 0x36, 0xC9, + 0xF1, 0x66, 0x6B, 0x5C, 0xA5, 0x89, 0xC3, 0x32, + 0x92, 0xD4, 0x4A, 0xB3, 0xF5, 0x56, 0x84, 0xA7, + 0x10, 0x45, 0x1C, 0xBE, 0x5E, 0xC8, 0xF4, 0x4F, + 0x7A, 0x4F, 0x4C, 0xC5, 0x95, 0xB2, 0x6B, 0x4C, + 0x6F, 0xB1, 0xB3, 0x6A, 0x18, 0x2B, 0x64, 0x8E, + 0x83, 0x3E, 0xBC, 0x59, 0x49, 0xD9, 0xA1, 0xF8, + 0xF4, 0xC1, 0x40, 0x09, 0x8E, 0x11, 0x8E, 0x0E, + 0xA8, 0x51, 0x2B, 0xEE, 0x5D, 0x87, 0x8A, 0xAC, + 0xF9, 0x4F, 0xA8, 0xD4, 0x10, 0x28, 0x3F, 0x1D, + 0x5B, 0xAD, 0x09, 0x93, 0x16, 0x8B, 0xD5, 0x96, + 0xE4, 0x15, 0xB0, 0x83, 0x9F, 0xB0, 0x3A, 0x6A, + 0x5A, 0x68, 0xAF, 0x3B, 0x51, 0xBC, 0xF8, 0x3C, + 0x0F, 0x80, 0xD5, 0xBF, 0xA3, 0xC4, 0xFF, 0xAB, + 0x05, 0xFA, 0xA3, 0x96, 0xAC, 0x31, 0x22, 0x94, + 0xC9, 0xCA, 0xB1, 0xFB, 0xAE, 0xF9, 0x00, 0x0B, + 0x0A, 0x68, 0xD6, 0x20, 0x19, 0xEA, 0xC6, 0x77, + 0x1A, 0xBF, 0x26, 0x3C, 0x46, 0x4A, 0x43, 0x8A, + 0xCC, 0x8C, 0x33, 0xB1, 0x49, 0x78, 0x7F, 0x57, + 0x65, 0xB5, 0x10, 0x8C, 0x03, 0xF8, 0xDE, 0xFA, + 0x97, 0x9B, 0xEE, 0x54, 0x70, 0x84, 0x7D, 0xE0, + 0xBB, 0x5A, 0x72, 0x92, 0x5E, 0x0E, 0x57, 0x3B, + 0x45, 0x91, 0x5B, 0x5E, 0x89, 0xD1, 0x26, 0x62, + 0xC9, 0xEF, 0x7B, 0x6E, 0x5F, 0xC6, 0x7F, 0x87, + 0x2E, 0x3C, 0xC8, 0x5F, 0x7F, 0xC1, 0x66, 0xF6, + 0x09, 0x27, 0xFB, 0xD8, 0x6A, 0x33, 0x18, 0x71, + 0x8C, 0x4E, 0x4B, 0xC3, 0x50, 0xB7, 0x88, 0x81, + 0xEB, 0x21, 0x20, 0x03, 0x75, 0x2B, 0xA9, 0x8F, + 0xEE, 0x3C, 0x35, 0xD6, 0x30, 0xD9, 0x8F, 0x75, + 0xAB, 0x67, 0x54, 0xDF, 0x22, 0x25, 0x2D, 0x8B, + 0xB7, 0x29, 0xE7, 0x49, 0x72, 0x23, 0x40, 0x7C, + 0x4A, 0x2D, 0x3F, 0xB9, 0xCE, 0x4F, 0x4F, 0xC9, + 0x39, 0x94, 0x19, 0x4B, 0x9F, 0xE0, 0x4B, 0x44, + 0x4A, 0xC4, 0xA1, 0x6A, 0xFA, 0x55, 0xF4, 0xC3, + 0x9A, 0x8C, 0xF4, 0x8B, 0xBB, 0xB4, 0x17, 0x80, + 0xBC, 0x79, 0xBC, 0xE2, 0x71, 0x1C, 0x73, 0xEE, + 0x8A, 0x29, 0x49, 0x86, 0x59, 0xED, 0x37, 0xC2, + 0xDB, 0x11, 0xD7, 0x46, 0xAD, 0xDB, 0x81, 0xF9, + 0xDE, 0x3D, 0x4C, 0x2B, 0xEA, 0xAC, 0xDC, 0xA2, + 0x77, 0x00, 0xBA, 0xCF, 0x8A, 0x21, 0xB3, 0x25, + 0xFE, 0x69, 0x82, 0x1E, 0x8F, 0x90, 0xD5, 0x5D, + 0x55, 0xD2, 0x36, 0x91, 0xD0, 0xE4, 0xAF, 0x9E, + 0x41, 0xDB, 0x56, 0x86, 0xCF, 0x86, 0xC8, 0x40, + 0x7D, 0xF9, 0x23, 0xCC, 0xA1, 0xDA, 0x8B, 0x74, + 0xEB, 0x84, 0x22, 0xC8, 0x81, 0xCD, 0x1F, 0x35, + 0x78, 0x14, 0x42, 0x1C, 0xEF, 0x42, 0xF3, 0x58, + 0x9E, 0x2E, 0x48, 0x40, 0x29, 0xEF, 0x1C, 0x7F, + 0xBB, 0x32, 0xCD, 0x00, 0xEA, 0x49, 0x4F, 0xDE, + 0x6F, 0xB5, 0x6E, 0x31, 0x36, 0xBF, 0x72, 0x36, + 0x06, 0x06, 0xF6, 0x7A, 0xD2, 0xBB, 0x9A, 0xC2, + 0xA6, 0x73, 0x44, 0xFD, 0xB6, 0xFD, 0x9D, 0x17, + 0x7F, 0xCA, 0x5F, 0xB7, 0x0F, 0xD7, 0xF2, 0xAB, + 0x33, 0x24, 0x98, 0x2D, 0x5D, 0xD4, 0xC4, 0xD0, + 0xF0, 0x40, 0xC3, 0xC6, 0x4E, 0xDA, 0x52, 0x2F, + 0x47, 0x14, 0xE3, 0xA4, 0x66, 0x20, 0xDD, 0xE4, + 0x72, 0x06, 0x1D, 0x81, 0xE0, 0xF7, 0x24, 0x2B, + 0x69, 0xB3, 0x18, 0x65, 0x3C, 0x41, 0xCC, 0x74, + 0xE3, 0xB9, 0x13, 0xCE, 0x44, 0xAC, 0xD3, 0x17, + 0x7F, 0x8A, 0x8E, 0x54, 0xF7, 0xA3, 0x62, 0x1B, + 0x0E, 0x0A, 0xF4, 0x02, 0x7A, 0x7D, 0x6F, 0x22, + 0x80, 0xB5, 0x22, 0x8B, 0xDF, 0xA3, 0x65, 0x41, + 0x9C, 0x3D, 0xF7, 0x86, 0x2E, 0x17, 0x03, 0xDC, + 0x09, 0x09, 0xB1, 0x57, 0xC5, 0x48, 0xC8, 0xDD, + 0x9D, 0xEA, 0x6C, 0x00, 0x64, 0xC6, 0xC2, 0x3A, + 0x00, 0x13, 0x0B, 0x56, 0x0C, 0x67, 0x70, 0xAE, + 0x6C, 0x4F, 0x16, 0xE4, 0x25, 0x03, 0x4D, 0x1D, + 0x33, 0xF5, 0x1C, 0x29, 0x17, 0x88, 0x74, 0x09, + 0x22, 0x33, 0xD4, 0x35, 0xE2, 0x76, 0x7E, 0xAA, + 0x52, 0x72, 0x19, 0x41, 0xD4, 0x82, 0xDA, 0x8D, + 0x03, 0xCF, 0x96, 0x88, 0x7A, 0x73, 0xAD, 0xFD, + 0x39, 0x52, 0x71, 0x37, 0xC1, 0x0A, 0xCA, 0x95, + 0xEF, 0x16, 0xF9, 0x71, 0xAA, 0x77, 0x2E, 0xEC, + 0xAA, 0xEE, 0x07, 0xB8, 0xAC, 0xD0, 0x12, 0x28, + 0x45, 0xC4, 0xFE, 0x6F, 0x86, 0x60, 0xFD, 0x6E, + 0xD4, 0x9B, 0xAC, 0x6F, 0xC1, 0x18, 0xAC, 0x3B, + 0x7C, 0x75, 0xE4, 0x05, 0x50, 0xE9, 0xFF, 0x7B, + 0xB2, 0x43, 0x38, 0x27, 0x6F, 0xF3, 0xFD, 0xA0, + 0x06, 0xF1, 0x7A, 0x45, 0x80, 0xEF, 0xCD, 0xF1, + 0xC3, 0x1E, 0x11, 0x3F, 0xA7, 0x0D, 0x9C, 0x23, + 0x2C, 0x12, 0x5E, 0xF0, 0x56, 0xB8, 0xF5, 0xF5, + 0x77, 0xAF, 0xD4, 0x81, 0x94, 0xD8, 0x79, 0xB7, + 0x59, 0xA6, 0x6A, 0xC8, 0x77, 0xFC, 0x60, 0xA8, + 0x2F, 0xE3, 0x37, 0xF8, 0x16, 0x96, 0xCF, 0x8B, + 0x10, 0x48, 0xCF, 0xFD, 0x1D, 0x63, 0x2C, 0x26, + 0xA0, 0x79, 0xB2, 0xE2, 0xFB, 0xBE, 0xE2, 0xC6, + 0x1D, 0xDB, 0x8B, 0x68, 0x76, 0x0B, 0x12, 0xA7, + 0xB0, 0x56, 0x01, 0x3B, 0x31, 0x28, 0x66, 0x4D, + 0xDD, 0xA7, 0x9F, 0x80, 0x6B, 0x30, 0x75, 0xF5, + 0x67, 0x80, 0x55, 0xA0, 0xB4, 0x5E, 0x29, 0x9F, + 0xE2, 0xB0, 0x74, 0xAA, 0x0B, 0x9A, 0x35, 0x57, + 0x55, 0xC1, 0xAE, 0xF9, 0x7C, 0x4A, 0xEB, 0x62, + 0x61, 0x96, 0xFA, 0x4F, 0xBD, 0x0B, 0x8F, 0xDA, + 0xCF, 0x8E, 0x6A, 0xBC, 0x39, 0x77, 0x70, 0x11, + 0x8A, 0x65, 0x68, 0xAD, 0xE5, 0x18, 0x7E, 0xF4, + 0xA5, 0xC9, 0x57, 0xB9, 0x36, 0xB2, 0xA9, 0xA8, + 0x3B, 0xE4, 0xCA, 0x38, 0x22, 0xB3, 0x6E, 0xE0, + 0xB1, 0x36, 0xAE, 0x79, 0xC7, 0x19, 0x65, 0xBD, + 0x92, 0xCF, 0x4D, 0x13, 0x6C, 0x42, 0x64, 0x2B, + 0xF7, 0x6F, 0x85, 0x50, 0xDB, 0x51, 0xC9, 0xF3, + 0xC7, 0xDF, 0x3A, 0x7D, 0x40, 0x3B, 0x2D, 0x85, + 0x1E, 0x3F, 0xC5, 0x8B, 0xDF, 0x71, 0x49, 0xF3, + 0xD9, 0xAF, 0x90, 0xE8, 0xAD, 0x18, 0x04, 0x51, + 0xA7, 0x51, 0x6E, 0x3B, 0xC3, 0xB8, 0x9A, 0x3C, + 0x11, 0xA5, 0x89, 0x9F, 0x37, 0x27, 0x9F, 0xC4, + 0x2F, 0xDE, 0x15, 0xA1, 0xA9, 0x3C, 0xF8, 0x6B, + 0xA9, 0x88, 0x60, 0x4C, 0x07, 0xFF, 0xEA, 0x6C, + 0xD1, 0xD2, 0x2E, 0x21, 0x74, 0x5C, 0x4E, 0x43, + 0xCA, 0x41, 0xCE, 0x2D, 0x9C, 0x04, 0x8C, 0xD2, + 0xE5, 0xF3, 0x5A, 0xC0, 0xA7, 0x21, 0xD5, 0x26, + 0xC9, 0x9F, 0x14, 0xE5, 0x69, 0x16, 0xF2, 0xEB, + 0x62, 0xBD, 0xFA, 0x3E, 0xAD, 0x61, 0x34, 0xA5, + 0x28, 0x4E, 0xF2, 0x20, 0x5B, 0x08, 0x78, 0x1C, + 0x91, 0x03, 0xD1, 0xB2, 0x60, 0x49, 0x87, 0xD7, + 0x30, 0x0F, 0x34, 0xD9, 0xB6, 0x97, 0xCA, 0xD0, + 0x9F, 0x51, 0xD3, 0x5F, 0xFB, 0xD5, 0xB3, 0xBD, + 0x30, 0xE5, 0x52, 0xBF, 0x14, 0x38, 0xDD, 0x2E, + 0x59, 0x62, 0x02, 0xA4, 0xC8, 0x23, 0xFF, 0x37, + 0x73, 0x42, 0x35, 0x48, 0x56, 0xEF, 0xC1, 0x8D, + 0x46, 0xD1, 0xAE, 0x7C, 0x31, 0x34, 0x6D, 0xD7, + 0xF3, 0x9A, 0xCF, 0x9E, 0x29, 0xF4, 0xB4, 0xE3, + 0x8A, 0xF0, 0x35, 0x3E, 0xB3, 0x6C, 0x2E, 0x5B, + 0x4E, 0xB5, 0xDF, 0xC7, 0x29, 0x6B, 0xD2, 0x9B, + 0xCF, 0x41, 0xBC, 0xA0, 0x5C, 0xF6, 0x16, 0x16, + 0x90, 0x2B, 0x11, 0x2C, 0x58, 0xDA, 0xCE, 0x52, + 0xE6, 0x47, 0xBC, 0x5A, 0xE2, 0xD2, 0x9B, 0xCF, + 0x6A, 0x91, 0x85, 0x7C, 0x99, 0x3C, 0x5F, 0xED, + 0x53, 0x3D, 0x82, 0xB7, 0x38, 0x83, 0xD4, 0xCE, + 0x13, 0xDA, 0x10, 0xD3, 0xBB, 0xFE, 0x18, 0x59, + 0xDE, 0x79, 0xCB, 0x52, 0xD6, 0xB7, 0xD7, 0x5D, + 0x7D, 0x8E, 0x13, 0x86, 0xC0, 0x7D, 0x7F, 0x64, + 0x09, 0x2B, 0xB4, 0x49, 0xC0, 0x54, 0xFF, 0x5E, + 0x39, 0xA6, 0x13, 0xB6, 0x4E, 0x3B, 0x2F, 0xC3, + 0x9C, 0xA4, 0x50, 0x19, 0x2C, 0x29, 0x43, 0x03, + 0x6C, 0x34, 0xA2, 0xAF, 0x5D, 0x3B, 0x24, 0xB3, + 0x91, 0x71, 0x70, 0xC8, 0xB6, 0xA9, 0x8F, 0x29, + 0xF6, 0xA3, 0xFE, 0x41, 0x2F, 0x20, 0x8E, 0x17, + 0x13, 0xAC, 0xF9, 0x4A, 0x8E, 0x45, 0x43, 0x00, + 0xD8, 0xDF, 0x39, 0xC7, 0x19, 0xDD, 0xCA, 0x21, + 0xA7, 0x79, 0xDF, 0x46, 0x81, 0x01, 0x70, 0x74, + 0x42, 0x3F, 0xB5, 0xAF, 0x1D, 0xCC, 0xD7, 0x97, + 0xDD, 0x37, 0x1C, 0x49, 0x74, 0xDE, 0x29, 0xD2, + 0xF7, 0x70, 0xDC, 0x37, 0xA9, 0x69, 0x25, 0x83, + 0xDF, 0x75, 0xE5, 0x64, 0x72, 0xAB, 0x5B, 0xE0, + 0x1B, 0x97, 0x97, 0x91, 0xD7, 0x33, 0x19, 0x22, + 0x12, 0x5B, 0xDB, 0x19, 0x57, 0xFD, 0x98, 0x96, + 0xE4, 0xE9, 0x4E, 0x9C, 0x0A, 0x0A, 0xFF, 0xEA, + 0x26, 0xFF, 0xC3, 0x8F, 0xEF, 0x06, 0x67, 0xC6, + 0x43, 0xC2, 0x8F, 0xA1, 0xF5, 0x87, 0x87, 0xA5, + 0xA5, 0x8D, 0x93, 0xB9, 0xEF, 0x46, 0xC9, 0x3F, + 0x7B, 0x17, 0x07, 0x7C, 0xA7, 0x41, 0xCD, 0xD7, + 0xA4, 0x74, 0xF5, 0x3F, 0x2D, 0x79, 0x63, 0xDD, + 0x80, 0x99, 0xE3, 0x32, 0xC5, 0x40, 0x07, 0x12, + 0x0C, 0x7F, 0xC0, 0xF6, 0x1E, 0x85, 0xF2, 0xEC, + 0x2E, 0x9E, 0x7C, 0x77, 0x00, 0x29, 0x37, 0x85, + 0xFB, 0x4D, 0xEB, 0xDD, 0xD5, 0xA5, 0x12, 0x18, + 0xB6, 0x91, 0x74, 0xC0, 0x1E, 0x26, 0x6D, 0x6A, + 0x9C, 0x75, 0x6C, 0xA1, 0xE6, 0x5B, 0xDF, 0xF3, + 0x5F, 0xCB, 0xE3, 0x58, 0x83, 0x98, 0xE3, 0x54, + 0x33, 0xBB, 0x5D, 0xF8, 0xAE, 0xBB, 0x6B, 0xB4, + 0xA2, 0xC3, 0x63, 0x24, 0x06, 0xD9, 0x88, 0x31, + 0x0D, 0x8B, 0x4E, 0xF7, 0xAD, 0x3C, 0x65, 0x2D, + 0x8A, 0xDD, 0x3F, 0xDB, 0xBF, 0x49, 0xCE, 0xD5, + 0x03, 0x2B, 0x02, 0x91, 0x8D, 0x2C, 0x7C, 0xA3, + 0xDC, 0xB0, 0x2D, 0x07, 0x8D, 0x08, 0x2C, 0x3B, + 0x25, 0x2F, 0x2F, 0x59, 0xFF, 0xFD, 0x46, 0xEB, + 0xB5, 0x59, 0x4B, 0xA1, 0xE8, 0x05, 0x05, 0x3E, + 0xBB, 0x71, 0xA5, 0x9F, 0xE0, 0x94, 0x6A, 0xAD, + 0x92, 0x8E, 0xCD, 0xB1, 0x07, 0x5A, 0x01, 0x9B, + 0x0A, 0x92, 0x56, 0x8A, 0x59, 0x87, 0xB7, 0x9F, + 0x10, 0x1B, 0xF3, 0xB4, 0xE6, 0x88, 0x4A, 0xB9, + 0x88, 0x4F, 0xDA, 0x7B, 0x29, 0x19, 0x8F, 0xE8, + 0x0B, 0xC4, 0xEB, 0x7C, 0xE0, 0x23, 0x00, 0xDB, + 0x81, 0x36, 0x4D, 0x4D, 0x0A, 0x03, 0xBA, 0x8F, + 0x84, 0xA8, 0xD5, 0x18, 0xDD, 0x90, 0x67, 0x02, + 0x11, 0xF0, 0x90, 0x59, 0x95, 0x1B, 0x38, 0x92, + 0x62, 0x47, 0xE8, 0xED, 0x88, 0xEB, 0x93, 0x6E, + 0xB7, 0xB8, 0x4A, 0x8A, 0xFE, 0x85, 0xE6, 0xD0, + 0x54, 0xA7, 0x3A, 0x4E, 0xF8, 0x6A, 0x66, 0xC4, + 0xC2, 0x56, 0xB4, 0xA3, 0x30, 0x18, 0xED, 0x0A, + 0x29, 0xA9, 0xFE, 0xC8, 0x50, 0x10, 0x87, 0xB1, + 0x60, 0x3E, 0x99, 0x93, 0xDB, 0xD7, 0xD9, 0xA6, + 0xD3, 0xB9, 0x0E, 0x68, 0x9D, 0x29, 0xB4, 0xBB, + 0xC4, 0x79, 0x5A, 0xEA, 0x8E, 0xBF, 0x34, 0xF2, + 0xDB, 0xF4, 0xAC, 0x20, 0xE2, 0xF3, 0x1E, 0xED, + 0x5D, 0xAA, 0xC4, 0xD7, 0xFF, 0xF2, 0xD8, 0xBA, + 0xA7, 0x9C, 0xB8, 0x97, 0xC9, 0xFF, 0xA7, 0x48, + 0x11, 0x57, 0x0C, 0x31, 0x16, 0x54, 0x41, 0xF1, + 0xD6, 0x71, 0xED, 0x74, 0xBD, 0xC8, 0xC5, 0xFE, + 0xC4, 0x07, 0x18, 0x53, 0x38, 0xEA, 0x1B, 0x48, + 0xAD, 0x2A, 0xDA, 0x8E, 0x86, 0xE5, 0x96, 0xB1, + 0xB9, 0x20, 0xC9, 0x74, 0x31, 0x95, 0x4A, 0x28, + 0xF5, 0x6C, 0x7F, 0xC9, 0x71, 0xF9, 0xA0, 0x37, + 0x04, 0x10, 0x5A, 0x28, 0x77, 0xA7, 0x04, 0xCD, + 0x7D, 0x48, 0xD0, 0x69, 0xE3, 0xF2, 0x2A, 0x86, + 0xBD, 0xC3, 0xD6, 0x63, 0x18, 0xB8, 0xEB, 0x05, + 0x90, 0x11, 0x04, 0xFE, 0xA1, 0x9D, 0xAF, 0x87, + 0x1F, 0x27, 0x29, 0xA0, 0x85, 0x4D, 0x7C, 0x0C, + 0x4D, 0xE0, 0x77, 0x1C, 0x36, 0x8A, 0x43, 0xEA, + 0xC9, 0x6E, 0x67, 0x3F, 0xEB, 0x6D, 0x05, 0x1C, + 0xF3, 0x0C, 0x4C, 0xB0, 0xEB, 0xD5, 0xA0, 0xC6, + 0xDA, 0xA5, 0x0A, 0x02, 0x8C, 0x8B, 0xF9, 0x36, + 0x97, 0xBC, 0xBA, 0x37, 0x3C, 0xBB, 0xE1, 0x7B, + 0xD3, 0x74, 0x38, 0x24, 0x95, 0xDB, 0x0E, 0x57, + 0x74, 0x01, 0xE7, 0x4D, 0x2F, 0x83, 0xE9, 0x9E, + 0xD6, 0xE6, 0x10, 0xD8, 0x0A, 0x0B, 0xCF, 0xB2, + 0x40, 0x65, 0x07, 0xEC, 0xBE, 0xBD, 0x49, 0x7F, + 0x95, 0x97, 0x5C, 0x82, 0x4A, 0xCD, 0xFB, 0xFA, + 0xE0, 0x37, 0x03, 0x2D, 0x5A, 0x66, 0x0C, 0x15, + 0xEE, 0x2E, 0x8E, 0xBA, 0x38, 0x6A, 0xCB, 0xFF, + 0xCD, 0xAD, 0x83, 0xCE, 0x9A, 0x8B, 0x12, 0xB1, + 0xF1, 0x3A, 0xAF, 0x46, 0x65, 0x68, 0x46, 0xB7, + 0x1C, 0x98, 0x0F, 0x64, 0x8E, 0xF7, 0xDC, 0xFC, + 0xD0, 0xC8, 0x13, 0x02, 0xDA, 0x5E, 0xAE, 0x93, + 0x3F, 0xF3, 0x1B, 0x82, 0x52, 0x23, 0xFB, 0x8C, + 0xAC, 0x04, 0xDC, 0xF7, 0x8B, 0x53, 0x90, 0xAB, + 0x84, 0xB8, 0x36, 0x01, 0x66, 0x05, 0xB2, 0x45, + 0xC6, 0xBD, 0x55, 0x3F, 0x87, 0x33, 0x53, 0xC6, + 0xC4, 0xDE, 0xF2, 0xAA, 0xFC, 0xAF, 0x56, 0x84, + 0xFB, 0x3A, 0x78, 0x41, 0x8A, 0x37, 0x93, 0x5B, + 0x52, 0xD5, 0x41, 0x55, 0xDC, 0x9B, 0xAF, 0xA0, + 0x1F, 0xB2, 0xAA, 0x0C, 0x3A, 0x15, 0x61, 0x31, + 0x3D, 0x20, 0xB8, 0xB0, 0xBB, 0xF2, 0x8C, 0x50, + 0x71, 0x5D, 0x38, 0x6C, 0x99, 0x57, 0x5E, 0x00, + 0x0F, 0x39, 0x17, 0x91, 0x8F, 0x10, 0xCC, 0xBF, + 0x25, 0xEC, 0x4D, 0x05, 0xCB, 0x36, 0x2E, 0x03, + 0x03, 0x9D, 0x89, 0x6E, 0x22, 0xB2, 0xAC, 0xE4, + 0x73, 0xAA, 0x67, 0x48, 0x27, 0xA4, 0x91, 0x87, + 0x7E, 0x12, 0xDF, 0x9A, 0x4D, 0xCE, 0x5B, 0x7F, + 0x19, 0x6C, 0x72, 0xB4, 0x60, 0xE2, 0xDD, 0xA3, + 0xEA, 0xF3, 0x6F, 0xB8, 0xBA, 0x7F, 0xD8, 0x99, + 0x13, 0x0E, 0x1D, 0x14, 0xD9, 0xB0, 0x13, 0x3E, + 0x23, 0x8F, 0xB6, 0xB4, 0x46, 0x7E, 0x60, 0xC9, + 0x14, 0x5F, 0x9A, 0x1C, 0xA1, 0x9E, 0x98, 0xFD, + 0xE0, 0xE8, 0x64, 0x9C, 0x3A, 0x00, 0x4F, 0x50, + 0xC2, 0xA6, 0x63, 0xF6, 0x15, 0xB5, 0xA0, 0xF2, + 0x7E, 0xD2, 0xD8, 0x87, 0x79, 0x15, 0x14, 0xE0, + 0xA0, 0xFC, 0xF9, 0x3A, 0x13, 0xD7, 0xE5, 0x53, + 0x1E, 0x5D, 0x87, 0xD1, 0x4A, 0x12, 0x34, 0x62, + 0x04, 0x4B, 0x3D, 0xDD, 0xF4, 0xD2, 0xF3, 0x97, + 0xF7, 0xA6, 0xDA, 0xAD, 0xE8, 0x95, 0x00, 0x80, + 0xE6, 0x55, 0x6A, 0x44, 0x21, 0xF2, 0xAB, 0xE9, + 0x2A, 0x06, 0xBB, 0x04, 0x55, 0x4C, 0xC5, 0x8C, + 0x88, 0xAA, 0xDD, 0x9E, 0x84, 0xBA, 0x98, 0x80, + 0x35, 0x13, 0x8E, 0xD9, 0x48, 0xD6, 0xE2, 0xC6, + 0x27, 0x02, 0xA1, 0x60, 0xBE, 0xCC, 0x62, 0x02, + 0x40, 0x4C, 0x20, 0x6E, 0x71, 0x75, 0xDA, 0x50, + 0xFC, 0x89, 0xD9, 0x29, 0x56, 0x13, 0xF4, 0x7C, + 0x5D, 0xE5, 0x35, 0x14, 0x13, 0xEF, 0x73, 0x0A, + 0x82, 0x84, 0x73, 0x06, 0xA1, 0x18, 0x25, 0x9D, + 0xB1, 0x3E, 0xB7, 0x49, 0xEA, 0x18, 0xE2, 0x87, + 0xAC, 0xED, 0xC3, 0x65, 0x53, 0x51, 0x4B, 0x33, + 0xB2, 0x17, 0xFB, 0xF5, 0xC9, 0x7E, 0xFA, 0xFF, + 0x9D, 0x94, 0x14, 0x93, 0x02, 0xB5, 0x99, 0x9E, + 0x93, 0x09, 0xDF, 0xED, 0xD3, 0x01, 0xAE, 0x6E, + 0xF8, 0x2C, 0x45, 0x67, 0x95, 0x90, 0x57, 0xE6, + 0xB4, 0x5C, 0xAD, 0x2E, 0x9F, 0xDA, 0x94, 0xF7, + 0x6B, 0xA3, 0x1B, 0x69, 0xE2, 0xBB, 0xD6, 0x29, + 0xC1, 0x45, 0xC8, 0xB3, 0xCF, 0xEC, 0x1F, 0xD3, + 0x62, 0x55, 0x97, 0x8D, 0x0B, 0xE0, 0x57, 0xB8, + 0xB7, 0x00, 0x4A, 0x13, 0x20, 0x4D, 0x1D, 0xB2, + 0xCC, 0x69, 0x5A, 0x5C, 0x26, 0x23, 0x72, 0x8B, + 0x74, 0x0A, 0x78, 0xA8, 0x3A, 0x0F, 0x35, 0xA8, + 0xA2, 0xC3, 0x0A, 0x66, 0x33, 0xBF, 0xEA, 0x7A, + 0x53, 0xB6, 0x9E, 0x55, 0x33, 0xDD, 0x3D, 0x9C, + 0xCF, 0x43, 0x76, 0xC8, 0xE0, 0x90, 0xC9, 0x66, + 0xAC, 0x3C, 0x8E, 0x72, 0x0C, 0x75, 0xE4, 0xDC, + 0x52, 0xCD, 0x3E, 0x8A, 0x88, 0xD6, 0x8C, 0xD1, + 0x21, 0x54, 0xAB, 0x3B, 0xEC, 0x0C, 0xDC, 0x70, + 0xCC, 0xD0, 0x63, 0x1A, 0x30, 0x51, 0x5E, 0x32, + 0x98, 0x68, 0x5E, 0xD7, 0x1C, 0x71, 0x94, 0x1A, + 0xE8, 0x4E, 0x2A, 0x02, 0x16, 0x00, 0x1A, 0xC5, + 0xD2, 0xFF, 0x6B, 0xA0, 0x48, 0xB1, 0xF6, 0xE1, + 0xDA, 0x0E, 0x6E, 0xC3, 0xD3, 0xFD, 0x5D, 0xE7, + 0x6C, 0xFB, 0xC0, 0x2E, 0x6F, 0xD0, 0xA9, 0x4F, + 0xD0, 0x97, 0xCB, 0x70, 0x89, 0x1C, 0xE0, 0x7C, + 0xCB, 0xFC, 0x8B, 0x78, 0x27, 0x54, 0x1E, 0x74, + 0x86, 0x32, 0xF0, 0x69, 0xC7, 0xE4, 0x97, 0xE4, + 0x84, 0xCD, 0x30, 0x7C, 0xAD, 0xE3, 0x79, 0xC6, + 0xC7, 0x59, 0xB2, 0x56, 0x27, 0x74, 0xB0, 0x98, + 0x87, 0x09, 0xF6, 0x7B, 0x73, 0xA1, 0x1A, 0x53, + 0xC2, 0x6B, 0x2D, 0x1B, 0x7C, 0xBE, 0x45, 0x94, + 0x95, 0xED, 0x37, 0x00, 0x0A, 0x17, 0x75, 0x89, + 0x63, 0x85, 0xAA, 0x3F, 0xA8, 0x87, 0xB8, 0x18, + 0x48, 0x82, 0x90, 0xFE, 0xCE, 0x7E, 0xD6, 0x68, + 0x0E, 0x99, 0x20, 0xDC, 0xBD, 0x16, 0xE0, 0x96, + 0xEB, 0x3C, 0x7D, 0xE6, 0x6C, 0x4C, 0xBA, 0xA5, + 0x0B, 0x73, 0x51, 0x27, 0x9B, 0xDF, 0xC6, 0x92, + 0xDE, 0xED, 0x36, 0xCA, 0x5A, 0xAE, 0xF3, 0x02, + 0x7F, 0xEE, 0xB1, 0xB3, 0x01, 0xE0, 0xAB, 0x2F, + 0x13, 0xCE, 0x62, 0x1E, 0x0B, 0xB9, 0x45, 0x38, + 0x03, 0x09, 0x5E, 0xCB, 0xB1, 0x68, 0xD7, 0x10, + 0xCF, 0x5D, 0x47, 0xE5, 0x28, 0x72, 0x28, 0x4E, + 0x7C, 0x09, 0x38, 0x2A, 0xCB, 0x48, 0xF4, 0x3C, + 0xD8, 0x7C, 0x9E, 0x04, 0x44, 0x7B, 0xCA, 0xC5, + 0x4A, 0xA6, 0xD2, 0x82, 0x5A, 0x26, 0x45, 0xB6, + 0xB0, 0x22, 0xB2, 0x0A, 0xC2, 0x6B, 0x0C, 0x91, + 0x6A, 0x2C, 0xA2, 0x9A, 0x3C, 0xC5, 0xE2, 0xEE, + 0x15, 0x4F, 0x02, 0x0B, 0x2B, 0xCF, 0x93, 0x93, + 0xCA, 0x93, 0x60, 0x59, 0xD9, 0x79, 0x32, 0x0E, + 0xAA, 0xC7, 0x21, 0x81, 0xA2, 0x70, 0x08, 0xF7, + 0x46, 0xD1, 0x85, 0xBD, 0xA6, 0x02, 0x85, 0x7E, + 0x3F, 0xE0, 0x08, 0x9E, 0x37, 0x9A, 0xF0, 0xE7, + 0xB0, 0x88, 0x51, 0xFF, 0xF8, 0xE2, 0x2B, 0xF7, + 0x7C, 0xA4, 0xDB, 0x6B, 0x36, 0xBD, 0xF1, 0x41, + 0xFE, 0xD6, 0x5B, 0xC4, 0x39, 0x2A, 0xFA, 0xEB, + 0x45, 0x89, 0xEA, 0xA2, 0x7B, 0xAD, 0x25, 0x75, + 0x02, 0x43, 0xC7, 0xF7, 0x49, 0x2F, 0xFB, 0xCB, + 0xA1, 0x26, 0x68, 0xF7, 0x68, 0xF3, 0xC5, 0x0B, + 0x18, 0x30, 0xEC, 0x5F, 0x8D, 0x24, 0xD6, 0xBA, + 0x21, 0x57, 0x4A, 0x90, 0x05, 0xE3, 0x02, 0xBA, + 0xF5, 0x00, 0x20, 0x55, 0xB2, 0xDC, 0x4E, 0xCB, + 0x1A, 0xC8, 0xD5, 0x6A, 0x05, 0xE5, 0xB5, 0x9E, + 0x43, 0x24, 0x34, 0xB9, 0x76, 0x48, 0x98, 0xAB, + 0x0A, 0x6B, 0xD8, 0xBE, 0xF5, 0x2A, 0xC2, 0x34, + 0x9A, 0xB2, 0xC7, 0x44, 0xA9, 0xD7, 0xC3, 0x8B, + 0xF6, 0x93, 0x57, 0xFC, 0xE2, 0xD4, 0x94, 0x93, + 0x1D, 0xA4, 0x78, 0x5A, 0xB4, 0x3D, 0x86, 0x6D, + 0xF2, 0xC3, 0xBE, 0x04, 0x1F, 0x44, 0x86, 0xE2, + 0xF8, 0xE7, 0x6A, 0xD1, 0x67, 0x32, 0x44, 0xD0, + 0x7C, 0xA6, 0xF6, 0xED, 0x34, 0xCD, 0x6C, 0xC2, + 0x42, 0xAE, 0x3B, 0x81, 0x69, 0x16, 0xFF, 0x38, + 0x26, 0xC2, 0x0B, 0x16, 0x34, 0xA7, 0xC9, 0xF5, + 0x41, 0x4E, 0xFE, 0x83, 0xB6, 0xD1, 0x8C, 0xAF, + 0xB3, 0xE7, 0x99, 0x5C, 0xBA, 0xF9, 0x38, 0xFB, + 0xA1, 0x6E, 0x26, 0x6E, 0x26, 0xD1, 0xD0, 0x0E, + 0x44, 0xC1, 0x30, 0xE0, 0x1F, 0x2F, 0xE6, 0x04, + 0xF0, 0x2E, 0x79, 0x91, 0x8B, 0xE1, 0xE9, 0x65, + 0x2B, 0x63, 0x3D, 0xB8, 0xD2, 0x9D, 0xC3, 0xB4, + 0x93, 0x4B, 0x1A, 0x69, 0x8F, 0xD4, 0xEF, 0xEC, + 0x91, 0xF1, 0xDD, 0xB9, 0x50, 0x40, 0x05, 0xDC, + 0xDD, 0x3A, 0xD5, 0xBC, 0x40, 0x8F, 0x92, 0xCB, + 0xC2, 0xAC, 0x67, 0x6F, 0x3F, 0xBE, 0xDB, 0xAA, + 0x9B, 0x2B, 0x5C, 0x9E, 0x47, 0x03, 0x1D, 0x31, + 0xB6, 0x9D, 0xAC, 0x69, 0x4A, 0x2C, 0x02, 0xD2, + 0x5E, 0x02, 0x48, 0xDC, 0xF8, 0x51, 0x26, 0xA5, + 0x29, 0xF9, 0x09, 0xD7, 0xB8, 0x20, 0x5C, 0x42, + 0x96, 0x07, 0x04, 0x90, 0x47, 0x7D, 0x02, 0x69, + 0x28, 0x4A, 0x0F, 0x84, 0x9B, 0xBD, 0x77, 0xF5, + 0x56, 0xD7, 0x5A, 0x34, 0xC6, 0xE2, 0x9D, 0x25, + 0x73, 0x21, 0x08, 0xB0, 0xA9, 0x1F, 0x87, 0x07, + 0x36, 0x44, 0x92, 0x89, 0x4F, 0xE3, 0x78, 0x1F, + 0x6B, 0x69, 0x67, 0x25, 0x7B, 0xBE, 0xA5, 0x26, + 0x1C, 0xB7, 0x72, 0x3A, 0x92, 0x83, 0xEE, 0x0F, + 0x43, 0x68, 0x42, 0x88, 0xEE, 0x61, 0xC1, 0xAE, + 0x95, 0xB0, 0x6D, 0x7E, 0xCD, 0xA1, 0xF4, 0x90, + 0x05, 0xB1, 0x1E, 0x7B, 0x05, 0x0A, 0xB7, 0xBB, + 0x75, 0x77, 0x5E, 0x19, 0x3F, 0x37, 0x31, 0x90, + 0x25, 0x4F, 0x1C, 0x70, 0xEE, 0x69, 0x71, 0xC7, + 0x30, 0xDE, 0xAC, 0x9D, 0x20, 0x9E, 0xB0, 0xD1, + 0xAC, 0x72, 0x92, 0xDC, 0x76, 0xF2, 0x01, 0x00, + 0x19, 0x32, 0x98, 0xFC, 0x75, 0x25, 0x7F, 0x68, + 0x0D, 0x77, 0xE3, 0x48, 0x61, 0x99, 0x0C, 0xF1, + 0xD1, 0x91, 0x4C, 0x1F, 0xB1, 0x8B, 0x84, 0x79, + 0x42, 0x9A, 0x6C, 0x83, 0xFC, 0x89, 0xB4, 0x75, + 0x86, 0x41, 0x19, 0x8A, 0x4C, 0xE5, 0x0B, 0x83, + 0xBE, 0xB6, 0xAA, 0x1F, 0x46, 0x69, 0x0C, 0xBE, + 0x56, 0x59, 0x73, 0x29, 0x91, 0x0D, 0x44, 0x72, + 0x10, 0xEE, 0xBA, 0x10, 0x23, 0x10, 0x39, 0x5F, + 0x19, 0x71, 0x6E, 0x2A, 0x06, 0x2A, 0x77, 0x66, + 0xC6, 0x9B, 0x80, 0x6B, 0xAF, 0xE7, 0xC8, 0xB6, + 0x17, 0xF4, 0xF5, 0xE8, 0x13, 0x4B, 0xDD, 0x71, + 0xEB, 0xF7, 0x74, 0xB0, 0xEB, 0xF1, 0x82, 0x3A, + 0x83, 0x51, 0xAA, 0xB5, 0x5C, 0x9F, 0x4C, 0xCA, + 0x0A, 0x97, 0xFB, 0xC3, 0x07, 0xD7, 0x27, 0xF3, + 0x31, 0x80, 0x46, 0xEA, 0xDE, 0xA7, 0x0F, 0xC6, + 0xDD, 0x3C, 0xFE, 0x86, 0x06, 0x8F, 0x5A, 0x20, + 0xBF, 0x7D, 0xF1, 0xDC, 0xBF, 0x1B, 0x5F, 0x19, + 0xA4, 0xE4, 0x73, 0xB4, 0xBD, 0x3C, 0x29, 0xA5, + 0xA1, 0xAB, 0xC8, 0x21, 0x06, 0xC7, 0x1A, 0x26, + 0xCE, 0xB5, 0xCE, 0xA6, 0xD5, 0xE9, 0x36, 0x81, + 0x70, 0x8F, 0x7C, 0x30, 0x14, 0x9D, 0x15, 0x22, + 0x05, 0xC8, 0x22, 0x73, 0xE8, 0xA0, 0x93, 0x47, + 0x58, 0x68, 0x89, 0x54, 0xCA, 0x88, 0x3F, 0xCE, + 0x0C, 0x93, 0x1D, 0x4C, 0x58, 0xA2, 0xC3, 0x5A, + 0xBE, 0xB1, 0xB0, 0xB1, 0xC2, 0xDF, 0x2F, 0x05, + 0x09, 0x67, 0x05, 0xC4, 0x88, 0xEB, 0xE3, 0xE3, + 0x36, 0xD8, 0x91, 0xD6, 0x05, 0x10, 0x8D, 0x91, + 0x3B, 0x8B, 0x9D, 0x70, 0x9E, 0x63, 0xE8, 0xD5, + 0xAF, 0x3D, 0x9A, 0xA4, 0x82, 0xC3, 0x30, 0x76, + 0x72, 0x7C, 0x8D, 0xA2, 0xC7, 0x0C, 0xD7, 0x55, + 0x30, 0x25, 0x01, 0x70, 0x09, 0xB7, 0x7E, 0x4F, + 0x1E, 0x94, 0x9D, 0xB9, 0x94, 0xCA, 0xF6, 0xF2, + 0x05, 0xB7, 0x9B, 0x65, 0x34, 0x52, 0xE2, 0x96, + 0xAA, 0x58, 0xB2, 0x2D, 0x65, 0x26, 0x58, 0xA7, + 0xDC, 0x4E, 0x6B, 0x95, 0x52, 0x81, 0xF7, 0x97, + 0xB9, 0x01, 0x17, 0x5F, 0xC7, 0xCF, 0xE0, 0x33, + 0x80, 0xF6, 0xC6, 0x45, 0x5A, 0x8C, 0x4F, 0x38, + 0xE2, 0xBC, 0xCB, 0x29, 0x18, 0x9E, 0x52, 0x21, + 0x43, 0x12, 0x03, 0xF3, 0x45, 0xC9, 0xC1, 0x5A, + 0x62, 0x85, 0xAD, 0x12, 0x3F, 0x84, 0x0B, 0x99, + 0x55, 0xE9, 0xE4, 0xA8, 0x36, 0x2B, 0xE2, 0x88, + 0x68, 0xE4, 0xF6, 0xB9, 0x63, 0xAD, 0xB8, 0xFF, + 0xA6, 0xB7, 0x78, 0xD1, 0x6B, 0xD8, 0x94, 0xA3, + 0xB0, 0xE4, 0xC1, 0x0E, 0x5F, 0xC6, 0x7A, 0x3A, + 0x97, 0x46, 0xA0, 0x6C, 0xC0, 0xE2, 0x24, 0xDE, + 0xAF, 0x6D, 0x25, 0xF9, 0x4C, 0x1F, 0xC2, 0x13, + 0xF3, 0x69, 0xDE, 0xBE, 0xE1, 0xCC, 0xA2, 0x61, + 0x38, 0x46, 0xB8, 0x72, 0x5C, 0x43, 0x31, 0x6F, + 0x14, 0x5B, 0x8A, 0xCC, 0xF0, 0x54, 0x7B, 0xBF, + 0xF0, 0x7A, 0x76, 0xF8, 0x32, 0x84, 0x8A, 0xD1, + 0x09, 0x1B, 0x78, 0x77, 0xF0, 0xFE, 0x50, 0x92, + 0x0A, 0xB5, 0xC3, 0x6B, 0x76, 0x94, 0x40, 0xB5, + 0xDB, 0xB6, 0x18, 0x85, 0x91, 0x71, 0x1D, 0x52, + 0xA8, 0x99, 0xB5, 0xCC, 0xD0, 0x18, 0xA4, 0x42, + 0x62, 0x34, 0x3C, 0x78, 0xD6, 0xA5, 0x98, 0x29, + 0x9D, 0x4D, 0xE1, 0xB6, 0xF4, 0xA2, 0x93, 0xED, + 0xB9, 0xB8, 0xE6, 0x88, 0xC7, 0x16, 0xA0, 0x35, + 0xFB, 0x2C, 0x9D, 0x0A, 0x83, 0x0D, 0x3D, 0x6B, + 0xAC, 0xEA, 0x61, 0x05, 0x0A, 0xE6, 0xA7, 0xDD, + 0x3F, 0x08, 0x14, 0x73, 0xCA, 0x0D, 0x84, 0xB8, + 0x22, 0xE2, 0xDF, 0x96, 0xB3, 0x73, 0xE4, 0x20, + 0x13, 0xEE, 0x19, 0x72, 0x22, 0x56, 0x1D, 0x11, + 0xAC, 0xF7, 0xBA, 0x0E, 0xE0, 0xA2, 0x18, 0xEE, + 0x5B, 0xC3, 0xF6, 0x13, 0xAE, 0x6D, 0x42, 0x9B, + 0xB1, 0xCC, 0x8F, 0xDD, 0x04, 0xE9, 0x95, 0x26, + 0x26, 0x2C, 0x09, 0x91, 0xBA, 0x6F, 0xC1, 0x23, + 0x4C, 0x09, 0x77, 0xAF, 0x78, 0x81, 0x3E, 0x05, + 0x12, 0xDE, 0xC8, 0x91, 0xDC, 0x87, 0xB8, 0xB2, + 0x35, 0x81, 0x6E, 0x19, 0xE2, 0xC2, 0x86, 0x0F, + 0x58, 0xFA, 0xE4, 0xE1, 0xBA, 0xF7, 0xB4, 0x22, + 0xEF, 0x0A, 0xFA, 0x53, 0xA5, 0x9B, 0x82, 0x6C, + 0xBA, 0xDF, 0x26, 0x2D, 0x70, 0x07, 0x27, 0xD0, + 0xAB, 0x33, 0xAD, 0x71, 0x08, 0xB3, 0x91, 0xC9, + 0x8A, 0xE0, 0x4F, 0x4C, 0xD6, 0xC5, 0xBA, 0xE0, + 0x7C, 0xE0, 0xBF, 0x4D, 0x01, 0x7A, 0xC8, 0xFC, + 0xE5, 0x03, 0x72, 0x87, 0xA9, 0x30, 0x9A, 0xD4, + 0xA3, 0xD6, 0xE9, 0xB3, 0x08, 0x3E, 0x54, 0xB5, + 0xA6, 0x98, 0xBA, 0x9B, 0x2B, 0xF0, 0x00, 0x0B, + 0x3A, 0xE9, 0xF0, 0xB1, 0x5A, 0xB9, 0x87, 0x33, + 0x42, 0x77, 0x03, 0xC8, 0x57, 0xBD, 0x6C, 0x59, + 0x92, 0xC3, 0xDE, 0xA8, 0x71, 0xA6, 0x41, 0xF4, + 0xDE, 0x6D, 0x49, 0xAB, 0xBD, 0x39, 0x1E, 0x8A, + 0xEF, 0xCD, 0x59, 0x72, 0xC3, 0x3D, 0x74, 0x63, + 0xFC, 0x41, 0xFA, 0x4C, 0xB6, 0x79, 0xA9, 0xBC, + 0x7B, 0x9E, 0xD8, 0x1D, 0x0E, 0x23, 0xA7, 0x66, + 0x39, 0x3D, 0x7E, 0xAA, 0xC0, 0x3E, 0x3B, 0x05, + 0x3F, 0xC9, 0x11, 0xC4, 0x92, 0xCC, 0xD3, 0xF2, + 0xDB, 0xB9, 0xEF, 0x13, 0x07, 0x70, 0xC4, 0x68, + 0x3C, 0x2C, 0x07, 0x23, 0xE6, 0xA9, 0x09, 0xC3, + 0xBE, 0xBC, 0x9F, 0x1E, 0xA8, 0x58, 0xCC, 0xEE, + 0x9D, 0xC8, 0xC8, 0x7B, 0x53, 0xE1, 0x93, 0x8A, + 0x26, 0x79, 0x6C, 0x9D, 0x7B, 0x57, 0x61, 0x5E, + 0x42, 0xD2, 0x64, 0x5F, 0x16, 0xC3, 0x40, 0xD8, + 0xF0, 0x92, 0x6D, 0x95, 0x5E, 0x4B, 0x3C, 0x48, + 0xA6, 0x59, 0x57, 0xF4, 0x30, 0x51, 0x1B, 0x45, + 0x00, 0x02, 0x65, 0xAE, 0x56, 0x16, 0xE5, 0xD5, + 0x1E, 0x65, 0x5D, 0xEF, 0xA0, 0x3F, 0x86, 0x76, + 0x7B, 0x35, 0xE9, 0xF5, 0x14, 0x48, 0xD7, 0x99, + 0x4C, 0x91, 0x01, 0xA4, 0x51, 0xD1, 0x6B, 0x48, + 0x3A, 0x42, 0x25, 0x47, 0xE7, 0xFD, 0x7E, 0x21, + 0x32, 0xB7, 0xCB, 0xF7, 0xE5, 0x36, 0x95, 0x64, + 0x12, 0x73, 0xB2, 0xA8, 0xEE, 0x2D, 0x88, 0xF9, + 0x8D, 0xFE, 0xDB, 0xB3, 0xD7, 0xD1, 0x7E, 0x28, + 0xC2, 0x91, 0x49, 0xC0, 0xC0, 0x65, 0x25, 0xF6, + 0xDD, 0xB2, 0x39, 0xEF, 0x2C, 0x75, 0xA5, 0xBA, + 0x18, 0x81, 0xB2, 0x4D, 0x8D, 0x62, 0x29, 0x71, + 0x65, 0x88, 0x4E, 0x25, 0xCE, 0x9F, 0x91, 0xB9, + 0xB9, 0xD9, 0xF2, 0xA4, 0x0B, 0xA3, 0x3B, 0x84, + 0xD9, 0xD4, 0x3A, 0x94, 0xA6, 0x1B, 0x93, 0x71, + 0x33, 0x6C, 0x4C, 0x9F, 0x30, 0x3B, 0x18, 0x3D, + 0xAC, 0x15, 0x6C, 0x49, 0x9F, 0xC4, 0x86, 0xFF, + 0x5F, 0x8C, 0xCF, 0xCB, 0xE7, 0x70, 0x17, 0x70, + 0x65, 0x25, 0xBB, 0x1A, 0xD0, 0xE3, 0x10, 0x9B, + 0x1D, 0x19, 0x4D, 0x19, 0x58, 0x45, 0xB7, 0x41, + 0xFF, 0xE5, 0xC9, 0x05, 0xDC, 0xC2, 0x4F, 0x6D, + 0x0D, 0x68, 0x37, 0xFC, 0x4D, 0x5D, 0x9A, 0x85, + 0xFA, 0x40, 0x2F, 0xBE, 0x56, 0x15, 0x13, 0x9A, + 0x64, 0x9E, 0x4C, 0x9C, 0xE0, 0x8F, 0x18, 0xDF, + 0x53, 0x47, 0x19, 0xA1, 0x03, 0x66, 0xD3, 0x32, + 0xFE, 0x0D, 0xC0, 0x40, 0x94, 0xA2, 0x00, 0xFB, + 0x53, 0xF7, 0x71, 0xC4, 0xD4, 0x47, 0x29, 0x1A, + 0x7D, 0x02, 0x16, 0x3F, 0x56, 0x96, 0x2B, 0x9E, + 0x57, 0x17, 0x02, 0x9A, 0x5F, 0x27, 0x93, 0xD6, + 0x48, 0xFB, 0xA5, 0xE9, 0x14, 0xD9, 0xC1, 0x45, + 0x63, 0x38, 0xB2, 0xB6, 0xCA, 0xBD, 0x6A, 0xCE, + 0x80, 0xB4, 0x5C, 0xC8, 0xD7, 0x6D, 0x09, 0xA7, + 0x27, 0xF9, 0x12, 0x88, 0x3E, 0x3C, 0x79, 0x48, + 0xCF, 0xE6, 0x54, 0x12, 0x8D, 0x91, 0x9B, 0x5B, + 0xF2, 0x74, 0x38, 0xE6, 0x96, 0xC0, 0xAF, 0xED, + 0x96, 0x20, 0x6F, 0xD5, 0xB3, 0x95, 0x82, 0xB1, + 0xE1, 0x38, 0x46, 0xF4, 0x85, 0xAD, 0x9F, 0x68, + 0x4C, 0x76, 0x93, 0x9E, 0x08, 0xDD, 0xAC, 0x36, + 0x2C, 0x08, 0x2A, 0xA7, 0x21, 0x56, 0x62, 0xBE, + 0x9F, 0x46, 0x6B, 0xA0, 0x36, 0xC7, 0xC9, 0x6A, + 0xEF, 0xE8, 0xE1, 0x6A, 0x42, 0xA1, 0x35, 0x64, + 0xCF, 0xCA, 0xF6, 0x0E, 0x3C, 0x9E, 0xBB, 0xF9, + 0x88, 0xA3, 0x0A, 0xAC, 0x81, 0x3D, 0x5E, 0x82, + 0xB8, 0x71, 0x46, 0xC6, 0xAE, 0x14, 0x71, 0xFE, + 0x47, 0x33, 0xC3, 0xA5, 0x46, 0x02, 0x97, 0x5A, + 0x44, 0x4E, 0x00, 0x38, 0x8C, 0x24, 0xB5, 0x0E, + 0x19, 0x14, 0xFD, 0xF4, 0x89, 0x99, 0x72, 0x19, + 0xEB, 0x55, 0x5C, 0xC9, 0x62, 0xE8, 0xFD, 0x92, + 0x03, 0x44, 0xB9, 0x2E, 0x01, 0x99, 0x48, 0xE0, + 0xD9, 0xB0, 0xD9, 0x5F, 0x75, 0x7E, 0xB2, 0xD0, + 0xD5, 0xE8, 0xBD, 0xF0, 0x6C, 0xCD, 0x4F, 0x54, + 0x6C, 0x1D, 0xB1, 0x12, 0x82, 0x6E, 0x53, 0xE7, + 0x67, 0xD8, 0xDC, 0xE8, 0xD4, 0xB5, 0x68, 0x51, + 0x15, 0xC6, 0x26, 0x44, 0x65, 0xB4, 0x70, 0x4D, + 0xD6, 0x3F, 0x63, 0xDC, 0xEE, 0x70, 0x71, 0x13, + 0xB2, 0x52, 0x5B, 0xF0, 0x5E, 0xCD, 0x71, 0x44, + 0x46, 0x83, 0x8F, 0x47, 0xC6, 0xE1, 0x48, 0x8A, + 0xD5, 0xCF, 0xBE, 0x1F, 0x91, 0x76, 0x91, 0xE5, + 0x9F, 0x2A, 0xB0, 0x63, 0x6F, 0x37, 0x32, 0x4B, + 0x54, 0xD0, 0x7F, 0x91, 0x24, 0xD7, 0x8F, 0xB2, + 0xF4, 0xD0, 0x44, 0x55, 0xD5, 0x88, 0x10, 0xD1, + 0xE5, 0x1D, 0xF8, 0xF8, 0x73, 0xD5, 0xA8, 0x37, + 0x30, 0xAD, 0x0E, 0xF0, 0x75, 0x3A, 0x0B, 0xFC, + 0xD8, 0x97, 0x78, 0xA1, 0x38, 0xFC, 0x55, 0x97, + 0x31, 0x7D, 0x84, 0x55, 0x7C, 0xFF, 0x77, 0x90, + 0x1D, 0xE5, 0x40, 0x14, 0x0E, 0x58, 0xEF, 0xA4, + 0xC2, 0x9D, 0x52, 0xBC, 0x96, 0x41, 0xF8, 0x36, + 0x2A, 0xB6, 0xF9, 0x68, 0x45, 0x5D, 0xB1, 0xDF, + 0x02, 0x24, 0x3E, 0xF4, 0x59, 0x62, 0x1C, 0x38, + 0x45, 0x5E, 0x7C, 0xB6, 0xC8, 0x08, 0x55, 0x4C, + 0x3D, 0x46, 0xA2, 0x2F, 0x0D, 0xDD, 0x56, 0x1A, + 0x9D, 0x67, 0xC8, 0x48, 0x62, 0xA2, 0x5B, 0xD6, + 0x06, 0x98, 0x72, 0x41, 0xAD, 0x89, 0x59, 0x0B, + 0xBD, 0x34, 0x3A, 0xBA, 0xF3, 0x87, 0xB5, 0xA4, + 0xC6, 0x4F, 0x3C, 0x31, 0x22, 0x5F, 0x7F, 0x8E, + 0x07, 0x57, 0x36, 0x4B, 0x91, 0x10, 0x9A, 0x57, + 0x6A, 0x97, 0x7E, 0x82, 0x8A, 0x79, 0x8B, 0xC0, + 0x4A, 0x74, 0xB0, 0x36, 0x26, 0xE4, 0x61, 0xB7, + 0x09, 0x23, 0x3B, 0xFF, 0xAC, 0x93, 0x0C, 0x57, + 0x46, 0x67, 0xFA, 0xD0, 0x5C, 0x23, 0x66, 0xC5, + 0xB2, 0x84, 0x46, 0xDE, 0x00, 0x90, 0xD1, 0x7F, + 0x5E, 0x7F, 0x90, 0x3B, 0xEC, 0x6E, 0xF6, 0xB6, + 0x97, 0x31, 0x6D, 0x78, 0x29, 0x18, 0xF8, 0x3E, + 0xC5, 0x44, 0xB9, 0x9D, 0x07, 0x0F, 0x43, 0x35, + 0x63, 0xCC, 0x9C, 0xBE, 0xAD, 0x53, 0x74, 0xF6, + 0xE0, 0x34, 0x77, 0x86, 0x9B, 0xFD, 0x38, 0xD0, + 0xF8, 0xB1, 0xEC, 0x49, 0x21, 0xF8, 0xAD, 0x06, + 0x55, 0x04, 0x70, 0x7B, 0x55, 0x30, 0xC9, 0xBF, + 0xD3, 0x30, 0x21, 0x06, 0x83, 0xB8, 0xCA, 0x57, + 0x4E, 0xFC, 0x5E, 0x05, 0xF3, 0x6A, 0x8A, 0x14, + 0x16, 0xF9, 0xD3, 0xF3, 0x09, 0x21, 0x8D, 0x1D, + 0xEC, 0xED, 0x5C, 0x9A, 0x4E, 0xDF, 0x90, 0xBE, + 0xC6, 0x7B, 0x2E, 0x85, 0x48, 0xDF, 0xBD, 0xE0, + 0xA7, 0xB3, 0x88, 0xF9, 0xDA, 0x17, 0x7A, 0x4A, + 0xAC, 0x86, 0xEF, 0xA3, 0xA2, 0x2D, 0xD1, 0x3F, + 0xB0, 0x68, 0x32, 0x6A, 0x46, 0x4E, 0x86, 0x5F, + 0x9C, 0xE0, 0x40, 0xE4, 0x3F, 0x72, 0xCC, 0x77, + 0x22, 0xFF, 0xBE, 0x8D, 0x82, 0xFB, 0x77, 0x2A, + 0x6B, 0xB0, 0x3C, 0x8E, 0x44, 0xD8, 0xAB, 0x79, + 0x3C, 0x9D, 0xCD, 0x49, 0x61, 0xEE, 0x3E, 0x74, + 0x9E, 0x8C, 0x5B, 0x6C, 0xB3, 0x81, 0x07, 0x83, + 0xFA, 0xB7, 0x77, 0xAA, 0x65, 0x71, 0x9C, 0xDB, + 0x70, 0xC7, 0x5E, 0x6E, 0x55, 0xBE, 0xB3, 0xEA, + 0xAB, 0xDC, 0x49, 0xE0, 0x42, 0xC6, 0xDF, 0x20, + 0x25, 0xE1, 0x19, 0xCD, 0xAA, 0x32, 0xE5, 0x48, + 0x72, 0xD6, 0x8C, 0xFE, 0xFA, 0x97, 0x40, 0x4D, + 0x9D, 0x1F, 0x15, 0xA7, 0xD9, 0xF3, 0x61, 0x81, + 0x7E, 0x7F, 0x36, 0xFA, 0x49, 0x0D, 0xB1, 0x45, + 0x3C, 0x0C, 0xD9, 0x1E, 0x53, 0xF9, 0xE6, 0x12, + 0x2A, 0xDE, 0x3A, 0x81, 0xD0, 0x5F, 0x6E, 0x63, + 0x30, 0x21, 0x7D, 0xAA, 0x26, 0x67, 0xC8, 0x54, + 0x5B, 0x70, 0x24, 0x6F, 0xFF, 0xA9, 0xB6, 0x07, + 0x87, 0x75, 0x31, 0x00, 0x96, 0x87, 0x06, 0x9B, + 0xAD, 0x52, 0xBB, 0x30, 0x8E, 0xD0, 0x93, 0xD6, + 0x14, 0x64, 0xBE, 0x38, 0x7E, 0xA7, 0x84, 0xDD, + 0x81, 0x2F, 0x03, 0x61, 0x71, 0x18, 0x51, 0x3F, + 0x1A, 0x64, 0xBD, 0xF2, 0xE8, 0xD8, 0x79, 0x2F, + 0xC5, 0x3B, 0xFB, 0xF7, 0x0A, 0x77, 0xFA, 0xB3, + 0xDA, 0x99, 0xCE, 0x50, 0xAD, 0x10, 0xA3, 0xFC, + 0x14, 0xBC, 0x0D, 0x6B, 0xF6, 0x69, 0xB4, 0x3E, + 0xEF, 0x73, 0xB2, 0xA7, 0x2B, 0xE8, 0x8A, 0xC8, + 0x54, 0xBD, 0x2C, 0x2D, 0x49, 0x59, 0x85, 0x8A, + 0xE7, 0xE1, 0x63, 0x48, 0x5F, 0xE7, 0x95, 0x78, + 0x64, 0xF2, 0xA3, 0xD3, 0xA7, 0x9F, 0x0A, 0x56, + 0x97, 0xA1, 0x57, 0xA9, 0xA0, 0x8A, 0x80, 0x13, + 0x38, 0xD2, 0xD0, 0xAF, 0x03, 0x16, 0x0D, 0x51, + 0xF0, 0x38, 0x48, 0xEB, 0x0F, 0x61, 0x36, 0xE2, + 0xC1, 0x5C, 0xD4, 0x76, 0xBF, 0xF1, 0x83, 0xCA, + 0xD0, 0xA6, 0x91, 0xCE, 0xCA, 0x02, 0x7A, 0x9D, + 0x92, 0x6B, 0x83, 0x10, 0x40, 0x1A, 0xD7, 0xAC, + 0xC2, 0x6F, 0x8D, 0x87, 0x5A, 0x9E, 0x53, 0xDB, + 0x32, 0xA3, 0x91, 0x00, 0x76, 0x9C, 0xEE, 0x62, + 0x54, 0x98, 0x9F, 0xF5, 0x68, 0x35, 0x8B, 0xB7, + 0x20, 0x2D, 0x24, 0x9E, 0x4E, 0x4A, 0xC9, 0x08, + 0x70, 0x97, 0x84, 0x7B, 0xCD, 0xFC, 0xF4, 0xF5, + 0x76, 0x4F, 0xDA, 0xBC, 0xDB, 0x59, 0xCF, 0x07, + 0x3A, 0x84, 0x9B, 0x18, 0xEE, 0xAB, 0x4E, 0xD6, + 0x4A, 0x92, 0x94, 0xD2, 0xD9, 0x3E, 0x08, 0x2D, + 0xB4, 0x1E, 0xB8, 0x71, 0xE5, 0x82, 0xFD, 0x7B, + 0x67, 0x94, 0xF8, 0x15, 0x61, 0xC6, 0xFF, 0x0F, + 0xA5, 0xFF, 0x30, 0x57, 0x18, 0x6A, 0xDA, 0xEF, + 0xB8, 0x44, 0xF9, 0x53, 0x63, 0x13, 0x70, 0xB4, + 0xB5, 0x1D, 0x51, 0x29, 0xF6, 0x9F, 0x55, 0xC6, + 0x29, 0xD9, 0x1C, 0x06, 0x67, 0x4F, 0x48, 0x03, + 0xF6, 0x32, 0xEA, 0x89, 0x19, 0x1C, 0xC8, 0x6F, + 0x3A, 0x0B, 0x02, 0x60, 0x03, 0x4C, 0x9B, 0x89, + 0xDB, 0x96, 0x6A, 0x16, 0x18, 0x67, 0xEF, 0x8D, + 0x1C, 0xE7, 0xDC, 0xC8, 0xDE, 0xA6, 0x3D, 0xDF, + 0xF7, 0xB4, 0x06, 0x4E, 0xA0, 0x0A, 0xA6, 0xD9, + 0x7F, 0xFA, 0x5C, 0xF3, 0x2E, 0x2E, 0x21, 0x40, + 0x6A, 0xA9, 0x50, 0x9D, 0xB1, 0xF4, 0x4F, 0xA0, + 0x03, 0xFF, 0x08, 0xA6, 0xA2, 0x39, 0xDE, 0x23, + 0x6B, 0x53, 0xB4, 0x08, 0x51, 0x31, 0xE8, 0xA5, + 0xAD, 0xBD, 0x97, 0xB6, 0x7F, 0xCF, 0x07, 0x65, + 0x3F, 0x88, 0xFD, 0x51, 0xD6, 0xCF, 0x34, 0x22, + 0x01, 0xCA, 0x8B, 0xE7, 0x07, 0xD3, 0x1D, 0xC7, + 0xB1, 0xF9, 0xF5, 0xB5, 0x73, 0xEE, 0x04, 0x15, + 0x6D, 0xDC, 0xC3, 0x64, 0xEF, 0xD0, 0x29, 0x37, + 0xB6, 0xDE, 0xBE, 0x13, 0xAE, 0x62, 0x3C, 0x7C, + 0xCB, 0xAC, 0x13, 0xF0, 0x41, 0x61, 0xC5, 0x48, + 0x9E, 0xFC, 0x5A, 0x4F, 0x8E, 0x00, 0xF1, 0xB0, + 0xEE, 0x59, 0x01, 0x83, 0x21, 0x79, 0xD9, 0x94, + 0x01, 0xBB, 0x77, 0x29, 0x0D, 0x6B, 0x42, 0x6C, + 0xA7, 0x59, 0x48, 0x0C, 0x4B, 0xEB, 0xD2, 0x3C, + 0xF9, 0x00, 0x47, 0x5F, 0x34, 0xFE, 0x0E, 0x06, + 0x99, 0x25, 0xED, 0xCB, 0x19, 0x40, 0x76, 0xA4, + 0xAA, 0xEF, 0x64, 0x09, 0xC2, 0x08, 0x20, 0xBC, + 0x67, 0xC6, 0xAD, 0x62, 0x54, 0xC2, 0x0E, 0x32, + 0xC9, 0xB0, 0x95, 0x83, 0xCD, 0xF9, 0xA9, 0x17, + 0x9E, 0xE2, 0xDD, 0x02, 0xB4, 0x3C, 0xD6, 0x9F, + 0x2E, 0xC2, 0x35, 0x93, 0xA1, 0xB1, 0xA9, 0x58, + 0x44, 0x0C, 0x58, 0x2D, 0x90, 0xA6, 0xD2, 0x41, + 0x4D, 0xFC, 0xC8, 0x48, 0xEF, 0x4E, 0x82, 0x4E, + 0x4D, 0xFF, 0x28, 0x09, 0xF7, 0xD5, 0xCE, 0x8E, + 0x5B, 0x4C, 0xBB, 0x48, 0xCB, 0xF4, 0x58, 0x11, + 0x35, 0x8F, 0x5D, 0x9E, 0xCF, 0x2F, 0xFD, 0x73, + 0xC4, 0xA2, 0x9E, 0xAD, 0xF7, 0xDE, 0x41, 0xAB, + 0xC2, 0x35, 0xFD, 0x37, 0x36, 0x51, 0x27, 0xE2, + 0x8D, 0xC2, 0xE1, 0xE1, 0x5F, 0x61, 0xB1, 0xF3, + 0xA7, 0x56, 0xD1, 0x0B, 0x7C, 0xA5, 0xCE, 0xA7, + 0xE7, 0x6B, 0x5A, 0xF8, 0x40, 0xA2, 0x03, 0xCF, + 0xD3, 0x07, 0x62, 0x2D, 0xC8, 0x22, 0x3F, 0x28, + 0x6D, 0xD5, 0x81, 0x6B, 0x08, 0x79, 0x2B, 0x0C, + 0x96, 0x7E, 0x5C, 0x0E, 0xA0, 0xDB, 0xAA, 0x9D, + 0xD3, 0xAD, 0xDB, 0xB0, 0xE5, 0x07, 0x9C, 0x92, + 0xA4, 0x52, 0xE1, 0x1F, 0x76, 0xAD, 0x44, 0xD4, + 0x9F, 0xDB, 0xD9, 0x6A, 0x2D, 0x06, 0x92, 0x50, + 0x71, 0xD2, 0xE4, 0x9B, 0xCA, 0xC9, 0x28, 0x48, + 0x76, 0x98, 0x75, 0x9E, 0x6D, 0xB2, 0x5A, 0xDF, + 0x13, 0x65, 0x89, 0x14, 0xFE, 0x08, 0x3E, 0x0D, + 0xFF, 0x99, 0x90, 0x1E, 0x71, 0xCB, 0x3D, 0x4B, + 0x4A, 0xAA, 0x31, 0x33, 0xD1, 0x4C, 0x87, 0x7E, + 0x0E, 0xAA, 0x89, 0x28, 0x4C, 0x83, 0x49, 0x31, + 0xBB, 0x67, 0x78, 0x9B, 0x02, 0x7C, 0x42, 0x45, + 0x70, 0x4B, 0xD2, 0x02, 0xAB, 0x30, 0x5C, 0x9F, + 0xB8, 0x87, 0xEC, 0xFE, 0x98, 0xC2, 0x5F, 0x3A, + 0xF2, 0x6D, 0xBF, 0x50, 0xBC, 0x51, 0x4B, 0x09, + 0x2B, 0x98, 0x86, 0xC1, 0x1A, 0x9B, 0xD3, 0x66, + 0x49, 0x48, 0xDC, 0x65, 0x69, 0xD3, 0xB0, 0x2C, + 0x43, 0xB1, 0xE2, 0xF2, 0x27, 0xAE, 0xD2, 0xAD, + 0xF5, 0xA0, 0xFC, 0x86, 0x83, 0xF8, 0xB8, 0xBA, + 0x50, 0x0C, 0x29, 0x09, 0x3B, 0xF2, 0xF5, 0x3C, + 0x72, 0x26, 0x81, 0x6B, 0xB2, 0xBA, 0xC3, 0x80, + 0xA3, 0xD5, 0x20, 0x99, 0x8A, 0xBB, 0xAC, 0xB8, + 0xDA, 0xA7, 0x30, 0xA4, 0xCE, 0x2D, 0xBB, 0xDC, + 0xF9, 0xF3, 0xD4, 0xB5, 0xC7, 0xEA, 0xC0, 0x3F, + 0xE4, 0x0D, 0x8B, 0xF8, 0x3A, 0xCF, 0x84, 0x11, + 0x3D, 0xBC, 0x4C, 0x0F, 0x30, 0x5D, 0xE1, 0x4C, + 0x91, 0x0F, 0xF1, 0x23, 0xDA, 0x5A, 0xDC, 0x0A, + 0x9F, 0x88, 0xFC, 0x8B, 0x85, 0x7E, 0x95, 0x36, + 0x7D, 0x82, 0x0F, 0xE2, 0x2A, 0x71, 0xB1, 0x50, + 0xA6, 0xF9, 0xAB, 0xF6, 0x0B, 0x30, 0xDA, 0x8E, + 0x6F, 0xF3, 0xDD, 0xC3, 0x30, 0xAF, 0xFB, 0x08, + 0x83, 0xC7, 0x16, 0x99, 0x00, 0x4F, 0x99, 0x01, + 0x2B, 0x8A, 0x9F, 0x40, 0x2B, 0xC4, 0x91, 0x10, + 0x65, 0x68, 0x8C, 0x7E, 0xFA, 0x45, 0xC6, 0x96, + 0x75, 0xC5, 0x4D, 0x34, 0x92, 0xA2, 0x49, 0x01, + 0xC4, 0x07, 0x4F, 0x6E, 0xCA, 0x85, 0xD5, 0xEE, + 0x5A, 0xF2, 0x2F, 0x98, 0x53, 0x69, 0x95, 0xB3, + 0xD2, 0xC6, 0x1C, 0x28, 0x88, 0x43, 0xC5, 0xF1, + 0x77, 0x1A, 0x80, 0x46, 0xE8, 0xEA, 0x7E, 0x53, + 0xB8, 0xC0, 0x02, 0x24, 0xF0, 0x28, 0xC6, 0xDB, + 0x4F, 0xF5, 0x01, 0x0F, 0xF2, 0x40, 0xFB, 0x38, + 0x28, 0xDA, 0xD3, 0x79, 0x5C, 0xA5, 0x98, 0x76, + 0x7B, 0x1D, 0xF3, 0xE4, 0x17, 0x62, 0xAD, 0x30, + 0xC8, 0x8B, 0xDD, 0xE8, 0xB5, 0xDE, 0x22, 0xF2, + 0xE4, 0x98, 0x6C, 0xCC, 0x07, 0x89, 0x83, 0x4E, + 0xD7, 0xB6, 0xF2, 0x6A, 0x19, 0xD5, 0x2B, 0xC5, + 0x9C, 0x28, 0xC5, 0x71, 0x4F, 0x6D, 0xCB, 0xD9, + 0x96, 0x98, 0xF5, 0x0D, 0xA1, 0x96, 0x92, 0x5F, + 0x2F, 0xCE, 0x88, 0xAF, 0xB7, 0x41, 0x7E, 0x00, + 0x56, 0x01, 0x53, 0x7C, 0xC8, 0x35, 0xF4, 0xA5, + 0x9F, 0xC9, 0xBA, 0x03, 0xB3, 0x69, 0x99, 0x40, + 0x94, 0x3D, 0x95, 0xE0, 0xDD, 0xA6, 0x5F, 0x7A, + 0xC7, 0x04, 0xC8, 0xBF, 0x37, 0x12, 0x07, 0x15, + 0x58, 0x00, 0x0F, 0xB4, 0x28, 0x8D, 0x48, 0x35, + 0xA6, 0x12, 0xC3, 0x88, 0xCE, 0xEA, 0x6A, 0x06, + 0xE6, 0x6E, 0x1B, 0x2D, 0x25, 0x9F, 0x28, 0x03, + 0x66, 0xDC, 0xA8, 0x6D, 0xA7, 0x20, 0x35, 0x40, + 0x58, 0x57, 0xD1, 0xB8, 0xDB, 0x5D, 0xF0, 0x67, + 0x2E, 0x30, 0xF5, 0xB2, 0x99, 0x4E, 0x91, 0x06, + 0x06, 0x26, 0xFD, 0x72, 0xCF, 0xDE, 0x67, 0x49, + 0xDB, 0x6B, 0x0D, 0x7F, 0xAF, 0x89, 0x43, 0x07, + 0x1F, 0xB6, 0x56, 0x42, 0x99, 0xDE, 0xDF, 0x56, + 0xF8, 0xED, 0xB9, 0xB3, 0xE6, 0x77, 0x91, 0x30, + 0xC2, 0x27, 0x90, 0xDE, 0x79, 0xE7, 0x00, 0x7D, + 0xE4, 0xAE, 0x2C, 0x1E, 0xB5, 0x46, 0x2C, 0x4E, + 0x79, 0x8A, 0x08, 0xD5, 0xF1, 0xF1, 0x2C, 0xAF, + 0xA9, 0x80, 0x91, 0x91, 0x79, 0xAE, 0x25, 0x87, + 0xC2, 0xFF, 0x18, 0x86, 0x3E, 0x1D, 0x1D, 0xA2, + 0x75, 0x41, 0xED, 0xEF, 0xE6, 0x4A, 0x26, 0xFE, + 0xD4, 0x75, 0xE5, 0x82, 0x90, 0x58, 0x6E, 0x7F, + 0x0C, 0x1D, 0xB5, 0xB5, 0xF2, 0x3B, 0x19, 0x6E, + 0x07, 0xF8, 0x0C, 0xF0, 0x0C, 0x08, 0x9D, 0x51, + 0x9A, 0x77, 0xE7, 0x98, 0x4E, 0xB7, 0x50, 0x69, + 0xCA, 0x8B, 0x8D, 0xCD, 0xC2, 0xFC, 0xD9, 0xB2, + 0xA0, 0x34, 0x75, 0xB3, 0x60, 0xB3, 0xB0, 0x2C, + 0x11, 0xA6, 0x15, 0xB6, 0x0E, 0x4D, 0x8F, 0x41, + 0x94, 0x0A, 0x7D, 0xC2, 0x74, 0x1F, 0xA3, 0x58, + 0xFA, 0x1D, 0x26, 0x55, 0x85, 0x62, 0xFD, 0x93, + 0x60, 0x60, 0x32, 0x15, 0x75, 0xCC, 0x33, 0x4E, + 0x21, 0x35, 0x4B, 0x8C, 0x30, 0x13, 0xE7, 0x24, + 0xEF, 0xEB, 0x2B, 0x14, 0x48, 0x72, 0x7D, 0x83, + 0x8C, 0x70, 0x99, 0x71, 0x0B, 0x1F, 0x34, 0xF2, + 0xEF, 0x96, 0xEF, 0xFD, 0x8D, 0xB8, 0x0E, 0x35, + 0x55, 0x5C, 0x38, 0x5B, 0x72, 0xDD, 0x0A, 0xE2, + 0x62, 0x93, 0x0B, 0x61, 0x5E, 0x71, 0x9A, 0x90, + 0x3F, 0x2E, 0x53, 0x2E, 0xB7, 0xDC, 0xA0, 0xD1, + 0xE6, 0xCD, 0x18, 0x14, 0x08, 0x5F, 0x7A, 0x98, + 0x77, 0xF9, 0x36, 0xBE, 0xB0, 0xF7, 0x39, 0x42, + 0xCB, 0xC4, 0x44, 0xEB, 0xFB, 0x49, 0xF1, 0xE0, + 0x43, 0xF9, 0x35, 0x09, 0x68, 0x7D, 0x2C, 0x87, + 0x3D, 0x09, 0xBF, 0x80, 0x26, 0x11, 0x2A, 0xB7, + 0x6E, 0x58, 0x44, 0xA9, 0x5F, 0xEB, 0x42, 0xC5, + 0xF2, 0x09, 0xE0, 0x2F, 0xC5, 0x1E, 0xA5, 0x74, + 0xF1, 0xE4, 0xBD, 0x14, 0xBC, 0x05, 0x93, 0x74, + 0xA2, 0x74, 0x35, 0x3A, 0x4A, 0x76, 0x54, 0xE5, + 0x9D, 0xF0, 0x27, 0x18, 0x0C, 0x7B, 0xF8, 0x90, + 0xB0, 0x86, 0x30, 0x12, 0x9D, 0xE2, 0xF7, 0xA7, + 0x07, 0xB1, 0xFF, 0x1B, 0x5C, 0xBD, 0xA7, 0xDB, + 0x6D, 0xE7, 0xDF, 0x3B, 0xD9, 0xFA, 0xB1, 0x5D, + 0xBB, 0x0F, 0x85, 0xB2, 0x47, 0x10, 0x48, 0xE8, + 0x3A, 0xF8, 0xFA, 0x56, 0xD9, 0x2D, 0x4A, 0xCA, + 0x40, 0xF4, 0xE4, 0x78, 0x36, 0x41, 0xD5, 0x23, + 0x6F, 0x9D, 0x4F, 0xDB, 0x3C, 0x09, 0x3E, 0x5F, + 0x5D, 0x81, 0xCA, 0x5E, 0xA3, 0x0A, 0x4C, 0x86, + 0xD3, 0x2F, 0x22, 0x12, 0x0A, 0x2D, 0x39, 0xD9, + 0xAA, 0x10, 0xB5, 0x57, 0x84, 0x18, 0x9D, 0x2E, + 0x2A, 0xA6, 0x98, 0xB4, 0x61, 0xFE, 0x92, 0xEB, + 0x3F, 0xB3, 0x1B, 0x78, 0xAC, 0x6E, 0xB9, 0xF4, + 0xA2, 0xD1, 0xB2, 0x29, 0x53, 0x73, 0xF1, 0x3C, + 0x3E, 0x84, 0x05, 0x11, 0xCD, 0x4E, 0x85, 0x6D, + 0xF2, 0x90, 0xA6, 0xBB, 0x18, 0x32, 0x20, 0xA4, + 0x4D, 0xA8, 0x3D, 0x11, 0x8B, 0xCA, 0x5C, 0xEB, + 0x5B, 0xF2, 0xC8, 0x2E, 0xA3, 0xD4, 0x34, 0x89, + 0xF4, 0xB0, 0x2B, 0xBC, 0x0C, 0x5F, 0x16, 0xAA, + 0x38, 0x88, 0x90, 0xCD, 0xEE, 0x69, 0xC2, 0x1F, + 0x35, 0x28, 0x85, 0xB9, 0x15, 0x0A, 0x18, 0xE6, + 0x84, 0x72, 0xD1, 0x5B, 0x65, 0xAE, 0x7E, 0x11, + 0x16, 0xCD, 0x89, 0x13, 0xA5, 0x6D, 0x81, 0xF5, + 0x54, 0xC8, 0x6B, 0xDC, 0x8E, 0x2F, 0x73, 0x54, + 0x52, 0x62, 0x34, 0x30, 0x34, 0xA3, 0x41, 0x91, + 0x5D, 0x1E, 0x57, 0xA2, 0xAD, 0x4C, 0x1D, 0xC2, + 0x01, 0x0D, 0x60, 0xC3, 0x6B, 0x27, 0xFC, 0x06, + 0x02, 0xAB, 0x6E, 0x6E, 0x42, 0x6E, 0x2C, 0x91, + 0x4E, 0xDA, 0x59, 0xBE, 0x7E, 0xA3, 0x15, 0x5E, + 0xBE, 0xB8, 0x6A, 0xE9, 0x26, 0x09, 0xD2, 0xFB, + 0x77, 0xE8, 0x41, 0x19, 0xB4, 0x7E, 0x53, 0x29, + 0x8D, 0xA5, 0xDC, 0x84, 0xD9, 0x10, 0xAA, 0xF4, + 0x99, 0x0D, 0xDA, 0x73, 0x0A, 0x14, 0x4B, 0xB1, + 0x53, 0x80, 0x86, 0x2C, 0x10, 0x54, 0x61, 0x33, + 0xD4, 0x26, 0xFB, 0xE1, 0xA5, 0xF5, 0x38, 0xEC, + 0x1B, 0xEF, 0x95, 0x8E, 0x88, 0xA7, 0x16, 0xDC, + 0x22, 0xAF, 0xBC, 0x39, 0x41, 0x19, 0xAA, 0xFC, + 0xE3, 0xE4, 0xC8, 0x90, 0xF0, 0xD0, 0x35, 0x8F, + 0x3A, 0xF6, 0x00, 0xDB, 0x50, 0x23, 0x80, 0xAF, + 0x7A, 0x3D, 0x55, 0x45, 0x7A, 0x32, 0x53, 0x4F, + 0xF6, 0x86, 0x28, 0x2D, 0xE4, 0x9C, 0x7B, 0xA1, + 0x4F, 0x68, 0xBF, 0xD6, 0xD8, 0x97, 0xCB, 0xF9, + 0x15, 0xE4, 0x88, 0x35, 0xD1, 0x3D, 0xE4, 0x9A, + 0xA4, 0x47, 0xEB, 0x44, 0x4C, 0x92, 0x22, 0x6F, + 0x2D, 0xBE, 0x4B, 0xFE, 0x96, 0xE2, 0x2D, 0x5A, + 0x03, 0xCB, 0x6E, 0x91, 0xBE, 0x73, 0x14, 0xEF, + 0x8B, 0xAC, 0x65, 0x09, 0xDA, 0x68, 0xA9, 0xE3, + 0x08, 0xB1, 0x17, 0x9A, 0xAB, 0x88, 0x1F, 0x7B, + 0x48, 0xAF, 0xB0, 0xBA, 0x2B, 0x92, 0x42, 0x1D, + 0x92, 0x26, 0x17, 0xEE, 0x58, 0x3E, 0x36, 0xAF, + 0xB7, 0x5C, 0x75, 0x79, 0x77, 0xB3, 0xB0, 0x96, + 0x87, 0x46, 0x80, 0x95, 0x91, 0x7A, 0x22, 0xC4, + 0x5E, 0xBB, 0xEA, 0xDD, 0xD6, 0x11, 0x1E, 0xAB, + 0x1F, 0x09, 0x7D, 0x9D, 0x2F, 0x2D, 0xD4, 0x4E, + 0x3C, 0x33, 0x5D, 0x6F, 0xD3, 0x54, 0xD1, 0xD0, + 0x4F, 0x2A, 0x12, 0x07, 0x2D, 0x19, 0x72, 0x39, + 0xEF, 0xC5, 0xA5, 0xC9, 0xDA, 0xC6, 0x71, 0xED, + 0xBC, 0x1B, 0x85, 0x88, 0x11, 0x2A, 0x02, 0xA7, + 0xFD, 0x3C, 0xF7, 0x31, 0x4D, 0x57, 0xEE, 0x56, + 0xF0, 0xBC, 0xF1, 0x90, 0x88, 0xFA, 0xC8, 0xC0, + 0xF5, 0x41, 0x39, 0x5B, 0x92, 0x1E, 0xE9, 0x94, + 0x79, 0x29, 0x58, 0xE2, 0x04, 0xB5, 0x9C, 0xEE, + 0x68, 0x2F, 0x5C, 0x91, 0xFA, 0xF6, 0x09, 0xCE, + 0x10, 0xFB, 0xBD, 0x4A, 0xCA, 0x8B, 0x51, 0xFC, + 0x1F, 0xC7, 0x16, 0xA3, 0x49, 0x1A, 0x70, 0xCC, + 0x38, 0xE6, 0x9C, 0xCA, 0x21, 0x2B, 0x13, 0xBA, + 0x51, 0x94, 0xCB, 0x25, 0x45, 0x55, 0x12, 0x2F, + 0xA5, 0xF7, 0xAB, 0x1A, 0x75, 0xD2, 0xAC, 0x03, + 0xAD, 0xFF, 0x9D, 0x79, 0x87, 0x83, 0xBA, 0xA6, + 0x80, 0x32, 0x7A, 0x32, 0x3B, 0x26, 0xF5, 0xCF, + 0xDF, 0xEC, 0xBE, 0x07, 0x89, 0x3F, 0x87, 0x38, + 0x77, 0x93, 0xA8, 0xD4, 0x6B, 0x5B, 0x73, 0x42, + 0x45, 0xD8, 0x71, 0x2D, 0x86, 0x33, 0x6F, 0xCD, + 0x6E, 0xE4, 0x3E, 0x08, 0xE1, 0x02, 0xE3, 0x2E, + 0x2D, 0xF8, 0x03, 0x8C, 0x80, 0x23, 0x0B, 0x95, + 0x50, 0xE3, 0x07, 0xDB, 0x84, 0xB6, 0xA6, 0x4F, + 0xDB, 0xAF, 0x77, 0x8D, 0xD6, 0xEE, 0x2C, 0x52, + 0x31, 0x8F, 0xF6, 0xDF, 0xB4, 0x92, 0x9F, 0x29, + 0x2E, 0x2B, 0x7D, 0x57, 0xE9, 0x8A, 0xB3, 0x00, + 0xB4, 0xC9, 0x73, 0x96, 0x61, 0x99, 0x99, 0x62, + 0xC7, 0x8B, 0x8E, 0x90, 0xB7, 0x08, 0xA4, 0x9C, + 0x62, 0xA4, 0x54, 0x3D, 0xD1, 0x97, 0x3B, 0x82, + 0xEB, 0xAC, 0x3E, 0xA1, 0x55, 0xF9, 0x29, 0x39, + 0xCB, 0x4C, 0xC9, 0x3C, 0x1E, 0xCE, 0x9A, 0x6D, + 0x1E, 0x8B, 0xA0, 0x4F, 0x6A, 0xF2, 0xE7, 0xC0, + 0x96, 0x6F, 0x05, 0x44, 0xA7, 0xB0, 0x49, 0x4D, + 0x8C, 0xB1, 0xD3, 0x0D, 0x23, 0xC1, 0xB6, 0x90, + 0xA6, 0x59, 0x44, 0xDD, 0x50, 0xAC, 0x08, 0xF0, + 0x7A, 0x63, 0xD4, 0xA6, 0xC4, 0xE7, 0x38, 0xA1, + 0x34, 0x51, 0xCA, 0x6C, 0xBE, 0xF5, 0x44, 0xD2, + 0x37, 0xF1, 0xA3, 0xEE, 0xAA, 0x69, 0xCA, 0xDE, + 0x06, 0xCE, 0x9C, 0xFA, 0x24, 0x63, 0xE7, 0xF9, + 0xCB, 0xD3, 0xF8, 0x0D, 0x97, 0x5F, 0xFA, 0xAF, + 0xBF, 0x21, 0x26, 0x5D, 0x4D, 0xBD, 0xA7, 0x61, + 0xED, 0x13, 0xC7, 0x20, 0xD6, 0xB5, 0x58, 0x49, + 0x2B, 0x7C, 0xA2, 0x1B, 0x36, 0x91, 0x00, 0xF0, + 0x9C, 0x32, 0xD8, 0xB7, 0xF1, 0x5F, 0x40, 0x46, + 0x89, 0xE4, 0xE6, 0x1A, 0x84, 0x1B, 0x9A, 0xB4, + 0xA9, 0xE8, 0x6B, 0x02, 0x91, 0xB3, 0xCB, 0x48, + 0xB1, 0x65, 0x0F, 0x43, 0x37, 0x71, 0x0F, 0x14, + 0xC0, 0x46, 0x8A, 0xA7, 0x03, 0x6F, 0xD4, 0x5B, + 0xE8, 0x1F, 0xC1, 0xB1, 0x14, 0x30, 0x01, 0x3E, + 0x61, 0x78, 0xCA, 0xE2, 0x0A, 0x01, 0xAE, 0x56, + 0xFF, 0xE3, 0xD3, 0x10, 0x70, 0x9B, 0x52, 0xD1, + 0x82, 0x2F, 0x11, 0xF3, 0x47, 0xFA, 0x1E, 0x3B, + 0xD7, 0xF9, 0x93, 0xE1, 0x9A, 0x74, 0x4B, 0x4E, + 0x79, 0x3E, 0xC4, 0x08, 0x1A, 0xB6, 0x04, 0x04, + 0x6A, 0x39, 0x89, 0x4A, 0xAB, 0x96, 0xE9, 0xDF, + 0xEB, 0x6D, 0xA1, 0x65, 0xF3, 0x3E, 0xDC, 0xB9, + 0x89, 0xEA, 0x83, 0x5C, 0xA3, 0x1B, 0xF0, 0x59, + 0x0C, 0xFE, 0x5B, 0xB3, 0xCC, 0x58, 0x8F, 0xC4, + 0x2F, 0xD7, 0x11, 0x04, 0x53, 0x23, 0xFA, 0x47, + 0xAB, 0xA0, 0xA9, 0x5A, 0x00, 0x9B, 0x25, 0x0C, + 0x68, 0x8F, 0x4D, 0x51, 0x1A, 0xCA, 0x77, 0xC9, + 0xB5, 0xB1, 0x35, 0xE1, 0x18, 0x09, 0x4C, 0x64, + 0x82, 0xE5, 0xF9, 0xDF, 0x9C, 0x09, 0x64, 0x31, + 0xC7, 0xAB, 0xB0, 0xEB, 0x79, 0x32, 0xB7, 0xAC, + 0x02, 0xD8, 0xF6, 0x0D, 0x95, 0x3F, 0x4E, 0x2D, + 0x4A, 0x17, 0x06, 0xC8, 0x62, 0x8C, 0x2C, 0xF7, + 0xB4, 0xE6, 0xAF, 0x99, 0x55, 0x4F, 0x8B, 0x06, + 0x99, 0xD6, 0x9A, 0xA3, 0x76, 0x13, 0x94, 0xF8, + 0xA2, 0x7F, 0xD4, 0x00, 0x2B, 0xB1, 0xF2, 0x49, + 0xF2, 0x85, 0xD5, 0xE4, 0xBF, 0x17, 0xA7, 0x37, + 0x13, 0x9E, 0x5A, 0xE6, 0xCE, 0x4A, 0xC1, 0x09, + 0x14, 0x7D, 0xB3, 0xF8, 0x24, 0x03, 0x5C, 0x63, + 0x57, 0x03, 0xCC, 0x2E, 0xF6, 0xB4, 0xB6, 0x69, + 0xA1, 0xD8, 0xB8, 0x17, 0xF2, 0x11, 0x4B, 0x26, + 0x42, 0x26, 0xFB, 0xBB, 0x31, 0x78, 0xDB, 0x4C, + 0x9E, 0xD1, 0xE9, 0x91, 0xBB, 0x62, 0x4F, 0x11, + 0xBB, 0xDD, 0x7F, 0x77, 0xD4, 0x83, 0x15, 0x89, + 0x4D, 0xC9, 0x5C, 0xD3, 0xD1, 0x82, 0x86, 0x75, + 0x8A, 0x59, 0xE7, 0x09, 0x0E, 0xC5, 0xEF, 0xAA, + 0x01, 0x2A, 0x29, 0x70, 0xE2, 0x15, 0x46, 0xAA, + 0xA2, 0xD5, 0x3E, 0x9F, 0x02, 0x28, 0x7E, 0x35, + 0x15, 0x71, 0x52, 0x93, 0xD5, 0xA3, 0x97, 0x44, + 0x47, 0x3B, 0x7E, 0xC8, 0x36, 0x70, 0x20, 0xC1, + 0xB0, 0x43, 0x93, 0x26, 0xBD, 0xCF, 0x68, 0x52, + 0x50, 0x05, 0x71, 0xEF, 0x65, 0x34, 0x88, 0x2E, + 0x84, 0x58, 0x31, 0x46, 0x4A, 0xF3, 0xF9, 0xE3, + 0x16, 0x09, 0x77, 0x50, 0x3B, 0xE1, 0xCF, 0x46, + 0xC5, 0x3B, 0xBF, 0xAF, 0x82, 0x58, 0x69, 0x89, + 0x42, 0x0B, 0x30, 0x87, 0x90, 0xAA, 0xBD, 0x9E, + 0x7F, 0x9B, 0x12, 0xB0, 0xD9, 0xBC, 0xB4, 0xAF, + 0x47, 0x1A, 0xB7, 0x39, 0x1B, 0xBE, 0xC3, 0x46, + 0x7B, 0x40, 0x97, 0xDE, 0xA2, 0x35, 0xAE, 0x7E, + 0x75, 0x9E, 0x06, 0xBF, 0x17, 0x00, 0x0A, 0x8F, + 0x64, 0x69, 0x40, 0x02, 0xEB, 0x62, 0xB4, 0xC1, + 0x4C, 0x20, 0xB6, 0x0A, 0x56, 0x7E, 0x4F, 0xB7, + 0x15, 0xB1, 0x5F, 0xCE, 0x20, 0xEB, 0x3C, 0xEA, + 0x60, 0xCC, 0xF1, 0x54, 0x99, 0x2C, 0xE5, 0x8C, + 0x08, 0xB4, 0xFB, 0x40, 0xF6, 0xB6, 0x7B, 0xE0, + 0xD6, 0x22, 0x38, 0xBF, 0x2D, 0xA6, 0x1E, 0xA3, + 0xE1, 0x6A, 0x07, 0xAC, 0xD6, 0xB0, 0x46, 0xA6, + 0xF7, 0x1C, 0x64, 0x2E, 0x52, 0xCC, 0x5C, 0x75, + 0x71, 0x06, 0x3F, 0x70, 0x84, 0x52, 0x07, 0x91, + 0xBA, 0x8E, 0x9D, 0x38, 0x10, 0x79, 0xA1, 0xB0, + 0xE8, 0x50, 0x5F, 0x5B, 0xA3, 0x83, 0xAF, 0x5C, + 0xAD, 0x48, 0xB8, 0x7A, 0x61, 0xBE, 0x08, 0x7D, + 0xA0, 0xC1, 0x30, 0x16, 0x27, 0x48, 0xC3, 0x0F, + 0x99, 0x69, 0x64, 0x70, 0xB7, 0x0B, 0xA0, 0xE2, + 0xA6, 0xD6, 0xA1, 0xBE, 0x83, 0xC8, 0xC7, 0xC9, + 0x34, 0xE1, 0x73, 0x48, 0x40, 0x5A, 0x4F, 0xB5, + 0xCE, 0x44, 0x0B, 0xA4, 0x5E, 0xE0, 0xC9, 0x19, + 0x30, 0x49, 0x19, 0x24, 0x6B, 0xC9, 0xC6, 0x5C, + 0x2A, 0x6C, 0x04, 0x08, 0x68, 0x05, 0xBC, 0x40, + 0x4C, 0x76, 0x05, 0x5F, 0xE0, 0xED, 0x64, 0x6D, + 0x19, 0xE7, 0x26, 0x2D, 0x11, 0x05, 0x1E, 0x34, + 0xA8, 0xD4, 0x32, 0x9C, 0xBD, 0xDD, 0xD7, 0x40, + 0xC1, 0xFC, 0x63, 0x3C, 0x4C, 0x55, 0xB9, 0x35, + 0x7E, 0xCB, 0x55, 0xB1, 0x9D, 0x8F, 0x17, 0x1C, + 0x47, 0xFA, 0xE7, 0x75, 0xD9, 0x61, 0x8C, 0x09, + 0x50, 0xD8, 0x04, 0x15, 0x28, 0x10, 0xBB, 0x93, + 0x2D, 0x94, 0xFA, 0xE4, 0x24, 0xA0, 0xD0, 0x2F, + 0x30, 0x0B, 0x60, 0x27, 0x46, 0x88, 0x4B, 0x1A, + 0x94, 0xA8, 0x62, 0x59, 0x1A, 0x8F, 0xDF, 0x47, + 0xF4, 0x05, 0xF7, 0xFF, 0x04, 0x66, 0x36, 0x1D, + 0xD0, 0x99, 0x33, 0xEC, 0xB4, 0xAE, 0x67, 0x5C, + 0x88, 0x2C, 0xCD, 0x3A, 0x7A, 0xB7, 0x66, 0x7B, + 0x29, 0x51, 0x1E, 0x3C, 0x60, 0xF3, 0x2A, 0x03, + 0xF0, 0x81, 0x69, 0xD2, 0xA5, 0x24, 0x47, 0xEF, + 0x25, 0x7D, 0x61, 0xF9, 0xD1, 0xAD, 0xB3, 0xAE, + 0x82, 0x7E, 0x03, 0x25, 0xB4, 0x3F, 0x23, 0x7F, + 0x1E, 0x3F, 0xA2, 0xAB, 0x09, 0xC0, 0xFB, 0x42, + 0x73, 0x92, 0x8C, 0x36, 0x84, 0x4E, 0x7E, 0xFE, + 0x5C, 0x0B, 0x14, 0x47, 0x7A, 0x06, 0xF9, 0x0C, + 0x08, 0x88, 0x22, 0x82, 0xB9, 0xE4, 0xD2, 0x92, + 0x1E, 0x13, 0xAF, 0xD3, 0x39, 0xDE, 0x13, 0xF7, + 0x8C, 0xF6, 0xCB, 0xA0, 0xE6, 0xD3, 0xD0, 0xF9, + 0x64, 0xEA, 0x0F, 0xB0, 0x0F, 0xA7, 0x16, 0x4D, + 0xA5, 0x3B, 0x37, 0x5D, 0x13, 0x86, 0xA1, 0x60, + 0x2C, 0x9C, 0xE6, 0x72, 0xC3, 0xB0, 0xD4, 0x77, + 0xF4, 0xE6, 0xAF, 0x56, 0x4E, 0x56, 0x96, 0x85, + 0x47, 0xE5, 0x38, 0xD3, 0xCA, 0x01, 0x93, 0xDA, + 0x2F, 0x79, 0xE0, 0x10, 0x60, 0x86, 0x9D, 0xB4, + 0xF6, 0x45, 0x2D, 0xDE, 0xAB, 0x48, 0x35, 0x47, + 0xA7, 0x8E, 0xE2, 0x41, 0x33, 0xC7, 0x02, 0x09, + 0x9C, 0xDB, 0xE8, 0xBB, 0x89, 0xD3, 0xC9, 0x0D, + 0x90, 0x93, 0x4B, 0xB0, 0xA5, 0xC3, 0xFA, 0x4A, + 0x94, 0xCB, 0x65, 0x48, 0x26, 0x7B, 0xDE, 0x82, + 0xB2, 0x02, 0xA6, 0xB9, 0x34, 0x8E, 0xD4, 0x12, + 0x8A, 0xB4, 0xCA, 0x55, 0xEF, 0x96, 0xCE, 0xB5, + 0x5C, 0x62, 0x55, 0xC0, 0xD6, 0xEF, 0xDB, 0x63, + 0x08, 0xA0, 0x12, 0x69, 0xAF, 0x35, 0xAD, 0x44, + 0xA2, 0x75, 0x26, 0x56, 0x5A, 0xBB, 0xE3, 0x69, + 0x5D, 0x6B, 0x7C, 0xA7, 0x66, 0x14, 0x0A, 0x54, + 0x1C, 0x3C, 0x36, 0xBC, 0xE8, 0x43, 0x3E, 0x5F, + 0x59, 0x6C, 0xBC, 0x87, 0x93, 0xB9, 0xAE, 0x85, + 0x0E, 0x95, 0xDC, 0x0A, 0x66, 0x63, 0x09, 0x64, + 0xC2, 0xDA, 0x2B, 0x80, 0xE6, 0x86, 0xA5, 0x85, + 0x06, 0x2A, 0x31, 0x03, 0x15, 0x13, 0xFE, 0x95, + 0x34, 0x86, 0xAF, 0xBF, 0x68, 0x5A, 0x17, 0xB9, + 0xB5, 0x97, 0x9B, 0x27, 0x80, 0x2F, 0x6B, 0x31, + 0xB8, 0xC8, 0xA6, 0x9B, 0x3C, 0x62, 0x28, 0xC8, + 0x0D, 0x33, 0xE1, 0xE6, 0x4E, 0x18, 0x1B, 0xDD, + 0x3B, 0x33, 0x39, 0x93, 0xAB, 0xB0, 0x4A, 0x43, + 0x27, 0xFB, 0x05, 0x9F, 0xC3, 0x51, 0xD7, 0xBE, + 0x55, 0xDE, 0x62, 0x53, 0xFC, 0x34, 0xB6, 0xC3, + 0xC2, 0x7C, 0x3C, 0xF7, 0x12, 0x33, 0x7E, 0x5D, + 0xBC, 0xAA, 0x65, 0xA0, 0xA7, 0x89, 0xD8, 0x74, + 0x1F, 0xF2, 0x82, 0x37, 0x21, 0x5C, 0x1A, 0x7B, + 0xFD, 0xCB, 0x5F, 0xCB, 0x0D, 0xBA, 0xD4, 0x1F, + 0xBD, 0x00, 0xAD, 0x77, 0x57, 0xA6, 0xC1, 0x2B, + 0x4F, 0xF6, 0x33, 0xC3, 0xF9, 0xEA, 0xD4, 0xC4, + 0x7B, 0xE4, 0x46, 0xE5, 0xE5, 0x96, 0xA6, 0x57, + 0x12, 0xD3, 0xCD, 0xB4, 0xA8, 0x2B, 0xAC, 0x11, + 0xD1, 0xE7, 0x15, 0x01, 0x21, 0xD8, 0x9A, 0xE3, + 0x6D, 0xB6, 0x86, 0x73, 0x3F, 0xC7, 0xD7, 0xFF, + 0xF3, 0x0E, 0x32, 0xE9, 0x6C, 0xE8, 0xAD, 0x1A, + 0xC1, 0xF0, 0x49, 0x3E, 0x49, 0x39, 0x5B, 0xFF, + 0x70, 0xB2, 0x41, 0xDA, 0xC5, 0xB3, 0x80, 0xF5, + 0x33, 0xBD, 0x24, 0x04, 0x68, 0xF3, 0x99, 0x22, + 0xAD, 0xFE, 0x2B, 0xAF, 0x12, 0x5E, 0xAF, 0x44, + 0x83, 0xBE, 0x12, 0xEF, 0x3D, 0x02, 0x80, 0x79, + 0xA2, 0xA7, 0x3A, 0x96, 0x27, 0x14, 0x82, 0x80, + 0x60, 0x8A, 0x56, 0x9C, 0x5A, 0xCB, 0x4F, 0x80, + 0xAA, 0xF2, 0xFA, 0x75, 0xFB, 0x1D, 0x3A, 0x4A, + 0xCC, 0xB9, 0xD7, 0x5F, 0xDF, 0xCA, 0x1C, 0x7B, + 0x42, 0xCB, 0x77, 0x6D, 0x8B, 0x68, 0x69, 0x67, + 0xF2, 0x20, 0x7A, 0xE1, 0xB3, 0xF5, 0x6E, 0x20, + 0xCC, 0xFF, 0x2C, 0x1D, 0xDC, 0x34, 0x39, 0x80, + 0xBB, 0x02, 0x44, 0x14, 0xBD, 0xA2, 0xB6, 0x46, + 0xDF, 0x44, 0x1E, 0x87, 0xEE, 0xD5, 0x9A, 0x68, + 0xCF, 0xD7, 0x5E, 0x33, 0x4D, 0x53, 0xE3, 0x71, + 0x19, 0xE5, 0xEA, 0x68, 0x31, 0x77, 0xCE, 0x94, + 0xE0, 0xF6, 0x38, 0xDF, 0xA3, 0x06, 0x46, 0xDA, + 0xDE, 0x7F, 0xCC, 0x19, 0xD7, 0xD7, 0x37, 0x16, + 0x9B, 0x81, 0x1C, 0x26, 0xF4, 0xC0, 0x61, 0xC5, + 0xBB, 0xBB, 0xDB, 0xD6, 0x20, 0xEA, 0x57, 0x22, + 0xF8, 0x8D, 0xF0, 0xD3, 0x58, 0xB9, 0x4D, 0x9B, + 0x3C, 0xB2, 0x1B, 0x3B, 0xDF, 0x89, 0x12, 0x03, + 0x27, 0x42, 0xBA, 0xC1, 0xDB, 0xBB, 0x7E, 0xA2, + 0xF4, 0x40, 0xAD, 0xDB, 0xE4, 0xE2, 0x6D, 0xE4, + 0x28, 0xFC, 0x62, 0x88, 0x4F, 0x75, 0xAF, 0x87, + 0x50, 0x2E, 0x29, 0x54, 0xE8, 0x03, 0x9A, 0x14, + 0x2D, 0xCA, 0xDE, 0xED, 0x21, 0xF6, 0xC6, 0x45, + 0xF2, 0x9C, 0x77, 0x0C, 0x5D, 0x9F, 0x29, 0x42, + 0x8B, 0x94, 0x87, 0x4A, 0x3A, 0x00, 0xD5, 0xCE, + 0xCE, 0x8D, 0x3F, 0x1C, 0x61, 0xBE, 0x3E, 0x35, + 0xBC, 0xD9, 0x18, 0xA3, 0x61, 0xC5, 0xB7, 0xC9, + 0x73, 0xCF, 0xFA, 0x8E, 0xC7, 0x08, 0x59, 0x34, + 0xF6, 0xB9, 0xE4, 0xF7, 0xDC, 0x46, 0x43, 0x4C, + 0x66, 0x0C, 0x86, 0x24, 0xC1, 0xF8, 0xB5, 0x29, + 0x7E, 0xBA, 0xBC, 0xEB, 0x43, 0x46, 0x91, 0x3D, + 0x66, 0x39, 0xCE, 0x9B, 0x83, 0xBF, 0x4F, 0x7F, + 0x19, 0x03, 0xF3, 0x78, 0x53, 0x5E, 0x0D, 0x43, + 0x2E, 0x7F, 0x2B, 0xB5, 0xE9, 0x95, 0xF9, 0x87, + 0x4C, 0x35, 0x3F, 0x17, 0x99, 0x54, 0x06, 0xD6, + 0x4A, 0xAD, 0x86, 0x83, 0x57, 0x0A, 0x4A, 0x54, + 0xA6, 0x53, 0x5D, 0xB4, 0xE4, 0x05, 0xEC, 0xCF, + 0x29, 0x34, 0x28, 0x79, 0x00, 0xC8, 0xF1, 0xF2, + 0xCF, 0xF7, 0x45, 0x24, 0xD3, 0x6D, 0xA8, 0x43, + 0xD8, 0xA0, 0x08, 0xB5, 0xB1, 0x61, 0x37, 0x94, + 0x37, 0xB5, 0xB0, 0x92, 0x8B, 0x3A, 0xFA, 0xDF, + 0x75, 0x1F, 0xEE, 0xA9, 0xF1, 0x2B, 0x72, 0x18, + 0xD2, 0x2A, 0x63, 0xA3, 0xE7, 0x20, 0x82, 0x05, + 0x9B, 0xF3, 0xEE, 0x22, 0x85, 0x3B, 0xDA, 0x25, + 0x8B, 0x4D, 0x78, 0x73, 0x55, 0xBF, 0x24, 0x2E, + 0x38, 0x13, 0x42, 0x79, 0xEA, 0xCA, 0x7D, 0x53, + 0x98, 0x6F, 0x0C, 0x06, 0x23, 0xB8, 0x88, 0xCC, + 0x92, 0x73, 0xCB, 0xA2, 0xDA, 0x1C, 0x70, 0x22, + 0x3D, 0xD3, 0x32, 0x29, 0xD0, 0x3A, 0x4E, 0x52, + 0x7A, 0x7E, 0x90, 0xA6, 0x54, 0x94, 0x30, 0x06, + 0x72, 0xB0, 0x4C, 0x44, 0x28, 0x6F, 0xA5, 0x54, + 0x1D, 0xF2, 0x07, 0xDE, 0x7E, 0xF7, 0x4E, 0x08, + 0xC6, 0x33, 0x45, 0x88, 0x2D, 0x87, 0x84, 0xE4, + 0x5F, 0xDC, 0x08, 0x43, 0x7C, 0x88, 0x3A, 0x8D, + 0x22, 0x95, 0x43, 0xC6, 0x2C, 0x59, 0x91, 0xF8, + 0xAA, 0x78, 0xB4, 0x7C, 0x19, 0x5A, 0xD9, 0xF1, + 0xE2, 0x2B, 0xDC, 0x7C, 0x96, 0x61, 0xC2, 0x24, + 0x62, 0xA3, 0xB1, 0x54, 0x47, 0x93, 0x80, 0x43, + 0xE1, 0xD3, 0xFF, 0xCA, 0x40, 0xB4, 0x1B, 0x6D, + 0xFE, 0xC6, 0x35, 0x61, 0x38, 0x3F, 0x91, 0x47, + 0xE2, 0xF4, 0xCC, 0x7D, 0x72, 0xD9, 0xEC, 0xDF, + 0x46, 0x1B, 0x94, 0x04, 0x6D, 0x5E, 0x74, 0xF7, + 0xAC, 0x62, 0x76, 0x4C, 0x31, 0xF7, 0x59, 0xCD, + 0xBF, 0xA0, 0x8C, 0x60, 0x1E, 0x07, 0xA9, 0xEF, + 0x6B, 0x43, 0x6C, 0xA2, 0x64, 0x64, 0x19, 0xAD, + 0x95, 0x1A, 0xD8, 0x34, 0xBB, 0xC2, 0xD0, 0xA5, + 0xE8, 0x54, 0x26, 0xC5, 0x7B, 0x48, 0x4E, 0x98, + 0xD3, 0xD7, 0x0C, 0xEB, 0x3C, 0x89, 0xFA, 0x57, + 0x0F, 0x4F, 0x17, 0x24, 0x62, 0xC8, 0xC1, 0xCF, + 0x05, 0xC0, 0x92, 0x97, 0x4D, 0x99, 0x56, 0x33, + 0x6B, 0xA5, 0xFB, 0x4F, 0x33, 0x8E, 0xE8, 0x42, + 0xB5, 0xB3, 0x21, 0xFD, 0xDB, 0x94, 0xC5, 0x3C, + 0x6A, 0x21, 0x5F, 0x0C, 0x74, 0xA4, 0xB5, 0x85, + 0xB2, 0x60, 0xA9, 0xD5, 0x20, 0x3E, 0x97, 0x7B, + 0x0A, 0xE1, 0xCD, 0x55, 0x98, 0x34, 0x41, 0x40, + 0x6A, 0xE6, 0x53, 0x88, 0xAF, 0x2C, 0xF3, 0x43, + 0x67, 0xD6, 0xB1, 0x22, 0xC0, 0x72, 0xB2, 0xCE, + 0x7E, 0xDC, 0xE4, 0xF6, 0x10, 0xCD, 0x95, 0x52, + 0xD1, 0x0B, 0xEC, 0xA6, 0xD8, 0x25, 0xCA, 0x4E, + 0x02, 0xAF, 0xE0, 0x32, 0x68, 0xA5, 0xBC, 0xFF, + 0xC0, 0x79, 0x33, 0xE2, 0xAF, 0x3A, 0x85, 0xF1, + 0x6C, 0x43, 0x3C, 0x5D, 0x6E, 0x8B, 0xED, 0xE3, + 0x20, 0x33, 0x37, 0x73, 0x3F, 0x5C, 0x53, 0xB0, + 0x45, 0xE2, 0x13, 0x6B, 0x96, 0x1D, 0x3D, 0x11, + 0x52, 0x28, 0x5D, 0xA2, 0x5E, 0x33, 0x9E, 0x97, + 0x4B, 0x2E, 0x76, 0x91, 0x93, 0x9D, 0x25, 0x99, + 0x94, 0x47, 0x86, 0x76, 0xF2, 0x7C, 0xC7, 0x72, + 0x08, 0x50, 0x54, 0xBB, 0xFC, 0xD7, 0xF1, 0x65, + 0xF1, 0x9A, 0x50, 0x65, 0x00, 0x00, 0xAC, 0x45, + 0x13, 0xE1, 0xDD, 0x8E, 0x53, 0x0A, 0xD9, 0x1A, + 0x91, 0xA5, 0x1B, 0xD6, 0xA5, 0x75, 0x29, 0x66, + 0x25, 0xEC, 0x16, 0x7E, 0xBC, 0x0F, 0x2A, 0xED, + 0x43, 0xFC, 0xE4, 0xEE, 0xE9, 0x31, 0xCE, 0xDF, + 0x0B, 0x46, 0x40, 0x31, 0x76, 0x24, 0x5B, 0xEB, + 0x2A, 0x83, 0x02, 0x42, 0xD4, 0x91, 0xCB, 0x82, + 0x82, 0x11, 0x7C, 0xB4, 0x27, 0x0E, 0xA0, 0x4B, + 0xB6, 0x6D, 0xFD, 0xCE, 0x0B, 0xDB, 0xF9, 0x26, + 0x89, 0xC6, 0x85, 0x77, 0x1B, 0xB9, 0xC0, 0x9F, + 0xF5, 0xB9, 0x10, 0x90, 0x8E, 0x67, 0x4E, 0x89, + 0xBB, 0x80, 0xC6, 0xA2, 0x6B, 0xA3, 0xD2, 0x5E, + 0x25, 0xB2, 0x9E, 0x56, 0x0B, 0x76, 0x1D, 0xFC, + 0x2E, 0xA2, 0x2C, 0xA2, 0xCB, 0x2B, 0x60, 0x9D, + 0xF1, 0xC3, 0x05, 0x89, 0x0B, 0x70, 0x32, 0x3C, + 0x4D, 0x5D, 0x6A, 0x93, 0x20, 0x8F, 0x6C, 0x9F, + 0x1F, 0x64, 0xAA, 0x52, 0xE0, 0x3B, 0x62, 0xF5, + 0xBD, 0xC2, 0x39, 0x62, 0x0F, 0x01, 0x86, 0xA0, + 0x37, 0x9C, 0x06, 0x31, 0x03, 0xC7, 0x0D, 0x9F, + 0x12, 0x90, 0x1B, 0xE2, 0xE8, 0x51, 0x22, 0x74, + 0x2D, 0x0E, 0x36, 0xD7, 0xD3, 0x33, 0x5D, 0xD5, + 0x0B, 0x8C, 0x42, 0xD8, 0x0D, 0x68, 0xA0, 0xB9, + 0x14, 0x84, 0xB6, 0xFA, 0xE2, 0xE6, 0x60, 0xC4, + 0x2E, 0x0F, 0xDA, 0xF5, 0xF6, 0x60, 0x01, 0xFC, + 0x0A, 0xDC, 0x1E, 0x98, 0x22, 0x27, 0xBC, 0x72, + 0xDE, 0x23, 0x95, 0x70, 0x60, 0x66, 0x6B, 0x8B, + 0xA7, 0xE7, 0x1E, 0x49, 0xE7, 0xC5, 0x7F, 0xF9, + 0x3B, 0xE6, 0xA8, 0x7D, 0x56, 0xC1, 0x13, 0x79, + 0xDA, 0x71, 0xE9, 0x01, 0x40, 0x43, 0xFA, 0xA6, + 0xF6, 0xE6, 0x4A, 0x74, 0x20, 0x01, 0xD6, 0x79, + 0x0C, 0xFC, 0xAE, 0xF5, 0xDC, 0x40, 0x06, 0xF7, + 0xC7, 0x05, 0x77, 0x23, 0xC3, 0x7B, 0x14, 0x57, + 0xFD, 0x53, 0xFC, 0x73, 0xCC, 0xBC, 0x0D, 0xE7, + 0x27, 0x0A, 0x38, 0xDF, 0xEA, 0xAB, 0x90, 0xBF, + 0xF2, 0x4D, 0x0B, 0x97, 0x98, 0xD7, 0x31, 0xAA, + 0x5E, 0x19, 0xB9, 0xFD, 0x8F, 0x49, 0x17, 0xA9, + 0x5A, 0xBA, 0xC6, 0x7A, 0x2C, 0x29, 0xC6, 0x67, + 0xCC, 0x26, 0xB9, 0x86, 0x6E, 0xB5, 0xC2, 0xAD, + 0x2A, 0xF2, 0xBD, 0x4B, 0x48, 0xC1, 0xC7, 0x34, + 0x14, 0xB8, 0x53, 0xA5, 0x40, 0x2A, 0x7C, 0xA4, + 0x2B, 0xB0, 0x9F, 0xD9, 0x7B, 0xDD, 0xDF, 0x14, + 0x0D, 0x51, 0xB2, 0x2E, 0xEC, 0xFB, 0x3C, 0x81, + 0xD8, 0xD1, 0xFD, 0x3C, 0x19, 0xC7, 0x00, 0x35, + 0xF3, 0xC2, 0x93, 0x70, 0xA0, 0x8B, 0x24, 0x2B, + 0xD7, 0x95, 0x04, 0x03, 0x44, 0x0E, 0x0A, 0x50, + 0xB5, 0x9C, 0x09, 0x25, 0x6A, 0x19, 0xB5, 0x08, + 0x08, 0x43, 0xB1, 0x50, 0x65, 0x59, 0x1A, 0xCF, + 0xA4, 0xFF, 0x92, 0x6C, 0xBA, 0x05, 0x13, 0xFD, + 0x31, 0xBF, 0xFB, 0x52, 0xCD, 0x68, 0x8F, 0x01, + 0x94, 0x19, 0xCD, 0xD8, 0x1E, 0x4E, 0x71, 0x44, + 0xAF, 0x5E, 0xE4, 0xDC, 0x43, 0x07, 0x42, 0xF2, + 0x5A, 0xEA, 0x7F, 0xBA, 0xD9, 0x8C, 0x84, 0xC4, + 0x2A, 0xE3, 0xCB, 0xA9, 0xB6, 0x6D, 0x94, 0x11, + 0xAB, 0x50, 0x84, 0x56, 0x42, 0xAC, 0x6E, 0xB9, + 0xBD, 0xBC, 0x98, 0x82, 0x66, 0xAF, 0x40, 0x33, + 0x50, 0xF3, 0x13, 0xE5, 0x6E, 0x34, 0x24, 0xFF, + 0x5F, 0x0F, 0xCE, 0x29, 0x54, 0x32, 0xE0, 0x6F, + 0x0B, 0x8B, 0x52, 0x14, 0x6B, 0x0C, 0x2A, 0x57, + 0x7F, 0xB6, 0x2D, 0xD4, 0x2C, 0xD2, 0xD4, 0x1A, + 0x60, 0xF7, 0x1C, 0xBB, 0xF4, 0x07, 0x69, 0x02, + 0xF5, 0xE2, 0x2E, 0xC4, 0xFB, 0xE2, 0x83, 0xA0, + 0x60, 0x8C, 0x69, 0x6C, 0x1B, 0x9D, 0x0B, 0x90, + 0xE8, 0x0F, 0xD3, 0x8C, 0x76, 0x97, 0x0C, 0xC5, + 0x84, 0x61, 0x4F, 0x61, 0x0E, 0x84, 0xF5, 0x7D, + 0xC2, 0xD5, 0x0A, 0x9A, 0xC7, 0x56, 0x56, 0xD9, + 0xDE, 0x79, 0xD0, 0xE2, 0x65, 0xF3, 0x88, 0xBD, + 0x41, 0xE3, 0x10, 0xB6, 0x36, 0x65, 0x62, 0xBB, + 0x72, 0x5B, 0x7B, 0xD9, 0x67, 0xD9, 0x40, 0xB8, + 0x50, 0xA4, 0x3D, 0x06, 0xD5, 0x51, 0x25, 0x32, + 0xE8, 0x0B, 0x0E, 0x2D, 0xFA, 0xAB, 0x1C, 0x9C, + 0x80, 0x55, 0x51, 0x5B, 0x5A, 0x69, 0x76, 0x4D, + 0x95, 0x16, 0x84, 0x8A, 0xD7, 0x30, 0xA6, 0x2E, + 0xE9, 0x03, 0x33, 0x80, 0x4F, 0xF0, 0x9A, 0xBA, + 0x41, 0x4A, 0xDB, 0x9F, 0xB3, 0x7F, 0xC1, 0x9D, + 0xE5, 0x3B, 0x66, 0xC1, 0x15, 0xB9, 0x9A, 0x72, + 0x74, 0x7B, 0xF6, 0x52, 0x17, 0xF7, 0x5C, 0x46, + 0xE4, 0x4F, 0xD2, 0xF7, 0x8C, 0x49, 0x69, 0xE6, + 0x58, 0x21, 0xE4, 0xAE, 0xC0, 0x55, 0x01, 0xA7, + 0x18, 0x57, 0x10, 0x6E, 0x3F, 0x42, 0x7B, 0xC2, + 0x05, 0xEE, 0x24, 0x5D, 0x23, 0xB6, 0xC1, 0x59, + 0xF7, 0xA6, 0x40, 0xFD, 0xF0, 0x91, 0xE0, 0xA9, + 0x2C, 0x1E, 0x94, 0xB0, 0xFD, 0x05, 0xAA, 0xAE, + 0xDD, 0xB0, 0x61, 0x6F, 0x0F, 0xC7, 0x26, 0xE4, + 0x0E, 0xDB, 0x7A, 0x0B, 0x3E, 0x78, 0x92, 0x7E, + 0xB9, 0xD6, 0xAF, 0x36, 0x4A, 0x4F, 0x07, 0x2E, + 0x5E, 0xDB, 0xE7, 0x25, 0x4A, 0x9D, 0xB6, 0x88, + 0xB6, 0x7D, 0xD4, 0x60, 0xFC, 0xD0, 0xA5, 0x32, + 0x8A, 0x94, 0x5A, 0x53, 0xDF, 0x9B, 0xF9, 0x8B, + 0x57, 0xC9, 0xEB, 0xCC, 0xC2, 0x90, 0xFF, 0x6F, + 0xA2, 0x8F, 0xAC, 0xE3, 0xAA, 0xC2, 0xE0, 0x5D, + 0x89, 0x71, 0x0A, 0xC0, 0x0D, 0xDF, 0x6A, 0x14, + 0x98, 0x71, 0x34, 0xC6, 0x22, 0x55, 0xE5, 0x5A, + 0x7A, 0xA1, 0xFB, 0xE4, 0xB7, 0x15, 0x15, 0xE2, + 0xDE, 0xFD, 0x26, 0x4D, 0x99, 0x96, 0x87, 0x06, + 0xA9, 0x29, 0x86, 0x80, 0x3C, 0x91, 0x63, 0xCF, + 0x25, 0x91, 0x4A, 0xD0, 0x2A, 0xF8, 0xF6, 0x5E, + 0xB4, 0x58, 0xAA, 0xA0, 0x15, 0x46, 0xF0, 0xCB, + 0xED, 0x98, 0x26, 0xD5, 0xC5, 0x7F, 0x35, 0xE6, + 0xE5, 0x9E, 0xED, 0x75, 0x97, 0x75, 0x29, 0xFD, + 0x92, 0xA6, 0x71, 0xBE, 0xAF, 0x0D, 0x5E, 0x0A, + 0x80, 0x60, 0x72, 0xF5, 0x8F, 0x3D, 0x4B, 0x62, + 0xFF, 0x87, 0x5D, 0x5F, 0x38, 0x02, 0x82, 0x94, + 0x34, 0xEB, 0xAE, 0x8E, 0x5B, 0xC6, 0x5A, 0x44, + 0xD8, 0x11, 0x4C, 0x21, 0x56, 0xEC, 0x6D, 0x75, + 0x26, 0x57, 0x30, 0x59, 0x35, 0x39, 0x02, 0xA6, + 0x0C, 0xC3, 0x5A, 0x06, 0x06, 0xAD, 0x73, 0xA1, + 0x75, 0x83, 0xE5, 0xB6, 0x69, 0x7B, 0x70, 0x93, + 0x5A, 0xC7, 0x26, 0x7A, 0x5C, 0xB0, 0xE6, 0xB9, + 0xC5, 0x13, 0xCA, 0x4C, 0xDB, 0xE0, 0x8A, 0xB7, + 0x7C, 0xA5, 0xE5, 0x0A, 0x4C, 0x18, 0xB9, 0x42, + 0x6F, 0xCF, 0x75, 0x6F, 0x3C, 0x11, 0xB6, 0xC2, + 0xCC, 0xF3, 0x3C, 0x58, 0xC7, 0xB9, 0x5D, 0x59, + 0x9F, 0xD0, 0x39, 0x17, 0xE6, 0x90, 0x22, 0x83, + 0xDE, 0x97, 0xC0, 0x50, 0x2A, 0x5A, 0xBE, 0x10, + 0x30, 0x32, 0x1F, 0xB5, 0xDD, 0xE6, 0x79, 0xA2, + 0xE2, 0xB0, 0x4E, 0x4E, 0xB6, 0x1D, 0x1C, 0xF8, + 0xE3, 0xE6, 0xB6, 0xF4, 0x8C, 0x26, 0xFA, 0x1E, + 0xAF, 0xA7, 0x55, 0xE5, 0x56, 0x0C, 0xB8, 0xF8, + 0xDD, 0x17, 0xFA, 0x0D, 0x45, 0xF7, 0x04, 0x20, + 0x89, 0xD2, 0x3B, 0x8A, 0x7B, 0x0B, 0x62, 0xCC, + 0xB3, 0xC3, 0xE5, 0xC0, 0x04, 0x8D, 0x46, 0xDE, + 0xC1, 0x58, 0xB9, 0x93, 0xC6, 0x76, 0x17, 0x25, + 0xE1, 0xB6, 0x34, 0x82, 0x11, 0xB0, 0x40, 0xF1, + 0x33, 0xA0, 0x6C, 0x79, 0x1A, 0x4C, 0x28, 0x15, + 0xDF, 0x94, 0xE2, 0x39, 0x8A, 0x8F, 0xDE, 0xBF, + 0xE4, 0xEE, 0xBB, 0xDF, 0x84, 0x1A, 0xEE, 0x0F, + 0x67, 0xCD, 0xCC, 0x9F, 0x9F, 0xDC, 0xDC, 0x9B, + 0x67, 0x9D, 0x72, 0xC2, 0x71, 0x3F, 0xD9, 0x72, + 0xA2, 0x89, 0xF2, 0xF7, 0x5A, 0xD1, 0x69, 0x87, + 0x68, 0x85, 0x91, 0x52, 0x29, 0xF4, 0x10, 0x13, + 0xC1, 0xCD, 0xE4, 0x73, 0x9B, 0x06, 0x7D, 0x91, + 0xFB, 0xDD, 0xE7, 0x9D, 0xB9, 0x0A, 0xB3, 0x83, + 0xC1, 0x1C, 0x03, 0x97, 0xD2, 0xE1, 0xF0, 0xEF, + 0xDA, 0x9E, 0xBD, 0xB0, 0x6A, 0x3B, 0xC5, 0x0A, + 0x61, 0x37, 0xBF, 0x12, 0x9F, 0x57, 0x22, 0x5C, + 0x05, 0xDC, 0xD9, 0xC7, 0x75, 0x0B, 0x0A, 0xDF, + 0xFA, 0x84, 0xC1, 0x3D, 0x79, 0x21, 0x60, 0xFA, + 0xBD, 0xBF, 0xE1, 0xBB, 0xCE, 0xEE, 0x71, 0x90, + 0xB2, 0x7B, 0x8B, 0xCE, 0x57, 0xF7, 0x22, 0xA7, + 0xF1, 0x1C, 0x43, 0x6F, 0xC0, 0x71, 0xAA, 0xD0, + 0x8F, 0x84, 0xF8, 0xBD, 0xCF, 0xEF, 0xBF, 0xCB, + 0x3D, 0xAF, 0x61, 0xB5, 0xE1, 0x8F, 0x39, 0xFA, + 0xD4, 0x67, 0xCE, 0xAB, 0xBA, 0x31, 0x54, 0xB1, + 0xC6, 0x03, 0x24, 0x81, 0x33, 0x5E, 0x77, 0x55, + 0xB3, 0x36, 0xD1, 0x4E, 0xF8, 0x20, 0xCE, 0x46, + 0x99, 0x75, 0xA6, 0x6F, 0x19, 0x2C, 0x61, 0x4A, + 0xEB, 0x5B, 0xE3, 0x6B, 0x5C, 0x46, 0xFB, 0x18, + 0xF0, 0x7B, 0x97, 0xA5, 0x1A, 0xBD, 0x20, 0x86, + 0x0D, 0x5A, 0xE3, 0x6A, 0x83, 0x81, 0xF6, 0xAE, + 0xE2, 0x8A, 0x94, 0x22, 0xE6, 0xAF, 0x8E, 0xDC, + 0x15, 0x00, 0x28, 0x3F, 0x8F, 0xC0, 0xFF, 0xDE, + 0x5E, 0xC2, 0xF1, 0x74, 0xED, 0xAC, 0x75, 0xE8, + 0x0F, 0x0D, 0x7B, 0x0E, 0x4A, 0xC0, 0x85, 0x58, + 0xBA, 0xED, 0x86, 0x5C, 0x78, 0xBB, 0x5C, 0x53, + 0x41, 0x2A, 0x2D, 0x3B, 0xBF, 0x1F, 0xCB, 0xB7, + 0xCE, 0x49, 0x84, 0x9C, 0x81, 0x17, 0x5E, 0xEF, + 0x02, 0x67, 0x8C, 0x6A, 0x06, 0xD6, 0x8F, 0xB9, + 0x6C, 0x72, 0x6D, 0xE5, 0x59, 0xAC, 0xD8, 0xC2, + 0xF4, 0x01, 0x00, 0xBD, 0xFF, 0x5D, 0x38, 0x50, + 0x27, 0xD9, 0x4A, 0xB4, 0xAD, 0xDB, 0xF3, 0x7B, + 0x83, 0x26, 0x6D, 0x3F, 0x9E, 0x9C, 0x77, 0x99, + 0xB5, 0x7B, 0x89, 0x59, 0x4D, 0xC5, 0xA0, 0xE1, + 0xB1, 0xFB, 0x9C, 0xDA, 0x65, 0x24, 0x99, 0xD6, + 0x09, 0x0C, 0x58, 0xFE, 0x47, 0xA2, 0xBC, 0xF8, + 0xC7, 0x5C, 0x89, 0xD9, 0x60, 0x8A, 0xA8, 0x09, + 0x20, 0xC5, 0x29, 0x92, 0x34, 0xF1, 0x44, 0x0E, + 0xA6, 0x2F, 0xEC, 0xD7, 0x13, 0xA5, 0x5B, 0x86, + 0xF3, 0x00, 0x89, 0x9B, 0x6D, 0xAD, 0xCE, 0xBC, + 0xE7, 0x08, 0x84, 0x78, 0xA9, 0xD7, 0x79, 0x24, + 0x0C, 0xEE, 0x55, 0xB7, 0xDE, 0xA3, 0x7B, 0x23, + 0x7D, 0xB8, 0xF6, 0x94, 0x53, 0xB4, 0x0B, 0xC2, + 0xC7, 0x98, 0x7E, 0xF8, 0x1D, 0x1C, 0x88, 0x55, + 0xD1, 0xCB, 0xA9, 0x27, 0x35, 0xCC, 0x35, 0x95, + 0xF7, 0x80, 0x06, 0x1C, 0x8D, 0x22, 0x94, 0x99, + 0xB9, 0xE5, 0x1C, 0xE6, 0x62, 0xDF, 0xCA, 0x75, + 0x5E, 0x8D, 0x50, 0xE8, 0x45, 0x63, 0x94, 0xEC, + 0xD4, 0xC3, 0x2A, 0x2C, 0xC2, 0x88, 0x33, 0xDF, + 0x05, 0x01, 0xAE, 0x92, 0x4C, 0xC8, 0xA9, 0xB2, + 0x95, 0x68, 0x1A, 0x86, 0x3F, 0x53, 0x83, 0x48, + 0x9A, 0x25, 0x4F, 0x78, 0x1B, 0xD4, 0x26, 0x0B, + 0x8F, 0x7B, 0x2D, 0xDC, 0x91, 0x0C, 0xEA, 0xB0, + 0x9A, 0x1C, 0x63, 0xF9, 0x2F, 0x48, 0x17, 0x5F, + 0x6B, 0x1D, 0xA7, 0x1A, 0x55, 0x44, 0x50, 0x7C, + 0x54, 0x19, 0xBE, 0x0F, 0x6E, 0x50, 0x2D, 0x2A, + 0xC7, 0x24, 0x8A, 0xD2, 0x75, 0xD0, 0x3A, 0x2D, + 0x60, 0x21, 0x76, 0x4A, 0x14, 0x40, 0xE0, 0x24, + 0xC0, 0x1E, 0x2D, 0x09, 0xCA, 0xD5, 0xED, 0xB3, + 0x8D, 0xBA, 0xD9, 0x17, 0xEB, 0x8A, 0xCC, 0x3A, + 0x2A, 0x64, 0x05, 0x5B, 0xE8, 0x7E, 0x13, 0x5C, + 0x9E, 0x97, 0x6B, 0x89, 0x70, 0xC1, 0xD7, 0xC4, + 0x6C, 0x3D, 0x42, 0x34, 0xF6, 0x4B, 0xA9, 0x81, + 0xE3, 0xEC, 0xA2, 0x63, 0xAA, 0x44, 0x1D, 0x5C, + 0x83, 0xCF, 0x10, 0x43, 0x93, 0xEF, 0xCC, 0x8D, + 0x16, 0xA0, 0xB4, 0x3B, 0x9D, 0x89, 0x1E, 0xFB, + 0x58, 0xCF, 0xCA, 0xFC, 0x66, 0x3E, 0x6F, 0x9A, + 0xF2, 0xFA, 0xFF, 0xBF, 0xF8, 0x5A, 0x5B, 0xB2, + 0x24, 0x2B, 0x2E, 0x74, 0x32, 0x9A, 0x18, 0x70, + 0x68, 0xB3, 0xB0, 0x21, 0x77, 0x4A, 0x7B, 0x7D, + 0x94, 0x1F, 0x1C, 0xC1, 0x93, 0xC5, 0x24, 0x09, + 0x47, 0xDC, 0x3C, 0xED, 0xA8, 0xF7, 0x92, 0x5C, + 0xE2, 0x35, 0xDE, 0x63, 0x3A, 0xFC, 0xD7, 0xD9, + 0x48, 0xDB, 0x64, 0x29, 0x6B, 0x70, 0xB4, 0x4C, + 0xFD, 0xB0, 0x33, 0x85, 0xDB, 0x00, 0x97, 0xFA, + 0x1C, 0x63, 0x52, 0x9B, 0x3C, 0xA2, 0xD2, 0x68, + 0x10, 0xFD, 0x76, 0x5A, 0x0E, 0xFF, 0x5B, 0x88, + 0x6D, 0x8B, 0x00, 0xDB, 0xE6, 0x34, 0x6B, 0x4A, + 0x73, 0x9C, 0x8A, 0x70, 0x60, 0x05, 0xFC, 0x99, + 0xFA, 0x9D, 0x93, 0x6E, 0xFE, 0xF7, 0xDD, 0xB2, + 0x64, 0xFF, 0x59, 0x23, 0x25, 0x43, 0xD5, 0xDE, + 0xAC, 0x05, 0xC0, 0x9F, 0x33, 0xA1, 0x29, 0xF3, + 0xDA, 0xC6, 0xC6, 0xA1, 0x41, 0x79, 0xBC, 0x80, + 0x31, 0x2E, 0x35, 0x56, 0x2C, 0x34, 0xE4, 0x4C, + 0xA8, 0x6D, 0xF4, 0x6A, 0x14, 0xA9, 0x5F, 0xE5, + 0xE7, 0xA0, 0xCE, 0x88, 0xD2, 0x95, 0xF4, 0xAE, + 0x07, 0xD5, 0x2E, 0xF1, 0x1E, 0x7F, 0x2E, 0xCD, + 0x9A, 0x8B, 0xA9, 0x96, 0x99, 0x5A, 0x0B, 0x38, + 0x2D, 0xB5, 0x02, 0xB3, 0x3B, 0xB6, 0x50, 0xC9, + 0x05, 0xEC, 0x18, 0x29, 0x79, 0x98, 0xC6, 0x24, + 0xB7, 0x15, 0xDE, 0x6B, 0x80, 0x89, 0x8A, 0x02, + 0x5D, 0x49, 0x26, 0xD8, 0x6E, 0x00, 0x82, 0x60, + 0x0B, 0x4E, 0x08, 0xB7, 0x92, 0xAC, 0x96, 0xFB, + 0xD7, 0xF9, 0x7D, 0x42, 0xAE, 0x50, 0xB1, 0x6C, + 0xB2, 0x8B, 0x3E, 0x4A, 0xFF, 0xAD, 0xF8, 0x4D, + 0x10, 0xAE, 0x0D, 0x08, 0x44, 0x4D, 0x1B, 0x02, + 0xC7, 0xE5, 0x3E, 0xB6, 0x45, 0xD7, 0xE2, 0xF3, + 0x41, 0xF1, 0xBB, 0x91, 0x2B, 0x59, 0xDA, 0xD7, + 0x49, 0x07, 0xD0, 0xBF, 0x23, 0x16, 0xAD, 0x43, + 0x79, 0xBB, 0xA9, 0xAA, 0x96, 0x84, 0x9A, 0xA4, + 0xED, 0xF2, 0x0C, 0xDF, 0x89, 0xDC, 0xC4, 0x5E, + 0x7C, 0x75, 0x85, 0x45, 0x21, 0x68, 0x77, 0x6C, + 0xB8, 0x72, 0x11, 0x6D, 0x6F, 0xBA, 0xC5, 0x1C, + 0x0B, 0x82, 0x71, 0x34, 0x36, 0xF2, 0x42, 0xCE, + 0x85, 0xA8, 0x61, 0xDE, 0xFF, 0x96, 0xF3, 0xE2, + 0x63, 0xB6, 0x01, 0xC5, 0x05, 0xC3, 0x0F, 0x46, + 0xE8, 0xD8, 0xB5, 0x30, 0xCF, 0xA7, 0xCA, 0xEF, + 0xB6, 0x83, 0xF3, 0x30, 0xF9, 0x70, 0x77, 0x08, + 0x17, 0x2E, 0x21, 0x6B, 0x2D, 0xFE, 0xD4, 0xAA, + 0x62, 0xAC, 0xED, 0x3F, 0x5F, 0x2D, 0xEC, 0x26, + 0xB5, 0x38, 0x16, 0x20, 0x9D, 0xF6, 0x7B, 0xF8, + 0x1B, 0x4D, 0x8A, 0xE8, 0xAE, 0x8A, 0x6A, 0x80, + 0xF3, 0x44, 0x2C, 0xAE, 0xF5, 0xEC, 0x5A, 0xD6, + 0xFB, 0x9D, 0x0D, 0x41, 0x67, 0x37, 0x62, 0x85, + 0xB1, 0x55, 0x47, 0xF8, 0xFD, 0x7B, 0x4D, 0x86, + 0x7D, 0xBE, 0x37, 0x1A, 0x35, 0x15, 0xEB, 0x56, + 0x38, 0xB0, 0x16, 0xDD, 0x3B, 0xF8, 0x28, 0x05, + 0x53, 0x36, 0xE1, 0x79, 0x50, 0x2B, 0x91, 0x00, + 0x24, 0x0B, 0xB4, 0x1F, 0x27, 0xE4, 0xAF, 0x55, + 0x11, 0x23, 0xBE, 0x22, 0x12, 0xFD, 0x65, 0xAC, + 0xE6, 0xA5, 0xC4, 0x0E, 0x25, 0xEC, 0x49, 0xD1, + 0x92, 0x69, 0x44, 0x5C, 0x55, 0xFE, 0x18, 0x1C, + 0xEE, 0xEF, 0xF3, 0x47, 0x4A, 0xA7, 0x65, 0x89, + 0x8B, 0x71, 0x35, 0x30, 0x27, 0xAC, 0x6B, 0x53, + 0xD2, 0xF2, 0xA0, 0x5D, 0x2C, 0xD1, 0xD7, 0xF1, + 0x58, 0xC9, 0xA7, 0xC9, 0xE5, 0x6B, 0x89, 0xA1, + 0xBE, 0xEB, 0x02, 0x86, 0xDA, 0x15, 0x73, 0xF2, + 0x5A, 0xC7, 0x59, 0x7B, 0x46, 0xAA, 0x68, 0x6C, + 0x01, 0xFB, 0x0A, 0x74, 0xAC, 0x4C, 0xD5, 0x3C, + 0x9F, 0x51, 0x1A, 0x71, 0x4E, 0x1B, 0x81, 0x81, + 0x1A, 0x56, 0x93, 0x80, 0x59, 0x9B, 0xD6, 0x42, + 0xE6, 0x93, 0x5A, 0xC3, 0xAA, 0x2B, 0xC6, 0x58, + 0x51, 0x5D, 0x62, 0x47, 0x27, 0x47, 0xDB, 0xA0, + 0x2D, 0x4F, 0x95, 0xB4, 0xC8, 0x29, 0x4C, 0xD2, + 0x9E, 0x09, 0x66, 0x30, 0xBE, 0xFF, 0x74, 0x07, + 0xC3, 0x98, 0x6E, 0x3F, 0xD1, 0xA0, 0x5D, 0xFA, + 0x29, 0x4F, 0x7F, 0x1E, 0x83, 0xFF, 0xBA, 0x4E, + 0x78, 0x4B, 0xF0, 0xC0, 0xF7, 0xD5, 0xA6, 0xC1, + 0xBF, 0x2E, 0x1E, 0x94, 0xFB, 0x8A, 0x2D, 0xC2, + 0x88, 0x68, 0xBD, 0xF9, 0x90, 0x72, 0xBA, 0x57, + 0xD9, 0x24, 0x1C, 0x81, 0x47, 0x2F, 0x22, 0x60, + 0xBE, 0x64, 0x44, 0xA6, 0xD2, 0x99, 0xE2, 0x9D, + 0xD8, 0x6A, 0x8D, 0x06, 0x96, 0x37, 0xB9, 0x9D, + 0x34, 0xAF, 0xF8, 0x62, 0x09, 0x06, 0x43, 0x70, + 0x4F, 0xCF, 0xC4, 0x53, 0x81, 0xE7, 0x22, 0x09, + 0x60, 0x17, 0xA6, 0xEE, 0xF7, 0x97, 0x14, 0xD7, + 0x54, 0x8D, 0xA7, 0x83, 0x73, 0xF4, 0x0F, 0x15, + 0x8F, 0x4C, 0x69, 0x1B, 0x92, 0xFB, 0x0D, 0xB9, + 0x1B, 0x40, 0x6B, 0xFC, 0x4D, 0xF3, 0x5B, 0x8E, + 0xDC, 0x02, 0xE2, 0x49, 0xDC, 0xF0, 0xB8, 0xBB, + 0x2C, 0xB1, 0x5D, 0x75, 0x05, 0xED, 0x33, 0x94, + 0xA7, 0x2B, 0x72, 0xBB, 0xEC, 0x33, 0x46, 0xC6, + 0xC8, 0x4A, 0xEF, 0xB8, 0xB7, 0xAD, 0x07, 0xBC, + 0xF0, 0x76, 0xDF, 0x85, 0xE0, 0x8F, 0x52, 0x98, + 0x9C, 0x0B, 0xAC, 0x5A, 0xD7, 0xFA, 0x25, 0xAD, + 0x48, 0xC5, 0x8F, 0x80, 0xC4, 0xAF, 0x92, 0x3B, + 0xB3, 0x00, 0x14, 0xD8, 0xD0, 0xC2, 0x13, 0x67, + 0x3E, 0xB1, 0x5E, 0xE8, 0x59, 0xB7, 0x40, 0xD3, + 0x14, 0x94, 0x25, 0xE8, 0xA3, 0x21, 0x37, 0xF9, + 0xDC, 0x17, 0x55, 0x62, 0x18, 0x06, 0xF4, 0x2D, + 0xBD, 0x3F, 0x5B, 0x9D, 0xF0, 0x6A, 0xAD, 0xC2, + 0xD0, 0xC9, 0x54, 0xF8, 0x1B, 0x0A, 0x55, 0xA7, + 0xD3, 0x4A, 0x5F, 0xF2, 0x58, 0xC1, 0x3B, 0x46, + 0xAA, 0xB1, 0x15, 0x2E, 0xC7, 0xE9, 0xCF, 0x76, + 0x79, 0xDD, 0xC5, 0x8C, 0x47, 0xF3, 0x2A, 0xB5, + 0x74, 0x18, 0xC8, 0x98, 0x22, 0xD7, 0xFE, 0x3D, + 0x50, 0xDE, 0xEC, 0x52, 0x25, 0x1A, 0x8D, 0xC5, + 0xC2, 0xBC, 0xBB, 0x71, 0xDC, 0x48, 0x07, 0xF1, + 0x9B, 0xC6, 0x25, 0xC3, 0x3C, 0xA6, 0xCA, 0x45, + 0xBC, 0x61, 0xA1, 0x88, 0x7A, 0xBF, 0xCC, 0x1E, + 0x45, 0xE7, 0x4D, 0x7B, 0xDD, 0x16, 0x46, 0x00, + 0x7C, 0xAE, 0x2C, 0x1C, 0x7E, 0x0C, 0x9A, 0xC1, + 0xE9, 0x39, 0x3C, 0x3B, 0x8A, 0x52, 0xEB, 0x2D, + 0x98, 0x94, 0x84, 0xA8, 0xFD, 0x19, 0x33, 0x37, + 0xC2, 0xD3, 0x7A, 0xE3, 0x06, 0x24, 0x67, 0xAC, + 0x8F, 0x40, 0xB0, 0xFB, 0x6C, 0x8D, 0xA0, 0xE9, + 0x34, 0xA8, 0xC8, 0x38, 0x56, 0xA0, 0x34, 0x8D, + 0x64, 0x3F, 0x25, 0x10, 0x2B, 0x92, 0x3C, 0xD0, + 0x48, 0xBE, 0x84, 0x29, 0x8B, 0x3B, 0xAB, 0x34, + 0xAB, 0x6A, 0xA8, 0x43, 0x83, 0xF5, 0xB9, 0x81, + 0x3D, 0xB8, 0xFA, 0x5F, 0xFF, 0x2D, 0x04, 0xD2, + 0x9A, 0x6C, 0x86, 0xA1, 0x91, 0xE1, 0x01, 0xDC, + 0x7E, 0xB1, 0xF3, 0xA2, 0x86, 0x55, 0xD8, 0x09, + 0xE2, 0xB1, 0xB0, 0xDA, 0x0B, 0xDA, 0x18, 0xB2, + 0x7B, 0x2A, 0x76, 0x42, 0x21, 0xBC, 0xB4, 0xD1, + 0x22, 0xA0, 0xC8, 0x7B, 0xA9, 0xBA, 0xA3, 0xF0, + 0xE3, 0x8C, 0x05, 0xFC, 0x3B, 0x0C, 0xFA, 0x35, + 0xD0, 0xFC, 0xAF, 0xED, 0x7B, 0x52, 0x53, 0x7F, + 0x5E, 0xEC, 0x81, 0xEF, 0x66, 0x80, 0x22, 0x8E, + 0xDA, 0x5C, 0x25, 0x0A, 0x18, 0x4B, 0x0E, 0x06, + 0x74, 0xD6, 0x4D, 0x06, 0xEF, 0x13, 0xDA, 0x8F, + 0x97, 0x28, 0x9F, 0x7F, 0x4C, 0xC1, 0x0E, 0x4A, + 0xBF, 0xDC, 0x46, 0x78, 0x07, 0x0F, 0x52, 0x9B, + 0x29, 0x28, 0x35, 0xBE, 0x54, 0x59, 0xE8, 0x03, + 0x5E, 0xFD, 0x0C, 0x4A, 0xEC, 0xFE, 0x7E, 0x60, + 0xAF, 0xC1, 0x0F, 0x8E, 0x30, 0xAC, 0x90, 0xD5, + 0xC6, 0x35, 0x65, 0x81, 0x2C, 0xEF, 0x01, 0x3F, + 0xF7, 0x67, 0x4E, 0x1C, 0x62, 0xA1, 0x29, 0x6E, + 0xE2, 0x08, 0xE4, 0xBE, 0x01, 0xE1, 0xEE, 0xDD, + 0x2F, 0xCB, 0xBC, 0xF3, 0xBF, 0xBE, 0x62, 0x96, + 0xB4, 0x7B, 0xB9, 0x14, 0x38, 0xF7, 0x78, 0xC3, + 0x7E, 0xB0, 0xB8, 0x85, 0xB3, 0x2E, 0x4F, 0xD1, + 0x12, 0xD8, 0x69, 0x7C, 0x84, 0x96, 0x41, 0x24, + 0x9F, 0x08, 0xF8, 0x6B, 0x20, 0xF7, 0xEA, 0xDC, + 0xB1, 0xA5, 0x09, 0x49, 0xE1, 0x8B, 0xC4, 0x77, + 0x9B, 0x22, 0xBB, 0x38, 0xC1, 0xD1, 0x82, 0xCC, + 0x86, 0x78, 0xE4, 0xE4, 0x56, 0xF4, 0x9B, 0x70, + 0x2C, 0xBB, 0x86, 0x52, 0x94, 0x47, 0x65, 0xE7, + 0x97, 0x17, 0xAF, 0xA7, 0x29, 0x54, 0xD6, 0xAA, + 0x38, 0x15, 0x85, 0xC8, 0xDC, 0xAB, 0x2F, 0x09, + 0x79, 0x53, 0xE1, 0xD9, 0x85, 0xF5, 0x85, 0x08, + 0xB9, 0x18, 0x6E, 0x7C, 0x1B, 0x3F, 0x3C, 0xA7, + 0xAA, 0x89, 0x03, 0xAD, 0xB2, 0x3A, 0x9F, 0x5A, + 0x13, 0x03, 0xCD, 0xB4, 0x95, 0xC1, 0xE3, 0xE7, + 0xBA, 0x6E, 0xE7, 0x6B, 0x58, 0x80, 0xE2, 0xA3, + 0x20, 0x5B, 0x76, 0x28, 0xAC, 0x82, 0x91, 0x89, + 0xE3, 0x08, 0x39, 0xAB, 0x87, 0xD9, 0x0E, 0x5B, + 0x22, 0xB9, 0x0D, 0x19, 0x7D, 0x0A, 0x86, 0xD8, + 0x95, 0x42, 0xD4, 0x13, 0xDD, 0x35, 0xA5, 0x3A, + 0x0A, 0x50, 0x7C, 0x9D, 0x16, 0x72, 0x3D, 0x8C, + 0x23, 0x78, 0x36, 0x4A, 0x8F, 0xB7, 0x65, 0xC4, + 0xD8, 0x49, 0x69, 0x82, 0xDB, 0x4D, 0xDC, 0xD3, + 0xD2, 0xAF, 0x16, 0x86, 0x7E, 0xCD, 0x79, 0xF1, + 0x4C, 0x9D, 0xDF, 0xFB, 0xD4, 0x65, 0xC2, 0x47, + 0x4F, 0x51, 0x3D, 0x62, 0xA9, 0x5E, 0x9C, 0xBB, + 0xD8, 0x3F, 0x48, 0x1F, 0xB8, 0x26, 0xDC, 0xB4, + 0xDA, 0x45, 0x01, 0x05, 0xF1, 0xA5, 0xEF, 0x1F, + 0x11, 0xA0, 0x65, 0x68, 0x7A, 0x01, 0x5C, 0xB1, + 0xC3, 0xF8, 0x94, 0xDF, 0x38, 0x5F, 0x5F, 0x01, + 0xBD, 0xCA, 0x47, 0x9D, 0x74, 0xC5, 0xB3, 0xB2, + 0x65, 0x37, 0xCA, 0x60, 0x3D, 0x57, 0x83, 0x1E, + 0x7B, 0xFE, 0xAF, 0x37, 0xF3, 0x7E, 0x14, 0x25, + 0xBF, 0x78, 0x37, 0xC7, 0xB4, 0x01, 0x17, 0xC6, + 0xFB, 0x1C, 0x96, 0x48, 0xB3, 0x6E, 0x4D, 0xDE, + 0xAC, 0x5B, 0x78, 0xD5, 0x3A, 0x1A, 0x24, 0xB4, + 0x7C, 0x37, 0xDC, 0x49, 0x08, 0xE4, 0x99, 0x65, + 0x4D, 0x47, 0x7F, 0xF4, 0x40, 0x99, 0xE9, 0xA5, + 0xEF, 0xEE, 0xBF, 0x5B, 0x13, 0xD1, 0xC4, 0x6F, + 0xED, 0x3D, 0x6D, 0xD0, 0x1B, 0x8E, 0xC7, 0x8E, + 0x80, 0xA8, 0xAC, 0xDF, 0x9E, 0xEE, 0x5E, 0x45, + 0x8C, 0x1E, 0x92, 0x4E, 0xD3, 0x60, 0x4A, 0x62, + 0x9D, 0xA7, 0x14, 0x7C, 0xC1, 0x5A, 0x00, 0x32, + 0x81, 0x5E, 0x84, 0xEB, 0x8A, 0x3A, 0x27, 0xDB, + 0xA5, 0xA6, 0x4C, 0xD6, 0xDB, 0x23, 0xDD, 0x2C, + 0x5C, 0x59, 0x75, 0x51, 0xE9, 0x7F, 0xF6, 0x38, + 0x76, 0x80, 0x5B, 0x4F, 0xD4, 0x07, 0xE4, 0xE3, + 0xE7, 0x74, 0xB1, 0x06, 0xE3, 0xEA, 0xC8, 0x97, + 0x37, 0x5B, 0x8F, 0x09, 0x76, 0x90, 0xE5, 0x5D, + 0x5B, 0x4E, 0x36, 0x59, 0x99, 0x03, 0xBD, 0x71, + 0xC9, 0xDA, 0xB2, 0x2A, 0x82, 0xA7, 0x85, 0x7B, + 0x6E, 0x33, 0xBA, 0x56, 0x6C, 0xE6, 0xE2, 0x76, + 0x9B, 0xE2, 0xF0, 0xCC, 0x76, 0xF0, 0x16, 0x1A, + 0x58, 0xC7, 0x38, 0x2E, 0xF1, 0x3D, 0x46, 0xC6, + 0x45, 0xCF, 0x85, 0x08, 0x23, 0x8D, 0xC0, 0x1A, + 0x02, 0xF5, 0x1E, 0x7D, 0xDF, 0x88, 0xEB, 0xFF, + 0xB4, 0xB9, 0xAC, 0xA6, 0x7D, 0xE2, 0xD2, 0x88, + 0x8C, 0x0B, 0xDA, 0xC9, 0x17, 0x44, 0x5C, 0x86, + 0xEC, 0x52, 0x82, 0x71, 0x5B, 0x40, 0x66, 0x83, + 0xE8, 0x7C, 0x02, 0x92, 0x3A, 0xFD, 0x81, 0x0F, + 0x3B, 0xC2, 0xDF, 0x2B, 0xFE, 0xB0, 0x68, 0xA4, + 0xF0, 0xED, 0x47, 0xF6, 0x07, 0x8D, 0x3D, 0x3E, + 0x4C, 0x79, 0x2A, 0x32, 0x51, 0x4F, 0x78, 0xEE, + 0x50, 0x0D, 0xDE, 0x32, 0x78, 0xE9, 0xE2, 0x16, + 0x7D, 0x02, 0x31, 0x5B, 0x4F, 0xC8, 0x6D, 0xBB, + 0x22, 0x44, 0x6C, 0x39, 0x1A, 0x72, 0xDD, 0xC3, + 0x29, 0x66, 0xAA, 0x95, 0xB4, 0xB3, 0x53, 0x6B, + 0x0B, 0x1B, 0xFA, 0x37, 0x0D, 0x31, 0x31, 0xAF, + 0x46, 0x10, 0xFB, 0xE6, 0xAC, 0x14, 0xA8, 0x42, + 0xBE, 0x9D, 0xDE, 0x00, 0x52, 0x7E, 0x39, 0xD2, + 0xF4, 0x5D, 0x34, 0xF7, 0x52, 0x04, 0xBC, 0x9C, + 0x17, 0xB9, 0x5F, 0xB5, 0xBC, 0x11, 0x73, 0x9A, + 0x08, 0x6B, 0x71, 0x5A, 0xC9, 0x4B, 0x11, 0xCA, + 0x05, 0x33, 0xCA, 0x07, 0xA7, 0xAA, 0x85, 0x7A, + 0x02, 0x47, 0x18, 0xB0, 0x0B, 0xE5, 0xCC, 0x75, + 0x24, 0x9B, 0x6D, 0xAF, 0xCD, 0xBB, 0x0B, 0x95, + 0x5C, 0x70, 0x82, 0xF6, 0x2D, 0xA7, 0x37, 0xED, + 0xD1, 0x65, 0x8B, 0x77, 0x1D, 0x76, 0xE6, 0xD8, + 0x11, 0xD1, 0x88, 0xEB, 0xDF, 0xD9, 0xC7, 0x9C, + 0x4C, 0x5F, 0xDF, 0x31, 0x8B, 0x63, 0x6D, 0x8E, + 0x30, 0xCE, 0x68, 0x39, 0x46, 0x75, 0xD4, 0x35, + 0x63, 0x4D, 0x34, 0x89, 0x59, 0x87, 0x15, 0x47, + 0xDF, 0x5C, 0xD9, 0x92, 0xD1, 0xC7, 0xDC, 0xC2, + 0xF0, 0x55, 0x1B, 0xA8, 0xF8, 0x57, 0xFF, 0xB5, + 0x4C, 0x97, 0xC6, 0xC8, 0x96, 0xBE, 0xA4, 0xCE, + 0x57, 0xAA, 0x71, 0x24, 0x4B, 0x7C, 0x1E, 0xA9, + 0x9B, 0xA5, 0xD2, 0xCA, 0xE8, 0x43, 0x71, 0xA5, + 0xD8, 0xE7, 0x79, 0x7F, 0xE9, 0xCD, 0xE1, 0xBF, + 0x8C, 0x9C, 0xAC, 0x93, 0x02, 0x62, 0x0C, 0xA5, + 0x44, 0xB6, 0x43, 0x3F, 0x3A, 0xF5, 0xC2, 0xA4, + 0x9F, 0x0C, 0x09, 0xC7, 0xCB, 0xA8, 0x20, 0x05, + 0x1F, 0x8C, 0x6E, 0x35, 0x88, 0x87, 0x92, 0xAE, + 0x37, 0x81, 0x49, 0x3D, 0x06, 0xA8, 0xF5, 0xA1, + 0x7B, 0xD8, 0xC4, 0x48, 0xE7, 0x35, 0x6D, 0xF4, + 0x14, 0x60, 0xDC, 0x63, 0xF4, 0x32, 0x90, 0xC1, + 0x9F, 0x9B, 0x23, 0xED, 0xC8, 0x39, 0x73, 0x04, + 0xF2, 0xF7, 0x6D, 0x3F, 0x1C, 0x71, 0x65, 0x80, + 0x6B, 0x41, 0xF9, 0xAB, 0xCB, 0xB0, 0x44, 0xFA, + 0x15, 0x37, 0xF4, 0xFF, 0x58, 0x78, 0x20, 0xB4, + 0x5A, 0x90, 0xE2, 0xC1, 0x4B, 0xC3, 0xC7, 0x81, + 0xF6, 0x75, 0x1E, 0xA4, 0x6B, 0xAB, 0xA4, 0x29, + 0xE6, 0x33, 0x50, 0xCE, 0x7D, 0xD7, 0xE5, 0x7A, + 0x4E, 0x23, 0xA2, 0xAB, 0xCD, 0x42, 0x90, 0x7F, + 0xE0, 0x33, 0xAF, 0x8A, 0x6D, 0x71, 0xC4, 0x1C, + 0xBD, 0xFA, 0xB7, 0x57, 0x57, 0xC6, 0xAA, 0x25, + 0xE6, 0x2C, 0xB2, 0x9A, 0x29, 0xF9, 0x8E, 0xF3, + 0x00, 0xB7, 0xD1, 0x95, 0x17, 0xE2, 0xDF, 0xA9, + 0x17, 0x44, 0xFF, 0x4A, 0x7A, 0xBD, 0x98, 0xB0, + 0xDF, 0x8E, 0xFB, 0x61, 0xFD, 0xCA, 0x84, 0x57, + 0xFC, 0xBB, 0xCE, 0xA8, 0x62, 0xCD, 0x73, 0x53, + 0x1E, 0x95, 0xA1, 0x20, 0x92, 0xB3, 0x14, 0x37, + 0x4C, 0x99, 0xD2, 0xDA, 0xCE, 0xA3, 0xEB, 0x1B, + 0xCF, 0x28, 0x42, 0x1A, 0xC7, 0x2C, 0x28, 0x4C, + 0x7D, 0x40, 0x5B, 0xD0, 0xE2, 0x6B, 0xA6, 0x47, + 0x92, 0xEF, 0x7A, 0x7B, 0x19, 0xF2, 0x84, 0x12, + 0x3A, 0x7B, 0xF9, 0xF3, 0xE4, 0xF8, 0x4F, 0x88, + 0x92, 0x4E, 0x19, 0x25, 0x45, 0x8A, 0x4B, 0x7C, + 0x4F, 0x24, 0xFB, 0x25, 0xBE, 0xF2, 0x10, 0x99, + 0x91, 0x0E, 0xFC, 0xDE, 0xB6, 0xCD, 0x43, 0x92, + 0xF6, 0xFD, 0x60, 0x4F, 0x4B, 0x05, 0x81, 0xD7, + 0x80, 0x48, 0xD6, 0xDD, 0x01, 0x94, 0xCE, 0x47, + 0x26, 0xA4, 0x56, 0x54, 0x25, 0x30, 0x9E, 0x14, + 0x11, 0x1D, 0xCD, 0xC2, 0xE8, 0x39, 0x19, 0x75, + 0xCC, 0xD3, 0xC0, 0x35, 0x38, 0x70, 0x6C, 0xD3, + 0xAF, 0x92, 0xCE, 0x06, 0x01, 0xB4, 0xBA, 0xB9, + 0x3D, 0x8D, 0x7E, 0x89, 0x88, 0x7B, 0xD2, 0x4A, + 0x16, 0x20, 0xC9, 0xA9, 0x3E, 0x60, 0xE5, 0x4A, + 0xCF, 0x8A, 0xB3, 0xE2, 0x00, 0x98, 0x55, 0x0D, + 0x38, 0x56, 0x8D, 0x90, 0x7F, 0xC6, 0x81, 0xC7, + 0xF9, 0x31, 0x56, 0x0B, 0xEB, 0x8B, 0xC5, 0x2E, + 0xBB, 0xB2, 0x01, 0xA6, 0xD1, 0xD2, 0x65, 0x99, + 0xD7, 0xC7, 0xF9, 0x83, 0x6F, 0x26, 0xEB, 0x47, + 0x7D, 0xBE, 0x46, 0x6E, 0xE6, 0xF2, 0x3B, 0x09, + 0xFF, 0x0D, 0x4B, 0xC8, 0xCB, 0x59, 0xB6, 0x00, + 0xC2, 0x3C, 0x4C, 0xEA, 0x66, 0x86, 0x59, 0x82, + 0xAB, 0x31, 0xB6, 0xFF, 0xAE, 0xF4, 0x91, 0x7C, + 0x45, 0x28, 0xDB, 0x03, 0xF7, 0x08, 0x51, 0xC9, + 0xCD, 0xCD, 0xD3, 0xC8, 0x4D, 0x9A, 0x23, 0x8C, + 0xFC, 0x06, 0x6F, 0x4A, 0x2E, 0xDE, 0x66, 0xCF, + 0xD0, 0xCC, 0x94, 0x2D, 0x53, 0xF1, 0x56, 0x5D, + 0xB1, 0x33, 0xCF, 0x39, 0x8F, 0x80, 0x14, 0x21, + 0xF5, 0x3C, 0xCE, 0x7E, 0xAE, 0x91, 0x60, 0x30, + 0xE8, 0x3B, 0xE8, 0x23, 0x6F, 0x82, 0x2F, 0xCA, + 0x64, 0x1C, 0x47, 0x3D, 0x56, 0xD6, 0xB8, 0xFD, + 0x78, 0xBD, 0x23, 0x0D, 0x01, 0xBB, 0x12, 0x9C, + 0xD2, 0x58, 0x00, 0xAC, 0x62, 0xB5, 0x4D, 0x68, + 0x61, 0xA4, 0x7B, 0xFC, 0xF3, 0x95, 0x3A, 0x2C, + 0x05, 0x7F, 0x1F, 0x42, 0xD7, 0xCF, 0xC5, 0xEC, + 0x83, 0xC0, 0x6A, 0x1E, 0x0D, 0x7B, 0x3B, 0x32, + 0x76, 0x75, 0xF9, 0x1A, 0x5D, 0x01, 0x9A, 0x6C, + 0x19, 0xC7, 0xFF, 0x1C, 0x60, 0xE1, 0x58, 0x6A, + 0x13, 0x86, 0x43, 0xCF, 0xB7, 0x6B, 0x30, 0xEF, + 0x3E, 0x33, 0xF2, 0xAB, 0xBE, 0xAC, 0xA0, 0xDE, + 0xD0, 0x58, 0xC4, 0x83, 0x77, 0x09, 0x4F, 0x84, + 0x24, 0xEF, 0x68, 0x2F, 0xA0, 0x6C, 0x60, 0x24, + 0x5D, 0xFF, 0xF5, 0x4C, 0xD3, 0xD7, 0x58, 0xC3, + 0x0C, 0xA9, 0x41, 0x56, 0xDD, 0x88, 0xFE, 0xB9, + 0xA8, 0xAD, 0x8F, 0xFB, 0x9A, 0x49, 0xE7, 0xCF, + 0x66, 0x9E, 0x7B, 0xCF, 0x60, 0x25, 0xAB, 0x25, + 0x5C, 0x25, 0x3C, 0xC0, 0xB1, 0xAE, 0x76, 0xC9, + 0xB1, 0xFC, 0x2A, 0xBE, 0x03, 0x54, 0xE6, 0x08, + 0xBC, 0xC7, 0xE9, 0xF9, 0x7D, 0x2B, 0x65, 0x9A, + 0x84, 0x78, 0x31, 0xA2, 0x63, 0x13, 0xF1, 0x05, + 0xBD, 0xE7, 0x4A, 0xEA, 0x6E, 0x30, 0xFC, 0x99, + 0x17, 0xE5, 0xA4, 0x9F, 0xF5, 0x59, 0xB1, 0x1F, + 0xAB, 0xF7, 0x91, 0x81, 0x0E, 0xB8, 0x8E, 0x95, + 0x8B, 0x8D, 0x1D, 0xD3, 0x68, 0x79, 0x48, 0x07, + 0xA4, 0xF8, 0xAD, 0xDD, 0x64, 0x40, 0x3B, 0xCC, + 0x78, 0x5C, 0xD9, 0x2E, 0xF7, 0x9C, 0x1B, 0x1E, + 0x89, 0x9A, 0x68, 0x8F, 0x22, 0xB5, 0x3E, 0xFC, + 0xA2, 0x23, 0x11, 0x34, 0xCE, 0x15, 0xA4, 0xB6, + 0xD8, 0x6D, 0x8F, 0x94, 0xEF, 0x20, 0x3D, 0x16, + 0xF1, 0x1A, 0xCD, 0x5F, 0xCA, 0x28, 0x44, 0x7A, + 0x80, 0x96, 0x93, 0x67, 0xAA, 0xE2, 0x06, 0x75, + 0x4B, 0xAF, 0x6E, 0xCB, 0x4A, 0x56, 0x45, 0x32, + 0xDE, 0x2D, 0x13, 0xB8, 0x0B, 0xFB, 0xD5, 0x3F, + 0x46, 0xC0, 0xDD, 0x7A, 0x7C, 0xFE, 0x12, 0xD7, + 0xC1, 0x51, 0x21, 0x0F, 0xF7, 0x9B, 0x3C, 0x6F, + 0x4B, 0x52, 0x72, 0x40, 0xE2, 0x76, 0x5B, 0x81, + 0x05, 0xEE, 0x68, 0xC1, 0x28, 0xE2, 0x11, 0xB2, + 0xA6, 0xA3, 0x47, 0x7D, 0xC6, 0x80, 0x13, 0xB8, + 0xE5, 0x99, 0x41, 0x7A, 0x8C, 0xD4, 0xB2, 0x2A, + 0x6C, 0xED, 0x8C, 0x7B, 0xE3, 0x8A, 0x88, 0x93, + 0x29, 0xF3, 0x7B, 0x4E, 0x03, 0x1E, 0xC9, 0x7C, + 0x75, 0x44, 0xAD, 0xF9, 0xAC, 0xB5, 0x22, 0xFD, + 0x93, 0x4F, 0x41, 0x95, 0x99, 0x17, 0xCE, 0x03, + 0xB1, 0x1C, 0xFF, 0x7A, 0xE5, 0xED, 0x2A, 0xC7, + 0x49, 0xE3, 0x8A, 0x39, 0x07, 0x7E, 0x19, 0x42, + 0x21, 0xA6, 0x61, 0xA2, 0x0C, 0xA3, 0x28, 0x08, + 0x77, 0x95, 0xB3, 0x7C, 0xB0, 0xBD, 0x90, 0xB5, + 0xC7, 0x08, 0x8B, 0x82, 0xC1, 0xFF, 0x92, 0x2E, + 0x71, 0xAC, 0x14, 0x8A, 0xC5, 0xE2, 0x6D, 0xEE, + 0xA9, 0x52, 0x06, 0xFE, 0xEB, 0xC8, 0x4A, 0x92, + 0xCC, 0x3B, 0x27, 0x22, 0xE0, 0x4C, 0x17, 0xEB, + 0x06, 0x88, 0x59, 0xBE, 0x25, 0x6C, 0x60, 0xAC, + 0x35, 0x30, 0x30, 0x82, 0x83, 0x02, 0x1F, 0x96, + 0xB5, 0xFD, 0x9C, 0xFA, 0x3E, 0xB8, 0x9D, 0x35, + 0x55, 0x4E, 0xCB, 0x34, 0x3F, 0x25, 0x08, 0x07, + 0xCA, 0x34, 0x39, 0xD2, 0xA3, 0xD5, 0xD4, 0x7A, + 0xA4, 0xC7, 0xC8, 0x29, 0xC3, 0xEE, 0x36, 0x5E, + 0x16, 0xFD, 0x71, 0xC4, 0xB4, 0x04, 0xF2, 0x38, + 0x37, 0x69, 0x81, 0x0C, 0xC0, 0x52, 0x1C, 0x1D, + 0xC4, 0xFF, 0x74, 0x1B, 0xD4, 0x50, 0x59, 0x74, + 0x92, 0x50, 0xCC, 0x34, 0xED, 0x1C, 0x23, 0xE1, + 0x36, 0x2B, 0x92, 0x32, 0xD6, 0xAC, 0x21, 0x65, + 0x9E, 0x4C, 0x51, 0x5F, 0x5F, 0xCB, 0xE9, 0x3C, + 0x7F, 0x3A, 0x74, 0xB6, 0x05, 0x30, 0x41, 0x1F, + 0x76, 0xEA, 0x20, 0xAA, 0x5E, 0xC2, 0xE3, 0xBA, + 0xD9, 0x86, 0x6B, 0x8E, 0x0D, 0xEB, 0xB6, 0xCF, + 0xE0, 0xE8, 0xF5, 0xFD, 0xE4, 0x3C, 0x29, 0x7C, + 0xD9, 0xDB, 0xCA, 0xA7, 0x87, 0xC5, 0xE0, 0x65, + 0x47, 0xBB, 0x73, 0xEE, 0xF9, 0xE7, 0xA4, 0x42, + 0x56, 0xD7, 0xCA, 0x0D, 0x6A, 0xAB, 0x70, 0xCA, + 0x6C, 0x2B, 0x59, 0x3C, 0x8B, 0x5A, 0x19, 0x90, + 0xC7, 0x50, 0x96, 0x21, 0x04, 0x06, 0x7A, 0x6B, + 0x99, 0xF3, 0x73, 0x7A, 0x02, 0xEC, 0xB5, 0x1B, + 0x32, 0xD7, 0xCA, 0x56, 0x66, 0xD4, 0xC1, 0xB6, + 0x39, 0x8A, 0x10, 0x29, 0x0C, 0x81, 0x80, 0x72, + 0x8E, 0x8C, 0x0F, 0x1E, 0x93, 0x61, 0xF7, 0x00, + 0xA1, 0xA4, 0x65, 0x5F, 0xD4, 0x4E, 0xD9, 0x62, + 0x27, 0x65, 0xF9, 0x21, 0xE3, 0x8C, 0xC8, 0xFC, + 0x14, 0xC7, 0x08, 0x8C, 0x9C, 0x0C, 0xFD, 0x97, + 0x08, 0x4D, 0x8B, 0x41, 0x47, 0x76, 0x68, 0x34, + 0x86, 0xC1, 0x64, 0xC4, 0xB9, 0x0B, 0x83, 0x36, + 0x77, 0xB9, 0x63, 0x8D, 0x04, 0xC0, 0x60, 0x2B, + 0x15, 0x2D, 0x98, 0xA6, 0x84, 0xF0, 0x28, 0x91, + 0x88, 0x63, 0x1F, 0x01, 0x2E, 0xE1, 0x60, 0xB1, + 0x17, 0xB8, 0x2A, 0x65, 0x94, 0x46, 0x23, 0xAD, + 0x2D, 0xA2, 0x89, 0x4C, 0xFC, 0x58, 0x8C, 0x8B, + 0x34, 0x04, 0x37, 0xF0, 0x5D, 0xC4, 0xA6, 0x0B, + 0xF8, 0x0C, 0xF8, 0x69, 0xCD, 0xC2, 0xDD, 0x9B, + 0x1F, 0x76, 0xE5, 0xAE, 0x54, 0x30, 0x0C, 0xD9, + 0x58, 0x22, 0x98, 0x0F, 0x93, 0xDB, 0x31, 0xB0, + 0x1A, 0x6A, 0xE1, 0xE1, 0xA7, 0x3C, 0x2B, 0x83, + 0x49, 0x7D, 0x40, 0x94, 0x09, 0xEF, 0x40, 0xC3, + 0x65, 0x2B, 0xE5, 0x40, 0x9A, 0xE7, 0x19, 0xBE, + 0x3E, 0xF2, 0x1C, 0x4B, 0x6D, 0x41, 0x20, 0x42, + 0xE5, 0x8E, 0xB4, 0x8B, 0x44, 0xF7, 0x06, 0xB6, + 0x00, 0x50, 0x58, 0x69, 0xA4, 0xA3, 0x26, 0x10, + 0x2F, 0x79, 0xA4, 0xA0, 0xA6, 0xC9, 0x65, 0x14, + 0xC5, 0xDC, 0x1D, 0x77, 0x0D, 0xA8, 0xAB, 0xF4, + 0x60, 0x41, 0xED, 0xED, 0x93, 0x82, 0xE0, 0xA4, + 0x74, 0xBB, 0xF6, 0xE9, 0xAA, 0xDB, 0x73, 0x3A, + 0x0C, 0x50, 0xEF, 0x23, 0x65, 0x98, 0xA1, 0x2A, + 0xF9, 0x20, 0xF4, 0xFF, 0x60, 0x53, 0x32, 0x06, + 0x8E, 0xC3, 0x96, 0xDF, 0x2F, 0xC0, 0xEF, 0x26, + 0xB0, 0x83, 0x29, 0x5F, 0xDB, 0x4A, 0x0B, 0x42, + 0x97, 0x8B, 0xFC, 0x6D, 0xAA, 0x13, 0xF3, 0x57, + 0xEB, 0x48, 0xF4, 0x1D, 0xD1, 0x75, 0x44, 0x0E, + 0xEB, 0x5E, 0xB6, 0x79, 0xED, 0xCF, 0xC6, 0xDE, + 0x5D, 0x1D, 0x09, 0x22, 0x51, 0x40, 0x52, 0x58, + 0xC0, 0x98, 0x8B, 0xE1, 0xE3, 0x91, 0x3A, 0xEE, + 0x2D, 0xBE, 0xCB, 0x77, 0x35, 0xFF, 0x03, 0xA8, + 0x6A, 0x8C, 0xC2, 0x88, 0x2F, 0x59, 0x39, 0x72, + 0x31, 0xFA, 0x90, 0xE3, 0x54, 0x38, 0xE0, 0xE5, + 0xB2, 0x65, 0xDC, 0xD7, 0x0B, 0x03, 0x64, 0xCF, + 0xCA, 0x70, 0x30, 0x0B, 0x36, 0x8B, 0x9A, 0xB2, + 0x6F, 0x42, 0x49, 0xB1, 0x62, 0xED, 0x4D, 0xB3, + 0x75, 0xAF, 0x58, 0xE6, 0x7D, 0xC6, 0x75, 0x13, + 0xB7, 0x9B, 0xE4, 0x3B, 0x79, 0xC3, 0x35, 0x79, + 0x9F, 0x21, 0x08, 0x9A, 0x59, 0xC7, 0x6F, 0x2C, + 0x85, 0x53, 0x8B, 0xF6, 0xAE, 0x02, 0x03, 0x5E, + 0x42, 0xF9, 0x0F, 0x04, 0xD7, 0x12, 0x22, 0x41, + 0x1A, 0x34, 0xD7, 0x27, 0x2C, 0x84, 0xFF, 0x74, + 0x43, 0x7A, 0x85, 0x26, 0x00, 0xD3, 0x72, 0x62, + 0xFB, 0x8D, 0x6F, 0x40, 0x0C, 0x06, 0xCF, 0xC8, + 0x9A, 0x5D, 0xD2, 0x6B, 0x55, 0x05, 0x25, 0xCF, + 0xF2, 0xEE, 0x4D, 0x3C, 0x79, 0xD3, 0xDE, 0x72, + 0x36, 0x9B, 0xA3, 0x53, 0xCF, 0xF6, 0x4D, 0xAD, + 0x10, 0xEB, 0xF0, 0x91, 0x34, 0x21, 0x01, 0x04, + 0x84, 0xC5, 0xA2, 0x01, 0x60, 0x6E, 0x7E, 0xE8, + 0x33, 0xE7, 0xEA, 0xF8, 0x09, 0x44, 0x7C, 0x40, + 0x63, 0xDF, 0x47, 0xA5, 0x6D, 0x78, 0xDF, 0x0E, + 0x18, 0x4D, 0x62, 0x09, 0xCD, 0x43, 0x53, 0xFB, + 0x67, 0x2C, 0x52, 0xC4, 0x35, 0x8E, 0xD7, 0x06, + 0xFC, 0x1C, 0x3A, 0xBA, 0xF3, 0xFE, 0xAF, 0x27, + 0x0B, 0x29, 0xA3, 0x3E, 0xA4, 0xE1, 0xE3, 0x70, + 0x7C, 0x05, 0x49, 0xDA, 0xE5, 0x37, 0xAB, 0xF3, + 0xF4, 0x7B, 0xED, 0xFB, 0x83, 0x47, 0x26, 0xD7, + 0xEE, 0x81, 0x25, 0xF0, 0xD9, 0x23, 0xFE, 0xFD, + 0xC1, 0xBE, 0x76, 0x20, 0x63, 0xB6, 0x74, 0xC6, + 0xF3, 0xCF, 0x33, 0x56, 0x62, 0x89, 0x50, 0xA9, + 0x9D, 0xA6, 0x2C, 0xAD, 0x8A, 0xFF, 0x0A, 0x4B, + 0xDA, 0x38, 0x6C, 0xD4, 0x5D, 0x5D, 0x0D, 0x71, + 0x8A, 0x26, 0xEE, 0x00, 0x11, 0x69, 0xEC, 0x1A, + 0xEA, 0xEE, 0x42, 0x06, 0x9A, 0xBF, 0xBF, 0xE3, + 0xA8, 0x87, 0xEA, 0x68, 0x2F, 0x30, 0xE4, 0x31, + 0xB8, 0x49, 0x22, 0x9E, 0x9E, 0xCA, 0xAB, 0x0C, + 0x7A, 0x57, 0x51, 0x50, 0xCF, 0x27, 0xCD, 0x01, + 0x4D, 0x1B, 0x7C, 0x5C, 0xBE, 0xC7, 0x7D, 0x47, + 0xF2, 0xFF, 0x8E, 0xA2, 0xDE, 0xB4, 0xC0, 0x6B, + 0x70, 0x63, 0x54, 0x52, 0x21, 0x6B, 0xDA, 0xBD, + 0xD6, 0xC8, 0xF7, 0x33, 0xAD, 0x13, 0x6C, 0x91, + 0x80, 0xCC, 0x6C, 0x99, 0x97, 0xE0, 0x59, 0x6E, + 0x83, 0x72, 0xF1, 0x19, 0xE5, 0xDD, 0xB3, 0x49, + 0xE3, 0x50, 0xD7, 0x1B, 0x68, 0x5E, 0xE6, 0x6D, + 0x5A, 0x7F, 0x59, 0xFA, 0x37, 0xE4, 0xDD, 0xEF, + 0xE4, 0x4B, 0xBF, 0x78, 0x25, 0x89, 0x49, 0xA4, + 0x1E, 0x51, 0x43, 0xA4, 0x43, 0xBD, 0x6A, 0x5A, + 0x1D, 0xCC, 0x9D, 0x14, 0xC1, 0x15, 0xDC, 0x1A, + 0x2F, 0xF1, 0x82, 0x5C, 0x13, 0x23, 0x3C, 0x72, + 0xA0, 0xA8, 0x3A, 0x70, 0x99, 0xD5, 0x29, 0xF4, + 0x57, 0x8C, 0xAB, 0xE7, 0x1A, 0xC9, 0x79, 0x53, + 0x5B, 0x55, 0x0D, 0xD9, 0x10, 0xAD, 0xD7, 0xD5, + 0xB5, 0x9C, 0xFC, 0xC9, 0x0B, 0x73, 0x23, 0xA2, + 0x88, 0x68, 0x1B, 0x35, 0x8F, 0x95, 0x92, 0x4B, + 0x11, 0x37, 0x6A, 0xA8, 0xBF, 0x53, 0x0A, 0xEE, + 0x56, 0x01, 0xE0, 0x61, 0x38, 0x4D, 0x7E, 0xC7, + 0xCE, 0xC2, 0xBE, 0x20, 0x1E, 0x00, 0xC5, 0x2B, + 0x9C, 0x41, 0x03, 0xC4, 0xD8, 0xD5, 0xB9, 0x8F, + 0x98, 0xF9, 0x06, 0x6B, 0xC1, 0x71, 0x0E, 0x49, + 0xA4, 0xA3, 0x27, 0xD3, 0x08, 0xAF, 0xA2, 0xFB, + 0xB6, 0xC8, 0xB4, 0x30, 0xC8, 0x4C, 0x97, 0x2F, + 0x52, 0x1E, 0xBF, 0x30, 0x04, 0xE1, 0x47, 0x2D, + 0x7D, 0xB2, 0xC4, 0x8B, 0x41, 0x7A, 0xC7, 0xBA, + 0x6E, 0x29, 0x57, 0x33, 0xC2, 0xFB, 0xDE, 0x8F, + 0x31, 0x2B, 0xD4, 0xD1, 0x71, 0x28, 0x81, 0x12, + 0x08, 0x28, 0xAF, 0xBB, 0x1F, 0x1F, 0x24, 0x6D, + 0xB8, 0xAD, 0xBF, 0x72, 0x1F, 0x1F, 0xB9, 0x2A, + 0x5B, 0xD8, 0x12, 0x07, 0x5D, 0xEA, 0xDC, 0x15, + 0x87, 0xC0, 0xE5, 0xE3, 0x3A, 0xE1, 0xF3, 0xF1, + 0xA5, 0x5A, 0x16, 0x94, 0xBC, 0x7A, 0xBF, 0x9F, + 0x6F, 0x7E, 0x1D, 0xD1, 0xE8, 0x27, 0xEA, 0x17, + 0xD6, 0xCD, 0x4C, 0x9B, 0x40, 0x3C, 0xA7, 0xEA, + 0x53, 0x04, 0x7B, 0x0A, 0xC7, 0x58, 0x54, 0x92, + 0x70, 0x14, 0x0C, 0x8D, 0xB6, 0x2C, 0xA7, 0xA0, + 0x4C, 0xF1, 0x68, 0x7E, 0xFC, 0xA0, 0x7E, 0x71, + 0x03, 0x88, 0xAD, 0x0B, 0x97, 0x8C, 0xD9, 0x40, + 0x51, 0xD8, 0xE2, 0x41, 0x16, 0xBC, 0x03, 0xA7, + 0xB6, 0x3C, 0x85, 0xB8, 0x24, 0x7C, 0x11, 0x9D, + 0x55, 0x82, 0x19, 0x5F, 0x93, 0x5E, 0x4C, 0xBD, + 0x4B, 0x15, 0x66, 0xBE, 0x1F, 0x5D, 0xF4, 0xBD, + 0xA7, 0xE1, 0x59, 0x2A, 0xAB, 0x54, 0xDF, 0x22, + 0x7E, 0x21, 0xDF, 0x99, 0x57, 0x1D, 0xA2, 0xDF, + 0x04, 0xEE, 0xC1, 0x97, 0x53, 0xD9, 0x66, 0xE7, + 0x95, 0xD8, 0xB4, 0x1E, 0xFB, 0x59, 0x2F, 0xBF, + 0x10, 0x33, 0x9F, 0xA2, 0xA2, 0x10, 0x6D, 0x6D, + 0x03, 0x0A, 0xEB, 0x30, 0x44, 0x32, 0x9E, 0x5E, + 0x0C, 0x3B, 0xDC, 0xA9, 0x33, 0x44, 0x89, 0xC1, + 0x26, 0x3E, 0x7D, 0x79, 0xB9, 0x36, 0xFC, 0xDA, + 0x9C, 0xA2, 0x93, 0x6F, 0x7E, 0x28, 0x06, 0xF7, + 0x55, 0x99, 0x74, 0xEE, 0xD9, 0x23, 0xD6, 0x51, + 0xA3, 0x8E, 0xA5, 0x46, 0x03, 0xD4, 0xAB, 0x81, + 0x10, 0x61, 0x09, 0x13, 0xF9, 0x95, 0xF7, 0x74, + 0x57, 0x55, 0x78, 0x65, 0x63, 0x73, 0x22, 0xD2, + 0x73, 0xEB, 0x4B, 0xAE, 0xD4, 0xD0, 0x8D, 0x5C, + 0x34, 0x3C, 0xD6, 0xF9, 0x85, 0xF5, 0x85, 0x0C, + 0xA2, 0xDC, 0x15, 0xE7, 0xBA, 0xCB, 0xD7, 0x54, + 0x6E, 0x47, 0x71, 0xFE, 0xCC, 0xD7, 0x12, 0x55, + 0x5C, 0x87, 0x81, 0x58, 0x8B, 0xE2, 0x24, 0x5D, + 0x13, 0x65, 0x02, 0xC9, 0x2B, 0x27, 0xE9, 0xFC, + 0x67, 0x36, 0x17, 0xB1, 0x7D, 0xDA, 0x2D, 0x8C, + 0x84, 0xE3, 0xEA, 0x6F, 0x18, 0x8A, 0x3A, 0xBE, + 0x7F, 0xF2, 0x35, 0x74, 0x72, 0x0C, 0x6D, 0xFF, + 0x0F, 0x23, 0xFF, 0xED, 0x53, 0x2F, 0xCF, 0x66, + 0xF3, 0x96, 0x19, 0xE2, 0x06, 0x12, 0xAA, 0x7A, + 0x16, 0xCF, 0xCB, 0xEF, 0x21, 0x62, 0x80, 0x3A, + 0xF6, 0x8B, 0x68, 0x94, 0x30, 0xDB, 0x3D, 0xF5, + 0x9F, 0x6F, 0x86, 0x3F, 0x7F, 0x35, 0xB7, 0xCC, + 0x71, 0xA8, 0x8C, 0x6A, 0x8A, 0x4F, 0xB7, 0xE0, + 0x5A, 0xA1, 0xB4, 0x25, 0xF8, 0x90, 0x72, 0xDA, + 0x28, 0xAB, 0x3A, 0xDC, 0xDB, 0x53, 0xC3, 0xC4, + 0x3A, 0x4C, 0x89, 0xF2, 0xCE, 0x4B, 0x32, 0x76, + 0xE0, 0xAC, 0x3E, 0xFC, 0x57, 0x76, 0xEB, 0x00, + 0x69, 0x63, 0x0D, 0xB1, 0x72, 0xE2, 0x1C, 0x9B, + 0x59, 0xB6, 0x31, 0x3A, 0x58, 0x0B, 0x3A, 0xB9, + 0x45, 0xA6, 0x6B, 0xC8, 0xDE, 0xC2, 0xB6, 0x56, + 0x00, 0xBB, 0xA8, 0xFA, 0xA5, 0xBD, 0x0D, 0xB9, + 0x2D, 0x0A, 0xAF, 0x35, 0x45, 0x78, 0xD9, 0x1D, + 0x4C, 0xE5, 0x7F, 0x55, 0x72, 0x07, 0xCD, 0x75, + 0xA3, 0x20, 0x95, 0x00, 0xDF, 0x60, 0x46, 0x8A, + 0xE3, 0xBF, 0x70, 0x3C, 0x69, 0xDC, 0xD5, 0xD0, + 0x66, 0x96, 0x76, 0x48, 0xB4, 0x32, 0x86, 0xE5, + 0x0B, 0x1E, 0xFD, 0xEA, 0x86, 0xD6, 0x32, 0xD6, + 0x01, 0x8F, 0xFA, 0x18, 0x5C, 0x84, 0x28, 0x88, + 0x2C, 0x8F, 0x5C, 0x86, 0x2E, 0x55, 0x8A, 0x01, + 0x1E, 0x88, 0x6D, 0x83, 0x8E, 0xE0, 0xEF, 0xCB, + 0x16, 0xCD, 0xEE, 0xB6, 0xA9, 0x8D, 0x17, 0x8F, + 0xE1, 0xE4, 0xF2, 0x61, 0x2C, 0xB0, 0x1E, 0x00, + 0x11, 0x07, 0xEC, 0x9A, 0xE1, 0xB4, 0xAD, 0x12, + 0xE9, 0x46, 0x44, 0x78, 0xA9, 0xDF, 0x79, 0x08, + 0x8F, 0x75, 0x8A, 0x7C, 0xAD, 0xAC, 0x9F, 0x96, + 0x96, 0xEA, 0x9A, 0xCE, 0xA6, 0x9E, 0xCA, 0x85, + 0xA3, 0x25, 0x64, 0x10, 0x03, 0xB9, 0x64, 0x2F, + 0xE4, 0x1E, 0x0E, 0xB8, 0x15, 0xD3, 0x50, 0xA1, + 0x70, 0x65, 0xCC, 0xDC, 0xC0, 0xE7, 0x5E, 0x3D, + 0x78, 0x38, 0x72, 0xB5, 0xBA, 0x8A, 0x5A, 0xE3, + 0x1A, 0x26, 0xFA, 0x16, 0xC4, 0x34, 0xC4, 0xA9, + 0xFE, 0xED, 0xA7, 0x00, 0x1D, 0xAF, 0x73, 0x8F, + 0x66, 0xB4, 0xA7, 0x30, 0x34, 0x37, 0x30, 0x23, + 0x1C, 0xCE, 0x76, 0x6B, 0x60, 0x25, 0xC4, 0x21, + 0xC0, 0x2F, 0x6F, 0x2D, 0xD1, 0x19, 0xE6, 0x66, + 0x41, 0x8F, 0x73, 0x64, 0xF4, 0x0D, 0xDC, 0x88, + 0x23, 0x38, 0x3F, 0xAB, 0x94, 0x5B, 0x92, 0x17, + 0x96, 0x62, 0xAC, 0x50, 0xD1, 0x42, 0xEE, 0x0E, + 0x75, 0x44, 0xE3, 0x0D, 0xA4, 0xCB, 0x70, 0x32, + 0x6A, 0x07, 0xB6, 0xF2, 0x62, 0x6E, 0xBC, 0xFA, + 0x9C, 0xB3, 0x51, 0x50, 0xA2, 0x31, 0xEE, 0xC4, + 0xB8, 0x30, 0x29, 0xA7, 0x91, 0x16, 0x1F, 0x5D, + 0x2E, 0x99, 0x29, 0x27, 0xC4, 0x8C, 0x45, 0x95, + 0xF4, 0x16, 0xB3, 0x9E, 0x18, 0xA1, 0xD7, 0x2D, + 0x14, 0xD2, 0x1A, 0x04, 0x59, 0x2C, 0x7B, 0xC8, + 0xDE, 0x94, 0x26, 0x0A, 0x90, 0xF1, 0x00, 0x14, + 0xA0, 0x71, 0x92, 0x78, 0x71, 0x9E, 0xA2, 0x12, + 0xD5, 0x0D, 0xC8, 0x88, 0x06, 0x05, 0xF8, 0xDA, + 0x60, 0xD1, 0x71, 0xE8, 0x62, 0x35, 0x33, 0x30, + 0xD6, 0x5D, 0xF4, 0x25, 0x00, 0x5C, 0x18, 0x82, + 0x67, 0x07, 0xD6, 0xF8, 0xCF, 0x86, 0x79, 0xDF, + 0xF2, 0x95, 0xF4, 0xF9, 0xE1, 0x4C, 0x16, 0x7B, + 0x8D, 0xAB, 0x2B, 0x88, 0xAD, 0xBA, 0xF0, 0x50, + 0x2E, 0x93, 0x49, 0x34, 0xBC, 0x3A, 0x5C, 0x44, + 0xFA, 0xB4, 0x43, 0x54, 0x32, 0xE7, 0xF5, 0xCA, + 0x41, 0xE7, 0x84, 0xCE, 0x28, 0x06, 0x58, 0xA9, + 0xED, 0x9B, 0x98, 0xEC, 0x20, 0x33, 0x25, 0xCE, + 0xBA, 0xB6, 0x0C, 0xCB, 0x0D, 0xD2, 0x61, 0x71, + 0x59, 0x86, 0x97, 0xA0, 0xCA, 0xFA, 0x14, 0x03, + 0x87, 0xAE, 0x90, 0xD4, 0x6E, 0xAC, 0x6A, 0xA8, + 0xDD, 0x58, 0x66, 0x3E, 0xA5, 0x90, 0xB1, 0x22, + 0x8C, 0x28, 0x2F, 0x28, 0x63, 0x5D, 0x65, 0xFE, + 0x18, 0xAF, 0x17, 0x38, 0xCE, 0x6E, 0x02, 0x77, + 0x4C, 0xC2, 0x96, 0xA9, 0xBB, 0x89, 0x74, 0x58, + 0x97, 0xC4, 0xF7, 0xB3, 0x57, 0xC5, 0x92, 0x47, + 0x21, 0x09, 0xB2, 0xA5, 0xC3, 0x7D, 0xC6, 0x02, + 0x1A, 0x92, 0x0E, 0x3D, 0xEE, 0x91, 0x80, 0x6D, + 0xB0, 0xD0, 0xD5, 0x69, 0x5C, 0x52, 0x38, 0x98, + 0xA6, 0x85, 0xA9, 0xA3, 0x64, 0x77, 0x15, 0x80, + 0xDE, 0x83, 0x83, 0x9A, 0x16, 0x27, 0x22, 0xF2, + 0x59, 0x25, 0x54, 0x91, 0x82, 0x7B, 0xCA, 0x24, + 0x03, 0x50, 0x4C, 0xE7, 0x23, 0xA8, 0x23, 0x4A, + 0x4A, 0xE9, 0x5D, 0x91, 0xDE, 0x19, 0xA3, 0xFD, + 0xB6, 0x8B, 0x01, 0xF4, 0xD0, 0x4E, 0xE6, 0x2C, + 0xF8, 0xD5, 0x82, 0xC7, 0xCF, 0x10, 0xBE, 0xBA, + 0x89, 0xE8, 0x7F, 0xE2, 0x4F, 0x80, 0xA8, 0x28, + 0x62, 0x1A, 0x86, 0x7C, 0x66, 0x91, 0x82, 0x2E, + 0x18, 0x4B, 0x41, 0x63, 0x41, 0x0B, 0x7F, 0xF2, + 0x61, 0xAD, 0x6F, 0xAC, 0x1A, 0x10, 0x3B, 0x90, + 0xEE, 0xCC, 0x8A, 0x68, 0x26, 0x48, 0x32, 0x16, + 0x1A, 0x46, 0x07, 0xED, 0x15, 0xE8, 0x2B, 0x50, + 0x04, 0xA5, 0x81, 0xFE, 0xD8, 0xEA, 0x24, 0x86, + 0x25, 0x63, 0xD7, 0x4C, 0x61, 0xD7, 0x8E, 0xA8, + 0xC1, 0x22, 0xCE, 0x89, 0xB2, 0xCD, 0xD1, 0xC0, + 0x56, 0x7A, 0x35, 0x65, 0xD8, 0xB6, 0xE4, 0xB1, + 0x93, 0x0F, 0x94, 0xE5, 0x69, 0x32, 0xB7, 0x91, + 0x21, 0xB1, 0x2A, 0xBE, 0xF2, 0xF8, 0x94, 0xB7, + 0x09, 0x90, 0x6B, 0x12, 0x7D, 0x1B, 0xDA, 0xCE, + 0xE0, 0xA6, 0x8B, 0xBE, 0x33, 0x7B, 0xF3, 0xF7, + 0xED, 0xC3, 0xEC, 0x01, 0xDC, 0x1B, 0x70, 0x9C, + 0xEB, 0xFA, 0xED, 0x16, 0xB3, 0x87, 0x75, 0xB5, + 0x26, 0x83, 0x90, 0x60, 0x73, 0x03, 0x63, 0xCA, + 0x20, 0xCD, 0x57, 0x85, 0x4C, 0xA4, 0x4D, 0xEE, + 0x8A, 0x41, 0x75, 0x01, 0x1B, 0x51, 0x8A, 0x9D, + 0xC1, 0x0E, 0x33, 0xBB, 0x9C, 0xC4, 0x4B, 0x4B, + 0x04, 0x26, 0x1F, 0x0A, 0x05, 0x4F, 0xC4, 0xDA, + 0xB2, 0x12, 0xA5, 0x96, 0x6E, 0x6E, 0x97, 0xEC, + 0xF8, 0xB2, 0x64, 0xB7, 0x3F, 0x85, 0x6F, 0x0E, + 0xD8, 0x33, 0x4B, 0xA7, 0x7A, 0x1C, 0xCB, 0x2F, + 0xE3, 0xA8, 0xD9, 0xC0, 0x4B, 0xDC, 0xE7, 0xC1, + 0x79, 0xCA, 0xFA, 0x7B, 0xDE, 0x20, 0xEA, 0x06, + 0xBE, 0x8A, 0x99, 0x47, 0x04, 0x66, 0xD5, 0x7B, + 0xD2, 0xDF, 0x0B, 0x8B, 0x1D, 0x63, 0xE4, 0x38, + 0xDB, 0x9B, 0xA5, 0x3A, 0xA9, 0x0E, 0xAE, 0xAC, + 0x47, 0xD5, 0x4E, 0xF6, 0xDF, 0x27, 0x5D, 0xE4, + 0x0A, 0x36, 0xC9, 0xCA, 0x8C, 0x1F, 0x48, 0xCA, + 0xD8, 0x10, 0xE3, 0x58, 0x08, 0x47, 0x0E, 0xB9, + 0xF1, 0x48, 0xAE, 0xF4, 0x42, 0x3F, 0x2A, 0x7D, + 0xB8, 0xEA, 0x11, 0x0C, 0x36, 0xE4, 0x83, 0x2B, + 0x15, 0x89, 0xB8, 0xB9, 0xCB, 0x0D, 0xA4, 0xDA, + 0x2C, 0xAA, 0xF0, 0x92, 0x56, 0x4D, 0xA1, 0x7B, + 0xAA, 0x78, 0xC4, 0x5B, 0x19, 0xB5, 0x39, 0xCB, + 0xAA, 0x09, 0x99, 0x30, 0x32, 0xB2, 0x8F, 0x93, + 0xB6, 0x89, 0x49, 0x99, 0x0D, 0x1A, 0xD6, 0xA1, + 0x96, 0x3D, 0x1A, 0x98, 0xDE, 0xF1, 0xC8, 0xEE, + 0x9A, 0x03, 0x95, 0xC8, 0xD4, 0x75, 0x6F, 0x8C, + 0x8B, 0x0A, 0x17, 0xEE, 0x6A, 0xFA, 0x33, 0x26, + 0xD2, 0x52, 0x41, 0xD8, 0x8B, 0xAD, 0xCF, 0x87, + 0x47, 0x0A, 0xEB, 0x1D, 0x7A, 0xF6, 0x84, 0x70, + 0xD9, 0xA7, 0x06, 0xEC, 0x73, 0xCE, 0x46, 0x0B, + 0x4E, 0xB0, 0x26, 0xBE, 0x93, 0xD9, 0xC2, 0x1D, + 0x2B, 0xC7, 0x64, 0x9F, 0x1B, 0x68, 0x43, 0xCD, + 0xE9, 0x95, 0x3B, 0xD9, 0xFB, 0xFF, 0xCC, 0x2A, + 0x7F, 0x84, 0x4F, 0x0A, 0x07, 0x0F, 0xFA, 0x80, + 0x65, 0x48, 0x29, 0x5C, 0x63, 0x0B, 0x5F, 0x0C, + 0x03, 0xEF, 0x3E, 0x87, 0x0A, 0x6F, 0x44, 0x7A, + 0x5E, 0xBD, 0xD5, 0xF3, 0x13, 0x9D, 0x6B, 0x38, + 0x7E, 0x78, 0xDB, 0x36, 0xF6, 0xD7, 0x8E, 0x4E, + 0x20, 0xF8, 0xDC, 0x1F, 0xCF, 0xEA, 0x1B, 0x04, + 0x52, 0x62, 0xDF, 0xA4, 0xCC, 0xEE, 0x89, 0x67, + 0x3C, 0x56, 0x5B, 0xE1, 0x0B, 0xB3, 0x31, 0xDD, + 0xEE, 0x53, 0xC7, 0x9F, 0xE6, 0x1F, 0x87, 0x7C, + 0x06, 0xD5, 0xC2, 0xC2, 0xEC, 0x51, 0x69, 0xBD, + 0xAB, 0xA2, 0x22, 0xDE, 0x71, 0xD3, 0x08, 0xA8, + 0x15, 0x14, 0x56, 0x15, 0xF0, 0xA9, 0xE4, 0x54, + 0x93, 0x35, 0xD6, 0xD0, 0x00, 0x92, 0x58, 0xDF, + 0x71, 0x16, 0x7D, 0x01, 0x97, 0xE4, 0x14, 0x9B, + 0x80, 0x1A, 0xB7, 0x9F, 0xCE, 0xCF, 0xBE, 0x2C, + 0xF4, 0x15, 0x05, 0xAC, 0x31, 0xA4, 0x31, 0x4E, + 0x25, 0x05, 0x9B, 0x3E, 0xA3, 0x6D, 0x58, 0xAD, + 0xC2, 0xF7, 0x3F, 0xA3, 0x64, 0xF1, 0x4C, 0x32, + 0x60, 0x00, 0x54, 0x89, 0x56, 0x16, 0xCC, 0x5C, + 0x14, 0xD2, 0xB1, 0xC1, 0x5D, 0xB7, 0x06, 0x70, + 0x00, 0xE8, 0x4A, 0x97, 0xDB, 0x46, 0xE3, 0x74, + 0xD4, 0xD6, 0x33, 0x56, 0x65, 0xF5, 0x45, 0x1E, + 0xA1, 0x03, 0x7D, 0x42, 0x10, 0x95, 0x32, 0x62, + 0x39, 0x71, 0xE0, 0x30, 0xBC, 0x92, 0x32, 0x36, + 0x06, 0xB7, 0x00, 0x04, 0xD2, 0x80, 0x7A, 0xDE, + 0xDD, 0xDD, 0x56, 0x49, 0x0F, 0x12, 0xAE, 0x46, + 0x18, 0xAC, 0x1F, 0xC1, 0x70, 0x9F, 0xC1, 0xE9, + 0xC8, 0xEB, 0x18, 0x4D, 0x72, 0x47, 0x08, 0x38, + 0x30, 0x00, 0xD3, 0x99, 0xE7, 0xBC, 0xB1, 0x34, + 0xA7, 0x65, 0x60, 0x9C, 0x30, 0xDE, 0xA6, 0x0E, + 0x7A, 0x05, 0x96, 0x4A, 0xAD, 0xED, 0x11, 0xE7, + 0xCC, 0xB3, 0xCB, 0x44, 0xB4, 0x9F, 0x4F, 0x95, + 0x4E, 0x45, 0xE4, 0xB0, 0xC4, 0x64, 0x6E, 0x8C, + 0x05, 0xE2, 0xCD, 0x7B, 0xC2, 0x3A, 0xF6, 0x3D, + 0xFF, 0xF6, 0xF9, 0x8A, 0xC8, 0xBA, 0x07, 0x89, + 0x56, 0xD5, 0x69, 0x81, 0xB6, 0x89, 0xF5, 0x0A, + 0xDA, 0x02, 0xCC, 0x8D, 0x01, 0x5A, 0x4A, 0x3E, + 0x00, 0x92, 0x40, 0x1D, 0x36, 0x1A, 0x36, 0x06, + 0x72, 0xA8, 0x63, 0x0C, 0xF4, 0xB6, 0xEA, 0x97, + 0x2A, 0x37, 0xC9, 0xE8, 0x81, 0x4B, 0xF4, 0x52, + 0xA5, 0x0A, 0x67, 0x8B, 0x46, 0x1D, 0x84, 0x78, + 0xF3, 0xAC, 0x86, 0x3E, 0x99, 0x65, 0x18, 0xE0, + 0x4F, 0x6B, 0xEA, 0x23, 0x11, 0x55, 0x3F, 0xF0, + 0xC3, 0xCD, 0x76, 0x68, 0x13, 0xCB, 0x74, 0x70, + 0xE0, 0xA7, 0x68, 0x8D, 0xAC, 0x8D, 0x86, 0x23, + 0x87, 0xF5, 0x29, 0x81, 0x2E, 0x61, 0x2C, 0x68, + 0xF5, 0x3E, 0x96, 0xD0, 0xEF, 0x1F, 0x8B, 0x05, + 0x52, 0xB3, 0x55, 0xF4, 0x13, 0xC5, 0xDC, 0xE7, + 0x65, 0xC4, 0xFD, 0x76, 0x4B, 0x9E, 0x90, 0x28, + 0x0F, 0xEC, 0xCD, 0x2D, 0x42, 0x05, 0x7D, 0x0B, + 0xCA, 0xCA, 0x28, 0x5D, 0x74, 0x4F, 0xB9, 0x03, + 0x7D, 0x38, 0x33, 0xB6, 0xF5, 0x72, 0x81, 0x68, + 0x3C, 0x23, 0xC5, 0x14, 0x74, 0xFB, 0x51, 0xE4, + 0xF4, 0xBC, 0x62, 0x48, 0x29, 0xD4, 0xC0, 0x1A, + 0x6E, 0x6F, 0x8B, 0x20, 0xA0, 0x83, 0x47, 0xD1, + 0xE1, 0x04, 0xB6, 0x81, 0xB6, 0x76, 0x0F, 0xF3, + 0x3B, 0x5D, 0x77, 0xE1, 0x45, 0x40, 0xB6, 0xAB, + 0x59, 0x6F, 0x59, 0xC4, 0x9F, 0xF5, 0x85, 0x4E, + 0xB1, 0xB2, 0x60, 0x97, 0xEA, 0x0A, 0xA6, 0xAF, + 0x9F, 0xAD, 0xA8, 0x7F, 0xC7, 0x76, 0x99, 0x6B, + 0xF9, 0x50, 0x7A, 0x55, 0x42, 0x94, 0xCC, 0x53, + 0x5F, 0x0F, 0xD3, 0xDB, 0x7A, 0x0F, 0x81, 0xC8, + 0x5F, 0xBB, 0x27, 0x64, 0x53, 0x09, 0x5A, 0xCC, + 0x82, 0x9E, 0x84, 0x9E, 0x1B, 0x19, 0x68, 0xDD, + 0xA0, 0x90, 0xCE, 0xF9, 0x33, 0xE5, 0x61, 0xF0, + 0xFF, 0x01, 0x93, 0xEA, 0x94, 0x6B, 0x3E, 0xE9, + 0x06, 0x33, 0x0D, 0x83, 0x7C, 0xC1, 0x44, 0x4A, + 0x5E, 0x13, 0xA4, 0xAD, 0x60, 0xA7, 0x8E, 0xF1, + 0x2C, 0xED, 0x11, 0xCA, 0x2E, 0x55, 0x67, 0x4B, + 0x1D, 0x84, 0xE8, 0xB2, 0x32, 0xB6, 0xC1, 0x15, + 0x7F, 0xD9, 0x70, 0xF7, 0xEB, 0xF0, 0x6F, 0x5D, + 0xE3, 0x27, 0xA4, 0xF2, 0xBB, 0xF9, 0xA8, 0xF2, + 0x13, 0x37, 0x89, 0x4F, 0x2D, 0xE7, 0xD6, 0x37, + 0xE8, 0x30, 0x29, 0x7E, 0xD1, 0x2E, 0x00, 0x0E, + 0x0D, 0xCA, 0x53, 0x93, 0x92, 0x92, 0xCE, 0x8C, + 0xA4, 0xE7, 0x9F, 0xF1, 0x51, 0xDE, 0x15, 0x06, + 0x33, 0x84, 0x70, 0x24, 0x37, 0xB5, 0xFE, 0x6A, + 0xB9, 0x64, 0x2B, 0x50, 0xA0, 0x26, 0x8A, 0x00, + 0x96, 0x5B, 0xFE, 0xAF, 0xD4, 0xC6, 0xE3, 0x17, + 0xF2, 0xAB, 0xAB, 0xF3, 0xE3, 0xF0, 0x03, 0x73, + 0x90, 0xBE, 0x6C, 0x04, 0x6D, 0xCA, 0x8F, 0x9C, + 0x0B, 0x35, 0xE1, 0xCA, 0x39, 0x81, 0xB2, 0x6F, + 0xD5, 0x0B, 0xC7, 0xCD, 0x0D, 0x6C, 0xD4, 0x30, + 0xBD, 0x7A, 0x25, 0x01, 0xB0, 0x28, 0x65, 0xA8, + 0xE7, 0x8D, 0xFD, 0x9F, 0xE5, 0xAD, 0x8E, 0xFD, + 0xD4, 0x16, 0x1F, 0xA7, 0x58, 0x6B, 0x43, 0xE1, + 0x46, 0x61, 0x66, 0xB7, 0xFE, 0x4B, 0x09, 0xD4, + 0xE7, 0x60, 0x8A, 0x72, 0x10, 0xB8, 0xB9, 0x11, + 0x0E, 0x52, 0x8D, 0x4B, 0xEE, 0x55, 0x89, 0xC3, + 0x2D, 0x04, 0x66, 0x8E, 0xCE, 0x2D, 0x33, 0xCF, + 0xF7, 0x8C, 0xB8, 0xE7, 0x33, 0x5B, 0x93, 0x95, + 0x37, 0x6D, 0x9B, 0xAA, 0xD5, 0x1E, 0xFA, 0x56, + 0x92, 0xAE, 0x2A, 0x61, 0x33, 0x99, 0xDE, 0xD1, + 0xFE, 0x05, 0xAA, 0x2D, 0x2A, 0xE0, 0x70, 0x3C, + 0x78, 0x99, 0x52, 0xCB, 0x35, 0x89, 0x49, 0x4F, + 0xD7, 0x3F, 0x5D, 0x36, 0x92, 0x20, 0x42, 0x43, + 0x02, 0xBC, 0xE0, 0xE9, 0xE0, 0xDF, 0x06, 0x62, + 0x4D, 0x95, 0x90, 0x32, 0x23, 0x04, 0x4D, 0x06, + 0xAA, 0x29, 0xE8, 0x7A, 0xD6, 0xD5, 0x8F, 0x0F, + 0xF4, 0x76, 0x89, 0x1E, 0x6F, 0x75, 0x89, 0xE5, + 0x4C, 0x12, 0xA8, 0x1D, 0xB2, 0x79, 0x51, 0xFC, + 0x84, 0x3E, 0xF0, 0x04, 0xE5, 0x73, 0x0B, 0x65, + 0x79, 0xAC, 0x6A, 0x88, 0x6E, 0xCA, 0x24, 0xBF, + 0x20, 0x8C, 0x51, 0x26, 0xFE, 0x79, 0x40, 0xEB, + 0x17, 0xF7, 0xFF, 0x6F, 0xAC, 0x9F, 0x55, 0x48, + 0xD5, 0x12, 0x73, 0xBF, 0x23, 0xE5, 0xD4, 0x42, + 0xAA, 0x2C, 0x11, 0xAB, 0xE8, 0x17, 0x39, 0x0C, + 0x38, 0x62, 0xFC, 0x6E, 0x3D, 0x00, 0xE6, 0xDF, + 0x2B, 0x35, 0x8A, 0x0B, 0x11, 0xA6, 0x4E, 0xFC, + 0x27, 0x3E, 0xAD, 0xFD, 0x51, 0xFB, 0x91, 0x13, + 0x0A, 0x52, 0x59, 0x08, 0xF1, 0x30, 0x9A, 0x65, + 0x04, 0xDB, 0xBF, 0xF2, 0x62, 0xDD, 0x88, 0x3A, + 0x9B, 0x8F, 0x48, 0x12, 0x34, 0x3A, 0x7E, 0x2C, + 0xBF, 0xC6, 0x6C, 0xCF, 0xBC, 0xBD, 0x75, 0x2E, + 0x92, 0xD4, 0x24, 0x58, 0x19, 0xDA, 0x25, 0xA5, + 0x07, 0x31, 0x13, 0x53, 0x58, 0x58, 0xC1, 0x03, + 0x26, 0x53, 0x24, 0x8C, 0x22, 0x54, 0x58, 0xCD, + 0xB5, 0xE8, 0x55, 0x74, 0x42, 0xE3, 0x0A, 0x20, + 0x2F, 0x04, 0xC7, 0xB3, 0x82, 0x67, 0x57, 0xDC, + 0x58, 0xC8, 0x8B, 0xE3, 0xE3, 0x29, 0x7C, 0x57, + 0xA1, 0xBC, 0x3C, 0xA5, 0x0B, 0x8F, 0xEC, 0x79, + 0xD3, 0x6D, 0x91, 0xF6, 0x39, 0xA6, 0xFD, 0x67, + 0x26, 0xDD, 0xFD, 0xFE, 0x2C, 0x87, 0xF6, 0xDE, + 0x12, 0x8B, 0xA7, 0x3C, 0xDE, 0xA3, 0x52, 0x9A, + 0x71, 0xB2, 0xC9, 0x65, 0xC4, 0xBC, 0x43, 0xDF, + 0x6B, 0x89, 0x1F, 0xDB, 0x25, 0x09, 0x6B, 0x47, + 0x39, 0xE2, 0xD8, 0x69, 0x15, 0x99, 0xC9, 0x61, + 0x89, 0x33, 0x85, 0x66, 0x7B, 0x2A, 0x07, 0xD4, + 0x2B, 0x42, 0x06, 0x45, 0xD9, 0x8A, 0x01, 0xEF, + 0xBF, 0xF6, 0x4A, 0x64, 0x5A, 0x4E, 0x4D, 0xEC, + 0xC5, 0xAC, 0x2E, 0x5E, 0xA4, 0x1B, 0x41, 0xE3, + 0xD9, 0x8B, 0x91, 0xF0, 0xF4, 0x4C, 0x11, 0x3D, + 0xE5, 0x1B, 0x53, 0x57, 0xF8, 0x18, 0xCB, 0xF7, + 0xB5, 0x53, 0x51, 0x1E, 0xB8, 0x29, 0x9E, 0xE8, + 0xD7, 0xF2, 0x6F, 0x8A, 0x9B, 0x9F, 0xC7, 0x85, + 0xA3, 0xB6, 0xD9, 0xAC, 0xD8, 0xB7, 0x44, 0x80, + 0xF4, 0x8A, 0xC5, 0x6B, 0x25, 0xB2, 0xD8, 0xBF, + 0x0C, 0xA6, 0xD2, 0xC0, 0x5B, 0x48, 0x37, 0x88, + 0x28, 0x52, 0xD5, 0x31, 0x1D, 0x02, 0x9D, 0x37, + 0x15, 0x60, 0xA3, 0x08, 0x86, 0xF9, 0xCA, 0x62, + 0x58, 0x18, 0xA1, 0x1B, 0xCF, 0x20, 0x30, 0x69, + 0x9A, 0x9F, 0xE2, 0x2A, 0xED, 0xA2, 0x63, 0x8C, + 0xA7, 0xBC, 0x8C, 0x68, 0xB5, 0x00, 0xE4, 0x04, + 0xC4, 0x8F, 0x91, 0x67, 0xEF, 0xB5, 0x9C, 0xBA, + 0xC7, 0x74, 0x1F, 0x6F, 0x20, 0xE5, 0x19, 0x13, + 0xCD, 0xB4, 0x96, 0x38, 0x5D, 0xE7, 0x93, 0x1E, + 0x5B, 0x96, 0xBC, 0xF8, 0x68, 0x08, 0xD5, 0x46, + 0x69, 0x10, 0x0E, 0xBB, 0x5D, 0xB9, 0xFC, 0xE5, + 0x90, 0xE1, 0x58, 0x31, 0x0B, 0xC2, 0x08, 0x10, + 0x94, 0x21, 0xD2, 0x36, 0x46, 0x22, 0x89, 0xAB, + 0x28, 0x6C, 0x5D, 0x56, 0xB9, 0x78, 0x86, 0xD1, + 0x07, 0x26, 0xE9, 0x20, 0x80, 0x9F, 0x30, 0xB4, + 0xB2, 0x10, 0xE3, 0xA6, 0x61, 0x9C, 0x8A, 0xA0, + 0xD2, 0x2A, 0x37, 0x45, 0xB8, 0x75, 0x5A, 0xC9, + 0xE5, 0x81, 0x12, 0xCB, 0x74, 0xBC, 0x41, 0xB1, + 0x75, 0x34, 0xBC, 0x6E, 0x8F, 0xEC, 0xF1, 0xB6, + 0xE0, 0xC6, 0xAD, 0xAF, 0x8A, 0x42, 0xB7, 0x8E, + 0x16, 0xFC, 0x5A, 0xC4, 0xA3, 0x41, 0xC5, 0xC4, + 0xDB, 0x07, 0x9C, 0x5D, 0xB7, 0x71, 0x24, 0xB8, + 0x93, 0x72, 0x0A, 0x08, 0xD8, 0x01, 0xCC, 0x79, + 0x52, 0xE7, 0x24, 0x32, 0x5E, 0x59, 0xCF, 0x01, + 0xBA, 0xAC, 0x67, 0x47, 0x40, 0x33, 0x69, 0x6F, + 0x6A, 0x02, 0xC9, 0xD8, 0x6C, 0x22, 0x33, 0x05, + 0x68, 0xB3, 0x29, 0x52, 0x67, 0xF1, 0x61, 0x2A, + 0xB8, 0x67, 0x1C, 0x69, 0x52, 0xA6, 0x13, 0x00, + 0x32, 0x6B, 0x09, 0xCC, 0xEE, 0xC7, 0x16, 0x0E, + 0x7F, 0xEA, 0xD7, 0x8D, 0xB9, 0x8A, 0x80, 0x62, + 0x0A, 0x60, 0xC0, 0x32, 0xD9, 0x8F, 0xBE, 0xA2, + 0xF9, 0x79, 0x4F, 0xC9, 0x08, 0x58, 0x69, 0x2D, + 0x57, 0x52, 0xF3, 0x08, 0x65, 0xA7, 0xA3, 0x61, + 0x27, 0xC0, 0x5B, 0x58, 0x64, 0x39, 0x99, 0xC7, + 0x33, 0x73, 0x4F, 0x30, 0x61, 0x37, 0x13, 0xE1, + 0x75, 0xDB, 0xF5, 0x40, 0x37, 0x38, 0x03, 0x56, + 0x79, 0xCC, 0xC5, 0x48, 0xF1, 0x29, 0x62, 0x39, + 0x81, 0x4F, 0xBE, 0x85, 0x43, 0xB8, 0x3A, 0xC7, + 0xF9, 0x46, 0xFB, 0x99, 0x21, 0xF1, 0x0B, 0x27, + 0x1E, 0x1D, 0x56, 0xD1, 0x22, 0x2F, 0x2C, 0xFA, + 0x6B, 0x16, 0x78, 0xEA, 0x0A, 0x3D, 0x56, 0xC0, + 0x56, 0xDE, 0x06, 0x92, 0x50, 0x57, 0x94, 0xBD, + 0x2D, 0x7F, 0x4A, 0x26, 0x32, 0x9E, 0xFC, 0xBA, + 0x0C, 0x14, 0xAF, 0x5A, 0xC5, 0x56, 0x72, 0x4A, + 0xB5, 0xE8, 0x8F, 0x62, 0x06, 0xE0, 0x1F, 0x6A, + 0x7E, 0x66, 0x19, 0xD3, 0x98, 0xA8, 0xCE, 0xAE, + 0xA9, 0xDE, 0x2D, 0x86, 0x43, 0xE8, 0xF5, 0x9D, + 0x4B, 0x60, 0x99, 0xC6, 0x90, 0xF9, 0xEC, 0xFA, + 0xAC, 0x24, 0x43, 0xE1, 0x83, 0x7D, 0xB9, 0xA5, + 0x81, 0xC1, 0xA1, 0xED, 0x87, 0xF3, 0x93, 0xA6, + 0x15, 0x1B, 0xBC, 0x4B, 0x27, 0x50, 0xE8, 0xEB, + 0x2B, 0x6F, 0xF1, 0x32, 0xFE, 0xB7, 0x5D, 0x99, + 0xA9, 0x43, 0x3A, 0x7A, 0x23, 0x3F, 0x72, 0x79, + 0x44, 0x8E, 0xDA, 0x98, 0xD0, 0xBD, 0x66, 0x9B, + 0x23, 0xDA, 0x2F, 0xF4, 0x15, 0xF9, 0xEA, 0x81, + 0xB5, 0x08, 0x32, 0xD8, 0x31, 0x3E, 0x34, 0x3C, + 0x44, 0x2C, 0x88, 0xE8, 0x68, 0x06, 0x34, 0x91, + 0xB5, 0x81, 0x48, 0xEA, 0x9B, 0x03, 0x27, 0x13, + 0x1D, 0xE0, 0x55, 0xD7, 0x83, 0xE0, 0x8E, 0x1A, + 0xC7, 0xCA, 0x69, 0xBC, 0x2E, 0x66, 0x9C, 0x5B, + 0x36, 0xA3, 0xCA, 0x6E, 0x84, 0xBC, 0xD2, 0xCF, + 0x06, 0x86, 0x47, 0xE1, 0xEE, 0x48, 0x41, 0xBE, + 0xE3, 0x71, 0xD0, 0xC8, 0xDD, 0xA7, 0xDC, 0xCA, + 0x0D, 0x0A, 0xC2, 0x29, 0xBE, 0x8E, 0x21, 0xDC, + 0x09, 0xC9, 0x41, 0x33, 0xC2, 0xED, 0x40, 0xF8, + 0x4A, 0x45, 0x37, 0x17, 0xD4, 0xFC, 0xE5, 0x16, + 0x4C, 0x36, 0xDB, 0x2C, 0x22, 0x33, 0x90, 0xB4, + 0xFA, 0x83, 0x68, 0x6E, 0xCC, 0x49, 0xCD, 0x3B, + 0x4A, 0x8E, 0xF2, 0xA1, 0x7C, 0xD5, 0x6D, 0x25, + 0xF8, 0x8B, 0x80, 0xC2, 0x3B, 0xC6, 0xF1, 0x7D, + 0xA6, 0x75, 0x02, 0x9C, 0xC1, 0x78, 0xC2, 0xD2, + 0x6B, 0x9F, 0x13, 0x57, 0x2C, 0xD0, 0xD5, 0x30, + 0x69, 0xC7, 0x5D, 0x88, 0x6A, 0x57, 0x9C, 0x23, + 0xF9, 0x1C, 0xCE, 0x8B, 0x07, 0xF3, 0xB9, 0x15, + 0xAB, 0x9E, 0x66, 0x99, 0xD2, 0x3E, 0x52, 0x07, + 0x9D, 0x85, 0x7D, 0xAC, 0x19, 0x63, 0xF6, 0x51, + 0x43, 0x28, 0x6D, 0xD0, 0xD9, 0xAB, 0x02, 0x1D, + 0xF7, 0xC8, 0xF0, 0xAA, 0x0B, 0x1A, 0x22, 0xB5, + 0x4A, 0x11, 0x40, 0x00, 0x12, 0x2D, 0xB6, 0xBC, + 0x34, 0x01, 0xFA, 0xF0, 0xE0, 0xAA, 0xD4, 0xD9, + 0xAF, 0x6E, 0x73, 0x6F, 0x63, 0xAD, 0xF4, 0x29, + 0x9D, 0x54, 0x31, 0xB2, 0x17, 0xBE, 0xFD, 0x44, + 0x0A, 0xE7, 0x44, 0x85, 0x87, 0x80, 0x91, 0x48, + 0xC0, 0x7B, 0x26, 0xF1, 0x93, 0x3F, 0x55, 0x99, + 0x18, 0xEC, 0x84, 0xA6, 0xC8, 0x3D, 0x54, 0x47, + 0xD5, 0x51, 0x3B, 0x44, 0xF6, 0x1D, 0x3B, 0x3A, + 0x67, 0x55, 0xCF, 0x39, 0xB9, 0xEC, 0x14, 0x98, + 0x64, 0xA9, 0x1F, 0x15, 0x94, 0xB1, 0x77, 0x5A, + 0x33, 0x40, 0xAD, 0x43, 0x53, 0x55, 0xBF, 0x32, + 0x29, 0xAE, 0xF2, 0x2B, 0xD0, 0x1A, 0x6C, 0x20, + 0xA2, 0xD3, 0x53, 0xFB, 0xA7, 0x00, 0xF5, 0xF1, + 0xC6, 0x61, 0x59, 0xB7, 0x07, 0x2E, 0xE4, 0x91, + 0xD6, 0x63, 0xF0, 0xD5, 0x3C, 0x82, 0x18, 0xFF, + 0xEB, 0x19, 0x46, 0x48, 0x3D, 0xBE, 0x8C, 0x96, + 0x32, 0x82, 0x6F, 0xF6, 0x39, 0xDF, 0x28, 0xFA, + 0xFA, 0x6F, 0x26, 0x67, 0xAF, 0xB7, 0x1A, 0x1A, + 0x5E, 0xB2, 0x15, 0xDF, 0xC0, 0x14, 0x6C, 0x05, + 0x61, 0xCF, 0xB9, 0x06, 0xD5, 0x3C, 0x9B, 0x08, + 0xA2, 0xE5, 0xD8, 0x66, 0x14, 0x71, 0xE9, 0x77, + 0xA2, 0x7E, 0x57, 0x25, 0x1B, 0xAD, 0x12, 0x07, + 0x27, 0xC4, 0x91, 0x3F, 0xE2, 0x91, 0xD9, 0xE4, + 0xB0, 0xD5, 0x43, 0x85, 0x34, 0x50, 0x31, 0xAD, + 0x62, 0x8B, 0x5F, 0x6E, 0x82, 0x2C, 0x95, 0x06, + 0x53, 0x55, 0xD1, 0x31, 0x95, 0xAE, 0x4C, 0xD8, + 0x06, 0x3D, 0xE9, 0x9A, 0x0A, 0x9C, 0xA2, 0x6C, + 0xB1, 0x89, 0x3B, 0xD9, 0x55, 0x42, 0x34, 0x7C, + 0x4B, 0x32, 0x57, 0x0A, 0x5D, 0x4F, 0xA8, 0xC3, + 0x6D, 0x28, 0x0A, 0x20, 0x8E, 0x16, 0xF3, 0xD3, + 0x9A, 0x61, 0x08, 0x7F, 0x77, 0x39, 0x3E, 0xFD, + 0x82, 0x3B, 0x83, 0x18, 0x81, 0x1C, 0xBE, 0x25, + 0x72, 0x20, 0xD1, 0x9D, 0x3D, 0x6C, 0xC0, 0xC7, + 0xA0, 0x4C, 0x85, 0xA1, 0x54, 0x1B, 0x30, 0x77, + 0x89, 0x12, 0x87, 0xFB, 0x93, 0xE5, 0xF9, 0xBE, + 0x33, 0xD2, 0xFB, 0xD9, 0xB7, 0xD3, 0x8F, 0xBE, + 0x91, 0x1B, 0x63, 0x8A, 0x69, 0x06, 0x4C, 0x5E, + 0x1B, 0xA0, 0x74, 0x03, 0xD0, 0x00, 0xDF, 0xD1, + 0xB7, 0x4E, 0xAD, 0x6D, 0x48, 0x9F, 0x8B, 0x28, + 0x0C, 0x40, 0xDD, 0xA6, 0x72, 0x88, 0x89, 0x18, + 0x0B, 0xAD, 0xE0, 0x8D, 0x6B, 0xCD, 0x2D, 0xC9, + 0x58, 0x43, 0x95, 0xCD, 0x3A, 0x82, 0xEF, 0x9B, + 0xCB, 0xE4, 0xF9, 0xB5, 0xAF, 0x3B, 0x48, 0x3B, + 0xFF, 0xD1, 0x67, 0x27, 0x1D, 0x9A, 0xF8, 0x9C, + 0xE7, 0xD0, 0x12, 0x2C, 0xF1, 0xE3, 0x80, 0x77, + 0xB5, 0xD4, 0x32, 0xEC, 0x45, 0xCF, 0x1C, 0xAF, + 0x6A, 0xEC, 0x37, 0x2B, 0xBC, 0xCF, 0xD5, 0xB1, + 0x13, 0xA7, 0xF8, 0x94, 0xFA, 0xB3, 0x3D, 0x5D, + 0xCD, 0x32, 0x7C, 0xFB, 0xE3, 0x7E, 0xC8, 0x8C, + 0xD8, 0x8C, 0xC2, 0x8A, 0x8A, 0x82, 0x0C, 0x08, + 0x34, 0xD5, 0xA0, 0xCD, 0x73, 0x85, 0x4D, 0xAA, + 0xDA, 0xAA, 0x03, 0x87, 0x66, 0xC9, 0xA4, 0x64, + 0x08, 0xB9, 0x97, 0x10, 0x26, 0x32, 0xE6, 0xB0, + 0x46, 0x71, 0x8F, 0x15, 0xB4, 0xA3, 0xE5, 0x63, + 0x5A, 0x3C, 0x48, 0x05, 0xAD, 0x04, 0xC3, 0x7B, + 0x44, 0x08, 0x02, 0xC8, 0x66, 0x6A, 0xC1, 0x4E, + 0x67, 0x43, 0xC7, 0xFE, 0x65, 0xCE, 0x0A, 0xB0, + 0x41, 0xCE, 0x95, 0x52, 0x2E, 0x72, 0x72, 0x3C, + 0xCD, 0x88, 0xA1, 0xCA, 0x1B, 0xF0, 0xFB, 0x02, + 0xC0, 0x07, 0x08, 0x24, 0xC6, 0xCD, 0xBE, 0xD3, + 0xCE, 0x0A, 0xC0, 0x9F, 0x9B, 0xB2, 0xA8, 0x81, + 0xB5, 0xB1, 0xB3, 0x37, 0xC7, 0x6F, 0xA8, 0xA3, + 0x45, 0xF2, 0x6D, 0x4D, 0xB8, 0x0C, 0x67, 0xD2, + 0x2B, 0x37, 0x68, 0x8A, 0x61, 0x02, 0xF0, 0x30, + 0x40, 0xA6, 0x7D, 0xEE, 0x64, 0x6A, 0xF5, 0x79, + 0xC7, 0xBE, 0xB4, 0x8F, 0x3E, 0x4B, 0xA8, 0x21, + 0x55, 0x8C, 0xDE, 0xB3, 0x0E, 0xBC, 0x77, 0xF1, + 0x6B, 0x5D, 0x3A, 0x6A, 0x2D, 0x96, 0x60, 0x8A, + 0x34, 0x38, 0x10, 0xD7, 0x7B, 0x9D, 0x50, 0xB2, + 0xFE, 0xD3, 0xE9, 0x59, 0x88, 0x17, 0xBF, 0xBA, + 0xF9, 0x77, 0xA5, 0x94, 0xEC, 0x04, 0x7D, 0x32, + 0xF3, 0x28, 0x42, 0x06, 0xFC, 0x56, 0x8E, 0xEE, + 0x68, 0xEA, 0xC9, 0x59, 0xA7, 0xB2, 0x32, 0x40, + 0x3A, 0x09, 0xB0, 0xF9, 0xDB, 0xC0, 0x99, 0xA5, + 0xF4, 0x06, 0xFD, 0x39, 0xE5, 0xD6, 0x07, 0x46, + 0xF4, 0xDE, 0x73, 0x70, 0x1A, 0xBF, 0x8B, 0x62, + 0xB2, 0x5E, 0xAD, 0x0C, 0x4E, 0x6D, 0x64, 0x5C, + 0x61, 0x5B, 0x31, 0xF3, 0x60, 0x59, 0xED, 0x86, + 0x4E, 0xCC, 0xCB, 0x32, 0xE5, 0x5A, 0xF2, 0xD2, + 0xBC, 0x3D, 0x85, 0xD7, 0xA0, 0xFE, 0x54, 0xCF, + 0x31, 0xCB, 0xAC, 0xF5, 0x31, 0xD2, 0x72, 0x37, + 0x6B, 0xC8, 0x68, 0xEE, 0x9E, 0xD9, 0x4A, 0xD7, + 0x0C, 0xE8, 0x53, 0xF2, 0x1A, 0x34, 0xAC, 0xEB, + 0x54, 0x00, 0x57, 0x71, 0x37, 0xCF, 0x81, 0xD3, + 0xF6, 0x89, 0xFB, 0x9B, 0xAC, 0x18, 0xB1, 0x02, + 0xC1, 0x44, 0x89, 0xCC, 0x25, 0x06, 0xF6, 0x96, + 0x8A, 0xA2, 0xCF, 0xF2, 0x0A, 0x8D, 0xB1, 0xB7, + 0xF5, 0x1B, 0xA0, 0x7D, 0xA6, 0xA5, 0xD6, 0xEB, + 0x37, 0xB1, 0x5F, 0x94, 0xEE, 0xF2, 0xD2, 0xE9, + 0x86, 0x7F, 0x9D, 0xCE, 0x8F, 0xB8, 0x0E, 0x19, + 0xC2, 0x60, 0x2C, 0x4D, 0xF1, 0x1D, 0x15, 0x24, + 0x8E, 0x3F, 0xC8, 0xFC, 0x97, 0x36, 0x5C, 0x17, + 0x99, 0x0D, 0x1B, 0xDB, 0x60, 0xCF, 0x97, 0x4A, + 0x60, 0xF8, 0xB3, 0xA7, 0x9B, 0xBF, 0x25, 0x14, + 0x16, 0x32, 0x44, 0x6D, 0x34, 0x49, 0x1A, 0x70, + 0xA8, 0x33, 0x2C, 0x0A, 0xFD, 0x65, 0x4A, 0x3C, + 0xB9, 0x01, 0xF0, 0xFA, 0x36, 0x27, 0x64, 0xC7, + 0x17, 0xC8, 0xC5, 0x0C, 0xFD, 0x7D, 0x50, 0x00, + 0x7C, 0x07, 0xA6, 0x1C, 0x52, 0xA4, 0xD9, 0x08, + 0xEA, 0x79, 0xAF, 0x73, 0x48, 0x56, 0x6E, 0xB6, + 0x61, 0x72, 0x88, 0x39, 0x3D, 0x8D, 0xC2, 0x38, + 0xE0, 0xFA, 0x01, 0xD6, 0x5A, 0xB2, 0x84, 0xBB, + 0x04, 0x7F, 0x21, 0xF3, 0x64, 0xE7, 0x01, 0x1B, + 0xF7, 0x50, 0x67, 0xB0, 0x3F, 0xB2, 0x31, 0xEA, + 0x0E, 0x57, 0x04, 0x4E, 0xD7, 0xD8, 0x01, 0x80, + 0x45, 0xB4, 0xB9, 0x65, 0xD8, 0x58, 0xDB, 0x99, + 0xA4, 0xAF, 0xFF, 0xE2, 0xCC, 0x6B, 0xD4, 0x3A, + 0x60, 0x09, 0x84, 0x4F, 0x38, 0x72, 0x86, 0xB7, + 0x0B, 0xF7, 0x7F, 0xBF, 0x12, 0x90, 0x1A, 0xDF, + 0x8B, 0xAE, 0xF8, 0x16, 0x4F, 0xB4, 0x7E, 0xF9, + 0x22, 0x77, 0x00, 0xE0, 0x80, 0xAE, 0xB6, 0x4B, + 0x98, 0xA0, 0x22, 0x06, 0xF9, 0x7D, 0x68, 0x6B, + 0xBD, 0x46, 0xA1, 0x6C, 0x18, 0x86, 0x95, 0x35, + 0x50, 0x39, 0x96, 0x7D, 0x5E, 0x04, 0xD3, 0xD2, + 0xFF, 0x1F, 0x95, 0xEC, 0x9B, 0xEC, 0xFD, 0x94, + 0x4E, 0x8F, 0x65, 0xAA, 0x3C, 0xFA, 0x3D, 0x79, + 0x93, 0x04, 0x11, 0xB2, 0x8C, 0x0E, 0xB2, 0xDE, + 0x4A, 0xDD, 0x0F, 0x3B, 0x66, 0xD1, 0xA6, 0x6E, + 0x9F, 0x64, 0xC4, 0x8B, 0x38, 0xF9, 0x8E, 0x33, + 0x8B, 0x04, 0xA4, 0x16, 0x51, 0x83, 0xBC, 0xCB, + 0xC6, 0x7E, 0xC7, 0xF1, 0xFB, 0x9B, 0xAC, 0x18 }; static const struct gmac_test_data gmac_test_case_1 = { @@ -1201,4 +9373,37 @@ static const struct cryptodev_perf_test_data AES_GCM_128_12IV_0AAD = { }, }; +static const struct gmac_test_data gmac_test_case_4 = { + .key = { + .data = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 + }, + .len = 16 + }, + .iv = { + .data = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 + }, + .len = 12 + }, + .aad = { + .data = gmac_plaintext, + .len = 65376 + }, + .plaintext = { + .data = NULL, + .len = 0 + }, + .gmac_tag = { + .data = { + 0xde, 0xb4, 0xd1, 0x3e, 0xf7, 0x55, 0x99, 0x1b, + 0x40, 0x8a, 0x5c, 0xdc, 0xf3, 0x38, 0xfb, 0x30 + }, + .len = 16 + } +}; + + #endif /* TEST_CRYPTODEV_GCM_TEST_VECTORS_H_ */ -- 2.5.0 ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dpdk-dev] [PATCH v4 4/5] app/test: added big data GMAC test for libcrypto 2016-09-30 16:32 ` [dpdk-dev] [PATCH v4 4/5] app/test: added big data GMAC test for libcrypto Slawomir Mrozowicz @ 2016-09-30 17:18 ` Thomas Monjalon 2016-10-03 8:12 ` Mrozowicz, SlawomirX 0 siblings, 1 reply; 34+ messages in thread From: Thomas Monjalon @ 2016-09-30 17:18 UTC (permalink / raw) To: Slawomir Mrozowicz, Piotr Azarewicz; +Cc: dev, Wei Dai 2016-09-30 18:32, Slawomir Mrozowicz: > This patch add big data AES-GMAC test for libcrypto PMD. > > Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com> > --- > app/test/test_cryptodev.c | 18 +- > app/test/test_cryptodev_gcm_test_vectors.h | 8245 +++++++++++++++++++++++++++- > 2 files changed, 8242 insertions(+), 21 deletions(-) The test data are really too big. Is it possible to generate them as Wei Dai did for LPM? http://dpdk.org/patch/16175 http://dpdk.org/patch/16253 ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dpdk-dev] [PATCH v4 4/5] app/test: added big data GMAC test for libcrypto 2016-09-30 17:18 ` Thomas Monjalon @ 2016-10-03 8:12 ` Mrozowicz, SlawomirX 0 siblings, 0 replies; 34+ messages in thread From: Mrozowicz, SlawomirX @ 2016-10-03 8:12 UTC (permalink / raw) To: Thomas Monjalon, Azarewicz, PiotrX T; +Cc: dev, Dai, Wei >-----Original Message----- >From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com] >Sent: Friday, September 30, 2016 7:19 PM >To: Mrozowicz, SlawomirX <slawomirx.mrozowicz@intel.com>; Azarewicz, >PiotrX T <piotrx.t.azarewicz@intel.com> >Cc: dev@dpdk.org; Dai, Wei <wei.dai@intel.com> >Subject: Re: [dpdk-dev] [PATCH v4 4/5] app/test: added big data GMAC test >for libcrypto > >2016-09-30 18:32, Slawomir Mrozowicz: >> This patch add big data AES-GMAC test for libcrypto PMD. >> >> Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com> >> --- >> app/test/test_cryptodev.c | 18 +- >> app/test/test_cryptodev_gcm_test_vectors.h | 8245 >+++++++++++++++++++++++++++- >> 2 files changed, 8242 insertions(+), 21 deletions(-) > >The test data are really too big. >Is it possible to generate them as Wei Dai did for LPM? > http://dpdk.org/patch/16175 > http://dpdk.org/patch/16253 Yes it is possible. We will prepare new patch set with the changes which you proposed. Sławek ^ permalink raw reply [flat|nested] 34+ messages in thread
* [dpdk-dev] [PATCH v4 5/5] examples/l2fwd-crypto: updated example for libcrypto PMD 2016-09-30 16:32 ` [dpdk-dev] [PATCH v4 2/5] app/test: cryptodev AES tests rework Slawomir Mrozowicz 2016-09-30 16:32 ` [dpdk-dev] [PATCH v4 3/5] app/test: added tests for libcrypto PMD Slawomir Mrozowicz 2016-09-30 16:32 ` [dpdk-dev] [PATCH v4 4/5] app/test: added big data GMAC test for libcrypto Slawomir Mrozowicz @ 2016-09-30 16:32 ` Slawomir Mrozowicz 2 siblings, 0 replies; 34+ messages in thread From: Slawomir Mrozowicz @ 2016-09-30 16:32 UTC (permalink / raw) To: dev; +Cc: Slawomir Mrozowicz, Daniel Mrzyglod Libcrypto PMD has support for: Supported cipher algorithms: RTE_CRYPTO_CIPHER_3DES_CBC RTE_CRYPTO_CIPHER_AES_CBC RTE_CRYPTO_CIPHER_AES_CTR RTE_CRYPTO_CIPHER_3DES_CTR RTE_CRYPTO_CIPHER_AES_GCM Supported authentication algorithms: RTE_CRYPTO_AUTH_AES_GMAC RTE_CRYPTO_AUTH_MD5 RTE_CRYPTO_AUTH_SHA1 RTE_CRYPTO_AUTH_SHA224 RTE_CRYPTO_AUTH_SHA256 RTE_CRYPTO_AUTH_SHA384 RTE_CRYPTO_AUTH_SHA512 RTE_CRYPTO_AUTH_MD5_HMAC RTE_CRYPTO_AUTH_SHA1_HMAC RTE_CRYPTO_AUTH_SHA224_HMAC RTE_CRYPTO_AUTH_SHA256_HMAC RTE_CRYPTO_AUTH_SHA384_HMAC RTE_CRYPTO_AUTH_SHA512_HMAC Signed-off-by: Daniel Mrzyglod <danielx.t.mrzyglod@intel.com> --- v3: - change description --- examples/l2fwd-crypto/main.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/examples/l2fwd-crypto/main.c b/examples/l2fwd-crypto/main.c index 0593734..dae45f5 100644 --- a/examples/l2fwd-crypto/main.c +++ b/examples/l2fwd-crypto/main.c @@ -340,15 +340,22 @@ fill_supported_algorithm_tables(void) strcpy(supported_auth_algo[i], "NOT_SUPPORTED"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_AES_GCM], "AES_GCM"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_AES_GMAC], "AES_GMAC"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_MD5_HMAC], "MD5_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_MD5], "MD5"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_NULL], "NULL"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_AES_XCBC_MAC], "AES_XCBC_MAC"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA1_HMAC], "SHA1_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA1], "SHA1"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA224_HMAC], "SHA224_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA224], "SHA224"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA256_HMAC], "SHA256_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA256], "SHA256"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA384_HMAC], "SHA384_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA384], "SHA384"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA512_HMAC], "SHA512_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA512], "SHA512"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SNOW3G_UIA2], "SNOW3G_UIA2"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_ZUC_EIA3], "ZUC_EIA3"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_KASUMI_F9], "KASUMI_F9"); @@ -363,6 +370,8 @@ fill_supported_algorithm_tables(void) strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_SNOW3G_UEA2], "SNOW3G_UEA2"); strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_ZUC_EEA3], "ZUC_EEA3"); strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_KASUMI_F8], "KASUMI_F8"); + strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_3DES_CTR], "3DES_CTR"); + strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_3DES_CBC], "3DES_CBC"); } -- 2.5.0 ^ permalink raw reply [flat|nested] 34+ messages in thread
* [dpdk-dev] [PATCH v5 0/4] new crypto software based device 2016-09-30 16:17 ` [dpdk-dev] [PATCH v4 0/5] new crypto software based device Slawomir Mrozowicz 2016-09-30 16:17 ` [dpdk-dev] [PATCH v4 1/5] libcrypto_pmd: initial implementation of SW crypto device Slawomir Mrozowicz 2016-09-30 16:32 ` [dpdk-dev] [PATCH v4 2/5] app/test: cryptodev AES tests rework Slawomir Mrozowicz @ 2016-10-03 14:26 ` Slawomir Mrozowicz 2016-10-03 14:45 ` [dpdk-dev] [PATCH v5 1/4] libcrypto_pmd: initial implementation of SW crypto device Slawomir Mrozowicz ` (5 more replies) 2 siblings, 6 replies; 34+ messages in thread From: Slawomir Mrozowicz @ 2016-10-03 14:26 UTC (permalink / raw) To: dev; +Cc: Slawomir Mrozowicz This code provides the initial implementation of the libcrypto poll mode driver. All cryptography operations are using Openssl library crypto API. Each algorithm uses EVP_ interface from openssl API - which is recommended by Openssl maintainers. For more information about how to use this driver, go to: doc/guides/cryptodevs/libcrypto.rst Changes in V5: - reduce source of big data test Changes in V4: - move aes test rework to another patch - move big data test to another patch - checking if libcrypto pmd is available Changes in V3: - add nagative verification tests - add big data test - fix pmd according to negative verification tests - change gmac aad max size - update documentation and commits comments Changes in V2: - add gcm/gmac algorithm correction - unit test rework Slawomir Mrozowicz (1): libcrypto_pmd: initial implementation of SW crypto device Piotr Azarewicz (2) app/test: cryptodev AES tests rework app/test: added tests for libcrypto PMD Daniel Mrzyglod (1) examples/l2fwd-crypto: updated example for libcrypto PMD MAINTAINERS | 4 + app/test/Makefile | 2 +- app/test/test_cryptodev.c | 1581 ++++++++++++++++++-- app/test/test_cryptodev.h | 1 + app/test/test_cryptodev_aes.c | 687 --------- app/test/test_cryptodev_aes.h | 1124 -------------- app/test/test_cryptodev_aes_test_vectors.h | 1095 ++++++++++++++ app/test/test_cryptodev_blockcipher.c | 531 +++++++ app/test/test_cryptodev_blockcipher.h | 125 ++ app/test/test_cryptodev_des_test_vectors.h | 952 ++++++++++++ app/test/test_cryptodev_gcm_test_vectors.h | 36 +- app/test/test_cryptodev_hash_test_vectors.h | 491 ++++++ app/test/test_cryptodev_perf.c | 689 ++++++++- config/common_base | 6 + doc/guides/cryptodevs/index.rst | 1 + doc/guides/cryptodevs/libcrypto.rst | 116 ++ doc/guides/rel_notes/release_16_11.rst | 23 +- drivers/crypto/Makefile | 1 + drivers/crypto/libcrypto/Makefile | 60 + drivers/crypto/libcrypto/rte_libcrypto_pmd.c | 1051 +++++++++++++ drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c | 708 +++++++++ .../crypto/libcrypto/rte_libcrypto_pmd_private.h | 174 +++ .../crypto/libcrypto/rte_pmd_libcrypto_version.map | 3 + examples/l2fwd-crypto/main.c | 9 + lib/librte_cryptodev/rte_cryptodev.h | 5 +- mk/rte.app.mk | 23 +- 26 files changed, 7563 insertions(+), 1935 deletions(-) delete mode 100644 app/test/test_cryptodev_aes.c delete mode 100644 app/test/test_cryptodev_aes.h create mode 100644 app/test/test_cryptodev_aes_test_vectors.h create mode 100644 app/test/test_cryptodev_blockcipher.c create mode 100644 app/test/test_cryptodev_blockcipher.h create mode 100644 app/test/test_cryptodev_des_test_vectors.h create mode 100644 app/test/test_cryptodev_hash_test_vectors.h create mode 100644 doc/guides/cryptodevs/libcrypto.rst create mode 100644 drivers/crypto/libcrypto/Makefile create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd.c create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h create mode 100644 drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map -- 2.5.0 ^ permalink raw reply [flat|nested] 34+ messages in thread
* [dpdk-dev] [PATCH v5 1/4] libcrypto_pmd: initial implementation of SW crypto device 2016-10-03 14:26 ` [dpdk-dev] [PATCH v5 0/4] new crypto software based device Slawomir Mrozowicz @ 2016-10-03 14:45 ` Slawomir Mrozowicz 2016-10-03 15:02 ` [dpdk-dev] [PATCH v5 2/4] app/test: cryptodev AES tests rework Slawomir Mrozowicz ` (4 subsequent siblings) 5 siblings, 0 replies; 34+ messages in thread From: Slawomir Mrozowicz @ 2016-10-03 14:45 UTC (permalink / raw) To: dev Cc: Slawomir Mrozowicz, Michal Kobylinski, Tomasz Kulasek, Daniel Mrzyglod This code provides the initial implementation of the libcrypto poll mode driver. All cryptography operations are using Openssl library crypto API. Each algorithm uses EVP_ interface from openssl API - which is recommended by Openssl maintainers. This patch adds libcrypto poll mode driver support to librte_cryptodev library. Signed-off-by: Slawomir Mrozowicz <slawomirx.mrozowicz@intel.com> Signed-off-by: Michal Kobylinski <michalx.kobylinski@intel.com> Signed-off-by: Tomasz Kulasek <tomaszx.kulasek@intel.com> Signed-off-by: Daniel Mrzyglod <danielx.t.mrzyglod@intel.com> --- v2: - add gcm crypto cipher and authentication algorithm - rework gmac crypto authentication algorithm v3: - fix pmd according to negative verification tests - change gmac aad max size - update documentation --- MAINTAINERS | 4 + config/common_base | 6 + doc/guides/cryptodevs/index.rst | 1 + doc/guides/cryptodevs/libcrypto.rst | 116 +++ doc/guides/rel_notes/release_16_11.rst | 23 +- drivers/crypto/Makefile | 1 + drivers/crypto/libcrypto/Makefile | 60 ++ drivers/crypto/libcrypto/rte_libcrypto_pmd.c | 1051 ++++++++++++++++++++ drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c | 708 +++++++++++++ .../crypto/libcrypto/rte_libcrypto_pmd_private.h | 174 ++++ .../crypto/libcrypto/rte_pmd_libcrypto_version.map | 3 + lib/librte_cryptodev/rte_cryptodev.h | 5 +- mk/rte.app.mk | 23 +- 13 files changed, 2162 insertions(+), 13 deletions(-) create mode 100644 doc/guides/cryptodevs/libcrypto.rst create mode 100644 drivers/crypto/libcrypto/Makefile create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd.c create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h create mode 100644 drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map diff --git a/MAINTAINERS b/MAINTAINERS index 58a10b8..1e9d1f8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -439,6 +439,10 @@ M: Declan Doherty <declan.doherty@intel.com> F: drivers/crypto/null/ F: doc/guides/cryptodevs/null.rst +LibCrypto Crypto PMD +M: Declan Doherty <declan.doherty@intel.com> +F: drivers/crypto/libcrypto/ +F: doc/guides/cryptodevs/libcrypto.rst Packet processing ----------------- diff --git a/config/common_base b/config/common_base index 3a412ee..87b8646 100644 --- a/config/common_base +++ b/config/common_base @@ -376,6 +376,12 @@ CONFIG_RTE_LIBRTE_PMD_AESNI_MB=n CONFIG_RTE_LIBRTE_PMD_AESNI_MB_DEBUG=n # +# Compile PMD for Software backed device +# +CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO=n +CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO_DEBUG=n + +# # Compile PMD for AESNI GCM device # CONFIG_RTE_LIBRTE_PMD_AESNI_GCM=n diff --git a/doc/guides/cryptodevs/index.rst b/doc/guides/cryptodevs/index.rst index 906f1b4..bae8e53 100644 --- a/doc/guides/cryptodevs/index.rst +++ b/doc/guides/cryptodevs/index.rst @@ -39,6 +39,7 @@ Crypto Device Drivers aesni_mb aesni_gcm kasumi + libcrypto null snow3g qat diff --git a/doc/guides/cryptodevs/libcrypto.rst b/doc/guides/cryptodevs/libcrypto.rst new file mode 100644 index 0000000..77eff95 --- /dev/null +++ b/doc/guides/cryptodevs/libcrypto.rst @@ -0,0 +1,116 @@ +.. 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. + +LibCrypto Crypto Poll Mode Driver + +This code provides the initial implementation of the libcrypto poll mode +driver. All cryptography operations are using Openssl library crypto API. +Each algorithm uses EVP_ interface from openssl API - which is recommended +by Openssl maintainers. + +For more details about openssl library please visit openssl webpage: +https://www.openssl.org/ + +Features +-------- + +LibCrypto PMD has support for: + +Supported cipher algorithms: +* ``RTE_CRYPTO_CIPHER_3DES_CBC`` +* ``RTE_CRYPTO_CIPHER_AES_CBC`` +* ``RTE_CRYPTO_CIPHER_AES_CTR`` +* ``RTE_CRYPTO_CIPHER_3DES_CTR`` +* ``RTE_CRYPTO_CIPHER_AES_GCM`` + +Supported authentication algorithms: +* ``RTE_CRYPTO_AUTH_AES_GMAC`` +* ``RTE_CRYPTO_AUTH_MD5`` +* ``RTE_CRYPTO_AUTH_SHA1`` +* ``RTE_CRYPTO_AUTH_SHA224`` +* ``RTE_CRYPTO_AUTH_SHA256`` +* ``RTE_CRYPTO_AUTH_SHA384`` +* ``RTE_CRYPTO_AUTH_SHA512`` +* ``RTE_CRYPTO_AUTH_MD5_HMAC`` +* ``RTE_CRYPTO_AUTH_SHA1_HMAC`` +* ``RTE_CRYPTO_AUTH_SHA224_HMAC`` +* ``RTE_CRYPTO_AUTH_SHA256_HMAC`` +* ``RTE_CRYPTO_AUTH_SHA384_HMAC`` +* ``RTE_CRYPTO_AUTH_SHA512_HMAC`` + + +Installation +------------ + +To compile libcrypto PMD, it has to be enabled in the config/common_base file +and appropriate openssl packages have to be installed in the build environment. + +The newest openssl library version is supported: +* 1.0.2h-fips 3 May 2016. +Older versions that were also verified: +* 1.0.1f 6 Jan 2014 +* 1.0.1 14 Mar 2012 + +For Ubuntu 14.04 LTS these packages have to be installed in the build system: +sudo apt-get install openssl +sudo apt-get install libc6-dev-i386 (for i686-native-linuxapp-gcc target) + +This code was also verified on Fedora 24. +This code was NOT yet verified on FreeBSD. + +Initialization +-------------- + +User can use app/test application to check how to use this pmd and to verify +crypto processing. + +Test name is cryptodev_libcrypto_autotest. +For performance test cryptodev_libcrypto_perftest can be used. + +To verify real traffic l2fwd-crypto example can be used with this command: + +.. code-block:: console + +sudo ./build/l2fwd-crypto -c 0x3 -n 4 --vdev "cryptodev_libcrypto_pmd" +--vdev "cryptodev_libcrypto_pmd"-- -p 0x3 --chain CIPHER_HASH +--cipher_op ENCRYPT --cipher_algo AES_CBC +--cipher_key 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f +--iv 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:ff +--auth_op GENERATE --auth_algo SHA1_HMAC +--auth_key 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11 +:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11 +:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11 + +Limitations +----------- + +* Maximum number of sessions is 2048. +* Chained mbufs are not supported. +* Hash only is not supported for GCM and GMAC. +* Cipher only is not supported for GCM and GMAC. diff --git a/doc/guides/rel_notes/release_16_11.rst b/doc/guides/rel_notes/release_16_11.rst index cc507a9..6e92966 100644 --- a/doc/guides/rel_notes/release_16_11.rst +++ b/doc/guides/rel_notes/release_16_11.rst @@ -34,7 +34,28 @@ New Features Refer to the previous release notes for examples. - This section is a comment. Make sure to start the actual text at the margin. +* **Added libcrypto PMD.** + + A new crypto PMD has been added, which provides several ciphering and hashing. + All cryptography operations are using Openssl library crypto API. + +* ** Added support of C3xxx Device in QAT PMD.** + Support for Device c3xxx has been enabled in QAT PMD. + +* ** Added support of C62XX Device in QAT PMD.** + Support for Device c62xx has been enabled in QAT PMD. + + +* **Updated the QAT PMD.** + The QAT PMD was updated with changes including the following: + + * Added support for MD5_HMAC algorithm. + * Added support for SHA224-HMAC algorithm. + * Added support for SHA384-HMAC algorithm. + * Added support for NULL algorithm. + * Added support for KASUMI (F8 and F9) algorithm. + * Added support for GMAC algorithm. + * Added support for 3DES block cipher algorithm. * ** Added support of C3xxx Device in QAT PMD.** Support for Device c3xxx has been enabled in QAT PMD. diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index 17d74fc..b452ea6 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -33,6 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += aesni_gcm DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += aesni_mb +DIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += libcrypto DIRS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += qat DIRS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += snow3g DIRS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI) += kasumi diff --git a/drivers/crypto/libcrypto/Makefile b/drivers/crypto/libcrypto/Makefile new file mode 100644 index 0000000..c5f8cf2 --- /dev/null +++ b/drivers/crypto/libcrypto/Makefile @@ -0,0 +1,60 @@ +# 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 + +# library name +LIB = librte_pmd_libcrypto.a + +# build flags +CFLAGS += -O3 +CFLAGS += $(WERROR_FLAGS) + +# library version +LIBABIVER := 1 + +# versioning export map +EXPORT_MAP := rte_pmd_libcrypto_version.map + +# external library dependencies +LDLIBS += -lcrypto + +# library source files +SRCS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += rte_libcrypto_pmd.c +SRCS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += rte_libcrypto_pmd_ops.c + +# library dependencies +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_eal +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_mbuf +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_mempool +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_ring +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_cryptodev + +include $(RTE_SDK)/mk/rte.lib.mk diff --git a/drivers/crypto/libcrypto/rte_libcrypto_pmd.c b/drivers/crypto/libcrypto/rte_libcrypto_pmd.c new file mode 100644 index 0000000..d9a60d0 --- /dev/null +++ b/drivers/crypto/libcrypto/rte_libcrypto_pmd.c @@ -0,0 +1,1051 @@ +/*- + * 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_common.h> +#include <rte_hexdump.h> +#include <rte_cryptodev.h> +#include <rte_cryptodev_pmd.h> +#include <rte_dev.h> +#include <rte_malloc.h> +#include <rte_cpuflags.h> + +#include <openssl/evp.h> + +#include "rte_libcrypto_pmd_private.h" + +static int cryptodev_libcrypto_uninit(const char *name); + +/*----------------------------------------------------------------------------*/ + +/** + * Global static parameter used to create a unique name for each + * LIBCRYPTO crypto device. + */ +static unsigned int unique_name_id; + +static inline int +create_unique_device_name(char *name, size_t size) +{ + int ret; + + if (name == NULL) + return -EINVAL; + + ret = snprintf(name, size, "%s_%u", RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), + unique_name_id++); + if (ret < 0) + return ret; + return 0; +} + +/** + * Increment counter by 1 + * Counter is 64 bit array, big-endian + */ +static void +ctr_inc(uint8_t *ctr) +{ + uint64_t *ctr64 = (uint64_t *)ctr; + + *ctr64 = __builtin_bswap64(*ctr64); + (*ctr64)++; + *ctr64 = __builtin_bswap64(*ctr64); +} + +/* + *------------------------------------------------------------------------------ + * Session Prepare + *------------------------------------------------------------------------------ + */ + +/** Get xform chain order */ +static enum libcrypto_chain_order +libcrypto_get_chain_order(const struct rte_crypto_sym_xform *xform) +{ + enum libcrypto_chain_order res = LIBCRYPTO_CHAIN_NOT_SUPPORTED; + + if (xform != NULL) { + if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) { + if (xform->next == NULL) + res = LIBCRYPTO_CHAIN_ONLY_AUTH; + else if (xform->next->type == + RTE_CRYPTO_SYM_XFORM_CIPHER) + res = LIBCRYPTO_CHAIN_AUTH_CIPHER; + } + if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) { + if (xform->next == NULL) + res = LIBCRYPTO_CHAIN_ONLY_CIPHER; + else if (xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH) + res = LIBCRYPTO_CHAIN_CIPHER_AUTH; + } + } + + return res; +} + +/** Get session cipher key from input cipher key */ +static void +get_cipher_key(uint8_t *input_key, int keylen, uint8_t *session_key) +{ + memcpy(session_key, input_key, keylen); +} + +/** Get key ede 24 bytes standard from input key */ +static int +get_cipher_key_ede(uint8_t *key, int keylen, uint8_t *key_ede) +{ + int res = 0; + + /* Initialize keys - 24 bytes: [key1-key2-key3] */ + switch (keylen) { + case 24: + memcpy(key_ede, key, 24); + break; + case 16: + /* K3 = K1 */ + memcpy(key_ede, key, 16); + memcpy(key_ede + 16, key, 8); + break; + case 8: + /* K1 = K2 = K3 (DES compatibility) */ + memcpy(key_ede, key, 8); + memcpy(key_ede + 8, key, 8); + memcpy(key_ede + 16, key, 8); + break; + default: + LIBCRYPTO_LOG_ERR("Unsupported key size"); + res = -EINVAL; + } + + return res; +} + +/** Get adequate libcrypto function for input cipher algorithm */ +static uint8_t +get_cipher_algo(enum rte_crypto_cipher_algorithm sess_algo, size_t keylen, + const EVP_CIPHER **algo) +{ + int res = 0; + + if (algo != NULL) { + switch (sess_algo) { + case RTE_CRYPTO_CIPHER_3DES_CBC: + switch (keylen) { + case 16: + *algo = EVP_des_ede_cbc(); + break; + case 24: + *algo = EVP_des_ede3_cbc(); + break; + default: + res = -EINVAL; + } + break; + case RTE_CRYPTO_CIPHER_3DES_CTR: + break; + case RTE_CRYPTO_CIPHER_AES_CBC: + switch (keylen) { + case 16: + *algo = EVP_aes_128_cbc(); + break; + case 24: + *algo = EVP_aes_192_cbc(); + break; + case 32: + *algo = EVP_aes_256_cbc(); + break; + default: + res = -EINVAL; + } + break; + case RTE_CRYPTO_CIPHER_AES_CTR: + switch (keylen) { + case 16: + *algo = EVP_aes_128_ctr(); + break; + case 24: + *algo = EVP_aes_192_ctr(); + break; + case 32: + *algo = EVP_aes_256_ctr(); + break; + default: + res = -EINVAL; + } + break; + case RTE_CRYPTO_CIPHER_AES_GCM: + switch (keylen) { + case 16: + *algo = EVP_aes_128_gcm(); + break; + case 24: + *algo = EVP_aes_192_gcm(); + break; + case 32: + *algo = EVP_aes_256_gcm(); + break; + default: + res = -EINVAL; + } + break; + default: + res = -EINVAL; + break; + } + } else { + res = -EINVAL; + } + + return res; +} + +/** Get adequate libcrypto function for input auth algorithm */ +static uint8_t +get_auth_algo(enum rte_crypto_auth_algorithm sessalgo, + const EVP_MD **algo) +{ + int res = 0; + + if (algo != NULL) { + switch (sessalgo) { + case RTE_CRYPTO_AUTH_MD5: + case RTE_CRYPTO_AUTH_MD5_HMAC: + *algo = EVP_md5(); + break; + case RTE_CRYPTO_AUTH_SHA1: + case RTE_CRYPTO_AUTH_SHA1_HMAC: + *algo = EVP_sha1(); + break; + case RTE_CRYPTO_AUTH_SHA224: + case RTE_CRYPTO_AUTH_SHA224_HMAC: + *algo = EVP_sha224(); + break; + case RTE_CRYPTO_AUTH_SHA256: + case RTE_CRYPTO_AUTH_SHA256_HMAC: + *algo = EVP_sha256(); + break; + case RTE_CRYPTO_AUTH_SHA384: + case RTE_CRYPTO_AUTH_SHA384_HMAC: + *algo = EVP_sha384(); + break; + case RTE_CRYPTO_AUTH_SHA512: + case RTE_CRYPTO_AUTH_SHA512_HMAC: + *algo = EVP_sha512(); + break; + default: + res = -EINVAL; + break; + } + } else { + res = -EINVAL; + } + + return res; +} + +/** Set session cipher parameters */ +static int +libcrypto_set_session_cipher_parameters(struct libcrypto_session *sess, + const struct rte_crypto_sym_xform *xform) +{ + /* Select cipher direction */ + sess->cipher.direction = xform->cipher.op; + /* Select cipher key */ + sess->cipher.key.length = xform->cipher.key.length; + + /* Select cipher algo */ + switch (xform->cipher.algo) { + case RTE_CRYPTO_CIPHER_3DES_CBC: + case RTE_CRYPTO_CIPHER_AES_CBC: + case RTE_CRYPTO_CIPHER_AES_CTR: + case RTE_CRYPTO_CIPHER_AES_GCM: + sess->cipher.mode = LIBCRYPTO_CIPHER_LIB; + sess->cipher.algo = xform->cipher.algo; + sess->cipher.ctx = EVP_CIPHER_CTX_new(); + + if (get_cipher_algo(sess->cipher.algo, sess->cipher.key.length, + &sess->cipher.evp_algo) != 0) + return -EINVAL; + + get_cipher_key(xform->cipher.key.data, sess->cipher.key.length, + sess->cipher.key.data); + + break; + + case RTE_CRYPTO_CIPHER_3DES_CTR: + sess->cipher.mode = LIBCRYPTO_CIPHER_DES3CTR; + sess->cipher.ctx = EVP_CIPHER_CTX_new(); + + if (get_cipher_key_ede(xform->cipher.key.data, + sess->cipher.key.length, sess->cipher.key.data) != 0) + return -EINVAL; + break; + + default: + sess->cipher.algo = RTE_CRYPTO_CIPHER_NULL; + return -EINVAL; + } + + return 0; +} + +/* Set session auth parameters */ +static int +libcrypto_set_session_auth_parameters(struct libcrypto_session *sess, + const struct rte_crypto_sym_xform *xform) +{ + /* Select auth generate/verify */ + sess->auth.operation = xform->auth.op; + sess->auth.algo = xform->auth.algo; + + /* Select auth algo */ + switch (xform->auth.algo) { + case RTE_CRYPTO_AUTH_AES_GMAC: + case RTE_CRYPTO_AUTH_AES_GCM: + /* Check additional condition for AES_GMAC/GCM */ + if (sess->cipher.algo != RTE_CRYPTO_CIPHER_AES_GCM) + return -EINVAL; + sess->chain_order = LIBCRYPTO_CHAIN_COMBINED; + break; + + case RTE_CRYPTO_AUTH_MD5: + case RTE_CRYPTO_AUTH_SHA1: + case RTE_CRYPTO_AUTH_SHA224: + case RTE_CRYPTO_AUTH_SHA256: + case RTE_CRYPTO_AUTH_SHA384: + case RTE_CRYPTO_AUTH_SHA512: + sess->auth.mode = LIBCRYPTO_AUTH_AS_AUTH; + if (get_auth_algo(xform->auth.algo, &sess->auth.auth.evp_algo) != 0) + return -EINVAL; + sess->auth.auth.ctx = EVP_MD_CTX_create(); + break; + + case RTE_CRYPTO_AUTH_MD5_HMAC: + case RTE_CRYPTO_AUTH_SHA1_HMAC: + case RTE_CRYPTO_AUTH_SHA224_HMAC: + case RTE_CRYPTO_AUTH_SHA256_HMAC: + case RTE_CRYPTO_AUTH_SHA384_HMAC: + case RTE_CRYPTO_AUTH_SHA512_HMAC: + sess->auth.mode = LIBCRYPTO_AUTH_AS_HMAC; + sess->auth.hmac.ctx = EVP_MD_CTX_create(); + if (get_auth_algo(xform->auth.algo, &sess->auth.hmac.evp_algo) != 0) + return -EINVAL; + sess->auth.hmac.pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, + xform->auth.key.data, xform->auth.key.length); + break; + + default: + return -EINVAL; + } + + return 0; +} + +/** Parse crypto xform chain and set private session parameters */ +int +libcrypto_set_session_parameters(struct libcrypto_session *sess, + const struct rte_crypto_sym_xform *xform) +{ + const struct rte_crypto_sym_xform *cipher_xform = NULL; + const struct rte_crypto_sym_xform *auth_xform = NULL; + + sess->chain_order = libcrypto_get_chain_order(xform); + switch (sess->chain_order) { + case LIBCRYPTO_CHAIN_ONLY_CIPHER: + cipher_xform = xform; + break; + case LIBCRYPTO_CHAIN_ONLY_AUTH: + auth_xform = xform; + break; + case LIBCRYPTO_CHAIN_CIPHER_AUTH: + cipher_xform = xform; + auth_xform = xform->next; + break; + case LIBCRYPTO_CHAIN_AUTH_CIPHER: + auth_xform = xform; + cipher_xform = xform->next; + break; + default: + return -EINVAL; + } + + /* cipher_xform must be check before auth_xform */ + if (cipher_xform) { + if (libcrypto_set_session_cipher_parameters(sess, cipher_xform)) { + LIBCRYPTO_LOG_ERR( + "Invalid/unsupported cipher parameters"); + return -EINVAL; + } + } + + if (auth_xform) { + if (libcrypto_set_session_auth_parameters(sess, auth_xform)) { + LIBCRYPTO_LOG_ERR( + "Invalid/unsupported auth parameters"); + return -EINVAL; + } + } + + return 0; +} + +/** Reset private session parameters */ +void +libcrypto_reset_session(struct libcrypto_session *sess) +{ + EVP_CIPHER_CTX_free(sess->cipher.ctx); + + switch (sess->auth.mode) { + case LIBCRYPTO_AUTH_AS_AUTH: + EVP_MD_CTX_destroy(sess->auth.auth.ctx); + break; + case LIBCRYPTO_AUTH_AS_HMAC: + EVP_PKEY_free(sess->auth.hmac.pkey); + EVP_MD_CTX_destroy(sess->auth.hmac.ctx); + break; + default: + break; + } +} + +/** Provide session for operation */ +static struct libcrypto_session * +get_session(struct libcrypto_qp *qp, struct rte_crypto_op *op) +{ + struct libcrypto_session *sess = NULL; + + if (op->sym->sess_type == RTE_CRYPTO_SYM_OP_WITH_SESSION) { + /* get existing session */ + if (likely(op->sym->session != NULL && + op->sym->session->dev_type == + RTE_CRYPTODEV_LIBCRYPTO_PMD)) + sess = (struct libcrypto_session *) + op->sym->session->_private; + } else { + /* provide internal session */ + void *_sess = NULL; + + if (!rte_mempool_get(qp->sess_mp, (void **)&_sess)) { + sess = (struct libcrypto_session *) + ((struct rte_cryptodev_sym_session *)_sess) + ->_private; + + if (unlikely(libcrypto_set_session_parameters( + sess, op->sym->xform) != 0)) { + rte_mempool_put(qp->sess_mp, _sess); + sess = NULL; + } else + op->sym->session = _sess; + } + } + + if (sess == NULL) + op->status = RTE_CRYPTO_OP_STATUS_INVALID_SESSION; + + return sess; +} + +/* + *------------------------------------------------------------------------------ + * Process Operations + *------------------------------------------------------------------------------ + */ + +/** Process standard libcrypto cipher encryption */ +static int +process_libcrypto_cipher_encrypt(uint8_t *src, uint8_t *dst, + uint8_t *iv, uint8_t *key, int srclen, + EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo) +{ + int dstlen, totlen; + + if (EVP_EncryptInit_ex(ctx, algo, NULL, key, iv) <= 0) + goto process_cipher_encrypt_err; + + if (EVP_EncryptUpdate(ctx, dst, &dstlen, src, srclen) <= 0) + goto process_cipher_encrypt_err; + + if (EVP_EncryptFinal_ex(ctx, dst + dstlen, &totlen) <= 0) + goto process_cipher_encrypt_err; + + return 0; + +process_cipher_encrypt_err: + LIBCRYPTO_LOG_ERR("Process libcrypto cipher encrypt failed"); + return -EINVAL; +} + +/** Process standard libcrypto cipher decryption */ +static int +process_libcrypto_cipher_decrypt(uint8_t *src, uint8_t *dst, + uint8_t *iv, uint8_t *key, int srclen, + EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo) +{ + int dstlen, totlen; + + if (EVP_DecryptInit_ex(ctx, algo, NULL, key, iv) <= 0) + goto process_cipher_decrypt_err; + + if (EVP_CIPHER_CTX_set_padding(ctx, 0) <= 0) + goto process_cipher_decrypt_err; + + if (EVP_DecryptUpdate(ctx, dst, &dstlen, src, srclen) <= 0) + goto process_cipher_decrypt_err; + + if (EVP_DecryptFinal_ex(ctx, dst + dstlen, &totlen) <= 0) + goto process_cipher_decrypt_err; + + return 0; + +process_cipher_decrypt_err: + LIBCRYPTO_LOG_ERR("Process libcrypto cipher decrypt failed"); + return -EINVAL; +} + +/** Process cipher des 3 ctr encryption, decryption algorithm */ +static int +process_libcrypto_cipher_des3ctr(uint8_t *src, uint8_t *dst, + uint8_t *iv, uint8_t *key, int srclen, EVP_CIPHER_CTX *ctx) +{ + uint8_t ebuf[8], ctr[8]; + int unused, n; + + /* We use 3DES encryption also for decryption. + * IV is not important for 3DES ecb + */ + if (EVP_EncryptInit_ex(ctx, EVP_des_ede3_ecb(), NULL, key, NULL) <= 0) + goto process_cipher_des3ctr_err; + + memcpy(ctr, iv, 8); + n = 0; + + while (n < srclen) { + if (n % 8 == 0) { + if (EVP_EncryptUpdate(ctx, (unsigned char *)&ebuf, &unused, + (const unsigned char *)&ctr, 8) <= 0) + goto process_cipher_des3ctr_err; + ctr_inc(ctr); + } + dst[n] = src[n] ^ ebuf[n % 8]; + n++; + } + + return 0; + +process_cipher_des3ctr_err: + LIBCRYPTO_LOG_ERR("Process libcrypto cipher des 3 ede ctr failed"); + return -EINVAL; +} + +/** Process auth/encription aes-gcm algorithm */ +static int +process_libcrypto_auth_encryption_gcm(uint8_t *src, int srclen, + uint8_t *aad, int aadlen, uint8_t *iv, int ivlen, + uint8_t *key, uint8_t *dst, uint8_t *tag, + EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo) +{ + int len = 0, unused = 0; + uint8_t empty[] = {}; + + if (EVP_EncryptInit_ex(ctx, algo, NULL, NULL, NULL) <= 0) + goto process_auth_encryption_gcm_err; + + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, NULL) <= 0) + goto process_auth_encryption_gcm_err; + + if (EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv) <= 0) + goto process_auth_encryption_gcm_err; + + if (aadlen > 0) { + if (EVP_EncryptUpdate(ctx, NULL, &len, aad, aadlen) <= 0) + goto process_auth_encryption_gcm_err; + + /* Workaround open ssl bug in version less then 1.0.1f */ + if (EVP_EncryptUpdate(ctx, empty, &unused, empty, 0) <= 0) + goto process_auth_encryption_gcm_err; + } + + if (srclen > 0) + if (EVP_EncryptUpdate(ctx, dst, &len, src, srclen) <= 0) + goto process_auth_encryption_gcm_err; + + if (EVP_EncryptFinal_ex(ctx, dst + len, &len) <= 0) + goto process_auth_encryption_gcm_err; + + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag) <= 0) + goto process_auth_encryption_gcm_err; + + return 0; + +process_auth_encryption_gcm_err: + LIBCRYPTO_LOG_ERR("Process libcrypto auth encryption gcm failed"); + return -EINVAL; +} + +static int +process_libcrypto_auth_decryption_gcm(uint8_t *src, int srclen, + uint8_t *aad, int aadlen, uint8_t *iv, int ivlen, + uint8_t *key, uint8_t *dst, uint8_t *tag, + EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo) +{ + int len = 0, unused = 0; + uint8_t empty[] = {}; + + if (EVP_DecryptInit_ex(ctx, algo, NULL, NULL, NULL) <= 0) + goto process_auth_decryption_gcm_err; + + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, NULL) <= 0) + goto process_auth_decryption_gcm_err; + + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag) <= 0) + goto process_auth_decryption_gcm_err; + + if (EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv) <= 0) + goto process_auth_decryption_gcm_err; + + if (aadlen > 0) { + if (EVP_DecryptUpdate(ctx, NULL, &len, aad, aadlen) <= 0) + goto process_auth_decryption_gcm_err; + + /* Workaround open ssl bug in version less then 1.0.1f */ + if (EVP_DecryptUpdate(ctx, empty, &unused, empty, 0) <= 0) + goto process_auth_decryption_gcm_err; + } + + if (srclen > 0) + if (EVP_DecryptUpdate(ctx, dst, &len, src, srclen) <= 0) + goto process_auth_decryption_gcm_err; + + if (EVP_DecryptFinal_ex(ctx, dst + len, &len) <= 0) + goto process_auth_decryption_gcm_final_err; + + return 0; + +process_auth_decryption_gcm_err: + LIBCRYPTO_LOG_ERR("Process libcrypto auth decription gcm failed"); + return -EINVAL; + +process_auth_decryption_gcm_final_err: + return -EFAULT; +} + +/** Process standard libcrypto auth algorithms */ +static int +process_libcrypto_auth(uint8_t *src, uint8_t *dst, + __rte_unused uint8_t *iv, __rte_unused EVP_PKEY * pkey, + int srclen, EVP_MD_CTX *ctx, const EVP_MD *algo) +{ + size_t dstlen; + + if (EVP_DigestInit_ex(ctx, algo, NULL) <= 0) + goto process_auth_err; + + if (EVP_DigestUpdate(ctx, (char *)src, srclen) <= 0) + goto process_auth_err; + + if (EVP_DigestFinal_ex(ctx, dst, (unsigned int *)&dstlen) <= 0) + goto process_auth_err; + + return 0; + +process_auth_err: + LIBCRYPTO_LOG_ERR("Process libcrypto auth failed"); + return -EINVAL; +} + +/** Process standard libcrypto auth algorithms with hmac */ +static int +process_libcrypto_auth_hmac(uint8_t *src, uint8_t *dst, + __rte_unused uint8_t *iv, EVP_PKEY *pkey, + int srclen, EVP_MD_CTX *ctx, const EVP_MD *algo) +{ + size_t dstlen; + + if (EVP_DigestSignInit(ctx, NULL, algo, NULL, pkey) <= 0) + goto process_auth_err; + + if (EVP_DigestSignUpdate(ctx, (char *)src, srclen) <= 0) + goto process_auth_err; + + if (EVP_DigestSignFinal(ctx, dst, &dstlen) <= 0) + goto process_auth_err; + + return 0; + +process_auth_err: + LIBCRYPTO_LOG_ERR("Process libcrypto auth failed"); + return -EINVAL; +} + +/*----------------------------------------------------------------------------*/ + +/** Process auth/cipher combined operation */ +static void +process_libcrypto_combined_op + (struct rte_crypto_op *op, struct libcrypto_session *sess, + struct rte_mbuf *mbuf_src, struct rte_mbuf *mbuf_dst) +{ + /* cipher */ + uint8_t *src = NULL, *dst = NULL, *iv, *tag, *aad; + int srclen, ivlen, aadlen, status = -1; + + iv = op->sym->cipher.iv.data; + ivlen = op->sym->cipher.iv.length; + aad = op->sym->auth.aad.data; + aadlen = op->sym->auth.aad.length; + + tag = op->sym->auth.digest.data; + if (tag == NULL) + tag = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *, + op->sym->cipher.data.offset + + op->sym->cipher.data.length); + + if (sess->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) + srclen = 0; + else { + srclen = op->sym->cipher.data.length; + src = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *, + op->sym->cipher.data.offset); + dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *, + op->sym->cipher.data.offset); + } + + if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) + status = process_libcrypto_auth_encryption_gcm( + src, srclen, aad, aadlen, iv, ivlen, + sess->cipher.key.data, dst, tag, + sess->cipher.ctx, sess->cipher.evp_algo); + else + status = process_libcrypto_auth_decryption_gcm( + src, srclen, aad, aadlen, iv, ivlen, + sess->cipher.key.data, dst, tag, + sess->cipher.ctx, sess->cipher.evp_algo); + + if (status != 0) { + if (status == (-EFAULT) && + sess->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY) + op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED; + else + op->status = RTE_CRYPTO_OP_STATUS_ERROR; + } +} + +/** Process cipher operation */ +static void +process_libcrypto_cipher_op + (struct rte_crypto_op *op, struct libcrypto_session *sess, + struct rte_mbuf *mbuf_src, struct rte_mbuf *mbuf_dst) +{ + uint8_t *src, *dst, *iv; + int srclen, status; + + srclen = op->sym->cipher.data.length; + src = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *, + op->sym->cipher.data.offset); + dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *, + op->sym->cipher.data.offset); + + iv = op->sym->cipher.iv.data; + + if (sess->cipher.mode == LIBCRYPTO_CIPHER_LIB) + if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) + status = process_libcrypto_cipher_encrypt(src, dst, iv, + sess->cipher.key.data, srclen, + sess->cipher.ctx, sess->cipher.evp_algo); + else + status = process_libcrypto_cipher_decrypt(src, dst, iv, + sess->cipher.key.data, srclen, + sess->cipher.ctx, sess->cipher.evp_algo); + else + status = process_libcrypto_cipher_des3ctr(src, dst, iv, + sess->cipher.key.data, srclen, sess->cipher.ctx); + + if (status != 0) + op->status = RTE_CRYPTO_OP_STATUS_ERROR; +} + +/** Process auth operation */ +static void +process_libcrypto_auth_op + (struct rte_crypto_op *op, struct libcrypto_session *sess, + struct rte_mbuf *mbuf_src, struct rte_mbuf *mbuf_dst) +{ + uint8_t *src, *dst; + int srclen, status; + + srclen = op->sym->auth.data.length; + src = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *, + op->sym->auth.data.offset); + + if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY) + dst = (uint8_t *)rte_pktmbuf_append(mbuf_src, + op->sym->auth.digest.length); + else { + dst = op->sym->auth.digest.data; + if (dst == NULL) + dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *, + op->sym->auth.data.offset + + op->sym->auth.data.length); + } + + switch (sess->auth.mode) { + case LIBCRYPTO_AUTH_AS_AUTH: + status = process_libcrypto_auth(src, dst, + NULL, NULL, srclen, + sess->auth.auth.ctx, sess->auth.auth.evp_algo); + break; + case LIBCRYPTO_AUTH_AS_HMAC: + status = process_libcrypto_auth_hmac(src, dst, + NULL, sess->auth.hmac.pkey, srclen, + sess->auth.hmac.ctx, sess->auth.hmac.evp_algo); + break; + default: + status = -1; + break; + } + + if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY) { + if (memcmp(dst, op->sym->auth.digest.data, + op->sym->auth.digest.length) != 0) { + op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED; + } + /* Trim area used for digest from mbuf. */ + rte_pktmbuf_trim(mbuf_src, + op->sym->auth.digest.length); + } + + if (status != 0) + op->status = RTE_CRYPTO_OP_STATUS_ERROR; +} + +/** Process crypto operation for mbuf */ +static int +process_op(const struct libcrypto_qp *qp, struct rte_crypto_op *op, + struct libcrypto_session *sess) +{ + struct rte_mbuf *msrc, *mdst; + int retval; + + msrc = op->sym->m_src; + mdst = op->sym->m_dst ? op->sym->m_dst : op->sym->m_src; + + op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED; + + switch (sess->chain_order) { + case LIBCRYPTO_CHAIN_ONLY_CIPHER: + process_libcrypto_cipher_op(op, sess, msrc, mdst); + break; + case LIBCRYPTO_CHAIN_ONLY_AUTH: + process_libcrypto_auth_op(op, sess, msrc, mdst); + break; + case LIBCRYPTO_CHAIN_CIPHER_AUTH: + process_libcrypto_cipher_op(op, sess, msrc, mdst); + process_libcrypto_auth_op(op, sess, mdst, mdst); + break; + case LIBCRYPTO_CHAIN_AUTH_CIPHER: + process_libcrypto_auth_op(op, sess, msrc, mdst); + process_libcrypto_cipher_op(op, sess, msrc, mdst); + break; + case LIBCRYPTO_CHAIN_COMBINED: + process_libcrypto_combined_op(op, sess, msrc, mdst); + break; + default: + op->status = RTE_CRYPTO_OP_STATUS_ERROR; + break; + } + + /* Free session if a session-less crypto op */ + if (op->sym->sess_type == RTE_CRYPTO_SYM_OP_SESSIONLESS) { + libcrypto_reset_session(sess); + memset(sess, 0, sizeof(struct libcrypto_session)); + rte_mempool_put(qp->sess_mp, op->sym->session); + op->sym->session = NULL; + } + + + if (op->status == RTE_CRYPTO_OP_STATUS_NOT_PROCESSED) + op->status = RTE_CRYPTO_OP_STATUS_SUCCESS; + + if (op->status != RTE_CRYPTO_OP_STATUS_ERROR) + retval = rte_ring_enqueue(qp->processed_ops, (void *)op); + else + retval = -1; + + return retval; +} + +/* + *------------------------------------------------------------------------------ + * PMD Framework + *------------------------------------------------------------------------------ + */ + +/** Enqueue burst */ +static uint16_t +libcrypto_pmd_enqueue_burst(void *queue_pair, struct rte_crypto_op **ops, + uint16_t nb_ops) +{ + struct libcrypto_session *sess; + struct libcrypto_qp *qp = queue_pair; + int i, retval; + + for (i = 0; i < nb_ops; i++) { + sess = get_session(qp, ops[i]); + if (unlikely(sess == NULL)) + goto enqueue_err; + + retval = process_op(qp, ops[i], sess); + if (unlikely(retval < 0)) + goto enqueue_err; + } + + qp->stats.enqueued_count += i; + return i; + +enqueue_err: + qp->stats.enqueue_err_count++; + return i; +} + +/** Dequeue burst */ +static uint16_t +libcrypto_pmd_dequeue_burst(void *queue_pair, struct rte_crypto_op **ops, + uint16_t nb_ops) +{ + struct libcrypto_qp *qp = queue_pair; + + unsigned int nb_dequeued = 0; + + nb_dequeued = rte_ring_dequeue_burst(qp->processed_ops, + (void **)ops, nb_ops); + qp->stats.dequeued_count += nb_dequeued; + + return nb_dequeued; +} + +/** Create LIBCRYPTO crypto device */ +static int +cryptodev_libcrypto_create(const char *name, + struct rte_crypto_vdev_init_params *init_params) +{ + struct rte_cryptodev *dev; + char crypto_dev_name[RTE_CRYPTODEV_NAME_MAX_LEN]; + struct libcrypto_private *internals; + + /* create a unique device name */ + if (create_unique_device_name(crypto_dev_name, + RTE_CRYPTODEV_NAME_MAX_LEN) != 0) { + LIBCRYPTO_LOG_ERR("failed to create unique cryptodev name"); + return -EINVAL; + } + + dev = rte_cryptodev_pmd_virtual_dev_init(crypto_dev_name, + sizeof(struct libcrypto_private), init_params->socket_id); + if (dev == NULL) { + LIBCRYPTO_LOG_ERR("failed to create cryptodev vdev"); + goto init_error; + } + + dev->dev_type = RTE_CRYPTODEV_LIBCRYPTO_PMD; + dev->dev_ops = rte_libcrypto_pmd_ops; + + /* register rx/tx burst functions for data path */ + dev->dequeue_burst = libcrypto_pmd_dequeue_burst; + dev->enqueue_burst = libcrypto_pmd_enqueue_burst; + + dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO | + RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING | + RTE_CRYPTODEV_FF_CPU_AESNI; + + /* Set vector instructions mode supported */ + internals = dev->data->dev_private; + + internals->max_nb_qpairs = init_params->max_nb_queue_pairs; + internals->max_nb_sessions = init_params->max_nb_sessions; + + return 0; + +init_error: + LIBCRYPTO_LOG_ERR("driver %s: cryptodev_libcrypto_create failed", name); + + cryptodev_libcrypto_uninit(crypto_dev_name); + return -EFAULT; +} + +/** Initialise LIBCRYPTO crypto device */ +static int +cryptodev_libcrypto_init(const char *name, + const char *input_args) +{ + struct rte_crypto_vdev_init_params init_params = { + RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_QUEUE_PAIRS, + RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_SESSIONS, + rte_socket_id() + }; + + rte_cryptodev_parse_vdev_init_params(&init_params, input_args); + + RTE_LOG(INFO, PMD, "Initialising %s on NUMA node %d\n", name, + init_params.socket_id); + RTE_LOG(INFO, PMD, " Max number of queue pairs = %d\n", + init_params.max_nb_queue_pairs); + RTE_LOG(INFO, PMD, " Max number of sessions = %d\n", + init_params.max_nb_sessions); + + return cryptodev_libcrypto_create(name, &init_params); +} + +/** Uninitialise LIBCRYPTO crypto device */ +static int +cryptodev_libcrypto_uninit(const char *name) +{ + if (name == NULL) + return -EINVAL; + + RTE_LOG(INFO, PMD, + "Closing LIBCRYPTO crypto device %s on numa socket %u\n", + name, rte_socket_id()); + + return 0; +} + +static struct rte_driver cryptodev_libcrypto_pmd_drv = { + .type = PMD_VDEV, + .init = cryptodev_libcrypto_init, + .uninit = cryptodev_libcrypto_uninit +}; + +PMD_REGISTER_DRIVER(cryptodev_libcrypto_pmd_drv, CRYPTODEV_NAME_LIBCRYPTO_PMD); +DRIVER_REGISTER_PARAM_STRING(CRYPTODEV_NAME_LIBCRYPTO_PMD, + "max_nb_queue_pairs=<int> " + "max_nb_sessions=<int> " + "socket_id=<int>"); diff --git a/drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c b/drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c new file mode 100644 index 0000000..b5d7bd5 --- /dev/null +++ b/drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c @@ -0,0 +1,708 @@ +/*- + * 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 <string.h> + +#include <rte_common.h> +#include <rte_malloc.h> +#include <rte_cryptodev_pmd.h> + +#include "rte_libcrypto_pmd_private.h" + + +static const struct rte_cryptodev_capabilities libcrypto_pmd_capabilities[] = { + { /* MD5 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_MD5_HMAC, + .block_size = 64, + .key_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .digest_size = { + .min = 16, + .max = 16, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* MD5 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_MD5, + .block_size = 64, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 16, + .max = 16, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA1 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .block_size = 64, + .key_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .digest_size = { + .min = 20, + .max = 20, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA1 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA1, + .block_size = 64, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 20, + .max = 20, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA224 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA224_HMAC, + .block_size = 64, + .key_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .digest_size = { + .min = 28, + .max = 28, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA224 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA224, + .block_size = 64, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 28, + .max = 28, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA256 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA256_HMAC, + .block_size = 64, + .key_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .digest_size = { + .min = 32, + .max = 32, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA256 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA256, + .block_size = 64, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 32, + .max = 32, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA384 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA384_HMAC, + .block_size = 128, + .key_size = { + .min = 128, + .max = 128, + .increment = 0 + }, + .digest_size = { + .min = 48, + .max = 48, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA384 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA384, + .block_size = 128, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 48, + .max = 48, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA512 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA512_HMAC, + .block_size = 128, + .key_size = { + .min = 128, + .max = 128, + .increment = 0 + }, + .digest_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA512 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA512, + .block_size = 128, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* AES CBC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, + {.cipher = { + .algo = RTE_CRYPTO_CIPHER_AES_CBC, + .block_size = 16, + .key_size = { + .min = 16, + .max = 32, + .increment = 8 + }, + .iv_size = { + .min = 16, + .max = 16, + .increment = 0 + } + }, } + }, } + }, + { /* AES CTR */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, + {.cipher = { + .algo = RTE_CRYPTO_CIPHER_AES_CTR, + .block_size = 16, + .key_size = { + .min = 16, + .max = 32, + .increment = 8 + }, + .iv_size = { + .min = 16, + .max = 16, + .increment = 0 + } + }, } + }, } + }, + { /* AES GCM (AUTH) */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_AES_GCM, + .block_size = 16, + .key_size = { + .min = 16, + .max = 32, + .increment = 8 + }, + .digest_size = { + .min = 16, + .max = 16, + .increment = 0 + }, + .aad_size = { + .min = 8, + .max = 12, + .increment = 4 + } + }, } + }, } + }, + { /* AES GCM (CIPHER) */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, + {.cipher = { + .algo = RTE_CRYPTO_CIPHER_AES_GCM, + .block_size = 16, + .key_size = { + .min = 16, + .max = 16, + .increment = 0 + }, + .iv_size = { + .min = 12, + .max = 16, + .increment = 4 + } + }, } + }, } + }, + { /* AES GMAC (AUTH) */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_AES_GMAC, + .block_size = 16, + .key_size = { + .min = 16, + .max = 32, + .increment = 8 + }, + .digest_size = { + .min = 16, + .max = 16, + .increment = 0 + }, + .aad_size = { + .min = 8, + .max = 65532, + .increment = 4 + } + }, } + }, } + }, + { /* 3DES CBC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, + {.cipher = { + .algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .block_size = 8, + .key_size = { + .min = 16, + .max = 24, + .increment = 8 + }, + .iv_size = { + .min = 8, + .max = 8, + .increment = 0 + } + }, } + }, } + }, + { /* 3DES CTR */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, + {.cipher = { + .algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .block_size = 8, + .key_size = { + .min = 16, + .max = 24, + .increment = 8 + }, + .iv_size = { + .min = 8, + .max = 8, + .increment = 0 + } + }, } + }, } + }, + + RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST() +}; + + +/** Configure device */ +static int +libcrypto_pmd_config(__rte_unused struct rte_cryptodev *dev) +{ + return 0; +} + +/** Start device */ +static int +libcrypto_pmd_start(__rte_unused struct rte_cryptodev *dev) +{ + return 0; +} + +/** Stop device */ +static void +libcrypto_pmd_stop(__rte_unused struct rte_cryptodev *dev) +{ +} + +/** Close device */ +static int +libcrypto_pmd_close(__rte_unused struct rte_cryptodev *dev) +{ + return 0; +} + + +/** Get device statistics */ +static void +libcrypto_pmd_stats_get(struct rte_cryptodev *dev, + struct rte_cryptodev_stats *stats) +{ + int qp_id; + + for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) { + struct libcrypto_qp *qp = dev->data->queue_pairs[qp_id]; + + stats->enqueued_count += qp->stats.enqueued_count; + stats->dequeued_count += qp->stats.dequeued_count; + + stats->enqueue_err_count += qp->stats.enqueue_err_count; + stats->dequeue_err_count += qp->stats.dequeue_err_count; + } +} + +/** Reset device statistics */ +static void +libcrypto_pmd_stats_reset(struct rte_cryptodev *dev) +{ + int qp_id; + + for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) { + struct libcrypto_qp *qp = dev->data->queue_pairs[qp_id]; + + memset(&qp->stats, 0, sizeof(qp->stats)); + } +} + + +/** Get device info */ +static void +libcrypto_pmd_info_get(struct rte_cryptodev *dev, + struct rte_cryptodev_info *dev_info) +{ + struct libcrypto_private *internals = dev->data->dev_private; + + if (dev_info != NULL) { + dev_info->dev_type = dev->dev_type; + dev_info->feature_flags = dev->feature_flags; + dev_info->capabilities = libcrypto_pmd_capabilities; + dev_info->max_nb_queue_pairs = internals->max_nb_qpairs; + dev_info->sym.max_nb_sessions = internals->max_nb_sessions; + } +} + +/** Release queue pair */ +static int +libcrypto_pmd_qp_release(struct rte_cryptodev *dev, uint16_t qp_id) +{ + if (dev->data->queue_pairs[qp_id] != NULL) { + rte_free(dev->data->queue_pairs[qp_id]); + dev->data->queue_pairs[qp_id] = NULL; + } + return 0; +} + +/** set a unique name for the queue pair based on it's name, dev_id and qp_id */ +static int +libcrypto_pmd_qp_set_unique_name(struct rte_cryptodev *dev, + struct libcrypto_qp *qp) +{ + unsigned int n = snprintf(qp->name, sizeof(qp->name), + "libcrypto_pmd_%u_qp_%u", + dev->data->dev_id, qp->id); + + if (n > sizeof(qp->name)) + return -1; + + return 0; +} + + +/** Create a ring to place processed operations on */ +static struct rte_ring * +libcrypto_pmd_qp_create_processed_ops_ring(struct libcrypto_qp *qp, + unsigned int ring_size, int socket_id) +{ + struct rte_ring *r; + + r = rte_ring_lookup(qp->name); + if (r) { + if (r->prod.size >= ring_size) { + LIBCRYPTO_LOG_INFO( + "Reusing existing ring %s for processed ops", + qp->name); + return r; + } + + LIBCRYPTO_LOG_ERR( + "Unable to reuse existing ring %s for processed ops", + qp->name); + return NULL; + } + + return rte_ring_create(qp->name, ring_size, socket_id, + RING_F_SP_ENQ | RING_F_SC_DEQ); +} + + +/** Setup a queue pair */ +static int +libcrypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id, + const struct rte_cryptodev_qp_conf *qp_conf, + int socket_id) +{ + struct libcrypto_qp *qp = NULL; + + /* Free memory prior to re-allocation if needed. */ + if (dev->data->queue_pairs[qp_id] != NULL) + libcrypto_pmd_qp_release(dev, qp_id); + + /* Allocate the queue pair data structure. */ + qp = rte_zmalloc_socket("LIBCRYPTO PMD Queue Pair", sizeof(*qp), + RTE_CACHE_LINE_SIZE, socket_id); + if (qp == NULL) + return -ENOMEM; + + qp->id = qp_id; + dev->data->queue_pairs[qp_id] = qp; + + if (libcrypto_pmd_qp_set_unique_name(dev, qp)) + goto qp_setup_cleanup; + + qp->processed_ops = libcrypto_pmd_qp_create_processed_ops_ring(qp, + qp_conf->nb_descriptors, socket_id); + if (qp->processed_ops == NULL) + goto qp_setup_cleanup; + + qp->sess_mp = dev->data->session_pool; + + memset(&qp->stats, 0, sizeof(qp->stats)); + + return 0; + +qp_setup_cleanup: + if (qp) + rte_free(qp); + + return -1; +} + +/** Start queue pair */ +static int +libcrypto_pmd_qp_start(__rte_unused struct rte_cryptodev *dev, + __rte_unused uint16_t queue_pair_id) +{ + return -ENOTSUP; +} + +/** Stop queue pair */ +static int +libcrypto_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev, + __rte_unused uint16_t queue_pair_id) +{ + return -ENOTSUP; +} + +/** Return the number of allocated queue pairs */ +static uint32_t +libcrypto_pmd_qp_count(struct rte_cryptodev *dev) +{ + return dev->data->nb_queue_pairs; +} + +/** Returns the size of the session structure */ +static unsigned +libcrypto_pmd_session_get_size(struct rte_cryptodev *dev __rte_unused) +{ + return sizeof(struct libcrypto_session); +} + +/** Configure the session from a crypto xform chain */ +static void * +libcrypto_pmd_session_configure(struct rte_cryptodev *dev __rte_unused, + struct rte_crypto_sym_xform *xform, void *sess) +{ + if (unlikely(sess == NULL)) { + LIBCRYPTO_LOG_ERR("invalid session struct"); + return NULL; + } + + if (libcrypto_set_session_parameters( + sess, xform) != 0) { + LIBCRYPTO_LOG_ERR("failed configure session parameters"); + return NULL; + } + + return sess; +} + + +/** Clear the memory of session so it doesn't leave key material behind */ +static void +libcrypto_pmd_session_clear(struct rte_cryptodev *dev __rte_unused, void *sess) +{ + /* + * Current just resetting the whole data structure, need to investigate + * whether a more selective reset of key would be more performant + */ + if (sess) { + libcrypto_reset_session(sess); + memset(sess, 0, sizeof(struct libcrypto_session)); + } +} + +struct rte_cryptodev_ops libcrypto_pmd_ops = { + .dev_configure = libcrypto_pmd_config, + .dev_start = libcrypto_pmd_start, + .dev_stop = libcrypto_pmd_stop, + .dev_close = libcrypto_pmd_close, + + .stats_get = libcrypto_pmd_stats_get, + .stats_reset = libcrypto_pmd_stats_reset, + + .dev_infos_get = libcrypto_pmd_info_get, + + .queue_pair_setup = libcrypto_pmd_qp_setup, + .queue_pair_release = libcrypto_pmd_qp_release, + .queue_pair_start = libcrypto_pmd_qp_start, + .queue_pair_stop = libcrypto_pmd_qp_stop, + .queue_pair_count = libcrypto_pmd_qp_count, + + .session_get_size = libcrypto_pmd_session_get_size, + .session_configure = libcrypto_pmd_session_configure, + .session_clear = libcrypto_pmd_session_clear +}; + +struct rte_cryptodev_ops *rte_libcrypto_pmd_ops = &libcrypto_pmd_ops; diff --git a/drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h b/drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h new file mode 100644 index 0000000..dbef57f --- /dev/null +++ b/drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h @@ -0,0 +1,174 @@ +/*- + * 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 _LIBCRYPTO_PMD_PRIVATE_H_ +#define _LIBCRYPTO_PMD_PRIVATE_H_ + +#include <openssl/evp.h> +#include <openssl/des.h> + + +#define LIBCRYPTO_LOG_ERR(fmt, args...) \ + RTE_LOG(ERR, CRYPTODEV, "[%s] %s() line %u: " fmt "\n", \ + RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), \ + __func__, __LINE__, ## args) + +#ifdef RTE_LIBRTE_LIBCRYPTO_DEBUG +#define LIBCRYPTO_LOG_INFO(fmt, args...) \ + RTE_LOG(INFO, CRYPTODEV, "[%s] %s() line %u: " fmt "\n", \ + RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), \ + __func__, __LINE__, ## args) + +#define LIBCRYPTO_LOG_DBG(fmt, args...) \ + RTE_LOG(DEBUG, CRYPTODEV, "[%s] %s() line %u: " fmt "\n", \ + RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), \ + __func__, __LINE__, ## args) +#else +#define LIBCRYPTO_LOG_INFO(fmt, args...) +#define LIBCRYPTO_LOG_DBG(fmt, args...) +#endif + + +/** LIBCRYPTO operation order mode enumerator */ +enum libcrypto_chain_order { + LIBCRYPTO_CHAIN_ONLY_CIPHER, + LIBCRYPTO_CHAIN_ONLY_AUTH, + LIBCRYPTO_CHAIN_CIPHER_AUTH, + LIBCRYPTO_CHAIN_AUTH_CIPHER, + LIBCRYPTO_CHAIN_COMBINED, + LIBCRYPTO_CHAIN_NOT_SUPPORTED +}; + +/** LIBCRYPTO cipher mode enumerator */ +enum libcrypto_cipher_mode { + LIBCRYPTO_CIPHER_LIB, + LIBCRYPTO_CIPHER_DES3CTR, +}; + +/** LIBCRYPTO auth mode enumerator */ +enum libcrypto_auth_mode { + LIBCRYPTO_AUTH_AS_AUTH, + LIBCRYPTO_AUTH_AS_HMAC, +}; + +/** private data structure for each LIBCRYPTO crypto device */ +struct libcrypto_private { + unsigned int max_nb_qpairs; + /**< Max number of queue pairs */ + unsigned int max_nb_sessions; + /**< Max number of sessions */ +}; + +/** LIBCRYPTO crypto queue pair */ +struct libcrypto_qp { + uint16_t id; + /**< Queue Pair Identifier */ + char name[RTE_CRYPTODEV_NAME_LEN]; + /**< Unique Queue Pair Name */ + struct rte_ring *processed_ops; + /**< Ring for placing process packets */ + struct rte_mempool *sess_mp; + /**< Session Mempool */ + struct rte_cryptodev_stats stats; + /**< Queue pair statistics */ +} __rte_cache_aligned; + +/** LIBCRYPTO crypto private session structure */ +struct libcrypto_session { + enum libcrypto_chain_order chain_order; + /**< chain order mode */ + + /** Cipher Parameters */ + struct { + enum rte_crypto_cipher_operation direction; + /**< cipher operation direction */ + enum libcrypto_cipher_mode mode; + /**< cipher operation mode */ + enum rte_crypto_cipher_algorithm algo; + /**< cipher algorithm */ + + struct { + uint8_t data[32]; + /**< key data */ + size_t length; + /**< key length in bytes */ + } key; + + const EVP_CIPHER *evp_algo; + /**< pointer to EVP algorithm function */ + EVP_CIPHER_CTX *ctx; + /**< pointer to EVP context structure */ + } cipher; + + /** Authentication Parameters */ + struct { + enum rte_crypto_auth_operation operation; + /**< auth operation generate or verify */ + enum libcrypto_auth_mode mode; + /**< auth operation mode */ + enum rte_crypto_auth_algorithm algo; + /**< cipher algorithm */ + + union { + struct { + const EVP_MD *evp_algo; + /**< pointer to EVP algorithm function */ + EVP_MD_CTX *ctx; + /**< pointer to EVP context structure */ + } auth; + + struct { + EVP_PKEY *pkey; + /**< pointer to EVP key */ + const EVP_MD *evp_algo; + /**< pointer to EVP algorithm function */ + EVP_MD_CTX *ctx; + /**< pointer to EVP context structure */ + } hmac; + }; + } auth; + +} __rte_cache_aligned; + +/** Set and validate LIBCRYPTO crypto session parameters */ +extern int +libcrypto_set_session_parameters(struct libcrypto_session *sess, + const struct rte_crypto_sym_xform *xform); + +/** Reset LIBCRYPTO crypto session parameters */ +extern void +libcrypto_reset_session(struct libcrypto_session *sess); + +/** device specific operations function pointer structure */ +extern struct rte_cryptodev_ops *rte_libcrypto_pmd_ops; + +#endif /* _LIBCRYPTO_PMD_PRIVATE_H_ */ diff --git a/drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map b/drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map new file mode 100644 index 0000000..cc5829e --- /dev/null +++ b/drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map @@ -0,0 +1,3 @@ +DPDK_16.11 { + local: *; +}; diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h index b1658eb..311fd78 100644 --- a/lib/librte_cryptodev/rte_cryptodev.h +++ b/lib/librte_cryptodev/rte_cryptodev.h @@ -56,6 +56,8 @@ extern "C" { /**< AES-NI Multi buffer PMD device name */ #define CRYPTODEV_NAME_AESNI_GCM_PMD crypto_aesni_gcm /**< AES-NI GCM PMD device name */ +#define CRYPTODEV_NAME_LIBCRYPTO_PMD cryptodev_libcrypto +/**< Open SSL Crypto PMD device name */ #define CRYPTODEV_NAME_QAT_SYM_PMD crypto_qat /**< Intel QAT Symmetric Crypto PMD device name */ #define CRYPTODEV_NAME_SNOW3G_PMD crypto_snow3g @@ -73,7 +75,8 @@ enum rte_cryptodev_type { RTE_CRYPTODEV_QAT_SYM_PMD, /**< QAT PMD Symmetric Crypto */ RTE_CRYPTODEV_SNOW3G_PMD, /**< SNOW 3G PMD */ RTE_CRYPTODEV_KASUMI_PMD, /**< KASUMI PMD */ - RTE_CRYPTODEV_ZUC_PMD /**< ZUC PMD */ + RTE_CRYPTODEV_ZUC_PMD, /**< ZUC PMD */ + RTE_CRYPTODEV_LIBCRYPTO_PMD, /**< LibCrypto PMD */ }; extern const char **rte_cyptodev_names; diff --git a/mk/rte.app.mk b/mk/rte.app.mk index 440bf83..43ea1c1 100644 --- a/mk/rte.app.mk +++ b/mk/rte.app.mk @@ -131,18 +131,19 @@ endif # $(CONFIG_RTE_LIBRTE_VHOST) _LDLIBS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += -lrte_pmd_vmxnet3_uio ifeq ($(CONFIG_RTE_LIBRTE_CRYPTODEV),y) -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -lrte_pmd_aesni_mb -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += -lrte_pmd_aesni_gcm -lcrypto -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -lrte_pmd_aesni_mb +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += -lrte_pmd_aesni_gcm -lcrypto +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += -lrte_pmd_libcrypto -lcrypto _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO) += -lrte_pmd_null_crypto -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += -lrte_pmd_qat -lcrypto -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += -lrte_pmd_snow3g -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += -L$(LIBSSO_SNOW3G_PATH)/build -lsso_snow3g -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI) += -lrte_pmd_kasumi -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI) += -L$(LIBSSO_KASUMI_PATH)/build -lsso_kasumi -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_ZUC) += -lrte_pmd_zuc -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_ZUC) += -L$(LIBSSO_ZUC_PATH)/build -lsso_zuc +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += -lrte_pmd_qat -lcrypto +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += -lrte_pmd_snow3g +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += -L$(LIBSSO_SNOW3G_PATH)/build -lsso_snow3g +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI) += -lrte_pmd_kasumi +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI) += -L$(LIBSSO_KASUMI_PATH)/build -lsso_kasumi +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_ZUC) += -lrte_pmd_zuc +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_ZUC) += -L$(LIBSSO_ZUC_PATH)/build -lsso_zuc endif # CONFIG_RTE_LIBRTE_CRYPTODEV endif # !CONFIG_RTE_BUILD_SHARED_LIBS -- 2.5.0 ^ permalink raw reply [flat|nested] 34+ messages in thread
* [dpdk-dev] [PATCH v5 2/4] app/test: cryptodev AES tests rework 2016-10-03 14:26 ` [dpdk-dev] [PATCH v5 0/4] new crypto software based device Slawomir Mrozowicz 2016-10-03 14:45 ` [dpdk-dev] [PATCH v5 1/4] libcrypto_pmd: initial implementation of SW crypto device Slawomir Mrozowicz @ 2016-10-03 15:02 ` Slawomir Mrozowicz 2016-10-03 15:17 ` [dpdk-dev] [PATCH v5 3/4] app/test: added tests for libcrypto PMD Slawomir Mrozowicz ` (3 subsequent siblings) 5 siblings, 0 replies; 34+ messages in thread From: Slawomir Mrozowicz @ 2016-10-03 15:02 UTC (permalink / raw) To: dev; +Cc: Slawomir Mrozowicz, Piotr Azarewicz, Fiona Trahe This patch rework AES tests . In general - rename AES-named functions to blockcipher functions pattern. Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com> Signed-off-by: Fiona Trahe <fiona.trahe@intel.com> --- app/test/Makefile | 2 +- app/test/test_cryptodev.c | 74 +- app/test/test_cryptodev_aes.c | 687 ----------------- app/test/test_cryptodev_aes.h | 1124 ---------------------------- app/test/test_cryptodev_aes_test_vectors.h | 797 ++++++++++++++++++++ app/test/test_cryptodev_blockcipher.c | 509 +++++++++++++ app/test/test_cryptodev_blockcipher.h | 124 +++ 7 files changed, 1478 insertions(+), 1839 deletions(-) delete mode 100644 app/test/test_cryptodev_aes.c delete mode 100644 app/test/test_cryptodev_aes.h create mode 100644 app/test/test_cryptodev_aes_test_vectors.h create mode 100644 app/test/test_cryptodev_blockcipher.c create mode 100644 app/test/test_cryptodev_blockcipher.h diff --git a/app/test/Makefile b/app/test/Makefile index 611d77a..5be023a 100644 --- a/app/test/Makefile +++ b/app/test/Makefile @@ -193,7 +193,7 @@ endif SRCS-$(CONFIG_RTE_LIBRTE_PMD_RING) += test_pmd_ring.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_RING) += test_pmd_ring_perf.c -SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_aes.c +SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_blockcipher.c SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_perf.c SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev.c diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c index 9d7caba..c46db94 100644 --- a/app/test/test_cryptodev.c +++ b/app/test/test_cryptodev.c @@ -43,7 +43,8 @@ #include "test.h" #include "test_cryptodev.h" -#include "test_cryptodev_aes.h" +#include "test_cryptodev_blockcipher.h" +#include "test_cryptodev_aes_test_vectors.h" #include "test_cryptodev_kasumi_test_vectors.h" #include "test_cryptodev_kasumi_hash_test_vectors.h" #include "test_cryptodev_snow3g_test_vectors.h" @@ -86,12 +87,16 @@ struct crypto_unittest_params { */ static int test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( - struct crypto_unittest_params *ut_params); + struct crypto_unittest_params *ut_params, uint8_t *cipher_key, + uint8_t *hmac_key); static int test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, struct crypto_unittest_params *ut_params, - struct crypto_testsuite_params *ts_param); + struct crypto_testsuite_params *ts_param, + const uint8_t *cipher, + const uint8_t *digest, + const uint8_t *iv); static struct rte_mbuf * setup_test_string(struct rte_mempool *mpool, @@ -313,7 +318,7 @@ testsuite_setup(void) nb_devs = rte_cryptodev_count(); if (nb_devs < 1) { - RTE_LOG(ERR, USER1, "No crypto devices found?"); + RTE_LOG(ERR, USER1, "No crypto devices found?\n"); return TEST_FAILED; } @@ -872,7 +877,6 @@ static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA1_digest[] = { 0x18, 0x8c, 0x1d, 0x32 }; - static int test_AES_CBC_HMAC_SHA1_encrypt_digest(void) { @@ -1003,17 +1007,24 @@ static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA512_digest[] = { static int test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( - struct crypto_unittest_params *ut_params); + struct crypto_unittest_params *ut_params, + uint8_t *cipher_key, + uint8_t *hmac_key); static int test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, struct crypto_unittest_params *ut_params, - struct crypto_testsuite_params *ts_params); + struct crypto_testsuite_params *ts_params, + const uint8_t *cipher, + const uint8_t *digest, + const uint8_t *iv); static int test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( - struct crypto_unittest_params *ut_params) + struct crypto_unittest_params *ut_params, + uint8_t *cipher_key, + uint8_t *hmac_key) { /* Setup Cipher Parameters */ @@ -1022,7 +1033,7 @@ test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC; ut_params->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT; - ut_params->cipher_xform.cipher.key.data = aes_cbc_key; + ut_params->cipher_xform.cipher.key.data = cipher_key; ut_params->cipher_xform.cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC; /* Setup HMAC Parameters */ @@ -1031,7 +1042,7 @@ test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SHA512_HMAC; - ut_params->auth_xform.auth.key.data = hmac_sha512_key; + ut_params->auth_xform.auth.key.data = hmac_key; ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA512; ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA512; @@ -1042,12 +1053,15 @@ test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( static int test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, struct crypto_unittest_params *ut_params, - struct crypto_testsuite_params *ts_params) + struct crypto_testsuite_params *ts_params, + const uint8_t *cipher, + const uint8_t *digest, + const uint8_t *iv) { /* Generate test mbuf data and digest */ ut_params->ibuf = setup_test_string(ts_params->mbuf_pool, (const char *) - catch_22_quote_2_512_bytes_AES_CBC_ciphertext, + cipher, QUOTE_512_BYTES, 0); ut_params->digest = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, @@ -1055,7 +1069,7 @@ test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, TEST_ASSERT_NOT_NULL(ut_params->digest, "no room to append digest"); rte_memcpy(ut_params->digest, - catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA512_digest, + digest, DIGEST_BYTE_LENGTH_SHA512); /* Generate Crypto op data structure */ @@ -1085,7 +1099,7 @@ test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, ut_params->ibuf, 0); sym_op->cipher.iv.length = CIPHER_IV_LENGTH_AES_CBC; - rte_memcpy(sym_op->cipher.iv.data, aes_cbc_iv, + rte_memcpy(sym_op->cipher.iv.data, iv, CIPHER_IV_LENGTH_AES_CBC); sym_op->cipher.data.offset = CIPHER_IV_LENGTH_AES_CBC; @@ -1115,14 +1129,15 @@ test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, } static int -test_AES_mb_all(void) +test_AES_chain_mb_all(void) { struct crypto_testsuite_params *ts_params = &testsuite_params; int status; - status = test_AES_all_tests(ts_params->mbuf_pool, + status = test_blockcipher_all_tests(ts_params->mbuf_pool, ts_params->op_mpool, ts_params->valid_devs[0], - RTE_CRYPTODEV_AESNI_MB_PMD); + RTE_CRYPTODEV_AESNI_MB_PMD, + BLKCIPHER_AES_CHAIN_TYPE); TEST_ASSERT_EQUAL(status, 0, "Test failed"); @@ -1130,14 +1145,15 @@ test_AES_mb_all(void) } static int -test_AES_qat_all(void) +test_AES_chain_qat_all(void) { struct crypto_testsuite_params *ts_params = &testsuite_params; int status; - status = test_AES_all_tests(ts_params->mbuf_pool, + status = test_blockcipher_all_tests(ts_params->mbuf_pool, ts_params->op_mpool, ts_params->valid_devs[0], - RTE_CRYPTODEV_QAT_SYM_PMD); + RTE_CRYPTODEV_QAT_SYM_PMD, + BLKCIPHER_AES_CHAIN_TYPE); TEST_ASSERT_EQUAL(status, 0, "Test failed"); @@ -4024,7 +4040,8 @@ test_multi_session(void) uint16_t i; - test_AES_CBC_HMAC_SHA512_decrypt_create_session_params(ut_params); + test_AES_CBC_HMAC_SHA512_decrypt_create_session_params(ut_params, + aes_cbc_key, hmac_sha512_key); rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info); @@ -4043,10 +4060,13 @@ test_multi_session(void) i); /* Attempt to send a request on each session */ - TEST_ASSERT_SUCCESS(test_AES_CBC_HMAC_SHA512_decrypt_perform( - sessions[i], ut_params, ts_params), - "Failed to perform decrypt on request " - "number %u.", i); + TEST_ASSERT_SUCCESS( + test_AES_CBC_HMAC_SHA512_decrypt_perform(sessions[i], ut_params, + ts_params, + catch_22_quote_2_512_bytes_AES_CBC_ciphertext, + catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA512_digest, + aes_cbc_iv), + "Failed to perform decrypt on request number %u.", i); /* free crypto operation structure */ if (ut_params->op) rte_crypto_op_free(ut_params->op); @@ -4700,7 +4720,7 @@ static struct unit_test_suite cryptodev_qat_testsuite = { TEST_CASE_ST(ut_setup, ut_teardown, test_multi_session), - TEST_CASE_ST(ut_setup, ut_teardown, test_AES_qat_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_qat_all), TEST_CASE_ST(ut_setup, ut_teardown, test_stats), /** AES GCM Authenticated Encryption */ @@ -4836,7 +4856,7 @@ static struct unit_test_suite cryptodev_aesni_mb_testsuite = { .setup = testsuite_setup, .teardown = testsuite_teardown, .unit_test_cases = { - TEST_CASE_ST(ut_setup, ut_teardown, test_AES_mb_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_mb_all), TEST_CASES_END() /**< NULL terminate unit test array */ } diff --git a/app/test/test_cryptodev_aes.c b/app/test/test_cryptodev_aes.c deleted file mode 100644 index e19c45b..0000000 --- a/app/test/test_cryptodev_aes.c +++ /dev/null @@ -1,687 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2015-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_common.h> -#include <rte_hexdump.h> -#include <rte_mbuf.h> -#include <rte_malloc.h> -#include <rte_memcpy.h> - -#include <rte_crypto.h> -#include <rte_cryptodev.h> -#include <rte_cryptodev_pmd.h> - -#include "test.h" -#include "test_cryptodev_aes.h" - -#ifndef AES_TEST_MSG_LEN -#define AES_TEST_MSG_LEN 256 -#endif - -#define AES_TEST_OP_ENCRYPT 0x01 -#define AES_TEST_OP_DECRYPT 0x02 -#define AES_TEST_OP_AUTH_GEN 0x04 -#define AES_TEST_OP_AUTH_VERIFY 0x08 - -#define AES_TEST_FEATURE_OOP 0x01 -#define AES_TEST_FEATURE_SESSIONLESS 0x02 -#define AES_TEST_FEATURE_STOPPER 0x04 /* stop upon failing */ - -#define AES_TEST_TARGET_PMD_MB 0x0001 /* Multi-buffer flag */ -#define AES_TEST_TARGET_PMD_QAT 0x0002 /* QAT flag */ - -#define AES_TEST_OP_CIPHER (AES_TEST_OP_ENCRYPT | \ - AES_TEST_OP_DECRYPT) - -#define AES_TEST_OP_AUTH (AES_TEST_OP_AUTH_GEN | \ - AES_TEST_OP_AUTH_VERIFY) - -#define AES_TEST_OP_ENC_AUTH_GEN (AES_TEST_OP_ENCRYPT | \ - AES_TEST_OP_AUTH_GEN) - -#define AES_TEST_OP_AUTH_VERIFY_DEC (AES_TEST_OP_DECRYPT | \ - AES_TEST_OP_AUTH_VERIFY) - -struct aes_test_case { - const char *test_descr; /* test description */ - const struct aes_test_data *test_data; - uint8_t op_mask; /* operation mask */ - uint8_t feature_mask; - uint32_t pmd_mask; -}; - -static const struct aes_test_case aes_test_cases[] = { - { - .test_descr = "AES-128-CTR HMAC-SHA1 Encryption Digest", - .test_data = &aes_test_data_1, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CTR HMAC-SHA1 Decryption Digest " - "Verify", - .test_data = &aes_test_data_1, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-192-CTR XCBC Encryption Digest", - .test_data = &aes_test_data_2, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-192-CTR XCBC Decryption Digest Verify", - .test_data = &aes_test_data_2, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-256-CTR HMAC-SHA1 Encryption Digest", - .test_data = &aes_test_data_3, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-256-CTR HMAC-SHA1 Decryption Digest " - "Verify", - .test_data = &aes_test_data_3, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest", - .test_data = &aes_test_data_4, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " - "Verify", - .test_data = &aes_test_data_4, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA256 Encryption Digest", - .test_data = &aes_test_data_5, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA256 Decryption Digest " - "Verify", - .test_data = &aes_test_data_5, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest", - .test_data = &aes_test_data_6, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest " - "Sessionless", - .test_data = &aes_test_data_6, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .feature_mask = AES_TEST_FEATURE_SESSIONLESS, - .pmd_mask = AES_TEST_TARGET_PMD_MB - }, - { - .test_descr = "AES-128-CBC HMAC-SHA512 Decryption Digest " - "Verify", - .test_data = &aes_test_data_6, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC XCBC Encryption Digest", - .test_data = &aes_test_data_7, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC XCBC Decryption Digest Verify", - .test_data = &aes_test_data_7, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest " - "OOP", - .test_data = &aes_test_data_4, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .feature_mask = AES_TEST_FEATURE_OOP, - .pmd_mask = AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " - "Verify OOP", - .test_data = &aes_test_data_4, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .feature_mask = AES_TEST_FEATURE_OOP, - .pmd_mask = AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA224 Encryption Digest", - .test_data = &aes_test_data_8, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA224 Decryption Digest " - "Verify", - .test_data = &aes_test_data_8, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA384 Encryption Digest", - .test_data = &aes_test_data_9, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA384 Decryption Digest " - "Verify", - .test_data = &aes_test_data_9, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, -}; - -static int -test_AES_one_case(const struct aes_test_case *t, - struct rte_mempool *mbuf_pool, - struct rte_mempool *op_mpool, - uint8_t dev_id, - enum rte_cryptodev_type cryptodev_type, - char *test_msg) -{ - struct rte_mbuf *ibuf = NULL; - struct rte_mbuf *obuf = NULL; - struct rte_mbuf *iobuf; - struct rte_crypto_sym_xform *cipher_xform = NULL; - struct rte_crypto_sym_xform *auth_xform = NULL; - struct rte_crypto_sym_xform *init_xform = NULL; - struct rte_crypto_sym_op *sym_op = NULL; - struct rte_crypto_op *op = NULL; - struct rte_cryptodev_sym_session *sess = NULL; - - int status = TEST_SUCCESS; - const struct aes_test_data *tdata = t->test_data; - uint8_t cipher_key[tdata->cipher_key.len]; - uint8_t auth_key[tdata->auth_key.len]; - uint32_t buf_len = tdata->ciphertext.len; - uint32_t digest_len = 0; - char *buf_p = NULL; - - if (tdata->cipher_key.len) - memcpy(cipher_key, tdata->cipher_key.data, - tdata->cipher_key.len); - if (tdata->auth_key.len) - memcpy(auth_key, tdata->auth_key.data, - tdata->auth_key.len); - - switch (cryptodev_type) { - case RTE_CRYPTODEV_QAT_SYM_PMD: - digest_len = tdata->digest.len; - break; - case RTE_CRYPTODEV_AESNI_MB_PMD: - digest_len = tdata->digest.truncated_len; - break; - default: - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Unsupported PMD type"); - status = TEST_FAILED; - goto error_exit; - } - - /* preparing data */ - ibuf = rte_pktmbuf_alloc(mbuf_pool); - if (!ibuf) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Allocation of rte_mbuf failed"); - status = TEST_FAILED; - goto error_exit; - } - - if (t->op_mask & AES_TEST_OP_CIPHER) - buf_len += tdata->iv.len; - if (t->op_mask & AES_TEST_OP_AUTH) - buf_len += digest_len; - - buf_p = rte_pktmbuf_append(ibuf, buf_len); - if (!buf_p) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "No room to append mbuf"); - status = TEST_FAILED; - goto error_exit; - } - - if (t->op_mask & AES_TEST_OP_CIPHER) { - rte_memcpy(buf_p, tdata->iv.data, tdata->iv.len); - buf_p += tdata->iv.len; - } - - /* only encryption requires plaintext.data input, - * decryption/(digest gen)/(digest verify) use ciphertext.data - * to be computed */ - if (t->op_mask & AES_TEST_OP_ENCRYPT) { - rte_memcpy(buf_p, tdata->plaintext.data, - tdata->plaintext.len); - buf_p += tdata->plaintext.len; - } else { - rte_memcpy(buf_p, tdata->ciphertext.data, - tdata->ciphertext.len); - buf_p += tdata->ciphertext.len; - } - - if (t->op_mask & AES_TEST_OP_AUTH_VERIFY) - rte_memcpy(buf_p, tdata->digest.data, digest_len); - else - memset(buf_p, 0, digest_len); - - if (t->feature_mask & AES_TEST_FEATURE_OOP) { - obuf = rte_pktmbuf_alloc(mbuf_pool); - if (!obuf) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, - "Allocation of rte_mbuf failed"); - status = TEST_FAILED; - goto error_exit; - } - - buf_p = rte_pktmbuf_append(obuf, buf_len); - if (!buf_p) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, - "No room to append mbuf"); - status = TEST_FAILED; - goto error_exit; - } - memset(buf_p, 0, buf_len); - } - - /* Generate Crypto op data structure */ - op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_SYMMETRIC); - if (!op) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Failed to allocate symmetric crypto " - "operation struct"); - status = TEST_FAILED; - goto error_exit; - } - - sym_op = op->sym; - - sym_op->m_src = ibuf; - - if (t->feature_mask & AES_TEST_FEATURE_OOP) { - sym_op->m_dst = obuf; - iobuf = obuf; - } else { - sym_op->m_dst = NULL; - iobuf = ibuf; - } - - /* sessionless op requires allocate xform using - * rte_crypto_op_sym_xforms_alloc(), otherwise rte_zmalloc() - * is used */ - if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) { - uint32_t n_xforms = 0; - - if (t->op_mask & AES_TEST_OP_CIPHER) - n_xforms++; - if (t->op_mask & AES_TEST_OP_AUTH) - n_xforms++; - - if (rte_crypto_op_sym_xforms_alloc(op, n_xforms) - == NULL) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, "Failed to " - "allocate space for crypto transforms"); - status = TEST_FAILED; - goto error_exit; - } - } else { - cipher_xform = rte_zmalloc(NULL, - sizeof(struct rte_crypto_sym_xform), 0); - - auth_xform = rte_zmalloc(NULL, - sizeof(struct rte_crypto_sym_xform), 0); - - if (!cipher_xform || !auth_xform) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, "Failed to " - "allocate memory for crypto transforms"); - status = TEST_FAILED; - goto error_exit; - } - } - - /* preparing xform, for sessioned op, init_xform is initialized - * here and later as param in rte_cryptodev_sym_session_create() - * call */ - if (t->op_mask == AES_TEST_OP_ENC_AUTH_GEN) { - if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) { - cipher_xform = op->sym->xform; - auth_xform = cipher_xform->next; - auth_xform->next = NULL; - } else { - cipher_xform->next = auth_xform; - auth_xform->next = NULL; - init_xform = cipher_xform; - } - } else if (t->op_mask == AES_TEST_OP_AUTH_VERIFY_DEC) { - if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) { - auth_xform = op->sym->xform; - cipher_xform = auth_xform->next; - cipher_xform->next = NULL; - } else { - auth_xform->next = cipher_xform; - cipher_xform->next = NULL; - init_xform = auth_xform; - } - } else if ((t->op_mask == AES_TEST_OP_ENCRYPT) || - (t->op_mask == AES_TEST_OP_DECRYPT)) { - if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) - cipher_xform = op->sym->xform; - else - init_xform = cipher_xform; - cipher_xform->next = NULL; - } else if ((t->op_mask == AES_TEST_OP_AUTH_GEN) || - (t->op_mask == AES_TEST_OP_AUTH_VERIFY)) { - if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) - auth_xform = op->sym->xform; - else - init_xform = auth_xform; - auth_xform->next = NULL; - } else { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Unrecognized operation"); - status = TEST_FAILED; - goto error_exit; - } - - /*configure xforms & sym_op cipher and auth data*/ - if (t->op_mask & AES_TEST_OP_CIPHER) { - cipher_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; - cipher_xform->cipher.algo = tdata->crypto_algo; - if (t->op_mask & AES_TEST_OP_ENCRYPT) - cipher_xform->cipher.op = - RTE_CRYPTO_CIPHER_OP_ENCRYPT; - else - cipher_xform->cipher.op = - RTE_CRYPTO_CIPHER_OP_DECRYPT; - cipher_xform->cipher.key.data = cipher_key; - cipher_xform->cipher.key.length = tdata->cipher_key.len; - - sym_op->cipher.data.offset = tdata->iv.len; - sym_op->cipher.data.length = tdata->ciphertext.len; - sym_op->cipher.iv.data = rte_pktmbuf_mtod(sym_op->m_src, - uint8_t *); - sym_op->cipher.iv.length = tdata->iv.len; - sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys( - sym_op->m_src); - } - - if (t->op_mask & AES_TEST_OP_AUTH) { - uint32_t auth_data_offset = 0; - uint32_t digest_offset = tdata->ciphertext.len; - - if (t->op_mask & AES_TEST_OP_CIPHER) { - digest_offset += tdata->iv.len; - auth_data_offset += tdata->iv.len; - } - - auth_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; - auth_xform->auth.algo = tdata->auth_algo; - auth_xform->auth.key.length = tdata->auth_key.len; - auth_xform->auth.key.data = auth_key; - auth_xform->auth.digest_length = digest_len; - - if (t->op_mask & AES_TEST_OP_AUTH_GEN) { - auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; - sym_op->auth.digest.data = rte_pktmbuf_mtod_offset - (iobuf, uint8_t *, digest_offset); - sym_op->auth.digest.phys_addr = - rte_pktmbuf_mtophys_offset(iobuf, - digest_offset); - } else { - auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; - sym_op->auth.digest.data = rte_pktmbuf_mtod_offset - (sym_op->m_src, uint8_t *, digest_offset); - sym_op->auth.digest.phys_addr = - rte_pktmbuf_mtophys_offset(sym_op->m_src, - digest_offset); - } - - sym_op->auth.data.offset = auth_data_offset; - sym_op->auth.data.length = tdata->ciphertext.len; - sym_op->auth.digest.length = digest_len; - } - - /* create session for sessioned op */ - if (!(t->feature_mask & AES_TEST_FEATURE_SESSIONLESS)) { - sess = rte_cryptodev_sym_session_create(dev_id, - init_xform); - if (!sess) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, - "Session creation failed"); - status = TEST_FAILED; - goto error_exit; - } - - /* attach symmetric crypto session to crypto operations */ - rte_crypto_op_attach_sym_session(op, sess); - } - - /* Process crypto operation */ - if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Error sending packet for encryption"); - status = TEST_FAILED; - goto error_exit; - } - - op = NULL; - - while (rte_cryptodev_dequeue_burst(dev_id, 0, &op, 1) == 0) - rte_pause(); - - if (!op) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Failed to process sym crypto op"); - status = TEST_FAILED; - goto error_exit; - } - - TEST_HEXDUMP(stdout, "m_src:", - rte_pktmbuf_mtod(sym_op->m_src, uint8_t *), buf_len); - if (t->feature_mask & AES_TEST_FEATURE_OOP) - TEST_HEXDUMP(stdout, "m_dst:", - rte_pktmbuf_mtod(sym_op->m_dst, uint8_t *), - buf_len); - - /* Verify results */ - if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) { - if (t->op_mask & AES_TEST_OP_AUTH_VERIFY) - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: Digest verification failed " - "(0x%X)", __LINE__, op->status); - else - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: Digest verification failed " - "(0x%X)", __LINE__, op->status); - status = TEST_FAILED; - goto error_exit; - } - - if (t->op_mask & AES_TEST_OP_CIPHER) { - uint8_t *crypto_res; - const uint8_t *compare_ref; - uint32_t compare_len; - - crypto_res = rte_pktmbuf_mtod_offset(iobuf, uint8_t *, - tdata->iv.len); - - if (t->op_mask & AES_TEST_OP_ENCRYPT) { - compare_ref = tdata->ciphertext.data; - compare_len = tdata->ciphertext.len; - } else { - compare_ref = tdata->plaintext.data; - compare_len = tdata->plaintext.len; - } - - if (memcmp(crypto_res, compare_ref, compare_len)) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, - "Crypto data not as expected"); - status = TEST_FAILED; - goto error_exit; - } - } - - if (t->op_mask & AES_TEST_OP_AUTH_GEN) { - uint8_t *auth_res; - - if (t->op_mask & AES_TEST_OP_CIPHER) - auth_res = rte_pktmbuf_mtod_offset(iobuf, - uint8_t *, - tdata->iv.len + tdata->ciphertext.len); - else - auth_res = rte_pktmbuf_mtod_offset(iobuf, - uint8_t *, tdata->ciphertext.len); - - if (memcmp(auth_res, tdata->digest.data, digest_len)) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, "Generated " - "digest data not as expected"); - status = TEST_FAILED; - goto error_exit; - } - } - - snprintf(test_msg, AES_TEST_MSG_LEN, "PASS"); - -error_exit: - if (!(t->feature_mask & AES_TEST_FEATURE_SESSIONLESS)) { - if (sess) - rte_cryptodev_sym_session_free(dev_id, sess); - if (cipher_xform) - rte_free(cipher_xform); - if (auth_xform) - rte_free(auth_xform); - } - - if (op) - rte_crypto_op_free(op); - - if (obuf) - rte_pktmbuf_free(obuf); - - if (ibuf) - rte_pktmbuf_free(ibuf); - - return status; -} - -int -test_AES_all_tests(struct rte_mempool *mbuf_pool, - struct rte_mempool *op_mpool, - uint8_t dev_id, - enum rte_cryptodev_type cryptodev_type) -{ - int status, overall_status = TEST_SUCCESS; - uint32_t i, test_index = 0; - char test_msg[AES_TEST_MSG_LEN + 1]; - uint32_t n_test_cases = sizeof(aes_test_cases) / - sizeof(aes_test_cases[0]); - uint32_t target_pmd_mask = 0; - - switch (cryptodev_type) { - case RTE_CRYPTODEV_AESNI_MB_PMD: - target_pmd_mask = AES_TEST_TARGET_PMD_MB; - break; - case RTE_CRYPTODEV_QAT_SYM_PMD: - target_pmd_mask = AES_TEST_TARGET_PMD_QAT; - break; - default: - TEST_ASSERT(-1, "Unrecognized cryptodev type"); - break; - } - - for (i = 0; i < n_test_cases; i++) { - const struct aes_test_case *tc = &aes_test_cases[i]; - - if (!(tc->pmd_mask & target_pmd_mask)) - continue; - - status = test_AES_one_case(tc, mbuf_pool, op_mpool, - dev_id, cryptodev_type, test_msg); - - printf(" %u) TestCase %s %s\n", test_index ++, - tc->test_descr, test_msg); - - if (status != TEST_SUCCESS) { - if (overall_status == TEST_SUCCESS) - overall_status = status; - - if (tc->feature_mask & AES_TEST_FEATURE_STOPPER) - break; - } - } - - return overall_status; -} diff --git a/app/test/test_cryptodev_aes.h b/app/test/test_cryptodev_aes.h deleted file mode 100644 index ef518e0..0000000 --- a/app/test/test_cryptodev_aes.h +++ /dev/null @@ -1,1124 +0,0 @@ -/*- - * 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 TEST_CRYPTODEV_AES_H_ -#define TEST_CRYPTODEV_AES_H_ - -struct aes_test_data { - enum rte_crypto_cipher_algorithm crypto_algo; - - struct { - uint8_t data[64]; - unsigned len; - } cipher_key; - - struct { - uint8_t data[64] __rte_aligned(16); - unsigned len; - } iv; - - struct { - uint8_t data[2048]; - unsigned len; - } plaintext; - - struct { - uint8_t data[2048]; - unsigned len; - } ciphertext; - - enum rte_crypto_auth_algorithm auth_algo; - - struct { - uint8_t data[128]; - unsigned len; - } auth_key; - - struct { - uint8_t data[128]; - unsigned len; /* for qat */ - unsigned truncated_len; /* for mb */ - } digest; -}; - -int -test_AES_all_tests(struct rte_mempool *mbuf_pool, - struct rte_mempool *op_mpool, - uint8_t dev_id, - enum rte_cryptodev_type cryptodev_type); - -/* test vectors */ -/* AES128-CTR-SHA1 test vector */ -static const struct aes_test_data aes_test_data_1 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, - .cipher_key = { - .data = { - 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, - 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C - }, - .len = 16 - }, - .iv = { - .data = { - 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, - 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF - }, - .len = 16 - }, - .plaintext = { - .data = { - 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, - 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, - 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, - 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, - 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, - 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, - 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, - 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 - }, - .len = 64 - }, - .ciphertext = { - .data = { - 0x87, 0x4D, 0x61, 0x91, 0xB6, 0x20, 0xE3, 0x26, - 0x1B, 0xEF, 0x68, 0x64, 0x99, 0x0D, 0xB6, 0xCE, - 0x98, 0x06, 0xF6, 0x6B, 0x79, 0x70, 0xFD, 0xFF, - 0x86, 0x17, 0x18, 0x7B, 0xB9, 0xFF, 0xFD, 0xFF, - 0x5A, 0xE4, 0xDF, 0x3E, 0xDB, 0xD5, 0xD3, 0x5E, - 0x5B, 0x4F, 0x09, 0x02, 0x0D, 0xB0, 0x3E, 0xAB, - 0x1E, 0x03, 0x1D, 0xDA, 0x2F, 0xBE, 0x03, 0xD1, - 0x79, 0x21, 0x70, 0xA0, 0xF3, 0x00, 0x9C, 0xEE - }, - .len = 64 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, - .auth_key = { - .data = { - 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, - 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, - 0xDE, 0xF4, 0xDE, 0xAD - }, - .len = 20 - }, - .digest = { - .data = { - 0x9B, 0x6F, 0x0C, 0x43, 0xF5, 0xC1, 0x3E, 0xB0, - 0xB1, 0x70, 0xB8, 0x2B, 0x33, 0x09, 0xD2, 0xB2, - 0x56, 0x20, 0xFB, 0xFE - }, - .len = 20, - .truncated_len = 12 - } -}; - -/** AES-192-CTR XCBC test vector */ -static const struct aes_test_data aes_test_data_2 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, - .cipher_key = { - .data = { - 0xCB, 0xC5, 0xED, 0x5B, 0xE7, 0x7C, 0xBD, 0x8C, - 0x50, 0xD9, 0x30, 0xF2, 0xB5, 0x6A, 0x0E, 0x5F, - 0xAA, 0xAE, 0xAD, 0xA2, 0x1F, 0x49, 0x52, 0xD4 - }, - .len = 24 - }, - .iv = { - .data = { - 0x3F, 0x69, 0xA8, 0xCD, 0xE8, 0xF0, 0xEF, 0x40, - 0xB8, 0x7A, 0x4B, 0xED, 0x2B, 0xAF, 0xBF, 0x57 - }, - .len = 16 - }, - .plaintext = { - .data = { - 0x01, 0x0F, 0x10, 0x1F, 0x20, 0x1C, 0x0E, 0xB8, - 0xFB, 0x5C, 0xCD, 0xCC, 0x1F, 0xF9, 0xAF, 0x0B, - 0x95, 0x03, 0x74, 0x99, 0x49, 0xE7, 0x62, 0x55, - 0xDA, 0xEA, 0x13, 0x20, 0x1D, 0xC6, 0xCC, 0xCC, - 0xD1, 0x70, 0x75, 0x47, 0x02, 0x2F, 0xFB, 0x86, - 0xBB, 0x6B, 0x23, 0xD2, 0xC9, 0x74, 0xD7, 0x7B, - 0x08, 0x03, 0x3B, 0x79, 0x39, 0xBB, 0x91, 0x29, - 0xDA, 0x14, 0x39, 0x8D, 0xFF, 0x81, 0x50, 0x96, - }, - .len = 64 - }, - .ciphertext = { - .data = { - 0x4A, 0x6C, 0xC8, 0xCC, 0x96, 0x2A, 0x13, 0x84, - 0x1C, 0x36, 0x88, 0xE9, 0xE5, 0x94, 0x70, 0xB2, - 0x14, 0x5B, 0x13, 0x80, 0xEA, 0xD8, 0x8D, 0x37, - 0xFD, 0x70, 0xA8, 0x83, 0xE8, 0x2B, 0x88, 0x1E, - 0xBA, 0x94, 0x3F, 0xF6, 0xB3, 0x1F, 0xDE, 0x34, - 0xF3, 0x5B, 0x80, 0xE9, 0xAB, 0xF5, 0x1C, 0x29, - 0xB6, 0xD9, 0x76, 0x2B, 0x06, 0xC6, 0x74, 0xF1, - 0x59, 0x5E, 0x9E, 0xA5, 0x7B, 0x2D, 0xD7, 0xF0 - }, - .len = 64 - }, - .auth_algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC, - .auth_key = { - .data = { - 0x87, 0x61, 0x54, 0x53, 0xC4, 0x6D, 0xDD, 0x51, - 0xE1, 0x9F, 0x86, 0x64, 0x39, 0x0A, 0xE6, 0x59 - }, - .len = 16 - }, - .digest = { - .data = { - 0xCA, 0x33, 0xB3, 0x3B, 0x16, 0x94, 0xAA, 0x55, - 0x36, 0x6B, 0x45, 0x46 - }, - .len = 12, - .truncated_len = 12 - } -}; - -/** AES-256-CTR SHA1 test vector */ -static const struct aes_test_data aes_test_data_3 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, - .cipher_key = { - .data = { - 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, - 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, - 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, - 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 - }, - .len = 32 - }, - .iv = { - .data = { - 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, - 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF - }, - .len = 16 - }, - .plaintext = { - .data = { - 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, - 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, - 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, - 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, - 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, - 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, - 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, - 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 - }, - .len = 64 - }, - .ciphertext = { - .data = { - 0x60, 0x1E, 0xC3, 0x13, 0x77, 0x57, 0x89, 0xA5, - 0xB7, 0xA7, 0xF5, 0x04, 0xBB, 0xF3, 0xD2, 0x28, - 0xF4, 0x43, 0xE3, 0xCA, 0x4D, 0x62, 0xB5, 0x9A, - 0xCA, 0x84, 0xE9, 0x90, 0xCA, 0xCA, 0xF5, 0xC5, - 0x2B, 0x09, 0x30, 0xDA, 0xA2, 0x3D, 0xE9, 0x4C, - 0xE8, 0x70, 0x17, 0xBA, 0x2D, 0x84, 0x98, 0x8D, - 0xDF, 0xC9, 0xC5, 0x8D, 0xB6, 0x7A, 0xAD, 0xA6, - 0x13, 0xC2, 0xDD, 0x08, 0x45, 0x79, 0x41, 0xA6 - }, - .len = 64 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, - .auth_key = { - .data = { - 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, - 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, - 0xDE, 0xF4, 0xDE, 0xAD - }, - .len = 20 - }, - .digest = { - .data = { - 0x3B, 0x1A, 0x9D, 0x82, 0x35, 0xD5, 0xDD, 0x64, - 0xCC, 0x1B, 0xA9, 0xC0, 0xEB, 0xE9, 0x42, 0x16, - 0xE7, 0x87, 0xA3, 0xEF - }, - .len = 20, - .truncated_len = 12 - } -}; - -/** AES-128-CBC SHA1 test vector */ -static const struct aes_test_data aes_test_data_4 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, - .auth_key = { - .data = { - 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, - 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, - 0xDE, 0xF4, 0xDE, 0xAD - }, - .len = 20 - }, - .digest = { - .data = { - 0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60, - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0x18, 0x8C, 0x1D, 0x32 - }, - .len = 20, - .truncated_len = 12 - } -}; - -/** AES-128-CBC SHA256 test vector */ -static const struct aes_test_data aes_test_data_5 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC, - .auth_key = { - .data = { - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60 - }, - .len = 32 - }, - .digest = { - .data = { - 0xC8, 0x57, 0x57, 0x31, 0x03, 0xE0, 0x03, 0x55, - 0x07, 0xC8, 0x9E, 0x7F, 0x48, 0x9A, 0x61, 0x9A, - 0x68, 0xEE, 0x03, 0x0E, 0x71, 0x75, 0xC7, 0xF4, - 0x2E, 0x45, 0x26, 0x32, 0x7C, 0x12, 0x15, 0x15 - }, - .len = 32, - .truncated_len = 16 - } -}; - -/** AES-128-CBC SHA512 test vector */ -static const struct aes_test_data aes_test_data_6 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA512_HMAC, - .auth_key = { - .data = { - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, - 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, - 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, - 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, - 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, - 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 - }, - .len = 64 - }, - .digest = { - .data = { - 0x5D, 0x54, 0x66, 0xC1, 0x6E, 0xBC, 0x04, 0xB8, - 0x46, 0xB8, 0x08, 0x6E, 0xE0, 0xF0, 0x43, 0x48, - 0x37, 0x96, 0x9C, 0xC6, 0x9C, 0xC2, 0x1E, 0xE8, - 0xF2, 0x0C, 0x0B, 0xEF, 0x86, 0xA2, 0xE3, 0x70, - 0x95, 0xC8, 0xB3, 0x06, 0x47, 0xA9, 0x90, 0xE8, - 0xA0, 0xC6, 0x72, 0x69, 0x05, 0xC0, 0x0D, 0x0E, - 0x21, 0x96, 0x65, 0x93, 0x74, 0x43, 0x2A, 0x1D, - 0x2E, 0xBF, 0xC2, 0xC2, 0xEE, 0xCC, 0x2F, 0x0A - }, - .len = 64, - .truncated_len = 32 - } -}; - -/** AES-128-CBC XCBC test vector */ -static const struct aes_test_data aes_test_data_7 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC, - .auth_key = { - .data = { - 0x87, 0x61, 0x54, 0x53, 0xC4, 0x6D, 0xDD, 0x51, - 0xE1, 0x9F, 0x86, 0x64, 0x39, 0x0A, 0xE6, 0x59 - }, - .len = 16 - }, - .digest = { - .data = { - 0xE0, 0xAC, 0x9A, 0xC4, 0x22, 0x64, 0x35, 0x89, - 0x77, 0x1D, 0x8B, 0x75 - }, - .len = 12, - .truncated_len = 12 - } -}; - -/** AES-128-CBC SHA224 test vector */ -static const struct aes_test_data aes_test_data_8 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA224_HMAC, - .auth_key = { - .data = { - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, - 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, - 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, - 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, - 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, - 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 - }, - .len = 64 - }, - .digest = { - .data = { - 0xA3, 0xCA, 0xC7, 0x1D, 0xA8, 0x61, 0x30, 0x98, - 0x3B, 0x8F, 0x01, 0x19, 0xAE, 0x8D, 0xBD, 0x34, - 0x40, 0x63, 0xA8, 0x2F, 0xDF, 0x85, 0x2B, 0x7F, - 0x63, 0x7C, 0xDD, 0xB7 - }, - .len = 28, - .truncated_len = 14 - } -}; - -/** AES-128-CBC SHA384 test vector */ -static const struct aes_test_data aes_test_data_9 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA384_HMAC, - .auth_key = { - .data = { - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, - 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, - 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, - 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, - 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, - 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60, - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, - 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, - 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, - 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, - 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, - 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 - }, - .len = 128 - }, - .digest = { - .data = { - 0x23, 0x60, 0xC8, 0xB1, 0x2D, 0x6C, 0x1E, 0x72, - 0x25, 0xAB, 0xF9, 0xC3, 0x9A, 0xA9, 0x4F, 0x8C, - 0x56, 0x38, 0x65, 0x0E, 0x74, 0xD5, 0x45, 0x9D, - 0xA3, 0xFD, 0x7E, 0x6D, 0x9E, 0x74, 0x88, 0x9D, - 0xA7, 0x12, 0x9D, 0xD8, 0x81, 0x3C, 0x86, 0x2F, - 0x4D, 0xF9, 0x6F, 0x0A, 0xB0, 0xC9, 0xEB, 0x0B - }, - .len = 48, - .truncated_len = 24 - } -}; - -#endif /* TEST_CRYPTODEV_AES_H_ */ diff --git a/app/test/test_cryptodev_aes_test_vectors.h b/app/test/test_cryptodev_aes_test_vectors.h new file mode 100644 index 0000000..92c0cc2 --- /dev/null +++ b/app/test/test_cryptodev_aes_test_vectors.h @@ -0,0 +1,797 @@ +/* + * 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 TEST_CRYPTODEV_AES_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_AES_TEST_VECTORS_H_ + +/* test vectors */ +static const uint8_t plaintext_aes128ctr[] = { + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, + 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, + 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, + 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, + 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, + 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, + 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 +}; + +static const uint8_t ciphertext64_aes128ctr[] = { + 0x87, 0x4D, 0x61, 0x91, 0xB6, 0x20, 0xE3, 0x26, + 0x1B, 0xEF, 0x68, 0x64, 0x99, 0x0D, 0xB6, 0xCE, + 0x98, 0x06, 0xF6, 0x6B, 0x79, 0x70, 0xFD, 0xFF, + 0x86, 0x17, 0x18, 0x7B, 0xB9, 0xFF, 0xFD, 0xFF, + 0x5A, 0xE4, 0xDF, 0x3E, 0xDB, 0xD5, 0xD3, 0x5E, + 0x5B, 0x4F, 0x09, 0x02, 0x0D, 0xB0, 0x3E, 0xAB, + 0x1E, 0x03, 0x1D, 0xDA, 0x2F, 0xBE, 0x03, 0xD1, + 0x79, 0x21, 0x70, 0xA0, 0xF3, 0x00, 0x9C, 0xEE +}; + +static const uint8_t plaintext_aes192ctr[] = { + 0x01, 0x0F, 0x10, 0x1F, 0x20, 0x1C, 0x0E, 0xB8, + 0xFB, 0x5C, 0xCD, 0xCC, 0x1F, 0xF9, 0xAF, 0x0B, + 0x95, 0x03, 0x74, 0x99, 0x49, 0xE7, 0x62, 0x55, + 0xDA, 0xEA, 0x13, 0x20, 0x1D, 0xC6, 0xCC, 0xCC, + 0xD1, 0x70, 0x75, 0x47, 0x02, 0x2F, 0xFB, 0x86, + 0xBB, 0x6B, 0x23, 0xD2, 0xC9, 0x74, 0xD7, 0x7B, + 0x08, 0x03, 0x3B, 0x79, 0x39, 0xBB, 0x91, 0x29, + 0xDA, 0x14, 0x39, 0x8D, 0xFF, 0x81, 0x50, 0x96, +}; + +static const uint8_t ciphertext64_aes192ctr[] = { + 0x4A, 0x6C, 0xC8, 0xCC, 0x96, 0x2A, 0x13, 0x84, + 0x1C, 0x36, 0x88, 0xE9, 0xE5, 0x94, 0x70, 0xB2, + 0x14, 0x5B, 0x13, 0x80, 0xEA, 0xD8, 0x8D, 0x37, + 0xFD, 0x70, 0xA8, 0x83, 0xE8, 0x2B, 0x88, 0x1E, + 0xBA, 0x94, 0x3F, 0xF6, 0xB3, 0x1F, 0xDE, 0x34, + 0xF3, 0x5B, 0x80, 0xE9, 0xAB, 0xF5, 0x1C, 0x29, + 0xB6, 0xD9, 0x76, 0x2B, 0x06, 0xC6, 0x74, 0xF1, + 0x59, 0x5E, 0x9E, 0xA5, 0x7B, 0x2D, 0xD7, 0xF0 +}; + +static const uint8_t plaintext_aes256ctr[] = { + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, + 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, + 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, + 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, + 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, + 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, + 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 +}; + +static const uint8_t ciphertext64_aes256ctr[] = { + 0x60, 0x1E, 0xC3, 0x13, 0x77, 0x57, 0x89, 0xA5, + 0xB7, 0xA7, 0xF5, 0x04, 0xBB, 0xF3, 0xD2, 0x28, + 0xF4, 0x43, 0xE3, 0xCA, 0x4D, 0x62, 0xB5, 0x9A, + 0xCA, 0x84, 0xE9, 0x90, 0xCA, 0xCA, 0xF5, 0xC5, + 0x2B, 0x09, 0x30, 0xDA, 0xA2, 0x3D, 0xE9, 0x4C, + 0xE8, 0x70, 0x17, 0xBA, 0x2D, 0x84, 0x98, 0x8D, + 0xDF, 0xC9, 0xC5, 0x8D, 0xB6, 0x7A, 0xAD, 0xA6, + 0x13, 0xC2, 0xDD, 0x08, 0x45, 0x79, 0x41, 0xA6 +}; + +static const uint8_t plaintext_aes_common[] = { + "What a lousy earth! He wondered how many people " + "were destitute that same night even in his own " + "prosperous country, how many homes were " + "shanties, how many husbands were drunk and " + "wives socked, and how many children were " + "bullied, abused, or abandoned. How many " + "families hungered for food they could not " + "afford to buy? How many hearts were broken? How " + "many suicides would take place that same night, " + "how many people would go insane? How many " + "cockroaches and landlords would triumph? How " + "many winners were losers, successes failures, " + "and rich men poor men? How many wise guys were " + "stupid? How many happy endings were unhappy " + "endings? How many honest men were liars, brave " + "men cowards, loyal men traitors, how many " + "sainted men were corrupt, how many people in " + "positions of trust had sold their souls to " + "bodyguards, how many had never had souls? How " + "many straight-and-narrow paths were crooked " + "paths? How many best families were worst " + "families and how many good people were bad " + "people? When you added them all up and then " + "subtracted, you might be left with only the " + "children, and perhaps with Albert Einstein and " + "an old violinist or sculptor somewhere." +}; + +static const uint8_t ciphertext512_aes128cbc[] = { + 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, + 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, + 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, + 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, + 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, + 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, + 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, + 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, + 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, + 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, + 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, + 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, + 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, + 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, + 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, + 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, + 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, + 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, + 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, + 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, + 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, + 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, + 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, + 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, + 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, + 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, + 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, + 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, + 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, + 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, + 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, + 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, + 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, + 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, + 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, + 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, + 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, + 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, + 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, + 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, + 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, + 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, + 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, + 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, + 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, + 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, + 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, + 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, + 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, + 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, + 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, + 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, + 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, + 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, + 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, + 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, + 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, + 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, + 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, + 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, + 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, + 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C +}; + +/* AES128-CTR-SHA1 test vector */ +static const struct blockcipher_test_data aes_test_data_1 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key = { + .data = { + 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C + }, + .len = 16 + }, + .iv = { + .data = { + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes128ctr, + .len = 64 + }, + .ciphertext = { + .data = ciphertext64_aes128ctr, + .len = 64 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x9B, 0x6F, 0x0C, 0x43, 0xF5, 0xC1, 0x3E, 0xB0, + 0xB1, 0x70, 0xB8, 0x2B, 0x33, 0x09, 0xD2, 0xB2, + 0x56, 0x20, 0xFB, 0xFE + }, + .len = 20, + .truncated_len = 12 + } +}; + +/** AES-192-CTR XCBC test vector */ +static const struct blockcipher_test_data aes_test_data_2 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key = { + .data = { + 0xCB, 0xC5, 0xED, 0x5B, 0xE7, 0x7C, 0xBD, 0x8C, + 0x50, 0xD9, 0x30, 0xF2, 0xB5, 0x6A, 0x0E, 0x5F, + 0xAA, 0xAE, 0xAD, 0xA2, 0x1F, 0x49, 0x52, 0xD4 + }, + .len = 24 + }, + .iv = { + .data = { + 0x3F, 0x69, 0xA8, 0xCD, 0xE8, 0xF0, 0xEF, 0x40, + 0xB8, 0x7A, 0x4B, 0xED, 0x2B, 0xAF, 0xBF, 0x57 + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes192ctr, + .len = 64 + }, + .ciphertext = { + .data = ciphertext64_aes192ctr, + .len = 64 + }, + .auth_algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC, + .auth_key = { + .data = { + 0x87, 0x61, 0x54, 0x53, 0xC4, 0x6D, 0xDD, 0x51, + 0xE1, 0x9F, 0x86, 0x64, 0x39, 0x0A, 0xE6, 0x59 + }, + .len = 16 + }, + .digest = { + .data = { + 0xCA, 0x33, 0xB3, 0x3B, 0x16, 0x94, 0xAA, 0x55, + 0x36, 0x6B, 0x45, 0x46 + }, + .len = 12, + .truncated_len = 12 + } +}; + +/** AES-256-CTR SHA1 test vector */ +static const struct blockcipher_test_data aes_test_data_3 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key = { + .data = { + 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, + 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, + 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, + 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 + }, + .len = 32 + }, + .iv = { + .data = { + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes256ctr, + .len = 64 + }, + .ciphertext = { + .data = ciphertext64_aes256ctr, + .len = 64 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x3B, 0x1A, 0x9D, 0x82, 0x35, 0xD5, 0xDD, 0x64, + 0xCC, 0x1B, 0xA9, 0xC0, 0xEB, 0xE9, 0x42, 0x16, + 0xE7, 0x87, 0xA3, 0xEF + }, + .len = 20, + .truncated_len = 12 + } +}; + +/** AES-128-CBC SHA1 test vector */ +static const struct blockcipher_test_data aes_test_data_4 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60, + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0x18, 0x8C, 0x1D, 0x32 + }, + .len = 20, + .truncated_len = 12 + } +}; + +/** AES-128-CBC SHA256 test vector */ +static const struct blockcipher_test_data aes_test_data_5 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC, + .auth_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, + 0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60 + }, + .len = 32 + }, + .digest = { + .data = { + 0xC8, 0x57, 0x57, 0x31, 0x03, 0xE0, 0x03, 0x55, + 0x07, 0xC8, 0x9E, 0x7F, 0x48, 0x9A, 0x61, 0x9A, + 0x68, 0xEE, 0x03, 0x0E, 0x71, 0x75, 0xC7, 0xF4, + 0x2E, 0x45, 0x26, 0x32, 0x7C, 0x12, 0x15, 0x15 + }, + .len = 32, + .truncated_len = 16 + } +}; + +/** AES-128-CBC SHA512 test vector */ +static const struct blockcipher_test_data aes_test_data_6 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA512_HMAC, + .auth_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 + }, + .len = 64 + }, + .digest = { + .data = { + 0x5D, 0x54, 0x66, 0xC1, 0x6E, 0xBC, 0x04, 0xB8, + 0x46, 0xB8, 0x08, 0x6E, 0xE0, 0xF0, 0x43, 0x48, + 0x37, 0x96, 0x9C, 0xC6, 0x9C, 0xC2, 0x1E, 0xE8, + 0xF2, 0x0C, 0x0B, 0xEF, 0x86, 0xA2, 0xE3, 0x70, + 0x95, 0xC8, 0xB3, 0x06, 0x47, 0xA9, 0x90, 0xE8, + 0xA0, 0xC6, 0x72, 0x69, 0x05, 0xC0, 0x0D, 0x0E, + 0x21, 0x96, 0x65, 0x93, 0x74, 0x43, 0x2A, 0x1D, + 0x2E, 0xBF, 0xC2, 0xC2, 0xEE, 0xCC, 0x2F, 0x0A + }, + .len = 64, + .truncated_len = 32 + } +}; + +/** AES-128-CBC XCBC test vector */ +static const struct blockcipher_test_data aes_test_data_7 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC, + .auth_key = { + .data = { + 0x87, 0x61, 0x54, 0x53, 0xC4, 0x6D, 0xDD, 0x51, + 0xE1, 0x9F, 0x86, 0x64, 0x39, 0x0A, 0xE6, 0x59 + }, + .len = 16 + }, + .digest = { + .data = { + 0xE0, 0xAC, 0x9A, 0xC4, 0x22, 0x64, 0x35, 0x89, + 0x77, 0x1D, 0x8B, 0x75 + }, + .len = 12, + .truncated_len = 12 + } +}; + +/** AES-128-CBC SHA224 test vector */ +static const struct blockcipher_test_data aes_test_data_8 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA224_HMAC, + .auth_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 + }, + .len = 64 + }, + .digest = { + .data = { + 0xA3, 0xCA, 0xC7, 0x1D, 0xA8, 0x61, 0x30, 0x98, + 0x3B, 0x8F, 0x01, 0x19, 0xAE, 0x8D, 0xBD, 0x34, + 0x40, 0x63, 0xA8, 0x2F, 0xDF, 0x85, 0x2B, 0x7F, + 0x63, 0x7C, 0xDD, 0xB7 + }, + .len = 28, + .truncated_len = 14 + } +}; + +/** AES-128-CBC SHA384 test vector */ +static const struct blockcipher_test_data aes_test_data_9 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA384_HMAC, + .auth_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60, + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 + }, + .len = 128 + }, + .digest = { + .data = { + 0x23, 0x60, 0xC8, 0xB1, 0x2D, 0x6C, 0x1E, 0x72, + 0x25, 0xAB, 0xF9, 0xC3, 0x9A, 0xA9, 0x4F, 0x8C, + 0x56, 0x38, 0x65, 0x0E, 0x74, 0xD5, 0x45, 0x9D, + 0xA3, 0xFD, 0x7E, 0x6D, 0x9E, 0x74, 0x88, 0x9D, + 0xA7, 0x12, 0x9D, 0xD8, 0x81, 0x3C, 0x86, 0x2F, + 0x4D, 0xF9, 0x6F, 0x0A, 0xB0, 0xC9, 0xEB, 0x0B + }, + .len = 48, + .truncated_len = 24 + } +}; + +static const struct blockcipher_test_case aes_chain_test_cases[] = { + { + .test_descr = "AES-128-CTR HMAC-SHA1 Encryption Digest", + .test_data = &aes_test_data_1, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CTR HMAC-SHA1 Decryption Digest " + "Verify", + .test_data = &aes_test_data_1, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-192-CTR XCBC Encryption Digest", + .test_data = &aes_test_data_2, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-192-CTR XCBC Decryption Digest Verify", + .test_data = &aes_test_data_2, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-256-CTR HMAC-SHA1 Encryption Digest", + .test_data = &aes_test_data_3, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-256-CTR HMAC-SHA1 Decryption Digest " + "Verify", + .test_data = &aes_test_data_3, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " + "Verify", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA256 Encryption Digest", + .test_data = &aes_test_data_5, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA256 Decryption Digest " + "Verify", + .test_data = &aes_test_data_5, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest", + .test_data = &aes_test_data_6, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest " + "Sessionless", + .test_data = &aes_test_data_6, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB + }, + { + .test_descr = "AES-128-CBC HMAC-SHA512 Decryption Digest " + "Verify", + .test_data = &aes_test_data_6, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC XCBC Encryption Digest", + .test_data = &aes_test_data_7, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC XCBC Decryption Digest Verify", + .test_data = &aes_test_data_7, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest " + "OOP", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " + "Verify OOP", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA224 Encryption Digest", + .test_data = &aes_test_data_8, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA224 Decryption Digest " + "Verify", + .test_data = &aes_test_data_8, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA384 Encryption Digest", + .test_data = &aes_test_data_9, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA384 Decryption Digest " + "Verify", + .test_data = &aes_test_data_9, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, +}; + +#endif /* TEST_CRYPTODEV_AES_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_blockcipher.c b/app/test/test_cryptodev_blockcipher.c new file mode 100644 index 0000000..6661859 --- /dev/null +++ b/app/test/test_cryptodev_blockcipher.c @@ -0,0 +1,509 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2015-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_common.h> +#include <rte_hexdump.h> +#include <rte_mbuf.h> +#include <rte_malloc.h> +#include <rte_memcpy.h> + +#include <rte_crypto.h> +#include <rte_cryptodev.h> +#include <rte_cryptodev_pmd.h> + +#include "test.h" +#include "test_cryptodev_blockcipher.h" +#include "test_cryptodev_aes_test_vectors.h" + +static int +test_blockcipher_one_case(const struct blockcipher_test_case *t, + struct rte_mempool *mbuf_pool, + struct rte_mempool *op_mpool, + uint8_t dev_id, + enum rte_cryptodev_type cryptodev_type, + char *test_msg) +{ + struct rte_mbuf *ibuf = NULL; + struct rte_mbuf *obuf = NULL; + struct rte_mbuf *iobuf; + struct rte_crypto_sym_xform *cipher_xform = NULL; + struct rte_crypto_sym_xform *auth_xform = NULL; + struct rte_crypto_sym_xform *init_xform = NULL; + struct rte_crypto_sym_op *sym_op = NULL; + struct rte_crypto_op *op = NULL; + struct rte_cryptodev_sym_session *sess = NULL; + + int status = TEST_SUCCESS; + const struct blockcipher_test_data *tdata = t->test_data; + uint8_t cipher_key[tdata->cipher_key.len]; + uint8_t auth_key[tdata->auth_key.len]; + uint32_t buf_len = tdata->ciphertext.len; + uint32_t digest_len = 0; + char *buf_p = NULL; + + if (tdata->cipher_key.len) + memcpy(cipher_key, tdata->cipher_key.data, + tdata->cipher_key.len); + if (tdata->auth_key.len) + memcpy(auth_key, tdata->auth_key.data, + tdata->auth_key.len); + + switch (cryptodev_type) { + case RTE_CRYPTODEV_QAT_SYM_PMD: + digest_len = tdata->digest.len; + break; + case RTE_CRYPTODEV_AESNI_MB_PMD: + digest_len = tdata->digest.truncated_len; + break; + default: + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Unsupported PMD type"); + status = TEST_FAILED; + goto error_exit; + } + + /* preparing data */ + ibuf = rte_pktmbuf_alloc(mbuf_pool); + if (!ibuf) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Allocation of rte_mbuf failed"); + status = TEST_FAILED; + goto error_exit; + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) + buf_len += tdata->iv.len; + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) + buf_len += digest_len; + + buf_p = rte_pktmbuf_append(ibuf, buf_len); + if (!buf_p) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "No room to append mbuf"); + status = TEST_FAILED; + goto error_exit; + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { + rte_memcpy(buf_p, tdata->iv.data, tdata->iv.len); + buf_p += tdata->iv.len; + } + + /* only encryption requires plaintext.data input, + * decryption/(digest gen)/(digest verify) use ciphertext.data + * to be computed + */ + if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) { + rte_memcpy(buf_p, tdata->plaintext.data, + tdata->plaintext.len); + buf_p += tdata->plaintext.len; + } else { + rte_memcpy(buf_p, tdata->ciphertext.data, + tdata->ciphertext.len); + buf_p += tdata->ciphertext.len; + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) + rte_memcpy(buf_p, tdata->digest.data, digest_len); + else + memset(buf_p, 0, digest_len); + + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) { + obuf = rte_pktmbuf_alloc(mbuf_pool); + if (!obuf) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "Allocation of rte_mbuf failed"); + status = TEST_FAILED; + goto error_exit; + } + + buf_p = rte_pktmbuf_append(obuf, buf_len); + if (!buf_p) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "No room to append mbuf"); + status = TEST_FAILED; + goto error_exit; + } + memset(buf_p, 0, buf_len); + } + + /* Generate Crypto op data structure */ + op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_SYMMETRIC); + if (!op) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Failed to allocate symmetric crypto " + "operation struct"); + status = TEST_FAILED; + goto error_exit; + } + + sym_op = op->sym; + + sym_op->m_src = ibuf; + + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) { + sym_op->m_dst = obuf; + iobuf = obuf; + } else { + sym_op->m_dst = NULL; + iobuf = ibuf; + } + + /* sessionless op requires allocate xform using + * rte_crypto_op_sym_xforms_alloc(), otherwise rte_zmalloc() + * is used + */ + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) { + uint32_t n_xforms = 0; + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) + n_xforms++; + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) + n_xforms++; + + if (rte_crypto_op_sym_xforms_alloc(op, n_xforms) + == NULL) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, "Failed to " + "allocate space for crypto transforms"); + status = TEST_FAILED; + goto error_exit; + } + } else { + cipher_xform = rte_zmalloc(NULL, + sizeof(struct rte_crypto_sym_xform), 0); + + auth_xform = rte_zmalloc(NULL, + sizeof(struct rte_crypto_sym_xform), 0); + + if (!cipher_xform || !auth_xform) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, "Failed to " + "allocate memory for crypto transforms"); + status = TEST_FAILED; + goto error_exit; + } + } + + /* preparing xform, for sessioned op, init_xform is initialized + * here and later as param in rte_cryptodev_sym_session_create() call + */ + if (t->op_mask == BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN) { + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) { + cipher_xform = op->sym->xform; + auth_xform = cipher_xform->next; + auth_xform->next = NULL; + } else { + cipher_xform->next = auth_xform; + auth_xform->next = NULL; + init_xform = cipher_xform; + } + } else if (t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC) { + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) { + auth_xform = op->sym->xform; + cipher_xform = auth_xform->next; + cipher_xform->next = NULL; + } else { + auth_xform->next = cipher_xform; + cipher_xform->next = NULL; + init_xform = auth_xform; + } + } else if ((t->op_mask == BLOCKCIPHER_TEST_OP_ENCRYPT) || + (t->op_mask == BLOCKCIPHER_TEST_OP_DECRYPT)) { + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) + cipher_xform = op->sym->xform; + else + init_xform = cipher_xform; + cipher_xform->next = NULL; + } else if ((t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_GEN) || + (t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_VERIFY)) { + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) + auth_xform = op->sym->xform; + else + init_xform = auth_xform; + auth_xform->next = NULL; + } else { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Unrecognized operation"); + status = TEST_FAILED; + goto error_exit; + } + + /*configure xforms & sym_op cipher and auth data*/ + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { + cipher_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; + cipher_xform->cipher.algo = tdata->crypto_algo; + if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) + cipher_xform->cipher.op = + RTE_CRYPTO_CIPHER_OP_ENCRYPT; + else + cipher_xform->cipher.op = + RTE_CRYPTO_CIPHER_OP_DECRYPT; + cipher_xform->cipher.key.data = cipher_key; + cipher_xform->cipher.key.length = tdata->cipher_key.len; + + sym_op->cipher.data.offset = tdata->iv.len; + sym_op->cipher.data.length = tdata->ciphertext.len; + sym_op->cipher.iv.data = rte_pktmbuf_mtod(sym_op->m_src, + uint8_t *); + sym_op->cipher.iv.length = tdata->iv.len; + sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys( + sym_op->m_src); + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) { + uint32_t auth_data_offset = 0; + uint32_t digest_offset = tdata->ciphertext.len; + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { + digest_offset += tdata->iv.len; + auth_data_offset += tdata->iv.len; + } + + auth_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; + auth_xform->auth.algo = tdata->auth_algo; + auth_xform->auth.key.length = tdata->auth_key.len; + auth_xform->auth.key.data = auth_key; + auth_xform->auth.digest_length = digest_len; + + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) { + auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; + sym_op->auth.digest.data = rte_pktmbuf_mtod_offset + (iobuf, uint8_t *, digest_offset); + sym_op->auth.digest.phys_addr = + rte_pktmbuf_mtophys_offset(iobuf, + digest_offset); + } else { + auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; + sym_op->auth.digest.data = rte_pktmbuf_mtod_offset + (sym_op->m_src, uint8_t *, digest_offset); + sym_op->auth.digest.phys_addr = + rte_pktmbuf_mtophys_offset(sym_op->m_src, + digest_offset); + } + + sym_op->auth.data.offset = auth_data_offset; + sym_op->auth.data.length = tdata->ciphertext.len; + sym_op->auth.digest.length = digest_len; + } + + /* create session for sessioned op */ + if (!(t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)) { + sess = rte_cryptodev_sym_session_create(dev_id, + init_xform); + if (!sess) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "Session creation failed"); + status = TEST_FAILED; + goto error_exit; + } + + /* attach symmetric crypto session to crypto operations */ + rte_crypto_op_attach_sym_session(op, sess); + } + + /* Process crypto operation */ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Error sending packet for encryption"); + status = TEST_FAILED; + goto error_exit; + } + + op = NULL; + + while (rte_cryptodev_dequeue_burst(dev_id, 0, &op, 1) == 0) + rte_pause(); + + if (!op) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s", + __LINE__, "Failed to process sym crypto op"); + status = TEST_FAILED; + goto error_exit; + } + + TEST_HEXDUMP(stdout, "m_src:", + rte_pktmbuf_mtod(sym_op->m_src, uint8_t *), buf_len); + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) + TEST_HEXDUMP(stdout, "m_dst:", + rte_pktmbuf_mtod(sym_op->m_dst, uint8_t *), + buf_len); + + /* Verify results */ + if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) { + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: Digest verification failed " + "(0x%X)", __LINE__, op->status); + else + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: Digest verification failed " + "(0x%X)", __LINE__, op->status); + status = TEST_FAILED; + goto error_exit; + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { + uint8_t *crypto_res; + const uint8_t *compare_ref; + uint32_t compare_len; + + crypto_res = rte_pktmbuf_mtod_offset(iobuf, uint8_t *, + tdata->iv.len); + + if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) { + compare_ref = tdata->ciphertext.data; + compare_len = tdata->ciphertext.len; + } else { + compare_ref = tdata->plaintext.data; + compare_len = tdata->plaintext.len; + } + + if (memcmp(crypto_res, compare_ref, compare_len)) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "Crypto data not as expected"); + status = TEST_FAILED; + goto error_exit; + } + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) { + uint8_t *auth_res; + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) + auth_res = rte_pktmbuf_mtod_offset(iobuf, + uint8_t *, + tdata->iv.len + tdata->ciphertext.len); + else + auth_res = rte_pktmbuf_mtod_offset(iobuf, + uint8_t *, tdata->ciphertext.len); + + if (memcmp(auth_res, tdata->digest.data, digest_len)) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, "Generated " + "digest data not as expected"); + status = TEST_FAILED; + goto error_exit; + } + } + + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "PASS"); + +error_exit: + if (!(t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)) { + if (sess) + rte_cryptodev_sym_session_free(dev_id, sess); + if (cipher_xform) + rte_free(cipher_xform); + if (auth_xform) + rte_free(auth_xform); + } + + if (op) + rte_crypto_op_free(op); + + if (obuf) + rte_pktmbuf_free(obuf); + + if (ibuf) + rte_pktmbuf_free(ibuf); + + return status; +} + +int +test_blockcipher_all_tests(struct rte_mempool *mbuf_pool, + struct rte_mempool *op_mpool, + uint8_t dev_id, + enum rte_cryptodev_type cryptodev_type, + enum blockcipher_test_type test_type) +{ + int status, overall_status = TEST_SUCCESS; + uint32_t i, test_index = 0; + char test_msg[BLOCKCIPHER_TEST_MSG_LEN + 1]; + uint32_t n_test_cases = 0; + uint32_t target_pmd_mask = 0; + const struct blockcipher_test_case *tcs = NULL; + + switch (test_type) { + case BLKCIPHER_AES_CHAIN_TYPE: + n_test_cases = sizeof(aes_chain_test_cases) / + sizeof(aes_chain_test_cases[0]); + tcs = aes_chain_test_cases; + break; + case BLKCIPHER_AES_CIPHERONLY_TYPE: + case BLKCIPHER_3DES_CHAIN_TYPE: + case BLKCIPHER_3DES_CIPHERONLY_TYPE: + case BLKCIPHER_AUTHONLY_TYPE: + default: + break; + } + + switch (cryptodev_type) { + case RTE_CRYPTODEV_AESNI_MB_PMD: + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB; + break; + case RTE_CRYPTODEV_QAT_SYM_PMD: + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT; + break; + default: + TEST_ASSERT(0, "Unrecognized cryptodev type"); + break; + } + + for (i = 0; i < n_test_cases; i++) { + const struct blockcipher_test_case *tc = &tcs[i]; + + if (!(tc->pmd_mask & target_pmd_mask)) + continue; + + status = test_blockcipher_one_case(tc, mbuf_pool, op_mpool, + dev_id, cryptodev_type, test_msg); + + printf(" %u) TestCase %s %s\n", test_index ++, + tc->test_descr, test_msg); + + if (status != TEST_SUCCESS) { + if (overall_status == TEST_SUCCESS) + overall_status = status; + + if (tc->feature_mask & BLOCKCIPHER_TEST_FEATURE_STOPPER) + break; + } + } + + return overall_status; +} diff --git a/app/test/test_cryptodev_blockcipher.h b/app/test/test_cryptodev_blockcipher.h new file mode 100644 index 0000000..686e6fb --- /dev/null +++ b/app/test/test_cryptodev_blockcipher.h @@ -0,0 +1,124 @@ +/*- + * 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 TEST_CRYPTODEV_BLOCKCIPHER_H_ +#define TEST_CRYPTODEV_BLOCKCIPHER_H_ + +#ifndef BLOCKCIPHER_TEST_MSG_LEN +#define BLOCKCIPHER_TEST_MSG_LEN 256 +#endif + +#define BLOCKCIPHER_TEST_OP_ENCRYPT 0x01 +#define BLOCKCIPHER_TEST_OP_DECRYPT 0x02 +#define BLOCKCIPHER_TEST_OP_AUTH_GEN 0x04 +#define BLOCKCIPHER_TEST_OP_AUTH_VERIFY 0x08 + +#define BLOCKCIPHER_TEST_FEATURE_OOP 0x01 +#define BLOCKCIPHER_TEST_FEATURE_SESSIONLESS 0x02 +#define BLOCKCIPHER_TEST_FEATURE_STOPPER 0x04 /* stop upon failing */ + +#define BLOCKCIPHER_TEST_TARGET_PMD_MB 0x0001 /* Multi-buffer flag */ +#define BLOCKCIPHER_TEST_TARGET_PMD_QAT 0x0002 /* QAT flag */ + +#define BLOCKCIPHER_TEST_OP_CIPHER (BLOCKCIPHER_TEST_OP_ENCRYPT | \ + BLOCKCIPHER_TEST_OP_DECRYPT) + +#define BLOCKCIPHER_TEST_OP_AUTH (BLOCKCIPHER_TEST_OP_AUTH_GEN | \ + BLOCKCIPHER_TEST_OP_AUTH_VERIFY) + +#define BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN (BLOCKCIPHER_TEST_OP_ENCRYPT | \ + BLOCKCIPHER_TEST_OP_AUTH_GEN) + +#define BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC (BLOCKCIPHER_TEST_OP_DECRYPT | \ + BLOCKCIPHER_TEST_OP_AUTH_VERIFY) + +enum blockcipher_test_type { + BLKCIPHER_AES_CHAIN_TYPE, /* use aes_chain_test_cases[] */ + BLKCIPHER_AES_CIPHERONLY_TYPE, /* use aes_cipheronly_test_cases[] */ + BLKCIPHER_3DES_CHAIN_TYPE, /* use triple_des_chain_test_cases[] */ + BLKCIPHER_3DES_CIPHERONLY_TYPE, /* triple_des_cipheronly_test_cases[] */ + BLKCIPHER_AUTHONLY_TYPE /* use hash_test_cases[] */ +}; + +struct blockcipher_test_case { + const char *test_descr; /* test description */ + const struct blockcipher_test_data *test_data; + uint8_t op_mask; /* operation mask */ + uint8_t feature_mask; + uint32_t pmd_mask; +}; + +struct blockcipher_test_data { + enum rte_crypto_cipher_algorithm crypto_algo; + + struct { + uint8_t data[64]; + unsigned int len; + } cipher_key; + + struct { + uint8_t data[64] __rte_aligned(16); + unsigned int len; + } iv; + + struct { + const uint8_t *data; + unsigned int len; + } plaintext; + + struct { + const uint8_t *data; + unsigned int len; + } ciphertext; + + enum rte_crypto_auth_algorithm auth_algo; + + struct { + uint8_t data[128]; + unsigned int len; + } auth_key; + + struct { + uint8_t data[128]; + unsigned int len; /* for qat */ + unsigned int truncated_len; /* for mb */ + } digest; +}; + +int +test_blockcipher_all_tests(struct rte_mempool *mbuf_pool, + struct rte_mempool *op_mpool, + uint8_t dev_id, + enum rte_cryptodev_type cryptodev_type, + enum blockcipher_test_type test_type); + +#endif /* TEST_CRYPTODEV_BLOCKCIPHER_H_ */ -- 2.5.0 ^ permalink raw reply [flat|nested] 34+ messages in thread
* [dpdk-dev] [PATCH v5 3/4] app/test: added tests for libcrypto PMD 2016-10-03 14:26 ` [dpdk-dev] [PATCH v5 0/4] new crypto software based device Slawomir Mrozowicz 2016-10-03 14:45 ` [dpdk-dev] [PATCH v5 1/4] libcrypto_pmd: initial implementation of SW crypto device Slawomir Mrozowicz 2016-10-03 15:02 ` [dpdk-dev] [PATCH v5 2/4] app/test: cryptodev AES tests rework Slawomir Mrozowicz @ 2016-10-03 15:17 ` Slawomir Mrozowicz 2016-10-03 15:28 ` [dpdk-dev] [PATCH v5 4/4] examples/l2fwd-crypto: updated example " Slawomir Mrozowicz ` (2 subsequent siblings) 5 siblings, 0 replies; 34+ messages in thread From: Slawomir Mrozowicz @ 2016-10-03 15:17 UTC (permalink / raw) To: dev; +Cc: Slawomir Mrozowicz, Piotr Azarewicz, Marcin Kerlin, Daniel Mrzyglod This patch containes unit tests for libcrypto PMD. User can use app/test application to check how to use this pmd and to verify crypto processing. Test name is cryptodev_libcrypto_autotest. For performance test cryptodev_libcrypto_perftest can be used. Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com> Signed-off-by: Marcin Kerlin <marcinx.kerlin@intel.com> Signed-off-by: Daniel Mrzyglod <danielx.t.mrzyglod@intel.com> --- v2: - rename AES-named functions to blockcipher - replace different test cases with blockcipher functions pattern - add 3DES tests into QuickAssist PMD testsuite v3: - add nagative verification tests - add big data test v4: - move aes test rework to another patch - move big data test to another patch - checking if libcrypto pmd is available v5: - add reduced big data test --- app/test/test_cryptodev.c | 1495 +++++++++++++++++++++++++-- app/test/test_cryptodev.h | 1 + app/test/test_cryptodev_aes_test_vectors.h | 304 +++++- app/test/test_cryptodev_blockcipher.c | 22 + app/test/test_cryptodev_blockcipher.h | 1 + app/test/test_cryptodev_des_test_vectors.h | 952 +++++++++++++++++ app/test/test_cryptodev_gcm_test_vectors.h | 36 +- app/test/test_cryptodev_hash_test_vectors.h | 491 +++++++++ app/test/test_cryptodev_perf.c | 689 +++++++++++- 9 files changed, 3911 insertions(+), 80 deletions(-) create mode 100644 app/test/test_cryptodev_des_test_vectors.h create mode 100644 app/test/test_cryptodev_hash_test_vectors.h diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c index c46db94..54982d2 100644 --- a/app/test/test_cryptodev.c +++ b/app/test/test_cryptodev.c @@ -45,6 +45,8 @@ #include "test_cryptodev_blockcipher.h" #include "test_cryptodev_aes_test_vectors.h" +#include "test_cryptodev_des_test_vectors.h" +#include "test_cryptodev_hash_test_vectors.h" #include "test_cryptodev_kasumi_test_vectors.h" #include "test_cryptodev_kasumi_hash_test_vectors.h" #include "test_cryptodev_snow3g_test_vectors.h" @@ -167,7 +169,7 @@ testsuite_setup(void) /* Not already created so create */ ts_params->mbuf_pool = rte_pktmbuf_pool_create( "CRYPTO_MBUFPOOL", - NUM_MBUFS, MBUF_CACHE_SIZE, 0, MBUF_SIZE, + NUM_MBUFS, MBUF_CACHE_SIZE, 0, UINT16_MAX, rte_socket_id()); if (ts_params->mbuf_pool == NULL) { RTE_LOG(ERR, USER1, "Can't create CRYPTO_MBUFPOOL\n"); @@ -308,6 +310,26 @@ testsuite_setup(void) } } + /* Create 2 LIBCRYPTO devices if required */ + if (gbl_cryptodev_type == RTE_CRYPTODEV_LIBCRYPTO_PMD) { +#ifndef RTE_LIBRTE_PMD_LIBCRYPTO + RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO must be" + " enabled in config file to run this testsuite.\n"); + return TEST_FAILED; +#endif + nb_devs = rte_cryptodev_count_devtype(RTE_CRYPTODEV_LIBCRYPTO_PMD); + if (nb_devs < 2) { + for (i = nb_devs; i < 2; i++) { + ret = rte_eal_vdev_init( + RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), NULL); + + TEST_ASSERT(ret == 0, + "Failed to create instance %u of pmd : %s", + i, RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD)); + } + } + } + #ifndef RTE_LIBRTE_PMD_QAT if (gbl_cryptodev_type == RTE_CRYPTODEV_QAT_SYM_PMD) { RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_QAT must be enabled " @@ -877,6 +899,315 @@ static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA1_digest[] = { 0x18, 0x8c, 0x1d, 0x32 }; + +/* Multisession Vector context Test */ +/*Begin Session 0 */ +static uint8_t ms_aes_cbc_key0[] = { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static uint8_t ms_aes_cbc_iv0[] = { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static const uint8_t ms_aes_cbc_cipher0[] = { + 0x3C, 0xE4, 0xEE, 0x42, 0xB6, 0x9B, 0xC3, 0x38, + 0x5F, 0xAD, 0x54, 0xDC, 0xA8, 0x32, 0x81, 0xDC, + 0x7A, 0x6F, 0x85, 0x58, 0x07, 0x35, 0xED, 0xEB, + 0xAD, 0x79, 0x79, 0x96, 0xD3, 0x0E, 0xA6, 0xD9, + 0xAA, 0x86, 0xA4, 0x8F, 0xB5, 0xD6, 0x6E, 0x6D, + 0x0C, 0x91, 0x2F, 0xC4, 0x67, 0x98, 0x0E, 0xC4, + 0x8D, 0x83, 0x68, 0x69, 0xC4, 0xD3, 0x94, 0x34, + 0xC4, 0x5D, 0x60, 0x55, 0x22, 0x87, 0x8F, 0x6F, + 0x17, 0x8E, 0x75, 0xE4, 0x02, 0xF5, 0x1B, 0x99, + 0xC8, 0x39, 0xA9, 0xAB, 0x23, 0x91, 0x12, 0xED, + 0x08, 0xE7, 0xD9, 0x25, 0x89, 0x24, 0x4F, 0x8D, + 0x68, 0xF3, 0x10, 0x39, 0x0A, 0xEE, 0x45, 0x24, + 0xDF, 0x7A, 0x9D, 0x00, 0x25, 0xE5, 0x35, 0x71, + 0x4E, 0x40, 0x59, 0x6F, 0x0A, 0x13, 0xB3, 0x72, + 0x1D, 0x98, 0x63, 0x94, 0x89, 0xA5, 0x39, 0x8E, + 0xD3, 0x9C, 0x8A, 0x7F, 0x71, 0x2F, 0xC7, 0xCD, + 0x81, 0x05, 0xDC, 0xC0, 0x8D, 0xCE, 0x6D, 0x18, + 0x30, 0xC4, 0x72, 0x51, 0xF0, 0x27, 0xC8, 0xF6, + 0x60, 0x5B, 0x7C, 0xB2, 0xE3, 0x49, 0x0C, 0x29, + 0xC6, 0x9F, 0x39, 0x57, 0x80, 0x55, 0x24, 0x2C, + 0x9B, 0x0F, 0x5A, 0xB3, 0x89, 0x55, 0x31, 0x96, + 0x0D, 0xCD, 0xF6, 0x51, 0x03, 0x2D, 0x89, 0x26, + 0x74, 0x44, 0xD6, 0xE8, 0xDC, 0xEA, 0x44, 0x55, + 0x64, 0x71, 0x9C, 0x9F, 0x5D, 0xBA, 0x39, 0x46, + 0xA8, 0x17, 0xA1, 0x9C, 0x52, 0x9D, 0xBC, 0x6B, + 0x4A, 0x98, 0xE6, 0xEA, 0x33, 0xEC, 0x58, 0xB4, + 0x43, 0xF0, 0x32, 0x45, 0xA4, 0xC1, 0x55, 0xB7, + 0x5D, 0xB5, 0x59, 0xB2, 0xE3, 0x96, 0xFF, 0xA5, + 0xAF, 0xE1, 0x86, 0x1B, 0x42, 0xE6, 0x3B, 0xA0, + 0x90, 0x4A, 0xE8, 0x8C, 0x21, 0x7F, 0x36, 0x1E, + 0x5B, 0x65, 0x25, 0xD1, 0xC1, 0x5A, 0xCA, 0x3D, + 0x10, 0xED, 0x2D, 0x79, 0xD0, 0x0F, 0x58, 0x44, + 0x69, 0x81, 0xF5, 0xD4, 0xC9, 0x0F, 0x90, 0x76, + 0x1F, 0x54, 0xD2, 0xD5, 0x97, 0xCE, 0x2C, 0xE3, + 0xEF, 0xF4, 0xB7, 0xC6, 0x3A, 0x87, 0x7F, 0x83, + 0x2A, 0xAF, 0xCD, 0x90, 0x12, 0xA7, 0x7D, 0x85, + 0x1D, 0x62, 0xD3, 0x85, 0x25, 0x05, 0xDB, 0x45, + 0x92, 0xA3, 0xF6, 0xA2, 0xA8, 0x41, 0xE4, 0x25, + 0x86, 0x87, 0x67, 0x24, 0xEC, 0x89, 0x23, 0x2A, + 0x9B, 0x20, 0x4D, 0x93, 0xEE, 0xE2, 0x2E, 0xC1, + 0x0B, 0x15, 0x33, 0xCF, 0x00, 0xD1, 0x1A, 0xDA, + 0x93, 0xFD, 0x28, 0x21, 0x5B, 0xCF, 0xD1, 0xF3, + 0x5A, 0x81, 0xBA, 0x82, 0x5E, 0x2F, 0x61, 0xB4, + 0x05, 0x71, 0xB5, 0xF4, 0x39, 0x3C, 0x1F, 0x60, + 0x00, 0x7A, 0xC4, 0xF8, 0x35, 0x20, 0x6C, 0x3A, + 0xCC, 0x03, 0x8F, 0x7B, 0xA2, 0xB6, 0x65, 0x8A, + 0xB6, 0x5F, 0xFD, 0x25, 0xD3, 0x5F, 0x92, 0xF9, + 0xAE, 0x17, 0x9B, 0x5E, 0x6E, 0x9A, 0xE4, 0x55, + 0x10, 0x25, 0x07, 0xA4, 0xAF, 0x21, 0x69, 0x13, + 0xD8, 0xFA, 0x31, 0xED, 0xF7, 0xA7, 0xA7, 0x3B, + 0xB8, 0x96, 0x8E, 0x10, 0x86, 0x74, 0xD8, 0xB1, + 0x34, 0x9E, 0x9B, 0x6A, 0x26, 0xA8, 0xD4, 0xD0, + 0xB5, 0xF6, 0xDE, 0xE7, 0xCA, 0x06, 0xDC, 0xA3, + 0x6F, 0xEE, 0x6B, 0x1E, 0xB5, 0x30, 0x99, 0x23, + 0xF9, 0x76, 0xF0, 0xA0, 0xCF, 0x3B, 0x94, 0x7B, + 0x19, 0x8D, 0xA5, 0x0C, 0x18, 0xA6, 0x1D, 0x07, + 0x89, 0xBE, 0x5B, 0x61, 0xE5, 0xF1, 0x42, 0xDB, + 0xD4, 0x2E, 0x02, 0x1F, 0xCE, 0xEF, 0x92, 0xB1, + 0x1B, 0x56, 0x50, 0xF2, 0x16, 0xE5, 0xE7, 0x4F, + 0xFD, 0xBB, 0x3E, 0xD2, 0xFC, 0x3C, 0xC6, 0x0F, + 0xF9, 0x12, 0x4E, 0xCB, 0x1E, 0x0C, 0x15, 0x84, + 0x2A, 0x14, 0x8A, 0x02, 0xE4, 0x7E, 0x95, 0x5B, + 0x86, 0xDB, 0x9B, 0x62, 0x5B, 0x19, 0xD2, 0x17, + 0xFA, 0x13, 0xBB, 0x6B, 0x3F, 0x45, 0x9F, 0xBF +}; + + +static uint8_t ms_hmac_key0[] = { + 0xFF, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 +}; + +static const uint8_t ms_hmac_digest0[] = { + 0x43, 0x52, 0xED, 0x34, 0xAB, 0x36, 0xB2, 0x51, + 0xFB, 0xA3, 0xA6, 0x7C, 0x38, 0xFC, 0x42, 0x8F, + 0x57, 0x64, 0xAB, 0x81, 0xA7, 0x89, 0xB7, 0x6C, + 0xA0, 0xDC, 0xB9, 0x4D, 0xC4, 0x30, 0xF9, 0xD4, + 0x10, 0x82, 0x55, 0xD0, 0xAB, 0x32, 0xFB, 0x56, + 0x0D, 0xE4, 0x68, 0x3D, 0x76, 0xD0, 0x7B, 0xE4, + 0xA6, 0x2C, 0x34, 0x9E, 0x8C, 0x41, 0xF8, 0x23, + 0x28, 0x1B, 0x3A, 0x90, 0x26, 0x34, 0x47, 0x90 + }; + +/* End Session 0 */ +/* Begin session 1 */ + +static uint8_t ms_aes_cbc_key1[] = { + 0xf1, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static uint8_t ms_aes_cbc_iv1[] = { + 0xf1, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static const uint8_t ms_aes_cbc_cipher1[] = { + 0x5A, 0x7A, 0x67, 0x5D, 0xB8, 0xE1, 0xDC, 0x71, + 0x39, 0xA8, 0x74, 0x93, 0x9C, 0x4C, 0xFE, 0x23, + 0x61, 0xCD, 0xA4, 0xB3, 0xD9, 0xCE, 0x99, 0x09, + 0x2A, 0x23, 0xF3, 0x29, 0xBF, 0x4C, 0xB4, 0x6A, + 0x1B, 0x6B, 0x73, 0x4D, 0x48, 0x0C, 0xCF, 0x6C, + 0x5E, 0x34, 0x9E, 0x7F, 0xBC, 0x8F, 0xCC, 0x8F, + 0x75, 0x1D, 0x3D, 0x77, 0x10, 0x76, 0xC8, 0xB9, + 0x99, 0x6F, 0xD6, 0x56, 0x75, 0xA9, 0xB2, 0x66, + 0xC2, 0x24, 0x2B, 0x9C, 0xFE, 0x40, 0x8E, 0x43, + 0x20, 0x97, 0x1B, 0xFA, 0xD0, 0xCF, 0x04, 0xAB, + 0xBB, 0xF6, 0x5D, 0xF5, 0xA0, 0x19, 0x7C, 0x23, + 0x5D, 0x80, 0x8C, 0x49, 0xF6, 0x76, 0x88, 0x29, + 0x27, 0x4C, 0x59, 0x2B, 0x43, 0xA6, 0xB2, 0x26, + 0x27, 0x78, 0xBE, 0x1B, 0xE1, 0x4F, 0x5A, 0x1F, + 0xFC, 0x68, 0x08, 0xE7, 0xC4, 0xD1, 0x34, 0x68, + 0xB7, 0x13, 0x14, 0x41, 0x62, 0x6B, 0x1F, 0x77, + 0x0C, 0x68, 0x1D, 0x0D, 0xED, 0x89, 0xAA, 0xD8, + 0x97, 0x02, 0xBA, 0x5E, 0xD4, 0x84, 0x25, 0x97, + 0x03, 0xA5, 0xA6, 0x13, 0x66, 0x02, 0xF4, 0xC3, + 0xF3, 0xD3, 0xCC, 0x95, 0xC3, 0x87, 0x46, 0x90, + 0x1F, 0x6E, 0x14, 0xA8, 0x00, 0xF2, 0x6F, 0xD5, + 0xA1, 0xAD, 0xD5, 0x40, 0xA2, 0x0F, 0x32, 0x7E, + 0x99, 0xA3, 0xF5, 0x53, 0xC3, 0x26, 0xA1, 0x45, + 0x01, 0x88, 0x57, 0x84, 0x3E, 0x7B, 0x4E, 0x0B, + 0x3C, 0xB5, 0x3E, 0x9E, 0xE9, 0x78, 0x77, 0xC5, + 0xC0, 0x89, 0xA8, 0xF8, 0xF1, 0xA5, 0x2D, 0x5D, + 0xF9, 0xC6, 0xFB, 0xCB, 0x05, 0x23, 0xBD, 0x6E, + 0x5E, 0x14, 0xC6, 0x57, 0x73, 0xCF, 0x98, 0xBD, + 0x10, 0x8B, 0x18, 0xA6, 0x01, 0x5B, 0x13, 0xAE, + 0x8E, 0xDE, 0x1F, 0xB5, 0xB7, 0x40, 0x6C, 0xC1, + 0x1E, 0xA1, 0x19, 0x20, 0x9E, 0x95, 0xE0, 0x2F, + 0x1C, 0xF5, 0xD9, 0xD0, 0x2B, 0x1E, 0x82, 0x25, + 0x62, 0xB4, 0xEB, 0xA1, 0x1F, 0xCE, 0x44, 0xA1, + 0xCB, 0x92, 0x01, 0x6B, 0xE4, 0x26, 0x23, 0xE3, + 0xC5, 0x67, 0x35, 0x55, 0xDA, 0xE5, 0x27, 0xEE, + 0x8D, 0x12, 0x84, 0xB7, 0xBA, 0xA7, 0x1C, 0xD6, + 0x32, 0x3F, 0x67, 0xED, 0xFB, 0x5B, 0x8B, 0x52, + 0x46, 0x8C, 0xF9, 0x69, 0xCD, 0xAE, 0x79, 0xAA, + 0x37, 0x78, 0x49, 0xEB, 0xC6, 0x8E, 0x76, 0x63, + 0x84, 0xFF, 0x9D, 0x22, 0x99, 0x51, 0xB7, 0x5E, + 0x83, 0x4C, 0x8B, 0xDF, 0x5A, 0x07, 0xCC, 0xBA, + 0x42, 0xA5, 0x98, 0xB6, 0x47, 0x0E, 0x66, 0xEB, + 0x23, 0x0E, 0xBA, 0x44, 0xA8, 0xAA, 0x20, 0x71, + 0x79, 0x9C, 0x77, 0x5F, 0xF5, 0xFE, 0xEC, 0xEF, + 0xC6, 0x64, 0x3D, 0x84, 0xD0, 0x2B, 0xA7, 0x0A, + 0xC3, 0x72, 0x5B, 0x9C, 0xFA, 0xA8, 0x87, 0x95, + 0x94, 0x11, 0x38, 0xA7, 0x1E, 0x58, 0xE3, 0x73, + 0xC6, 0xC9, 0xD1, 0x7B, 0x92, 0xDB, 0x0F, 0x49, + 0x74, 0xC2, 0xA2, 0x0E, 0x35, 0x57, 0xAC, 0xDB, + 0x9A, 0x1C, 0xCF, 0x5A, 0x32, 0x3E, 0x26, 0x9B, + 0xEC, 0xB3, 0xEF, 0x9C, 0xFE, 0xBE, 0x52, 0xAC, + 0xB1, 0x29, 0xDD, 0xFD, 0x07, 0xE2, 0xEE, 0xED, + 0xE4, 0x46, 0x37, 0xFE, 0xD1, 0xDC, 0xCD, 0x02, + 0xF9, 0x31, 0xB0, 0xFB, 0x36, 0xB7, 0x34, 0xA4, + 0x76, 0xE8, 0x57, 0xBF, 0x99, 0x92, 0xC7, 0xAF, + 0x98, 0x10, 0xE2, 0x70, 0xCA, 0xC9, 0x2B, 0x82, + 0x06, 0x96, 0x88, 0x0D, 0xB3, 0xAC, 0x9E, 0x6D, + 0x43, 0xBC, 0x5B, 0x31, 0xCF, 0x65, 0x8D, 0xA6, + 0xC7, 0xFE, 0x73, 0xE1, 0x54, 0xF7, 0x10, 0xF9, + 0x86, 0xF7, 0xDF, 0xA1, 0xA1, 0xD8, 0xAE, 0x35, + 0xB3, 0x90, 0xDC, 0x6F, 0x43, 0x7A, 0x8B, 0xE0, + 0xFE, 0x8F, 0x33, 0x4D, 0x29, 0x6C, 0x45, 0x53, + 0x73, 0xDD, 0x21, 0x0B, 0x85, 0x30, 0xB5, 0xA5, + 0xF3, 0x5D, 0xEC, 0x79, 0x61, 0x9D, 0x9E, 0xB3 + +}; + +static uint8_t ms_hmac_key1[] = { + 0xFE, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 +}; + +static const uint8_t ms_hmac_digest1[] = { + 0xCE, 0x6E, 0x5F, 0x77, 0x96, 0x9A, 0xB1, 0x69, + 0x2D, 0x5E, 0xF3, 0x2F, 0x32, 0x10, 0xCB, 0x50, + 0x0E, 0x09, 0x56, 0x25, 0x07, 0x34, 0xC9, 0x20, + 0xEC, 0x13, 0x43, 0x23, 0x5C, 0x08, 0x8B, 0xCD, + 0xDC, 0x86, 0x8C, 0xEE, 0x0A, 0x95, 0x2E, 0xB9, + 0x8C, 0x7B, 0x02, 0x7A, 0xD4, 0xE1, 0x49, 0xB4, + 0x45, 0xB5, 0x52, 0x37, 0xC6, 0xFF, 0xFE, 0xAA, + 0x0A, 0x87, 0xB8, 0x51, 0xF9, 0x2A, 0x01, 0x8F +}; +/* End Session 1 */ +/* Begin Session 2 */ +static uint8_t ms_aes_cbc_key2[] = { + 0xff, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static uint8_t ms_aes_cbc_iv2[] = { + 0xff, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static const uint8_t ms_aes_cbc_cipher2[] = { + 0xBB, 0x3C, 0x68, 0x25, 0xFD, 0xB6, 0xA2, 0x91, + 0x20, 0x56, 0xF6, 0x30, 0x35, 0xFC, 0x9E, 0x97, + 0xF2, 0x90, 0xFC, 0x7E, 0x3E, 0x0A, 0x75, 0xC8, + 0x4C, 0xF2, 0x2D, 0xAC, 0xD3, 0x93, 0xF0, 0xC5, + 0x14, 0x88, 0x8A, 0x23, 0xC2, 0x59, 0x9A, 0x98, + 0x4B, 0xD5, 0x2C, 0xDA, 0x43, 0xA9, 0x34, 0x69, + 0x7C, 0x6D, 0xDB, 0xDC, 0xCB, 0xC0, 0xA0, 0x09, + 0xA7, 0x86, 0x16, 0x4B, 0xBF, 0xA8, 0xB6, 0xCF, + 0x7F, 0x74, 0x1F, 0x22, 0xF0, 0xF6, 0xBB, 0x44, + 0x8B, 0x4C, 0x9E, 0x23, 0xF8, 0x9F, 0xFC, 0x5B, + 0x9E, 0x9C, 0x2A, 0x79, 0x30, 0x8F, 0xBF, 0xA9, + 0x68, 0xA1, 0x20, 0x71, 0x7C, 0x77, 0x22, 0x34, + 0x07, 0xCD, 0xC6, 0xF6, 0x50, 0x0A, 0x08, 0x99, + 0x17, 0x98, 0xE3, 0x93, 0x8A, 0xB0, 0xEE, 0xDF, + 0xC2, 0xBA, 0x3B, 0x44, 0x73, 0xDF, 0xDD, 0xDC, + 0x14, 0x4D, 0x3B, 0xBB, 0x5E, 0x58, 0xC1, 0x26, + 0xA7, 0xAE, 0x47, 0xF3, 0x24, 0x6D, 0x4F, 0xD3, + 0x6E, 0x3E, 0x33, 0xE6, 0x7F, 0xCA, 0x50, 0xAF, + 0x5D, 0x3D, 0xA0, 0xDD, 0xC9, 0xF3, 0x30, 0xD3, + 0x6E, 0x8B, 0x2E, 0x12, 0x24, 0x34, 0xF0, 0xD3, + 0xC7, 0x8D, 0x23, 0x29, 0xAA, 0x05, 0xE1, 0xFA, + 0x2E, 0xF6, 0x8D, 0x37, 0x86, 0xC0, 0x6D, 0x13, + 0x2D, 0x98, 0xF3, 0x52, 0x39, 0x22, 0xCE, 0x38, + 0xC2, 0x1A, 0x72, 0xED, 0xFB, 0xCC, 0xE4, 0x71, + 0x5A, 0x0C, 0x0D, 0x09, 0xF8, 0xE8, 0x1B, 0xBC, + 0x53, 0xC8, 0xD8, 0x8F, 0xE5, 0x98, 0x5A, 0xB1, + 0x06, 0xA6, 0x5B, 0xE6, 0xA2, 0x88, 0x21, 0x9E, + 0x36, 0xC0, 0x34, 0xF9, 0xFB, 0x3B, 0x0A, 0x22, + 0x00, 0x00, 0x39, 0x48, 0x8D, 0x23, 0x74, 0x62, + 0x72, 0x91, 0xE6, 0x36, 0xAA, 0x77, 0x9C, 0x72, + 0x9D, 0xA8, 0xC3, 0xA9, 0xD5, 0x44, 0x72, 0xA6, + 0xB9, 0x28, 0x8F, 0x64, 0x4C, 0x8A, 0x64, 0xE6, + 0x4E, 0xFA, 0xEF, 0x87, 0xDE, 0x7B, 0x22, 0x44, + 0xB0, 0xDF, 0x2E, 0x5F, 0x0B, 0xA5, 0xF2, 0x24, + 0x07, 0x5C, 0x2D, 0x39, 0xB7, 0x3D, 0x8A, 0xE5, + 0x0E, 0x9D, 0x4E, 0x50, 0xED, 0x03, 0x99, 0x8E, + 0xF0, 0x06, 0x55, 0x4E, 0xA2, 0x24, 0xE7, 0x17, + 0x46, 0xDF, 0x6C, 0xCD, 0xC6, 0x44, 0xE8, 0xF9, + 0xB9, 0x1B, 0x36, 0xF6, 0x7F, 0x10, 0xA4, 0x7D, + 0x90, 0xBD, 0xE4, 0xAA, 0xD6, 0x9E, 0x18, 0x9D, + 0x22, 0x35, 0xD6, 0x55, 0x54, 0xAA, 0xF7, 0x22, + 0xA3, 0x3E, 0xEF, 0xC8, 0xA2, 0x34, 0x8D, 0xA9, + 0x37, 0x63, 0xA6, 0xC3, 0x57, 0xCB, 0x0C, 0x49, + 0x7D, 0x02, 0xBE, 0xAA, 0x13, 0x75, 0xB7, 0x4E, + 0x52, 0x62, 0xA5, 0xC2, 0x33, 0xC7, 0x6C, 0x1B, + 0xF6, 0x34, 0xF6, 0x09, 0xA5, 0x0C, 0xC7, 0xA2, + 0x61, 0x48, 0x62, 0x7D, 0x17, 0x15, 0xE3, 0x95, + 0xC8, 0x63, 0xD2, 0xA4, 0x43, 0xA9, 0x49, 0x07, + 0xB2, 0x3B, 0x2B, 0x62, 0x7D, 0xCB, 0x51, 0xB3, + 0x25, 0x33, 0x47, 0x0E, 0x14, 0x67, 0xDC, 0x6A, + 0x9B, 0x51, 0xAC, 0x9D, 0x8F, 0xA2, 0x2B, 0x57, + 0x8C, 0x5C, 0x5F, 0x76, 0x23, 0x92, 0x0F, 0x84, + 0x46, 0x0E, 0x40, 0x85, 0x38, 0x60, 0xFA, 0x61, + 0x20, 0xC5, 0xE3, 0xF1, 0x70, 0xAC, 0x1B, 0xBF, + 0xC4, 0x2B, 0xC5, 0x67, 0xD1, 0x43, 0xC5, 0x17, + 0x74, 0x71, 0x69, 0x6F, 0x82, 0x89, 0x19, 0x8A, + 0x70, 0x43, 0x92, 0x01, 0xC4, 0x63, 0x7E, 0xB1, + 0x59, 0x4E, 0xCD, 0xEA, 0x93, 0xA4, 0x52, 0x53, + 0x9B, 0x61, 0x5B, 0xD2, 0x3E, 0x19, 0x39, 0xB7, + 0x32, 0xEA, 0x8E, 0xF8, 0x1D, 0x76, 0x5C, 0xB2, + 0x73, 0x2D, 0x91, 0xC0, 0x18, 0xED, 0x25, 0x2A, + 0x53, 0x64, 0xF0, 0x92, 0x31, 0x55, 0x21, 0xA8, + 0x24, 0xA9, 0xD1, 0x02, 0xF6, 0x6C, 0x2B, 0x70, + 0xA9, 0x59, 0xC1, 0xD6, 0xC3, 0x57, 0x5B, 0x92 +}; + +static uint8_t ms_hmac_key2[] = { + 0xFC, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 +}; + +static const uint8_t ms_hmac_digest2[] = { + 0xA5, 0x0F, 0x9C, 0xFB, 0x08, 0x62, 0x59, 0xFF, + 0x80, 0x2F, 0xEB, 0x4B, 0xE1, 0x46, 0x21, 0xD6, + 0x02, 0x98, 0xF2, 0x8E, 0xF4, 0xEC, 0xD4, 0x77, + 0x86, 0x4C, 0x31, 0x28, 0xC8, 0x25, 0x80, 0x27, + 0x3A, 0x72, 0x5D, 0x6A, 0x56, 0x8A, 0xD3, 0x82, + 0xB0, 0xEC, 0x31, 0x6D, 0x8B, 0x6B, 0xB4, 0x24, + 0xE7, 0x62, 0xC1, 0x52, 0xBC, 0x14, 0x1B, 0x8E, + 0xEC, 0x9A, 0xF1, 0x47, 0x80, 0xD2, 0xB0, 0x59 +}; + +/* End Session 2 */ + + static int test_AES_CBC_HMAC_SHA1_encrypt_digest(void) { @@ -1145,6 +1476,38 @@ test_AES_chain_mb_all(void) } static int +test_AES_chain_libcrypto_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_LIBCRYPTO_PMD, + BLKCIPHER_AES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_cipheronly_libcrypto_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_LIBCRYPTO_PMD, + BLKCIPHER_AES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int test_AES_chain_qat_all(void) { struct crypto_testsuite_params *ts_params = &testsuite_params; @@ -1160,6 +1523,22 @@ test_AES_chain_qat_all(void) return TEST_SUCCESS; } +static int +test_authonly_libcrypto_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_LIBCRYPTO_PMD, + BLKCIPHER_AUTHONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + /* ***** SNOW 3G Tests ***** */ static int create_wireless_algo_hash_session(uint8_t dev_id, @@ -3411,6 +3790,70 @@ test_zuc_hash_generate_test_case_5(void) return test_zuc_authentication(&zuc_hash_test_case_5); } +static int +test_3DES_chain_qat_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_QAT_SYM_PMD, + BLKCIPHER_3DES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_cipheronly_qat_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_QAT_SYM_PMD, + BLKCIPHER_3DES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_chain_libcrypto_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_LIBCRYPTO_PMD, + BLKCIPHER_3DES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_cipheronly_libcrypto_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_LIBCRYPTO_PMD, + BLKCIPHER_3DES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + /* ***** AES-GCM Tests ***** */ static int @@ -4103,6 +4546,112 @@ test_multi_session(void) return TEST_SUCCESS; } +struct multi_session_params { + struct crypto_unittest_params ut_params; + uint8_t *cipher_key; + uint8_t *hmac_key; + const uint8_t *cipher; + const uint8_t *digest; + uint8_t *iv; +}; + +#define MB_SESSION_NUMBER 3 + +static int +test_multi_session_random_usage(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_cryptodev_info dev_info; + struct rte_cryptodev_sym_session **sessions; + uint32_t i, j; + struct multi_session_params ut_paramz[] = { + + { + .cipher_key = ms_aes_cbc_key0, + .hmac_key = ms_hmac_key0, + .cipher = ms_aes_cbc_cipher0, + .digest = ms_hmac_digest0, + .iv = ms_aes_cbc_iv0 + }, + { + .cipher_key = ms_aes_cbc_key1, + .hmac_key = ms_hmac_key1, + .cipher = ms_aes_cbc_cipher1, + .digest = ms_hmac_digest1, + .iv = ms_aes_cbc_iv1 + }, + { + .cipher_key = ms_aes_cbc_key2, + .hmac_key = ms_hmac_key2, + .cipher = ms_aes_cbc_cipher2, + .digest = ms_hmac_digest2, + .iv = ms_aes_cbc_iv2 + }, + + }; + + rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info); + + sessions = rte_malloc(NULL, + (sizeof(struct rte_cryptodev_sym_session *) + * dev_info.sym.max_nb_sessions) + 1, 0); + + for (i = 0; i < MB_SESSION_NUMBER; i++) { + rte_memcpy(&ut_paramz[i].ut_params, &testsuite_params, + sizeof(struct crypto_unittest_params)); + + test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( + &ut_paramz[i].ut_params, ut_paramz[i].cipher_key, + ut_paramz[i].hmac_key); + + /* Create multiple crypto sessions*/ + sessions[i] = rte_cryptodev_sym_session_create(ts_params->valid_devs[0], + &ut_paramz[i].ut_params.auth_xform); + + TEST_ASSERT_NOT_NULL(sessions[i], + "Session creation failed at session number %u", i); + + } + + srand(time(NULL)); + for (i = 0; i < 40000; i++) { + + j = rand() % MB_SESSION_NUMBER; + + TEST_ASSERT_SUCCESS( + test_AES_CBC_HMAC_SHA512_decrypt_perform(sessions[j], + &ut_paramz[j].ut_params, ts_params, ut_paramz[j].cipher, + ut_paramz[j].digest, ut_paramz[j].iv), + "Failed to perform decrypt on request number %u.", i); + + if (ut_paramz[j].ut_params.op) + rte_crypto_op_free(ut_paramz[j].ut_params.op); + + /* + * free mbuf - both obuf and ibuf are usually the same, + * so check if they point at the same address is necessary, + * to avoid freeing the mbuf twice. + */ + if (ut_paramz[j].ut_params.obuf) { + rte_pktmbuf_free(ut_paramz[j].ut_params.obuf); + if (ut_paramz[j].ut_params.ibuf == ut_paramz[j].ut_params.obuf) + ut_paramz[j].ut_params.ibuf = 0; + ut_paramz[j].ut_params.obuf = 0; + } + if (ut_paramz[j].ut_params.ibuf) { + rte_pktmbuf_free(ut_paramz[j].ut_params.ibuf); + ut_paramz[j].ut_params.ibuf = 0; + } + } + + for (i = 0; i < MB_SESSION_NUMBER; i++) + rte_cryptodev_sym_session_free(ts_params->valid_devs[0], sessions[i]); + + rte_free(sessions); + + return TEST_SUCCESS; +} + static int test_null_cipher_only_operation(void) { @@ -4456,6 +5005,15 @@ test_null_burst_operation(void) return TEST_SUCCESS; } +static void +generate_gmac_large_plaintext(uint8_t *data) +{ + uint16_t i; + + for (i = 32; i < GMAC_LARGE_PLAINTEXT_LENGTH; i += 32) + memcpy(&data[i], &data[0], 32); +} + static int create_gmac_operation(enum rte_crypto_auth_operation op, const struct gmac_test_data *tdata) @@ -4470,6 +5028,9 @@ create_gmac_operation(enum rte_crypto_auth_operation op, iv_pad_len = RTE_ALIGN_CEIL(tdata->iv.len, 16); aad_pad_len = RTE_ALIGN_CEIL(tdata->aad.len, 16); + if (tdata->aad.len == GMAC_LARGE_PLAINTEXT_LENGTH) + generate_gmac_large_plaintext(tdata->aad.data); + /* Generate Crypto op data structure */ ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool, RTE_CRYPTO_OP_TYPE_SYMMETRIC); @@ -4647,6 +5208,12 @@ test_AES_GMAC_authentication_test_case_3(void) } static int +test_AES_GMAC_authentication_test_case_4(void) +{ + return test_AES_GMAC_authentication(&gmac_test_case_4); +} + +static int test_AES_GMAC_authentication_verify(const struct gmac_test_data *tdata) { struct crypto_testsuite_params *ts_params = &testsuite_params; @@ -4706,72 +5273,786 @@ test_AES_GMAC_authentication_verify_test_case_3(void) return test_AES_GMAC_authentication_verify(&gmac_test_case_3); } -static struct unit_test_suite cryptodev_qat_testsuite = { - .suite_name = "Crypto QAT Unit Test Suite", - .setup = testsuite_setup, - .teardown = testsuite_teardown, - .unit_test_cases = { - TEST_CASE_ST(ut_setup, ut_teardown, - test_device_configure_invalid_dev_id), - TEST_CASE_ST(ut_setup, ut_teardown, - test_device_configure_invalid_queue_pair_ids), - TEST_CASE_ST(ut_setup, ut_teardown, - test_queue_pair_descriptor_setup), - TEST_CASE_ST(ut_setup, ut_teardown, - test_multi_session), +static int +test_AES_GMAC_authentication_verify_test_case_4(void) +{ + return test_AES_GMAC_authentication_verify(&gmac_test_case_4); +} - TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_qat_all), - TEST_CASE_ST(ut_setup, ut_teardown, test_stats), +struct test_crypto_vector { + enum rte_crypto_cipher_algorithm crypto_algo; - /** AES GCM Authenticated Encryption */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_7), + struct { + uint8_t data[64]; + unsigned int len; + } cipher_key; - /** AES GCM Authenticated Decryption */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_7), + struct { + uint8_t data[64]; + unsigned int len; + } iv; - /** AES GMAC Authentication */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_verify_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_verify_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_verify_test_case_3), + struct { + const uint8_t *data; + unsigned int len; + } plaintext; - /** SNOW 3G encrypt only (UEA2) */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_snow3g_encryption_test_case_1), + struct { + const uint8_t *data; + unsigned int len; + } ciphertext; + + enum rte_crypto_auth_algorithm auth_algo; + + struct { + uint8_t data[128]; + unsigned int len; + } auth_key; + + struct { + const uint8_t *data; + unsigned int len; + } aad; + + struct { + uint8_t data[128]; + unsigned int len; + } digest; +}; + +static const struct test_crypto_vector +hmac_sha1_test_crypto_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .plaintext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0xC4, 0xB7, 0x0E, 0x6B, 0xDE, 0xD1, 0xE7, 0x77, + 0x7E, 0x2E, 0x8F, 0xFC, 0x48, 0x39, 0x46, 0x17, + 0x3F, 0x91, 0x64, 0x59 + }, + .len = 20 + } +}; + +static const struct test_crypto_vector +aes128_gmac_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_AES_GMAC, + .crypto_algo = RTE_CRYPTO_CIPHER_AES_GCM, + .aad = { + .data = plaintext_hash, + .len = 512 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B + }, + .len = 12 + }, + .cipher_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA + }, + .len = 16 + }, + .digest = { + .data = { + 0xCA, 0x00, 0x99, 0x8B, 0x30, 0x7E, 0x74, 0x56, + 0x32, 0xA7, 0x87, 0xB5, 0xE9, 0xB2, 0x34, 0x5A + }, + .len = 16 + } +}; + +static const struct test_crypto_vector +aes128cbc_hmac_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_hash, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60, + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0x18, 0x8C, 0x1D, 0x32 + }, + .len = 20 + } +}; + +static void +data_corruption(uint8_t *data) +{ + data[0] += 1; +} + +static void +tag_corruption(uint8_t *data, unsigned int tag_offset) +{ + data[tag_offset] += 1; +} + +static int +create_auth_session(struct crypto_unittest_params *ut_params, + uint8_t dev_id, + const struct test_crypto_vector *reference, + enum rte_crypto_auth_operation auth_op) +{ + uint8_t auth_key[reference->auth_key.len + 1]; + + memcpy(auth_key, reference->auth_key.data, reference->auth_key.len); + + /* Setup Authentication Parameters */ + ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; + ut_params->auth_xform.auth.op = auth_op; + ut_params->auth_xform.next = NULL; + ut_params->auth_xform.auth.algo = reference->auth_algo; + ut_params->auth_xform.auth.key.length = reference->auth_key.len; + ut_params->auth_xform.auth.key.data = auth_key; + ut_params->auth_xform.auth.digest_length = reference->digest.len; + ut_params->auth_xform.auth.add_auth_data_length = reference->aad.len; + + /* Create Crypto session*/ + ut_params->sess = rte_cryptodev_sym_session_create(dev_id, + &ut_params->auth_xform); + + TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); + + return 0; +} + +static int +create_auth_cipher_session(struct crypto_unittest_params *ut_params, + uint8_t dev_id, + const struct test_crypto_vector *reference, + enum rte_crypto_auth_operation auth_op, + enum rte_crypto_cipher_operation cipher_op) +{ + uint8_t cipher_key[reference->cipher_key.len + 1]; + uint8_t auth_key[reference->auth_key.len + 1]; + + memcpy(cipher_key, reference->cipher_key.data, reference->cipher_key.len); + memcpy(auth_key, reference->auth_key.data, reference->auth_key.len); + + /* Setup Authentication Parameters */ + ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; + ut_params->auth_xform.auth.op = auth_op; + ut_params->auth_xform.next = &ut_params->cipher_xform; + ut_params->auth_xform.auth.algo = reference->auth_algo; + ut_params->auth_xform.auth.key.length = reference->auth_key.len; + ut_params->auth_xform.auth.key.data = auth_key; + ut_params->auth_xform.auth.digest_length = reference->digest.len; + ut_params->auth_xform.auth.add_auth_data_length = reference->aad.len; + + /* Setup Cipher Parameters */ + ut_params->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; + ut_params->cipher_xform.next = NULL; + ut_params->cipher_xform.cipher.algo = reference->crypto_algo; + ut_params->cipher_xform.cipher.op = cipher_op; + ut_params->cipher_xform.cipher.key.data = cipher_key; + ut_params->cipher_xform.cipher.key.length = reference->cipher_key.len; + + /* Create Crypto session*/ + ut_params->sess = rte_cryptodev_sym_session_create(dev_id, + &ut_params->auth_xform); + + TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); + + return 0; +} + +static int +create_auth_operation(struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int auth_generate) +{ + /* Generate Crypto op data structure */ + ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC); + TEST_ASSERT_NOT_NULL(ut_params->op, + "Failed to allocate pktmbuf offload"); + + /* Set crypto operation data parameters */ + rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); + + struct rte_crypto_sym_op *sym_op = ut_params->op->sym; + + /* set crypto operation source mbuf */ + sym_op->m_src = ut_params->ibuf; + + /* digest */ + sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( + ut_params->ibuf, reference->digest.len); + + TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, + "no room to append auth tag"); + + sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( + ut_params->ibuf, reference->plaintext.len); + sym_op->auth.digest.length = reference->digest.len; + + if (auth_generate) + memset(sym_op->auth.digest.data, 0, reference->digest.len); + else + memcpy(sym_op->auth.digest.data, + reference->digest.data, + reference->digest.len); + + TEST_HEXDUMP(stdout, "digest:", + sym_op->auth.digest.data, + sym_op->auth.digest.length); + + sym_op->auth.data.length = reference->plaintext.len; + sym_op->auth.data.offset = 0; + + return 0; +} + +static int +create_auth_GMAC_operation(struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int auth_generate) +{ + /* Generate Crypto op data structure */ + ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC); + TEST_ASSERT_NOT_NULL(ut_params->op, + "Failed to allocate pktmbuf offload"); + + /* Set crypto operation data parameters */ + rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); + + struct rte_crypto_sym_op *sym_op = ut_params->op->sym; + + /* set crypto operation source mbuf */ + sym_op->m_src = ut_params->ibuf; + + /* aad */ + sym_op->auth.aad.data = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + reference->aad.len); + TEST_ASSERT_NOT_NULL(sym_op->auth.aad.data, "no room to append AAD"); + memcpy(sym_op->auth.aad.data, reference->aad.data, reference->aad.len); + + TEST_HEXDUMP(stdout, "AAD:", sym_op->auth.aad.data, reference->aad.len); + + sym_op->auth.aad.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); + sym_op->auth.aad.length = reference->aad.len; + + /* digest */ + sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( + ut_params->ibuf, reference->digest.len); + + TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, + "no room to append auth tag"); + + sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( + ut_params->ibuf, reference->ciphertext.len); + sym_op->auth.digest.length = reference->digest.len; + + if (auth_generate) + memset(sym_op->auth.digest.data, 0, reference->digest.len); + else + memcpy(sym_op->auth.digest.data, + reference->digest.data, + reference->digest.len); + + TEST_HEXDUMP(stdout, "digest:", + sym_op->auth.digest.data, + sym_op->auth.digest.length); + + sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend( + ut_params->ibuf, reference->iv.len); + TEST_ASSERT_NOT_NULL(sym_op->cipher.iv.data, "no room to prepend iv"); + + sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); + sym_op->cipher.iv.length = reference->iv.len; + + memcpy(sym_op->cipher.iv.data, reference->iv.data, reference->iv.len); + + sym_op->cipher.data.length = 0; + sym_op->cipher.data.offset = 0; + + sym_op->auth.data.length = 0; + sym_op->auth.data.offset = 0; + + return 0; +} + +static int +create_cipher_auth_operation(struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int auth_generate) +{ + /* Generate Crypto op data structure */ + ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC); + TEST_ASSERT_NOT_NULL(ut_params->op, + "Failed to allocate pktmbuf offload"); + + /* Set crypto operation data parameters */ + rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); + + struct rte_crypto_sym_op *sym_op = ut_params->op->sym; + + /* set crypto operation source mbuf */ + sym_op->m_src = ut_params->ibuf; + + /* digest */ + sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( + ut_params->ibuf, reference->digest.len); + + TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, + "no room to append auth tag"); + + sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( + ut_params->ibuf, reference->ciphertext.len); + sym_op->auth.digest.length = reference->digest.len; + + if (auth_generate) + memset(sym_op->auth.digest.data, 0, reference->digest.len); + else + memcpy(sym_op->auth.digest.data, + reference->digest.data, + reference->digest.len); + + TEST_HEXDUMP(stdout, "digest:", + sym_op->auth.digest.data, + sym_op->auth.digest.length); + + sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend( + ut_params->ibuf, reference->iv.len); + TEST_ASSERT_NOT_NULL(sym_op->cipher.iv.data, "no room to prepend iv"); + + sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); + sym_op->cipher.iv.length = reference->iv.len; + + memcpy(sym_op->cipher.iv.data, reference->iv.data, reference->iv.len); + + sym_op->cipher.data.length = reference->ciphertext.len; + sym_op->cipher.data.offset = reference->iv.len; + + sym_op->auth.data.length = reference->ciphertext.len; + sym_op->auth.data.offset = reference->iv.len; + + return 0; +} + +static int +create_auth_verify_operation(struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return create_auth_operation(ts_params, ut_params, reference, 0); +} + +static int +create_auth_verify_GMAC_operation( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return create_auth_GMAC_operation(ts_params, ut_params, reference, 0); +} + +static int +create_cipher_auth_verify_operation(struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return create_cipher_auth_operation(ts_params, ut_params, reference, 0); +} + +static int +test_authentication_verify_fail_when_data_corruption( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int data_corrupted) +{ + int retval; + + uint8_t *plaintext; + + /* Create session */ + retval = create_auth_session(ut_params, + ts_params->valid_devs[0], + reference, + RTE_CRYPTO_AUTH_OP_VERIFY); + if (retval < 0) + return retval; + + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + TEST_ASSERT_NOT_NULL(ut_params->ibuf, + "Failed to allocate input buffer in mempool"); + + /* clear mbuf payload */ + memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->ibuf)); + + plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + reference->plaintext.len); + TEST_ASSERT_NOT_NULL(plaintext, "no room to append plaintext"); + memcpy(plaintext, reference->plaintext.data, reference->plaintext.len); + + TEST_HEXDUMP(stdout, "plaintext:", plaintext, reference->plaintext.len); + + /* Create operation */ + retval = create_auth_verify_operation(ts_params, ut_params, reference); + + if (retval < 0) + return retval; + + if (data_corrupted) + data_corruption(plaintext); + else + tag_corruption(plaintext, reference->plaintext.len); + + ut_params->op = process_crypto_request(ts_params->valid_devs[0], + ut_params->op); + TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process"); + TEST_ASSERT_EQUAL(ut_params->op->status, + RTE_CRYPTO_OP_STATUS_AUTH_FAILED, + "authentication not failed"); + + ut_params->obuf = ut_params->op->sym->m_src; + TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf"); + + return 0; +} + +static int +test_authentication_verify_GMAC_fail_when_corruption( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int data_corrupted) +{ + int retval; + + /* Create session */ + retval = create_auth_cipher_session(ut_params, + ts_params->valid_devs[0], + reference, + RTE_CRYPTO_AUTH_OP_VERIFY, + RTE_CRYPTO_CIPHER_OP_DECRYPT); + if (retval < 0) + return retval; + + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + TEST_ASSERT_NOT_NULL(ut_params->ibuf, + "Failed to allocate input buffer in mempool"); + + /* clear mbuf payload */ + memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->ibuf)); + + /* Create operation */ + retval = create_auth_verify_GMAC_operation(ts_params, + ut_params, + reference); + + if (retval < 0) + return retval; + + if (data_corrupted) + data_corruption(ut_params->op->sym->auth.aad.data); + else + tag_corruption(ut_params->op->sym->auth.aad.data, reference->aad.len); + + ut_params->op = process_crypto_request(ts_params->valid_devs[0], + ut_params->op); + TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process"); + TEST_ASSERT_EQUAL(ut_params->op->status, + RTE_CRYPTO_OP_STATUS_AUTH_FAILED, + "authentication not failed"); + + ut_params->obuf = ut_params->op->sym->m_src; + TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf"); + + return 0; +} + +static int +test_authenticated_decryption_fail_when_corruption( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int data_corrupted) +{ + int retval; + + uint8_t *ciphertext; + + /* Create session */ + retval = create_auth_cipher_session(ut_params, + ts_params->valid_devs[0], + reference, + RTE_CRYPTO_AUTH_OP_VERIFY, + RTE_CRYPTO_CIPHER_OP_DECRYPT); + if (retval < 0) + return retval; + + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + TEST_ASSERT_NOT_NULL(ut_params->ibuf, + "Failed to allocate input buffer in mempool"); + + /* clear mbuf payload */ + memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->ibuf)); + + ciphertext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + reference->ciphertext.len); + TEST_ASSERT_NOT_NULL(ciphertext, "no room to append ciphertext"); + memcpy(ciphertext, reference->ciphertext.data, reference->ciphertext.len); + + /* Create operation */ + retval = create_cipher_auth_verify_operation(ts_params, + ut_params, + reference); + + if (retval < 0) + return retval; + + if (data_corrupted) + data_corruption(ciphertext); + else + tag_corruption(ciphertext, reference->ciphertext.len); + + ut_params->op = process_crypto_request(ts_params->valid_devs[0], + ut_params->op); + + TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process"); + TEST_ASSERT_EQUAL(ut_params->op->status, + RTE_CRYPTO_OP_STATUS_AUTH_FAILED, + "authentication not failed"); + + ut_params->obuf = ut_params->op->sym->m_src; + TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf"); + + return 0; +} + +static int +test_authentication_verify_fail_when_data_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authentication_verify_fail_when_data_corruption( + ts_params, ut_params, reference, 1); +} + +static int +test_authentication_verify_fail_when_tag_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authentication_verify_fail_when_data_corruption( + ts_params, ut_params, reference, 0); +} + +static int +test_authentication_verify_GMAC_fail_when_data_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authentication_verify_GMAC_fail_when_corruption( + ts_params, ut_params, reference, 1); +} + +static int +test_authentication_verify_GMAC_fail_when_tag_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authentication_verify_GMAC_fail_when_corruption( + ts_params, ut_params, reference, 0); +} + +static int +test_authenticated_decryption_fail_when_data_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authenticated_decryption_fail_when_corruption( + ts_params, ut_params, reference, 1); +} + +static int +test_authenticated_decryption_fail_when_tag_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authenticated_decryption_fail_when_corruption( + ts_params, ut_params, reference, 0); +} + +static int +authentication_verify_HMAC_SHA1_fail_when_data_corrupted(void) +{ + return test_authentication_verify_fail_when_data_corrupted( + &testsuite_params, &unittest_params, + &hmac_sha1_test_crypto_vector); +} + +static int +authentication_verify_HMAC_SHA1_fail_when_tag_corrupted(void) +{ + return test_authentication_verify_fail_when_tag_corrupted( + &testsuite_params, &unittest_params, + &hmac_sha1_test_crypto_vector); +} + +static int +authentication_verify_AES128_GMAC_fail_when_data_corrupted(void) +{ + return test_authentication_verify_GMAC_fail_when_data_corrupted( + &testsuite_params, &unittest_params, + &aes128_gmac_test_vector); +} + +static int +authentication_verify_AES128_GMAC_fail_when_tag_corrupted(void) +{ + return test_authentication_verify_GMAC_fail_when_tag_corrupted( + &testsuite_params, &unittest_params, + &aes128_gmac_test_vector); +} + +static int +auth_decryption_AES128CBC_HMAC_SHA1_fail_when_data_corrupted(void) +{ + return test_authenticated_decryption_fail_when_data_corrupted( + &testsuite_params, + &unittest_params, + &aes128cbc_hmac_sha1_test_vector); +} + +static int +auth_decryption_AES128CBC_HMAC_SHA1_fail_when_tag_corrupted(void) +{ + return test_authenticated_decryption_fail_when_tag_corrupted( + &testsuite_params, + &unittest_params, + &aes128cbc_hmac_sha1_test_vector); +} + +static struct unit_test_suite cryptodev_qat_testsuite = { + .suite_name = "Crypto QAT Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, + test_device_configure_invalid_dev_id), + TEST_CASE_ST(ut_setup, ut_teardown, + test_device_configure_invalid_queue_pair_ids), + TEST_CASE_ST(ut_setup, ut_teardown, + test_queue_pair_descriptor_setup), + TEST_CASE_ST(ut_setup, ut_teardown, + test_multi_session), + + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_qat_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_3DES_chain_qat_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_3DES_cipheronly_qat_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_stats), + + /** AES GCM Authenticated Encryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_7), + + /** AES GCM Authenticated Decryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_7), + + /** AES GMAC Authentication */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_3), + + /** SNOW 3G encrypt only (UEA2) */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_snow3g_encryption_test_case_1), TEST_CASE_ST(ut_setup, ut_teardown, test_snow3g_encryption_test_case_2), TEST_CASE_ST(ut_setup, ut_teardown, @@ -4862,6 +6143,87 @@ static struct unit_test_suite cryptodev_aesni_mb_testsuite = { } }; +static struct unit_test_suite cryptodev_libcrypto_testsuite = { + .suite_name = "Crypto Device LIBCRYPTO Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, test_multi_session), + TEST_CASE_ST(ut_setup, ut_teardown, test_multi_session_random_usage), + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_libcrypto_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_cipheronly_libcrypto_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_3DES_chain_libcrypto_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_3DES_cipheronly_libcrypto_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_authonly_libcrypto_all), + + /** AES GCM Authenticated Encryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_7), + + /** AES GCM Authenticated Decryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_7), + + /** AES GMAC Authentication */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_4), + + /** Negative tests */ + TEST_CASE_ST(ut_setup, ut_teardown, + authentication_verify_HMAC_SHA1_fail_when_data_corrupted), + TEST_CASE_ST(ut_setup, ut_teardown, + authentication_verify_HMAC_SHA1_fail_when_tag_corrupted), + TEST_CASE_ST(ut_setup, ut_teardown, + authentication_verify_AES128_GMAC_fail_when_data_corrupted), + TEST_CASE_ST(ut_setup, ut_teardown, + authentication_verify_AES128_GMAC_fail_when_tag_corrupted), + TEST_CASE_ST(ut_setup, ut_teardown, + auth_decryption_AES128CBC_HMAC_SHA1_fail_when_data_corrupted), + TEST_CASE_ST(ut_setup, ut_teardown, + auth_decryption_AES128CBC_HMAC_SHA1_fail_when_tag_corrupted), + + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + static struct unit_test_suite cryptodev_aesni_gcm_testsuite = { .suite_name = "Crypto Device AESNI GCM Unit Test Suite", .setup = testsuite_setup, @@ -5105,6 +6467,14 @@ test_cryptodev_aesni_mb(void /*argv __rte_unused, int argc __rte_unused*/) } static int +test_cryptodev_libcrypto(void) +{ + gbl_cryptodev_type = RTE_CRYPTODEV_LIBCRYPTO_PMD; + + return unit_test_suite_runner(&cryptodev_libcrypto_testsuite); +} + +static int test_cryptodev_aesni_gcm(void) { gbl_cryptodev_type = RTE_CRYPTODEV_AESNI_GCM_PMD; @@ -5146,6 +6516,7 @@ test_cryptodev_sw_zuc(void /*argv __rte_unused, int argc __rte_unused*/) REGISTER_TEST_COMMAND(cryptodev_qat_autotest, test_cryptodev_qat); REGISTER_TEST_COMMAND(cryptodev_aesni_mb_autotest, test_cryptodev_aesni_mb); +REGISTER_TEST_COMMAND(cryptodev_libcrypto_autotest, test_cryptodev_libcrypto); REGISTER_TEST_COMMAND(cryptodev_aesni_gcm_autotest, test_cryptodev_aesni_gcm); REGISTER_TEST_COMMAND(cryptodev_null_autotest, test_cryptodev_null); REGISTER_TEST_COMMAND(cryptodev_sw_snow3g_autotest, test_cryptodev_sw_snow3g); diff --git a/app/test/test_cryptodev.h b/app/test/test_cryptodev.h index 3c37c32..a9089aa 100644 --- a/app/test/test_cryptodev.h +++ b/app/test/test_cryptodev.h @@ -63,6 +63,7 @@ #define DIGEST_BYTE_LENGTH_SNOW3G_UIA2 (BYTE_LENGTH(32)) #define DIGEST_BYTE_LENGTH_KASUMI_F9 (BYTE_LENGTH(32)) #define AES_XCBC_MAC_KEY_SZ (16) +#define DIGEST_BYTE_LENGTH_AES_GCM (BYTE_LENGTH(128)) #define TRUNCATED_DIGEST_BYTE_LENGTH_SHA1 (12) #define TRUNCATED_DIGEST_BYTE_LENGTH_SHA224 (16) diff --git a/app/test/test_cryptodev_aes_test_vectors.h b/app/test/test_cryptodev_aes_test_vectors.h index 92c0cc2..ee46f9f 100644 --- a/app/test/test_cryptodev_aes_test_vectors.h +++ b/app/test/test_cryptodev_aes_test_vectors.h @@ -634,12 +634,204 @@ static const struct blockcipher_test_data aes_test_data_9 = { } }; +static const uint8_t ciphertext512_aes192cbc[] = { + 0x45, 0xEE, 0x9A, 0xEA, 0x3C, 0x03, 0xFC, 0x4C, + 0x84, 0x36, 0xB0, 0xDA, 0xB0, 0xDC, 0xF3, 0x5B, + 0x75, 0xA7, 0xBE, 0x0E, 0xC0, 0x8D, 0x6C, 0xF8, + 0xC1, 0x0F, 0xD0, 0x35, 0x1D, 0x82, 0xAE, 0x7C, + 0x57, 0xC5, 0x7A, 0x55, 0x87, 0x1B, 0xD4, 0x03, + 0x0A, 0x64, 0xC9, 0xE0, 0xF4, 0xC7, 0x6F, 0x57, + 0x52, 0xC6, 0x73, 0xBA, 0x84, 0x0B, 0x5B, 0x89, + 0x21, 0xD2, 0x9B, 0x88, 0x68, 0xF5, 0xA9, 0x7F, + 0x3F, 0x49, 0xEB, 0xF4, 0xD4, 0x52, 0xD2, 0x64, + 0x80, 0xB2, 0x53, 0xDA, 0x19, 0xF6, 0x10, 0x24, + 0x23, 0x26, 0x7A, 0x7C, 0x07, 0x57, 0x4B, 0x0E, + 0x58, 0x49, 0x61, 0xD1, 0xDC, 0x9A, 0x32, 0x6B, + 0x0F, 0x43, 0x9E, 0x4D, 0xB4, 0x07, 0x4E, 0xB3, + 0x51, 0x74, 0xDE, 0x29, 0xBC, 0x98, 0xF9, 0xDF, + 0x78, 0x9A, 0x18, 0x9C, 0xD6, 0x7A, 0x55, 0x7C, + 0xE6, 0x1D, 0x5C, 0x1A, 0x99, 0xD2, 0xC3, 0x7B, + 0x9F, 0x96, 0x74, 0x2D, 0xE0, 0xEF, 0xD1, 0xE3, + 0x08, 0x9F, 0xAF, 0xE6, 0xED, 0xCA, 0xE1, 0xEA, + 0x23, 0x6F, 0x7C, 0x81, 0xA8, 0xC0, 0x5B, 0x8B, + 0x53, 0x90, 0x51, 0x2D, 0x0F, 0xF6, 0x7D, 0xA7, + 0x1C, 0xBD, 0x83, 0x84, 0x54, 0xA4, 0x15, 0xFB, + 0x3E, 0x25, 0xA7, 0x3A, 0x0A, 0x73, 0xD9, 0x88, + 0x6F, 0x80, 0x78, 0x95, 0x7F, 0x60, 0xAA, 0x86, + 0x8A, 0xFC, 0xDF, 0xC1, 0xCB, 0xDE, 0xBB, 0x25, + 0x52, 0x20, 0xC6, 0x79, 0xD4, 0x0F, 0x25, 0xE7, + 0xDB, 0xB2, 0x17, 0xA4, 0x6F, 0x3C, 0x6F, 0x91, + 0xF6, 0x44, 0x1E, 0xB6, 0x85, 0xBC, 0x7A, 0x14, + 0x10, 0x72, 0xBD, 0x16, 0x63, 0x39, 0x9E, 0x7B, + 0x84, 0x5B, 0x17, 0x61, 0xB1, 0x5D, 0x82, 0x0B, + 0x6D, 0x37, 0xD7, 0x79, 0xB8, 0x24, 0x91, 0x30, + 0x82, 0x91, 0x02, 0xB1, 0x18, 0x4B, 0xE0, 0xF4, + 0x13, 0x1B, 0xB2, 0x4C, 0xDA, 0xB8, 0x99, 0x96, + 0x83, 0x2F, 0xBE, 0x53, 0x8D, 0xDE, 0xFA, 0xAD, + 0xF6, 0x5C, 0xDB, 0xE5, 0x66, 0x26, 0x8F, 0x13, + 0x2B, 0x76, 0x47, 0x73, 0xDE, 0x1A, 0x74, 0xA6, + 0x30, 0xAF, 0x42, 0xA0, 0xE5, 0xD2, 0x8F, 0xC2, + 0xED, 0x3E, 0x9E, 0x29, 0x54, 0x3C, 0xDE, 0x9F, + 0x5D, 0x30, 0x2B, 0x63, 0xFB, 0xE3, 0xB1, 0x07, + 0xEE, 0x74, 0x4A, 0xAF, 0xB1, 0x20, 0x8D, 0xEC, + 0xE6, 0x78, 0x16, 0x8D, 0xA4, 0x6E, 0x34, 0x7D, + 0x47, 0xFB, 0x0B, 0xC1, 0x32, 0xD7, 0x0D, 0x6C, + 0x6F, 0x93, 0x9C, 0x5E, 0xEF, 0x1F, 0x9C, 0x45, + 0x80, 0x6B, 0x74, 0xA6, 0x81, 0xF2, 0xF6, 0xFA, + 0xAA, 0x9D, 0x4F, 0xCA, 0xB5, 0x90, 0x59, 0xB0, + 0x3B, 0xF2, 0xF0, 0x75, 0xFD, 0x8A, 0xD8, 0x97, + 0x65, 0x88, 0x56, 0x4C, 0x44, 0xDF, 0x73, 0xF7, + 0x56, 0x9C, 0x48, 0x7E, 0xB0, 0x1F, 0x1D, 0x7D, + 0x6A, 0x11, 0xF5, 0xC2, 0xF4, 0x17, 0xEF, 0x58, + 0xD8, 0x2A, 0xAF, 0x56, 0x2F, 0xCF, 0xEC, 0xA4, + 0x58, 0x8B, 0x60, 0xCE, 0xD4, 0x0F, 0x9C, 0x21, + 0xEC, 0x3E, 0x74, 0x7B, 0x81, 0x3D, 0x69, 0xC6, + 0x5E, 0x12, 0x83, 0xE9, 0xEF, 0x81, 0x58, 0x36, + 0x6A, 0x60, 0x0F, 0x54, 0x28, 0x11, 0xF9, 0x64, + 0x36, 0xAD, 0x79, 0xF5, 0x1C, 0x74, 0xD0, 0xC3, + 0x7B, 0x61, 0xE1, 0x92, 0xB0, 0x13, 0x91, 0x87, + 0x32, 0x1F, 0xF2, 0x5A, 0xDA, 0x25, 0x69, 0xEB, + 0xD7, 0x32, 0x7F, 0xF5, 0x23, 0x21, 0x54, 0x47, + 0x7B, 0x1B, 0x33, 0xB0, 0x3D, 0xF6, 0xE2, 0x7E, + 0x3E, 0xA2, 0x9E, 0xCA, 0x48, 0x0B, 0x4A, 0x29, + 0x81, 0xD4, 0x4E, 0xD5, 0x69, 0xFB, 0xCD, 0x37, + 0x8A, 0xC1, 0x5B, 0x50, 0xFF, 0xB5, 0x7D, 0x43, + 0x0F, 0xAE, 0xA6, 0xC2, 0xE5, 0x8F, 0x45, 0xB2, + 0x85, 0x99, 0x02, 0xA2, 0x9B, 0xBE, 0x90, 0x43, + 0x4F, 0x2F, 0x50, 0xE2, 0x77, 0x62, 0xD9, 0xCC +}; + +/** AES-192-CBC test vector */ +static const struct blockcipher_test_data aes_test_data_10 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes192cbc, + .len = 512 + } +}; + +static const uint8_t ciphertext512_aes256cbc[] = { + 0xF3, 0xDD, 0xF0, 0x0B, 0xFF, 0xA2, 0x6A, 0x04, + 0xBE, 0xDA, 0x52, 0xA6, 0xFE, 0x6B, 0xA6, 0xA7, + 0x48, 0x1D, 0x7D, 0x98, 0x65, 0xDB, 0xEF, 0x06, + 0x26, 0xB5, 0x8E, 0xEB, 0x05, 0x0E, 0x77, 0x98, + 0x17, 0x8E, 0xD0, 0xD4, 0x7B, 0x92, 0x8F, 0x5C, + 0xD0, 0x74, 0x5C, 0xA8, 0x4B, 0x54, 0xB6, 0x2F, + 0x83, 0x72, 0x2C, 0xFF, 0x72, 0xE9, 0xE4, 0x15, + 0x4C, 0x32, 0xAF, 0xC8, 0xC9, 0x89, 0x3C, 0x6E, + 0x31, 0xD5, 0xC0, 0x16, 0xC0, 0x31, 0x7D, 0x11, + 0xAB, 0xCB, 0xDE, 0xD2, 0xD6, 0xAA, 0x76, 0x5E, + 0xBA, 0xF6, 0xE2, 0x92, 0xCB, 0x86, 0x07, 0xFA, + 0xD4, 0x9E, 0x83, 0xED, 0xFD, 0xB8, 0x70, 0x54, + 0x6B, 0xBE, 0xEC, 0x72, 0xDD, 0x28, 0x5E, 0x95, + 0x78, 0xA5, 0x28, 0x43, 0x3D, 0x6D, 0xB1, 0xD9, + 0x69, 0x1F, 0xC9, 0x66, 0x0E, 0x32, 0x44, 0x08, + 0xD2, 0xAE, 0x2C, 0x43, 0xF2, 0xD0, 0x7D, 0x26, + 0x70, 0xE5, 0xA1, 0xCA, 0x37, 0xE9, 0x7D, 0xC7, + 0xA3, 0xFA, 0x81, 0x91, 0x64, 0xAA, 0x64, 0x91, + 0x9A, 0x95, 0x2D, 0xC9, 0xF9, 0xCE, 0xFE, 0x9F, + 0xC4, 0xD8, 0x81, 0xBE, 0x57, 0x84, 0xC5, 0x02, + 0xDB, 0x30, 0xC1, 0xD9, 0x0E, 0xA0, 0xA6, 0x00, + 0xD6, 0xF3, 0x52, 0x7E, 0x0D, 0x23, 0x6B, 0x2B, + 0x34, 0x99, 0x1F, 0x70, 0x27, 0x6D, 0x58, 0x84, + 0x93, 0x77, 0xB8, 0x3E, 0xF1, 0x71, 0x58, 0x42, + 0x8B, 0x2B, 0xC8, 0x6D, 0x05, 0x84, 0xFF, 0x4E, + 0x85, 0xEF, 0x4A, 0x9D, 0x91, 0x6A, 0xD5, 0xE1, + 0xAF, 0x01, 0xEB, 0x83, 0x8F, 0x23, 0x7C, 0x7F, + 0x12, 0x91, 0x05, 0xF0, 0x4E, 0xD9, 0x17, 0x62, + 0x75, 0xBB, 0xAC, 0x97, 0xEE, 0x3B, 0x4E, 0xC7, + 0xE5, 0x92, 0xF8, 0x9D, 0x4C, 0xF9, 0xEE, 0x55, + 0x18, 0xBB, 0xCC, 0xB4, 0xF2, 0x59, 0xB9, 0xFC, + 0x7A, 0x0F, 0x98, 0xD4, 0x8B, 0xFE, 0xF7, 0x83, + 0x46, 0xE2, 0x83, 0x33, 0x3E, 0x95, 0x8D, 0x17, + 0x1E, 0x85, 0xF8, 0x8C, 0x51, 0xB0, 0x6C, 0xB5, + 0x5E, 0x95, 0xBA, 0x4B, 0x69, 0x1B, 0x48, 0x69, + 0x0B, 0x8F, 0xA5, 0x18, 0x13, 0xB9, 0x77, 0xD1, + 0x80, 0x32, 0x32, 0x6D, 0x53, 0xA1, 0x95, 0x40, + 0x96, 0x8A, 0xCC, 0xA3, 0x69, 0xF8, 0x9F, 0xB5, + 0x8E, 0xD2, 0x68, 0x07, 0x4F, 0xA7, 0xEC, 0xF8, + 0x20, 0x21, 0x58, 0xF8, 0xD8, 0x9E, 0x5F, 0x40, + 0xBA, 0xB9, 0x76, 0x57, 0x3B, 0x17, 0xAD, 0xEE, + 0xCB, 0xDF, 0x07, 0xC1, 0xDF, 0x66, 0xA8, 0x0D, + 0xC2, 0xCE, 0x8F, 0x79, 0xC3, 0x32, 0xE0, 0x8C, + 0xFE, 0x5A, 0xF3, 0x55, 0x27, 0x73, 0x6F, 0xA1, + 0x54, 0xC6, 0xFC, 0x28, 0x9D, 0xBE, 0x97, 0xB9, + 0x54, 0x97, 0x72, 0x3A, 0x61, 0xAF, 0x6F, 0xDE, + 0xF8, 0x0E, 0xBB, 0x6B, 0x96, 0x84, 0xDD, 0x9B, + 0x62, 0xBA, 0x47, 0xB5, 0xC9, 0x3B, 0x4E, 0x8C, + 0x78, 0x2A, 0xCC, 0x0A, 0x69, 0x54, 0x25, 0x5E, + 0x8B, 0xAC, 0x56, 0xD9, 0xFE, 0x48, 0xBA, 0xCE, + 0xA9, 0xCE, 0xA6, 0x1D, 0xBF, 0x3E, 0x3C, 0x66, + 0x40, 0x71, 0x79, 0xAD, 0x5B, 0x26, 0xAD, 0xBE, + 0x58, 0x13, 0x64, 0x60, 0x7C, 0x05, 0xFC, 0xE3, + 0x51, 0x7A, 0xF2, 0xCC, 0x54, 0x16, 0x2C, 0xA4, + 0xCE, 0x5F, 0x59, 0x12, 0x77, 0xEB, 0xD9, 0x23, + 0xE3, 0x86, 0xFB, 0xD7, 0x48, 0x76, 0x9D, 0xE3, + 0x89, 0x87, 0x39, 0xFA, 0x7B, 0x21, 0x0B, 0x76, + 0xB2, 0xED, 0x1C, 0x27, 0x4B, 0xD5, 0x27, 0x05, + 0x8C, 0x7D, 0x58, 0x6C, 0xCA, 0xA5, 0x54, 0x9A, + 0x0F, 0xCB, 0xE9, 0x88, 0x31, 0xAD, 0x49, 0xEE, + 0x38, 0xFB, 0xC9, 0xFB, 0xB4, 0x7A, 0x00, 0x58, + 0x20, 0x32, 0xD3, 0x53, 0x5A, 0xDD, 0x74, 0x95, + 0x60, 0x59, 0x09, 0xAE, 0x7E, 0xEC, 0x74, 0xA3, + 0xB7, 0x1C, 0x6D, 0xF2, 0xAE, 0x79, 0xA4, 0x7C +}; + +/** AES-256-CBC test vector */ +static const struct blockcipher_test_data aes_test_data_11 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0, + 0x37, 0x07, 0xB8, 0x23, 0xA2, 0xA3, 0xB5, 0x8D + }, + .len = 32 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes256cbc, + .len = 512 + } +}; + static const struct blockcipher_test_case aes_chain_test_cases[] = { { .test_descr = "AES-128-CTR HMAC-SHA1 Encryption Digest", .test_data = &aes_test_data_1, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -648,6 +840,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_1, .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -669,6 +862,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_3, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -677,6 +871,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_3, .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -684,6 +879,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_4, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -692,6 +888,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_4, .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -699,6 +896,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_5, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -707,6 +905,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_5, .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -714,6 +913,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_6, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -722,7 +922,8 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_6, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO }, { .test_descr = "AES-128-CBC HMAC-SHA512 Decryption Digest " @@ -730,6 +931,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_6, .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -752,7 +954,8 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_4, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO }, { .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " @@ -760,13 +963,15 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_4, .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO }, { .test_descr = "AES-128-CBC HMAC-SHA224 Encryption Digest", .test_data = &aes_test_data_8, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -775,6 +980,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_8, .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -782,6 +988,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_9, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -790,8 +997,99 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_9, .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest Sessionless", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = + "AES-128-CBC HMAC-SHA1 Decryption Digest Verify Sessionless", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, +}; + +static const struct blockcipher_test_case aes_cipheronly_test_cases[] = { + { + .test_descr = "AES-128-CBC Encryption", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-128-CBC Decryption", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-192-CBC Encryption", + .test_data = &aes_test_data_10, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-192-CBC Decryption", + .test_data = &aes_test_data_10, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-256-CBC Encryption", + .test_data = &aes_test_data_11, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-256-CBC Decryption", + .test_data = &aes_test_data_11, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-128-CTR Encryption", + .test_data = &aes_test_data_1, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-128-CTR Decryption", + .test_data = &aes_test_data_1, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-192-CTR Encryption", + .test_data = &aes_test_data_2, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-192-CTR Decryption", + .test_data = &aes_test_data_2, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-256-CTR Encryption", + .test_data = &aes_test_data_3, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-256-CTR Decryption", + .test_data = &aes_test_data_3, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, }; #endif /* TEST_CRYPTODEV_AES_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_blockcipher.c b/app/test/test_cryptodev_blockcipher.c index 6661859..6649080 100644 --- a/app/test/test_cryptodev_blockcipher.c +++ b/app/test/test_cryptodev_blockcipher.c @@ -43,6 +43,8 @@ #include "test.h" #include "test_cryptodev_blockcipher.h" #include "test_cryptodev_aes_test_vectors.h" +#include "test_cryptodev_des_test_vectors.h" +#include "test_cryptodev_hash_test_vectors.h" static int test_blockcipher_one_case(const struct blockcipher_test_case *t, @@ -79,6 +81,7 @@ test_blockcipher_one_case(const struct blockcipher_test_case *t, switch (cryptodev_type) { case RTE_CRYPTODEV_QAT_SYM_PMD: + case RTE_CRYPTODEV_LIBCRYPTO_PMD: digest_len = tdata->digest.len; break; case RTE_CRYPTODEV_AESNI_MB_PMD: @@ -465,9 +468,25 @@ test_blockcipher_all_tests(struct rte_mempool *mbuf_pool, tcs = aes_chain_test_cases; break; case BLKCIPHER_AES_CIPHERONLY_TYPE: + n_test_cases = sizeof(aes_cipheronly_test_cases) / + sizeof(aes_cipheronly_test_cases[0]); + tcs = aes_cipheronly_test_cases; + break; case BLKCIPHER_3DES_CHAIN_TYPE: + n_test_cases = sizeof(triple_des_chain_test_cases) / + sizeof(triple_des_chain_test_cases[0]); + tcs = triple_des_chain_test_cases; + break; case BLKCIPHER_3DES_CIPHERONLY_TYPE: + n_test_cases = sizeof(triple_des_cipheronly_test_cases) / + sizeof(triple_des_cipheronly_test_cases[0]); + tcs = triple_des_cipheronly_test_cases; + break; case BLKCIPHER_AUTHONLY_TYPE: + n_test_cases = sizeof(hash_test_cases) / + sizeof(hash_test_cases[0]); + tcs = hash_test_cases; + break; default: break; } @@ -479,6 +498,9 @@ test_blockcipher_all_tests(struct rte_mempool *mbuf_pool, case RTE_CRYPTODEV_QAT_SYM_PMD: target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT; break; + case RTE_CRYPTODEV_LIBCRYPTO_PMD: + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO; + break; default: TEST_ASSERT(0, "Unrecognized cryptodev type"); break; diff --git a/app/test/test_cryptodev_blockcipher.h b/app/test/test_cryptodev_blockcipher.h index 686e6fb..3232a86 100644 --- a/app/test/test_cryptodev_blockcipher.h +++ b/app/test/test_cryptodev_blockcipher.h @@ -48,6 +48,7 @@ #define BLOCKCIPHER_TEST_TARGET_PMD_MB 0x0001 /* Multi-buffer flag */ #define BLOCKCIPHER_TEST_TARGET_PMD_QAT 0x0002 /* QAT flag */ +#define BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO 0x0004 /* SW LIBCRYPTO flag */ #define BLOCKCIPHER_TEST_OP_CIPHER (BLOCKCIPHER_TEST_OP_ENCRYPT | \ BLOCKCIPHER_TEST_OP_DECRYPT) diff --git a/app/test/test_cryptodev_des_test_vectors.h b/app/test/test_cryptodev_des_test_vectors.h new file mode 100644 index 0000000..f3144fe --- /dev/null +++ b/app/test/test_cryptodev_des_test_vectors.h @@ -0,0 +1,952 @@ +/* + * 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 TEST_CRYPTODEV_DES_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_DES_TEST_VECTORS_H_ + +static const uint8_t plaintext_des[] = { + "What a lousy earth! He wondered how many people " + "were destitute that same night even in his own " + "prosperous country, how many homes were " + "shanties, how many husbands were drunk and " + "wives socked, and how many children were " + "bullied, abused, or abandoned. How many " + "families hungered for food they could not " + "afford to buy? How many hearts were broken? How " + "many suicides would take place that same night, " + "how many people would go insane? How many " + "cockroaches and landlords would triumph? How " + "many winners were losers, successes failures, " + "and rich men poor men? How many wise guys were " + "stupid? How many happy endings were unhappy " + "endings? How many honest men were liars, brave " + "men cowards, loyal men traitors, how many " + "sainted men were corrupt, how many people in " + "positions of trust had sold their souls to " + "bodyguards, how many had never had souls? How " + "many straight-and-narrow paths were crooked " + "paths? How many best families were worst " + "families and how many good people were bad " + "people? When you added them all up and then " + "subtracted, you might be left with only the " + "children, and perhaps with Albert Einstein and " + "an old violinist or sculptor somewhere." +}; + +static const uint8_t ciphertext512_des128ctr[] = { + 0x13, 0x39, 0x3B, 0xBC, 0x1D, 0xE3, 0x23, 0x09, + 0x9B, 0x08, 0xD1, 0x09, 0x52, 0x93, 0x78, 0x29, + 0x11, 0x21, 0xBA, 0x01, 0x15, 0xCD, 0xEC, 0xAA, + 0x79, 0x77, 0x58, 0xAE, 0xAE, 0xBC, 0x97, 0x33, + 0x94, 0xA9, 0x2D, 0xC0, 0x0A, 0xA9, 0xA4, 0x4B, + 0x19, 0x07, 0x88, 0x06, 0x7E, 0x81, 0x0F, 0xB5, + 0x60, 0xCF, 0xA7, 0xC3, 0x2A, 0x43, 0xFF, 0x16, + 0x3A, 0x5F, 0x11, 0x2D, 0x11, 0x38, 0x37, 0x94, + 0x2A, 0xC8, 0x3D, 0x20, 0xBB, 0x93, 0x95, 0x54, + 0x12, 0xFF, 0x0C, 0x47, 0x89, 0x7D, 0x73, 0xD1, + 0x2E, 0x3A, 0x80, 0x52, 0xA8, 0x92, 0x93, 0x99, + 0x16, 0xB8, 0x12, 0x1B, 0x8B, 0xA8, 0xC1, 0x81, + 0x95, 0x18, 0x82, 0xD6, 0x5A, 0xA7, 0xFE, 0xCF, + 0xC4, 0xAC, 0x85, 0x91, 0x0C, 0x2F, 0x1D, 0x10, + 0x9A, 0x65, 0x07, 0xB0, 0x2E, 0x5A, 0x2D, 0x48, + 0x26, 0xF8, 0x17, 0x7A, 0x53, 0xD6, 0xB8, 0xDF, + 0xB1, 0x10, 0x48, 0x7E, 0x8F, 0xBE, 0x2E, 0xA1, + 0x0D, 0x9E, 0xA9, 0xF1, 0x3B, 0x3B, 0x33, 0xCD, + 0xDC, 0x52, 0x7E, 0xC0, 0x0E, 0xA0, 0xD8, 0xA7, + 0xC6, 0x34, 0x5A, 0xAA, 0x29, 0x8B, 0xA9, 0xAC, + 0x1F, 0x78, 0xAD, 0xEE, 0x34, 0x59, 0x30, 0xFB, + 0x2A, 0x20, 0x3D, 0x4D, 0x30, 0xA7, 0x7D, 0xD8, + 0xA0, 0xC6, 0xA2, 0xD3, 0x9A, 0xFB, 0x50, 0x97, + 0x4D, 0x25, 0xA2, 0x37, 0x51, 0x54, 0xB7, 0xEB, + 0xED, 0x77, 0xDB, 0x94, 0x35, 0x8B, 0x70, 0x95, + 0x4A, 0x00, 0xA7, 0xF1, 0x8A, 0x66, 0x0E, 0xC6, + 0x05, 0x7B, 0x69, 0x05, 0x42, 0x03, 0x96, 0x2C, + 0x55, 0x00, 0x1B, 0xC0, 0x19, 0x4D, 0x0D, 0x2E, + 0xF5, 0x81, 0x11, 0x64, 0xCA, 0xBB, 0xF2, 0x0F, + 0x9C, 0x60, 0xE2, 0xCC, 0x02, 0x6E, 0x83, 0xD5, + 0x24, 0xF4, 0x12, 0x0E, 0x6A, 0xEA, 0x4F, 0x6C, + 0x79, 0x69, 0x65, 0x67, 0xDB, 0xF7, 0xEA, 0x98, + 0x5D, 0x56, 0x98, 0xB7, 0x88, 0xE7, 0x23, 0xC9, + 0x17, 0x32, 0x92, 0x33, 0x5A, 0x0C, 0x15, 0x20, + 0x3B, 0x1C, 0xF9, 0x0F, 0x4D, 0xD1, 0xE8, 0xE6, + 0x9E, 0x5E, 0x24, 0x1B, 0xA4, 0xB8, 0xB9, 0xE9, + 0x2F, 0xFC, 0x89, 0xB4, 0xB9, 0xF4, 0xA6, 0xAD, + 0x55, 0xF4, 0xDF, 0x58, 0x63, 0x25, 0xE3, 0x41, + 0x70, 0xDF, 0x10, 0xE7, 0x13, 0x87, 0x8D, 0xB3, + 0x62, 0x4F, 0xF5, 0x86, 0x85, 0x8F, 0x59, 0xF0, + 0x21, 0x0E, 0x8F, 0x11, 0xAD, 0xBF, 0xDD, 0x61, + 0x68, 0x3F, 0x54, 0x57, 0x49, 0x38, 0xC8, 0x24, + 0x8E, 0x0A, 0xAC, 0xCA, 0x2C, 0x36, 0x3E, 0x5F, + 0x0A, 0xCE, 0xFD, 0x1A, 0x60, 0x63, 0x5A, 0xE6, + 0x06, 0x64, 0xB5, 0x94, 0x3C, 0xC9, 0xAF, 0x7C, + 0xCD, 0x49, 0x10, 0xCF, 0xAF, 0x0E, 0x2E, 0x79, + 0x27, 0xB2, 0x67, 0x02, 0xED, 0xEE, 0x80, 0x77, + 0x7C, 0x6D, 0x4B, 0xDB, 0xCF, 0x8D, 0x68, 0x00, + 0x2E, 0xD9, 0xF0, 0x8E, 0x08, 0xBF, 0xA6, 0x9B, + 0xFE, 0xA4, 0xFB, 0x19, 0x46, 0xAF, 0x1B, 0xA9, + 0xF8, 0x22, 0x81, 0x21, 0x97, 0xFC, 0xC0, 0x8A, + 0x26, 0x58, 0x13, 0x29, 0xB6, 0x69, 0x94, 0x4B, + 0xAB, 0xB3, 0x88, 0x0D, 0xA9, 0x48, 0x0E, 0xE8, + 0x70, 0xFC, 0xA1, 0x21, 0xC4, 0x2C, 0xE5, 0x99, + 0xB4, 0xF1, 0x6F, 0xB2, 0x4B, 0x4B, 0xCD, 0x48, + 0x15, 0x47, 0x2D, 0x72, 0x39, 0x99, 0x9D, 0x24, + 0x0C, 0x8B, 0xDC, 0xA1, 0xEE, 0xF6, 0xF4, 0x73, + 0xC3, 0xB8, 0x0C, 0x23, 0x0D, 0xA7, 0xC4, 0x7D, + 0x27, 0xE2, 0x14, 0x11, 0x53, 0x19, 0xE7, 0xCA, + 0x94, 0x4E, 0x0D, 0x2C, 0xF7, 0x36, 0x47, 0xDB, + 0x77, 0x3C, 0x22, 0xAC, 0xBE, 0xE1, 0x06, 0x55, + 0xE5, 0xDD, 0x8B, 0x65, 0xE8, 0xE9, 0x91, 0x52, + 0x59, 0x97, 0xFC, 0x8C, 0xEE, 0x96, 0x22, 0x60, + 0xEE, 0xBF, 0x82, 0xF0, 0xCA, 0x14, 0xF9, 0xD3 +}; + +static const struct blockcipher_test_data +triple_des128ctr_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128ctr, + .len = 512 + } +}; + +static const struct blockcipher_test_data +triple_des128ctr_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128ctr, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .digest = { + .data = { + 0xC3, 0x40, 0xD5, 0xD9, 0x8F, 0x8A, 0xC0, 0xF0, + 0x46, 0x28, 0x02, 0x01, 0xB5, 0xC1, 0x87, 0x4D, + 0xAC, 0xFE, 0x48, 0x76 + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +triple_des128ctr_hmac_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128ctr, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0xF1, 0xC1, 0xDB, 0x4D, 0xFA, 0x7F, 0x2F, 0xE5, + 0xF8, 0x49, 0xEA, 0x1D, 0x7F, 0xCB, 0x42, 0x59, + 0xC4, 0x1E, 0xB1, 0x18 + }, + .len = 20 + } +}; + +static const uint8_t ciphertext512_des192ctr[] = { + 0xFF, 0x32, 0x52, 0x97, 0x10, 0xBF, 0x0B, 0x10, + 0x68, 0x0F, 0x4F, 0x56, 0x8B, 0x2C, 0x7B, 0x8E, + 0x39, 0x1E, 0x1A, 0x2F, 0x83, 0xDE, 0x5E, 0x35, + 0xC8, 0x4B, 0xDF, 0xD5, 0xBC, 0x84, 0x50, 0x1A, + 0x02, 0xDF, 0xB3, 0x11, 0xE4, 0xDA, 0xB8, 0x0E, + 0x47, 0xC6, 0x0C, 0x51, 0x09, 0x62, 0x9C, 0x5D, + 0x71, 0x40, 0x49, 0xD8, 0x55, 0xBD, 0x7D, 0x90, + 0x71, 0xC5, 0xF7, 0x07, 0x6F, 0x08, 0x71, 0x2A, + 0xB1, 0x77, 0x9B, 0x0F, 0xA1, 0xB0, 0xD6, 0x10, + 0xB2, 0xE5, 0x31, 0xEC, 0x21, 0x13, 0x89, 0x2A, + 0x09, 0x7E, 0x30, 0xDB, 0xA0, 0xF0, 0xDC, 0xE4, + 0x74, 0x64, 0x39, 0xA3, 0xB0, 0xB1, 0x80, 0x66, + 0x52, 0xD4, 0x4E, 0xC9, 0x5A, 0x52, 0x6A, 0xC7, + 0xB5, 0x2B, 0x61, 0xD5, 0x17, 0xD5, 0xF3, 0xCC, + 0x41, 0x61, 0xD2, 0xA6, 0xF4, 0x51, 0x24, 0x3A, + 0x63, 0x5D, 0x23, 0xB1, 0xF0, 0x22, 0xE7, 0x45, + 0xFA, 0x5F, 0x7E, 0x99, 0x00, 0x11, 0x28, 0x35, + 0xA3, 0xF4, 0x61, 0x94, 0x0E, 0x98, 0xCE, 0x35, + 0xDD, 0x91, 0x1B, 0x0B, 0x4D, 0xEE, 0xFF, 0xFF, + 0x0B, 0xD4, 0xDC, 0x56, 0xFC, 0x71, 0xE9, 0xEC, + 0xE8, 0x36, 0x51, 0xF8, 0x8B, 0x6A, 0xE1, 0x8C, + 0x2B, 0x25, 0x91, 0x91, 0x9B, 0x92, 0x76, 0xB5, + 0x3D, 0x26, 0xA8, 0x53, 0xEA, 0x30, 0x5B, 0x4D, + 0xDA, 0x16, 0xDA, 0x7D, 0x04, 0x88, 0xF5, 0x22, + 0xA8, 0x0C, 0xB9, 0x41, 0xC7, 0x91, 0x64, 0x86, + 0x99, 0x7D, 0x18, 0xB9, 0x67, 0xA2, 0x6E, 0x05, + 0x1A, 0x82, 0x8F, 0xA2, 0xEB, 0x4D, 0x0B, 0x8C, + 0x88, 0x2D, 0xBA, 0x77, 0x87, 0x32, 0x50, 0x3C, + 0x4C, 0xD8, 0xD3, 0x50, 0x39, 0xFA, 0xDF, 0x48, + 0x3E, 0x30, 0xF5, 0x76, 0x06, 0xB0, 0x1A, 0x05, + 0x60, 0x2C, 0xD3, 0xA0, 0x63, 0x1A, 0x19, 0x2D, + 0x6B, 0x76, 0xF2, 0x31, 0x4C, 0xA7, 0xE6, 0x5C, + 0x1B, 0x23, 0x20, 0x41, 0x32, 0xE5, 0x83, 0x47, + 0x04, 0xB6, 0x3E, 0xE0, 0xFD, 0x49, 0x1E, 0x1B, + 0x75, 0x10, 0x11, 0x46, 0xE9, 0xF9, 0x96, 0x9A, + 0xD7, 0x59, 0xFE, 0x38, 0x31, 0xFE, 0x79, 0xC4, + 0xC8, 0x46, 0x88, 0xDE, 0x2E, 0xAE, 0x20, 0xED, + 0x77, 0x50, 0x40, 0x38, 0x26, 0xD3, 0x35, 0xF6, + 0x29, 0x55, 0x6A, 0x6B, 0x38, 0x69, 0xFE, 0x90, + 0x5B, 0xA7, 0xFA, 0x6B, 0x73, 0x4F, 0xB9, 0x5D, + 0xDC, 0x6F, 0x98, 0xC3, 0x6A, 0xC4, 0xB5, 0x09, + 0xC5, 0x84, 0xA5, 0x6A, 0x84, 0xA4, 0xB3, 0x8A, + 0x5F, 0xCA, 0x92, 0x64, 0x9E, 0xC3, 0x0F, 0x84, + 0x8B, 0x2D, 0x48, 0xC6, 0x67, 0xAE, 0x07, 0xE0, + 0x28, 0x38, 0x6D, 0xC4, 0x4D, 0x13, 0x87, 0xE0, + 0xB2, 0x2F, 0xAA, 0xC0, 0xCF, 0x68, 0xD7, 0x9C, + 0xB8, 0x07, 0xE4, 0x51, 0xD7, 0x75, 0x86, 0xFA, + 0x0C, 0x50, 0x74, 0x68, 0x00, 0x64, 0x2A, 0x27, + 0x59, 0xE9, 0x80, 0xEB, 0xC2, 0xA3, 0xFA, 0x58, + 0xCC, 0x03, 0xE7, 0x7B, 0x66, 0x53, 0xFF, 0x90, + 0xA0, 0x85, 0xE2, 0xF8, 0x82, 0xFE, 0xC6, 0x2B, + 0xFF, 0x5E, 0x70, 0x85, 0x34, 0xB7, 0x22, 0x38, + 0xDB, 0xBC, 0x15, 0x30, 0x59, 0xC1, 0x48, 0x42, + 0xE5, 0x38, 0x8D, 0x37, 0x59, 0xDB, 0xA3, 0x20, + 0x17, 0x36, 0x1D, 0x4B, 0xBF, 0x4E, 0xA4, 0x35, + 0xCC, 0xFE, 0xF5, 0x7A, 0x73, 0xB4, 0x6D, 0x20, + 0x1D, 0xC0, 0xE5, 0x21, 0x5C, 0xD2, 0x8A, 0x65, + 0x08, 0xB6, 0x63, 0xAC, 0x9A, 0x1E, 0x3F, 0x3C, + 0xAB, 0xB6, 0x6D, 0x34, 0xB2, 0x3A, 0x08, 0xDA, + 0x29, 0x63, 0xD1, 0xA4, 0x83, 0x52, 0xB0, 0x63, + 0x1B, 0x89, 0x35, 0x57, 0x59, 0x2C, 0x0F, 0x72, + 0x72, 0xFD, 0xA0, 0xAC, 0xDB, 0xB4, 0xA3, 0xA1, + 0x18, 0x10, 0x12, 0x97, 0x99, 0x63, 0x38, 0x98, + 0x96, 0xB5, 0x16, 0x07, 0x4E, 0xE9, 0x2C, 0x97 +}; + +static const struct blockcipher_test_data +triple_des192ctr_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192ctr, + .len = 512 + } +}; + +static const struct blockcipher_test_data +triple_des192ctr_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192ctr, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .digest = { + .data = { + 0xEA, 0x62, 0xB9, 0xB2, 0x78, 0x6C, 0x8E, 0xDB, + 0xA3, 0xB6, 0xFF, 0x23, 0x3A, 0x47, 0xD8, 0xC8, + 0xED, 0x5E, 0x20, 0x1D + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +triple_des192ctr_hmac_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192ctr, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x32, 0xD5, 0x19, 0x8F, 0x79, 0x3A, 0xAA, 0x7B, + 0x70, 0x67, 0x4E, 0x63, 0x88, 0xA3, 0x9A, 0x82, + 0x07, 0x33, 0x12, 0x94 + }, + .len = 20 + } +}; + +static const uint8_t ciphertext512_des128cbc[] = { + 0x28, 0x2a, 0xff, 0x15, 0x5c, 0xdf, 0xd9, 0x6b, + 0x54, 0xbc, 0x7b, 0xfb, 0xc5, 0x64, 0x4d, 0xdd, + 0x3e, 0xf2, 0x9e, 0xb7, 0x53, 0x65, 0x37, 0x05, + 0xe0, 0xdf, 0xae, 0xf7, 0xc9, 0x27, 0xe4, 0xec, + 0x11, 0x27, 0xc2, 0x9e, 0x02, 0x4e, 0x03, 0x3b, + 0x33, 0xf2, 0x66, 0x08, 0x24, 0x5f, 0xab, 0xc2, + 0x7e, 0x21, 0x19, 0x5d, 0x51, 0xc3, 0xe2, 0x97, + 0x6f, 0x2e, 0xb4, 0xaa, 0x34, 0x70, 0x88, 0x78, + 0x4e, 0xe7, 0x3d, 0xe1, 0x9f, 0x87, 0x1c, 0x8b, + 0xac, 0x8d, 0xa1, 0x1a, 0xcd, 0xb0, 0xf8, 0xb6, + 0x24, 0x36, 0xe3, 0x8c, 0x07, 0xe7, 0xe4, 0x92, + 0x13, 0x86, 0x6f, 0x13, 0xec, 0x04, 0x5c, 0xe9, + 0xb9, 0xca, 0x45, 0x8a, 0x2c, 0x46, 0xda, 0x54, + 0x1d, 0xb5, 0x81, 0xb1, 0xcd, 0xf3, 0x7d, 0x11, + 0x6b, 0xb3, 0x0a, 0x45, 0xe5, 0x6e, 0x51, 0x3e, + 0x2c, 0xac, 0x7c, 0xbc, 0xa7, 0x7e, 0x22, 0x4d, + 0xe6, 0x02, 0xe3, 0x3f, 0x77, 0xd7, 0x73, 0x72, + 0x0e, 0xfb, 0x42, 0x85, 0x80, 0xdf, 0xa8, 0x91, + 0x60, 0x40, 0x48, 0xcd, 0x1b, 0xd9, 0xbf, 0x2f, + 0xf2, 0xdf, 0xd0, 0xbd, 0x3f, 0x82, 0xce, 0x15, + 0x9d, 0x6e, 0xc6, 0x59, 0x6f, 0x27, 0x0d, 0xf9, + 0x26, 0xe2, 0x11, 0x29, 0x50, 0xc3, 0x0a, 0xb7, + 0xde, 0x9d, 0xe9, 0x55, 0xa1, 0xe9, 0x01, 0x33, + 0x56, 0x51, 0xa7, 0x3a, 0x9e, 0x63, 0xc5, 0x08, + 0x01, 0x3b, 0x03, 0x4b, 0xc6, 0xc4, 0xa1, 0xc0, + 0xc0, 0xd0, 0x0e, 0x48, 0xe5, 0x4c, 0x55, 0x6b, + 0x4a, 0xc1, 0x0a, 0x24, 0x4b, 0xd0, 0x02, 0xf4, + 0x31, 0x63, 0x11, 0xbd, 0xa6, 0x1f, 0xf4, 0xae, + 0x23, 0x5a, 0x40, 0x7e, 0x0e, 0x4e, 0x63, 0x8b, + 0x66, 0x3d, 0x55, 0x46, 0x6e, 0x5c, 0x76, 0xa7, + 0x68, 0x31, 0xce, 0x5d, 0xca, 0xe2, 0xb4, 0xb0, + 0xc1, 0x1f, 0x66, 0x18, 0x75, 0x64, 0x73, 0xa9, + 0x9e, 0xd5, 0x0e, 0x0e, 0xf7, 0x77, 0x61, 0xf8, + 0x89, 0xc6, 0xcf, 0x0c, 0x41, 0xd3, 0x8f, 0xfd, + 0x22, 0x52, 0x4f, 0x94, 0x5c, 0x19, 0x11, 0x3a, + 0xb5, 0x63, 0xe8, 0x81, 0x33, 0x13, 0x54, 0x3c, + 0x93, 0x36, 0xb5, 0x5b, 0x51, 0xaf, 0x51, 0xa2, + 0x08, 0xae, 0x83, 0x15, 0x77, 0x07, 0x28, 0x0d, + 0x98, 0xe1, 0x2f, 0x69, 0x0e, 0xfb, 0x9a, 0x2e, + 0x27, 0x27, 0xb0, 0xd5, 0xce, 0xf8, 0x16, 0x55, + 0xfd, 0xaa, 0xd7, 0x1a, 0x1b, 0x2e, 0x4c, 0x86, + 0x7a, 0x6a, 0x90, 0xf7, 0x0a, 0x07, 0xd3, 0x81, + 0x4b, 0x75, 0x6a, 0x79, 0xdb, 0x63, 0x45, 0x0f, + 0x31, 0x7e, 0xd0, 0x2a, 0x14, 0xff, 0xee, 0xcc, + 0x97, 0x8a, 0x7d, 0x74, 0xbd, 0x9d, 0xaf, 0x00, + 0xdb, 0x7e, 0xf3, 0xe6, 0x22, 0x76, 0x77, 0x58, + 0xba, 0x1c, 0x06, 0x96, 0xfb, 0x6f, 0x41, 0x71, + 0x66, 0x98, 0xae, 0x31, 0x7d, 0x29, 0x18, 0x71, + 0x0e, 0xe4, 0x98, 0x7e, 0x59, 0x5a, 0xc9, 0x78, + 0x9c, 0xfb, 0x6c, 0x81, 0x44, 0xb4, 0x0f, 0x5e, + 0x18, 0x53, 0xb8, 0x6f, 0xbc, 0x3b, 0x15, 0xf0, + 0x10, 0xdd, 0x0d, 0x4b, 0x0a, 0x36, 0x0e, 0xb4, + 0x76, 0x0f, 0x16, 0xa7, 0x5c, 0x9d, 0xcf, 0xb0, + 0x6d, 0x38, 0x02, 0x07, 0x05, 0xe9, 0xe9, 0x46, + 0x08, 0xb8, 0x52, 0xd6, 0xd9, 0x4c, 0x81, 0x63, + 0x1d, 0xe2, 0x5b, 0xd0, 0xf6, 0x5e, 0x1e, 0x81, + 0x48, 0x08, 0x66, 0x3a, 0x85, 0xed, 0x65, 0xfe, + 0xe8, 0x05, 0x7a, 0xe1, 0xe6, 0x12, 0xf2, 0x52, + 0x83, 0xdd, 0x82, 0xbe, 0xf6, 0x34, 0x8a, 0x6f, + 0xc5, 0x83, 0xcd, 0x3f, 0xbe, 0x58, 0x8b, 0x11, + 0x78, 0xdc, 0x0c, 0x83, 0x72, 0x5d, 0x05, 0x2a, + 0x01, 0x29, 0xee, 0x48, 0x9a, 0x67, 0x00, 0x6e, + 0x14, 0x60, 0x2d, 0x00, 0x52, 0x87, 0x98, 0x5e, + 0x43, 0xfe, 0xf1, 0x10, 0x14, 0xf1, 0x91, 0xcc +}; + +static const struct blockcipher_test_data +triple_des128cbc_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128cbc, + .len = 512 + } +}; + +static const struct blockcipher_test_data +triple_des128cbc_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .digest = { + .data = { + 0x94, 0x45, 0x7B, 0xDF, 0xFE, 0x80, 0xB9, 0xA6, + 0xA0, 0x7A, 0xE8, 0x93, 0x40, 0x7B, 0x85, 0x02, + 0x1C, 0xD7, 0xE8, 0x87 + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +triple_des128cbc_hmac_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x7E, 0xBA, 0xFF, 0x86, 0x8D, 0x65, 0xCD, 0x08, + 0x76, 0x34, 0x94, 0xE9, 0x9A, 0xCD, 0xB2, 0xBB, + 0xBF, 0x65, 0xF5, 0x42 + }, + .len = 20 + } +}; + +static const uint8_t ciphertext512_des192cbc[] = { + 0xd0, 0xc9, 0xdc, 0x51, 0x29, 0x97, 0x03, 0x64, + 0xcd, 0x22, 0xba, 0x3d, 0x2b, 0xbc, 0x21, 0x37, + 0x7b, 0x1e, 0x29, 0x23, 0xeb, 0x51, 0x6e, 0xac, + 0xbe, 0x5b, 0xd3, 0x67, 0xe0, 0x3f, 0xc3, 0xb5, + 0xe3, 0x04, 0x17, 0x42, 0x2b, 0xaa, 0xdd, 0xd6, + 0x0e, 0x69, 0xd0, 0x8f, 0x8a, 0xfc, 0xb4, 0x55, + 0x67, 0x06, 0x51, 0xbb, 0x00, 0x57, 0xee, 0x95, + 0x28, 0x79, 0x3f, 0xd9, 0x97, 0x2b, 0xb0, 0x02, + 0x35, 0x08, 0xce, 0x7a, 0xc3, 0x43, 0x2c, 0x87, + 0xaa, 0x97, 0x6a, 0xad, 0xf0, 0x26, 0xea, 0x1d, + 0xbb, 0x08, 0xe9, 0x52, 0x11, 0xd3, 0xaf, 0x36, + 0x17, 0x14, 0x21, 0xb2, 0xbc, 0x42, 0x51, 0x33, + 0x27, 0x8c, 0xd8, 0x45, 0xb9, 0x76, 0xa0, 0x11, + 0x24, 0x34, 0xde, 0x4d, 0x13, 0x67, 0x1b, 0xc3, + 0x31, 0x12, 0x66, 0x56, 0x59, 0xd2, 0xb1, 0x8f, + 0xec, 0x1e, 0xc0, 0x10, 0x7a, 0x86, 0xb1, 0x60, + 0xc3, 0x01, 0xd6, 0xa8, 0x55, 0xad, 0x58, 0x63, + 0xca, 0x68, 0xa9, 0x33, 0xe3, 0x93, 0x90, 0x7d, + 0x8f, 0xca, 0xf8, 0x1c, 0xc2, 0x9e, 0xfb, 0xde, + 0x9c, 0xc7, 0xf2, 0x6c, 0xff, 0xcc, 0x39, 0x17, + 0x49, 0x33, 0x0d, 0x7c, 0xed, 0x07, 0x99, 0x91, + 0x91, 0x6c, 0x5f, 0x3f, 0x02, 0x09, 0xdc, 0x70, + 0xf9, 0x3b, 0x8d, 0xaa, 0xf4, 0xbc, 0x0e, 0xec, + 0xf2, 0x26, 0xfb, 0xb2, 0x1c, 0x31, 0xae, 0xc6, + 0x72, 0xe8, 0x0b, 0x75, 0x05, 0x57, 0x58, 0x98, + 0x92, 0x37, 0x27, 0x8e, 0x3b, 0x0c, 0x25, 0xfb, + 0xcf, 0x82, 0x02, 0xd5, 0x0b, 0x1f, 0x89, 0x49, + 0xcd, 0x0f, 0xa1, 0xa7, 0x08, 0x63, 0x56, 0xa7, + 0x1f, 0x80, 0x3a, 0xef, 0x24, 0x89, 0x57, 0x1a, + 0x02, 0xdc, 0x2e, 0x51, 0xbd, 0x4a, 0x10, 0x23, + 0xfc, 0x02, 0x1a, 0x3f, 0x34, 0xbf, 0x1c, 0x98, + 0x1a, 0x40, 0x0a, 0x96, 0x8e, 0x41, 0xd5, 0x09, + 0x55, 0x37, 0xe9, 0x25, 0x11, 0x83, 0xf8, 0xf3, + 0xd4, 0xb0, 0xdb, 0x16, 0xd7, 0x51, 0x7e, 0x94, + 0xf7, 0xb4, 0x26, 0xe0, 0xf4, 0x80, 0x01, 0x65, + 0x51, 0xeb, 0xbc, 0xb0, 0x65, 0x8f, 0xdd, 0xb5, + 0xf7, 0x00, 0xec, 0x40, 0xab, 0x7d, 0x96, 0xcc, + 0x8d, 0xec, 0x89, 0x80, 0x31, 0x39, 0xa2, 0x5c, + 0xb0, 0x55, 0x4c, 0xee, 0xdd, 0x15, 0x2b, 0xa9, + 0x86, 0x4e, 0x23, 0x14, 0x36, 0xc5, 0x57, 0xf5, + 0xe3, 0xe8, 0x89, 0xc9, 0xb7, 0xf8, 0xeb, 0x08, + 0xe5, 0x93, 0x12, 0x5c, 0x0f, 0x79, 0xa1, 0x86, + 0xe4, 0xc2, 0xeb, 0xa6, 0xa0, 0x50, 0x6a, 0xec, + 0xd3, 0xce, 0x50, 0x78, 0x4e, 0x4f, 0x93, 0xd8, + 0xdc, 0xb4, 0xec, 0x02, 0xe9, 0xbd, 0x17, 0x99, + 0x1e, 0x16, 0x4e, 0xd7, 0xb0, 0x07, 0x02, 0x55, + 0x63, 0x24, 0x4f, 0x7b, 0x8f, 0xc5, 0x7a, 0x12, + 0x29, 0xff, 0x5d, 0xc1, 0xe7, 0xae, 0x48, 0xc8, + 0x57, 0x53, 0xe7, 0xcd, 0x10, 0x6c, 0x19, 0xfc, + 0xcc, 0xb9, 0xb1, 0xbe, 0x48, 0x9f, 0x2d, 0x3f, + 0x39, 0x2e, 0xdd, 0x71, 0xde, 0x1b, 0x54, 0xee, + 0x7d, 0x94, 0x8f, 0x27, 0x23, 0xe9, 0x74, 0x92, + 0x14, 0x93, 0x84, 0x65, 0xc9, 0x22, 0x7c, 0xa8, + 0x1b, 0x72, 0x73, 0xb1, 0x23, 0xa0, 0x6b, 0xcc, + 0xb5, 0x22, 0x06, 0x15, 0xe5, 0x96, 0x03, 0x4a, + 0x52, 0x8d, 0x1d, 0xbf, 0x3e, 0x82, 0x45, 0x9c, + 0x75, 0x9e, 0xa9, 0x3a, 0x97, 0xb6, 0x5d, 0xc4, + 0x75, 0x67, 0xa1, 0xf3, 0x0f, 0x7a, 0xfd, 0x71, + 0x58, 0x04, 0xf9, 0xa7, 0xc2, 0x56, 0x74, 0x04, + 0x74, 0x68, 0x6d, 0x8a, 0xf6, 0x6c, 0x5d, 0xd8, + 0xb5, 0xed, 0x70, 0x23, 0x32, 0x4d, 0x75, 0x92, + 0x88, 0x7b, 0x39, 0x37, 0x02, 0x4b, 0xb2, 0x1c, + 0x1f, 0x7e, 0x5b, 0x1b, 0x10, 0xfc, 0x17, 0x21, + 0x66, 0x62, 0x63, 0xc2, 0xcd, 0x16, 0x96, 0x3e +}; + +static const struct blockcipher_test_data +triple_des192cbc_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192cbc, + .len = 512 + } +}; + +static const struct blockcipher_test_data +triple_des192cbc_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .digest = { + .data = { + 0x53, 0x27, 0xC0, 0xE6, 0xD6, 0x1B, 0xD6, 0x45, + 0x94, 0x2D, 0xCE, 0x8B, 0x29, 0xA3, 0x52, 0x14, + 0xC1, 0x6B, 0x87, 0x99 + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +triple_des192cbc_hmac_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0xBA, 0xAC, 0x74, 0x19, 0x43, 0xB0, 0x72, 0xB8, + 0x08, 0xF5, 0x24, 0xC4, 0x09, 0xBD, 0x48, 0xC1, + 0x3C, 0x50, 0x1C, 0xDD + }, + .len = 20 + } +}; + +static const struct blockcipher_test_case triple_des_chain_test_cases[] = { + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Encryption Digest", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Decryption Digest Verify", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC SHA1 Encryption Digest", + .test_data = &triple_des128cbc_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-128-CBC SHA1 Decryption Digest Verify", + .test_data = &triple_des128cbc_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-192-CBC HMAC-SHA1 Encryption Digest", + .test_data = &triple_des192cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CBC HMAC-SHA1 Decryption Digest Verify", + .test_data = &triple_des192cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CBC SHA1 Encryption Digest", + .test_data = &triple_des192cbc_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-192-CBC SHA1 Decryption Digest Verify", + .test_data = &triple_des192cbc_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-128-CTR HMAC-SHA1 Encryption Digest", + .test_data = &triple_des128ctr_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CTR HMAC-SHA1 Decryption Digest Verify", + .test_data = &triple_des128ctr_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CTR SHA1 Encryption Digest", + .test_data = &triple_des128ctr_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-128-CTR SHA1 Decryption Digest Verify", + .test_data = &triple_des128ctr_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-192-CTR HMAC-SHA1 Encryption Digest", + .test_data = &triple_des192ctr_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CTR HMAC-SHA1 Decryption Digest Verify", + .test_data = &triple_des192ctr_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CTR SHA1 Encryption Digest", + .test_data = &triple_des192ctr_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-192-CTR SHA1 Decryption Digest Verify", + .test_data = &triple_des192ctr_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Encryption Digest OOP", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Decryption Digest Verify OOP", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Encryption Digest Sessionless", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = + "3DES-128-CBC HMAC-SHA1 Decryption Digest Verify Sessionless", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, +}; + +static const struct blockcipher_test_case triple_des_cipheronly_test_cases[] = { + { + .test_descr = "3DES-128-CBC Encryption", + .test_data = &triple_des128cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC Decryption", + .test_data = &triple_des128cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CBC Encryption", + .test_data = &triple_des192cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CBC Decryption", + .test_data = &triple_des192cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CTR Encryption", + .test_data = &triple_des128ctr_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CTR Decryption", + .test_data = &triple_des128ctr_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CTR Encryption", + .test_data = &triple_des192ctr_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CTR Decryption", + .test_data = &triple_des192ctr_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + } +}; + +#endif /* TEST_CRYPTODEV_DES_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_gcm_test_vectors.h b/app/test/test_cryptodev_gcm_test_vectors.h index deca09d..b404242 100644 --- a/app/test/test_cryptodev_gcm_test_vectors.h +++ b/app/test/test_cryptodev_gcm_test_vectors.h @@ -33,6 +33,8 @@ #ifndef TEST_CRYPTODEV_GCM_TEST_VECTORS_H_ #define TEST_CRYPTODEV_GCM_TEST_VECTORS_H_ +#define GMAC_LARGE_PLAINTEXT_LENGTH 65376 + struct gcm_test_data { struct { uint8_t data[64]; @@ -449,7 +451,7 @@ static const struct gcm_test_data gcm_test_case_7 = { }; /** GMAC Test Vectors */ -static uint8_t gmac_plaintext[] = { +static uint8_t gmac_plaintext[GMAC_LARGE_PLAINTEXT_LENGTH] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, @@ -1201,4 +1203,36 @@ static const struct cryptodev_perf_test_data AES_GCM_128_12IV_0AAD = { }, }; +static const struct gmac_test_data gmac_test_case_4 = { + .key = { + .data = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 + }, + .len = 16 + }, + .iv = { + .data = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 + }, + .len = 12 + }, + .aad = { + .data = gmac_plaintext, + .len = GMAC_LARGE_PLAINTEXT_LENGTH + }, + .plaintext = { + .data = NULL, + .len = 0 + }, + .gmac_tag = { + .data = { + 0x88, 0x82, 0xb4, 0x93, 0x8f, 0x04, 0xcd, 0x06, + 0xfd, 0xac, 0x6d, 0x8b, 0x9c, 0x9e, 0x8f, 0xec + }, + .len = 16 + } +}; + #endif /* TEST_CRYPTODEV_GCM_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_hash_test_vectors.h b/app/test/test_cryptodev_hash_test_vectors.h new file mode 100644 index 0000000..dfc84db --- /dev/null +++ b/app/test/test_cryptodev_hash_test_vectors.h @@ -0,0 +1,491 @@ +/* + * 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 TEST_CRYPTODEV_HASH_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_HASH_TEST_VECTORS_H_ + +static const uint8_t plaintext_hash[] = { + "What a lousy earth! He wondered how many people " + "were destitute that same night even in his own " + "prosperous country, how many homes were " + "shanties, how many husbands were drunk and " + "wives socked, and how many children were " + "bullied, abused, or abandoned. How many " + "families hungered for food they could not " + "afford to buy? How many hearts were broken? How " + "many suicides would take place that same night, " + "how many people would go insane? How many " + "cockroaches and landlords would triumph? How " + "many winners were losers, successes failures, " + "and rich men poor men? How many wise guys were " + "stupid? How many happy endings were unhappy " + "endings? How many honest men were liars, brave " + "men cowards, loyal men traitors, how many " + "sainted men were corrupt, how many people in " + "positions of trust had sold their souls to " + "bodyguards, how many had never had souls? How " + "many straight-and-narrow paths were crooked " + "paths? How many best families were worst " + "families and how many good people were bad " + "people? When you added them all up and then " + "subtracted, you might be left with only the " + "children, and perhaps with Albert Einstein and " + "an old violinist or sculptor somewhere." +}; + +static const struct blockcipher_test_data +md5_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_MD5, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0xB3, 0xE6, 0xBB, 0x50, 0x41, 0x35, 0x3C, 0x6B, + 0x7A, 0xFF, 0xD2, 0x64, 0xAF, 0xD5, 0x1C, 0xB2 + }, + .len = 16 + } +}; + +static const struct blockcipher_test_data +hmac_md5_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_MD5_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD + }, + .len = 16 + }, + .digest = { + .data = { + 0x50, 0xE8, 0xDE, 0xC5, 0xC1, 0x76, 0xAC, 0xAE, + 0x15, 0x4A, 0xF1, 0x7F, 0x7E, 0x04, 0x42, 0x9B + }, + .len = 16 + } +}; + +static const struct blockcipher_test_data +sha1_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0xA2, 0x8D, 0x40, 0x78, 0xDD, 0x9F, 0xBB, 0xD5, + 0x35, 0x62, 0xFB, 0xFA, 0x93, 0xFD, 0x7D, 0x70, + 0xA6, 0x7D, 0x45, 0xCA + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +hmac_sha1_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0xC4, 0xB7, 0x0E, 0x6B, 0xDE, 0xD1, 0xE7, 0x77, + 0x7E, 0x2E, 0x8F, 0xFC, 0x48, 0x39, 0x46, 0x17, + 0x3F, 0x91, 0x64, 0x59 + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +sha224_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA224, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0x91, 0xE7, 0xCD, 0x75, 0x14, 0x9C, 0xA9, 0xE9, + 0x2E, 0x46, 0x12, 0x20, 0x22, 0xF9, 0x68, 0x28, + 0x39, 0x26, 0xDF, 0xB5, 0x78, 0x62, 0xB2, 0x6E, + 0x5E, 0x8F, 0x25, 0x84 + }, + .len = 28 + } +}; + +static const struct blockcipher_test_data +hmac_sha224_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA224_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92, + 0xFB, 0xBF, 0xB0, 0x8C + }, + .len = 28 + }, + .digest = { + .data = { + 0x70, 0x0F, 0x04, 0x4D, 0x22, 0x02, 0x7D, 0x31, + 0x36, 0xDA, 0x77, 0x19, 0xB9, 0x66, 0x37, 0x7B, + 0xF1, 0x8A, 0x63, 0xBB, 0x5D, 0x1D, 0xE3, 0x9F, + 0x92, 0xF6, 0xAA, 0x19 + }, + .len = 28 + } +}; + +static const struct blockcipher_test_data +sha256_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA256, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0x7F, 0xF1, 0x0C, 0xF5, 0x90, 0x97, 0x19, 0x0F, + 0x00, 0xE4, 0x83, 0x01, 0xCA, 0x59, 0x00, 0x2E, + 0x1F, 0xC7, 0x84, 0xEE, 0x76, 0xA6, 0x39, 0x15, + 0x76, 0x2F, 0x87, 0xF9, 0x01, 0x06, 0xF3, 0xB7 + }, + .len = 32 + } +}; + +static const struct blockcipher_test_data +hmac_sha256_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92, + 0xFB, 0xBF, 0xB0, 0x8C, 0x29, 0x87, 0x90, 0xAC + }, + .len = 32 + }, + .digest = { + .data = { + 0xAF, 0x8F, 0x70, 0x1B, 0x4B, 0xAF, 0x34, 0xCB, + 0x02, 0x24, 0x48, 0x45, 0x83, 0x52, 0x8F, 0x22, + 0x06, 0x4D, 0x64, 0x09, 0x0A, 0xCC, 0x02, 0x77, + 0x71, 0x83, 0x48, 0x71, 0x07, 0x02, 0x25, 0x17 + }, + .len = 32 + } +}; + +static const struct blockcipher_test_data +sha384_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA384, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0x1D, 0xE7, 0x3F, 0x55, 0x86, 0xFE, 0x48, 0x9F, + 0xAC, 0xC6, 0x85, 0x32, 0xFA, 0x8E, 0xA6, 0x77, + 0x25, 0x84, 0xA5, 0x98, 0x8D, 0x0B, 0x80, 0xF4, + 0xEB, 0x2C, 0xFB, 0x6C, 0xEA, 0x7B, 0xFD, 0xD5, + 0xAD, 0x41, 0xAB, 0x15, 0xB0, 0x03, 0x15, 0xEC, + 0x9E, 0x3D, 0xED, 0xCB, 0x80, 0x7B, 0xF4, 0xB6 + }, + .len = 48 + } +}; + +static const struct blockcipher_test_data +hmac_sha384_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA384_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92, + 0xFB, 0xBF, 0xB0, 0x8C, 0x29, 0x87, 0x90, 0xAC, + 0x39, 0x8B, 0x5C, 0x49, 0x68, 0x1E, 0x3A, 0x05, + 0xCC, 0x68, 0x5C, 0x76, 0xCB, 0x3C, 0x71, 0x89 + }, + .len = 48 + }, + .digest = { + .data = { + 0xE2, 0x83, 0x18, 0x55, 0xB5, 0x8D, 0x94, 0x9B, + 0x01, 0xB6, 0xE2, 0x57, 0x7A, 0x62, 0xF5, 0xF4, + 0xAB, 0x39, 0xF3, 0x3C, 0x28, 0xA0, 0x0F, 0xCC, + 0xEE, 0x1C, 0xF1, 0xF8, 0x69, 0xF1, 0x24, 0x3B, + 0x10, 0x90, 0x0A, 0xE3, 0xF0, 0x59, 0xDD, 0xC0, + 0x6F, 0xE6, 0x8C, 0x84, 0xD5, 0x03, 0xF8, 0x9E + }, + .len = 48 + } +}; + +static const struct blockcipher_test_data +sha512_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA512, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0xB9, 0xBA, 0x28, 0x48, 0x3C, 0xC2, 0xD3, 0x65, + 0x4A, 0xD6, 0x00, 0x1D, 0xCE, 0x61, 0x64, 0x54, + 0x45, 0x8C, 0x64, 0x0E, 0xED, 0x0E, 0xD8, 0x1C, + 0x72, 0xCE, 0xD2, 0x44, 0x91, 0xC8, 0xEB, 0xC7, + 0x99, 0xC5, 0xCA, 0x89, 0x72, 0x64, 0x96, 0x41, + 0xC8, 0xEA, 0xB2, 0x4E, 0xD1, 0x21, 0x13, 0x49, + 0x64, 0x4E, 0x15, 0x68, 0x12, 0x67, 0x26, 0x0F, + 0x2C, 0x3C, 0x83, 0x25, 0x27, 0x86, 0xF0, 0xDB + }, + .len = 64 + } +}; + +static const struct blockcipher_test_data +hmac_sha512_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA512_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92, + 0xFB, 0xBF, 0xB0, 0x8C, 0x29, 0x87, 0x90, 0xAC, + 0x39, 0x8B, 0x5C, 0x49, 0x68, 0x1E, 0x3A, 0x05, + 0xCC, 0x68, 0x5C, 0x76, 0xCB, 0x3C, 0x71, 0x89, + 0xDE, 0xAA, 0x36, 0x44, 0x98, 0x93, 0x97, 0x1E, + 0x6D, 0x53, 0x83, 0x87, 0xB3, 0xB7, 0x56, 0x41 + }, + .len = 64 + }, + .digest = { + .data = { + 0xB8, 0x0B, 0x35, 0x97, 0x3F, 0x24, 0x3F, 0x05, + 0x2A, 0x7F, 0x2F, 0xD8, 0xD7, 0x56, 0x58, 0xAD, + 0x6F, 0x8D, 0x1F, 0x4C, 0x30, 0xF9, 0xA8, 0x29, + 0x7A, 0xE0, 0x8D, 0x88, 0xF5, 0x2E, 0x94, 0xF5, + 0x06, 0xF7, 0x5D, 0x57, 0x32, 0xA8, 0x49, 0x29, + 0xEA, 0x6B, 0x6D, 0x95, 0xBD, 0x76, 0xF5, 0x79, + 0x97, 0x37, 0x0F, 0xBE, 0xC2, 0x45, 0xA0, 0x87, + 0xAF, 0x24, 0x27, 0x0C, 0x78, 0xBA, 0xBE, 0x20 + }, + .len = 64 + } +}; + +static const struct blockcipher_test_case hash_test_cases[] = { + { + .test_descr = "MD5 Digest", + .test_data = &md5_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "MD5 Digest Verify", + .test_data = &md5_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-MD5 Digest", + .test_data = &hmac_md5_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-MD5 Digest Verify", + .test_data = &hmac_md5_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA1 Digest", + .test_data = &sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA1 Digest Verify", + .test_data = &sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA1 Digest", + .test_data = &hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA1 Digest Verify", + .test_data = &hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA224 Digest", + .test_data = &sha224_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA224 Digest Verify", + .test_data = &sha224_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA224 Digest", + .test_data = &hmac_sha224_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA224 Digest Verify", + .test_data = &hmac_sha224_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA256 Digest", + .test_data = &sha256_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA256 Digest Verify", + .test_data = &sha256_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA256 Digest", + .test_data = &hmac_sha256_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA256 Digest Verify", + .test_data = &hmac_sha256_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA384 Digest", + .test_data = &sha384_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA384 Digest Verify", + .test_data = &sha384_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA384 Digest", + .test_data = &hmac_sha384_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA384 Digest Verify", + .test_data = &hmac_sha384_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA512 Digest", + .test_data = &sha512_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA512 Digest Verify", + .test_data = &sha512_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA512 Digest", + .test_data = &hmac_sha512_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA512 Digest Verify", + .test_data = &hmac_sha512_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, +}; + +#endif /* TEST_CRYPTODEV_HASH_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_perf.c b/app/test/test_cryptodev_perf.c index 6af0896..6d6b4a1 100644 --- a/app/test/test_cryptodev_perf.c +++ b/app/test/test_cryptodev_perf.c @@ -151,12 +151,28 @@ static struct rte_cryptodev_sym_session * test_perf_create_snow3g_session(uint8_t dev_id, enum chain_mode chain, enum rte_crypto_cipher_algorithm cipher_algo, unsigned cipher_key_len, enum rte_crypto_auth_algorithm auth_algo); +static struct rte_cryptodev_sym_session * +test_perf_create_libcrypto_session(uint8_t dev_id, enum chain_mode chain, + enum rte_crypto_cipher_algorithm cipher_algo, + unsigned int cipher_key_len, enum rte_crypto_auth_algorithm auth_algo); static struct rte_mbuf * test_perf_create_pktmbuf(struct rte_mempool *mpool, unsigned buf_sz); static inline struct rte_crypto_op * test_perf_set_crypto_op_snow3g(struct rte_crypto_op *op, struct rte_mbuf *m, struct rte_cryptodev_sym_session *sess, unsigned data_len, unsigned digest_len); +static inline struct rte_crypto_op * +test_perf_set_crypto_op_aes(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len); +static inline struct rte_crypto_op * +test_perf_set_crypto_op_aes_gcm(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len); +static inline struct rte_crypto_op * +test_perf_set_crypto_op_3des(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len); static uint32_t get_auth_digest_length(enum rte_crypto_auth_algorithm algo); @@ -357,6 +373,26 @@ testsuite_setup(void) } } + /* Create 2 LIBCRYPTO devices if required */ + if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_LIBCRYPTO_PMD) { +#ifndef RTE_LIBRTE_PMD_LIBCRYPTO + RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO must be" + " enabled in config file to run this testsuite.\n"); + return TEST_FAILED; +#endif + nb_devs = rte_cryptodev_count_devtype(RTE_CRYPTODEV_LIBCRYPTO_PMD); + if (nb_devs < 2) { + for (i = nb_devs; i < 2; i++) { + ret = rte_eal_vdev_init( + RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), NULL); + + TEST_ASSERT(ret == 0, + "Failed to create instance %u of pmd : %s", + i, RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD)); + } + } + } + #ifndef RTE_LIBRTE_PMD_QAT if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_QAT_SYM_PMD) { RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_QAT must be enabled " @@ -367,7 +403,7 @@ testsuite_setup(void) nb_devs = rte_cryptodev_count(); if (nb_devs < 1) { - RTE_LOG(ERR, USER1, "No crypto devices found?"); + RTE_LOG(ERR, USER1, "No crypto devices found?\n"); return TEST_FAILED; } @@ -2242,6 +2278,151 @@ test_perf_snow3G_vary_burst_size(void) return 0; } +static int +test_perf_libcrypto_optimise_cyclecount(struct perf_test_params *pparams) +{ + uint32_t num_to_submit = pparams->total_operations; + struct rte_crypto_op *c_ops[num_to_submit]; + struct rte_crypto_op *proc_ops[num_to_submit]; + uint64_t failed_polls, retries, start_cycles, end_cycles, total_cycles = 0; + uint32_t burst_sent = 0, burst_received = 0; + uint32_t i, burst_size, num_sent, num_ops_received; + + struct crypto_testsuite_params *ts_params = &testsuite_params; + + static struct rte_cryptodev_sym_session *sess; + + static struct rte_crypto_op *(*test_perf_set_crypto_op) + (struct rte_crypto_op *, struct rte_mbuf *, + struct rte_cryptodev_sym_session *, unsigned int, + unsigned int); + + unsigned int digest_length = get_auth_digest_length(pparams->auth_algo); + + if (rte_cryptodev_count() == 0) { + printf("\nNo crypto devices found. Is PMD build configured?\n"); + return TEST_FAILED; + } + + /* Create Crypto session*/ + sess = test_perf_create_libcrypto_session(ts_params->dev_id, + pparams->chain, pparams->cipher_algo, + pparams->cipher_key_length, pparams->auth_algo); + TEST_ASSERT_NOT_NULL(sess, "Session creation failed"); + + /* Generate Crypto op data structure(s)*/ + for (i = 0; i < num_to_submit ; i++) { + struct rte_mbuf *m = test_perf_create_pktmbuf( + ts_params->mbuf_mp, + pparams->buf_size); + TEST_ASSERT_NOT_NULL(m, "Failed to allocate tx_buf"); + + struct rte_crypto_op *op = + rte_crypto_op_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC); + TEST_ASSERT_NOT_NULL(op, "Failed to allocate op"); + + switch (pparams->cipher_algo) { + case RTE_CRYPTO_CIPHER_3DES_CBC: + case RTE_CRYPTO_CIPHER_3DES_CTR: + test_perf_set_crypto_op = test_perf_set_crypto_op_3des; + break; + case RTE_CRYPTO_CIPHER_AES_CBC: + case RTE_CRYPTO_CIPHER_AES_CTR: + test_perf_set_crypto_op = test_perf_set_crypto_op_aes; + break; + case RTE_CRYPTO_CIPHER_AES_GCM: + test_perf_set_crypto_op = test_perf_set_crypto_op_aes_gcm; + break; + default: + return TEST_FAILED; + } + + op = test_perf_set_crypto_op(op, m, sess, pparams->buf_size, + digest_length); + TEST_ASSERT_NOT_NULL(op, "Failed to attach op to session"); + + c_ops[i] = op; + } + + printf("\nOn %s dev%u qp%u, %s, cipher algo:%s, cipher key length:%u, " + "auth_algo:%s, Packet Size %u bytes", + pmd_name(gbl_cryptodev_perftest_devtype), + ts_params->dev_id, 0, + chain_mode_name(pparams->chain), + cipher_algo_name(pparams->cipher_algo), + pparams->cipher_key_length, + auth_algo_name(pparams->auth_algo), + pparams->buf_size); + printf("\nOps Tx\tOps Rx\tOps/burst "); + printf("Retries EmptyPolls\tIACycles/CyOp\tIACycles/Burst\tIACycles/Byte"); + + for (i = 2; i <= 128 ; i *= 2) { + num_sent = 0; + num_ops_received = 0; + retries = 0; + failed_polls = 0; + burst_size = i; + total_cycles = 0; + while (num_sent < num_to_submit) { + start_cycles = rte_rdtsc_precise(); + burst_sent = rte_cryptodev_enqueue_burst(ts_params->dev_id, + 0, &c_ops[num_sent], + ((num_to_submit - num_sent) < burst_size) ? + num_to_submit - num_sent : burst_size); + end_cycles = rte_rdtsc_precise(); + if (burst_sent == 0) + retries++; + num_sent += burst_sent; + total_cycles += (end_cycles - start_cycles); + + /* Wait until requests have been sent. */ + rte_delay_ms(1); + + start_cycles = rte_rdtsc_precise(); + burst_received = rte_cryptodev_dequeue_burst( + ts_params->dev_id, 0, proc_ops, burst_size); + end_cycles = rte_rdtsc_precise(); + if (burst_received < burst_sent) + failed_polls++; + num_ops_received += burst_received; + + total_cycles += end_cycles - start_cycles; + } + + while (num_ops_received != num_to_submit) { + /* Sending 0 length burst to flush sw crypto device */ + rte_cryptodev_enqueue_burst(ts_params->dev_id, 0, NULL, 0); + + start_cycles = rte_rdtsc_precise(); + burst_received = rte_cryptodev_dequeue_burst( + ts_params->dev_id, 0, proc_ops, burst_size); + end_cycles = rte_rdtsc_precise(); + + total_cycles += end_cycles - start_cycles; + if (burst_received == 0) + failed_polls++; + num_ops_received += burst_received; + } + + printf("\n%u\t%u\t%u", num_sent, num_ops_received, burst_size); + printf("\t\t%"PRIu64, retries); + printf("\t%"PRIu64, failed_polls); + printf("\t\t%"PRIu64, total_cycles/num_ops_received); + printf("\t\t%"PRIu64, (total_cycles/num_ops_received)*burst_size); + printf("\t\t%"PRIu64, + total_cycles/(num_ops_received*pparams->buf_size)); + } + printf("\n"); + + for (i = 0; i < num_to_submit ; i++) { + rte_pktmbuf_free(c_ops[i]->sym->m_src); + rte_crypto_op_free(c_ops[i]); + } + + return TEST_SUCCESS; +} + static uint32_t get_auth_key_max_length(enum rte_crypto_auth_algorithm algo) { switch (algo) { @@ -2257,6 +2438,8 @@ static uint32_t get_auth_key_max_length(enum rte_crypto_auth_algorithm algo) return 128; case RTE_CRYPTO_AUTH_SHA512_HMAC: return 128; + case RTE_CRYPTO_AUTH_AES_GCM: + return 0; default: return 0; } @@ -2277,23 +2460,35 @@ static uint32_t get_auth_digest_length(enum rte_crypto_auth_algorithm algo) return TRUNCATED_DIGEST_BYTE_LENGTH_SHA384; case RTE_CRYPTO_AUTH_SHA512_HMAC: return TRUNCATED_DIGEST_BYTE_LENGTH_SHA512; + case RTE_CRYPTO_AUTH_AES_GCM: + return DIGEST_BYTE_LENGTH_AES_GCM; default: return 0; } } -static uint8_t aes_cbc_key[] = { +static uint8_t aes_key[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static uint8_t aes_cbc_iv[] = { +static uint8_t aes_iv[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static uint8_t triple_des_key[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static uint8_t triple_des_iv[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + static uint8_t hmac_sha_key[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -2343,7 +2538,7 @@ test_perf_create_aes_sha_session(uint8_t dev_id, enum chain_mode chain, cipher_xform.cipher.algo = cipher_algo; cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; - cipher_xform.cipher.key.data = aes_cbc_key; + cipher_xform.cipher.key.data = aes_key; cipher_xform.cipher.key.length = cipher_key_len; /* Setup HMAC Parameters */ @@ -2421,8 +2616,77 @@ test_perf_create_snow3g_session(uint8_t dev_id, enum chain_mode chain, } } -#define AES_CBC_BLOCK_SIZE 16 -#define AES_CBC_CIPHER_IV_LENGTH 16 +static struct rte_cryptodev_sym_session * +test_perf_create_libcrypto_session(uint8_t dev_id, enum chain_mode chain, + enum rte_crypto_cipher_algorithm cipher_algo, + unsigned int cipher_key_len, + enum rte_crypto_auth_algorithm auth_algo) +{ + struct rte_crypto_sym_xform cipher_xform = { 0 }; + struct rte_crypto_sym_xform auth_xform = { 0 }; + + /* Setup Cipher Parameters */ + cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; + cipher_xform.cipher.algo = cipher_algo; + cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; + + switch (cipher_algo) { + case RTE_CRYPTO_CIPHER_3DES_CBC: + case RTE_CRYPTO_CIPHER_3DES_CTR: + cipher_xform.cipher.key.data = triple_des_key; + break; + case RTE_CRYPTO_CIPHER_AES_CBC: + case RTE_CRYPTO_CIPHER_AES_CTR: + case RTE_CRYPTO_CIPHER_AES_GCM: + cipher_xform.cipher.key.data = aes_key; + break; + default: + return NULL; + } + + cipher_xform.cipher.key.length = cipher_key_len; + + /* Setup Auth Parameters */ + auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; + auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; + auth_xform.auth.algo = auth_algo; + + switch (auth_algo) { + case RTE_CRYPTO_AUTH_SHA1_HMAC: + auth_xform.auth.key.data = hmac_sha_key; + break; + case RTE_CRYPTO_AUTH_AES_GCM: + auth_xform.auth.key.data = NULL; + break; + default: + return NULL; + } + + auth_xform.auth.key.length = get_auth_key_max_length(auth_algo); + auth_xform.auth.digest_length = get_auth_digest_length(auth_algo); + + switch (chain) { + case CIPHER_HASH: + cipher_xform.next = &auth_xform; + auth_xform.next = NULL; + /* Create Crypto session*/ + return rte_cryptodev_sym_session_create(dev_id, &cipher_xform); + case HASH_CIPHER: + auth_xform.next = &cipher_xform; + cipher_xform.next = NULL; + /* Create Crypto session*/ + return rte_cryptodev_sym_session_create(dev_id, &auth_xform); + default: + return NULL; + } +} + +#define AES_BLOCK_SIZE 16 +#define AES_CIPHER_IV_LENGTH 16 + +#define TRIPLE_DES_BLOCK_SIZE 8 +#define TRIPLE_DES_CIPHER_IV_LENGTH 8 + #define SNOW3G_CIPHER_IV_LENGTH 16 static struct rte_mbuf * @@ -2441,7 +2705,7 @@ test_perf_create_pktmbuf(struct rte_mempool *mpool, unsigned buf_sz) } static inline struct rte_crypto_op * -test_perf_set_crypto_op(struct rte_crypto_op *op, struct rte_mbuf *m, +test_perf_set_crypto_op_aes(struct rte_crypto_op *op, struct rte_mbuf *m, struct rte_cryptodev_sym_session *sess, unsigned data_len, unsigned digest_len) { @@ -2455,19 +2719,53 @@ test_perf_set_crypto_op(struct rte_crypto_op *op, struct rte_mbuf *m, (m->data_off + data_len); op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, data_len); op->sym->auth.digest.length = digest_len; - op->sym->auth.aad.data = aes_cbc_iv; - op->sym->auth.aad.length = AES_CBC_CIPHER_IV_LENGTH; + op->sym->auth.aad.data = aes_iv; + op->sym->auth.aad.length = AES_CIPHER_IV_LENGTH; /* Cipher Parameters */ - op->sym->cipher.iv.data = aes_cbc_iv; - op->sym->cipher.iv.length = AES_CBC_CIPHER_IV_LENGTH; + op->sym->cipher.iv.data = aes_iv; + op->sym->cipher.iv.length = AES_CIPHER_IV_LENGTH; /* Data lengths/offsets Parameters */ op->sym->auth.data.offset = 0; op->sym->auth.data.length = data_len; - op->sym->cipher.data.offset = AES_CBC_BLOCK_SIZE; - op->sym->cipher.data.length = data_len - AES_CBC_BLOCK_SIZE; + op->sym->cipher.data.offset = AES_BLOCK_SIZE; + op->sym->cipher.data.length = data_len - AES_BLOCK_SIZE; + + op->sym->m_src = m; + + return op; +} + +static inline struct rte_crypto_op * +test_perf_set_crypto_op_aes_gcm(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len) +{ + if (rte_crypto_op_attach_sym_session(op, sess) != 0) { + rte_crypto_op_free(op); + return NULL; + } + + /* Authentication Parameters */ + op->sym->auth.digest.data = (uint8_t *)m->buf_addr + + (m->data_off + data_len); + op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, data_len); + op->sym->auth.digest.length = digest_len; + op->sym->auth.aad.data = aes_iv; + op->sym->auth.aad.length = AES_CIPHER_IV_LENGTH; + + /* Cipher Parameters */ + op->sym->cipher.iv.data = aes_iv; + op->sym->cipher.iv.length = AES_CIPHER_IV_LENGTH; + + /* Data lengths/offsets Parameters */ + op->sym->auth.data.offset = AES_BLOCK_SIZE; + op->sym->auth.data.length = data_len - AES_BLOCK_SIZE; + + op->sym->cipher.data.offset = AES_BLOCK_SIZE; + op->sym->cipher.data.length = data_len - AES_BLOCK_SIZE; op->sym->m_src = m; @@ -2508,7 +2806,39 @@ test_perf_set_crypto_op_snow3g(struct rte_crypto_op *op, struct rte_mbuf *m, return op; } +static inline struct rte_crypto_op * +test_perf_set_crypto_op_3des(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len) +{ + if (rte_crypto_op_attach_sym_session(op, sess) != 0) { + rte_crypto_op_free(op); + return NULL; + } + + /* Authentication Parameters */ + op->sym->auth.digest.data = (uint8_t *)m->buf_addr + + (m->data_off + data_len); + op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, data_len); + op->sym->auth.digest.length = digest_len; + op->sym->auth.aad.data = triple_des_iv; + op->sym->auth.aad.length = TRIPLE_DES_CIPHER_IV_LENGTH; + + /* Cipher Parameters */ + op->sym->cipher.iv.data = triple_des_iv; + op->sym->cipher.iv.length = TRIPLE_DES_CIPHER_IV_LENGTH; + + /* Data lengths/offsets Parameters */ + op->sym->auth.data.offset = 0; + op->sym->auth.data.length = data_len; + op->sym->cipher.data.offset = TRIPLE_DES_BLOCK_SIZE; + op->sym->cipher.data.length = data_len - TRIPLE_DES_BLOCK_SIZE; + + op->sym->m_src = m; + + return op; +} /* An mbuf set is used in each burst. An mbuf can be used by multiple bursts at * same time, i.e. as they're not dereferenced there's no need to wait until @@ -2579,7 +2909,7 @@ test_perf_aes_sha(uint8_t dev_id, uint16_t queue_id, "and free ops below."); } else { for (i = 0; i < ops_needed; i++) - ops[i] = test_perf_set_crypto_op(ops[i], + ops[i] = test_perf_set_crypto_op_aes(ops[i], mbufs[i + (pparams->burst_size * (j % NUM_MBUF_SETS))], sess, pparams->buf_size, digest_length); @@ -2790,6 +3120,154 @@ test_perf_snow3g(uint8_t dev_id, uint16_t queue_id, return TEST_SUCCESS; } +static int +test_perf_libcrypto(uint8_t dev_id, uint16_t queue_id, + struct perf_test_params *pparams) +{ + uint16_t i, k, l, m; + uint16_t j = 0; + uint16_t ops_unused = 0; + + uint64_t burst_enqueued = 0, total_enqueued = 0, burst_dequeued = 0; + uint64_t processed = 0, failed_polls = 0, retries = 0; + uint64_t tsc_start = 0, tsc_end = 0; + + unsigned int digest_length = get_auth_digest_length(pparams->auth_algo); + + struct rte_crypto_op *ops[pparams->burst_size]; + struct rte_crypto_op *proc_ops[pparams->burst_size]; + + struct rte_mbuf *mbufs[pparams->burst_size * NUM_MBUF_SETS]; + + struct crypto_testsuite_params *ts_params = &testsuite_params; + + static struct rte_cryptodev_sym_session *sess; + + static struct rte_crypto_op *(*test_perf_set_crypto_op) + (struct rte_crypto_op *, struct rte_mbuf *, + struct rte_cryptodev_sym_session *, unsigned int, + unsigned int); + + switch (pparams->cipher_algo) { + case RTE_CRYPTO_CIPHER_3DES_CBC: + case RTE_CRYPTO_CIPHER_3DES_CTR: + test_perf_set_crypto_op = test_perf_set_crypto_op_3des; + break; + case RTE_CRYPTO_CIPHER_AES_CBC: + case RTE_CRYPTO_CIPHER_AES_CTR: + test_perf_set_crypto_op = test_perf_set_crypto_op_aes; + break; + case RTE_CRYPTO_CIPHER_AES_GCM: + test_perf_set_crypto_op = test_perf_set_crypto_op_aes_gcm; + break; + default: + return TEST_FAILED; + } + + if (rte_cryptodev_count() == 0) { + printf("\nNo crypto devices found. Is PMD build configured?\n"); + return TEST_FAILED; + } + + /* Create Crypto session*/ + sess = test_perf_create_libcrypto_session(ts_params->dev_id, + pparams->chain, pparams->cipher_algo, + pparams->cipher_key_length, pparams->auth_algo); + TEST_ASSERT_NOT_NULL(sess, "Session creation failed"); + + /* Generate a burst of crypto operations */ + for (i = 0; i < (pparams->burst_size * NUM_MBUF_SETS); i++) { + mbufs[i] = test_perf_create_pktmbuf( + ts_params->mbuf_mp, + pparams->buf_size); + + if (mbufs[i] == NULL) { + printf("\nFailed to get mbuf - freeing the rest.\n"); + for (k = 0; k < i; k++) + rte_pktmbuf_free(mbufs[k]); + return -1; + } + } + + tsc_start = rte_rdtsc_precise(); + + while (total_enqueued < pparams->total_operations) { + uint16_t burst_size = + total_enqueued + pparams->burst_size <= pparams->total_operations ? + pparams->burst_size : pparams->total_operations - total_enqueued; + uint16_t ops_needed = burst_size - ops_unused; + + if (ops_needed != rte_crypto_op_bulk_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC, ops, ops_needed)){ + printf("\nFailed to alloc enough ops, finish dequeuing " + "and free ops below."); + } else { + for (i = 0; i < ops_needed; i++) + ops[i] = test_perf_set_crypto_op(ops[i], + mbufs[i + (pparams->burst_size * + (j % NUM_MBUF_SETS))], + sess, pparams->buf_size, digest_length); + + /* enqueue burst */ + burst_enqueued = rte_cryptodev_enqueue_burst(dev_id, + queue_id, ops, burst_size); + + if (burst_enqueued < burst_size) + retries++; + + ops_unused = burst_size - burst_enqueued; + total_enqueued += burst_enqueued; + } + + /* dequeue burst */ + burst_dequeued = rte_cryptodev_dequeue_burst(dev_id, queue_id, + proc_ops, pparams->burst_size); + if (burst_dequeued == 0) + failed_polls++; + else { + processed += burst_dequeued; + + for (l = 0; l < burst_dequeued; l++) + rte_crypto_op_free(proc_ops[l]); + } + j++; + } + + /* Dequeue any operations still in the crypto device */ + while (processed < pparams->total_operations) { + /* Sending 0 length burst to flush sw crypto device */ + rte_cryptodev_enqueue_burst(dev_id, queue_id, NULL, 0); + + /* dequeue burst */ + burst_dequeued = rte_cryptodev_dequeue_burst(dev_id, queue_id, + proc_ops, pparams->burst_size); + if (burst_dequeued == 0) + failed_polls++; + else { + processed += burst_dequeued; + + for (m = 0; m < burst_dequeued; m++) + rte_crypto_op_free(proc_ops[m]); + } + } + + tsc_end = rte_rdtsc_precise(); + + double ops_s = ((double)processed / (tsc_end - tsc_start)) + * rte_get_tsc_hz(); + double throughput = (ops_s * pparams->buf_size * NUM_MBUF_SETS) + / 1000000000; + + printf("\t%u\t%6.2f\t%10.2f\t%8"PRIu64"\t%8"PRIu64, pparams->buf_size, + ops_s / 1000000, throughput, retries, failed_polls); + + for (i = 0; i < pparams->burst_size * NUM_MBUF_SETS; i++) + rte_pktmbuf_free(mbufs[i]); + + printf("\n"); + return TEST_SUCCESS; +} + /* perf_test_aes_sha("avx2", HASH_CIPHER, 16, CBC, SHA1); @@ -2937,6 +3415,166 @@ test_perf_snow3G_vary_pkt_size(void) } static int +test_perf_libcrypto_vary_pkt_size(void) +{ + unsigned int total_operations = 1000000; + unsigned int burst_size = { 64 }; + unsigned int buf_lengths[] = { 64, 128, 256, 512, 768, 1024, 1280, 1536, + 1792, 2048 }; + uint8_t i, j; + + struct perf_test_params params_set[] = { + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key_length = 24, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key_length = 32, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key_length = 24, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_GCM, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_AES_GCM + }, + }; + + for (i = 0; i < RTE_DIM(params_set); i++) { + params_set[i].total_operations = total_operations; + params_set[i].burst_size = burst_size; + printf("\n%s. cipher algo: %s auth algo: %s cipher key size=%u." + " burst_size: %d ops\n", + chain_mode_name(params_set[i].chain), + cipher_algo_name(params_set[i].cipher_algo), + auth_algo_name(params_set[i].auth_algo), + params_set[i].cipher_key_length, + burst_size); + printf("\nBuffer Size(B)\tOPS(M)\tThroughput(Gbps)\tRetries\t" + "EmptyPolls\n"); + for (j = 0; j < RTE_DIM(buf_lengths); j++) { + params_set[i].buf_size = buf_lengths[j]; + test_perf_libcrypto(testsuite_params.dev_id, 0, ¶ms_set[i]); + } + } + + return 0; +} + +static int +test_perf_libcrypto_vary_burst_size(void) +{ + unsigned int total_operations = 4096; + uint16_t buf_lengths[] = { 40 }; + uint8_t i, j; + + struct perf_test_params params_set[] = { + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key_length = 24, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key_length = 32, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key_length = 24, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_GCM, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_AES_GCM + }, + }; + + printf("\n\nStart %s.", __func__); + printf("\nThis Test measures the average IA cycle cost using a " + "constant request(packet) size. "); + printf("Cycle cost is only valid when indicators show device is not busy," + " i.e. Retries and EmptyPolls = 0"); + + for (i = 0; i < RTE_DIM(params_set); i++) { + printf("\n"); + params_set[i].total_operations = total_operations; + + for (j = 0; j < RTE_DIM(buf_lengths); j++) { + params_set[i].buf_size = buf_lengths[j]; + test_perf_libcrypto_optimise_cyclecount(¶ms_set[i]); + } + } + + return 0; +} + +static int test_perf_aes_cbc_vary_burst_size(void) { return test_perf_crypto_qp_vary_burst_size(testsuite_params.dev_id); @@ -3377,6 +4015,19 @@ static struct unit_test_suite cryptodev_snow3g_testsuite = { } }; +static struct unit_test_suite cryptodev_libcrypto_testsuite = { + .suite_name = "Crypto Device LIBCRYPTO Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, + test_perf_libcrypto_vary_pkt_size), + TEST_CASE_ST(ut_setup, ut_teardown, + test_perf_libcrypto_vary_burst_size), + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + static int perftest_aesni_gcm_cryptodev(void) { @@ -3417,8 +4068,18 @@ perftest_qat_snow3g_cryptodev(void /*argv __rte_unused, int argc __rte_unused*/) return unit_test_suite_runner(&cryptodev_snow3g_testsuite); } +static int +perftest_libcrypto_cryptodev(void /*argv __rte_unused, int argc __rte_unused*/) +{ + gbl_cryptodev_perftest_devtype = RTE_CRYPTODEV_LIBCRYPTO_PMD; + + return unit_test_suite_runner(&cryptodev_libcrypto_testsuite); +} + REGISTER_TEST_COMMAND(cryptodev_aesni_mb_perftest, perftest_aesni_mb_cryptodev); REGISTER_TEST_COMMAND(cryptodev_qat_perftest, perftest_qat_cryptodev); REGISTER_TEST_COMMAND(cryptodev_sw_snow3g_perftest, perftest_sw_snow3g_cryptodev); REGISTER_TEST_COMMAND(cryptodev_qat_snow3g_perftest, perftest_qat_snow3g_cryptodev); REGISTER_TEST_COMMAND(cryptodev_aesni_gcm_perftest, perftest_aesni_gcm_cryptodev); +REGISTER_TEST_COMMAND(cryptodev_libcrypto_perftest, + perftest_libcrypto_cryptodev); -- 2.5.0 ^ permalink raw reply [flat|nested] 34+ messages in thread
* [dpdk-dev] [PATCH v5 4/4] examples/l2fwd-crypto: updated example for libcrypto PMD 2016-10-03 14:26 ` [dpdk-dev] [PATCH v5 0/4] new crypto software based device Slawomir Mrozowicz ` (2 preceding siblings ...) 2016-10-03 15:17 ` [dpdk-dev] [PATCH v5 3/4] app/test: added tests for libcrypto PMD Slawomir Mrozowicz @ 2016-10-03 15:28 ` Slawomir Mrozowicz 2016-10-03 22:36 ` [dpdk-dev] [PATCH v5 0/4] new crypto software based device De Lara Guarch, Pablo 2016-10-04 15:11 ` [dpdk-dev] [PATCH v6 " Slawomir Mrozowicz 5 siblings, 0 replies; 34+ messages in thread From: Slawomir Mrozowicz @ 2016-10-03 15:28 UTC (permalink / raw) To: dev; +Cc: Slawomir Mrozowicz, Daniel Mrzyglod Libcrypto PMD has support for: Supported cipher algorithms: RTE_CRYPTO_CIPHER_3DES_CBC RTE_CRYPTO_CIPHER_AES_CBC RTE_CRYPTO_CIPHER_AES_CTR RTE_CRYPTO_CIPHER_3DES_CTR RTE_CRYPTO_CIPHER_AES_GCM Supported authentication algorithms: RTE_CRYPTO_AUTH_AES_GMAC RTE_CRYPTO_AUTH_MD5 RTE_CRYPTO_AUTH_SHA1 RTE_CRYPTO_AUTH_SHA224 RTE_CRYPTO_AUTH_SHA256 RTE_CRYPTO_AUTH_SHA384 RTE_CRYPTO_AUTH_SHA512 RTE_CRYPTO_AUTH_MD5_HMAC RTE_CRYPTO_AUTH_SHA1_HMAC RTE_CRYPTO_AUTH_SHA224_HMAC RTE_CRYPTO_AUTH_SHA256_HMAC RTE_CRYPTO_AUTH_SHA384_HMAC RTE_CRYPTO_AUTH_SHA512_HMAC Signed-off-by: Daniel Mrzyglod <danielx.t.mrzyglod@intel.com> --- v3: - change description --- examples/l2fwd-crypto/main.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/examples/l2fwd-crypto/main.c b/examples/l2fwd-crypto/main.c index 0593734..dae45f5 100644 --- a/examples/l2fwd-crypto/main.c +++ b/examples/l2fwd-crypto/main.c @@ -340,15 +340,22 @@ fill_supported_algorithm_tables(void) strcpy(supported_auth_algo[i], "NOT_SUPPORTED"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_AES_GCM], "AES_GCM"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_AES_GMAC], "AES_GMAC"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_MD5_HMAC], "MD5_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_MD5], "MD5"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_NULL], "NULL"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_AES_XCBC_MAC], "AES_XCBC_MAC"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA1_HMAC], "SHA1_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA1], "SHA1"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA224_HMAC], "SHA224_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA224], "SHA224"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA256_HMAC], "SHA256_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA256], "SHA256"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA384_HMAC], "SHA384_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA384], "SHA384"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA512_HMAC], "SHA512_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA512], "SHA512"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SNOW3G_UIA2], "SNOW3G_UIA2"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_ZUC_EIA3], "ZUC_EIA3"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_KASUMI_F9], "KASUMI_F9"); @@ -363,6 +370,8 @@ fill_supported_algorithm_tables(void) strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_SNOW3G_UEA2], "SNOW3G_UEA2"); strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_ZUC_EEA3], "ZUC_EEA3"); strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_KASUMI_F8], "KASUMI_F8"); + strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_3DES_CTR], "3DES_CTR"); + strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_3DES_CBC], "3DES_CBC"); } -- 2.5.0 ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dpdk-dev] [PATCH v5 0/4] new crypto software based device 2016-10-03 14:26 ` [dpdk-dev] [PATCH v5 0/4] new crypto software based device Slawomir Mrozowicz ` (3 preceding siblings ...) 2016-10-03 15:28 ` [dpdk-dev] [PATCH v5 4/4] examples/l2fwd-crypto: updated example " Slawomir Mrozowicz @ 2016-10-03 22:36 ` De Lara Guarch, Pablo 2016-10-04 15:11 ` [dpdk-dev] [PATCH v6 " Slawomir Mrozowicz 5 siblings, 0 replies; 34+ messages in thread From: De Lara Guarch, Pablo @ 2016-10-03 22:36 UTC (permalink / raw) To: Mrozowicz, SlawomirX, dev; +Cc: Mrozowicz, SlawomirX Hi, > -----Original Message----- > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Slawomir Mrozowicz > Sent: Monday, October 03, 2016 7:26 AM > To: dev@dpdk.org > Cc: Mrozowicz, SlawomirX > Subject: [dpdk-dev] [PATCH v5 0/4] new crypto software based device > > This code provides the initial implementation of the libcrypto poll mode > driver. > All cryptography operations are using Openssl library crypto API. > Each algorithm uses EVP_ interface from openssl API - which is recommended > by > Openssl maintainers. > > For more information about how to use this driver, go to: > doc/guides/cryptodevs/libcrypto.rst > > Changes in V5: > - reduce source of big data test > > Changes in V4: > - move aes test rework to another patch > - move big data test to another patch > - checking if libcrypto pmd is available > > Changes in V3: > - add nagative verification tests > - add big data test > - fix pmd according to negative verification tests > - change gmac aad max size > - update documentation and commits comments > > Changes in V2: > - add gcm/gmac algorithm correction > - unit test rework > > Slawomir Mrozowicz (1): > libcrypto_pmd: initial implementation of SW crypto device > > Piotr Azarewicz (2) > app/test: cryptodev AES tests rework > app/test: added tests for libcrypto PMD > > Daniel Mrzyglod (1) > examples/l2fwd-crypto: updated example for libcrypto PMD > > MAINTAINERS | 4 + > app/test/Makefile | 2 +- > app/test/test_cryptodev.c | 1581 ++++++++++++++++++-- > app/test/test_cryptodev.h | 1 + > app/test/test_cryptodev_aes.c | 687 --------- > app/test/test_cryptodev_aes.h | 1124 -------------- > app/test/test_cryptodev_aes_test_vectors.h | 1095 ++++++++++++++ > app/test/test_cryptodev_blockcipher.c | 531 +++++++ > app/test/test_cryptodev_blockcipher.h | 125 ++ > app/test/test_cryptodev_des_test_vectors.h | 952 ++++++++++++ > app/test/test_cryptodev_gcm_test_vectors.h | 36 +- > app/test/test_cryptodev_hash_test_vectors.h | 491 ++++++ > app/test/test_cryptodev_perf.c | 689 ++++++++- > config/common_base | 6 + > doc/guides/cryptodevs/index.rst | 1 + > doc/guides/cryptodevs/libcrypto.rst | 116 ++ > doc/guides/rel_notes/release_16_11.rst | 23 +- > drivers/crypto/Makefile | 1 + > drivers/crypto/libcrypto/Makefile | 60 + > drivers/crypto/libcrypto/rte_libcrypto_pmd.c | 1051 +++++++++++++ > drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c | 708 +++++++++ > .../crypto/libcrypto/rte_libcrypto_pmd_private.h | 174 +++ > .../crypto/libcrypto/rte_pmd_libcrypto_version.map | 3 + > examples/l2fwd-crypto/main.c | 9 + > lib/librte_cryptodev/rte_cryptodev.h | 5 +- > mk/rte.app.mk | 23 +- > 26 files changed, 7563 insertions(+), 1935 deletions(-) > delete mode 100644 app/test/test_cryptodev_aes.c > delete mode 100644 app/test/test_cryptodev_aes.h > create mode 100644 app/test/test_cryptodev_aes_test_vectors.h > create mode 100644 app/test/test_cryptodev_blockcipher.c > create mode 100644 app/test/test_cryptodev_blockcipher.h > create mode 100644 app/test/test_cryptodev_des_test_vectors.h > create mode 100644 app/test/test_cryptodev_hash_test_vectors.h > create mode 100644 doc/guides/cryptodevs/libcrypto.rst > create mode 100644 drivers/crypto/libcrypto/Makefile > create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd.c > create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c > create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h > create mode 100644 > drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map > > -- > 2.5.0 There are still some checkpatch errors, mainly related to exceeding maximum line length. Some of these lines are more than 90 character long, so at least these ones should be fixed. Thanks, Pablo ^ permalink raw reply [flat|nested] 34+ messages in thread
* [dpdk-dev] [PATCH v6 0/4] new crypto software based device 2016-10-03 14:26 ` [dpdk-dev] [PATCH v5 0/4] new crypto software based device Slawomir Mrozowicz ` (4 preceding siblings ...) 2016-10-03 22:36 ` [dpdk-dev] [PATCH v5 0/4] new crypto software based device De Lara Guarch, Pablo @ 2016-10-04 15:11 ` Slawomir Mrozowicz 2016-10-04 15:11 ` [dpdk-dev] [PATCH v6 1/4] libcrypto_pmd: initial implementation of SW crypto device Slawomir Mrozowicz ` (4 more replies) 5 siblings, 5 replies; 34+ messages in thread From: Slawomir Mrozowicz @ 2016-10-04 15:11 UTC (permalink / raw) To: dev; +Cc: Slawomir Mrozowicz This code provides the initial implementation of the libcrypto poll mode driver. All cryptography operations are using Openssl library crypto API. Each algorithm uses EVP_ interface from openssl API - which is recommended by Openssl maintainers. For more information about how to use this driver, go to: doc/guides/cryptodevs/libcrypto.rst Changes in V6: - fix checkpatch warnings Changes in V5: - reduce source of big data test Changes in V4: - move aes test rework to another patch - move big data test to another patch - checking if libcrypto pmd is available Changes in V3: - add nagative verification tests - add big data test - fix pmd according to negative verification tests - change gmac aad max size - update documentation and commits comments Changes in V2: - add gcm/gmac algorithm correction - unit test rework Slawomir Mrozowicz (1): libcrypto_pmd: initial implementation of SW crypto device Piotr Azarewicz (2) app/test: cryptodev AES tests rework app/test: added tests for libcrypto PMD Daniel Mrzyglod (1) examples/l2fwd-crypto: updated example for libcrypto PMD MAINTAINERS | 4 + app/test/Makefile | 2 +- app/test/test_cryptodev.c | 1584 ++++++++++++++++++-- app/test/test_cryptodev.h | 1 + app/test/test_cryptodev_aes.c | 687 --------- app/test/test_cryptodev_aes.h | 1124 -------------- app/test/test_cryptodev_aes_test_vectors.h | 1097 ++++++++++++++ app/test/test_cryptodev_blockcipher.c | 538 +++++++ app/test/test_cryptodev_blockcipher.h | 125 ++ app/test/test_cryptodev_des_test_vectors.h | 955 ++++++++++++ app/test/test_cryptodev_gcm_test_vectors.h | 36 +- app/test/test_cryptodev_hash_test_vectors.h | 491 ++++++ app/test/test_cryptodev_perf.c | 712 ++++++++- config/common_base | 6 + doc/guides/cryptodevs/index.rst | 1 + doc/guides/cryptodevs/libcrypto.rst | 116 ++ doc/guides/rel_notes/release_16_11.rst | 23 +- drivers/crypto/Makefile | 1 + drivers/crypto/libcrypto/Makefile | 60 + drivers/crypto/libcrypto/rte_libcrypto_pmd.c | 1062 +++++++++++++ drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c | 708 +++++++++ .../crypto/libcrypto/rte_libcrypto_pmd_private.h | 174 +++ .../crypto/libcrypto/rte_pmd_libcrypto_version.map | 3 + examples/l2fwd-crypto/main.c | 9 + lib/librte_cryptodev/rte_cryptodev.h | 5 +- mk/rte.app.mk | 23 +- 26 files changed, 7621 insertions(+), 1926 deletions(-) delete mode 100644 app/test/test_cryptodev_aes.c delete mode 100644 app/test/test_cryptodev_aes.h create mode 100644 app/test/test_cryptodev_aes_test_vectors.h create mode 100644 app/test/test_cryptodev_blockcipher.c create mode 100644 app/test/test_cryptodev_blockcipher.h create mode 100644 app/test/test_cryptodev_des_test_vectors.h create mode 100644 app/test/test_cryptodev_hash_test_vectors.h create mode 100644 doc/guides/cryptodevs/libcrypto.rst create mode 100644 drivers/crypto/libcrypto/Makefile create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd.c create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h create mode 100644 drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map -- 2.5.0 ^ permalink raw reply [flat|nested] 34+ messages in thread
* [dpdk-dev] [PATCH v6 1/4] libcrypto_pmd: initial implementation of SW crypto device 2016-10-04 15:11 ` [dpdk-dev] [PATCH v6 " Slawomir Mrozowicz @ 2016-10-04 15:11 ` Slawomir Mrozowicz 2016-10-04 15:11 ` [dpdk-dev] [PATCH v6 2/4] app/test: cryptodev AES tests rework Slawomir Mrozowicz ` (3 subsequent siblings) 4 siblings, 0 replies; 34+ messages in thread From: Slawomir Mrozowicz @ 2016-10-04 15:11 UTC (permalink / raw) To: dev Cc: Slawomir Mrozowicz, Michal Kobylinski, Tomasz Kulasek, Daniel Mrzyglod This code provides the initial implementation of the libcrypto poll mode driver. All cryptography operations are using Openssl library crypto API. Each algorithm uses EVP_ interface from openssl API - which is recommended by Openssl maintainers. This patch adds libcrypto poll mode driver support to librte_cryptodev library. Signed-off-by: Slawomir Mrozowicz <slawomirx.mrozowicz@intel.com> Signed-off-by: Michal Kobylinski <michalx.kobylinski@intel.com> Signed-off-by: Tomasz Kulasek <tomaszx.kulasek@intel.com> Signed-off-by: Daniel Mrzyglod <danielx.t.mrzyglod@intel.com> --- v2: - add gcm crypto cipher and authentication algorithm - rework gmac crypto authentication algorithm v3: - fix pmd according to negative verification tests - change gmac aad max size - update documentation v6: - fix checkpatch warnings --- MAINTAINERS | 4 + config/common_base | 6 + doc/guides/cryptodevs/index.rst | 1 + doc/guides/cryptodevs/libcrypto.rst | 116 +++ doc/guides/rel_notes/release_16_11.rst | 23 +- drivers/crypto/Makefile | 1 + drivers/crypto/libcrypto/Makefile | 60 ++ drivers/crypto/libcrypto/rte_libcrypto_pmd.c | 1062 ++++++++++++++++++++ drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c | 708 +++++++++++++ .../crypto/libcrypto/rte_libcrypto_pmd_private.h | 174 ++++ .../crypto/libcrypto/rte_pmd_libcrypto_version.map | 3 + lib/librte_cryptodev/rte_cryptodev.h | 5 +- mk/rte.app.mk | 23 +- 13 files changed, 2173 insertions(+), 13 deletions(-) create mode 100644 doc/guides/cryptodevs/libcrypto.rst create mode 100644 drivers/crypto/libcrypto/Makefile create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd.c create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h create mode 100644 drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map diff --git a/MAINTAINERS b/MAINTAINERS index 58a10b8..1e9d1f8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -439,6 +439,10 @@ M: Declan Doherty <declan.doherty@intel.com> F: drivers/crypto/null/ F: doc/guides/cryptodevs/null.rst +LibCrypto Crypto PMD +M: Declan Doherty <declan.doherty@intel.com> +F: drivers/crypto/libcrypto/ +F: doc/guides/cryptodevs/libcrypto.rst Packet processing ----------------- diff --git a/config/common_base b/config/common_base index 3a412ee..87b8646 100644 --- a/config/common_base +++ b/config/common_base @@ -376,6 +376,12 @@ CONFIG_RTE_LIBRTE_PMD_AESNI_MB=n CONFIG_RTE_LIBRTE_PMD_AESNI_MB_DEBUG=n # +# Compile PMD for Software backed device +# +CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO=n +CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO_DEBUG=n + +# # Compile PMD for AESNI GCM device # CONFIG_RTE_LIBRTE_PMD_AESNI_GCM=n diff --git a/doc/guides/cryptodevs/index.rst b/doc/guides/cryptodevs/index.rst index 906f1b4..bae8e53 100644 --- a/doc/guides/cryptodevs/index.rst +++ b/doc/guides/cryptodevs/index.rst @@ -39,6 +39,7 @@ Crypto Device Drivers aesni_mb aesni_gcm kasumi + libcrypto null snow3g qat diff --git a/doc/guides/cryptodevs/libcrypto.rst b/doc/guides/cryptodevs/libcrypto.rst new file mode 100644 index 0000000..77eff95 --- /dev/null +++ b/doc/guides/cryptodevs/libcrypto.rst @@ -0,0 +1,116 @@ +.. 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. + +LibCrypto Crypto Poll Mode Driver + +This code provides the initial implementation of the libcrypto poll mode +driver. All cryptography operations are using Openssl library crypto API. +Each algorithm uses EVP_ interface from openssl API - which is recommended +by Openssl maintainers. + +For more details about openssl library please visit openssl webpage: +https://www.openssl.org/ + +Features +-------- + +LibCrypto PMD has support for: + +Supported cipher algorithms: +* ``RTE_CRYPTO_CIPHER_3DES_CBC`` +* ``RTE_CRYPTO_CIPHER_AES_CBC`` +* ``RTE_CRYPTO_CIPHER_AES_CTR`` +* ``RTE_CRYPTO_CIPHER_3DES_CTR`` +* ``RTE_CRYPTO_CIPHER_AES_GCM`` + +Supported authentication algorithms: +* ``RTE_CRYPTO_AUTH_AES_GMAC`` +* ``RTE_CRYPTO_AUTH_MD5`` +* ``RTE_CRYPTO_AUTH_SHA1`` +* ``RTE_CRYPTO_AUTH_SHA224`` +* ``RTE_CRYPTO_AUTH_SHA256`` +* ``RTE_CRYPTO_AUTH_SHA384`` +* ``RTE_CRYPTO_AUTH_SHA512`` +* ``RTE_CRYPTO_AUTH_MD5_HMAC`` +* ``RTE_CRYPTO_AUTH_SHA1_HMAC`` +* ``RTE_CRYPTO_AUTH_SHA224_HMAC`` +* ``RTE_CRYPTO_AUTH_SHA256_HMAC`` +* ``RTE_CRYPTO_AUTH_SHA384_HMAC`` +* ``RTE_CRYPTO_AUTH_SHA512_HMAC`` + + +Installation +------------ + +To compile libcrypto PMD, it has to be enabled in the config/common_base file +and appropriate openssl packages have to be installed in the build environment. + +The newest openssl library version is supported: +* 1.0.2h-fips 3 May 2016. +Older versions that were also verified: +* 1.0.1f 6 Jan 2014 +* 1.0.1 14 Mar 2012 + +For Ubuntu 14.04 LTS these packages have to be installed in the build system: +sudo apt-get install openssl +sudo apt-get install libc6-dev-i386 (for i686-native-linuxapp-gcc target) + +This code was also verified on Fedora 24. +This code was NOT yet verified on FreeBSD. + +Initialization +-------------- + +User can use app/test application to check how to use this pmd and to verify +crypto processing. + +Test name is cryptodev_libcrypto_autotest. +For performance test cryptodev_libcrypto_perftest can be used. + +To verify real traffic l2fwd-crypto example can be used with this command: + +.. code-block:: console + +sudo ./build/l2fwd-crypto -c 0x3 -n 4 --vdev "cryptodev_libcrypto_pmd" +--vdev "cryptodev_libcrypto_pmd"-- -p 0x3 --chain CIPHER_HASH +--cipher_op ENCRYPT --cipher_algo AES_CBC +--cipher_key 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f +--iv 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:ff +--auth_op GENERATE --auth_algo SHA1_HMAC +--auth_key 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11 +:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11 +:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11 + +Limitations +----------- + +* Maximum number of sessions is 2048. +* Chained mbufs are not supported. +* Hash only is not supported for GCM and GMAC. +* Cipher only is not supported for GCM and GMAC. diff --git a/doc/guides/rel_notes/release_16_11.rst b/doc/guides/rel_notes/release_16_11.rst index cc507a9..6e92966 100644 --- a/doc/guides/rel_notes/release_16_11.rst +++ b/doc/guides/rel_notes/release_16_11.rst @@ -34,7 +34,28 @@ New Features Refer to the previous release notes for examples. - This section is a comment. Make sure to start the actual text at the margin. +* **Added libcrypto PMD.** + + A new crypto PMD has been added, which provides several ciphering and hashing. + All cryptography operations are using Openssl library crypto API. + +* ** Added support of C3xxx Device in QAT PMD.** + Support for Device c3xxx has been enabled in QAT PMD. + +* ** Added support of C62XX Device in QAT PMD.** + Support for Device c62xx has been enabled in QAT PMD. + + +* **Updated the QAT PMD.** + The QAT PMD was updated with changes including the following: + + * Added support for MD5_HMAC algorithm. + * Added support for SHA224-HMAC algorithm. + * Added support for SHA384-HMAC algorithm. + * Added support for NULL algorithm. + * Added support for KASUMI (F8 and F9) algorithm. + * Added support for GMAC algorithm. + * Added support for 3DES block cipher algorithm. * ** Added support of C3xxx Device in QAT PMD.** Support for Device c3xxx has been enabled in QAT PMD. diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index 17d74fc..b452ea6 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -33,6 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += aesni_gcm DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += aesni_mb +DIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += libcrypto DIRS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += qat DIRS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += snow3g DIRS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI) += kasumi diff --git a/drivers/crypto/libcrypto/Makefile b/drivers/crypto/libcrypto/Makefile new file mode 100644 index 0000000..c5f8cf2 --- /dev/null +++ b/drivers/crypto/libcrypto/Makefile @@ -0,0 +1,60 @@ +# 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 + +# library name +LIB = librte_pmd_libcrypto.a + +# build flags +CFLAGS += -O3 +CFLAGS += $(WERROR_FLAGS) + +# library version +LIBABIVER := 1 + +# versioning export map +EXPORT_MAP := rte_pmd_libcrypto_version.map + +# external library dependencies +LDLIBS += -lcrypto + +# library source files +SRCS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += rte_libcrypto_pmd.c +SRCS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += rte_libcrypto_pmd_ops.c + +# library dependencies +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_eal +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_mbuf +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_mempool +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_ring +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_cryptodev + +include $(RTE_SDK)/mk/rte.lib.mk diff --git a/drivers/crypto/libcrypto/rte_libcrypto_pmd.c b/drivers/crypto/libcrypto/rte_libcrypto_pmd.c new file mode 100644 index 0000000..4997a45 --- /dev/null +++ b/drivers/crypto/libcrypto/rte_libcrypto_pmd.c @@ -0,0 +1,1062 @@ +/*- + * 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_common.h> +#include <rte_hexdump.h> +#include <rte_cryptodev.h> +#include <rte_cryptodev_pmd.h> +#include <rte_dev.h> +#include <rte_malloc.h> +#include <rte_cpuflags.h> + +#include <openssl/evp.h> + +#include "rte_libcrypto_pmd_private.h" + +static int cryptodev_libcrypto_uninit(const char *name); + +/*----------------------------------------------------------------------------*/ + +/** + * Global static parameter used to create a unique name for each + * LIBCRYPTO crypto device. + */ +static unsigned int unique_name_id; + +static inline int +create_unique_device_name(char *name, size_t size) +{ + int ret; + + if (name == NULL) + return -EINVAL; + + ret = snprintf(name, size, "%s_%u", + RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), + unique_name_id++); + if (ret < 0) + return ret; + return 0; +} + +/** + * Increment counter by 1 + * Counter is 64 bit array, big-endian + */ +static void +ctr_inc(uint8_t *ctr) +{ + uint64_t *ctr64 = (uint64_t *)ctr; + + *ctr64 = __builtin_bswap64(*ctr64); + (*ctr64)++; + *ctr64 = __builtin_bswap64(*ctr64); +} + +/* + *------------------------------------------------------------------------------ + * Session Prepare + *------------------------------------------------------------------------------ + */ + +/** Get xform chain order */ +static enum libcrypto_chain_order +libcrypto_get_chain_order(const struct rte_crypto_sym_xform *xform) +{ + enum libcrypto_chain_order res = LIBCRYPTO_CHAIN_NOT_SUPPORTED; + + if (xform != NULL) { + if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) { + if (xform->next == NULL) + res = LIBCRYPTO_CHAIN_ONLY_AUTH; + else if (xform->next->type == + RTE_CRYPTO_SYM_XFORM_CIPHER) + res = LIBCRYPTO_CHAIN_AUTH_CIPHER; + } + if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) { + if (xform->next == NULL) + res = LIBCRYPTO_CHAIN_ONLY_CIPHER; + else if (xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH) + res = LIBCRYPTO_CHAIN_CIPHER_AUTH; + } + } + + return res; +} + +/** Get session cipher key from input cipher key */ +static void +get_cipher_key(uint8_t *input_key, int keylen, uint8_t *session_key) +{ + memcpy(session_key, input_key, keylen); +} + +/** Get key ede 24 bytes standard from input key */ +static int +get_cipher_key_ede(uint8_t *key, int keylen, uint8_t *key_ede) +{ + int res = 0; + + /* Initialize keys - 24 bytes: [key1-key2-key3] */ + switch (keylen) { + case 24: + memcpy(key_ede, key, 24); + break; + case 16: + /* K3 = K1 */ + memcpy(key_ede, key, 16); + memcpy(key_ede + 16, key, 8); + break; + case 8: + /* K1 = K2 = K3 (DES compatibility) */ + memcpy(key_ede, key, 8); + memcpy(key_ede + 8, key, 8); + memcpy(key_ede + 16, key, 8); + break; + default: + LIBCRYPTO_LOG_ERR("Unsupported key size"); + res = -EINVAL; + } + + return res; +} + +/** Get adequate libcrypto function for input cipher algorithm */ +static uint8_t +get_cipher_algo(enum rte_crypto_cipher_algorithm sess_algo, size_t keylen, + const EVP_CIPHER **algo) +{ + int res = 0; + + if (algo != NULL) { + switch (sess_algo) { + case RTE_CRYPTO_CIPHER_3DES_CBC: + switch (keylen) { + case 16: + *algo = EVP_des_ede_cbc(); + break; + case 24: + *algo = EVP_des_ede3_cbc(); + break; + default: + res = -EINVAL; + } + break; + case RTE_CRYPTO_CIPHER_3DES_CTR: + break; + case RTE_CRYPTO_CIPHER_AES_CBC: + switch (keylen) { + case 16: + *algo = EVP_aes_128_cbc(); + break; + case 24: + *algo = EVP_aes_192_cbc(); + break; + case 32: + *algo = EVP_aes_256_cbc(); + break; + default: + res = -EINVAL; + } + break; + case RTE_CRYPTO_CIPHER_AES_CTR: + switch (keylen) { + case 16: + *algo = EVP_aes_128_ctr(); + break; + case 24: + *algo = EVP_aes_192_ctr(); + break; + case 32: + *algo = EVP_aes_256_ctr(); + break; + default: + res = -EINVAL; + } + break; + case RTE_CRYPTO_CIPHER_AES_GCM: + switch (keylen) { + case 16: + *algo = EVP_aes_128_gcm(); + break; + case 24: + *algo = EVP_aes_192_gcm(); + break; + case 32: + *algo = EVP_aes_256_gcm(); + break; + default: + res = -EINVAL; + } + break; + default: + res = -EINVAL; + break; + } + } else { + res = -EINVAL; + } + + return res; +} + +/** Get adequate libcrypto function for input auth algorithm */ +static uint8_t +get_auth_algo(enum rte_crypto_auth_algorithm sessalgo, + const EVP_MD **algo) +{ + int res = 0; + + if (algo != NULL) { + switch (sessalgo) { + case RTE_CRYPTO_AUTH_MD5: + case RTE_CRYPTO_AUTH_MD5_HMAC: + *algo = EVP_md5(); + break; + case RTE_CRYPTO_AUTH_SHA1: + case RTE_CRYPTO_AUTH_SHA1_HMAC: + *algo = EVP_sha1(); + break; + case RTE_CRYPTO_AUTH_SHA224: + case RTE_CRYPTO_AUTH_SHA224_HMAC: + *algo = EVP_sha224(); + break; + case RTE_CRYPTO_AUTH_SHA256: + case RTE_CRYPTO_AUTH_SHA256_HMAC: + *algo = EVP_sha256(); + break; + case RTE_CRYPTO_AUTH_SHA384: + case RTE_CRYPTO_AUTH_SHA384_HMAC: + *algo = EVP_sha384(); + break; + case RTE_CRYPTO_AUTH_SHA512: + case RTE_CRYPTO_AUTH_SHA512_HMAC: + *algo = EVP_sha512(); + break; + default: + res = -EINVAL; + break; + } + } else { + res = -EINVAL; + } + + return res; +} + +/** Set session cipher parameters */ +static int +libcrypto_set_session_cipher_parameters(struct libcrypto_session *sess, + const struct rte_crypto_sym_xform *xform) +{ + /* Select cipher direction */ + sess->cipher.direction = xform->cipher.op; + /* Select cipher key */ + sess->cipher.key.length = xform->cipher.key.length; + + /* Select cipher algo */ + switch (xform->cipher.algo) { + case RTE_CRYPTO_CIPHER_3DES_CBC: + case RTE_CRYPTO_CIPHER_AES_CBC: + case RTE_CRYPTO_CIPHER_AES_CTR: + case RTE_CRYPTO_CIPHER_AES_GCM: + sess->cipher.mode = LIBCRYPTO_CIPHER_LIB; + sess->cipher.algo = xform->cipher.algo; + sess->cipher.ctx = EVP_CIPHER_CTX_new(); + + if (get_cipher_algo(sess->cipher.algo, sess->cipher.key.length, + &sess->cipher.evp_algo) != 0) + return -EINVAL; + + get_cipher_key(xform->cipher.key.data, sess->cipher.key.length, + sess->cipher.key.data); + + break; + + case RTE_CRYPTO_CIPHER_3DES_CTR: + sess->cipher.mode = LIBCRYPTO_CIPHER_DES3CTR; + sess->cipher.ctx = EVP_CIPHER_CTX_new(); + + if (get_cipher_key_ede(xform->cipher.key.data, + sess->cipher.key.length, + sess->cipher.key.data) != 0) + return -EINVAL; + break; + + default: + sess->cipher.algo = RTE_CRYPTO_CIPHER_NULL; + return -EINVAL; + } + + return 0; +} + +/* Set session auth parameters */ +static int +libcrypto_set_session_auth_parameters(struct libcrypto_session *sess, + const struct rte_crypto_sym_xform *xform) +{ + /* Select auth generate/verify */ + sess->auth.operation = xform->auth.op; + sess->auth.algo = xform->auth.algo; + + /* Select auth algo */ + switch (xform->auth.algo) { + case RTE_CRYPTO_AUTH_AES_GMAC: + case RTE_CRYPTO_AUTH_AES_GCM: + /* Check additional condition for AES_GMAC/GCM */ + if (sess->cipher.algo != RTE_CRYPTO_CIPHER_AES_GCM) + return -EINVAL; + sess->chain_order = LIBCRYPTO_CHAIN_COMBINED; + break; + + case RTE_CRYPTO_AUTH_MD5: + case RTE_CRYPTO_AUTH_SHA1: + case RTE_CRYPTO_AUTH_SHA224: + case RTE_CRYPTO_AUTH_SHA256: + case RTE_CRYPTO_AUTH_SHA384: + case RTE_CRYPTO_AUTH_SHA512: + sess->auth.mode = LIBCRYPTO_AUTH_AS_AUTH; + if (get_auth_algo(xform->auth.algo, + &sess->auth.auth.evp_algo) != 0) + return -EINVAL; + sess->auth.auth.ctx = EVP_MD_CTX_create(); + break; + + case RTE_CRYPTO_AUTH_MD5_HMAC: + case RTE_CRYPTO_AUTH_SHA1_HMAC: + case RTE_CRYPTO_AUTH_SHA224_HMAC: + case RTE_CRYPTO_AUTH_SHA256_HMAC: + case RTE_CRYPTO_AUTH_SHA384_HMAC: + case RTE_CRYPTO_AUTH_SHA512_HMAC: + sess->auth.mode = LIBCRYPTO_AUTH_AS_HMAC; + sess->auth.hmac.ctx = EVP_MD_CTX_create(); + if (get_auth_algo(xform->auth.algo, + &sess->auth.hmac.evp_algo) != 0) + return -EINVAL; + sess->auth.hmac.pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, + xform->auth.key.data, xform->auth.key.length); + break; + + default: + return -EINVAL; + } + + return 0; +} + +/** Parse crypto xform chain and set private session parameters */ +int +libcrypto_set_session_parameters(struct libcrypto_session *sess, + const struct rte_crypto_sym_xform *xform) +{ + const struct rte_crypto_sym_xform *cipher_xform = NULL; + const struct rte_crypto_sym_xform *auth_xform = NULL; + + sess->chain_order = libcrypto_get_chain_order(xform); + switch (sess->chain_order) { + case LIBCRYPTO_CHAIN_ONLY_CIPHER: + cipher_xform = xform; + break; + case LIBCRYPTO_CHAIN_ONLY_AUTH: + auth_xform = xform; + break; + case LIBCRYPTO_CHAIN_CIPHER_AUTH: + cipher_xform = xform; + auth_xform = xform->next; + break; + case LIBCRYPTO_CHAIN_AUTH_CIPHER: + auth_xform = xform; + cipher_xform = xform->next; + break; + default: + return -EINVAL; + } + + /* cipher_xform must be check before auth_xform */ + if (cipher_xform) { + if (libcrypto_set_session_cipher_parameters( + sess, cipher_xform)) { + LIBCRYPTO_LOG_ERR( + "Invalid/unsupported cipher parameters"); + return -EINVAL; + } + } + + if (auth_xform) { + if (libcrypto_set_session_auth_parameters(sess, auth_xform)) { + LIBCRYPTO_LOG_ERR( + "Invalid/unsupported auth parameters"); + return -EINVAL; + } + } + + return 0; +} + +/** Reset private session parameters */ +void +libcrypto_reset_session(struct libcrypto_session *sess) +{ + EVP_CIPHER_CTX_free(sess->cipher.ctx); + + switch (sess->auth.mode) { + case LIBCRYPTO_AUTH_AS_AUTH: + EVP_MD_CTX_destroy(sess->auth.auth.ctx); + break; + case LIBCRYPTO_AUTH_AS_HMAC: + EVP_PKEY_free(sess->auth.hmac.pkey); + EVP_MD_CTX_destroy(sess->auth.hmac.ctx); + break; + default: + break; + } +} + +/** Provide session for operation */ +static struct libcrypto_session * +get_session(struct libcrypto_qp *qp, struct rte_crypto_op *op) +{ + struct libcrypto_session *sess = NULL; + + if (op->sym->sess_type == RTE_CRYPTO_SYM_OP_WITH_SESSION) { + /* get existing session */ + if (likely(op->sym->session != NULL && + op->sym->session->dev_type == + RTE_CRYPTODEV_LIBCRYPTO_PMD)) + sess = (struct libcrypto_session *) + op->sym->session->_private; + } else { + /* provide internal session */ + void *_sess = NULL; + + if (!rte_mempool_get(qp->sess_mp, (void **)&_sess)) { + sess = (struct libcrypto_session *) + ((struct rte_cryptodev_sym_session *)_sess) + ->_private; + + if (unlikely(libcrypto_set_session_parameters( + sess, op->sym->xform) != 0)) { + rte_mempool_put(qp->sess_mp, _sess); + sess = NULL; + } else + op->sym->session = _sess; + } + } + + if (sess == NULL) + op->status = RTE_CRYPTO_OP_STATUS_INVALID_SESSION; + + return sess; +} + +/* + *------------------------------------------------------------------------------ + * Process Operations + *------------------------------------------------------------------------------ + */ + +/** Process standard libcrypto cipher encryption */ +static int +process_libcrypto_cipher_encrypt(uint8_t *src, uint8_t *dst, + uint8_t *iv, uint8_t *key, int srclen, + EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo) +{ + int dstlen, totlen; + + if (EVP_EncryptInit_ex(ctx, algo, NULL, key, iv) <= 0) + goto process_cipher_encrypt_err; + + if (EVP_EncryptUpdate(ctx, dst, &dstlen, src, srclen) <= 0) + goto process_cipher_encrypt_err; + + if (EVP_EncryptFinal_ex(ctx, dst + dstlen, &totlen) <= 0) + goto process_cipher_encrypt_err; + + return 0; + +process_cipher_encrypt_err: + LIBCRYPTO_LOG_ERR("Process libcrypto cipher encrypt failed"); + return -EINVAL; +} + +/** Process standard libcrypto cipher decryption */ +static int +process_libcrypto_cipher_decrypt(uint8_t *src, uint8_t *dst, + uint8_t *iv, uint8_t *key, int srclen, + EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo) +{ + int dstlen, totlen; + + if (EVP_DecryptInit_ex(ctx, algo, NULL, key, iv) <= 0) + goto process_cipher_decrypt_err; + + if (EVP_CIPHER_CTX_set_padding(ctx, 0) <= 0) + goto process_cipher_decrypt_err; + + if (EVP_DecryptUpdate(ctx, dst, &dstlen, src, srclen) <= 0) + goto process_cipher_decrypt_err; + + if (EVP_DecryptFinal_ex(ctx, dst + dstlen, &totlen) <= 0) + goto process_cipher_decrypt_err; + + return 0; + +process_cipher_decrypt_err: + LIBCRYPTO_LOG_ERR("Process libcrypto cipher decrypt failed"); + return -EINVAL; +} + +/** Process cipher des 3 ctr encryption, decryption algorithm */ +static int +process_libcrypto_cipher_des3ctr(uint8_t *src, uint8_t *dst, + uint8_t *iv, uint8_t *key, int srclen, EVP_CIPHER_CTX *ctx) +{ + uint8_t ebuf[8], ctr[8]; + int unused, n; + + /* We use 3DES encryption also for decryption. + * IV is not important for 3DES ecb + */ + if (EVP_EncryptInit_ex(ctx, EVP_des_ede3_ecb(), NULL, key, NULL) <= 0) + goto process_cipher_des3ctr_err; + + memcpy(ctr, iv, 8); + n = 0; + + while (n < srclen) { + if (n % 8 == 0) { + if (EVP_EncryptUpdate(ctx, + (unsigned char *)&ebuf, &unused, + (const unsigned char *)&ctr, 8) <= 0) + goto process_cipher_des3ctr_err; + ctr_inc(ctr); + } + dst[n] = src[n] ^ ebuf[n % 8]; + n++; + } + + return 0; + +process_cipher_des3ctr_err: + LIBCRYPTO_LOG_ERR("Process libcrypto cipher des 3 ede ctr failed"); + return -EINVAL; +} + +/** Process auth/encription aes-gcm algorithm */ +static int +process_libcrypto_auth_encryption_gcm(uint8_t *src, int srclen, + uint8_t *aad, int aadlen, uint8_t *iv, int ivlen, + uint8_t *key, uint8_t *dst, uint8_t *tag, + EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo) +{ + int len = 0, unused = 0; + uint8_t empty[] = {}; + + if (EVP_EncryptInit_ex(ctx, algo, NULL, NULL, NULL) <= 0) + goto process_auth_encryption_gcm_err; + + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, NULL) <= 0) + goto process_auth_encryption_gcm_err; + + if (EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv) <= 0) + goto process_auth_encryption_gcm_err; + + if (aadlen > 0) { + if (EVP_EncryptUpdate(ctx, NULL, &len, aad, aadlen) <= 0) + goto process_auth_encryption_gcm_err; + + /* Workaround open ssl bug in version less then 1.0.1f */ + if (EVP_EncryptUpdate(ctx, empty, &unused, empty, 0) <= 0) + goto process_auth_encryption_gcm_err; + } + + if (srclen > 0) + if (EVP_EncryptUpdate(ctx, dst, &len, src, srclen) <= 0) + goto process_auth_encryption_gcm_err; + + if (EVP_EncryptFinal_ex(ctx, dst + len, &len) <= 0) + goto process_auth_encryption_gcm_err; + + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag) <= 0) + goto process_auth_encryption_gcm_err; + + return 0; + +process_auth_encryption_gcm_err: + LIBCRYPTO_LOG_ERR("Process libcrypto auth encryption gcm failed"); + return -EINVAL; +} + +static int +process_libcrypto_auth_decryption_gcm(uint8_t *src, int srclen, + uint8_t *aad, int aadlen, uint8_t *iv, int ivlen, + uint8_t *key, uint8_t *dst, uint8_t *tag, + EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo) +{ + int len = 0, unused = 0; + uint8_t empty[] = {}; + + if (EVP_DecryptInit_ex(ctx, algo, NULL, NULL, NULL) <= 0) + goto process_auth_decryption_gcm_err; + + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, NULL) <= 0) + goto process_auth_decryption_gcm_err; + + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag) <= 0) + goto process_auth_decryption_gcm_err; + + if (EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv) <= 0) + goto process_auth_decryption_gcm_err; + + if (aadlen > 0) { + if (EVP_DecryptUpdate(ctx, NULL, &len, aad, aadlen) <= 0) + goto process_auth_decryption_gcm_err; + + /* Workaround open ssl bug in version less then 1.0.1f */ + if (EVP_DecryptUpdate(ctx, empty, &unused, empty, 0) <= 0) + goto process_auth_decryption_gcm_err; + } + + if (srclen > 0) + if (EVP_DecryptUpdate(ctx, dst, &len, src, srclen) <= 0) + goto process_auth_decryption_gcm_err; + + if (EVP_DecryptFinal_ex(ctx, dst + len, &len) <= 0) + goto process_auth_decryption_gcm_final_err; + + return 0; + +process_auth_decryption_gcm_err: + LIBCRYPTO_LOG_ERR("Process libcrypto auth description gcm failed"); + return -EINVAL; + +process_auth_decryption_gcm_final_err: + return -EFAULT; +} + +/** Process standard libcrypto auth algorithms */ +static int +process_libcrypto_auth(uint8_t *src, uint8_t *dst, + __rte_unused uint8_t *iv, __rte_unused EVP_PKEY * pkey, + int srclen, EVP_MD_CTX *ctx, const EVP_MD *algo) +{ + size_t dstlen; + + if (EVP_DigestInit_ex(ctx, algo, NULL) <= 0) + goto process_auth_err; + + if (EVP_DigestUpdate(ctx, (char *)src, srclen) <= 0) + goto process_auth_err; + + if (EVP_DigestFinal_ex(ctx, dst, (unsigned int *)&dstlen) <= 0) + goto process_auth_err; + + return 0; + +process_auth_err: + LIBCRYPTO_LOG_ERR("Process libcrypto auth failed"); + return -EINVAL; +} + +/** Process standard libcrypto auth algorithms with hmac */ +static int +process_libcrypto_auth_hmac(uint8_t *src, uint8_t *dst, + __rte_unused uint8_t *iv, EVP_PKEY *pkey, + int srclen, EVP_MD_CTX *ctx, const EVP_MD *algo) +{ + size_t dstlen; + + if (EVP_DigestSignInit(ctx, NULL, algo, NULL, pkey) <= 0) + goto process_auth_err; + + if (EVP_DigestSignUpdate(ctx, (char *)src, srclen) <= 0) + goto process_auth_err; + + if (EVP_DigestSignFinal(ctx, dst, &dstlen) <= 0) + goto process_auth_err; + + return 0; + +process_auth_err: + LIBCRYPTO_LOG_ERR("Process libcrypto auth failed"); + return -EINVAL; +} + +/*----------------------------------------------------------------------------*/ + +/** Process auth/cipher combined operation */ +static void +process_libcrypto_combined_op + (struct rte_crypto_op *op, struct libcrypto_session *sess, + struct rte_mbuf *mbuf_src, struct rte_mbuf *mbuf_dst) +{ + /* cipher */ + uint8_t *src = NULL, *dst = NULL, *iv, *tag, *aad; + int srclen, ivlen, aadlen, status = -1; + + iv = op->sym->cipher.iv.data; + ivlen = op->sym->cipher.iv.length; + aad = op->sym->auth.aad.data; + aadlen = op->sym->auth.aad.length; + + tag = op->sym->auth.digest.data; + if (tag == NULL) + tag = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *, + op->sym->cipher.data.offset + + op->sym->cipher.data.length); + + if (sess->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) + srclen = 0; + else { + srclen = op->sym->cipher.data.length; + src = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *, + op->sym->cipher.data.offset); + dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *, + op->sym->cipher.data.offset); + } + + if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) + status = process_libcrypto_auth_encryption_gcm( + src, srclen, aad, aadlen, iv, ivlen, + sess->cipher.key.data, dst, tag, + sess->cipher.ctx, sess->cipher.evp_algo); + else + status = process_libcrypto_auth_decryption_gcm( + src, srclen, aad, aadlen, iv, ivlen, + sess->cipher.key.data, dst, tag, + sess->cipher.ctx, sess->cipher.evp_algo); + + if (status != 0) { + if (status == (-EFAULT) && + sess->auth.operation == + RTE_CRYPTO_AUTH_OP_VERIFY) + op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED; + else + op->status = RTE_CRYPTO_OP_STATUS_ERROR; + } +} + +/** Process cipher operation */ +static void +process_libcrypto_cipher_op + (struct rte_crypto_op *op, struct libcrypto_session *sess, + struct rte_mbuf *mbuf_src, struct rte_mbuf *mbuf_dst) +{ + uint8_t *src, *dst, *iv; + int srclen, status; + + srclen = op->sym->cipher.data.length; + src = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *, + op->sym->cipher.data.offset); + dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *, + op->sym->cipher.data.offset); + + iv = op->sym->cipher.iv.data; + + if (sess->cipher.mode == LIBCRYPTO_CIPHER_LIB) + if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) + status = process_libcrypto_cipher_encrypt(src, dst, iv, + sess->cipher.key.data, srclen, + sess->cipher.ctx, + sess->cipher.evp_algo); + else + status = process_libcrypto_cipher_decrypt(src, dst, iv, + sess->cipher.key.data, srclen, + sess->cipher.ctx, + sess->cipher.evp_algo); + else + status = process_libcrypto_cipher_des3ctr(src, dst, iv, + sess->cipher.key.data, srclen, + sess->cipher.ctx); + + if (status != 0) + op->status = RTE_CRYPTO_OP_STATUS_ERROR; +} + +/** Process auth operation */ +static void +process_libcrypto_auth_op + (struct rte_crypto_op *op, struct libcrypto_session *sess, + struct rte_mbuf *mbuf_src, struct rte_mbuf *mbuf_dst) +{ + uint8_t *src, *dst; + int srclen, status; + + srclen = op->sym->auth.data.length; + src = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *, + op->sym->auth.data.offset); + + if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY) + dst = (uint8_t *)rte_pktmbuf_append(mbuf_src, + op->sym->auth.digest.length); + else { + dst = op->sym->auth.digest.data; + if (dst == NULL) + dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *, + op->sym->auth.data.offset + + op->sym->auth.data.length); + } + + switch (sess->auth.mode) { + case LIBCRYPTO_AUTH_AS_AUTH: + status = process_libcrypto_auth(src, dst, + NULL, NULL, srclen, + sess->auth.auth.ctx, sess->auth.auth.evp_algo); + break; + case LIBCRYPTO_AUTH_AS_HMAC: + status = process_libcrypto_auth_hmac(src, dst, + NULL, sess->auth.hmac.pkey, srclen, + sess->auth.hmac.ctx, sess->auth.hmac.evp_algo); + break; + default: + status = -1; + break; + } + + if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY) { + if (memcmp(dst, op->sym->auth.digest.data, + op->sym->auth.digest.length) != 0) { + op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED; + } + /* Trim area used for digest from mbuf. */ + rte_pktmbuf_trim(mbuf_src, + op->sym->auth.digest.length); + } + + if (status != 0) + op->status = RTE_CRYPTO_OP_STATUS_ERROR; +} + +/** Process crypto operation for mbuf */ +static int +process_op(const struct libcrypto_qp *qp, struct rte_crypto_op *op, + struct libcrypto_session *sess) +{ + struct rte_mbuf *msrc, *mdst; + int retval; + + msrc = op->sym->m_src; + mdst = op->sym->m_dst ? op->sym->m_dst : op->sym->m_src; + + op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED; + + switch (sess->chain_order) { + case LIBCRYPTO_CHAIN_ONLY_CIPHER: + process_libcrypto_cipher_op(op, sess, msrc, mdst); + break; + case LIBCRYPTO_CHAIN_ONLY_AUTH: + process_libcrypto_auth_op(op, sess, msrc, mdst); + break; + case LIBCRYPTO_CHAIN_CIPHER_AUTH: + process_libcrypto_cipher_op(op, sess, msrc, mdst); + process_libcrypto_auth_op(op, sess, mdst, mdst); + break; + case LIBCRYPTO_CHAIN_AUTH_CIPHER: + process_libcrypto_auth_op(op, sess, msrc, mdst); + process_libcrypto_cipher_op(op, sess, msrc, mdst); + break; + case LIBCRYPTO_CHAIN_COMBINED: + process_libcrypto_combined_op(op, sess, msrc, mdst); + break; + default: + op->status = RTE_CRYPTO_OP_STATUS_ERROR; + break; + } + + /* Free session if a session-less crypto op */ + if (op->sym->sess_type == RTE_CRYPTO_SYM_OP_SESSIONLESS) { + libcrypto_reset_session(sess); + memset(sess, 0, sizeof(struct libcrypto_session)); + rte_mempool_put(qp->sess_mp, op->sym->session); + op->sym->session = NULL; + } + + + if (op->status == RTE_CRYPTO_OP_STATUS_NOT_PROCESSED) + op->status = RTE_CRYPTO_OP_STATUS_SUCCESS; + + if (op->status != RTE_CRYPTO_OP_STATUS_ERROR) + retval = rte_ring_enqueue(qp->processed_ops, (void *)op); + else + retval = -1; + + return retval; +} + +/* + *------------------------------------------------------------------------------ + * PMD Framework + *------------------------------------------------------------------------------ + */ + +/** Enqueue burst */ +static uint16_t +libcrypto_pmd_enqueue_burst(void *queue_pair, struct rte_crypto_op **ops, + uint16_t nb_ops) +{ + struct libcrypto_session *sess; + struct libcrypto_qp *qp = queue_pair; + int i, retval; + + for (i = 0; i < nb_ops; i++) { + sess = get_session(qp, ops[i]); + if (unlikely(sess == NULL)) + goto enqueue_err; + + retval = process_op(qp, ops[i], sess); + if (unlikely(retval < 0)) + goto enqueue_err; + } + + qp->stats.enqueued_count += i; + return i; + +enqueue_err: + qp->stats.enqueue_err_count++; + return i; +} + +/** Dequeue burst */ +static uint16_t +libcrypto_pmd_dequeue_burst(void *queue_pair, struct rte_crypto_op **ops, + uint16_t nb_ops) +{ + struct libcrypto_qp *qp = queue_pair; + + unsigned int nb_dequeued = 0; + + nb_dequeued = rte_ring_dequeue_burst(qp->processed_ops, + (void **)ops, nb_ops); + qp->stats.dequeued_count += nb_dequeued; + + return nb_dequeued; +} + +/** Create LIBCRYPTO crypto device */ +static int +cryptodev_libcrypto_create(const char *name, + struct rte_crypto_vdev_init_params *init_params) +{ + struct rte_cryptodev *dev; + char crypto_dev_name[RTE_CRYPTODEV_NAME_MAX_LEN]; + struct libcrypto_private *internals; + + /* create a unique device name */ + if (create_unique_device_name(crypto_dev_name, + RTE_CRYPTODEV_NAME_MAX_LEN) != 0) { + LIBCRYPTO_LOG_ERR("failed to create unique cryptodev name"); + return -EINVAL; + } + + dev = rte_cryptodev_pmd_virtual_dev_init(crypto_dev_name, + sizeof(struct libcrypto_private), + init_params->socket_id); + if (dev == NULL) { + LIBCRYPTO_LOG_ERR("failed to create cryptodev vdev"); + goto init_error; + } + + dev->dev_type = RTE_CRYPTODEV_LIBCRYPTO_PMD; + dev->dev_ops = rte_libcrypto_pmd_ops; + + /* register rx/tx burst functions for data path */ + dev->dequeue_burst = libcrypto_pmd_dequeue_burst; + dev->enqueue_burst = libcrypto_pmd_enqueue_burst; + + dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO | + RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING | + RTE_CRYPTODEV_FF_CPU_AESNI; + + /* Set vector instructions mode supported */ + internals = dev->data->dev_private; + + internals->max_nb_qpairs = init_params->max_nb_queue_pairs; + internals->max_nb_sessions = init_params->max_nb_sessions; + + return 0; + +init_error: + LIBCRYPTO_LOG_ERR("driver %s: cryptodev_libcrypto_create failed", name); + + cryptodev_libcrypto_uninit(crypto_dev_name); + return -EFAULT; +} + +/** Initialise LIBCRYPTO crypto device */ +static int +cryptodev_libcrypto_init(const char *name, + const char *input_args) +{ + struct rte_crypto_vdev_init_params init_params = { + RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_QUEUE_PAIRS, + RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_SESSIONS, + rte_socket_id() + }; + + rte_cryptodev_parse_vdev_init_params(&init_params, input_args); + + RTE_LOG(INFO, PMD, "Initialising %s on NUMA node %d\n", name, + init_params.socket_id); + RTE_LOG(INFO, PMD, " Max number of queue pairs = %d\n", + init_params.max_nb_queue_pairs); + RTE_LOG(INFO, PMD, " Max number of sessions = %d\n", + init_params.max_nb_sessions); + + return cryptodev_libcrypto_create(name, &init_params); +} + +/** Uninitialise LIBCRYPTO crypto device */ +static int +cryptodev_libcrypto_uninit(const char *name) +{ + if (name == NULL) + return -EINVAL; + + RTE_LOG(INFO, PMD, + "Closing LIBCRYPTO crypto device %s on numa socket %u\n", + name, rte_socket_id()); + + return 0; +} + +static struct rte_driver cryptodev_libcrypto_pmd_drv = { + .type = PMD_VDEV, + .init = cryptodev_libcrypto_init, + .uninit = cryptodev_libcrypto_uninit +}; + +PMD_REGISTER_DRIVER(cryptodev_libcrypto_pmd_drv, CRYPTODEV_NAME_LIBCRYPTO_PMD); +DRIVER_REGISTER_PARAM_STRING(CRYPTODEV_NAME_LIBCRYPTO_PMD, + "max_nb_queue_pairs=<int> " + "max_nb_sessions=<int> " + "socket_id=<int>"); diff --git a/drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c b/drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c new file mode 100644 index 0000000..b5d7bd5 --- /dev/null +++ b/drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c @@ -0,0 +1,708 @@ +/*- + * 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 <string.h> + +#include <rte_common.h> +#include <rte_malloc.h> +#include <rte_cryptodev_pmd.h> + +#include "rte_libcrypto_pmd_private.h" + + +static const struct rte_cryptodev_capabilities libcrypto_pmd_capabilities[] = { + { /* MD5 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_MD5_HMAC, + .block_size = 64, + .key_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .digest_size = { + .min = 16, + .max = 16, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* MD5 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_MD5, + .block_size = 64, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 16, + .max = 16, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA1 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .block_size = 64, + .key_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .digest_size = { + .min = 20, + .max = 20, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA1 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA1, + .block_size = 64, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 20, + .max = 20, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA224 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA224_HMAC, + .block_size = 64, + .key_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .digest_size = { + .min = 28, + .max = 28, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA224 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA224, + .block_size = 64, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 28, + .max = 28, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA256 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA256_HMAC, + .block_size = 64, + .key_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .digest_size = { + .min = 32, + .max = 32, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA256 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA256, + .block_size = 64, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 32, + .max = 32, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA384 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA384_HMAC, + .block_size = 128, + .key_size = { + .min = 128, + .max = 128, + .increment = 0 + }, + .digest_size = { + .min = 48, + .max = 48, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA384 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA384, + .block_size = 128, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 48, + .max = 48, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA512 HMAC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA512_HMAC, + .block_size = 128, + .key_size = { + .min = 128, + .max = 128, + .increment = 0 + }, + .digest_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* SHA512 */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_SHA512, + .block_size = 128, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 64, + .max = 64, + .increment = 0 + }, + .aad_size = { 0 } + }, } + }, } + }, + { /* AES CBC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, + {.cipher = { + .algo = RTE_CRYPTO_CIPHER_AES_CBC, + .block_size = 16, + .key_size = { + .min = 16, + .max = 32, + .increment = 8 + }, + .iv_size = { + .min = 16, + .max = 16, + .increment = 0 + } + }, } + }, } + }, + { /* AES CTR */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, + {.cipher = { + .algo = RTE_CRYPTO_CIPHER_AES_CTR, + .block_size = 16, + .key_size = { + .min = 16, + .max = 32, + .increment = 8 + }, + .iv_size = { + .min = 16, + .max = 16, + .increment = 0 + } + }, } + }, } + }, + { /* AES GCM (AUTH) */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_AES_GCM, + .block_size = 16, + .key_size = { + .min = 16, + .max = 32, + .increment = 8 + }, + .digest_size = { + .min = 16, + .max = 16, + .increment = 0 + }, + .aad_size = { + .min = 8, + .max = 12, + .increment = 4 + } + }, } + }, } + }, + { /* AES GCM (CIPHER) */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, + {.cipher = { + .algo = RTE_CRYPTO_CIPHER_AES_GCM, + .block_size = 16, + .key_size = { + .min = 16, + .max = 16, + .increment = 0 + }, + .iv_size = { + .min = 12, + .max = 16, + .increment = 4 + } + }, } + }, } + }, + { /* AES GMAC (AUTH) */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_AES_GMAC, + .block_size = 16, + .key_size = { + .min = 16, + .max = 32, + .increment = 8 + }, + .digest_size = { + .min = 16, + .max = 16, + .increment = 0 + }, + .aad_size = { + .min = 8, + .max = 65532, + .increment = 4 + } + }, } + }, } + }, + { /* 3DES CBC */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, + {.cipher = { + .algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .block_size = 8, + .key_size = { + .min = 16, + .max = 24, + .increment = 8 + }, + .iv_size = { + .min = 8, + .max = 8, + .increment = 0 + } + }, } + }, } + }, + { /* 3DES CTR */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, + {.cipher = { + .algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .block_size = 8, + .key_size = { + .min = 16, + .max = 24, + .increment = 8 + }, + .iv_size = { + .min = 8, + .max = 8, + .increment = 0 + } + }, } + }, } + }, + + RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST() +}; + + +/** Configure device */ +static int +libcrypto_pmd_config(__rte_unused struct rte_cryptodev *dev) +{ + return 0; +} + +/** Start device */ +static int +libcrypto_pmd_start(__rte_unused struct rte_cryptodev *dev) +{ + return 0; +} + +/** Stop device */ +static void +libcrypto_pmd_stop(__rte_unused struct rte_cryptodev *dev) +{ +} + +/** Close device */ +static int +libcrypto_pmd_close(__rte_unused struct rte_cryptodev *dev) +{ + return 0; +} + + +/** Get device statistics */ +static void +libcrypto_pmd_stats_get(struct rte_cryptodev *dev, + struct rte_cryptodev_stats *stats) +{ + int qp_id; + + for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) { + struct libcrypto_qp *qp = dev->data->queue_pairs[qp_id]; + + stats->enqueued_count += qp->stats.enqueued_count; + stats->dequeued_count += qp->stats.dequeued_count; + + stats->enqueue_err_count += qp->stats.enqueue_err_count; + stats->dequeue_err_count += qp->stats.dequeue_err_count; + } +} + +/** Reset device statistics */ +static void +libcrypto_pmd_stats_reset(struct rte_cryptodev *dev) +{ + int qp_id; + + for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) { + struct libcrypto_qp *qp = dev->data->queue_pairs[qp_id]; + + memset(&qp->stats, 0, sizeof(qp->stats)); + } +} + + +/** Get device info */ +static void +libcrypto_pmd_info_get(struct rte_cryptodev *dev, + struct rte_cryptodev_info *dev_info) +{ + struct libcrypto_private *internals = dev->data->dev_private; + + if (dev_info != NULL) { + dev_info->dev_type = dev->dev_type; + dev_info->feature_flags = dev->feature_flags; + dev_info->capabilities = libcrypto_pmd_capabilities; + dev_info->max_nb_queue_pairs = internals->max_nb_qpairs; + dev_info->sym.max_nb_sessions = internals->max_nb_sessions; + } +} + +/** Release queue pair */ +static int +libcrypto_pmd_qp_release(struct rte_cryptodev *dev, uint16_t qp_id) +{ + if (dev->data->queue_pairs[qp_id] != NULL) { + rte_free(dev->data->queue_pairs[qp_id]); + dev->data->queue_pairs[qp_id] = NULL; + } + return 0; +} + +/** set a unique name for the queue pair based on it's name, dev_id and qp_id */ +static int +libcrypto_pmd_qp_set_unique_name(struct rte_cryptodev *dev, + struct libcrypto_qp *qp) +{ + unsigned int n = snprintf(qp->name, sizeof(qp->name), + "libcrypto_pmd_%u_qp_%u", + dev->data->dev_id, qp->id); + + if (n > sizeof(qp->name)) + return -1; + + return 0; +} + + +/** Create a ring to place processed operations on */ +static struct rte_ring * +libcrypto_pmd_qp_create_processed_ops_ring(struct libcrypto_qp *qp, + unsigned int ring_size, int socket_id) +{ + struct rte_ring *r; + + r = rte_ring_lookup(qp->name); + if (r) { + if (r->prod.size >= ring_size) { + LIBCRYPTO_LOG_INFO( + "Reusing existing ring %s for processed ops", + qp->name); + return r; + } + + LIBCRYPTO_LOG_ERR( + "Unable to reuse existing ring %s for processed ops", + qp->name); + return NULL; + } + + return rte_ring_create(qp->name, ring_size, socket_id, + RING_F_SP_ENQ | RING_F_SC_DEQ); +} + + +/** Setup a queue pair */ +static int +libcrypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id, + const struct rte_cryptodev_qp_conf *qp_conf, + int socket_id) +{ + struct libcrypto_qp *qp = NULL; + + /* Free memory prior to re-allocation if needed. */ + if (dev->data->queue_pairs[qp_id] != NULL) + libcrypto_pmd_qp_release(dev, qp_id); + + /* Allocate the queue pair data structure. */ + qp = rte_zmalloc_socket("LIBCRYPTO PMD Queue Pair", sizeof(*qp), + RTE_CACHE_LINE_SIZE, socket_id); + if (qp == NULL) + return -ENOMEM; + + qp->id = qp_id; + dev->data->queue_pairs[qp_id] = qp; + + if (libcrypto_pmd_qp_set_unique_name(dev, qp)) + goto qp_setup_cleanup; + + qp->processed_ops = libcrypto_pmd_qp_create_processed_ops_ring(qp, + qp_conf->nb_descriptors, socket_id); + if (qp->processed_ops == NULL) + goto qp_setup_cleanup; + + qp->sess_mp = dev->data->session_pool; + + memset(&qp->stats, 0, sizeof(qp->stats)); + + return 0; + +qp_setup_cleanup: + if (qp) + rte_free(qp); + + return -1; +} + +/** Start queue pair */ +static int +libcrypto_pmd_qp_start(__rte_unused struct rte_cryptodev *dev, + __rte_unused uint16_t queue_pair_id) +{ + return -ENOTSUP; +} + +/** Stop queue pair */ +static int +libcrypto_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev, + __rte_unused uint16_t queue_pair_id) +{ + return -ENOTSUP; +} + +/** Return the number of allocated queue pairs */ +static uint32_t +libcrypto_pmd_qp_count(struct rte_cryptodev *dev) +{ + return dev->data->nb_queue_pairs; +} + +/** Returns the size of the session structure */ +static unsigned +libcrypto_pmd_session_get_size(struct rte_cryptodev *dev __rte_unused) +{ + return sizeof(struct libcrypto_session); +} + +/** Configure the session from a crypto xform chain */ +static void * +libcrypto_pmd_session_configure(struct rte_cryptodev *dev __rte_unused, + struct rte_crypto_sym_xform *xform, void *sess) +{ + if (unlikely(sess == NULL)) { + LIBCRYPTO_LOG_ERR("invalid session struct"); + return NULL; + } + + if (libcrypto_set_session_parameters( + sess, xform) != 0) { + LIBCRYPTO_LOG_ERR("failed configure session parameters"); + return NULL; + } + + return sess; +} + + +/** Clear the memory of session so it doesn't leave key material behind */ +static void +libcrypto_pmd_session_clear(struct rte_cryptodev *dev __rte_unused, void *sess) +{ + /* + * Current just resetting the whole data structure, need to investigate + * whether a more selective reset of key would be more performant + */ + if (sess) { + libcrypto_reset_session(sess); + memset(sess, 0, sizeof(struct libcrypto_session)); + } +} + +struct rte_cryptodev_ops libcrypto_pmd_ops = { + .dev_configure = libcrypto_pmd_config, + .dev_start = libcrypto_pmd_start, + .dev_stop = libcrypto_pmd_stop, + .dev_close = libcrypto_pmd_close, + + .stats_get = libcrypto_pmd_stats_get, + .stats_reset = libcrypto_pmd_stats_reset, + + .dev_infos_get = libcrypto_pmd_info_get, + + .queue_pair_setup = libcrypto_pmd_qp_setup, + .queue_pair_release = libcrypto_pmd_qp_release, + .queue_pair_start = libcrypto_pmd_qp_start, + .queue_pair_stop = libcrypto_pmd_qp_stop, + .queue_pair_count = libcrypto_pmd_qp_count, + + .session_get_size = libcrypto_pmd_session_get_size, + .session_configure = libcrypto_pmd_session_configure, + .session_clear = libcrypto_pmd_session_clear +}; + +struct rte_cryptodev_ops *rte_libcrypto_pmd_ops = &libcrypto_pmd_ops; diff --git a/drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h b/drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h new file mode 100644 index 0000000..dbef57f --- /dev/null +++ b/drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h @@ -0,0 +1,174 @@ +/*- + * 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 _LIBCRYPTO_PMD_PRIVATE_H_ +#define _LIBCRYPTO_PMD_PRIVATE_H_ + +#include <openssl/evp.h> +#include <openssl/des.h> + + +#define LIBCRYPTO_LOG_ERR(fmt, args...) \ + RTE_LOG(ERR, CRYPTODEV, "[%s] %s() line %u: " fmt "\n", \ + RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), \ + __func__, __LINE__, ## args) + +#ifdef RTE_LIBRTE_LIBCRYPTO_DEBUG +#define LIBCRYPTO_LOG_INFO(fmt, args...) \ + RTE_LOG(INFO, CRYPTODEV, "[%s] %s() line %u: " fmt "\n", \ + RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), \ + __func__, __LINE__, ## args) + +#define LIBCRYPTO_LOG_DBG(fmt, args...) \ + RTE_LOG(DEBUG, CRYPTODEV, "[%s] %s() line %u: " fmt "\n", \ + RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), \ + __func__, __LINE__, ## args) +#else +#define LIBCRYPTO_LOG_INFO(fmt, args...) +#define LIBCRYPTO_LOG_DBG(fmt, args...) +#endif + + +/** LIBCRYPTO operation order mode enumerator */ +enum libcrypto_chain_order { + LIBCRYPTO_CHAIN_ONLY_CIPHER, + LIBCRYPTO_CHAIN_ONLY_AUTH, + LIBCRYPTO_CHAIN_CIPHER_AUTH, + LIBCRYPTO_CHAIN_AUTH_CIPHER, + LIBCRYPTO_CHAIN_COMBINED, + LIBCRYPTO_CHAIN_NOT_SUPPORTED +}; + +/** LIBCRYPTO cipher mode enumerator */ +enum libcrypto_cipher_mode { + LIBCRYPTO_CIPHER_LIB, + LIBCRYPTO_CIPHER_DES3CTR, +}; + +/** LIBCRYPTO auth mode enumerator */ +enum libcrypto_auth_mode { + LIBCRYPTO_AUTH_AS_AUTH, + LIBCRYPTO_AUTH_AS_HMAC, +}; + +/** private data structure for each LIBCRYPTO crypto device */ +struct libcrypto_private { + unsigned int max_nb_qpairs; + /**< Max number of queue pairs */ + unsigned int max_nb_sessions; + /**< Max number of sessions */ +}; + +/** LIBCRYPTO crypto queue pair */ +struct libcrypto_qp { + uint16_t id; + /**< Queue Pair Identifier */ + char name[RTE_CRYPTODEV_NAME_LEN]; + /**< Unique Queue Pair Name */ + struct rte_ring *processed_ops; + /**< Ring for placing process packets */ + struct rte_mempool *sess_mp; + /**< Session Mempool */ + struct rte_cryptodev_stats stats; + /**< Queue pair statistics */ +} __rte_cache_aligned; + +/** LIBCRYPTO crypto private session structure */ +struct libcrypto_session { + enum libcrypto_chain_order chain_order; + /**< chain order mode */ + + /** Cipher Parameters */ + struct { + enum rte_crypto_cipher_operation direction; + /**< cipher operation direction */ + enum libcrypto_cipher_mode mode; + /**< cipher operation mode */ + enum rte_crypto_cipher_algorithm algo; + /**< cipher algorithm */ + + struct { + uint8_t data[32]; + /**< key data */ + size_t length; + /**< key length in bytes */ + } key; + + const EVP_CIPHER *evp_algo; + /**< pointer to EVP algorithm function */ + EVP_CIPHER_CTX *ctx; + /**< pointer to EVP context structure */ + } cipher; + + /** Authentication Parameters */ + struct { + enum rte_crypto_auth_operation operation; + /**< auth operation generate or verify */ + enum libcrypto_auth_mode mode; + /**< auth operation mode */ + enum rte_crypto_auth_algorithm algo; + /**< cipher algorithm */ + + union { + struct { + const EVP_MD *evp_algo; + /**< pointer to EVP algorithm function */ + EVP_MD_CTX *ctx; + /**< pointer to EVP context structure */ + } auth; + + struct { + EVP_PKEY *pkey; + /**< pointer to EVP key */ + const EVP_MD *evp_algo; + /**< pointer to EVP algorithm function */ + EVP_MD_CTX *ctx; + /**< pointer to EVP context structure */ + } hmac; + }; + } auth; + +} __rte_cache_aligned; + +/** Set and validate LIBCRYPTO crypto session parameters */ +extern int +libcrypto_set_session_parameters(struct libcrypto_session *sess, + const struct rte_crypto_sym_xform *xform); + +/** Reset LIBCRYPTO crypto session parameters */ +extern void +libcrypto_reset_session(struct libcrypto_session *sess); + +/** device specific operations function pointer structure */ +extern struct rte_cryptodev_ops *rte_libcrypto_pmd_ops; + +#endif /* _LIBCRYPTO_PMD_PRIVATE_H_ */ diff --git a/drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map b/drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map new file mode 100644 index 0000000..cc5829e --- /dev/null +++ b/drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map @@ -0,0 +1,3 @@ +DPDK_16.11 { + local: *; +}; diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h index b1658eb..311fd78 100644 --- a/lib/librte_cryptodev/rte_cryptodev.h +++ b/lib/librte_cryptodev/rte_cryptodev.h @@ -56,6 +56,8 @@ extern "C" { /**< AES-NI Multi buffer PMD device name */ #define CRYPTODEV_NAME_AESNI_GCM_PMD crypto_aesni_gcm /**< AES-NI GCM PMD device name */ +#define CRYPTODEV_NAME_LIBCRYPTO_PMD cryptodev_libcrypto +/**< Open SSL Crypto PMD device name */ #define CRYPTODEV_NAME_QAT_SYM_PMD crypto_qat /**< Intel QAT Symmetric Crypto PMD device name */ #define CRYPTODEV_NAME_SNOW3G_PMD crypto_snow3g @@ -73,7 +75,8 @@ enum rte_cryptodev_type { RTE_CRYPTODEV_QAT_SYM_PMD, /**< QAT PMD Symmetric Crypto */ RTE_CRYPTODEV_SNOW3G_PMD, /**< SNOW 3G PMD */ RTE_CRYPTODEV_KASUMI_PMD, /**< KASUMI PMD */ - RTE_CRYPTODEV_ZUC_PMD /**< ZUC PMD */ + RTE_CRYPTODEV_ZUC_PMD, /**< ZUC PMD */ + RTE_CRYPTODEV_LIBCRYPTO_PMD, /**< LibCrypto PMD */ }; extern const char **rte_cyptodev_names; diff --git a/mk/rte.app.mk b/mk/rte.app.mk index 440bf83..43ea1c1 100644 --- a/mk/rte.app.mk +++ b/mk/rte.app.mk @@ -131,18 +131,19 @@ endif # $(CONFIG_RTE_LIBRTE_VHOST) _LDLIBS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += -lrte_pmd_vmxnet3_uio ifeq ($(CONFIG_RTE_LIBRTE_CRYPTODEV),y) -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -lrte_pmd_aesni_mb -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += -lrte_pmd_aesni_gcm -lcrypto -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -lrte_pmd_aesni_mb +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += -lrte_pmd_aesni_gcm -lcrypto +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += -lrte_pmd_libcrypto -lcrypto _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO) += -lrte_pmd_null_crypto -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += -lrte_pmd_qat -lcrypto -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += -lrte_pmd_snow3g -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += -L$(LIBSSO_SNOW3G_PATH)/build -lsso_snow3g -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI) += -lrte_pmd_kasumi -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI) += -L$(LIBSSO_KASUMI_PATH)/build -lsso_kasumi -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_ZUC) += -lrte_pmd_zuc -_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_ZUC) += -L$(LIBSSO_ZUC_PATH)/build -lsso_zuc +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += -lrte_pmd_qat -lcrypto +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += -lrte_pmd_snow3g +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += -L$(LIBSSO_SNOW3G_PATH)/build -lsso_snow3g +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI) += -lrte_pmd_kasumi +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI) += -L$(LIBSSO_KASUMI_PATH)/build -lsso_kasumi +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_ZUC) += -lrte_pmd_zuc +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_ZUC) += -L$(LIBSSO_ZUC_PATH)/build -lsso_zuc endif # CONFIG_RTE_LIBRTE_CRYPTODEV endif # !CONFIG_RTE_BUILD_SHARED_LIBS -- 2.5.0 ^ permalink raw reply [flat|nested] 34+ messages in thread
* [dpdk-dev] [PATCH v6 2/4] app/test: cryptodev AES tests rework 2016-10-04 15:11 ` [dpdk-dev] [PATCH v6 " Slawomir Mrozowicz 2016-10-04 15:11 ` [dpdk-dev] [PATCH v6 1/4] libcrypto_pmd: initial implementation of SW crypto device Slawomir Mrozowicz @ 2016-10-04 15:11 ` Slawomir Mrozowicz 2016-10-04 15:11 ` [dpdk-dev] [PATCH v6 3/4] app/test: added tests for libcrypto PMD Slawomir Mrozowicz ` (2 subsequent siblings) 4 siblings, 0 replies; 34+ messages in thread From: Slawomir Mrozowicz @ 2016-10-04 15:11 UTC (permalink / raw) To: dev; +Cc: Slawomir Mrozowicz, Piotr Azarewicz, Fiona Trahe This patch rework AES tests . In general - rename AES-named functions to blockcipher functions pattern. Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com> Signed-off-by: Fiona Trahe <fiona.trahe@intel.com> --- v6: - fix checkpatch warnings --- app/test/Makefile | 2 +- app/test/test_cryptodev.c | 75 +- app/test/test_cryptodev_aes.c | 687 ----------------- app/test/test_cryptodev_aes.h | 1124 ---------------------------- app/test/test_cryptodev_aes_test_vectors.h | 797 ++++++++++++++++++++ app/test/test_cryptodev_blockcipher.c | 516 +++++++++++++ app/test/test_cryptodev_blockcipher.h | 124 +++ 7 files changed, 1486 insertions(+), 1839 deletions(-) delete mode 100644 app/test/test_cryptodev_aes.c delete mode 100644 app/test/test_cryptodev_aes.h create mode 100644 app/test/test_cryptodev_aes_test_vectors.h create mode 100644 app/test/test_cryptodev_blockcipher.c create mode 100644 app/test/test_cryptodev_blockcipher.h diff --git a/app/test/Makefile b/app/test/Makefile index 611d77a..5be023a 100644 --- a/app/test/Makefile +++ b/app/test/Makefile @@ -193,7 +193,7 @@ endif SRCS-$(CONFIG_RTE_LIBRTE_PMD_RING) += test_pmd_ring.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_RING) += test_pmd_ring_perf.c -SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_aes.c +SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_blockcipher.c SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_perf.c SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev.c diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c index 9d7caba..8f03157 100644 --- a/app/test/test_cryptodev.c +++ b/app/test/test_cryptodev.c @@ -43,7 +43,8 @@ #include "test.h" #include "test_cryptodev.h" -#include "test_cryptodev_aes.h" +#include "test_cryptodev_blockcipher.h" +#include "test_cryptodev_aes_test_vectors.h" #include "test_cryptodev_kasumi_test_vectors.h" #include "test_cryptodev_kasumi_hash_test_vectors.h" #include "test_cryptodev_snow3g_test_vectors.h" @@ -86,12 +87,16 @@ struct crypto_unittest_params { */ static int test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( - struct crypto_unittest_params *ut_params); + struct crypto_unittest_params *ut_params, uint8_t *cipher_key, + uint8_t *hmac_key); static int test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, struct crypto_unittest_params *ut_params, - struct crypto_testsuite_params *ts_param); + struct crypto_testsuite_params *ts_param, + const uint8_t *cipher, + const uint8_t *digest, + const uint8_t *iv); static struct rte_mbuf * setup_test_string(struct rte_mempool *mpool, @@ -313,7 +318,7 @@ testsuite_setup(void) nb_devs = rte_cryptodev_count(); if (nb_devs < 1) { - RTE_LOG(ERR, USER1, "No crypto devices found?"); + RTE_LOG(ERR, USER1, "No crypto devices found?\n"); return TEST_FAILED; } @@ -872,7 +877,6 @@ static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA1_digest[] = { 0x18, 0x8c, 0x1d, 0x32 }; - static int test_AES_CBC_HMAC_SHA1_encrypt_digest(void) { @@ -1003,17 +1007,24 @@ static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA512_digest[] = { static int test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( - struct crypto_unittest_params *ut_params); + struct crypto_unittest_params *ut_params, + uint8_t *cipher_key, + uint8_t *hmac_key); static int test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, struct crypto_unittest_params *ut_params, - struct crypto_testsuite_params *ts_params); + struct crypto_testsuite_params *ts_params, + const uint8_t *cipher, + const uint8_t *digest, + const uint8_t *iv); static int test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( - struct crypto_unittest_params *ut_params) + struct crypto_unittest_params *ut_params, + uint8_t *cipher_key, + uint8_t *hmac_key) { /* Setup Cipher Parameters */ @@ -1022,7 +1033,7 @@ test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC; ut_params->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT; - ut_params->cipher_xform.cipher.key.data = aes_cbc_key; + ut_params->cipher_xform.cipher.key.data = cipher_key; ut_params->cipher_xform.cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC; /* Setup HMAC Parameters */ @@ -1031,7 +1042,7 @@ test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SHA512_HMAC; - ut_params->auth_xform.auth.key.data = hmac_sha512_key; + ut_params->auth_xform.auth.key.data = hmac_key; ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA512; ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA512; @@ -1042,12 +1053,15 @@ test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( static int test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, struct crypto_unittest_params *ut_params, - struct crypto_testsuite_params *ts_params) + struct crypto_testsuite_params *ts_params, + const uint8_t *cipher, + const uint8_t *digest, + const uint8_t *iv) { /* Generate test mbuf data and digest */ ut_params->ibuf = setup_test_string(ts_params->mbuf_pool, (const char *) - catch_22_quote_2_512_bytes_AES_CBC_ciphertext, + cipher, QUOTE_512_BYTES, 0); ut_params->digest = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, @@ -1055,7 +1069,7 @@ test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, TEST_ASSERT_NOT_NULL(ut_params->digest, "no room to append digest"); rte_memcpy(ut_params->digest, - catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA512_digest, + digest, DIGEST_BYTE_LENGTH_SHA512); /* Generate Crypto op data structure */ @@ -1085,7 +1099,7 @@ test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, ut_params->ibuf, 0); sym_op->cipher.iv.length = CIPHER_IV_LENGTH_AES_CBC; - rte_memcpy(sym_op->cipher.iv.data, aes_cbc_iv, + rte_memcpy(sym_op->cipher.iv.data, iv, CIPHER_IV_LENGTH_AES_CBC); sym_op->cipher.data.offset = CIPHER_IV_LENGTH_AES_CBC; @@ -1115,14 +1129,15 @@ test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess, } static int -test_AES_mb_all(void) +test_AES_chain_mb_all(void) { struct crypto_testsuite_params *ts_params = &testsuite_params; int status; - status = test_AES_all_tests(ts_params->mbuf_pool, + status = test_blockcipher_all_tests(ts_params->mbuf_pool, ts_params->op_mpool, ts_params->valid_devs[0], - RTE_CRYPTODEV_AESNI_MB_PMD); + RTE_CRYPTODEV_AESNI_MB_PMD, + BLKCIPHER_AES_CHAIN_TYPE); TEST_ASSERT_EQUAL(status, 0, "Test failed"); @@ -1130,14 +1145,15 @@ test_AES_mb_all(void) } static int -test_AES_qat_all(void) +test_AES_chain_qat_all(void) { struct crypto_testsuite_params *ts_params = &testsuite_params; int status; - status = test_AES_all_tests(ts_params->mbuf_pool, + status = test_blockcipher_all_tests(ts_params->mbuf_pool, ts_params->op_mpool, ts_params->valid_devs[0], - RTE_CRYPTODEV_QAT_SYM_PMD); + RTE_CRYPTODEV_QAT_SYM_PMD, + BLKCIPHER_AES_CHAIN_TYPE); TEST_ASSERT_EQUAL(status, 0, "Test failed"); @@ -4024,7 +4040,8 @@ test_multi_session(void) uint16_t i; - test_AES_CBC_HMAC_SHA512_decrypt_create_session_params(ut_params); + test_AES_CBC_HMAC_SHA512_decrypt_create_session_params(ut_params, + aes_cbc_key, hmac_sha512_key); rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info); @@ -4043,10 +4060,14 @@ test_multi_session(void) i); /* Attempt to send a request on each session */ - TEST_ASSERT_SUCCESS(test_AES_CBC_HMAC_SHA512_decrypt_perform( - sessions[i], ut_params, ts_params), - "Failed to perform decrypt on request " - "number %u.", i); + TEST_ASSERT_SUCCESS( test_AES_CBC_HMAC_SHA512_decrypt_perform( + sessions[i], + ut_params, + ts_params, + catch_22_quote_2_512_bytes_AES_CBC_ciphertext, + catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA512_digest, + aes_cbc_iv), + "Failed to perform decrypt on request number %u.", i); /* free crypto operation structure */ if (ut_params->op) rte_crypto_op_free(ut_params->op); @@ -4700,7 +4721,7 @@ static struct unit_test_suite cryptodev_qat_testsuite = { TEST_CASE_ST(ut_setup, ut_teardown, test_multi_session), - TEST_CASE_ST(ut_setup, ut_teardown, test_AES_qat_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_qat_all), TEST_CASE_ST(ut_setup, ut_teardown, test_stats), /** AES GCM Authenticated Encryption */ @@ -4836,7 +4857,7 @@ static struct unit_test_suite cryptodev_aesni_mb_testsuite = { .setup = testsuite_setup, .teardown = testsuite_teardown, .unit_test_cases = { - TEST_CASE_ST(ut_setup, ut_teardown, test_AES_mb_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_mb_all), TEST_CASES_END() /**< NULL terminate unit test array */ } diff --git a/app/test/test_cryptodev_aes.c b/app/test/test_cryptodev_aes.c deleted file mode 100644 index e19c45b..0000000 --- a/app/test/test_cryptodev_aes.c +++ /dev/null @@ -1,687 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2015-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_common.h> -#include <rte_hexdump.h> -#include <rte_mbuf.h> -#include <rte_malloc.h> -#include <rte_memcpy.h> - -#include <rte_crypto.h> -#include <rte_cryptodev.h> -#include <rte_cryptodev_pmd.h> - -#include "test.h" -#include "test_cryptodev_aes.h" - -#ifndef AES_TEST_MSG_LEN -#define AES_TEST_MSG_LEN 256 -#endif - -#define AES_TEST_OP_ENCRYPT 0x01 -#define AES_TEST_OP_DECRYPT 0x02 -#define AES_TEST_OP_AUTH_GEN 0x04 -#define AES_TEST_OP_AUTH_VERIFY 0x08 - -#define AES_TEST_FEATURE_OOP 0x01 -#define AES_TEST_FEATURE_SESSIONLESS 0x02 -#define AES_TEST_FEATURE_STOPPER 0x04 /* stop upon failing */ - -#define AES_TEST_TARGET_PMD_MB 0x0001 /* Multi-buffer flag */ -#define AES_TEST_TARGET_PMD_QAT 0x0002 /* QAT flag */ - -#define AES_TEST_OP_CIPHER (AES_TEST_OP_ENCRYPT | \ - AES_TEST_OP_DECRYPT) - -#define AES_TEST_OP_AUTH (AES_TEST_OP_AUTH_GEN | \ - AES_TEST_OP_AUTH_VERIFY) - -#define AES_TEST_OP_ENC_AUTH_GEN (AES_TEST_OP_ENCRYPT | \ - AES_TEST_OP_AUTH_GEN) - -#define AES_TEST_OP_AUTH_VERIFY_DEC (AES_TEST_OP_DECRYPT | \ - AES_TEST_OP_AUTH_VERIFY) - -struct aes_test_case { - const char *test_descr; /* test description */ - const struct aes_test_data *test_data; - uint8_t op_mask; /* operation mask */ - uint8_t feature_mask; - uint32_t pmd_mask; -}; - -static const struct aes_test_case aes_test_cases[] = { - { - .test_descr = "AES-128-CTR HMAC-SHA1 Encryption Digest", - .test_data = &aes_test_data_1, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CTR HMAC-SHA1 Decryption Digest " - "Verify", - .test_data = &aes_test_data_1, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-192-CTR XCBC Encryption Digest", - .test_data = &aes_test_data_2, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-192-CTR XCBC Decryption Digest Verify", - .test_data = &aes_test_data_2, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-256-CTR HMAC-SHA1 Encryption Digest", - .test_data = &aes_test_data_3, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-256-CTR HMAC-SHA1 Decryption Digest " - "Verify", - .test_data = &aes_test_data_3, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest", - .test_data = &aes_test_data_4, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " - "Verify", - .test_data = &aes_test_data_4, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA256 Encryption Digest", - .test_data = &aes_test_data_5, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA256 Decryption Digest " - "Verify", - .test_data = &aes_test_data_5, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest", - .test_data = &aes_test_data_6, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest " - "Sessionless", - .test_data = &aes_test_data_6, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .feature_mask = AES_TEST_FEATURE_SESSIONLESS, - .pmd_mask = AES_TEST_TARGET_PMD_MB - }, - { - .test_descr = "AES-128-CBC HMAC-SHA512 Decryption Digest " - "Verify", - .test_data = &aes_test_data_6, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC XCBC Encryption Digest", - .test_data = &aes_test_data_7, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC XCBC Decryption Digest Verify", - .test_data = &aes_test_data_7, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest " - "OOP", - .test_data = &aes_test_data_4, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .feature_mask = AES_TEST_FEATURE_OOP, - .pmd_mask = AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " - "Verify OOP", - .test_data = &aes_test_data_4, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .feature_mask = AES_TEST_FEATURE_OOP, - .pmd_mask = AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA224 Encryption Digest", - .test_data = &aes_test_data_8, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA224 Decryption Digest " - "Verify", - .test_data = &aes_test_data_8, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA384 Encryption Digest", - .test_data = &aes_test_data_9, - .op_mask = AES_TEST_OP_ENC_AUTH_GEN, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, - { - .test_descr = "AES-128-CBC HMAC-SHA384 Decryption Digest " - "Verify", - .test_data = &aes_test_data_9, - .op_mask = AES_TEST_OP_AUTH_VERIFY_DEC, - .pmd_mask = AES_TEST_TARGET_PMD_MB | - AES_TEST_TARGET_PMD_QAT - }, -}; - -static int -test_AES_one_case(const struct aes_test_case *t, - struct rte_mempool *mbuf_pool, - struct rte_mempool *op_mpool, - uint8_t dev_id, - enum rte_cryptodev_type cryptodev_type, - char *test_msg) -{ - struct rte_mbuf *ibuf = NULL; - struct rte_mbuf *obuf = NULL; - struct rte_mbuf *iobuf; - struct rte_crypto_sym_xform *cipher_xform = NULL; - struct rte_crypto_sym_xform *auth_xform = NULL; - struct rte_crypto_sym_xform *init_xform = NULL; - struct rte_crypto_sym_op *sym_op = NULL; - struct rte_crypto_op *op = NULL; - struct rte_cryptodev_sym_session *sess = NULL; - - int status = TEST_SUCCESS; - const struct aes_test_data *tdata = t->test_data; - uint8_t cipher_key[tdata->cipher_key.len]; - uint8_t auth_key[tdata->auth_key.len]; - uint32_t buf_len = tdata->ciphertext.len; - uint32_t digest_len = 0; - char *buf_p = NULL; - - if (tdata->cipher_key.len) - memcpy(cipher_key, tdata->cipher_key.data, - tdata->cipher_key.len); - if (tdata->auth_key.len) - memcpy(auth_key, tdata->auth_key.data, - tdata->auth_key.len); - - switch (cryptodev_type) { - case RTE_CRYPTODEV_QAT_SYM_PMD: - digest_len = tdata->digest.len; - break; - case RTE_CRYPTODEV_AESNI_MB_PMD: - digest_len = tdata->digest.truncated_len; - break; - default: - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Unsupported PMD type"); - status = TEST_FAILED; - goto error_exit; - } - - /* preparing data */ - ibuf = rte_pktmbuf_alloc(mbuf_pool); - if (!ibuf) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Allocation of rte_mbuf failed"); - status = TEST_FAILED; - goto error_exit; - } - - if (t->op_mask & AES_TEST_OP_CIPHER) - buf_len += tdata->iv.len; - if (t->op_mask & AES_TEST_OP_AUTH) - buf_len += digest_len; - - buf_p = rte_pktmbuf_append(ibuf, buf_len); - if (!buf_p) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "No room to append mbuf"); - status = TEST_FAILED; - goto error_exit; - } - - if (t->op_mask & AES_TEST_OP_CIPHER) { - rte_memcpy(buf_p, tdata->iv.data, tdata->iv.len); - buf_p += tdata->iv.len; - } - - /* only encryption requires plaintext.data input, - * decryption/(digest gen)/(digest verify) use ciphertext.data - * to be computed */ - if (t->op_mask & AES_TEST_OP_ENCRYPT) { - rte_memcpy(buf_p, tdata->plaintext.data, - tdata->plaintext.len); - buf_p += tdata->plaintext.len; - } else { - rte_memcpy(buf_p, tdata->ciphertext.data, - tdata->ciphertext.len); - buf_p += tdata->ciphertext.len; - } - - if (t->op_mask & AES_TEST_OP_AUTH_VERIFY) - rte_memcpy(buf_p, tdata->digest.data, digest_len); - else - memset(buf_p, 0, digest_len); - - if (t->feature_mask & AES_TEST_FEATURE_OOP) { - obuf = rte_pktmbuf_alloc(mbuf_pool); - if (!obuf) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, - "Allocation of rte_mbuf failed"); - status = TEST_FAILED; - goto error_exit; - } - - buf_p = rte_pktmbuf_append(obuf, buf_len); - if (!buf_p) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, - "No room to append mbuf"); - status = TEST_FAILED; - goto error_exit; - } - memset(buf_p, 0, buf_len); - } - - /* Generate Crypto op data structure */ - op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_SYMMETRIC); - if (!op) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Failed to allocate symmetric crypto " - "operation struct"); - status = TEST_FAILED; - goto error_exit; - } - - sym_op = op->sym; - - sym_op->m_src = ibuf; - - if (t->feature_mask & AES_TEST_FEATURE_OOP) { - sym_op->m_dst = obuf; - iobuf = obuf; - } else { - sym_op->m_dst = NULL; - iobuf = ibuf; - } - - /* sessionless op requires allocate xform using - * rte_crypto_op_sym_xforms_alloc(), otherwise rte_zmalloc() - * is used */ - if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) { - uint32_t n_xforms = 0; - - if (t->op_mask & AES_TEST_OP_CIPHER) - n_xforms++; - if (t->op_mask & AES_TEST_OP_AUTH) - n_xforms++; - - if (rte_crypto_op_sym_xforms_alloc(op, n_xforms) - == NULL) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, "Failed to " - "allocate space for crypto transforms"); - status = TEST_FAILED; - goto error_exit; - } - } else { - cipher_xform = rte_zmalloc(NULL, - sizeof(struct rte_crypto_sym_xform), 0); - - auth_xform = rte_zmalloc(NULL, - sizeof(struct rte_crypto_sym_xform), 0); - - if (!cipher_xform || !auth_xform) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, "Failed to " - "allocate memory for crypto transforms"); - status = TEST_FAILED; - goto error_exit; - } - } - - /* preparing xform, for sessioned op, init_xform is initialized - * here and later as param in rte_cryptodev_sym_session_create() - * call */ - if (t->op_mask == AES_TEST_OP_ENC_AUTH_GEN) { - if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) { - cipher_xform = op->sym->xform; - auth_xform = cipher_xform->next; - auth_xform->next = NULL; - } else { - cipher_xform->next = auth_xform; - auth_xform->next = NULL; - init_xform = cipher_xform; - } - } else if (t->op_mask == AES_TEST_OP_AUTH_VERIFY_DEC) { - if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) { - auth_xform = op->sym->xform; - cipher_xform = auth_xform->next; - cipher_xform->next = NULL; - } else { - auth_xform->next = cipher_xform; - cipher_xform->next = NULL; - init_xform = auth_xform; - } - } else if ((t->op_mask == AES_TEST_OP_ENCRYPT) || - (t->op_mask == AES_TEST_OP_DECRYPT)) { - if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) - cipher_xform = op->sym->xform; - else - init_xform = cipher_xform; - cipher_xform->next = NULL; - } else if ((t->op_mask == AES_TEST_OP_AUTH_GEN) || - (t->op_mask == AES_TEST_OP_AUTH_VERIFY)) { - if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) - auth_xform = op->sym->xform; - else - init_xform = auth_xform; - auth_xform->next = NULL; - } else { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Unrecognized operation"); - status = TEST_FAILED; - goto error_exit; - } - - /*configure xforms & sym_op cipher and auth data*/ - if (t->op_mask & AES_TEST_OP_CIPHER) { - cipher_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; - cipher_xform->cipher.algo = tdata->crypto_algo; - if (t->op_mask & AES_TEST_OP_ENCRYPT) - cipher_xform->cipher.op = - RTE_CRYPTO_CIPHER_OP_ENCRYPT; - else - cipher_xform->cipher.op = - RTE_CRYPTO_CIPHER_OP_DECRYPT; - cipher_xform->cipher.key.data = cipher_key; - cipher_xform->cipher.key.length = tdata->cipher_key.len; - - sym_op->cipher.data.offset = tdata->iv.len; - sym_op->cipher.data.length = tdata->ciphertext.len; - sym_op->cipher.iv.data = rte_pktmbuf_mtod(sym_op->m_src, - uint8_t *); - sym_op->cipher.iv.length = tdata->iv.len; - sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys( - sym_op->m_src); - } - - if (t->op_mask & AES_TEST_OP_AUTH) { - uint32_t auth_data_offset = 0; - uint32_t digest_offset = tdata->ciphertext.len; - - if (t->op_mask & AES_TEST_OP_CIPHER) { - digest_offset += tdata->iv.len; - auth_data_offset += tdata->iv.len; - } - - auth_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; - auth_xform->auth.algo = tdata->auth_algo; - auth_xform->auth.key.length = tdata->auth_key.len; - auth_xform->auth.key.data = auth_key; - auth_xform->auth.digest_length = digest_len; - - if (t->op_mask & AES_TEST_OP_AUTH_GEN) { - auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; - sym_op->auth.digest.data = rte_pktmbuf_mtod_offset - (iobuf, uint8_t *, digest_offset); - sym_op->auth.digest.phys_addr = - rte_pktmbuf_mtophys_offset(iobuf, - digest_offset); - } else { - auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; - sym_op->auth.digest.data = rte_pktmbuf_mtod_offset - (sym_op->m_src, uint8_t *, digest_offset); - sym_op->auth.digest.phys_addr = - rte_pktmbuf_mtophys_offset(sym_op->m_src, - digest_offset); - } - - sym_op->auth.data.offset = auth_data_offset; - sym_op->auth.data.length = tdata->ciphertext.len; - sym_op->auth.digest.length = digest_len; - } - - /* create session for sessioned op */ - if (!(t->feature_mask & AES_TEST_FEATURE_SESSIONLESS)) { - sess = rte_cryptodev_sym_session_create(dev_id, - init_xform); - if (!sess) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, - "Session creation failed"); - status = TEST_FAILED; - goto error_exit; - } - - /* attach symmetric crypto session to crypto operations */ - rte_crypto_op_attach_sym_session(op, sess); - } - - /* Process crypto operation */ - if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Error sending packet for encryption"); - status = TEST_FAILED; - goto error_exit; - } - - op = NULL; - - while (rte_cryptodev_dequeue_burst(dev_id, 0, &op, 1) == 0) - rte_pause(); - - if (!op) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s", - __LINE__, "Failed to process sym crypto op"); - status = TEST_FAILED; - goto error_exit; - } - - TEST_HEXDUMP(stdout, "m_src:", - rte_pktmbuf_mtod(sym_op->m_src, uint8_t *), buf_len); - if (t->feature_mask & AES_TEST_FEATURE_OOP) - TEST_HEXDUMP(stdout, "m_dst:", - rte_pktmbuf_mtod(sym_op->m_dst, uint8_t *), - buf_len); - - /* Verify results */ - if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) { - if (t->op_mask & AES_TEST_OP_AUTH_VERIFY) - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: Digest verification failed " - "(0x%X)", __LINE__, op->status); - else - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: Digest verification failed " - "(0x%X)", __LINE__, op->status); - status = TEST_FAILED; - goto error_exit; - } - - if (t->op_mask & AES_TEST_OP_CIPHER) { - uint8_t *crypto_res; - const uint8_t *compare_ref; - uint32_t compare_len; - - crypto_res = rte_pktmbuf_mtod_offset(iobuf, uint8_t *, - tdata->iv.len); - - if (t->op_mask & AES_TEST_OP_ENCRYPT) { - compare_ref = tdata->ciphertext.data; - compare_len = tdata->ciphertext.len; - } else { - compare_ref = tdata->plaintext.data; - compare_len = tdata->plaintext.len; - } - - if (memcmp(crypto_res, compare_ref, compare_len)) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, - "Crypto data not as expected"); - status = TEST_FAILED; - goto error_exit; - } - } - - if (t->op_mask & AES_TEST_OP_AUTH_GEN) { - uint8_t *auth_res; - - if (t->op_mask & AES_TEST_OP_CIPHER) - auth_res = rte_pktmbuf_mtod_offset(iobuf, - uint8_t *, - tdata->iv.len + tdata->ciphertext.len); - else - auth_res = rte_pktmbuf_mtod_offset(iobuf, - uint8_t *, tdata->ciphertext.len); - - if (memcmp(auth_res, tdata->digest.data, digest_len)) { - snprintf(test_msg, AES_TEST_MSG_LEN, "line %u " - "FAILED: %s", __LINE__, "Generated " - "digest data not as expected"); - status = TEST_FAILED; - goto error_exit; - } - } - - snprintf(test_msg, AES_TEST_MSG_LEN, "PASS"); - -error_exit: - if (!(t->feature_mask & AES_TEST_FEATURE_SESSIONLESS)) { - if (sess) - rte_cryptodev_sym_session_free(dev_id, sess); - if (cipher_xform) - rte_free(cipher_xform); - if (auth_xform) - rte_free(auth_xform); - } - - if (op) - rte_crypto_op_free(op); - - if (obuf) - rte_pktmbuf_free(obuf); - - if (ibuf) - rte_pktmbuf_free(ibuf); - - return status; -} - -int -test_AES_all_tests(struct rte_mempool *mbuf_pool, - struct rte_mempool *op_mpool, - uint8_t dev_id, - enum rte_cryptodev_type cryptodev_type) -{ - int status, overall_status = TEST_SUCCESS; - uint32_t i, test_index = 0; - char test_msg[AES_TEST_MSG_LEN + 1]; - uint32_t n_test_cases = sizeof(aes_test_cases) / - sizeof(aes_test_cases[0]); - uint32_t target_pmd_mask = 0; - - switch (cryptodev_type) { - case RTE_CRYPTODEV_AESNI_MB_PMD: - target_pmd_mask = AES_TEST_TARGET_PMD_MB; - break; - case RTE_CRYPTODEV_QAT_SYM_PMD: - target_pmd_mask = AES_TEST_TARGET_PMD_QAT; - break; - default: - TEST_ASSERT(-1, "Unrecognized cryptodev type"); - break; - } - - for (i = 0; i < n_test_cases; i++) { - const struct aes_test_case *tc = &aes_test_cases[i]; - - if (!(tc->pmd_mask & target_pmd_mask)) - continue; - - status = test_AES_one_case(tc, mbuf_pool, op_mpool, - dev_id, cryptodev_type, test_msg); - - printf(" %u) TestCase %s %s\n", test_index ++, - tc->test_descr, test_msg); - - if (status != TEST_SUCCESS) { - if (overall_status == TEST_SUCCESS) - overall_status = status; - - if (tc->feature_mask & AES_TEST_FEATURE_STOPPER) - break; - } - } - - return overall_status; -} diff --git a/app/test/test_cryptodev_aes.h b/app/test/test_cryptodev_aes.h deleted file mode 100644 index ef518e0..0000000 --- a/app/test/test_cryptodev_aes.h +++ /dev/null @@ -1,1124 +0,0 @@ -/*- - * 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 TEST_CRYPTODEV_AES_H_ -#define TEST_CRYPTODEV_AES_H_ - -struct aes_test_data { - enum rte_crypto_cipher_algorithm crypto_algo; - - struct { - uint8_t data[64]; - unsigned len; - } cipher_key; - - struct { - uint8_t data[64] __rte_aligned(16); - unsigned len; - } iv; - - struct { - uint8_t data[2048]; - unsigned len; - } plaintext; - - struct { - uint8_t data[2048]; - unsigned len; - } ciphertext; - - enum rte_crypto_auth_algorithm auth_algo; - - struct { - uint8_t data[128]; - unsigned len; - } auth_key; - - struct { - uint8_t data[128]; - unsigned len; /* for qat */ - unsigned truncated_len; /* for mb */ - } digest; -}; - -int -test_AES_all_tests(struct rte_mempool *mbuf_pool, - struct rte_mempool *op_mpool, - uint8_t dev_id, - enum rte_cryptodev_type cryptodev_type); - -/* test vectors */ -/* AES128-CTR-SHA1 test vector */ -static const struct aes_test_data aes_test_data_1 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, - .cipher_key = { - .data = { - 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, - 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C - }, - .len = 16 - }, - .iv = { - .data = { - 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, - 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF - }, - .len = 16 - }, - .plaintext = { - .data = { - 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, - 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, - 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, - 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, - 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, - 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, - 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, - 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 - }, - .len = 64 - }, - .ciphertext = { - .data = { - 0x87, 0x4D, 0x61, 0x91, 0xB6, 0x20, 0xE3, 0x26, - 0x1B, 0xEF, 0x68, 0x64, 0x99, 0x0D, 0xB6, 0xCE, - 0x98, 0x06, 0xF6, 0x6B, 0x79, 0x70, 0xFD, 0xFF, - 0x86, 0x17, 0x18, 0x7B, 0xB9, 0xFF, 0xFD, 0xFF, - 0x5A, 0xE4, 0xDF, 0x3E, 0xDB, 0xD5, 0xD3, 0x5E, - 0x5B, 0x4F, 0x09, 0x02, 0x0D, 0xB0, 0x3E, 0xAB, - 0x1E, 0x03, 0x1D, 0xDA, 0x2F, 0xBE, 0x03, 0xD1, - 0x79, 0x21, 0x70, 0xA0, 0xF3, 0x00, 0x9C, 0xEE - }, - .len = 64 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, - .auth_key = { - .data = { - 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, - 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, - 0xDE, 0xF4, 0xDE, 0xAD - }, - .len = 20 - }, - .digest = { - .data = { - 0x9B, 0x6F, 0x0C, 0x43, 0xF5, 0xC1, 0x3E, 0xB0, - 0xB1, 0x70, 0xB8, 0x2B, 0x33, 0x09, 0xD2, 0xB2, - 0x56, 0x20, 0xFB, 0xFE - }, - .len = 20, - .truncated_len = 12 - } -}; - -/** AES-192-CTR XCBC test vector */ -static const struct aes_test_data aes_test_data_2 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, - .cipher_key = { - .data = { - 0xCB, 0xC5, 0xED, 0x5B, 0xE7, 0x7C, 0xBD, 0x8C, - 0x50, 0xD9, 0x30, 0xF2, 0xB5, 0x6A, 0x0E, 0x5F, - 0xAA, 0xAE, 0xAD, 0xA2, 0x1F, 0x49, 0x52, 0xD4 - }, - .len = 24 - }, - .iv = { - .data = { - 0x3F, 0x69, 0xA8, 0xCD, 0xE8, 0xF0, 0xEF, 0x40, - 0xB8, 0x7A, 0x4B, 0xED, 0x2B, 0xAF, 0xBF, 0x57 - }, - .len = 16 - }, - .plaintext = { - .data = { - 0x01, 0x0F, 0x10, 0x1F, 0x20, 0x1C, 0x0E, 0xB8, - 0xFB, 0x5C, 0xCD, 0xCC, 0x1F, 0xF9, 0xAF, 0x0B, - 0x95, 0x03, 0x74, 0x99, 0x49, 0xE7, 0x62, 0x55, - 0xDA, 0xEA, 0x13, 0x20, 0x1D, 0xC6, 0xCC, 0xCC, - 0xD1, 0x70, 0x75, 0x47, 0x02, 0x2F, 0xFB, 0x86, - 0xBB, 0x6B, 0x23, 0xD2, 0xC9, 0x74, 0xD7, 0x7B, - 0x08, 0x03, 0x3B, 0x79, 0x39, 0xBB, 0x91, 0x29, - 0xDA, 0x14, 0x39, 0x8D, 0xFF, 0x81, 0x50, 0x96, - }, - .len = 64 - }, - .ciphertext = { - .data = { - 0x4A, 0x6C, 0xC8, 0xCC, 0x96, 0x2A, 0x13, 0x84, - 0x1C, 0x36, 0x88, 0xE9, 0xE5, 0x94, 0x70, 0xB2, - 0x14, 0x5B, 0x13, 0x80, 0xEA, 0xD8, 0x8D, 0x37, - 0xFD, 0x70, 0xA8, 0x83, 0xE8, 0x2B, 0x88, 0x1E, - 0xBA, 0x94, 0x3F, 0xF6, 0xB3, 0x1F, 0xDE, 0x34, - 0xF3, 0x5B, 0x80, 0xE9, 0xAB, 0xF5, 0x1C, 0x29, - 0xB6, 0xD9, 0x76, 0x2B, 0x06, 0xC6, 0x74, 0xF1, - 0x59, 0x5E, 0x9E, 0xA5, 0x7B, 0x2D, 0xD7, 0xF0 - }, - .len = 64 - }, - .auth_algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC, - .auth_key = { - .data = { - 0x87, 0x61, 0x54, 0x53, 0xC4, 0x6D, 0xDD, 0x51, - 0xE1, 0x9F, 0x86, 0x64, 0x39, 0x0A, 0xE6, 0x59 - }, - .len = 16 - }, - .digest = { - .data = { - 0xCA, 0x33, 0xB3, 0x3B, 0x16, 0x94, 0xAA, 0x55, - 0x36, 0x6B, 0x45, 0x46 - }, - .len = 12, - .truncated_len = 12 - } -}; - -/** AES-256-CTR SHA1 test vector */ -static const struct aes_test_data aes_test_data_3 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, - .cipher_key = { - .data = { - 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, - 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, - 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, - 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 - }, - .len = 32 - }, - .iv = { - .data = { - 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, - 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF - }, - .len = 16 - }, - .plaintext = { - .data = { - 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, - 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, - 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, - 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, - 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, - 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, - 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, - 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 - }, - .len = 64 - }, - .ciphertext = { - .data = { - 0x60, 0x1E, 0xC3, 0x13, 0x77, 0x57, 0x89, 0xA5, - 0xB7, 0xA7, 0xF5, 0x04, 0xBB, 0xF3, 0xD2, 0x28, - 0xF4, 0x43, 0xE3, 0xCA, 0x4D, 0x62, 0xB5, 0x9A, - 0xCA, 0x84, 0xE9, 0x90, 0xCA, 0xCA, 0xF5, 0xC5, - 0x2B, 0x09, 0x30, 0xDA, 0xA2, 0x3D, 0xE9, 0x4C, - 0xE8, 0x70, 0x17, 0xBA, 0x2D, 0x84, 0x98, 0x8D, - 0xDF, 0xC9, 0xC5, 0x8D, 0xB6, 0x7A, 0xAD, 0xA6, - 0x13, 0xC2, 0xDD, 0x08, 0x45, 0x79, 0x41, 0xA6 - }, - .len = 64 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, - .auth_key = { - .data = { - 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, - 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, - 0xDE, 0xF4, 0xDE, 0xAD - }, - .len = 20 - }, - .digest = { - .data = { - 0x3B, 0x1A, 0x9D, 0x82, 0x35, 0xD5, 0xDD, 0x64, - 0xCC, 0x1B, 0xA9, 0xC0, 0xEB, 0xE9, 0x42, 0x16, - 0xE7, 0x87, 0xA3, 0xEF - }, - .len = 20, - .truncated_len = 12 - } -}; - -/** AES-128-CBC SHA1 test vector */ -static const struct aes_test_data aes_test_data_4 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, - .auth_key = { - .data = { - 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, - 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, - 0xDE, 0xF4, 0xDE, 0xAD - }, - .len = 20 - }, - .digest = { - .data = { - 0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60, - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0x18, 0x8C, 0x1D, 0x32 - }, - .len = 20, - .truncated_len = 12 - } -}; - -/** AES-128-CBC SHA256 test vector */ -static const struct aes_test_data aes_test_data_5 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC, - .auth_key = { - .data = { - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60 - }, - .len = 32 - }, - .digest = { - .data = { - 0xC8, 0x57, 0x57, 0x31, 0x03, 0xE0, 0x03, 0x55, - 0x07, 0xC8, 0x9E, 0x7F, 0x48, 0x9A, 0x61, 0x9A, - 0x68, 0xEE, 0x03, 0x0E, 0x71, 0x75, 0xC7, 0xF4, - 0x2E, 0x45, 0x26, 0x32, 0x7C, 0x12, 0x15, 0x15 - }, - .len = 32, - .truncated_len = 16 - } -}; - -/** AES-128-CBC SHA512 test vector */ -static const struct aes_test_data aes_test_data_6 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA512_HMAC, - .auth_key = { - .data = { - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, - 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, - 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, - 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, - 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, - 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 - }, - .len = 64 - }, - .digest = { - .data = { - 0x5D, 0x54, 0x66, 0xC1, 0x6E, 0xBC, 0x04, 0xB8, - 0x46, 0xB8, 0x08, 0x6E, 0xE0, 0xF0, 0x43, 0x48, - 0x37, 0x96, 0x9C, 0xC6, 0x9C, 0xC2, 0x1E, 0xE8, - 0xF2, 0x0C, 0x0B, 0xEF, 0x86, 0xA2, 0xE3, 0x70, - 0x95, 0xC8, 0xB3, 0x06, 0x47, 0xA9, 0x90, 0xE8, - 0xA0, 0xC6, 0x72, 0x69, 0x05, 0xC0, 0x0D, 0x0E, - 0x21, 0x96, 0x65, 0x93, 0x74, 0x43, 0x2A, 0x1D, - 0x2E, 0xBF, 0xC2, 0xC2, 0xEE, 0xCC, 0x2F, 0x0A - }, - .len = 64, - .truncated_len = 32 - } -}; - -/** AES-128-CBC XCBC test vector */ -static const struct aes_test_data aes_test_data_7 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC, - .auth_key = { - .data = { - 0x87, 0x61, 0x54, 0x53, 0xC4, 0x6D, 0xDD, 0x51, - 0xE1, 0x9F, 0x86, 0x64, 0x39, 0x0A, 0xE6, 0x59 - }, - .len = 16 - }, - .digest = { - .data = { - 0xE0, 0xAC, 0x9A, 0xC4, 0x22, 0x64, 0x35, 0x89, - 0x77, 0x1D, 0x8B, 0x75 - }, - .len = 12, - .truncated_len = 12 - } -}; - -/** AES-128-CBC SHA224 test vector */ -static const struct aes_test_data aes_test_data_8 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA224_HMAC, - .auth_key = { - .data = { - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, - 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, - 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, - 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, - 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, - 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 - }, - .len = 64 - }, - .digest = { - .data = { - 0xA3, 0xCA, 0xC7, 0x1D, 0xA8, 0x61, 0x30, 0x98, - 0x3B, 0x8F, 0x01, 0x19, 0xAE, 0x8D, 0xBD, 0x34, - 0x40, 0x63, 0xA8, 0x2F, 0xDF, 0x85, 0x2B, 0x7F, - 0x63, 0x7C, 0xDD, 0xB7 - }, - .len = 28, - .truncated_len = 14 - } -}; - -/** AES-128-CBC SHA384 test vector */ -static const struct aes_test_data aes_test_data_9 = { - .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, - .cipher_key = { - .data = { - 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, - 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A - }, - .len = 16 - }, - .iv = { - .data = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F - }, - .len = 16 - }, - .plaintext = { - .data = { - "What a lousy earth! He wondered how many people " - "were destitute that same night even in his own " - "prosperous country, how many homes were " - "shanties, how many husbands were drunk and " - "wives socked, and how many children were " - "bullied, abused, or abandoned. How many " - "families hungered for food they could not " - "afford to buy? How many hearts were broken? How " - "many suicides would take place that same night, " - "how many people would go insane? How many " - "cockroaches and landlords would triumph? How " - "many winners were losers, successes failures, " - "and rich men poor men? How many wise guys were " - "stupid? How many happy endings were unhappy " - "endings? How many honest men were liars, brave " - "men cowards, loyal men traitors, how many " - "sainted men were corrupt, how many people in " - "positions of trust had sold their souls to " - "bodyguards, how many had never had souls? How " - "many straight-and-narrow paths were crooked " - "paths? How many best families were worst " - "families and how many good people were bad " - "people? When you added them all up and then " - "subtracted, you might be left with only the " - "children, and perhaps with Albert Einstein and " - "an old violinist or sculptor somewhere." - }, - .len = 512 - }, - .ciphertext = { - .data = { - 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, - 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, - 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, - 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, - 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, - 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, - 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, - 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, - 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, - 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, - 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, - 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, - 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, - 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, - 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, - 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, - 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, - 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, - 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, - 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, - 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, - 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, - 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, - 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, - 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, - 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, - 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, - 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, - 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, - 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, - 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, - 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, - 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, - 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, - 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, - 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, - 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, - 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, - 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, - 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, - 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, - 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, - 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, - 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, - 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, - 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, - 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, - 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, - 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, - 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, - 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, - 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, - 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, - 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, - 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, - 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, - 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, - 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, - 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, - 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, - 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, - 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C - }, - .len = 512 - }, - .auth_algo = RTE_CRYPTO_AUTH_SHA384_HMAC, - .auth_key = { - .data = { - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, - 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, - 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, - 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, - 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, - 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60, - 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, - 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, - 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, - 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, - 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, - 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, - 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, - 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 - }, - .len = 128 - }, - .digest = { - .data = { - 0x23, 0x60, 0xC8, 0xB1, 0x2D, 0x6C, 0x1E, 0x72, - 0x25, 0xAB, 0xF9, 0xC3, 0x9A, 0xA9, 0x4F, 0x8C, - 0x56, 0x38, 0x65, 0x0E, 0x74, 0xD5, 0x45, 0x9D, - 0xA3, 0xFD, 0x7E, 0x6D, 0x9E, 0x74, 0x88, 0x9D, - 0xA7, 0x12, 0x9D, 0xD8, 0x81, 0x3C, 0x86, 0x2F, - 0x4D, 0xF9, 0x6F, 0x0A, 0xB0, 0xC9, 0xEB, 0x0B - }, - .len = 48, - .truncated_len = 24 - } -}; - -#endif /* TEST_CRYPTODEV_AES_H_ */ diff --git a/app/test/test_cryptodev_aes_test_vectors.h b/app/test/test_cryptodev_aes_test_vectors.h new file mode 100644 index 0000000..92c0cc2 --- /dev/null +++ b/app/test/test_cryptodev_aes_test_vectors.h @@ -0,0 +1,797 @@ +/* + * 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 TEST_CRYPTODEV_AES_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_AES_TEST_VECTORS_H_ + +/* test vectors */ +static const uint8_t plaintext_aes128ctr[] = { + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, + 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, + 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, + 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, + 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, + 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, + 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 +}; + +static const uint8_t ciphertext64_aes128ctr[] = { + 0x87, 0x4D, 0x61, 0x91, 0xB6, 0x20, 0xE3, 0x26, + 0x1B, 0xEF, 0x68, 0x64, 0x99, 0x0D, 0xB6, 0xCE, + 0x98, 0x06, 0xF6, 0x6B, 0x79, 0x70, 0xFD, 0xFF, + 0x86, 0x17, 0x18, 0x7B, 0xB9, 0xFF, 0xFD, 0xFF, + 0x5A, 0xE4, 0xDF, 0x3E, 0xDB, 0xD5, 0xD3, 0x5E, + 0x5B, 0x4F, 0x09, 0x02, 0x0D, 0xB0, 0x3E, 0xAB, + 0x1E, 0x03, 0x1D, 0xDA, 0x2F, 0xBE, 0x03, 0xD1, + 0x79, 0x21, 0x70, 0xA0, 0xF3, 0x00, 0x9C, 0xEE +}; + +static const uint8_t plaintext_aes192ctr[] = { + 0x01, 0x0F, 0x10, 0x1F, 0x20, 0x1C, 0x0E, 0xB8, + 0xFB, 0x5C, 0xCD, 0xCC, 0x1F, 0xF9, 0xAF, 0x0B, + 0x95, 0x03, 0x74, 0x99, 0x49, 0xE7, 0x62, 0x55, + 0xDA, 0xEA, 0x13, 0x20, 0x1D, 0xC6, 0xCC, 0xCC, + 0xD1, 0x70, 0x75, 0x47, 0x02, 0x2F, 0xFB, 0x86, + 0xBB, 0x6B, 0x23, 0xD2, 0xC9, 0x74, 0xD7, 0x7B, + 0x08, 0x03, 0x3B, 0x79, 0x39, 0xBB, 0x91, 0x29, + 0xDA, 0x14, 0x39, 0x8D, 0xFF, 0x81, 0x50, 0x96, +}; + +static const uint8_t ciphertext64_aes192ctr[] = { + 0x4A, 0x6C, 0xC8, 0xCC, 0x96, 0x2A, 0x13, 0x84, + 0x1C, 0x36, 0x88, 0xE9, 0xE5, 0x94, 0x70, 0xB2, + 0x14, 0x5B, 0x13, 0x80, 0xEA, 0xD8, 0x8D, 0x37, + 0xFD, 0x70, 0xA8, 0x83, 0xE8, 0x2B, 0x88, 0x1E, + 0xBA, 0x94, 0x3F, 0xF6, 0xB3, 0x1F, 0xDE, 0x34, + 0xF3, 0x5B, 0x80, 0xE9, 0xAB, 0xF5, 0x1C, 0x29, + 0xB6, 0xD9, 0x76, 0x2B, 0x06, 0xC6, 0x74, 0xF1, + 0x59, 0x5E, 0x9E, 0xA5, 0x7B, 0x2D, 0xD7, 0xF0 +}; + +static const uint8_t plaintext_aes256ctr[] = { + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, + 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, + 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, + 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, + 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, + 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, + 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 +}; + +static const uint8_t ciphertext64_aes256ctr[] = { + 0x60, 0x1E, 0xC3, 0x13, 0x77, 0x57, 0x89, 0xA5, + 0xB7, 0xA7, 0xF5, 0x04, 0xBB, 0xF3, 0xD2, 0x28, + 0xF4, 0x43, 0xE3, 0xCA, 0x4D, 0x62, 0xB5, 0x9A, + 0xCA, 0x84, 0xE9, 0x90, 0xCA, 0xCA, 0xF5, 0xC5, + 0x2B, 0x09, 0x30, 0xDA, 0xA2, 0x3D, 0xE9, 0x4C, + 0xE8, 0x70, 0x17, 0xBA, 0x2D, 0x84, 0x98, 0x8D, + 0xDF, 0xC9, 0xC5, 0x8D, 0xB6, 0x7A, 0xAD, 0xA6, + 0x13, 0xC2, 0xDD, 0x08, 0x45, 0x79, 0x41, 0xA6 +}; + +static const uint8_t plaintext_aes_common[] = { + "What a lousy earth! He wondered how many people " + "were destitute that same night even in his own " + "prosperous country, how many homes were " + "shanties, how many husbands were drunk and " + "wives socked, and how many children were " + "bullied, abused, or abandoned. How many " + "families hungered for food they could not " + "afford to buy? How many hearts were broken? How " + "many suicides would take place that same night, " + "how many people would go insane? How many " + "cockroaches and landlords would triumph? How " + "many winners were losers, successes failures, " + "and rich men poor men? How many wise guys were " + "stupid? How many happy endings were unhappy " + "endings? How many honest men were liars, brave " + "men cowards, loyal men traitors, how many " + "sainted men were corrupt, how many people in " + "positions of trust had sold their souls to " + "bodyguards, how many had never had souls? How " + "many straight-and-narrow paths were crooked " + "paths? How many best families were worst " + "families and how many good people were bad " + "people? When you added them all up and then " + "subtracted, you might be left with only the " + "children, and perhaps with Albert Einstein and " + "an old violinist or sculptor somewhere." +}; + +static const uint8_t ciphertext512_aes128cbc[] = { + 0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31, + 0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76, + 0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E, + 0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A, + 0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E, + 0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08, + 0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0, + 0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01, + 0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57, + 0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE, + 0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9, + 0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9, + 0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D, + 0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3, + 0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46, + 0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3, + 0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80, + 0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92, + 0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5, + 0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5, + 0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2, + 0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, + 0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4, + 0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62, + 0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4, + 0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4, + 0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54, + 0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61, + 0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91, + 0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A, + 0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF, + 0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F, + 0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28, + 0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E, + 0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7, + 0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76, + 0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6, + 0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03, + 0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C, + 0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2, + 0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6, + 0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96, + 0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6, + 0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA, + 0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87, + 0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55, + 0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B, + 0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98, + 0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53, + 0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A, + 0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26, + 0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36, + 0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36, + 0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D, + 0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E, + 0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E, + 0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A, + 0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6, + 0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4, + 0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7, + 0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1, + 0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C +}; + +/* AES128-CTR-SHA1 test vector */ +static const struct blockcipher_test_data aes_test_data_1 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key = { + .data = { + 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C + }, + .len = 16 + }, + .iv = { + .data = { + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes128ctr, + .len = 64 + }, + .ciphertext = { + .data = ciphertext64_aes128ctr, + .len = 64 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x9B, 0x6F, 0x0C, 0x43, 0xF5, 0xC1, 0x3E, 0xB0, + 0xB1, 0x70, 0xB8, 0x2B, 0x33, 0x09, 0xD2, 0xB2, + 0x56, 0x20, 0xFB, 0xFE + }, + .len = 20, + .truncated_len = 12 + } +}; + +/** AES-192-CTR XCBC test vector */ +static const struct blockcipher_test_data aes_test_data_2 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key = { + .data = { + 0xCB, 0xC5, 0xED, 0x5B, 0xE7, 0x7C, 0xBD, 0x8C, + 0x50, 0xD9, 0x30, 0xF2, 0xB5, 0x6A, 0x0E, 0x5F, + 0xAA, 0xAE, 0xAD, 0xA2, 0x1F, 0x49, 0x52, 0xD4 + }, + .len = 24 + }, + .iv = { + .data = { + 0x3F, 0x69, 0xA8, 0xCD, 0xE8, 0xF0, 0xEF, 0x40, + 0xB8, 0x7A, 0x4B, 0xED, 0x2B, 0xAF, 0xBF, 0x57 + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes192ctr, + .len = 64 + }, + .ciphertext = { + .data = ciphertext64_aes192ctr, + .len = 64 + }, + .auth_algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC, + .auth_key = { + .data = { + 0x87, 0x61, 0x54, 0x53, 0xC4, 0x6D, 0xDD, 0x51, + 0xE1, 0x9F, 0x86, 0x64, 0x39, 0x0A, 0xE6, 0x59 + }, + .len = 16 + }, + .digest = { + .data = { + 0xCA, 0x33, 0xB3, 0x3B, 0x16, 0x94, 0xAA, 0x55, + 0x36, 0x6B, 0x45, 0x46 + }, + .len = 12, + .truncated_len = 12 + } +}; + +/** AES-256-CTR SHA1 test vector */ +static const struct blockcipher_test_data aes_test_data_3 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key = { + .data = { + 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, + 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, + 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, + 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 + }, + .len = 32 + }, + .iv = { + .data = { + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes256ctr, + .len = 64 + }, + .ciphertext = { + .data = ciphertext64_aes256ctr, + .len = 64 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x3B, 0x1A, 0x9D, 0x82, 0x35, 0xD5, 0xDD, 0x64, + 0xCC, 0x1B, 0xA9, 0xC0, 0xEB, 0xE9, 0x42, 0x16, + 0xE7, 0x87, 0xA3, 0xEF + }, + .len = 20, + .truncated_len = 12 + } +}; + +/** AES-128-CBC SHA1 test vector */ +static const struct blockcipher_test_data aes_test_data_4 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60, + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0x18, 0x8C, 0x1D, 0x32 + }, + .len = 20, + .truncated_len = 12 + } +}; + +/** AES-128-CBC SHA256 test vector */ +static const struct blockcipher_test_data aes_test_data_5 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC, + .auth_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76, + 0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60 + }, + .len = 32 + }, + .digest = { + .data = { + 0xC8, 0x57, 0x57, 0x31, 0x03, 0xE0, 0x03, 0x55, + 0x07, 0xC8, 0x9E, 0x7F, 0x48, 0x9A, 0x61, 0x9A, + 0x68, 0xEE, 0x03, 0x0E, 0x71, 0x75, 0xC7, 0xF4, + 0x2E, 0x45, 0x26, 0x32, 0x7C, 0x12, 0x15, 0x15 + }, + .len = 32, + .truncated_len = 16 + } +}; + +/** AES-128-CBC SHA512 test vector */ +static const struct blockcipher_test_data aes_test_data_6 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA512_HMAC, + .auth_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 + }, + .len = 64 + }, + .digest = { + .data = { + 0x5D, 0x54, 0x66, 0xC1, 0x6E, 0xBC, 0x04, 0xB8, + 0x46, 0xB8, 0x08, 0x6E, 0xE0, 0xF0, 0x43, 0x48, + 0x37, 0x96, 0x9C, 0xC6, 0x9C, 0xC2, 0x1E, 0xE8, + 0xF2, 0x0C, 0x0B, 0xEF, 0x86, 0xA2, 0xE3, 0x70, + 0x95, 0xC8, 0xB3, 0x06, 0x47, 0xA9, 0x90, 0xE8, + 0xA0, 0xC6, 0x72, 0x69, 0x05, 0xC0, 0x0D, 0x0E, + 0x21, 0x96, 0x65, 0x93, 0x74, 0x43, 0x2A, 0x1D, + 0x2E, 0xBF, 0xC2, 0xC2, 0xEE, 0xCC, 0x2F, 0x0A + }, + .len = 64, + .truncated_len = 32 + } +}; + +/** AES-128-CBC XCBC test vector */ +static const struct blockcipher_test_data aes_test_data_7 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC, + .auth_key = { + .data = { + 0x87, 0x61, 0x54, 0x53, 0xC4, 0x6D, 0xDD, 0x51, + 0xE1, 0x9F, 0x86, 0x64, 0x39, 0x0A, 0xE6, 0x59 + }, + .len = 16 + }, + .digest = { + .data = { + 0xE0, 0xAC, 0x9A, 0xC4, 0x22, 0x64, 0x35, 0x89, + 0x77, 0x1D, 0x8B, 0x75 + }, + .len = 12, + .truncated_len = 12 + } +}; + +/** AES-128-CBC SHA224 test vector */ +static const struct blockcipher_test_data aes_test_data_8 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA224_HMAC, + .auth_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 + }, + .len = 64 + }, + .digest = { + .data = { + 0xA3, 0xCA, 0xC7, 0x1D, 0xA8, 0x61, 0x30, 0x98, + 0x3B, 0x8F, 0x01, 0x19, 0xAE, 0x8D, 0xBD, 0x34, + 0x40, 0x63, 0xA8, 0x2F, 0xDF, 0x85, 0x2B, 0x7F, + 0x63, 0x7C, 0xDD, 0xB7 + }, + .len = 28, + .truncated_len = 14 + } +}; + +/** AES-128-CBC SHA384 test vector */ +static const struct blockcipher_test_data aes_test_data_9 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA384_HMAC, + .auth_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60, + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 + }, + .len = 128 + }, + .digest = { + .data = { + 0x23, 0x60, 0xC8, 0xB1, 0x2D, 0x6C, 0x1E, 0x72, + 0x25, 0xAB, 0xF9, 0xC3, 0x9A, 0xA9, 0x4F, 0x8C, + 0x56, 0x38, 0x65, 0x0E, 0x74, 0xD5, 0x45, 0x9D, + 0xA3, 0xFD, 0x7E, 0x6D, 0x9E, 0x74, 0x88, 0x9D, + 0xA7, 0x12, 0x9D, 0xD8, 0x81, 0x3C, 0x86, 0x2F, + 0x4D, 0xF9, 0x6F, 0x0A, 0xB0, 0xC9, 0xEB, 0x0B + }, + .len = 48, + .truncated_len = 24 + } +}; + +static const struct blockcipher_test_case aes_chain_test_cases[] = { + { + .test_descr = "AES-128-CTR HMAC-SHA1 Encryption Digest", + .test_data = &aes_test_data_1, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CTR HMAC-SHA1 Decryption Digest " + "Verify", + .test_data = &aes_test_data_1, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-192-CTR XCBC Encryption Digest", + .test_data = &aes_test_data_2, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-192-CTR XCBC Decryption Digest Verify", + .test_data = &aes_test_data_2, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-256-CTR HMAC-SHA1 Encryption Digest", + .test_data = &aes_test_data_3, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-256-CTR HMAC-SHA1 Decryption Digest " + "Verify", + .test_data = &aes_test_data_3, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " + "Verify", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA256 Encryption Digest", + .test_data = &aes_test_data_5, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA256 Decryption Digest " + "Verify", + .test_data = &aes_test_data_5, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest", + .test_data = &aes_test_data_6, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest " + "Sessionless", + .test_data = &aes_test_data_6, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB + }, + { + .test_descr = "AES-128-CBC HMAC-SHA512 Decryption Digest " + "Verify", + .test_data = &aes_test_data_6, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC XCBC Encryption Digest", + .test_data = &aes_test_data_7, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC XCBC Decryption Digest Verify", + .test_data = &aes_test_data_7, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest " + "OOP", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " + "Verify OOP", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA224 Encryption Digest", + .test_data = &aes_test_data_8, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA224 Decryption Digest " + "Verify", + .test_data = &aes_test_data_8, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA384 Encryption Digest", + .test_data = &aes_test_data_9, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "AES-128-CBC HMAC-SHA384 Decryption Digest " + "Verify", + .test_data = &aes_test_data_9, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, +}; + +#endif /* TEST_CRYPTODEV_AES_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_blockcipher.c b/app/test/test_cryptodev_blockcipher.c new file mode 100644 index 0000000..a1d8c8b --- /dev/null +++ b/app/test/test_cryptodev_blockcipher.c @@ -0,0 +1,516 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2015-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_common.h> +#include <rte_hexdump.h> +#include <rte_mbuf.h> +#include <rte_malloc.h> +#include <rte_memcpy.h> + +#include <rte_crypto.h> +#include <rte_cryptodev.h> +#include <rte_cryptodev_pmd.h> + +#include "test.h" +#include "test_cryptodev_blockcipher.h" +#include "test_cryptodev_aes_test_vectors.h" + +static int +test_blockcipher_one_case(const struct blockcipher_test_case *t, + struct rte_mempool *mbuf_pool, + struct rte_mempool *op_mpool, + uint8_t dev_id, + enum rte_cryptodev_type cryptodev_type, + char *test_msg) +{ + struct rte_mbuf *ibuf = NULL; + struct rte_mbuf *obuf = NULL; + struct rte_mbuf *iobuf; + struct rte_crypto_sym_xform *cipher_xform = NULL; + struct rte_crypto_sym_xform *auth_xform = NULL; + struct rte_crypto_sym_xform *init_xform = NULL; + struct rte_crypto_sym_op *sym_op = NULL; + struct rte_crypto_op *op = NULL; + struct rte_cryptodev_sym_session *sess = NULL; + + int status = TEST_SUCCESS; + const struct blockcipher_test_data *tdata = t->test_data; + uint8_t cipher_key[tdata->cipher_key.len]; + uint8_t auth_key[tdata->auth_key.len]; + uint32_t buf_len = tdata->ciphertext.len; + uint32_t digest_len = 0; + char *buf_p = NULL; + + if (tdata->cipher_key.len) + memcpy(cipher_key, tdata->cipher_key.data, + tdata->cipher_key.len); + if (tdata->auth_key.len) + memcpy(auth_key, tdata->auth_key.data, + tdata->auth_key.len); + + switch (cryptodev_type) { + case RTE_CRYPTODEV_QAT_SYM_PMD: + digest_len = tdata->digest.len; + break; + case RTE_CRYPTODEV_AESNI_MB_PMD: + digest_len = tdata->digest.truncated_len; + break; + default: + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Unsupported PMD type"); + status = TEST_FAILED; + goto error_exit; + } + + /* preparing data */ + ibuf = rte_pktmbuf_alloc(mbuf_pool); + if (!ibuf) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Allocation of rte_mbuf failed"); + status = TEST_FAILED; + goto error_exit; + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) + buf_len += tdata->iv.len; + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) + buf_len += digest_len; + + buf_p = rte_pktmbuf_append(ibuf, buf_len); + if (!buf_p) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "No room to append mbuf"); + status = TEST_FAILED; + goto error_exit; + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { + rte_memcpy(buf_p, tdata->iv.data, tdata->iv.len); + buf_p += tdata->iv.len; + } + + /* only encryption requires plaintext.data input, + * decryption/(digest gen)/(digest verify) use ciphertext.data + * to be computed + */ + if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) { + rte_memcpy(buf_p, tdata->plaintext.data, + tdata->plaintext.len); + buf_p += tdata->plaintext.len; + } else { + rte_memcpy(buf_p, tdata->ciphertext.data, + tdata->ciphertext.len); + buf_p += tdata->ciphertext.len; + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) + rte_memcpy(buf_p, tdata->digest.data, digest_len); + else + memset(buf_p, 0, digest_len); + + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) { + obuf = rte_pktmbuf_alloc(mbuf_pool); + if (!obuf) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "Allocation of rte_mbuf failed"); + status = TEST_FAILED; + goto error_exit; + } + + buf_p = rte_pktmbuf_append(obuf, buf_len); + if (!buf_p) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "No room to append mbuf"); + status = TEST_FAILED; + goto error_exit; + } + memset(buf_p, 0, buf_len); + } + + /* Generate Crypto op data structure */ + op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_SYMMETRIC); + if (!op) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Failed to allocate symmetric crypto " + "operation struct"); + status = TEST_FAILED; + goto error_exit; + } + + sym_op = op->sym; + + sym_op->m_src = ibuf; + + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) { + sym_op->m_dst = obuf; + iobuf = obuf; + } else { + sym_op->m_dst = NULL; + iobuf = ibuf; + } + + /* sessionless op requires allocate xform using + * rte_crypto_op_sym_xforms_alloc(), otherwise rte_zmalloc() + * is used + */ + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) { + uint32_t n_xforms = 0; + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) + n_xforms++; + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) + n_xforms++; + + if (rte_crypto_op_sym_xforms_alloc(op, n_xforms) + == NULL) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, "Failed to " + "allocate space for crypto transforms"); + status = TEST_FAILED; + goto error_exit; + } + } else { + cipher_xform = rte_zmalloc(NULL, + sizeof(struct rte_crypto_sym_xform), 0); + + auth_xform = rte_zmalloc(NULL, + sizeof(struct rte_crypto_sym_xform), 0); + + if (!cipher_xform || !auth_xform) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, "Failed to " + "allocate memory for crypto transforms"); + status = TEST_FAILED; + goto error_exit; + } + } + + /* preparing xform, for sessioned op, init_xform is initialized + * here and later as param in rte_cryptodev_sym_session_create() call + */ + if (t->op_mask == BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN) { + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) { + cipher_xform = op->sym->xform; + auth_xform = cipher_xform->next; + auth_xform->next = NULL; + } else { + cipher_xform->next = auth_xform; + auth_xform->next = NULL; + init_xform = cipher_xform; + } + } else if (t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC) { + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) { + auth_xform = op->sym->xform; + cipher_xform = auth_xform->next; + cipher_xform->next = NULL; + } else { + auth_xform->next = cipher_xform; + cipher_xform->next = NULL; + init_xform = auth_xform; + } + } else if ((t->op_mask == BLOCKCIPHER_TEST_OP_ENCRYPT) || + (t->op_mask == BLOCKCIPHER_TEST_OP_DECRYPT)) { + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) + cipher_xform = op->sym->xform; + else + init_xform = cipher_xform; + cipher_xform->next = NULL; + } else if ((t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_GEN) || + (t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_VERIFY)) { + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) + auth_xform = op->sym->xform; + else + init_xform = auth_xform; + auth_xform->next = NULL; + } else { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Unrecognized operation"); + status = TEST_FAILED; + goto error_exit; + } + + /*configure xforms & sym_op cipher and auth data*/ + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { + cipher_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; + cipher_xform->cipher.algo = tdata->crypto_algo; + if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) + cipher_xform->cipher.op = + RTE_CRYPTO_CIPHER_OP_ENCRYPT; + else + cipher_xform->cipher.op = + RTE_CRYPTO_CIPHER_OP_DECRYPT; + cipher_xform->cipher.key.data = cipher_key; + cipher_xform->cipher.key.length = tdata->cipher_key.len; + + sym_op->cipher.data.offset = tdata->iv.len; + sym_op->cipher.data.length = tdata->ciphertext.len; + sym_op->cipher.iv.data = rte_pktmbuf_mtod(sym_op->m_src, + uint8_t *); + sym_op->cipher.iv.length = tdata->iv.len; + sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys( + sym_op->m_src); + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) { + uint32_t auth_data_offset = 0; + uint32_t digest_offset = tdata->ciphertext.len; + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { + digest_offset += tdata->iv.len; + auth_data_offset += tdata->iv.len; + } + + auth_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; + auth_xform->auth.algo = tdata->auth_algo; + auth_xform->auth.key.length = tdata->auth_key.len; + auth_xform->auth.key.data = auth_key; + auth_xform->auth.digest_length = digest_len; + + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) { + auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; + sym_op->auth.digest.data = rte_pktmbuf_mtod_offset + (iobuf, uint8_t *, digest_offset); + sym_op->auth.digest.phys_addr = + rte_pktmbuf_mtophys_offset(iobuf, + digest_offset); + } else { + auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; + sym_op->auth.digest.data = rte_pktmbuf_mtod_offset + (sym_op->m_src, uint8_t *, digest_offset); + sym_op->auth.digest.phys_addr = + rte_pktmbuf_mtophys_offset(sym_op->m_src, + digest_offset); + } + + sym_op->auth.data.offset = auth_data_offset; + sym_op->auth.data.length = tdata->ciphertext.len; + sym_op->auth.digest.length = digest_len; + } + + /* create session for sessioned op */ + if (!(t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)) { + sess = rte_cryptodev_sym_session_create(dev_id, + init_xform); + if (!sess) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "Session creation failed"); + status = TEST_FAILED; + goto error_exit; + } + + /* attach symmetric crypto session to crypto operations */ + rte_crypto_op_attach_sym_session(op, sess); + } + + /* Process crypto operation */ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Error sending packet for encryption"); + status = TEST_FAILED; + goto error_exit; + } + + op = NULL; + + while (rte_cryptodev_dequeue_burst(dev_id, 0, &op, 1) == 0) + rte_pause(); + + if (!op) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Failed to process sym crypto op"); + status = TEST_FAILED; + goto error_exit; + } + + TEST_HEXDUMP(stdout, "m_src:", + rte_pktmbuf_mtod(sym_op->m_src, uint8_t *), buf_len); + if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) + TEST_HEXDUMP(stdout, "m_dst:", + rte_pktmbuf_mtod(sym_op->m_dst, uint8_t *), + buf_len); + + /* Verify results */ + if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) { + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: Digest verification failed " + "(0x%X)", __LINE__, op->status); + else + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: Digest verification failed " + "(0x%X)", __LINE__, op->status); + status = TEST_FAILED; + goto error_exit; + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) { + uint8_t *crypto_res; + const uint8_t *compare_ref; + uint32_t compare_len; + + crypto_res = rte_pktmbuf_mtod_offset(iobuf, uint8_t *, + tdata->iv.len); + + if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) { + compare_ref = tdata->ciphertext.data; + compare_len = tdata->ciphertext.len; + } else { + compare_ref = tdata->plaintext.data; + compare_len = tdata->plaintext.len; + } + + if (memcmp(crypto_res, compare_ref, compare_len)) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "Crypto data not as expected"); + status = TEST_FAILED; + goto error_exit; + } + } + + if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) { + uint8_t *auth_res; + + if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) + auth_res = rte_pktmbuf_mtod_offset(iobuf, + uint8_t *, + tdata->iv.len + tdata->ciphertext.len); + else + auth_res = rte_pktmbuf_mtod_offset(iobuf, + uint8_t *, tdata->ciphertext.len); + + if (memcmp(auth_res, tdata->digest.data, digest_len)) { + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, "Generated " + "digest data not as expected"); + status = TEST_FAILED; + goto error_exit; + } + } + + snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "PASS"); + +error_exit: + if (!(t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)) { + if (sess) + rte_cryptodev_sym_session_free(dev_id, sess); + if (cipher_xform) + rte_free(cipher_xform); + if (auth_xform) + rte_free(auth_xform); + } + + if (op) + rte_crypto_op_free(op); + + if (obuf) + rte_pktmbuf_free(obuf); + + if (ibuf) + rte_pktmbuf_free(ibuf); + + return status; +} + +int +test_blockcipher_all_tests(struct rte_mempool *mbuf_pool, + struct rte_mempool *op_mpool, + uint8_t dev_id, + enum rte_cryptodev_type cryptodev_type, + enum blockcipher_test_type test_type) +{ + int status, overall_status = TEST_SUCCESS; + uint32_t i, test_index = 0; + char test_msg[BLOCKCIPHER_TEST_MSG_LEN + 1]; + uint32_t n_test_cases = 0; + uint32_t target_pmd_mask = 0; + const struct blockcipher_test_case *tcs = NULL; + + switch (test_type) { + case BLKCIPHER_AES_CHAIN_TYPE: + n_test_cases = sizeof(aes_chain_test_cases) / + sizeof(aes_chain_test_cases[0]); + tcs = aes_chain_test_cases; + break; + case BLKCIPHER_AES_CIPHERONLY_TYPE: + case BLKCIPHER_3DES_CHAIN_TYPE: + case BLKCIPHER_3DES_CIPHERONLY_TYPE: + case BLKCIPHER_AUTHONLY_TYPE: + default: + break; + } + + switch (cryptodev_type) { + case RTE_CRYPTODEV_AESNI_MB_PMD: + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB; + break; + case RTE_CRYPTODEV_QAT_SYM_PMD: + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT; + break; + default: + TEST_ASSERT(0, "Unrecognized cryptodev type"); + break; + } + + for (i = 0; i < n_test_cases; i++) { + const struct blockcipher_test_case *tc = &tcs[i]; + + if (!(tc->pmd_mask & target_pmd_mask)) + continue; + + status = test_blockcipher_one_case(tc, mbuf_pool, op_mpool, + dev_id, cryptodev_type, test_msg); + + printf(" %u) TestCase %s %s\n", test_index ++, + tc->test_descr, test_msg); + + if (status != TEST_SUCCESS) { + if (overall_status == TEST_SUCCESS) + overall_status = status; + + if (tc->feature_mask & BLOCKCIPHER_TEST_FEATURE_STOPPER) + break; + } + } + + return overall_status; +} diff --git a/app/test/test_cryptodev_blockcipher.h b/app/test/test_cryptodev_blockcipher.h new file mode 100644 index 0000000..3e25d4d --- /dev/null +++ b/app/test/test_cryptodev_blockcipher.h @@ -0,0 +1,124 @@ +/*- + * 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 TEST_CRYPTODEV_BLOCKCIPHER_H_ +#define TEST_CRYPTODEV_BLOCKCIPHER_H_ + +#ifndef BLOCKCIPHER_TEST_MSG_LEN +#define BLOCKCIPHER_TEST_MSG_LEN 256 +#endif + +#define BLOCKCIPHER_TEST_OP_ENCRYPT 0x01 +#define BLOCKCIPHER_TEST_OP_DECRYPT 0x02 +#define BLOCKCIPHER_TEST_OP_AUTH_GEN 0x04 +#define BLOCKCIPHER_TEST_OP_AUTH_VERIFY 0x08 + +#define BLOCKCIPHER_TEST_FEATURE_OOP 0x01 +#define BLOCKCIPHER_TEST_FEATURE_SESSIONLESS 0x02 +#define BLOCKCIPHER_TEST_FEATURE_STOPPER 0x04 /* stop upon failing */ + +#define BLOCKCIPHER_TEST_TARGET_PMD_MB 0x0001 /* Multi-buffer flag */ +#define BLOCKCIPHER_TEST_TARGET_PMD_QAT 0x0002 /* QAT flag */ + +#define BLOCKCIPHER_TEST_OP_CIPHER (BLOCKCIPHER_TEST_OP_ENCRYPT | \ + BLOCKCIPHER_TEST_OP_DECRYPT) + +#define BLOCKCIPHER_TEST_OP_AUTH (BLOCKCIPHER_TEST_OP_AUTH_GEN | \ + BLOCKCIPHER_TEST_OP_AUTH_VERIFY) + +#define BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN (BLOCKCIPHER_TEST_OP_ENCRYPT | \ + BLOCKCIPHER_TEST_OP_AUTH_GEN) + +#define BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC (BLOCKCIPHER_TEST_OP_DECRYPT | \ + BLOCKCIPHER_TEST_OP_AUTH_VERIFY) + +enum blockcipher_test_type { + BLKCIPHER_AES_CHAIN_TYPE, /* use aes_chain_test_cases[] */ + BLKCIPHER_AES_CIPHERONLY_TYPE, /* use aes_cipheronly_test_cases[] */ + BLKCIPHER_3DES_CHAIN_TYPE, /* use triple_des_chain_test_cases[] */ + BLKCIPHER_3DES_CIPHERONLY_TYPE, /* triple_des_cipheronly_test_cases[] */ + BLKCIPHER_AUTHONLY_TYPE /* use hash_test_cases[] */ +}; + +struct blockcipher_test_case { + const char *test_descr; /* test description */ + const struct blockcipher_test_data *test_data; + uint8_t op_mask; /* operation mask */ + uint8_t feature_mask; + uint32_t pmd_mask; +}; + +struct blockcipher_test_data { + enum rte_crypto_cipher_algorithm crypto_algo; + + struct { + uint8_t data[64]; + unsigned int len; + } cipher_key; + + struct { + uint8_t data[64] __rte_aligned(16); + unsigned int len; + } iv; + + struct { + const uint8_t *data; + unsigned int len; + } plaintext; + + struct { + const uint8_t *data; + unsigned int len; + } ciphertext; + + enum rte_crypto_auth_algorithm auth_algo; + + struct { + uint8_t data[128]; + unsigned int len; + } auth_key; + + struct { + uint8_t data[128]; + unsigned int len; /* for qat */ + unsigned int truncated_len; /* for mb */ + } digest; +}; + +int +test_blockcipher_all_tests(struct rte_mempool *mbuf_pool, + struct rte_mempool *op_mpool, + uint8_t dev_id, + enum rte_cryptodev_type cryptodev_type, + enum blockcipher_test_type test_type); + +#endif /* TEST_CRYPTODEV_BLOCKCIPHER_H_ */ -- 2.5.0 ^ permalink raw reply [flat|nested] 34+ messages in thread
* [dpdk-dev] [PATCH v6 3/4] app/test: added tests for libcrypto PMD 2016-10-04 15:11 ` [dpdk-dev] [PATCH v6 " Slawomir Mrozowicz 2016-10-04 15:11 ` [dpdk-dev] [PATCH v6 1/4] libcrypto_pmd: initial implementation of SW crypto device Slawomir Mrozowicz 2016-10-04 15:11 ` [dpdk-dev] [PATCH v6 2/4] app/test: cryptodev AES tests rework Slawomir Mrozowicz @ 2016-10-04 15:11 ` Slawomir Mrozowicz 2016-10-06 13:30 ` Trahe, Fiona 2016-10-04 15:11 ` [dpdk-dev] [PATCH v6 4/4] examples/l2fwd-crypto: updated example " Slawomir Mrozowicz 2016-10-04 23:36 ` [dpdk-dev] [PATCH v6 0/4] new crypto software based device De Lara Guarch, Pablo 4 siblings, 1 reply; 34+ messages in thread From: Slawomir Mrozowicz @ 2016-10-04 15:11 UTC (permalink / raw) To: dev; +Cc: Slawomir Mrozowicz, Piotr Azarewicz, Marcin Kerlin, Daniel Mrzyglod This patch contains unit tests for libcrypto PMD. User can use app/test application to check how to use this pmd and to verify crypto processing. Test name is cryptodev_libcrypto_autotest. For performance test cryptodev_libcrypto_perftest can be used. Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com> Signed-off-by: Marcin Kerlin <marcinx.kerlin@intel.com> Signed-off-by: Daniel Mrzyglod <danielx.t.mrzyglod@intel.com> --- v2: - rename AES-named functions to blockcipher - replace different test cases with blockcipher functions pattern - add 3DES tests into QuickAssist PMD testsuite v3: - add nagative verification tests - add big data test v4: - move aes test rework to another patch - move big data test to another patch - checking if libcrypto pmd is available v5: - add reduced big data test v6: - fix checkpatch warnings --- app/test/test_cryptodev.c | 1505 ++++++++++++++++++++++++++- app/test/test_cryptodev.h | 1 + app/test/test_cryptodev_aes_test_vectors.h | 306 +++++- app/test/test_cryptodev_blockcipher.c | 22 + app/test/test_cryptodev_blockcipher.h | 1 + app/test/test_cryptodev_des_test_vectors.h | 955 +++++++++++++++++ app/test/test_cryptodev_gcm_test_vectors.h | 36 +- app/test/test_cryptodev_hash_test_vectors.h | 491 +++++++++ app/test/test_cryptodev_perf.c | 712 ++++++++++++- 9 files changed, 3954 insertions(+), 75 deletions(-) create mode 100644 app/test/test_cryptodev_des_test_vectors.h create mode 100644 app/test/test_cryptodev_hash_test_vectors.h diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c index 8f03157..9767704 100644 --- a/app/test/test_cryptodev.c +++ b/app/test/test_cryptodev.c @@ -45,6 +45,8 @@ #include "test_cryptodev_blockcipher.h" #include "test_cryptodev_aes_test_vectors.h" +#include "test_cryptodev_des_test_vectors.h" +#include "test_cryptodev_hash_test_vectors.h" #include "test_cryptodev_kasumi_test_vectors.h" #include "test_cryptodev_kasumi_hash_test_vectors.h" #include "test_cryptodev_snow3g_test_vectors.h" @@ -167,7 +169,7 @@ testsuite_setup(void) /* Not already created so create */ ts_params->mbuf_pool = rte_pktmbuf_pool_create( "CRYPTO_MBUFPOOL", - NUM_MBUFS, MBUF_CACHE_SIZE, 0, MBUF_SIZE, + NUM_MBUFS, MBUF_CACHE_SIZE, 0, UINT16_MAX, rte_socket_id()); if (ts_params->mbuf_pool == NULL) { RTE_LOG(ERR, USER1, "Can't create CRYPTO_MBUFPOOL\n"); @@ -308,6 +310,28 @@ testsuite_setup(void) } } + /* Create 2 LIBCRYPTO devices if required */ + if (gbl_cryptodev_type == RTE_CRYPTODEV_LIBCRYPTO_PMD) { +#ifndef RTE_LIBRTE_PMD_LIBCRYPTO + RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO must be" + " enabled in config file to run this testsuite.\n"); + return TEST_FAILED; +#endif + nb_devs = rte_cryptodev_count_devtype( + RTE_CRYPTODEV_LIBCRYPTO_PMD); + if (nb_devs < 2) { + for (i = nb_devs; i < 2; i++) { + ret = rte_eal_vdev_init( + RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), + NULL); + + TEST_ASSERT(ret == 0, "Failed to create " + "instance %u of pmd : %s", i, + RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD)); + } + } + } + #ifndef RTE_LIBRTE_PMD_QAT if (gbl_cryptodev_type == RTE_CRYPTODEV_QAT_SYM_PMD) { RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_QAT must be enabled " @@ -877,6 +901,315 @@ static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA1_digest[] = { 0x18, 0x8c, 0x1d, 0x32 }; + +/* Multisession Vector context Test */ +/*Begin Session 0 */ +static uint8_t ms_aes_cbc_key0[] = { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static uint8_t ms_aes_cbc_iv0[] = { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static const uint8_t ms_aes_cbc_cipher0[] = { + 0x3C, 0xE4, 0xEE, 0x42, 0xB6, 0x9B, 0xC3, 0x38, + 0x5F, 0xAD, 0x54, 0xDC, 0xA8, 0x32, 0x81, 0xDC, + 0x7A, 0x6F, 0x85, 0x58, 0x07, 0x35, 0xED, 0xEB, + 0xAD, 0x79, 0x79, 0x96, 0xD3, 0x0E, 0xA6, 0xD9, + 0xAA, 0x86, 0xA4, 0x8F, 0xB5, 0xD6, 0x6E, 0x6D, + 0x0C, 0x91, 0x2F, 0xC4, 0x67, 0x98, 0x0E, 0xC4, + 0x8D, 0x83, 0x68, 0x69, 0xC4, 0xD3, 0x94, 0x34, + 0xC4, 0x5D, 0x60, 0x55, 0x22, 0x87, 0x8F, 0x6F, + 0x17, 0x8E, 0x75, 0xE4, 0x02, 0xF5, 0x1B, 0x99, + 0xC8, 0x39, 0xA9, 0xAB, 0x23, 0x91, 0x12, 0xED, + 0x08, 0xE7, 0xD9, 0x25, 0x89, 0x24, 0x4F, 0x8D, + 0x68, 0xF3, 0x10, 0x39, 0x0A, 0xEE, 0x45, 0x24, + 0xDF, 0x7A, 0x9D, 0x00, 0x25, 0xE5, 0x35, 0x71, + 0x4E, 0x40, 0x59, 0x6F, 0x0A, 0x13, 0xB3, 0x72, + 0x1D, 0x98, 0x63, 0x94, 0x89, 0xA5, 0x39, 0x8E, + 0xD3, 0x9C, 0x8A, 0x7F, 0x71, 0x2F, 0xC7, 0xCD, + 0x81, 0x05, 0xDC, 0xC0, 0x8D, 0xCE, 0x6D, 0x18, + 0x30, 0xC4, 0x72, 0x51, 0xF0, 0x27, 0xC8, 0xF6, + 0x60, 0x5B, 0x7C, 0xB2, 0xE3, 0x49, 0x0C, 0x29, + 0xC6, 0x9F, 0x39, 0x57, 0x80, 0x55, 0x24, 0x2C, + 0x9B, 0x0F, 0x5A, 0xB3, 0x89, 0x55, 0x31, 0x96, + 0x0D, 0xCD, 0xF6, 0x51, 0x03, 0x2D, 0x89, 0x26, + 0x74, 0x44, 0xD6, 0xE8, 0xDC, 0xEA, 0x44, 0x55, + 0x64, 0x71, 0x9C, 0x9F, 0x5D, 0xBA, 0x39, 0x46, + 0xA8, 0x17, 0xA1, 0x9C, 0x52, 0x9D, 0xBC, 0x6B, + 0x4A, 0x98, 0xE6, 0xEA, 0x33, 0xEC, 0x58, 0xB4, + 0x43, 0xF0, 0x32, 0x45, 0xA4, 0xC1, 0x55, 0xB7, + 0x5D, 0xB5, 0x59, 0xB2, 0xE3, 0x96, 0xFF, 0xA5, + 0xAF, 0xE1, 0x86, 0x1B, 0x42, 0xE6, 0x3B, 0xA0, + 0x90, 0x4A, 0xE8, 0x8C, 0x21, 0x7F, 0x36, 0x1E, + 0x5B, 0x65, 0x25, 0xD1, 0xC1, 0x5A, 0xCA, 0x3D, + 0x10, 0xED, 0x2D, 0x79, 0xD0, 0x0F, 0x58, 0x44, + 0x69, 0x81, 0xF5, 0xD4, 0xC9, 0x0F, 0x90, 0x76, + 0x1F, 0x54, 0xD2, 0xD5, 0x97, 0xCE, 0x2C, 0xE3, + 0xEF, 0xF4, 0xB7, 0xC6, 0x3A, 0x87, 0x7F, 0x83, + 0x2A, 0xAF, 0xCD, 0x90, 0x12, 0xA7, 0x7D, 0x85, + 0x1D, 0x62, 0xD3, 0x85, 0x25, 0x05, 0xDB, 0x45, + 0x92, 0xA3, 0xF6, 0xA2, 0xA8, 0x41, 0xE4, 0x25, + 0x86, 0x87, 0x67, 0x24, 0xEC, 0x89, 0x23, 0x2A, + 0x9B, 0x20, 0x4D, 0x93, 0xEE, 0xE2, 0x2E, 0xC1, + 0x0B, 0x15, 0x33, 0xCF, 0x00, 0xD1, 0x1A, 0xDA, + 0x93, 0xFD, 0x28, 0x21, 0x5B, 0xCF, 0xD1, 0xF3, + 0x5A, 0x81, 0xBA, 0x82, 0x5E, 0x2F, 0x61, 0xB4, + 0x05, 0x71, 0xB5, 0xF4, 0x39, 0x3C, 0x1F, 0x60, + 0x00, 0x7A, 0xC4, 0xF8, 0x35, 0x20, 0x6C, 0x3A, + 0xCC, 0x03, 0x8F, 0x7B, 0xA2, 0xB6, 0x65, 0x8A, + 0xB6, 0x5F, 0xFD, 0x25, 0xD3, 0x5F, 0x92, 0xF9, + 0xAE, 0x17, 0x9B, 0x5E, 0x6E, 0x9A, 0xE4, 0x55, + 0x10, 0x25, 0x07, 0xA4, 0xAF, 0x21, 0x69, 0x13, + 0xD8, 0xFA, 0x31, 0xED, 0xF7, 0xA7, 0xA7, 0x3B, + 0xB8, 0x96, 0x8E, 0x10, 0x86, 0x74, 0xD8, 0xB1, + 0x34, 0x9E, 0x9B, 0x6A, 0x26, 0xA8, 0xD4, 0xD0, + 0xB5, 0xF6, 0xDE, 0xE7, 0xCA, 0x06, 0xDC, 0xA3, + 0x6F, 0xEE, 0x6B, 0x1E, 0xB5, 0x30, 0x99, 0x23, + 0xF9, 0x76, 0xF0, 0xA0, 0xCF, 0x3B, 0x94, 0x7B, + 0x19, 0x8D, 0xA5, 0x0C, 0x18, 0xA6, 0x1D, 0x07, + 0x89, 0xBE, 0x5B, 0x61, 0xE5, 0xF1, 0x42, 0xDB, + 0xD4, 0x2E, 0x02, 0x1F, 0xCE, 0xEF, 0x92, 0xB1, + 0x1B, 0x56, 0x50, 0xF2, 0x16, 0xE5, 0xE7, 0x4F, + 0xFD, 0xBB, 0x3E, 0xD2, 0xFC, 0x3C, 0xC6, 0x0F, + 0xF9, 0x12, 0x4E, 0xCB, 0x1E, 0x0C, 0x15, 0x84, + 0x2A, 0x14, 0x8A, 0x02, 0xE4, 0x7E, 0x95, 0x5B, + 0x86, 0xDB, 0x9B, 0x62, 0x5B, 0x19, 0xD2, 0x17, + 0xFA, 0x13, 0xBB, 0x6B, 0x3F, 0x45, 0x9F, 0xBF +}; + + +static uint8_t ms_hmac_key0[] = { + 0xFF, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 +}; + +static const uint8_t ms_hmac_digest0[] = { + 0x43, 0x52, 0xED, 0x34, 0xAB, 0x36, 0xB2, 0x51, + 0xFB, 0xA3, 0xA6, 0x7C, 0x38, 0xFC, 0x42, 0x8F, + 0x57, 0x64, 0xAB, 0x81, 0xA7, 0x89, 0xB7, 0x6C, + 0xA0, 0xDC, 0xB9, 0x4D, 0xC4, 0x30, 0xF9, 0xD4, + 0x10, 0x82, 0x55, 0xD0, 0xAB, 0x32, 0xFB, 0x56, + 0x0D, 0xE4, 0x68, 0x3D, 0x76, 0xD0, 0x7B, 0xE4, + 0xA6, 0x2C, 0x34, 0x9E, 0x8C, 0x41, 0xF8, 0x23, + 0x28, 0x1B, 0x3A, 0x90, 0x26, 0x34, 0x47, 0x90 + }; + +/* End Session 0 */ +/* Begin session 1 */ + +static uint8_t ms_aes_cbc_key1[] = { + 0xf1, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static uint8_t ms_aes_cbc_iv1[] = { + 0xf1, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static const uint8_t ms_aes_cbc_cipher1[] = { + 0x5A, 0x7A, 0x67, 0x5D, 0xB8, 0xE1, 0xDC, 0x71, + 0x39, 0xA8, 0x74, 0x93, 0x9C, 0x4C, 0xFE, 0x23, + 0x61, 0xCD, 0xA4, 0xB3, 0xD9, 0xCE, 0x99, 0x09, + 0x2A, 0x23, 0xF3, 0x29, 0xBF, 0x4C, 0xB4, 0x6A, + 0x1B, 0x6B, 0x73, 0x4D, 0x48, 0x0C, 0xCF, 0x6C, + 0x5E, 0x34, 0x9E, 0x7F, 0xBC, 0x8F, 0xCC, 0x8F, + 0x75, 0x1D, 0x3D, 0x77, 0x10, 0x76, 0xC8, 0xB9, + 0x99, 0x6F, 0xD6, 0x56, 0x75, 0xA9, 0xB2, 0x66, + 0xC2, 0x24, 0x2B, 0x9C, 0xFE, 0x40, 0x8E, 0x43, + 0x20, 0x97, 0x1B, 0xFA, 0xD0, 0xCF, 0x04, 0xAB, + 0xBB, 0xF6, 0x5D, 0xF5, 0xA0, 0x19, 0x7C, 0x23, + 0x5D, 0x80, 0x8C, 0x49, 0xF6, 0x76, 0x88, 0x29, + 0x27, 0x4C, 0x59, 0x2B, 0x43, 0xA6, 0xB2, 0x26, + 0x27, 0x78, 0xBE, 0x1B, 0xE1, 0x4F, 0x5A, 0x1F, + 0xFC, 0x68, 0x08, 0xE7, 0xC4, 0xD1, 0x34, 0x68, + 0xB7, 0x13, 0x14, 0x41, 0x62, 0x6B, 0x1F, 0x77, + 0x0C, 0x68, 0x1D, 0x0D, 0xED, 0x89, 0xAA, 0xD8, + 0x97, 0x02, 0xBA, 0x5E, 0xD4, 0x84, 0x25, 0x97, + 0x03, 0xA5, 0xA6, 0x13, 0x66, 0x02, 0xF4, 0xC3, + 0xF3, 0xD3, 0xCC, 0x95, 0xC3, 0x87, 0x46, 0x90, + 0x1F, 0x6E, 0x14, 0xA8, 0x00, 0xF2, 0x6F, 0xD5, + 0xA1, 0xAD, 0xD5, 0x40, 0xA2, 0x0F, 0x32, 0x7E, + 0x99, 0xA3, 0xF5, 0x53, 0xC3, 0x26, 0xA1, 0x45, + 0x01, 0x88, 0x57, 0x84, 0x3E, 0x7B, 0x4E, 0x0B, + 0x3C, 0xB5, 0x3E, 0x9E, 0xE9, 0x78, 0x77, 0xC5, + 0xC0, 0x89, 0xA8, 0xF8, 0xF1, 0xA5, 0x2D, 0x5D, + 0xF9, 0xC6, 0xFB, 0xCB, 0x05, 0x23, 0xBD, 0x6E, + 0x5E, 0x14, 0xC6, 0x57, 0x73, 0xCF, 0x98, 0xBD, + 0x10, 0x8B, 0x18, 0xA6, 0x01, 0x5B, 0x13, 0xAE, + 0x8E, 0xDE, 0x1F, 0xB5, 0xB7, 0x40, 0x6C, 0xC1, + 0x1E, 0xA1, 0x19, 0x20, 0x9E, 0x95, 0xE0, 0x2F, + 0x1C, 0xF5, 0xD9, 0xD0, 0x2B, 0x1E, 0x82, 0x25, + 0x62, 0xB4, 0xEB, 0xA1, 0x1F, 0xCE, 0x44, 0xA1, + 0xCB, 0x92, 0x01, 0x6B, 0xE4, 0x26, 0x23, 0xE3, + 0xC5, 0x67, 0x35, 0x55, 0xDA, 0xE5, 0x27, 0xEE, + 0x8D, 0x12, 0x84, 0xB7, 0xBA, 0xA7, 0x1C, 0xD6, + 0x32, 0x3F, 0x67, 0xED, 0xFB, 0x5B, 0x8B, 0x52, + 0x46, 0x8C, 0xF9, 0x69, 0xCD, 0xAE, 0x79, 0xAA, + 0x37, 0x78, 0x49, 0xEB, 0xC6, 0x8E, 0x76, 0x63, + 0x84, 0xFF, 0x9D, 0x22, 0x99, 0x51, 0xB7, 0x5E, + 0x83, 0x4C, 0x8B, 0xDF, 0x5A, 0x07, 0xCC, 0xBA, + 0x42, 0xA5, 0x98, 0xB6, 0x47, 0x0E, 0x66, 0xEB, + 0x23, 0x0E, 0xBA, 0x44, 0xA8, 0xAA, 0x20, 0x71, + 0x79, 0x9C, 0x77, 0x5F, 0xF5, 0xFE, 0xEC, 0xEF, + 0xC6, 0x64, 0x3D, 0x84, 0xD0, 0x2B, 0xA7, 0x0A, + 0xC3, 0x72, 0x5B, 0x9C, 0xFA, 0xA8, 0x87, 0x95, + 0x94, 0x11, 0x38, 0xA7, 0x1E, 0x58, 0xE3, 0x73, + 0xC6, 0xC9, 0xD1, 0x7B, 0x92, 0xDB, 0x0F, 0x49, + 0x74, 0xC2, 0xA2, 0x0E, 0x35, 0x57, 0xAC, 0xDB, + 0x9A, 0x1C, 0xCF, 0x5A, 0x32, 0x3E, 0x26, 0x9B, + 0xEC, 0xB3, 0xEF, 0x9C, 0xFE, 0xBE, 0x52, 0xAC, + 0xB1, 0x29, 0xDD, 0xFD, 0x07, 0xE2, 0xEE, 0xED, + 0xE4, 0x46, 0x37, 0xFE, 0xD1, 0xDC, 0xCD, 0x02, + 0xF9, 0x31, 0xB0, 0xFB, 0x36, 0xB7, 0x34, 0xA4, + 0x76, 0xE8, 0x57, 0xBF, 0x99, 0x92, 0xC7, 0xAF, + 0x98, 0x10, 0xE2, 0x70, 0xCA, 0xC9, 0x2B, 0x82, + 0x06, 0x96, 0x88, 0x0D, 0xB3, 0xAC, 0x9E, 0x6D, + 0x43, 0xBC, 0x5B, 0x31, 0xCF, 0x65, 0x8D, 0xA6, + 0xC7, 0xFE, 0x73, 0xE1, 0x54, 0xF7, 0x10, 0xF9, + 0x86, 0xF7, 0xDF, 0xA1, 0xA1, 0xD8, 0xAE, 0x35, + 0xB3, 0x90, 0xDC, 0x6F, 0x43, 0x7A, 0x8B, 0xE0, + 0xFE, 0x8F, 0x33, 0x4D, 0x29, 0x6C, 0x45, 0x53, + 0x73, 0xDD, 0x21, 0x0B, 0x85, 0x30, 0xB5, 0xA5, + 0xF3, 0x5D, 0xEC, 0x79, 0x61, 0x9D, 0x9E, 0xB3 + +}; + +static uint8_t ms_hmac_key1[] = { + 0xFE, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 +}; + +static const uint8_t ms_hmac_digest1[] = { + 0xCE, 0x6E, 0x5F, 0x77, 0x96, 0x9A, 0xB1, 0x69, + 0x2D, 0x5E, 0xF3, 0x2F, 0x32, 0x10, 0xCB, 0x50, + 0x0E, 0x09, 0x56, 0x25, 0x07, 0x34, 0xC9, 0x20, + 0xEC, 0x13, 0x43, 0x23, 0x5C, 0x08, 0x8B, 0xCD, + 0xDC, 0x86, 0x8C, 0xEE, 0x0A, 0x95, 0x2E, 0xB9, + 0x8C, 0x7B, 0x02, 0x7A, 0xD4, 0xE1, 0x49, 0xB4, + 0x45, 0xB5, 0x52, 0x37, 0xC6, 0xFF, 0xFE, 0xAA, + 0x0A, 0x87, 0xB8, 0x51, 0xF9, 0x2A, 0x01, 0x8F +}; +/* End Session 1 */ +/* Begin Session 2 */ +static uint8_t ms_aes_cbc_key2[] = { + 0xff, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static uint8_t ms_aes_cbc_iv2[] = { + 0xff, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static const uint8_t ms_aes_cbc_cipher2[] = { + 0xBB, 0x3C, 0x68, 0x25, 0xFD, 0xB6, 0xA2, 0x91, + 0x20, 0x56, 0xF6, 0x30, 0x35, 0xFC, 0x9E, 0x97, + 0xF2, 0x90, 0xFC, 0x7E, 0x3E, 0x0A, 0x75, 0xC8, + 0x4C, 0xF2, 0x2D, 0xAC, 0xD3, 0x93, 0xF0, 0xC5, + 0x14, 0x88, 0x8A, 0x23, 0xC2, 0x59, 0x9A, 0x98, + 0x4B, 0xD5, 0x2C, 0xDA, 0x43, 0xA9, 0x34, 0x69, + 0x7C, 0x6D, 0xDB, 0xDC, 0xCB, 0xC0, 0xA0, 0x09, + 0xA7, 0x86, 0x16, 0x4B, 0xBF, 0xA8, 0xB6, 0xCF, + 0x7F, 0x74, 0x1F, 0x22, 0xF0, 0xF6, 0xBB, 0x44, + 0x8B, 0x4C, 0x9E, 0x23, 0xF8, 0x9F, 0xFC, 0x5B, + 0x9E, 0x9C, 0x2A, 0x79, 0x30, 0x8F, 0xBF, 0xA9, + 0x68, 0xA1, 0x20, 0x71, 0x7C, 0x77, 0x22, 0x34, + 0x07, 0xCD, 0xC6, 0xF6, 0x50, 0x0A, 0x08, 0x99, + 0x17, 0x98, 0xE3, 0x93, 0x8A, 0xB0, 0xEE, 0xDF, + 0xC2, 0xBA, 0x3B, 0x44, 0x73, 0xDF, 0xDD, 0xDC, + 0x14, 0x4D, 0x3B, 0xBB, 0x5E, 0x58, 0xC1, 0x26, + 0xA7, 0xAE, 0x47, 0xF3, 0x24, 0x6D, 0x4F, 0xD3, + 0x6E, 0x3E, 0x33, 0xE6, 0x7F, 0xCA, 0x50, 0xAF, + 0x5D, 0x3D, 0xA0, 0xDD, 0xC9, 0xF3, 0x30, 0xD3, + 0x6E, 0x8B, 0x2E, 0x12, 0x24, 0x34, 0xF0, 0xD3, + 0xC7, 0x8D, 0x23, 0x29, 0xAA, 0x05, 0xE1, 0xFA, + 0x2E, 0xF6, 0x8D, 0x37, 0x86, 0xC0, 0x6D, 0x13, + 0x2D, 0x98, 0xF3, 0x52, 0x39, 0x22, 0xCE, 0x38, + 0xC2, 0x1A, 0x72, 0xED, 0xFB, 0xCC, 0xE4, 0x71, + 0x5A, 0x0C, 0x0D, 0x09, 0xF8, 0xE8, 0x1B, 0xBC, + 0x53, 0xC8, 0xD8, 0x8F, 0xE5, 0x98, 0x5A, 0xB1, + 0x06, 0xA6, 0x5B, 0xE6, 0xA2, 0x88, 0x21, 0x9E, + 0x36, 0xC0, 0x34, 0xF9, 0xFB, 0x3B, 0x0A, 0x22, + 0x00, 0x00, 0x39, 0x48, 0x8D, 0x23, 0x74, 0x62, + 0x72, 0x91, 0xE6, 0x36, 0xAA, 0x77, 0x9C, 0x72, + 0x9D, 0xA8, 0xC3, 0xA9, 0xD5, 0x44, 0x72, 0xA6, + 0xB9, 0x28, 0x8F, 0x64, 0x4C, 0x8A, 0x64, 0xE6, + 0x4E, 0xFA, 0xEF, 0x87, 0xDE, 0x7B, 0x22, 0x44, + 0xB0, 0xDF, 0x2E, 0x5F, 0x0B, 0xA5, 0xF2, 0x24, + 0x07, 0x5C, 0x2D, 0x39, 0xB7, 0x3D, 0x8A, 0xE5, + 0x0E, 0x9D, 0x4E, 0x50, 0xED, 0x03, 0x99, 0x8E, + 0xF0, 0x06, 0x55, 0x4E, 0xA2, 0x24, 0xE7, 0x17, + 0x46, 0xDF, 0x6C, 0xCD, 0xC6, 0x44, 0xE8, 0xF9, + 0xB9, 0x1B, 0x36, 0xF6, 0x7F, 0x10, 0xA4, 0x7D, + 0x90, 0xBD, 0xE4, 0xAA, 0xD6, 0x9E, 0x18, 0x9D, + 0x22, 0x35, 0xD6, 0x55, 0x54, 0xAA, 0xF7, 0x22, + 0xA3, 0x3E, 0xEF, 0xC8, 0xA2, 0x34, 0x8D, 0xA9, + 0x37, 0x63, 0xA6, 0xC3, 0x57, 0xCB, 0x0C, 0x49, + 0x7D, 0x02, 0xBE, 0xAA, 0x13, 0x75, 0xB7, 0x4E, + 0x52, 0x62, 0xA5, 0xC2, 0x33, 0xC7, 0x6C, 0x1B, + 0xF6, 0x34, 0xF6, 0x09, 0xA5, 0x0C, 0xC7, 0xA2, + 0x61, 0x48, 0x62, 0x7D, 0x17, 0x15, 0xE3, 0x95, + 0xC8, 0x63, 0xD2, 0xA4, 0x43, 0xA9, 0x49, 0x07, + 0xB2, 0x3B, 0x2B, 0x62, 0x7D, 0xCB, 0x51, 0xB3, + 0x25, 0x33, 0x47, 0x0E, 0x14, 0x67, 0xDC, 0x6A, + 0x9B, 0x51, 0xAC, 0x9D, 0x8F, 0xA2, 0x2B, 0x57, + 0x8C, 0x5C, 0x5F, 0x76, 0x23, 0x92, 0x0F, 0x84, + 0x46, 0x0E, 0x40, 0x85, 0x38, 0x60, 0xFA, 0x61, + 0x20, 0xC5, 0xE3, 0xF1, 0x70, 0xAC, 0x1B, 0xBF, + 0xC4, 0x2B, 0xC5, 0x67, 0xD1, 0x43, 0xC5, 0x17, + 0x74, 0x71, 0x69, 0x6F, 0x82, 0x89, 0x19, 0x8A, + 0x70, 0x43, 0x92, 0x01, 0xC4, 0x63, 0x7E, 0xB1, + 0x59, 0x4E, 0xCD, 0xEA, 0x93, 0xA4, 0x52, 0x53, + 0x9B, 0x61, 0x5B, 0xD2, 0x3E, 0x19, 0x39, 0xB7, + 0x32, 0xEA, 0x8E, 0xF8, 0x1D, 0x76, 0x5C, 0xB2, + 0x73, 0x2D, 0x91, 0xC0, 0x18, 0xED, 0x25, 0x2A, + 0x53, 0x64, 0xF0, 0x92, 0x31, 0x55, 0x21, 0xA8, + 0x24, 0xA9, 0xD1, 0x02, 0xF6, 0x6C, 0x2B, 0x70, + 0xA9, 0x59, 0xC1, 0xD6, 0xC3, 0x57, 0x5B, 0x92 +}; + +static uint8_t ms_hmac_key2[] = { + 0xFC, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA, + 0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76, + 0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60, + 0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1, + 0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0, + 0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76, + 0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60 +}; + +static const uint8_t ms_hmac_digest2[] = { + 0xA5, 0x0F, 0x9C, 0xFB, 0x08, 0x62, 0x59, 0xFF, + 0x80, 0x2F, 0xEB, 0x4B, 0xE1, 0x46, 0x21, 0xD6, + 0x02, 0x98, 0xF2, 0x8E, 0xF4, 0xEC, 0xD4, 0x77, + 0x86, 0x4C, 0x31, 0x28, 0xC8, 0x25, 0x80, 0x27, + 0x3A, 0x72, 0x5D, 0x6A, 0x56, 0x8A, 0xD3, 0x82, + 0xB0, 0xEC, 0x31, 0x6D, 0x8B, 0x6B, 0xB4, 0x24, + 0xE7, 0x62, 0xC1, 0x52, 0xBC, 0x14, 0x1B, 0x8E, + 0xEC, 0x9A, 0xF1, 0x47, 0x80, 0xD2, 0xB0, 0x59 +}; + +/* End Session 2 */ + + static int test_AES_CBC_HMAC_SHA1_encrypt_digest(void) { @@ -1145,6 +1478,38 @@ test_AES_chain_mb_all(void) } static int +test_AES_chain_libcrypto_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_LIBCRYPTO_PMD, + BLKCIPHER_AES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_AES_cipheronly_libcrypto_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_LIBCRYPTO_PMD, + BLKCIPHER_AES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int test_AES_chain_qat_all(void) { struct crypto_testsuite_params *ts_params = &testsuite_params; @@ -1160,6 +1525,22 @@ test_AES_chain_qat_all(void) return TEST_SUCCESS; } +static int +test_authonly_libcrypto_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_LIBCRYPTO_PMD, + BLKCIPHER_AUTHONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + /* ***** SNOW 3G Tests ***** */ static int create_wireless_algo_hash_session(uint8_t dev_id, @@ -3411,6 +3792,70 @@ test_zuc_hash_generate_test_case_5(void) return test_zuc_authentication(&zuc_hash_test_case_5); } +static int +test_3DES_chain_qat_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_QAT_SYM_PMD, + BLKCIPHER_3DES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_cipheronly_qat_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_QAT_SYM_PMD, + BLKCIPHER_3DES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_chain_libcrypto_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_LIBCRYPTO_PMD, + BLKCIPHER_3DES_CHAIN_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + +static int +test_3DES_cipheronly_libcrypto_all(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + int status; + + status = test_blockcipher_all_tests(ts_params->mbuf_pool, + ts_params->op_mpool, ts_params->valid_devs[0], + RTE_CRYPTODEV_LIBCRYPTO_PMD, + BLKCIPHER_3DES_CIPHERONLY_TYPE); + + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + return TEST_SUCCESS; +} + /* ***** AES-GCM Tests ***** */ static int @@ -4104,6 +4549,119 @@ test_multi_session(void) return TEST_SUCCESS; } +struct multi_session_params { + struct crypto_unittest_params ut_params; + uint8_t *cipher_key; + uint8_t *hmac_key; + const uint8_t *cipher; + const uint8_t *digest; + uint8_t *iv; +}; + +#define MB_SESSION_NUMBER 3 + +static int +test_multi_session_random_usage(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_cryptodev_info dev_info; + struct rte_cryptodev_sym_session **sessions; + uint32_t i, j; + struct multi_session_params ut_paramz[] = { + + { + .cipher_key = ms_aes_cbc_key0, + .hmac_key = ms_hmac_key0, + .cipher = ms_aes_cbc_cipher0, + .digest = ms_hmac_digest0, + .iv = ms_aes_cbc_iv0 + }, + { + .cipher_key = ms_aes_cbc_key1, + .hmac_key = ms_hmac_key1, + .cipher = ms_aes_cbc_cipher1, + .digest = ms_hmac_digest1, + .iv = ms_aes_cbc_iv1 + }, + { + .cipher_key = ms_aes_cbc_key2, + .hmac_key = ms_hmac_key2, + .cipher = ms_aes_cbc_cipher2, + .digest = ms_hmac_digest2, + .iv = ms_aes_cbc_iv2 + }, + + }; + + rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info); + + sessions = rte_malloc(NULL, + (sizeof(struct rte_cryptodev_sym_session *) + * dev_info.sym.max_nb_sessions) + 1, 0); + + for (i = 0; i < MB_SESSION_NUMBER; i++) { + rte_memcpy(&ut_paramz[i].ut_params, &testsuite_params, + sizeof(struct crypto_unittest_params)); + + test_AES_CBC_HMAC_SHA512_decrypt_create_session_params( + &ut_paramz[i].ut_params, + ut_paramz[i].cipher_key, ut_paramz[i].hmac_key); + + /* Create multiple crypto sessions*/ + sessions[i] = rte_cryptodev_sym_session_create( + ts_params->valid_devs[0], + &ut_paramz[i].ut_params.auth_xform); + + TEST_ASSERT_NOT_NULL(sessions[i], + "Session creation failed at session number %u", + i); + + } + + srand(time(NULL)); + for (i = 0; i < 40000; i++) { + + j = rand() % MB_SESSION_NUMBER; + + TEST_ASSERT_SUCCESS( + test_AES_CBC_HMAC_SHA512_decrypt_perform( + sessions[j], + &ut_paramz[j].ut_params, + ts_params, ut_paramz[j].cipher, + ut_paramz[j].digest, + ut_paramz[j].iv), + "Failed to perform decrypt on request number %u.", i); + + if (ut_paramz[j].ut_params.op) + rte_crypto_op_free(ut_paramz[j].ut_params.op); + + /* + * free mbuf - both obuf and ibuf are usually the same, + * so check if they point at the same address is necessary, + * to avoid freeing the mbuf twice. + */ + if (ut_paramz[j].ut_params.obuf) { + rte_pktmbuf_free(ut_paramz[j].ut_params.obuf); + if (ut_paramz[j].ut_params.ibuf + == ut_paramz[j].ut_params.obuf) + ut_paramz[j].ut_params.ibuf = 0; + ut_paramz[j].ut_params.obuf = 0; + } + if (ut_paramz[j].ut_params.ibuf) { + rte_pktmbuf_free(ut_paramz[j].ut_params.ibuf); + ut_paramz[j].ut_params.ibuf = 0; + } + } + + for (i = 0; i < MB_SESSION_NUMBER; i++) + rte_cryptodev_sym_session_free(ts_params->valid_devs[0], + sessions[i]); + + rte_free(sessions); + + return TEST_SUCCESS; +} + static int test_null_cipher_only_operation(void) { @@ -4457,6 +5015,15 @@ test_null_burst_operation(void) return TEST_SUCCESS; } +static void +generate_gmac_large_plaintext(uint8_t *data) +{ + uint16_t i; + + for (i = 32; i < GMAC_LARGE_PLAINTEXT_LENGTH; i += 32) + memcpy(&data[i], &data[0], 32); +} + static int create_gmac_operation(enum rte_crypto_auth_operation op, const struct gmac_test_data *tdata) @@ -4471,6 +5038,14 @@ create_gmac_operation(enum rte_crypto_auth_operation op, iv_pad_len = RTE_ALIGN_CEIL(tdata->iv.len, 16); aad_pad_len = RTE_ALIGN_CEIL(tdata->aad.len, 16); + /* + * Runtime generate the large plain text instead of use hard code + * plain text vector. It is done to avoid create huge source file + * with the test vector. + */ + if (tdata->aad.len == GMAC_LARGE_PLAINTEXT_LENGTH) + generate_gmac_large_plaintext(tdata->aad.data); + /* Generate Crypto op data structure */ ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool, RTE_CRYPTO_OP_TYPE_SYMMETRIC); @@ -4648,6 +5223,12 @@ test_AES_GMAC_authentication_test_case_3(void) } static int +test_AES_GMAC_authentication_test_case_4(void) +{ + return test_AES_GMAC_authentication(&gmac_test_case_4); +} + +static int test_AES_GMAC_authentication_verify(const struct gmac_test_data *tdata) { struct crypto_testsuite_params *ts_params = &testsuite_params; @@ -4707,64 +5288,782 @@ test_AES_GMAC_authentication_verify_test_case_3(void) return test_AES_GMAC_authentication_verify(&gmac_test_case_3); } -static struct unit_test_suite cryptodev_qat_testsuite = { - .suite_name = "Crypto QAT Unit Test Suite", - .setup = testsuite_setup, - .teardown = testsuite_teardown, - .unit_test_cases = { - TEST_CASE_ST(ut_setup, ut_teardown, - test_device_configure_invalid_dev_id), - TEST_CASE_ST(ut_setup, ut_teardown, - test_device_configure_invalid_queue_pair_ids), - TEST_CASE_ST(ut_setup, ut_teardown, - test_queue_pair_descriptor_setup), - TEST_CASE_ST(ut_setup, ut_teardown, - test_multi_session), +static int +test_AES_GMAC_authentication_verify_test_case_4(void) +{ + return test_AES_GMAC_authentication_verify(&gmac_test_case_4); +} - TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_qat_all), - TEST_CASE_ST(ut_setup, ut_teardown, test_stats), +struct test_crypto_vector { + enum rte_crypto_cipher_algorithm crypto_algo; - /** AES GCM Authenticated Encryption */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_encryption_test_case_7), + struct { + uint8_t data[64]; + unsigned int len; + } cipher_key; - /** AES GCM Authenticated Decryption */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_3), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_4), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_5), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_6), - TEST_CASE_ST(ut_setup, ut_teardown, - test_mb_AES_GCM_authenticated_decryption_test_case_7), + struct { + uint8_t data[64]; + unsigned int len; + } iv; - /** AES GMAC Authentication */ - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_verify_test_case_1), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_test_case_2), - TEST_CASE_ST(ut_setup, ut_teardown, - test_AES_GMAC_authentication_verify_test_case_2), + struct { + const uint8_t *data; + unsigned int len; + } plaintext; + + struct { + const uint8_t *data; + unsigned int len; + } ciphertext; + + enum rte_crypto_auth_algorithm auth_algo; + + struct { + uint8_t data[128]; + unsigned int len; + } auth_key; + + struct { + const uint8_t *data; + unsigned int len; + } aad; + + struct { + uint8_t data[128]; + unsigned int len; + } digest; +}; + +static const struct test_crypto_vector +hmac_sha1_test_crypto_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .plaintext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0xC4, 0xB7, 0x0E, 0x6B, 0xDE, 0xD1, 0xE7, 0x77, + 0x7E, 0x2E, 0x8F, 0xFC, 0x48, 0x39, 0x46, 0x17, + 0x3F, 0x91, 0x64, 0x59 + }, + .len = 20 + } +}; + +static const struct test_crypto_vector +aes128_gmac_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_AES_GMAC, + .crypto_algo = RTE_CRYPTO_CIPHER_AES_GCM, + .aad = { + .data = plaintext_hash, + .len = 512 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B + }, + .len = 12 + }, + .cipher_key = { + .data = { + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA + }, + .len = 16 + }, + .digest = { + .data = { + 0xCA, 0x00, 0x99, 0x8B, 0x30, 0x7E, 0x74, 0x56, + 0x32, 0xA7, 0x87, 0xB5, 0xE9, 0xB2, 0x34, 0x5A + }, + .len = 16 + } +}; + +static const struct test_crypto_vector +aes128cbc_hmac_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_hash, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60, + 0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1, + 0x18, 0x8C, 0x1D, 0x32 + }, + .len = 20 + } +}; + +static void +data_corruption(uint8_t *data) +{ + data[0] += 1; +} + +static void +tag_corruption(uint8_t *data, unsigned int tag_offset) +{ + data[tag_offset] += 1; +} + +static int +create_auth_session(struct crypto_unittest_params *ut_params, + uint8_t dev_id, + const struct test_crypto_vector *reference, + enum rte_crypto_auth_operation auth_op) +{ + uint8_t auth_key[reference->auth_key.len + 1]; + + memcpy(auth_key, reference->auth_key.data, reference->auth_key.len); + + /* Setup Authentication Parameters */ + ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; + ut_params->auth_xform.auth.op = auth_op; + ut_params->auth_xform.next = NULL; + ut_params->auth_xform.auth.algo = reference->auth_algo; + ut_params->auth_xform.auth.key.length = reference->auth_key.len; + ut_params->auth_xform.auth.key.data = auth_key; + ut_params->auth_xform.auth.digest_length = reference->digest.len; + ut_params->auth_xform.auth.add_auth_data_length = reference->aad.len; + + /* Create Crypto session*/ + ut_params->sess = rte_cryptodev_sym_session_create(dev_id, + &ut_params->auth_xform); + + TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); + + return 0; +} + +static int +create_auth_cipher_session(struct crypto_unittest_params *ut_params, + uint8_t dev_id, + const struct test_crypto_vector *reference, + enum rte_crypto_auth_operation auth_op, + enum rte_crypto_cipher_operation cipher_op) +{ + uint8_t cipher_key[reference->cipher_key.len + 1]; + uint8_t auth_key[reference->auth_key.len + 1]; + + memcpy(cipher_key, reference->cipher_key.data, + reference->cipher_key.len); + memcpy(auth_key, reference->auth_key.data, reference->auth_key.len); + + /* Setup Authentication Parameters */ + ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; + ut_params->auth_xform.auth.op = auth_op; + ut_params->auth_xform.next = &ut_params->cipher_xform; + ut_params->auth_xform.auth.algo = reference->auth_algo; + ut_params->auth_xform.auth.key.length = reference->auth_key.len; + ut_params->auth_xform.auth.key.data = auth_key; + ut_params->auth_xform.auth.digest_length = reference->digest.len; + ut_params->auth_xform.auth.add_auth_data_length = reference->aad.len; + + /* Setup Cipher Parameters */ + ut_params->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; + ut_params->cipher_xform.next = NULL; + ut_params->cipher_xform.cipher.algo = reference->crypto_algo; + ut_params->cipher_xform.cipher.op = cipher_op; + ut_params->cipher_xform.cipher.key.data = cipher_key; + ut_params->cipher_xform.cipher.key.length = reference->cipher_key.len; + + /* Create Crypto session*/ + ut_params->sess = rte_cryptodev_sym_session_create(dev_id, + &ut_params->auth_xform); + + TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); + + return 0; +} + +static int +create_auth_operation(struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int auth_generate) +{ + /* Generate Crypto op data structure */ + ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC); + TEST_ASSERT_NOT_NULL(ut_params->op, + "Failed to allocate pktmbuf offload"); + + /* Set crypto operation data parameters */ + rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); + + struct rte_crypto_sym_op *sym_op = ut_params->op->sym; + + /* set crypto operation source mbuf */ + sym_op->m_src = ut_params->ibuf; + + /* digest */ + sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( + ut_params->ibuf, reference->digest.len); + + TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, + "no room to append auth tag"); + + sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( + ut_params->ibuf, reference->plaintext.len); + sym_op->auth.digest.length = reference->digest.len; + + if (auth_generate) + memset(sym_op->auth.digest.data, 0, reference->digest.len); + else + memcpy(sym_op->auth.digest.data, + reference->digest.data, + reference->digest.len); + + TEST_HEXDUMP(stdout, "digest:", + sym_op->auth.digest.data, + sym_op->auth.digest.length); + + sym_op->auth.data.length = reference->plaintext.len; + sym_op->auth.data.offset = 0; + + return 0; +} + +static int +create_auth_GMAC_operation(struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int auth_generate) +{ + /* Generate Crypto op data structure */ + ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC); + TEST_ASSERT_NOT_NULL(ut_params->op, + "Failed to allocate pktmbuf offload"); + + /* Set crypto operation data parameters */ + rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); + + struct rte_crypto_sym_op *sym_op = ut_params->op->sym; + + /* set crypto operation source mbuf */ + sym_op->m_src = ut_params->ibuf; + + /* aad */ + sym_op->auth.aad.data = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + reference->aad.len); + TEST_ASSERT_NOT_NULL(sym_op->auth.aad.data, "no room to append AAD"); + memcpy(sym_op->auth.aad.data, reference->aad.data, reference->aad.len); + + TEST_HEXDUMP(stdout, "AAD:", sym_op->auth.aad.data, reference->aad.len); + + sym_op->auth.aad.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); + sym_op->auth.aad.length = reference->aad.len; + + /* digest */ + sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( + ut_params->ibuf, reference->digest.len); + + TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, + "no room to append auth tag"); + + sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( + ut_params->ibuf, reference->ciphertext.len); + sym_op->auth.digest.length = reference->digest.len; + + if (auth_generate) + memset(sym_op->auth.digest.data, 0, reference->digest.len); + else + memcpy(sym_op->auth.digest.data, + reference->digest.data, + reference->digest.len); + + TEST_HEXDUMP(stdout, "digest:", + sym_op->auth.digest.data, + sym_op->auth.digest.length); + + sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend( + ut_params->ibuf, reference->iv.len); + TEST_ASSERT_NOT_NULL(sym_op->cipher.iv.data, "no room to prepend iv"); + + sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); + sym_op->cipher.iv.length = reference->iv.len; + + memcpy(sym_op->cipher.iv.data, reference->iv.data, reference->iv.len); + + sym_op->cipher.data.length = 0; + sym_op->cipher.data.offset = 0; + + sym_op->auth.data.length = 0; + sym_op->auth.data.offset = 0; + + return 0; +} + +static int +create_cipher_auth_operation(struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int auth_generate) +{ + /* Generate Crypto op data structure */ + ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC); + TEST_ASSERT_NOT_NULL(ut_params->op, + "Failed to allocate pktmbuf offload"); + + /* Set crypto operation data parameters */ + rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess); + + struct rte_crypto_sym_op *sym_op = ut_params->op->sym; + + /* set crypto operation source mbuf */ + sym_op->m_src = ut_params->ibuf; + + /* digest */ + sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append( + ut_params->ibuf, reference->digest.len); + + TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, + "no room to append auth tag"); + + sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( + ut_params->ibuf, reference->ciphertext.len); + sym_op->auth.digest.length = reference->digest.len; + + if (auth_generate) + memset(sym_op->auth.digest.data, 0, reference->digest.len); + else + memcpy(sym_op->auth.digest.data, + reference->digest.data, + reference->digest.len); + + TEST_HEXDUMP(stdout, "digest:", + sym_op->auth.digest.data, + sym_op->auth.digest.length); + + sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend( + ut_params->ibuf, reference->iv.len); + TEST_ASSERT_NOT_NULL(sym_op->cipher.iv.data, "no room to prepend iv"); + + sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); + sym_op->cipher.iv.length = reference->iv.len; + + memcpy(sym_op->cipher.iv.data, reference->iv.data, reference->iv.len); + + sym_op->cipher.data.length = reference->ciphertext.len; + sym_op->cipher.data.offset = reference->iv.len; + + sym_op->auth.data.length = reference->ciphertext.len; + sym_op->auth.data.offset = reference->iv.len; + + return 0; +} + +static int +create_auth_verify_operation(struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return create_auth_operation(ts_params, ut_params, reference, 0); +} + +static int +create_auth_verify_GMAC_operation( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return create_auth_GMAC_operation(ts_params, ut_params, reference, 0); +} + +static int +create_cipher_auth_verify_operation(struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return create_cipher_auth_operation(ts_params, ut_params, reference, 0); +} + +static int +test_authentication_verify_fail_when_data_corruption( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int data_corrupted) +{ + int retval; + + uint8_t *plaintext; + + /* Create session */ + retval = create_auth_session(ut_params, + ts_params->valid_devs[0], + reference, + RTE_CRYPTO_AUTH_OP_VERIFY); + if (retval < 0) + return retval; + + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + TEST_ASSERT_NOT_NULL(ut_params->ibuf, + "Failed to allocate input buffer in mempool"); + + /* clear mbuf payload */ + memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->ibuf)); + + plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + reference->plaintext.len); + TEST_ASSERT_NOT_NULL(plaintext, "no room to append plaintext"); + memcpy(plaintext, reference->plaintext.data, reference->plaintext.len); + + TEST_HEXDUMP(stdout, "plaintext:", plaintext, reference->plaintext.len); + + /* Create operation */ + retval = create_auth_verify_operation(ts_params, ut_params, reference); + + if (retval < 0) + return retval; + + if (data_corrupted) + data_corruption(plaintext); + else + tag_corruption(plaintext, reference->plaintext.len); + + ut_params->op = process_crypto_request(ts_params->valid_devs[0], + ut_params->op); + TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process"); + TEST_ASSERT_EQUAL(ut_params->op->status, + RTE_CRYPTO_OP_STATUS_AUTH_FAILED, + "authentication not failed"); + + ut_params->obuf = ut_params->op->sym->m_src; + TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf"); + + return 0; +} + +static int +test_authentication_verify_GMAC_fail_when_corruption( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int data_corrupted) +{ + int retval; + + /* Create session */ + retval = create_auth_cipher_session(ut_params, + ts_params->valid_devs[0], + reference, + RTE_CRYPTO_AUTH_OP_VERIFY, + RTE_CRYPTO_CIPHER_OP_DECRYPT); + if (retval < 0) + return retval; + + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + TEST_ASSERT_NOT_NULL(ut_params->ibuf, + "Failed to allocate input buffer in mempool"); + + /* clear mbuf payload */ + memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->ibuf)); + + /* Create operation */ + retval = create_auth_verify_GMAC_operation(ts_params, + ut_params, + reference); + + if (retval < 0) + return retval; + + if (data_corrupted) + data_corruption(ut_params->op->sym->auth.aad.data); + else + tag_corruption(ut_params->op->sym->auth.aad.data, + reference->aad.len); + + ut_params->op = process_crypto_request(ts_params->valid_devs[0], + ut_params->op); + TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process"); + TEST_ASSERT_EQUAL(ut_params->op->status, + RTE_CRYPTO_OP_STATUS_AUTH_FAILED, + "authentication not failed"); + + ut_params->obuf = ut_params->op->sym->m_src; + TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf"); + + return 0; +} + +static int +test_authenticated_decryption_fail_when_corruption( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference, + unsigned int data_corrupted) +{ + int retval; + + uint8_t *ciphertext; + + /* Create session */ + retval = create_auth_cipher_session(ut_params, + ts_params->valid_devs[0], + reference, + RTE_CRYPTO_AUTH_OP_VERIFY, + RTE_CRYPTO_CIPHER_OP_DECRYPT); + if (retval < 0) + return retval; + + ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool); + TEST_ASSERT_NOT_NULL(ut_params->ibuf, + "Failed to allocate input buffer in mempool"); + + /* clear mbuf payload */ + memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0, + rte_pktmbuf_tailroom(ut_params->ibuf)); + + ciphertext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + reference->ciphertext.len); + TEST_ASSERT_NOT_NULL(ciphertext, "no room to append ciphertext"); + memcpy(ciphertext, reference->ciphertext.data, + reference->ciphertext.len); + + /* Create operation */ + retval = create_cipher_auth_verify_operation(ts_params, + ut_params, + reference); + + if (retval < 0) + return retval; + + if (data_corrupted) + data_corruption(ciphertext); + else + tag_corruption(ciphertext, reference->ciphertext.len); + + ut_params->op = process_crypto_request(ts_params->valid_devs[0], + ut_params->op); + + TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process"); + TEST_ASSERT_EQUAL(ut_params->op->status, + RTE_CRYPTO_OP_STATUS_AUTH_FAILED, + "authentication not failed"); + + ut_params->obuf = ut_params->op->sym->m_src; + TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf"); + + return 0; +} + +static int +test_authentication_verify_fail_when_data_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authentication_verify_fail_when_data_corruption( + ts_params, ut_params, reference, 1); +} + +static int +test_authentication_verify_fail_when_tag_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authentication_verify_fail_when_data_corruption( + ts_params, ut_params, reference, 0); +} + +static int +test_authentication_verify_GMAC_fail_when_data_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authentication_verify_GMAC_fail_when_corruption( + ts_params, ut_params, reference, 1); +} + +static int +test_authentication_verify_GMAC_fail_when_tag_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authentication_verify_GMAC_fail_when_corruption( + ts_params, ut_params, reference, 0); +} + +static int +test_authenticated_decryption_fail_when_data_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authenticated_decryption_fail_when_corruption( + ts_params, ut_params, reference, 1); +} + +static int +test_authenticated_decryption_fail_when_tag_corrupted( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +{ + return test_authenticated_decryption_fail_when_corruption( + ts_params, ut_params, reference, 0); +} + +static int +authentication_verify_HMAC_SHA1_fail_data_corrupt(void) +{ + return test_authentication_verify_fail_when_data_corrupted( + &testsuite_params, &unittest_params, + &hmac_sha1_test_crypto_vector); +} + +static int +authentication_verify_HMAC_SHA1_fail_tag_corrupt(void) +{ + return test_authentication_verify_fail_when_tag_corrupted( + &testsuite_params, &unittest_params, + &hmac_sha1_test_crypto_vector); +} + +static int +authentication_verify_AES128_GMAC_fail_data_corrupt(void) +{ + return test_authentication_verify_GMAC_fail_when_data_corrupted( + &testsuite_params, &unittest_params, + &aes128_gmac_test_vector); +} + +static int +authentication_verify_AES128_GMAC_fail_tag_corrupt(void) +{ + return test_authentication_verify_GMAC_fail_when_tag_corrupted( + &testsuite_params, &unittest_params, + &aes128_gmac_test_vector); +} + +static int +auth_decryption_AES128CBC_HMAC_SHA1_fail_data_corrupt(void) +{ + return test_authenticated_decryption_fail_when_data_corrupted( + &testsuite_params, + &unittest_params, + &aes128cbc_hmac_sha1_test_vector); +} + +static int +auth_decryption_AES128CBC_HMAC_SHA1_fail_tag_corrupt(void) +{ + return test_authenticated_decryption_fail_when_tag_corrupted( + &testsuite_params, + &unittest_params, + &aes128cbc_hmac_sha1_test_vector); +} + +static struct unit_test_suite cryptodev_qat_testsuite = { + .suite_name = "Crypto QAT Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, + test_device_configure_invalid_dev_id), + TEST_CASE_ST(ut_setup, ut_teardown, + test_device_configure_invalid_queue_pair_ids), + TEST_CASE_ST(ut_setup, ut_teardown, + test_queue_pair_descriptor_setup), + TEST_CASE_ST(ut_setup, ut_teardown, + test_multi_session), + + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_qat_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_3DES_chain_qat_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_3DES_cipheronly_qat_all), + TEST_CASE_ST(ut_setup, ut_teardown, test_stats), + + /** AES GCM Authenticated Encryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_7), + + /** AES GCM Authenticated Decryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_7), + + /** AES GMAC Authentication */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_2), TEST_CASE_ST(ut_setup, ut_teardown, test_AES_GMAC_authentication_test_case_3), TEST_CASE_ST(ut_setup, ut_teardown, @@ -4863,6 +6162,93 @@ static struct unit_test_suite cryptodev_aesni_mb_testsuite = { } }; +static struct unit_test_suite cryptodev_libcrypto_testsuite = { + .suite_name = "Crypto Device LIBCRYPTO Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, test_multi_session), + TEST_CASE_ST(ut_setup, ut_teardown, + test_multi_session_random_usage), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_chain_libcrypto_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_cipheronly_libcrypto_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_3DES_chain_libcrypto_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_3DES_cipheronly_libcrypto_all), + TEST_CASE_ST(ut_setup, ut_teardown, + test_authonly_libcrypto_all), + + /** AES GCM Authenticated Encryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_encryption_test_case_7), + + /** AES GCM Authenticated Decryption */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_5), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_6), + TEST_CASE_ST(ut_setup, ut_teardown, + test_mb_AES_GCM_authenticated_decryption_test_case_7), + + /** AES GMAC Authentication */ + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_1), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_2), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_3), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_test_case_4), + TEST_CASE_ST(ut_setup, ut_teardown, + test_AES_GMAC_authentication_verify_test_case_4), + + /** Negative tests */ + TEST_CASE_ST(ut_setup, ut_teardown, + authentication_verify_HMAC_SHA1_fail_data_corrupt), + TEST_CASE_ST(ut_setup, ut_teardown, + authentication_verify_HMAC_SHA1_fail_tag_corrupt), + TEST_CASE_ST(ut_setup, ut_teardown, + authentication_verify_AES128_GMAC_fail_data_corrupt), + TEST_CASE_ST(ut_setup, ut_teardown, + authentication_verify_AES128_GMAC_fail_tag_corrupt), + TEST_CASE_ST(ut_setup, ut_teardown, + auth_decryption_AES128CBC_HMAC_SHA1_fail_data_corrupt), + TEST_CASE_ST(ut_setup, ut_teardown, + auth_decryption_AES128CBC_HMAC_SHA1_fail_tag_corrupt), + + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + static struct unit_test_suite cryptodev_aesni_gcm_testsuite = { .suite_name = "Crypto Device AESNI GCM Unit Test Suite", .setup = testsuite_setup, @@ -5106,6 +6492,14 @@ test_cryptodev_aesni_mb(void /*argv __rte_unused, int argc __rte_unused*/) } static int +test_cryptodev_libcrypto(void) +{ + gbl_cryptodev_type = RTE_CRYPTODEV_LIBCRYPTO_PMD; + + return unit_test_suite_runner(&cryptodev_libcrypto_testsuite); +} + +static int test_cryptodev_aesni_gcm(void) { gbl_cryptodev_type = RTE_CRYPTODEV_AESNI_GCM_PMD; @@ -5147,6 +6541,7 @@ test_cryptodev_sw_zuc(void /*argv __rte_unused, int argc __rte_unused*/) REGISTER_TEST_COMMAND(cryptodev_qat_autotest, test_cryptodev_qat); REGISTER_TEST_COMMAND(cryptodev_aesni_mb_autotest, test_cryptodev_aesni_mb); +REGISTER_TEST_COMMAND(cryptodev_libcrypto_autotest, test_cryptodev_libcrypto); REGISTER_TEST_COMMAND(cryptodev_aesni_gcm_autotest, test_cryptodev_aesni_gcm); REGISTER_TEST_COMMAND(cryptodev_null_autotest, test_cryptodev_null); REGISTER_TEST_COMMAND(cryptodev_sw_snow3g_autotest, test_cryptodev_sw_snow3g); diff --git a/app/test/test_cryptodev.h b/app/test/test_cryptodev.h index 3c37c32..a9089aa 100644 --- a/app/test/test_cryptodev.h +++ b/app/test/test_cryptodev.h @@ -63,6 +63,7 @@ #define DIGEST_BYTE_LENGTH_SNOW3G_UIA2 (BYTE_LENGTH(32)) #define DIGEST_BYTE_LENGTH_KASUMI_F9 (BYTE_LENGTH(32)) #define AES_XCBC_MAC_KEY_SZ (16) +#define DIGEST_BYTE_LENGTH_AES_GCM (BYTE_LENGTH(128)) #define TRUNCATED_DIGEST_BYTE_LENGTH_SHA1 (12) #define TRUNCATED_DIGEST_BYTE_LENGTH_SHA224 (16) diff --git a/app/test/test_cryptodev_aes_test_vectors.h b/app/test/test_cryptodev_aes_test_vectors.h index 92c0cc2..e922cd3 100644 --- a/app/test/test_cryptodev_aes_test_vectors.h +++ b/app/test/test_cryptodev_aes_test_vectors.h @@ -634,12 +634,204 @@ static const struct blockcipher_test_data aes_test_data_9 = { } }; +static const uint8_t ciphertext512_aes192cbc[] = { + 0x45, 0xEE, 0x9A, 0xEA, 0x3C, 0x03, 0xFC, 0x4C, + 0x84, 0x36, 0xB0, 0xDA, 0xB0, 0xDC, 0xF3, 0x5B, + 0x75, 0xA7, 0xBE, 0x0E, 0xC0, 0x8D, 0x6C, 0xF8, + 0xC1, 0x0F, 0xD0, 0x35, 0x1D, 0x82, 0xAE, 0x7C, + 0x57, 0xC5, 0x7A, 0x55, 0x87, 0x1B, 0xD4, 0x03, + 0x0A, 0x64, 0xC9, 0xE0, 0xF4, 0xC7, 0x6F, 0x57, + 0x52, 0xC6, 0x73, 0xBA, 0x84, 0x0B, 0x5B, 0x89, + 0x21, 0xD2, 0x9B, 0x88, 0x68, 0xF5, 0xA9, 0x7F, + 0x3F, 0x49, 0xEB, 0xF4, 0xD4, 0x52, 0xD2, 0x64, + 0x80, 0xB2, 0x53, 0xDA, 0x19, 0xF6, 0x10, 0x24, + 0x23, 0x26, 0x7A, 0x7C, 0x07, 0x57, 0x4B, 0x0E, + 0x58, 0x49, 0x61, 0xD1, 0xDC, 0x9A, 0x32, 0x6B, + 0x0F, 0x43, 0x9E, 0x4D, 0xB4, 0x07, 0x4E, 0xB3, + 0x51, 0x74, 0xDE, 0x29, 0xBC, 0x98, 0xF9, 0xDF, + 0x78, 0x9A, 0x18, 0x9C, 0xD6, 0x7A, 0x55, 0x7C, + 0xE6, 0x1D, 0x5C, 0x1A, 0x99, 0xD2, 0xC3, 0x7B, + 0x9F, 0x96, 0x74, 0x2D, 0xE0, 0xEF, 0xD1, 0xE3, + 0x08, 0x9F, 0xAF, 0xE6, 0xED, 0xCA, 0xE1, 0xEA, + 0x23, 0x6F, 0x7C, 0x81, 0xA8, 0xC0, 0x5B, 0x8B, + 0x53, 0x90, 0x51, 0x2D, 0x0F, 0xF6, 0x7D, 0xA7, + 0x1C, 0xBD, 0x83, 0x84, 0x54, 0xA4, 0x15, 0xFB, + 0x3E, 0x25, 0xA7, 0x3A, 0x0A, 0x73, 0xD9, 0x88, + 0x6F, 0x80, 0x78, 0x95, 0x7F, 0x60, 0xAA, 0x86, + 0x8A, 0xFC, 0xDF, 0xC1, 0xCB, 0xDE, 0xBB, 0x25, + 0x52, 0x20, 0xC6, 0x79, 0xD4, 0x0F, 0x25, 0xE7, + 0xDB, 0xB2, 0x17, 0xA4, 0x6F, 0x3C, 0x6F, 0x91, + 0xF6, 0x44, 0x1E, 0xB6, 0x85, 0xBC, 0x7A, 0x14, + 0x10, 0x72, 0xBD, 0x16, 0x63, 0x39, 0x9E, 0x7B, + 0x84, 0x5B, 0x17, 0x61, 0xB1, 0x5D, 0x82, 0x0B, + 0x6D, 0x37, 0xD7, 0x79, 0xB8, 0x24, 0x91, 0x30, + 0x82, 0x91, 0x02, 0xB1, 0x18, 0x4B, 0xE0, 0xF4, + 0x13, 0x1B, 0xB2, 0x4C, 0xDA, 0xB8, 0x99, 0x96, + 0x83, 0x2F, 0xBE, 0x53, 0x8D, 0xDE, 0xFA, 0xAD, + 0xF6, 0x5C, 0xDB, 0xE5, 0x66, 0x26, 0x8F, 0x13, + 0x2B, 0x76, 0x47, 0x73, 0xDE, 0x1A, 0x74, 0xA6, + 0x30, 0xAF, 0x42, 0xA0, 0xE5, 0xD2, 0x8F, 0xC2, + 0xED, 0x3E, 0x9E, 0x29, 0x54, 0x3C, 0xDE, 0x9F, + 0x5D, 0x30, 0x2B, 0x63, 0xFB, 0xE3, 0xB1, 0x07, + 0xEE, 0x74, 0x4A, 0xAF, 0xB1, 0x20, 0x8D, 0xEC, + 0xE6, 0x78, 0x16, 0x8D, 0xA4, 0x6E, 0x34, 0x7D, + 0x47, 0xFB, 0x0B, 0xC1, 0x32, 0xD7, 0x0D, 0x6C, + 0x6F, 0x93, 0x9C, 0x5E, 0xEF, 0x1F, 0x9C, 0x45, + 0x80, 0x6B, 0x74, 0xA6, 0x81, 0xF2, 0xF6, 0xFA, + 0xAA, 0x9D, 0x4F, 0xCA, 0xB5, 0x90, 0x59, 0xB0, + 0x3B, 0xF2, 0xF0, 0x75, 0xFD, 0x8A, 0xD8, 0x97, + 0x65, 0x88, 0x56, 0x4C, 0x44, 0xDF, 0x73, 0xF7, + 0x56, 0x9C, 0x48, 0x7E, 0xB0, 0x1F, 0x1D, 0x7D, + 0x6A, 0x11, 0xF5, 0xC2, 0xF4, 0x17, 0xEF, 0x58, + 0xD8, 0x2A, 0xAF, 0x56, 0x2F, 0xCF, 0xEC, 0xA4, + 0x58, 0x8B, 0x60, 0xCE, 0xD4, 0x0F, 0x9C, 0x21, + 0xEC, 0x3E, 0x74, 0x7B, 0x81, 0x3D, 0x69, 0xC6, + 0x5E, 0x12, 0x83, 0xE9, 0xEF, 0x81, 0x58, 0x36, + 0x6A, 0x60, 0x0F, 0x54, 0x28, 0x11, 0xF9, 0x64, + 0x36, 0xAD, 0x79, 0xF5, 0x1C, 0x74, 0xD0, 0xC3, + 0x7B, 0x61, 0xE1, 0x92, 0xB0, 0x13, 0x91, 0x87, + 0x32, 0x1F, 0xF2, 0x5A, 0xDA, 0x25, 0x69, 0xEB, + 0xD7, 0x32, 0x7F, 0xF5, 0x23, 0x21, 0x54, 0x47, + 0x7B, 0x1B, 0x33, 0xB0, 0x3D, 0xF6, 0xE2, 0x7E, + 0x3E, 0xA2, 0x9E, 0xCA, 0x48, 0x0B, 0x4A, 0x29, + 0x81, 0xD4, 0x4E, 0xD5, 0x69, 0xFB, 0xCD, 0x37, + 0x8A, 0xC1, 0x5B, 0x50, 0xFF, 0xB5, 0x7D, 0x43, + 0x0F, 0xAE, 0xA6, 0xC2, 0xE5, 0x8F, 0x45, 0xB2, + 0x85, 0x99, 0x02, 0xA2, 0x9B, 0xBE, 0x90, 0x43, + 0x4F, 0x2F, 0x50, 0xE2, 0x77, 0x62, 0xD9, 0xCC +}; + +/** AES-192-CBC test vector */ +static const struct blockcipher_test_data aes_test_data_10 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes192cbc, + .len = 512 + } +}; + +static const uint8_t ciphertext512_aes256cbc[] = { + 0xF3, 0xDD, 0xF0, 0x0B, 0xFF, 0xA2, 0x6A, 0x04, + 0xBE, 0xDA, 0x52, 0xA6, 0xFE, 0x6B, 0xA6, 0xA7, + 0x48, 0x1D, 0x7D, 0x98, 0x65, 0xDB, 0xEF, 0x06, + 0x26, 0xB5, 0x8E, 0xEB, 0x05, 0x0E, 0x77, 0x98, + 0x17, 0x8E, 0xD0, 0xD4, 0x7B, 0x92, 0x8F, 0x5C, + 0xD0, 0x74, 0x5C, 0xA8, 0x4B, 0x54, 0xB6, 0x2F, + 0x83, 0x72, 0x2C, 0xFF, 0x72, 0xE9, 0xE4, 0x15, + 0x4C, 0x32, 0xAF, 0xC8, 0xC9, 0x89, 0x3C, 0x6E, + 0x31, 0xD5, 0xC0, 0x16, 0xC0, 0x31, 0x7D, 0x11, + 0xAB, 0xCB, 0xDE, 0xD2, 0xD6, 0xAA, 0x76, 0x5E, + 0xBA, 0xF6, 0xE2, 0x92, 0xCB, 0x86, 0x07, 0xFA, + 0xD4, 0x9E, 0x83, 0xED, 0xFD, 0xB8, 0x70, 0x54, + 0x6B, 0xBE, 0xEC, 0x72, 0xDD, 0x28, 0x5E, 0x95, + 0x78, 0xA5, 0x28, 0x43, 0x3D, 0x6D, 0xB1, 0xD9, + 0x69, 0x1F, 0xC9, 0x66, 0x0E, 0x32, 0x44, 0x08, + 0xD2, 0xAE, 0x2C, 0x43, 0xF2, 0xD0, 0x7D, 0x26, + 0x70, 0xE5, 0xA1, 0xCA, 0x37, 0xE9, 0x7D, 0xC7, + 0xA3, 0xFA, 0x81, 0x91, 0x64, 0xAA, 0x64, 0x91, + 0x9A, 0x95, 0x2D, 0xC9, 0xF9, 0xCE, 0xFE, 0x9F, + 0xC4, 0xD8, 0x81, 0xBE, 0x57, 0x84, 0xC5, 0x02, + 0xDB, 0x30, 0xC1, 0xD9, 0x0E, 0xA0, 0xA6, 0x00, + 0xD6, 0xF3, 0x52, 0x7E, 0x0D, 0x23, 0x6B, 0x2B, + 0x34, 0x99, 0x1F, 0x70, 0x27, 0x6D, 0x58, 0x84, + 0x93, 0x77, 0xB8, 0x3E, 0xF1, 0x71, 0x58, 0x42, + 0x8B, 0x2B, 0xC8, 0x6D, 0x05, 0x84, 0xFF, 0x4E, + 0x85, 0xEF, 0x4A, 0x9D, 0x91, 0x6A, 0xD5, 0xE1, + 0xAF, 0x01, 0xEB, 0x83, 0x8F, 0x23, 0x7C, 0x7F, + 0x12, 0x91, 0x05, 0xF0, 0x4E, 0xD9, 0x17, 0x62, + 0x75, 0xBB, 0xAC, 0x97, 0xEE, 0x3B, 0x4E, 0xC7, + 0xE5, 0x92, 0xF8, 0x9D, 0x4C, 0xF9, 0xEE, 0x55, + 0x18, 0xBB, 0xCC, 0xB4, 0xF2, 0x59, 0xB9, 0xFC, + 0x7A, 0x0F, 0x98, 0xD4, 0x8B, 0xFE, 0xF7, 0x83, + 0x46, 0xE2, 0x83, 0x33, 0x3E, 0x95, 0x8D, 0x17, + 0x1E, 0x85, 0xF8, 0x8C, 0x51, 0xB0, 0x6C, 0xB5, + 0x5E, 0x95, 0xBA, 0x4B, 0x69, 0x1B, 0x48, 0x69, + 0x0B, 0x8F, 0xA5, 0x18, 0x13, 0xB9, 0x77, 0xD1, + 0x80, 0x32, 0x32, 0x6D, 0x53, 0xA1, 0x95, 0x40, + 0x96, 0x8A, 0xCC, 0xA3, 0x69, 0xF8, 0x9F, 0xB5, + 0x8E, 0xD2, 0x68, 0x07, 0x4F, 0xA7, 0xEC, 0xF8, + 0x20, 0x21, 0x58, 0xF8, 0xD8, 0x9E, 0x5F, 0x40, + 0xBA, 0xB9, 0x76, 0x57, 0x3B, 0x17, 0xAD, 0xEE, + 0xCB, 0xDF, 0x07, 0xC1, 0xDF, 0x66, 0xA8, 0x0D, + 0xC2, 0xCE, 0x8F, 0x79, 0xC3, 0x32, 0xE0, 0x8C, + 0xFE, 0x5A, 0xF3, 0x55, 0x27, 0x73, 0x6F, 0xA1, + 0x54, 0xC6, 0xFC, 0x28, 0x9D, 0xBE, 0x97, 0xB9, + 0x54, 0x97, 0x72, 0x3A, 0x61, 0xAF, 0x6F, 0xDE, + 0xF8, 0x0E, 0xBB, 0x6B, 0x96, 0x84, 0xDD, 0x9B, + 0x62, 0xBA, 0x47, 0xB5, 0xC9, 0x3B, 0x4E, 0x8C, + 0x78, 0x2A, 0xCC, 0x0A, 0x69, 0x54, 0x25, 0x5E, + 0x8B, 0xAC, 0x56, 0xD9, 0xFE, 0x48, 0xBA, 0xCE, + 0xA9, 0xCE, 0xA6, 0x1D, 0xBF, 0x3E, 0x3C, 0x66, + 0x40, 0x71, 0x79, 0xAD, 0x5B, 0x26, 0xAD, 0xBE, + 0x58, 0x13, 0x64, 0x60, 0x7C, 0x05, 0xFC, 0xE3, + 0x51, 0x7A, 0xF2, 0xCC, 0x54, 0x16, 0x2C, 0xA4, + 0xCE, 0x5F, 0x59, 0x12, 0x77, 0xEB, 0xD9, 0x23, + 0xE3, 0x86, 0xFB, 0xD7, 0x48, 0x76, 0x9D, 0xE3, + 0x89, 0x87, 0x39, 0xFA, 0x7B, 0x21, 0x0B, 0x76, + 0xB2, 0xED, 0x1C, 0x27, 0x4B, 0xD5, 0x27, 0x05, + 0x8C, 0x7D, 0x58, 0x6C, 0xCA, 0xA5, 0x54, 0x9A, + 0x0F, 0xCB, 0xE9, 0x88, 0x31, 0xAD, 0x49, 0xEE, + 0x38, 0xFB, 0xC9, 0xFB, 0xB4, 0x7A, 0x00, 0x58, + 0x20, 0x32, 0xD3, 0x53, 0x5A, 0xDD, 0x74, 0x95, + 0x60, 0x59, 0x09, 0xAE, 0x7E, 0xEC, 0x74, 0xA3, + 0xB7, 0x1C, 0x6D, 0xF2, 0xAE, 0x79, 0xA4, 0x7C +}; + +/** AES-256-CBC test vector */ +static const struct blockcipher_test_data aes_test_data_11 = { + .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0, + 0x37, 0x07, 0xB8, 0x23, 0xA2, 0xA3, 0xB5, 0x8D + }, + .len = 32 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + }, + .len = 16 + }, + .plaintext = { + .data = plaintext_aes_common, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_aes256cbc, + .len = 512 + } +}; + static const struct blockcipher_test_case aes_chain_test_cases[] = { { .test_descr = "AES-128-CTR HMAC-SHA1 Encryption Digest", .test_data = &aes_test_data_1, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -648,6 +840,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_1, .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -669,6 +862,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_3, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -677,6 +871,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_3, .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -684,6 +879,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_4, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -692,6 +888,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_4, .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -699,6 +896,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_5, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -707,6 +905,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_5, .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -714,6 +913,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_6, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -722,7 +922,8 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_6, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO }, { .test_descr = "AES-128-CBC HMAC-SHA512 Decryption Digest " @@ -730,6 +931,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_6, .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -752,7 +954,8 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_4, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO }, { .test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest " @@ -760,13 +963,15 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_4, .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, - .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO }, { .test_descr = "AES-128-CBC HMAC-SHA224 Encryption Digest", .test_data = &aes_test_data_8, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -775,6 +980,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_8, .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -782,6 +988,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_9, .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, { @@ -790,8 +997,101 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = { .test_data = &aes_test_data_9, .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB | + BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | BLOCKCIPHER_TEST_TARGET_PMD_QAT }, + { + .test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest " + "Sessionless", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = + "AES-128-CBC HMAC-SHA1 Decryption Digest " + "Verify Sessionless", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, +}; + +static const struct blockcipher_test_case aes_cipheronly_test_cases[] = { + { + .test_descr = "AES-128-CBC Encryption", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-128-CBC Decryption", + .test_data = &aes_test_data_4, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-192-CBC Encryption", + .test_data = &aes_test_data_10, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-192-CBC Decryption", + .test_data = &aes_test_data_10, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-256-CBC Encryption", + .test_data = &aes_test_data_11, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-256-CBC Decryption", + .test_data = &aes_test_data_11, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-128-CTR Encryption", + .test_data = &aes_test_data_1, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-128-CTR Decryption", + .test_data = &aes_test_data_1, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-192-CTR Encryption", + .test_data = &aes_test_data_2, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-192-CTR Decryption", + .test_data = &aes_test_data_2, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-256-CTR Encryption", + .test_data = &aes_test_data_3, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "AES-256-CTR Decryption", + .test_data = &aes_test_data_3, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, }; #endif /* TEST_CRYPTODEV_AES_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_blockcipher.c b/app/test/test_cryptodev_blockcipher.c index a1d8c8b..deb2ada 100644 --- a/app/test/test_cryptodev_blockcipher.c +++ b/app/test/test_cryptodev_blockcipher.c @@ -43,6 +43,8 @@ #include "test.h" #include "test_cryptodev_blockcipher.h" #include "test_cryptodev_aes_test_vectors.h" +#include "test_cryptodev_des_test_vectors.h" +#include "test_cryptodev_hash_test_vectors.h" static int test_blockcipher_one_case(const struct blockcipher_test_case *t, @@ -79,6 +81,7 @@ test_blockcipher_one_case(const struct blockcipher_test_case *t, switch (cryptodev_type) { case RTE_CRYPTODEV_QAT_SYM_PMD: + case RTE_CRYPTODEV_LIBCRYPTO_PMD: digest_len = tdata->digest.len; break; case RTE_CRYPTODEV_AESNI_MB_PMD: @@ -472,9 +475,25 @@ test_blockcipher_all_tests(struct rte_mempool *mbuf_pool, tcs = aes_chain_test_cases; break; case BLKCIPHER_AES_CIPHERONLY_TYPE: + n_test_cases = sizeof(aes_cipheronly_test_cases) / + sizeof(aes_cipheronly_test_cases[0]); + tcs = aes_cipheronly_test_cases; + break; case BLKCIPHER_3DES_CHAIN_TYPE: + n_test_cases = sizeof(triple_des_chain_test_cases) / + sizeof(triple_des_chain_test_cases[0]); + tcs = triple_des_chain_test_cases; + break; case BLKCIPHER_3DES_CIPHERONLY_TYPE: + n_test_cases = sizeof(triple_des_cipheronly_test_cases) / + sizeof(triple_des_cipheronly_test_cases[0]); + tcs = triple_des_cipheronly_test_cases; + break; case BLKCIPHER_AUTHONLY_TYPE: + n_test_cases = sizeof(hash_test_cases) / + sizeof(hash_test_cases[0]); + tcs = hash_test_cases; + break; default: break; } @@ -486,6 +505,9 @@ test_blockcipher_all_tests(struct rte_mempool *mbuf_pool, case RTE_CRYPTODEV_QAT_SYM_PMD: target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT; break; + case RTE_CRYPTODEV_LIBCRYPTO_PMD: + target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO; + break; default: TEST_ASSERT(0, "Unrecognized cryptodev type"); break; diff --git a/app/test/test_cryptodev_blockcipher.h b/app/test/test_cryptodev_blockcipher.h index 3e25d4d..cce094d 100644 --- a/app/test/test_cryptodev_blockcipher.h +++ b/app/test/test_cryptodev_blockcipher.h @@ -48,6 +48,7 @@ #define BLOCKCIPHER_TEST_TARGET_PMD_MB 0x0001 /* Multi-buffer flag */ #define BLOCKCIPHER_TEST_TARGET_PMD_QAT 0x0002 /* QAT flag */ +#define BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO 0x0004 /* SW LIBCRYPTO flag */ #define BLOCKCIPHER_TEST_OP_CIPHER (BLOCKCIPHER_TEST_OP_ENCRYPT | \ BLOCKCIPHER_TEST_OP_DECRYPT) diff --git a/app/test/test_cryptodev_des_test_vectors.h b/app/test/test_cryptodev_des_test_vectors.h new file mode 100644 index 0000000..687ccbe --- /dev/null +++ b/app/test/test_cryptodev_des_test_vectors.h @@ -0,0 +1,955 @@ +/* + * 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 TEST_CRYPTODEV_DES_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_DES_TEST_VECTORS_H_ + +static const uint8_t plaintext_des[] = { + "What a lousy earth! He wondered how many people " + "were destitute that same night even in his own " + "prosperous country, how many homes were " + "shanties, how many husbands were drunk and " + "wives socked, and how many children were " + "bullied, abused, or abandoned. How many " + "families hungered for food they could not " + "afford to buy? How many hearts were broken? How " + "many suicides would take place that same night, " + "how many people would go insane? How many " + "cockroaches and landlords would triumph? How " + "many winners were losers, successes failures, " + "and rich men poor men? How many wise guys were " + "stupid? How many happy endings were unhappy " + "endings? How many honest men were liars, brave " + "men cowards, loyal men traitors, how many " + "sainted men were corrupt, how many people in " + "positions of trust had sold their souls to " + "bodyguards, how many had never had souls? How " + "many straight-and-narrow paths were crooked " + "paths? How many best families were worst " + "families and how many good people were bad " + "people? When you added them all up and then " + "subtracted, you might be left with only the " + "children, and perhaps with Albert Einstein and " + "an old violinist or sculptor somewhere." +}; + +static const uint8_t ciphertext512_des128ctr[] = { + 0x13, 0x39, 0x3B, 0xBC, 0x1D, 0xE3, 0x23, 0x09, + 0x9B, 0x08, 0xD1, 0x09, 0x52, 0x93, 0x78, 0x29, + 0x11, 0x21, 0xBA, 0x01, 0x15, 0xCD, 0xEC, 0xAA, + 0x79, 0x77, 0x58, 0xAE, 0xAE, 0xBC, 0x97, 0x33, + 0x94, 0xA9, 0x2D, 0xC0, 0x0A, 0xA9, 0xA4, 0x4B, + 0x19, 0x07, 0x88, 0x06, 0x7E, 0x81, 0x0F, 0xB5, + 0x60, 0xCF, 0xA7, 0xC3, 0x2A, 0x43, 0xFF, 0x16, + 0x3A, 0x5F, 0x11, 0x2D, 0x11, 0x38, 0x37, 0x94, + 0x2A, 0xC8, 0x3D, 0x20, 0xBB, 0x93, 0x95, 0x54, + 0x12, 0xFF, 0x0C, 0x47, 0x89, 0x7D, 0x73, 0xD1, + 0x2E, 0x3A, 0x80, 0x52, 0xA8, 0x92, 0x93, 0x99, + 0x16, 0xB8, 0x12, 0x1B, 0x8B, 0xA8, 0xC1, 0x81, + 0x95, 0x18, 0x82, 0xD6, 0x5A, 0xA7, 0xFE, 0xCF, + 0xC4, 0xAC, 0x85, 0x91, 0x0C, 0x2F, 0x1D, 0x10, + 0x9A, 0x65, 0x07, 0xB0, 0x2E, 0x5A, 0x2D, 0x48, + 0x26, 0xF8, 0x17, 0x7A, 0x53, 0xD6, 0xB8, 0xDF, + 0xB1, 0x10, 0x48, 0x7E, 0x8F, 0xBE, 0x2E, 0xA1, + 0x0D, 0x9E, 0xA9, 0xF1, 0x3B, 0x3B, 0x33, 0xCD, + 0xDC, 0x52, 0x7E, 0xC0, 0x0E, 0xA0, 0xD8, 0xA7, + 0xC6, 0x34, 0x5A, 0xAA, 0x29, 0x8B, 0xA9, 0xAC, + 0x1F, 0x78, 0xAD, 0xEE, 0x34, 0x59, 0x30, 0xFB, + 0x2A, 0x20, 0x3D, 0x4D, 0x30, 0xA7, 0x7D, 0xD8, + 0xA0, 0xC6, 0xA2, 0xD3, 0x9A, 0xFB, 0x50, 0x97, + 0x4D, 0x25, 0xA2, 0x37, 0x51, 0x54, 0xB7, 0xEB, + 0xED, 0x77, 0xDB, 0x94, 0x35, 0x8B, 0x70, 0x95, + 0x4A, 0x00, 0xA7, 0xF1, 0x8A, 0x66, 0x0E, 0xC6, + 0x05, 0x7B, 0x69, 0x05, 0x42, 0x03, 0x96, 0x2C, + 0x55, 0x00, 0x1B, 0xC0, 0x19, 0x4D, 0x0D, 0x2E, + 0xF5, 0x81, 0x11, 0x64, 0xCA, 0xBB, 0xF2, 0x0F, + 0x9C, 0x60, 0xE2, 0xCC, 0x02, 0x6E, 0x83, 0xD5, + 0x24, 0xF4, 0x12, 0x0E, 0x6A, 0xEA, 0x4F, 0x6C, + 0x79, 0x69, 0x65, 0x67, 0xDB, 0xF7, 0xEA, 0x98, + 0x5D, 0x56, 0x98, 0xB7, 0x88, 0xE7, 0x23, 0xC9, + 0x17, 0x32, 0x92, 0x33, 0x5A, 0x0C, 0x15, 0x20, + 0x3B, 0x1C, 0xF9, 0x0F, 0x4D, 0xD1, 0xE8, 0xE6, + 0x9E, 0x5E, 0x24, 0x1B, 0xA4, 0xB8, 0xB9, 0xE9, + 0x2F, 0xFC, 0x89, 0xB4, 0xB9, 0xF4, 0xA6, 0xAD, + 0x55, 0xF4, 0xDF, 0x58, 0x63, 0x25, 0xE3, 0x41, + 0x70, 0xDF, 0x10, 0xE7, 0x13, 0x87, 0x8D, 0xB3, + 0x62, 0x4F, 0xF5, 0x86, 0x85, 0x8F, 0x59, 0xF0, + 0x21, 0x0E, 0x8F, 0x11, 0xAD, 0xBF, 0xDD, 0x61, + 0x68, 0x3F, 0x54, 0x57, 0x49, 0x38, 0xC8, 0x24, + 0x8E, 0x0A, 0xAC, 0xCA, 0x2C, 0x36, 0x3E, 0x5F, + 0x0A, 0xCE, 0xFD, 0x1A, 0x60, 0x63, 0x5A, 0xE6, + 0x06, 0x64, 0xB5, 0x94, 0x3C, 0xC9, 0xAF, 0x7C, + 0xCD, 0x49, 0x10, 0xCF, 0xAF, 0x0E, 0x2E, 0x79, + 0x27, 0xB2, 0x67, 0x02, 0xED, 0xEE, 0x80, 0x77, + 0x7C, 0x6D, 0x4B, 0xDB, 0xCF, 0x8D, 0x68, 0x00, + 0x2E, 0xD9, 0xF0, 0x8E, 0x08, 0xBF, 0xA6, 0x9B, + 0xFE, 0xA4, 0xFB, 0x19, 0x46, 0xAF, 0x1B, 0xA9, + 0xF8, 0x22, 0x81, 0x21, 0x97, 0xFC, 0xC0, 0x8A, + 0x26, 0x58, 0x13, 0x29, 0xB6, 0x69, 0x94, 0x4B, + 0xAB, 0xB3, 0x88, 0x0D, 0xA9, 0x48, 0x0E, 0xE8, + 0x70, 0xFC, 0xA1, 0x21, 0xC4, 0x2C, 0xE5, 0x99, + 0xB4, 0xF1, 0x6F, 0xB2, 0x4B, 0x4B, 0xCD, 0x48, + 0x15, 0x47, 0x2D, 0x72, 0x39, 0x99, 0x9D, 0x24, + 0x0C, 0x8B, 0xDC, 0xA1, 0xEE, 0xF6, 0xF4, 0x73, + 0xC3, 0xB8, 0x0C, 0x23, 0x0D, 0xA7, 0xC4, 0x7D, + 0x27, 0xE2, 0x14, 0x11, 0x53, 0x19, 0xE7, 0xCA, + 0x94, 0x4E, 0x0D, 0x2C, 0xF7, 0x36, 0x47, 0xDB, + 0x77, 0x3C, 0x22, 0xAC, 0xBE, 0xE1, 0x06, 0x55, + 0xE5, 0xDD, 0x8B, 0x65, 0xE8, 0xE9, 0x91, 0x52, + 0x59, 0x97, 0xFC, 0x8C, 0xEE, 0x96, 0x22, 0x60, + 0xEE, 0xBF, 0x82, 0xF0, 0xCA, 0x14, 0xF9, 0xD3 +}; + +static const struct blockcipher_test_data +triple_des128ctr_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128ctr, + .len = 512 + } +}; + +static const struct blockcipher_test_data +triple_des128ctr_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128ctr, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .digest = { + .data = { + 0xC3, 0x40, 0xD5, 0xD9, 0x8F, 0x8A, 0xC0, 0xF0, + 0x46, 0x28, 0x02, 0x01, 0xB5, 0xC1, 0x87, 0x4D, + 0xAC, 0xFE, 0x48, 0x76 + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +triple_des128ctr_hmac_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128ctr, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0xF1, 0xC1, 0xDB, 0x4D, 0xFA, 0x7F, 0x2F, 0xE5, + 0xF8, 0x49, 0xEA, 0x1D, 0x7F, 0xCB, 0x42, 0x59, + 0xC4, 0x1E, 0xB1, 0x18 + }, + .len = 20 + } +}; + +static const uint8_t ciphertext512_des192ctr[] = { + 0xFF, 0x32, 0x52, 0x97, 0x10, 0xBF, 0x0B, 0x10, + 0x68, 0x0F, 0x4F, 0x56, 0x8B, 0x2C, 0x7B, 0x8E, + 0x39, 0x1E, 0x1A, 0x2F, 0x83, 0xDE, 0x5E, 0x35, + 0xC8, 0x4B, 0xDF, 0xD5, 0xBC, 0x84, 0x50, 0x1A, + 0x02, 0xDF, 0xB3, 0x11, 0xE4, 0xDA, 0xB8, 0x0E, + 0x47, 0xC6, 0x0C, 0x51, 0x09, 0x62, 0x9C, 0x5D, + 0x71, 0x40, 0x49, 0xD8, 0x55, 0xBD, 0x7D, 0x90, + 0x71, 0xC5, 0xF7, 0x07, 0x6F, 0x08, 0x71, 0x2A, + 0xB1, 0x77, 0x9B, 0x0F, 0xA1, 0xB0, 0xD6, 0x10, + 0xB2, 0xE5, 0x31, 0xEC, 0x21, 0x13, 0x89, 0x2A, + 0x09, 0x7E, 0x30, 0xDB, 0xA0, 0xF0, 0xDC, 0xE4, + 0x74, 0x64, 0x39, 0xA3, 0xB0, 0xB1, 0x80, 0x66, + 0x52, 0xD4, 0x4E, 0xC9, 0x5A, 0x52, 0x6A, 0xC7, + 0xB5, 0x2B, 0x61, 0xD5, 0x17, 0xD5, 0xF3, 0xCC, + 0x41, 0x61, 0xD2, 0xA6, 0xF4, 0x51, 0x24, 0x3A, + 0x63, 0x5D, 0x23, 0xB1, 0xF0, 0x22, 0xE7, 0x45, + 0xFA, 0x5F, 0x7E, 0x99, 0x00, 0x11, 0x28, 0x35, + 0xA3, 0xF4, 0x61, 0x94, 0x0E, 0x98, 0xCE, 0x35, + 0xDD, 0x91, 0x1B, 0x0B, 0x4D, 0xEE, 0xFF, 0xFF, + 0x0B, 0xD4, 0xDC, 0x56, 0xFC, 0x71, 0xE9, 0xEC, + 0xE8, 0x36, 0x51, 0xF8, 0x8B, 0x6A, 0xE1, 0x8C, + 0x2B, 0x25, 0x91, 0x91, 0x9B, 0x92, 0x76, 0xB5, + 0x3D, 0x26, 0xA8, 0x53, 0xEA, 0x30, 0x5B, 0x4D, + 0xDA, 0x16, 0xDA, 0x7D, 0x04, 0x88, 0xF5, 0x22, + 0xA8, 0x0C, 0xB9, 0x41, 0xC7, 0x91, 0x64, 0x86, + 0x99, 0x7D, 0x18, 0xB9, 0x67, 0xA2, 0x6E, 0x05, + 0x1A, 0x82, 0x8F, 0xA2, 0xEB, 0x4D, 0x0B, 0x8C, + 0x88, 0x2D, 0xBA, 0x77, 0x87, 0x32, 0x50, 0x3C, + 0x4C, 0xD8, 0xD3, 0x50, 0x39, 0xFA, 0xDF, 0x48, + 0x3E, 0x30, 0xF5, 0x76, 0x06, 0xB0, 0x1A, 0x05, + 0x60, 0x2C, 0xD3, 0xA0, 0x63, 0x1A, 0x19, 0x2D, + 0x6B, 0x76, 0xF2, 0x31, 0x4C, 0xA7, 0xE6, 0x5C, + 0x1B, 0x23, 0x20, 0x41, 0x32, 0xE5, 0x83, 0x47, + 0x04, 0xB6, 0x3E, 0xE0, 0xFD, 0x49, 0x1E, 0x1B, + 0x75, 0x10, 0x11, 0x46, 0xE9, 0xF9, 0x96, 0x9A, + 0xD7, 0x59, 0xFE, 0x38, 0x31, 0xFE, 0x79, 0xC4, + 0xC8, 0x46, 0x88, 0xDE, 0x2E, 0xAE, 0x20, 0xED, + 0x77, 0x50, 0x40, 0x38, 0x26, 0xD3, 0x35, 0xF6, + 0x29, 0x55, 0x6A, 0x6B, 0x38, 0x69, 0xFE, 0x90, + 0x5B, 0xA7, 0xFA, 0x6B, 0x73, 0x4F, 0xB9, 0x5D, + 0xDC, 0x6F, 0x98, 0xC3, 0x6A, 0xC4, 0xB5, 0x09, + 0xC5, 0x84, 0xA5, 0x6A, 0x84, 0xA4, 0xB3, 0x8A, + 0x5F, 0xCA, 0x92, 0x64, 0x9E, 0xC3, 0x0F, 0x84, + 0x8B, 0x2D, 0x48, 0xC6, 0x67, 0xAE, 0x07, 0xE0, + 0x28, 0x38, 0x6D, 0xC4, 0x4D, 0x13, 0x87, 0xE0, + 0xB2, 0x2F, 0xAA, 0xC0, 0xCF, 0x68, 0xD7, 0x9C, + 0xB8, 0x07, 0xE4, 0x51, 0xD7, 0x75, 0x86, 0xFA, + 0x0C, 0x50, 0x74, 0x68, 0x00, 0x64, 0x2A, 0x27, + 0x59, 0xE9, 0x80, 0xEB, 0xC2, 0xA3, 0xFA, 0x58, + 0xCC, 0x03, 0xE7, 0x7B, 0x66, 0x53, 0xFF, 0x90, + 0xA0, 0x85, 0xE2, 0xF8, 0x82, 0xFE, 0xC6, 0x2B, + 0xFF, 0x5E, 0x70, 0x85, 0x34, 0xB7, 0x22, 0x38, + 0xDB, 0xBC, 0x15, 0x30, 0x59, 0xC1, 0x48, 0x42, + 0xE5, 0x38, 0x8D, 0x37, 0x59, 0xDB, 0xA3, 0x20, + 0x17, 0x36, 0x1D, 0x4B, 0xBF, 0x4E, 0xA4, 0x35, + 0xCC, 0xFE, 0xF5, 0x7A, 0x73, 0xB4, 0x6D, 0x20, + 0x1D, 0xC0, 0xE5, 0x21, 0x5C, 0xD2, 0x8A, 0x65, + 0x08, 0xB6, 0x63, 0xAC, 0x9A, 0x1E, 0x3F, 0x3C, + 0xAB, 0xB6, 0x6D, 0x34, 0xB2, 0x3A, 0x08, 0xDA, + 0x29, 0x63, 0xD1, 0xA4, 0x83, 0x52, 0xB0, 0x63, + 0x1B, 0x89, 0x35, 0x57, 0x59, 0x2C, 0x0F, 0x72, + 0x72, 0xFD, 0xA0, 0xAC, 0xDB, 0xB4, 0xA3, 0xA1, + 0x18, 0x10, 0x12, 0x97, 0x99, 0x63, 0x38, 0x98, + 0x96, 0xB5, 0x16, 0x07, 0x4E, 0xE9, 0x2C, 0x97 +}; + +static const struct blockcipher_test_data +triple_des192ctr_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192ctr, + .len = 512 + } +}; + +static const struct blockcipher_test_data +triple_des192ctr_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192ctr, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .digest = { + .data = { + 0xEA, 0x62, 0xB9, 0xB2, 0x78, 0x6C, 0x8E, 0xDB, + 0xA3, 0xB6, 0xFF, 0x23, 0x3A, 0x47, 0xD8, 0xC8, + 0xED, 0x5E, 0x20, 0x1D + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +triple_des192ctr_hmac_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192ctr, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x32, 0xD5, 0x19, 0x8F, 0x79, 0x3A, 0xAA, 0x7B, + 0x70, 0x67, 0x4E, 0x63, 0x88, 0xA3, 0x9A, 0x82, + 0x07, 0x33, 0x12, 0x94 + }, + .len = 20 + } +}; + +static const uint8_t ciphertext512_des128cbc[] = { + 0x28, 0x2a, 0xff, 0x15, 0x5c, 0xdf, 0xd9, 0x6b, + 0x54, 0xbc, 0x7b, 0xfb, 0xc5, 0x64, 0x4d, 0xdd, + 0x3e, 0xf2, 0x9e, 0xb7, 0x53, 0x65, 0x37, 0x05, + 0xe0, 0xdf, 0xae, 0xf7, 0xc9, 0x27, 0xe4, 0xec, + 0x11, 0x27, 0xc2, 0x9e, 0x02, 0x4e, 0x03, 0x3b, + 0x33, 0xf2, 0x66, 0x08, 0x24, 0x5f, 0xab, 0xc2, + 0x7e, 0x21, 0x19, 0x5d, 0x51, 0xc3, 0xe2, 0x97, + 0x6f, 0x2e, 0xb4, 0xaa, 0x34, 0x70, 0x88, 0x78, + 0x4e, 0xe7, 0x3d, 0xe1, 0x9f, 0x87, 0x1c, 0x8b, + 0xac, 0x8d, 0xa1, 0x1a, 0xcd, 0xb0, 0xf8, 0xb6, + 0x24, 0x36, 0xe3, 0x8c, 0x07, 0xe7, 0xe4, 0x92, + 0x13, 0x86, 0x6f, 0x13, 0xec, 0x04, 0x5c, 0xe9, + 0xb9, 0xca, 0x45, 0x8a, 0x2c, 0x46, 0xda, 0x54, + 0x1d, 0xb5, 0x81, 0xb1, 0xcd, 0xf3, 0x7d, 0x11, + 0x6b, 0xb3, 0x0a, 0x45, 0xe5, 0x6e, 0x51, 0x3e, + 0x2c, 0xac, 0x7c, 0xbc, 0xa7, 0x7e, 0x22, 0x4d, + 0xe6, 0x02, 0xe3, 0x3f, 0x77, 0xd7, 0x73, 0x72, + 0x0e, 0xfb, 0x42, 0x85, 0x80, 0xdf, 0xa8, 0x91, + 0x60, 0x40, 0x48, 0xcd, 0x1b, 0xd9, 0xbf, 0x2f, + 0xf2, 0xdf, 0xd0, 0xbd, 0x3f, 0x82, 0xce, 0x15, + 0x9d, 0x6e, 0xc6, 0x59, 0x6f, 0x27, 0x0d, 0xf9, + 0x26, 0xe2, 0x11, 0x29, 0x50, 0xc3, 0x0a, 0xb7, + 0xde, 0x9d, 0xe9, 0x55, 0xa1, 0xe9, 0x01, 0x33, + 0x56, 0x51, 0xa7, 0x3a, 0x9e, 0x63, 0xc5, 0x08, + 0x01, 0x3b, 0x03, 0x4b, 0xc6, 0xc4, 0xa1, 0xc0, + 0xc0, 0xd0, 0x0e, 0x48, 0xe5, 0x4c, 0x55, 0x6b, + 0x4a, 0xc1, 0x0a, 0x24, 0x4b, 0xd0, 0x02, 0xf4, + 0x31, 0x63, 0x11, 0xbd, 0xa6, 0x1f, 0xf4, 0xae, + 0x23, 0x5a, 0x40, 0x7e, 0x0e, 0x4e, 0x63, 0x8b, + 0x66, 0x3d, 0x55, 0x46, 0x6e, 0x5c, 0x76, 0xa7, + 0x68, 0x31, 0xce, 0x5d, 0xca, 0xe2, 0xb4, 0xb0, + 0xc1, 0x1f, 0x66, 0x18, 0x75, 0x64, 0x73, 0xa9, + 0x9e, 0xd5, 0x0e, 0x0e, 0xf7, 0x77, 0x61, 0xf8, + 0x89, 0xc6, 0xcf, 0x0c, 0x41, 0xd3, 0x8f, 0xfd, + 0x22, 0x52, 0x4f, 0x94, 0x5c, 0x19, 0x11, 0x3a, + 0xb5, 0x63, 0xe8, 0x81, 0x33, 0x13, 0x54, 0x3c, + 0x93, 0x36, 0xb5, 0x5b, 0x51, 0xaf, 0x51, 0xa2, + 0x08, 0xae, 0x83, 0x15, 0x77, 0x07, 0x28, 0x0d, + 0x98, 0xe1, 0x2f, 0x69, 0x0e, 0xfb, 0x9a, 0x2e, + 0x27, 0x27, 0xb0, 0xd5, 0xce, 0xf8, 0x16, 0x55, + 0xfd, 0xaa, 0xd7, 0x1a, 0x1b, 0x2e, 0x4c, 0x86, + 0x7a, 0x6a, 0x90, 0xf7, 0x0a, 0x07, 0xd3, 0x81, + 0x4b, 0x75, 0x6a, 0x79, 0xdb, 0x63, 0x45, 0x0f, + 0x31, 0x7e, 0xd0, 0x2a, 0x14, 0xff, 0xee, 0xcc, + 0x97, 0x8a, 0x7d, 0x74, 0xbd, 0x9d, 0xaf, 0x00, + 0xdb, 0x7e, 0xf3, 0xe6, 0x22, 0x76, 0x77, 0x58, + 0xba, 0x1c, 0x06, 0x96, 0xfb, 0x6f, 0x41, 0x71, + 0x66, 0x98, 0xae, 0x31, 0x7d, 0x29, 0x18, 0x71, + 0x0e, 0xe4, 0x98, 0x7e, 0x59, 0x5a, 0xc9, 0x78, + 0x9c, 0xfb, 0x6c, 0x81, 0x44, 0xb4, 0x0f, 0x5e, + 0x18, 0x53, 0xb8, 0x6f, 0xbc, 0x3b, 0x15, 0xf0, + 0x10, 0xdd, 0x0d, 0x4b, 0x0a, 0x36, 0x0e, 0xb4, + 0x76, 0x0f, 0x16, 0xa7, 0x5c, 0x9d, 0xcf, 0xb0, + 0x6d, 0x38, 0x02, 0x07, 0x05, 0xe9, 0xe9, 0x46, + 0x08, 0xb8, 0x52, 0xd6, 0xd9, 0x4c, 0x81, 0x63, + 0x1d, 0xe2, 0x5b, 0xd0, 0xf6, 0x5e, 0x1e, 0x81, + 0x48, 0x08, 0x66, 0x3a, 0x85, 0xed, 0x65, 0xfe, + 0xe8, 0x05, 0x7a, 0xe1, 0xe6, 0x12, 0xf2, 0x52, + 0x83, 0xdd, 0x82, 0xbe, 0xf6, 0x34, 0x8a, 0x6f, + 0xc5, 0x83, 0xcd, 0x3f, 0xbe, 0x58, 0x8b, 0x11, + 0x78, 0xdc, 0x0c, 0x83, 0x72, 0x5d, 0x05, 0x2a, + 0x01, 0x29, 0xee, 0x48, 0x9a, 0x67, 0x00, 0x6e, + 0x14, 0x60, 0x2d, 0x00, 0x52, 0x87, 0x98, 0x5e, + 0x43, 0xfe, 0xf1, 0x10, 0x14, 0xf1, 0x91, 0xcc +}; + +static const struct blockcipher_test_data +triple_des128cbc_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128cbc, + .len = 512 + } +}; + +static const struct blockcipher_test_data +triple_des128cbc_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .digest = { + .data = { + 0x94, 0x45, 0x7B, 0xDF, 0xFE, 0x80, 0xB9, 0xA6, + 0xA0, 0x7A, 0xE8, 0x93, 0x40, 0x7B, 0x85, 0x02, + 0x1C, 0xD7, 0xE8, 0x87 + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +triple_des128cbc_hmac_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A + }, + .len = 16 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des128cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0x7E, 0xBA, 0xFF, 0x86, 0x8D, 0x65, 0xCD, 0x08, + 0x76, 0x34, 0x94, 0xE9, 0x9A, 0xCD, 0xB2, 0xBB, + 0xBF, 0x65, 0xF5, 0x42 + }, + .len = 20 + } +}; + +static const uint8_t ciphertext512_des192cbc[] = { + 0xd0, 0xc9, 0xdc, 0x51, 0x29, 0x97, 0x03, 0x64, + 0xcd, 0x22, 0xba, 0x3d, 0x2b, 0xbc, 0x21, 0x37, + 0x7b, 0x1e, 0x29, 0x23, 0xeb, 0x51, 0x6e, 0xac, + 0xbe, 0x5b, 0xd3, 0x67, 0xe0, 0x3f, 0xc3, 0xb5, + 0xe3, 0x04, 0x17, 0x42, 0x2b, 0xaa, 0xdd, 0xd6, + 0x0e, 0x69, 0xd0, 0x8f, 0x8a, 0xfc, 0xb4, 0x55, + 0x67, 0x06, 0x51, 0xbb, 0x00, 0x57, 0xee, 0x95, + 0x28, 0x79, 0x3f, 0xd9, 0x97, 0x2b, 0xb0, 0x02, + 0x35, 0x08, 0xce, 0x7a, 0xc3, 0x43, 0x2c, 0x87, + 0xaa, 0x97, 0x6a, 0xad, 0xf0, 0x26, 0xea, 0x1d, + 0xbb, 0x08, 0xe9, 0x52, 0x11, 0xd3, 0xaf, 0x36, + 0x17, 0x14, 0x21, 0xb2, 0xbc, 0x42, 0x51, 0x33, + 0x27, 0x8c, 0xd8, 0x45, 0xb9, 0x76, 0xa0, 0x11, + 0x24, 0x34, 0xde, 0x4d, 0x13, 0x67, 0x1b, 0xc3, + 0x31, 0x12, 0x66, 0x56, 0x59, 0xd2, 0xb1, 0x8f, + 0xec, 0x1e, 0xc0, 0x10, 0x7a, 0x86, 0xb1, 0x60, + 0xc3, 0x01, 0xd6, 0xa8, 0x55, 0xad, 0x58, 0x63, + 0xca, 0x68, 0xa9, 0x33, 0xe3, 0x93, 0x90, 0x7d, + 0x8f, 0xca, 0xf8, 0x1c, 0xc2, 0x9e, 0xfb, 0xde, + 0x9c, 0xc7, 0xf2, 0x6c, 0xff, 0xcc, 0x39, 0x17, + 0x49, 0x33, 0x0d, 0x7c, 0xed, 0x07, 0x99, 0x91, + 0x91, 0x6c, 0x5f, 0x3f, 0x02, 0x09, 0xdc, 0x70, + 0xf9, 0x3b, 0x8d, 0xaa, 0xf4, 0xbc, 0x0e, 0xec, + 0xf2, 0x26, 0xfb, 0xb2, 0x1c, 0x31, 0xae, 0xc6, + 0x72, 0xe8, 0x0b, 0x75, 0x05, 0x57, 0x58, 0x98, + 0x92, 0x37, 0x27, 0x8e, 0x3b, 0x0c, 0x25, 0xfb, + 0xcf, 0x82, 0x02, 0xd5, 0x0b, 0x1f, 0x89, 0x49, + 0xcd, 0x0f, 0xa1, 0xa7, 0x08, 0x63, 0x56, 0xa7, + 0x1f, 0x80, 0x3a, 0xef, 0x24, 0x89, 0x57, 0x1a, + 0x02, 0xdc, 0x2e, 0x51, 0xbd, 0x4a, 0x10, 0x23, + 0xfc, 0x02, 0x1a, 0x3f, 0x34, 0xbf, 0x1c, 0x98, + 0x1a, 0x40, 0x0a, 0x96, 0x8e, 0x41, 0xd5, 0x09, + 0x55, 0x37, 0xe9, 0x25, 0x11, 0x83, 0xf8, 0xf3, + 0xd4, 0xb0, 0xdb, 0x16, 0xd7, 0x51, 0x7e, 0x94, + 0xf7, 0xb4, 0x26, 0xe0, 0xf4, 0x80, 0x01, 0x65, + 0x51, 0xeb, 0xbc, 0xb0, 0x65, 0x8f, 0xdd, 0xb5, + 0xf7, 0x00, 0xec, 0x40, 0xab, 0x7d, 0x96, 0xcc, + 0x8d, 0xec, 0x89, 0x80, 0x31, 0x39, 0xa2, 0x5c, + 0xb0, 0x55, 0x4c, 0xee, 0xdd, 0x15, 0x2b, 0xa9, + 0x86, 0x4e, 0x23, 0x14, 0x36, 0xc5, 0x57, 0xf5, + 0xe3, 0xe8, 0x89, 0xc9, 0xb7, 0xf8, 0xeb, 0x08, + 0xe5, 0x93, 0x12, 0x5c, 0x0f, 0x79, 0xa1, 0x86, + 0xe4, 0xc2, 0xeb, 0xa6, 0xa0, 0x50, 0x6a, 0xec, + 0xd3, 0xce, 0x50, 0x78, 0x4e, 0x4f, 0x93, 0xd8, + 0xdc, 0xb4, 0xec, 0x02, 0xe9, 0xbd, 0x17, 0x99, + 0x1e, 0x16, 0x4e, 0xd7, 0xb0, 0x07, 0x02, 0x55, + 0x63, 0x24, 0x4f, 0x7b, 0x8f, 0xc5, 0x7a, 0x12, + 0x29, 0xff, 0x5d, 0xc1, 0xe7, 0xae, 0x48, 0xc8, + 0x57, 0x53, 0xe7, 0xcd, 0x10, 0x6c, 0x19, 0xfc, + 0xcc, 0xb9, 0xb1, 0xbe, 0x48, 0x9f, 0x2d, 0x3f, + 0x39, 0x2e, 0xdd, 0x71, 0xde, 0x1b, 0x54, 0xee, + 0x7d, 0x94, 0x8f, 0x27, 0x23, 0xe9, 0x74, 0x92, + 0x14, 0x93, 0x84, 0x65, 0xc9, 0x22, 0x7c, 0xa8, + 0x1b, 0x72, 0x73, 0xb1, 0x23, 0xa0, 0x6b, 0xcc, + 0xb5, 0x22, 0x06, 0x15, 0xe5, 0x96, 0x03, 0x4a, + 0x52, 0x8d, 0x1d, 0xbf, 0x3e, 0x82, 0x45, 0x9c, + 0x75, 0x9e, 0xa9, 0x3a, 0x97, 0xb6, 0x5d, 0xc4, + 0x75, 0x67, 0xa1, 0xf3, 0x0f, 0x7a, 0xfd, 0x71, + 0x58, 0x04, 0xf9, 0xa7, 0xc2, 0x56, 0x74, 0x04, + 0x74, 0x68, 0x6d, 0x8a, 0xf6, 0x6c, 0x5d, 0xd8, + 0xb5, 0xed, 0x70, 0x23, 0x32, 0x4d, 0x75, 0x92, + 0x88, 0x7b, 0x39, 0x37, 0x02, 0x4b, 0xb2, 0x1c, + 0x1f, 0x7e, 0x5b, 0x1b, 0x10, 0xfc, 0x17, 0x21, + 0x66, 0x62, 0x63, 0xc2, 0xcd, 0x16, 0x96, 0x3e +}; + +static const struct blockcipher_test_data +triple_des192cbc_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192cbc, + .len = 512 + } +}; + +static const struct blockcipher_test_data +triple_des192cbc_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .digest = { + .data = { + 0x53, 0x27, 0xC0, 0xE6, 0xD6, 0x1B, 0xD6, 0x45, + 0x94, 0x2D, 0xCE, 0x8B, 0x29, 0xA3, 0x52, 0x14, + 0xC1, 0x6B, 0x87, 0x99 + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +triple_des192cbc_hmac_sha1_test_vector = { + .crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key = { + .data = { + 0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2, + 0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A, + 0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0 + }, + .len = 24 + }, + .iv = { + .data = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }, + .len = 8 + }, + .plaintext = { + .data = plaintext_des, + .len = 512 + }, + .ciphertext = { + .data = ciphertext512_des192cbc, + .len = 512 + }, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0xBA, 0xAC, 0x74, 0x19, 0x43, 0xB0, 0x72, 0xB8, + 0x08, 0xF5, 0x24, 0xC4, 0x09, 0xBD, 0x48, 0xC1, + 0x3C, 0x50, 0x1C, 0xDD + }, + .len = 20 + } +}; + +static const struct blockcipher_test_case triple_des_chain_test_cases[] = { + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Encryption Digest", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Decryption Digest Verify", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC SHA1 Encryption Digest", + .test_data = &triple_des128cbc_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-128-CBC SHA1 Decryption Digest Verify", + .test_data = &triple_des128cbc_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-192-CBC HMAC-SHA1 Encryption Digest", + .test_data = &triple_des192cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CBC HMAC-SHA1 Decryption Digest Verify", + .test_data = &triple_des192cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CBC SHA1 Encryption Digest", + .test_data = &triple_des192cbc_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-192-CBC SHA1 Decryption Digest Verify", + .test_data = &triple_des192cbc_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-128-CTR HMAC-SHA1 Encryption Digest", + .test_data = &triple_des128ctr_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CTR HMAC-SHA1 Decryption Digest Verify", + .test_data = &triple_des128ctr_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CTR SHA1 Encryption Digest", + .test_data = &triple_des128ctr_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-128-CTR SHA1 Decryption Digest Verify", + .test_data = &triple_des128ctr_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-192-CTR HMAC-SHA1 Encryption Digest", + .test_data = &triple_des192ctr_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CTR HMAC-SHA1 Decryption Digest Verify", + .test_data = &triple_des192ctr_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CTR SHA1 Encryption Digest", + .test_data = &triple_des192ctr_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-192-CTR SHA1 Decryption Digest Verify", + .test_data = &triple_des192ctr_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Encryption Digest OOP", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Decryption Digest" + " Verify OOP", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC HMAC-SHA1 Encryption Digest" + " Sessionless", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = + "3DES-128-CBC HMAC-SHA1 Decryption Digest" + " Verify Sessionless", + .test_data = &triple_des128cbc_hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, +}; + +static const struct blockcipher_test_case triple_des_cipheronly_test_cases[] = { + { + .test_descr = "3DES-128-CBC Encryption", + .test_data = &triple_des128cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CBC Decryption", + .test_data = &triple_des128cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CBC Encryption", + .test_data = &triple_des192cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CBC Decryption", + .test_data = &triple_des192cbc_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CTR Encryption", + .test_data = &triple_des128ctr_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-128-CTR Decryption", + .test_data = &triple_des128ctr_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CTR Encryption", + .test_data = &triple_des192ctr_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + }, + { + .test_descr = "3DES-192-CTR Decryption", + .test_data = &triple_des192ctr_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO | + BLOCKCIPHER_TEST_TARGET_PMD_QAT + } +}; + +#endif /* TEST_CRYPTODEV_DES_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_gcm_test_vectors.h b/app/test/test_cryptodev_gcm_test_vectors.h index deca09d..b404242 100644 --- a/app/test/test_cryptodev_gcm_test_vectors.h +++ b/app/test/test_cryptodev_gcm_test_vectors.h @@ -33,6 +33,8 @@ #ifndef TEST_CRYPTODEV_GCM_TEST_VECTORS_H_ #define TEST_CRYPTODEV_GCM_TEST_VECTORS_H_ +#define GMAC_LARGE_PLAINTEXT_LENGTH 65376 + struct gcm_test_data { struct { uint8_t data[64]; @@ -449,7 +451,7 @@ static const struct gcm_test_data gcm_test_case_7 = { }; /** GMAC Test Vectors */ -static uint8_t gmac_plaintext[] = { +static uint8_t gmac_plaintext[GMAC_LARGE_PLAINTEXT_LENGTH] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, @@ -1201,4 +1203,36 @@ static const struct cryptodev_perf_test_data AES_GCM_128_12IV_0AAD = { }, }; +static const struct gmac_test_data gmac_test_case_4 = { + .key = { + .data = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 + }, + .len = 16 + }, + .iv = { + .data = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 + }, + .len = 12 + }, + .aad = { + .data = gmac_plaintext, + .len = GMAC_LARGE_PLAINTEXT_LENGTH + }, + .plaintext = { + .data = NULL, + .len = 0 + }, + .gmac_tag = { + .data = { + 0x88, 0x82, 0xb4, 0x93, 0x8f, 0x04, 0xcd, 0x06, + 0xfd, 0xac, 0x6d, 0x8b, 0x9c, 0x9e, 0x8f, 0xec + }, + .len = 16 + } +}; + #endif /* TEST_CRYPTODEV_GCM_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_hash_test_vectors.h b/app/test/test_cryptodev_hash_test_vectors.h new file mode 100644 index 0000000..dfc84db --- /dev/null +++ b/app/test/test_cryptodev_hash_test_vectors.h @@ -0,0 +1,491 @@ +/* + * 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 TEST_CRYPTODEV_HASH_TEST_VECTORS_H_ +#define TEST_CRYPTODEV_HASH_TEST_VECTORS_H_ + +static const uint8_t plaintext_hash[] = { + "What a lousy earth! He wondered how many people " + "were destitute that same night even in his own " + "prosperous country, how many homes were " + "shanties, how many husbands were drunk and " + "wives socked, and how many children were " + "bullied, abused, or abandoned. How many " + "families hungered for food they could not " + "afford to buy? How many hearts were broken? How " + "many suicides would take place that same night, " + "how many people would go insane? How many " + "cockroaches and landlords would triumph? How " + "many winners were losers, successes failures, " + "and rich men poor men? How many wise guys were " + "stupid? How many happy endings were unhappy " + "endings? How many honest men were liars, brave " + "men cowards, loyal men traitors, how many " + "sainted men were corrupt, how many people in " + "positions of trust had sold their souls to " + "bodyguards, how many had never had souls? How " + "many straight-and-narrow paths were crooked " + "paths? How many best families were worst " + "families and how many good people were bad " + "people? When you added them all up and then " + "subtracted, you might be left with only the " + "children, and perhaps with Albert Einstein and " + "an old violinist or sculptor somewhere." +}; + +static const struct blockcipher_test_data +md5_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_MD5, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0xB3, 0xE6, 0xBB, 0x50, 0x41, 0x35, 0x3C, 0x6B, + 0x7A, 0xFF, 0xD2, 0x64, 0xAF, 0xD5, 0x1C, 0xB2 + }, + .len = 16 + } +}; + +static const struct blockcipher_test_data +hmac_md5_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_MD5_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD + }, + .len = 16 + }, + .digest = { + .data = { + 0x50, 0xE8, 0xDE, 0xC5, 0xC1, 0x76, 0xAC, 0xAE, + 0x15, 0x4A, 0xF1, 0x7F, 0x7E, 0x04, 0x42, 0x9B + }, + .len = 16 + } +}; + +static const struct blockcipher_test_data +sha1_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA1, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0xA2, 0x8D, 0x40, 0x78, 0xDD, 0x9F, 0xBB, 0xD5, + 0x35, 0x62, 0xFB, 0xFA, 0x93, 0xFD, 0x7D, 0x70, + 0xA6, 0x7D, 0x45, 0xCA + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +hmac_sha1_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD + }, + .len = 20 + }, + .digest = { + .data = { + 0xC4, 0xB7, 0x0E, 0x6B, 0xDE, 0xD1, 0xE7, 0x77, + 0x7E, 0x2E, 0x8F, 0xFC, 0x48, 0x39, 0x46, 0x17, + 0x3F, 0x91, 0x64, 0x59 + }, + .len = 20 + } +}; + +static const struct blockcipher_test_data +sha224_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA224, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0x91, 0xE7, 0xCD, 0x75, 0x14, 0x9C, 0xA9, 0xE9, + 0x2E, 0x46, 0x12, 0x20, 0x22, 0xF9, 0x68, 0x28, + 0x39, 0x26, 0xDF, 0xB5, 0x78, 0x62, 0xB2, 0x6E, + 0x5E, 0x8F, 0x25, 0x84 + }, + .len = 28 + } +}; + +static const struct blockcipher_test_data +hmac_sha224_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA224_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92, + 0xFB, 0xBF, 0xB0, 0x8C + }, + .len = 28 + }, + .digest = { + .data = { + 0x70, 0x0F, 0x04, 0x4D, 0x22, 0x02, 0x7D, 0x31, + 0x36, 0xDA, 0x77, 0x19, 0xB9, 0x66, 0x37, 0x7B, + 0xF1, 0x8A, 0x63, 0xBB, 0x5D, 0x1D, 0xE3, 0x9F, + 0x92, 0xF6, 0xAA, 0x19 + }, + .len = 28 + } +}; + +static const struct blockcipher_test_data +sha256_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA256, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0x7F, 0xF1, 0x0C, 0xF5, 0x90, 0x97, 0x19, 0x0F, + 0x00, 0xE4, 0x83, 0x01, 0xCA, 0x59, 0x00, 0x2E, + 0x1F, 0xC7, 0x84, 0xEE, 0x76, 0xA6, 0x39, 0x15, + 0x76, 0x2F, 0x87, 0xF9, 0x01, 0x06, 0xF3, 0xB7 + }, + .len = 32 + } +}; + +static const struct blockcipher_test_data +hmac_sha256_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92, + 0xFB, 0xBF, 0xB0, 0x8C, 0x29, 0x87, 0x90, 0xAC + }, + .len = 32 + }, + .digest = { + .data = { + 0xAF, 0x8F, 0x70, 0x1B, 0x4B, 0xAF, 0x34, 0xCB, + 0x02, 0x24, 0x48, 0x45, 0x83, 0x52, 0x8F, 0x22, + 0x06, 0x4D, 0x64, 0x09, 0x0A, 0xCC, 0x02, 0x77, + 0x71, 0x83, 0x48, 0x71, 0x07, 0x02, 0x25, 0x17 + }, + .len = 32 + } +}; + +static const struct blockcipher_test_data +sha384_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA384, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0x1D, 0xE7, 0x3F, 0x55, 0x86, 0xFE, 0x48, 0x9F, + 0xAC, 0xC6, 0x85, 0x32, 0xFA, 0x8E, 0xA6, 0x77, + 0x25, 0x84, 0xA5, 0x98, 0x8D, 0x0B, 0x80, 0xF4, + 0xEB, 0x2C, 0xFB, 0x6C, 0xEA, 0x7B, 0xFD, 0xD5, + 0xAD, 0x41, 0xAB, 0x15, 0xB0, 0x03, 0x15, 0xEC, + 0x9E, 0x3D, 0xED, 0xCB, 0x80, 0x7B, 0xF4, 0xB6 + }, + .len = 48 + } +}; + +static const struct blockcipher_test_data +hmac_sha384_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA384_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92, + 0xFB, 0xBF, 0xB0, 0x8C, 0x29, 0x87, 0x90, 0xAC, + 0x39, 0x8B, 0x5C, 0x49, 0x68, 0x1E, 0x3A, 0x05, + 0xCC, 0x68, 0x5C, 0x76, 0xCB, 0x3C, 0x71, 0x89 + }, + .len = 48 + }, + .digest = { + .data = { + 0xE2, 0x83, 0x18, 0x55, 0xB5, 0x8D, 0x94, 0x9B, + 0x01, 0xB6, 0xE2, 0x57, 0x7A, 0x62, 0xF5, 0xF4, + 0xAB, 0x39, 0xF3, 0x3C, 0x28, 0xA0, 0x0F, 0xCC, + 0xEE, 0x1C, 0xF1, 0xF8, 0x69, 0xF1, 0x24, 0x3B, + 0x10, 0x90, 0x0A, 0xE3, 0xF0, 0x59, 0xDD, 0xC0, + 0x6F, 0xE6, 0x8C, 0x84, 0xD5, 0x03, 0xF8, 0x9E + }, + .len = 48 + } +}; + +static const struct blockcipher_test_data +sha512_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA512, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .digest = { + .data = { + 0xB9, 0xBA, 0x28, 0x48, 0x3C, 0xC2, 0xD3, 0x65, + 0x4A, 0xD6, 0x00, 0x1D, 0xCE, 0x61, 0x64, 0x54, + 0x45, 0x8C, 0x64, 0x0E, 0xED, 0x0E, 0xD8, 0x1C, + 0x72, 0xCE, 0xD2, 0x44, 0x91, 0xC8, 0xEB, 0xC7, + 0x99, 0xC5, 0xCA, 0x89, 0x72, 0x64, 0x96, 0x41, + 0xC8, 0xEA, 0xB2, 0x4E, 0xD1, 0x21, 0x13, 0x49, + 0x64, 0x4E, 0x15, 0x68, 0x12, 0x67, 0x26, 0x0F, + 0x2C, 0x3C, 0x83, 0x25, 0x27, 0x86, 0xF0, 0xDB + }, + .len = 64 + } +}; + +static const struct blockcipher_test_data +hmac_sha512_test_vector = { + .auth_algo = RTE_CRYPTO_AUTH_SHA512_HMAC, + .ciphertext = { + .data = plaintext_hash, + .len = 512 + }, + .auth_key = { + .data = { + 0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA, + 0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD, + 0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92, + 0xFB, 0xBF, 0xB0, 0x8C, 0x29, 0x87, 0x90, 0xAC, + 0x39, 0x8B, 0x5C, 0x49, 0x68, 0x1E, 0x3A, 0x05, + 0xCC, 0x68, 0x5C, 0x76, 0xCB, 0x3C, 0x71, 0x89, + 0xDE, 0xAA, 0x36, 0x44, 0x98, 0x93, 0x97, 0x1E, + 0x6D, 0x53, 0x83, 0x87, 0xB3, 0xB7, 0x56, 0x41 + }, + .len = 64 + }, + .digest = { + .data = { + 0xB8, 0x0B, 0x35, 0x97, 0x3F, 0x24, 0x3F, 0x05, + 0x2A, 0x7F, 0x2F, 0xD8, 0xD7, 0x56, 0x58, 0xAD, + 0x6F, 0x8D, 0x1F, 0x4C, 0x30, 0xF9, 0xA8, 0x29, + 0x7A, 0xE0, 0x8D, 0x88, 0xF5, 0x2E, 0x94, 0xF5, + 0x06, 0xF7, 0x5D, 0x57, 0x32, 0xA8, 0x49, 0x29, + 0xEA, 0x6B, 0x6D, 0x95, 0xBD, 0x76, 0xF5, 0x79, + 0x97, 0x37, 0x0F, 0xBE, 0xC2, 0x45, 0xA0, 0x87, + 0xAF, 0x24, 0x27, 0x0C, 0x78, 0xBA, 0xBE, 0x20 + }, + .len = 64 + } +}; + +static const struct blockcipher_test_case hash_test_cases[] = { + { + .test_descr = "MD5 Digest", + .test_data = &md5_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "MD5 Digest Verify", + .test_data = &md5_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-MD5 Digest", + .test_data = &hmac_md5_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-MD5 Digest Verify", + .test_data = &hmac_md5_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA1 Digest", + .test_data = &sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA1 Digest Verify", + .test_data = &sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA1 Digest", + .test_data = &hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA1 Digest Verify", + .test_data = &hmac_sha1_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA224 Digest", + .test_data = &sha224_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA224 Digest Verify", + .test_data = &sha224_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA224 Digest", + .test_data = &hmac_sha224_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA224 Digest Verify", + .test_data = &hmac_sha224_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA256 Digest", + .test_data = &sha256_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA256 Digest Verify", + .test_data = &sha256_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA256 Digest", + .test_data = &hmac_sha256_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA256 Digest Verify", + .test_data = &hmac_sha256_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA384 Digest", + .test_data = &sha384_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA384 Digest Verify", + .test_data = &sha384_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA384 Digest", + .test_data = &hmac_sha384_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA384 Digest Verify", + .test_data = &hmac_sha384_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA512 Digest", + .test_data = &sha512_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "SHA512 Digest Verify", + .test_data = &sha512_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA512 Digest", + .test_data = &hmac_sha512_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, + { + .test_descr = "HMAC-SHA512 Digest Verify", + .test_data = &hmac_sha512_test_vector, + .op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY, + .pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO + }, +}; + +#endif /* TEST_CRYPTODEV_HASH_TEST_VECTORS_H_ */ diff --git a/app/test/test_cryptodev_perf.c b/app/test/test_cryptodev_perf.c index 6af0896..e8fc097 100644 --- a/app/test/test_cryptodev_perf.c +++ b/app/test/test_cryptodev_perf.c @@ -149,7 +149,13 @@ struct crypto_unittest_params { static struct rte_cryptodev_sym_session * test_perf_create_snow3g_session(uint8_t dev_id, enum chain_mode chain, - enum rte_crypto_cipher_algorithm cipher_algo, unsigned cipher_key_len, + enum rte_crypto_cipher_algorithm cipher_algo, + unsigned int cipher_key_len, + enum rte_crypto_auth_algorithm auth_algo); +static struct rte_cryptodev_sym_session * +test_perf_create_libcrypto_session(uint8_t dev_id, enum chain_mode chain, + enum rte_crypto_cipher_algorithm cipher_algo, + unsigned int cipher_key_len, enum rte_crypto_auth_algorithm auth_algo); static struct rte_mbuf * test_perf_create_pktmbuf(struct rte_mempool *mpool, unsigned buf_sz); @@ -157,6 +163,18 @@ static inline struct rte_crypto_op * test_perf_set_crypto_op_snow3g(struct rte_crypto_op *op, struct rte_mbuf *m, struct rte_cryptodev_sym_session *sess, unsigned data_len, unsigned digest_len); +static inline struct rte_crypto_op * +test_perf_set_crypto_op_aes(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len); +static inline struct rte_crypto_op * +test_perf_set_crypto_op_aes_gcm(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len); +static inline struct rte_crypto_op * +test_perf_set_crypto_op_3des(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len); static uint32_t get_auth_digest_length(enum rte_crypto_auth_algorithm algo); @@ -357,6 +375,28 @@ testsuite_setup(void) } } + /* Create 2 LIBCRYPTO devices if required */ + if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_LIBCRYPTO_PMD) { +#ifndef RTE_LIBRTE_PMD_LIBCRYPTO + RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO must be" + " enabled in config file to run this testsuite.\n"); + return TEST_FAILED; +#endif + nb_devs = rte_cryptodev_count_devtype( + RTE_CRYPTODEV_LIBCRYPTO_PMD); + if (nb_devs < 2) { + for (i = nb_devs; i < 2; i++) { + ret = rte_eal_vdev_init( + RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), + NULL); + + TEST_ASSERT(ret == 0, "Failed to create " + "instance %u of pmd : %s", i, + RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD)); + } + } + } + #ifndef RTE_LIBRTE_PMD_QAT if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_QAT_SYM_PMD) { RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_QAT must be enabled " @@ -367,7 +407,7 @@ testsuite_setup(void) nb_devs = rte_cryptodev_count(); if (nb_devs < 1) { - RTE_LOG(ERR, USER1, "No crypto devices found?"); + RTE_LOG(ERR, USER1, "No crypto devices found?\n"); return TEST_FAILED; } @@ -2242,6 +2282,161 @@ test_perf_snow3G_vary_burst_size(void) return 0; } +static int +test_perf_libcrypto_optimise_cyclecount(struct perf_test_params *pparams) +{ + uint32_t num_to_submit = pparams->total_operations; + struct rte_crypto_op *c_ops[num_to_submit]; + struct rte_crypto_op *proc_ops[num_to_submit]; + uint64_t failed_polls, retries, start_cycles, + end_cycles, total_cycles = 0; + uint32_t burst_sent = 0, burst_received = 0; + uint32_t i, burst_size, num_sent, num_ops_received; + + struct crypto_testsuite_params *ts_params = &testsuite_params; + + static struct rte_cryptodev_sym_session *sess; + + static struct rte_crypto_op *(*test_perf_set_crypto_op) + (struct rte_crypto_op *, struct rte_mbuf *, + struct rte_cryptodev_sym_session *, + unsigned int, unsigned int); + + unsigned int digest_length = get_auth_digest_length(pparams->auth_algo); + + if (rte_cryptodev_count() == 0) { + printf("\nNo crypto devices found. Is PMD build configured?\n"); + return TEST_FAILED; + } + + /* Create Crypto session*/ + sess = test_perf_create_libcrypto_session(ts_params->dev_id, + pparams->chain, pparams->cipher_algo, + pparams->cipher_key_length, pparams->auth_algo); + TEST_ASSERT_NOT_NULL(sess, "Session creation failed"); + + /* Generate Crypto op data structure(s)*/ + for (i = 0; i < num_to_submit ; i++) { + struct rte_mbuf *m = test_perf_create_pktmbuf( + ts_params->mbuf_mp, + pparams->buf_size); + TEST_ASSERT_NOT_NULL(m, "Failed to allocate tx_buf"); + + struct rte_crypto_op *op = + rte_crypto_op_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC); + TEST_ASSERT_NOT_NULL(op, "Failed to allocate op"); + + switch (pparams->cipher_algo) { + case RTE_CRYPTO_CIPHER_3DES_CBC: + case RTE_CRYPTO_CIPHER_3DES_CTR: + test_perf_set_crypto_op = test_perf_set_crypto_op_3des; + break; + case RTE_CRYPTO_CIPHER_AES_CBC: + case RTE_CRYPTO_CIPHER_AES_CTR: + test_perf_set_crypto_op = test_perf_set_crypto_op_aes; + break; + case RTE_CRYPTO_CIPHER_AES_GCM: + test_perf_set_crypto_op = + test_perf_set_crypto_op_aes_gcm; + break; + default: + return TEST_FAILED; + } + + op = test_perf_set_crypto_op(op, m, sess, pparams->buf_size, + digest_length); + TEST_ASSERT_NOT_NULL(op, "Failed to attach op to session"); + + c_ops[i] = op; + } + + printf("\nOn %s dev%u qp%u, %s, cipher algo:%s, cipher key length:%u, " + "auth_algo:%s, Packet Size %u bytes", + pmd_name(gbl_cryptodev_perftest_devtype), + ts_params->dev_id, 0, + chain_mode_name(pparams->chain), + cipher_algo_name(pparams->cipher_algo), + pparams->cipher_key_length, + auth_algo_name(pparams->auth_algo), + pparams->buf_size); + printf("\nOps Tx\tOps Rx\tOps/burst "); + printf("Retries EmptyPolls\tIACycles/CyOp\tIACycles/Burst\t" + "IACycles/Byte"); + + for (i = 2; i <= 128 ; i *= 2) { + num_sent = 0; + num_ops_received = 0; + retries = 0; + failed_polls = 0; + burst_size = i; + total_cycles = 0; + while (num_sent < num_to_submit) { + start_cycles = rte_rdtsc_precise(); + burst_sent = rte_cryptodev_enqueue_burst( + ts_params->dev_id, + 0, &c_ops[num_sent], + ((num_to_submit - num_sent) < + burst_size) ? + num_to_submit - num_sent : burst_size); + end_cycles = rte_rdtsc_precise(); + if (burst_sent == 0) + retries++; + num_sent += burst_sent; + total_cycles += (end_cycles - start_cycles); + + /* Wait until requests have been sent. */ + rte_delay_ms(1); + + start_cycles = rte_rdtsc_precise(); + burst_received = rte_cryptodev_dequeue_burst( + ts_params->dev_id, 0, proc_ops, + burst_size); + end_cycles = rte_rdtsc_precise(); + if (burst_received < burst_sent) + failed_polls++; + num_ops_received += burst_received; + + total_cycles += end_cycles - start_cycles; + } + + while (num_ops_received != num_to_submit) { + /* Sending 0 length burst to flush sw crypto device */ + rte_cryptodev_enqueue_burst(ts_params->dev_id, 0, + NULL, 0); + + start_cycles = rte_rdtsc_precise(); + burst_received = rte_cryptodev_dequeue_burst( + ts_params->dev_id, 0, proc_ops, + burst_size); + end_cycles = rte_rdtsc_precise(); + + total_cycles += end_cycles - start_cycles; + if (burst_received == 0) + failed_polls++; + num_ops_received += burst_received; + } + + printf("\n%u\t%u\t%u", num_sent, num_ops_received, burst_size); + printf("\t\t%"PRIu64, retries); + printf("\t%"PRIu64, failed_polls); + printf("\t\t%"PRIu64, total_cycles/num_ops_received); + printf("\t\t%"PRIu64, (total_cycles/num_ops_received) * + burst_size); + printf("\t\t%"PRIu64, + total_cycles / + (num_ops_received * pparams->buf_size)); + } + printf("\n"); + + for (i = 0; i < num_to_submit ; i++) { + rte_pktmbuf_free(c_ops[i]->sym->m_src); + rte_crypto_op_free(c_ops[i]); + } + + return TEST_SUCCESS; +} + static uint32_t get_auth_key_max_length(enum rte_crypto_auth_algorithm algo) { switch (algo) { @@ -2257,6 +2452,8 @@ static uint32_t get_auth_key_max_length(enum rte_crypto_auth_algorithm algo) return 128; case RTE_CRYPTO_AUTH_SHA512_HMAC: return 128; + case RTE_CRYPTO_AUTH_AES_GCM: + return 0; default: return 0; } @@ -2277,23 +2474,35 @@ static uint32_t get_auth_digest_length(enum rte_crypto_auth_algorithm algo) return TRUNCATED_DIGEST_BYTE_LENGTH_SHA384; case RTE_CRYPTO_AUTH_SHA512_HMAC: return TRUNCATED_DIGEST_BYTE_LENGTH_SHA512; + case RTE_CRYPTO_AUTH_AES_GCM: + return DIGEST_BYTE_LENGTH_AES_GCM; default: return 0; } } -static uint8_t aes_cbc_key[] = { +static uint8_t aes_key[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static uint8_t aes_cbc_iv[] = { +static uint8_t aes_iv[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static uint8_t triple_des_key[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static uint8_t triple_des_iv[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + static uint8_t hmac_sha_key[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -2343,7 +2552,7 @@ test_perf_create_aes_sha_session(uint8_t dev_id, enum chain_mode chain, cipher_xform.cipher.algo = cipher_algo; cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; - cipher_xform.cipher.key.data = aes_cbc_key; + cipher_xform.cipher.key.data = aes_key; cipher_xform.cipher.key.length = cipher_key_len; /* Setup HMAC Parameters */ @@ -2421,8 +2630,77 @@ test_perf_create_snow3g_session(uint8_t dev_id, enum chain_mode chain, } } -#define AES_CBC_BLOCK_SIZE 16 -#define AES_CBC_CIPHER_IV_LENGTH 16 +static struct rte_cryptodev_sym_session * +test_perf_create_libcrypto_session(uint8_t dev_id, enum chain_mode chain, + enum rte_crypto_cipher_algorithm cipher_algo, + unsigned int cipher_key_len, + enum rte_crypto_auth_algorithm auth_algo) +{ + struct rte_crypto_sym_xform cipher_xform = { 0 }; + struct rte_crypto_sym_xform auth_xform = { 0 }; + + /* Setup Cipher Parameters */ + cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; + cipher_xform.cipher.algo = cipher_algo; + cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; + + switch (cipher_algo) { + case RTE_CRYPTO_CIPHER_3DES_CBC: + case RTE_CRYPTO_CIPHER_3DES_CTR: + cipher_xform.cipher.key.data = triple_des_key; + break; + case RTE_CRYPTO_CIPHER_AES_CBC: + case RTE_CRYPTO_CIPHER_AES_CTR: + case RTE_CRYPTO_CIPHER_AES_GCM: + cipher_xform.cipher.key.data = aes_key; + break; + default: + return NULL; + } + + cipher_xform.cipher.key.length = cipher_key_len; + + /* Setup Auth Parameters */ + auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; + auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; + auth_xform.auth.algo = auth_algo; + + switch (auth_algo) { + case RTE_CRYPTO_AUTH_SHA1_HMAC: + auth_xform.auth.key.data = hmac_sha_key; + break; + case RTE_CRYPTO_AUTH_AES_GCM: + auth_xform.auth.key.data = NULL; + break; + default: + return NULL; + } + + auth_xform.auth.key.length = get_auth_key_max_length(auth_algo); + auth_xform.auth.digest_length = get_auth_digest_length(auth_algo); + + switch (chain) { + case CIPHER_HASH: + cipher_xform.next = &auth_xform; + auth_xform.next = NULL; + /* Create Crypto session*/ + return rte_cryptodev_sym_session_create(dev_id, &cipher_xform); + case HASH_CIPHER: + auth_xform.next = &cipher_xform; + cipher_xform.next = NULL; + /* Create Crypto session*/ + return rte_cryptodev_sym_session_create(dev_id, &auth_xform); + default: + return NULL; + } +} + +#define AES_BLOCK_SIZE 16 +#define AES_CIPHER_IV_LENGTH 16 + +#define TRIPLE_DES_BLOCK_SIZE 8 +#define TRIPLE_DES_CIPHER_IV_LENGTH 8 + #define SNOW3G_CIPHER_IV_LENGTH 16 static struct rte_mbuf * @@ -2441,7 +2719,7 @@ test_perf_create_pktmbuf(struct rte_mempool *mpool, unsigned buf_sz) } static inline struct rte_crypto_op * -test_perf_set_crypto_op(struct rte_crypto_op *op, struct rte_mbuf *m, +test_perf_set_crypto_op_aes(struct rte_crypto_op *op, struct rte_mbuf *m, struct rte_cryptodev_sym_session *sess, unsigned data_len, unsigned digest_len) { @@ -2455,19 +2733,54 @@ test_perf_set_crypto_op(struct rte_crypto_op *op, struct rte_mbuf *m, (m->data_off + data_len); op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, data_len); op->sym->auth.digest.length = digest_len; - op->sym->auth.aad.data = aes_cbc_iv; - op->sym->auth.aad.length = AES_CBC_CIPHER_IV_LENGTH; + op->sym->auth.aad.data = aes_iv; + op->sym->auth.aad.length = AES_CIPHER_IV_LENGTH; /* Cipher Parameters */ - op->sym->cipher.iv.data = aes_cbc_iv; - op->sym->cipher.iv.length = AES_CBC_CIPHER_IV_LENGTH; + op->sym->cipher.iv.data = aes_iv; + op->sym->cipher.iv.length = AES_CIPHER_IV_LENGTH; /* Data lengths/offsets Parameters */ op->sym->auth.data.offset = 0; op->sym->auth.data.length = data_len; - op->sym->cipher.data.offset = AES_CBC_BLOCK_SIZE; - op->sym->cipher.data.length = data_len - AES_CBC_BLOCK_SIZE; + op->sym->cipher.data.offset = AES_BLOCK_SIZE; + op->sym->cipher.data.length = data_len - AES_BLOCK_SIZE; + + op->sym->m_src = m; + + return op; +} + +static inline struct rte_crypto_op * +test_perf_set_crypto_op_aes_gcm(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len) +{ + if (rte_crypto_op_attach_sym_session(op, sess) != 0) { + rte_crypto_op_free(op); + return NULL; + } + + /* Authentication Parameters */ + op->sym->auth.digest.data = (uint8_t *)m->buf_addr + + (m->data_off + data_len); + op->sym->auth.digest.phys_addr = + rte_pktmbuf_mtophys_offset(m, data_len); + op->sym->auth.digest.length = digest_len; + op->sym->auth.aad.data = aes_iv; + op->sym->auth.aad.length = AES_CIPHER_IV_LENGTH; + + /* Cipher Parameters */ + op->sym->cipher.iv.data = aes_iv; + op->sym->cipher.iv.length = AES_CIPHER_IV_LENGTH; + + /* Data lengths/offsets Parameters */ + op->sym->auth.data.offset = AES_BLOCK_SIZE; + op->sym->auth.data.length = data_len - AES_BLOCK_SIZE; + + op->sym->cipher.data.offset = AES_BLOCK_SIZE; + op->sym->cipher.data.length = data_len - AES_BLOCK_SIZE; op->sym->m_src = m; @@ -2487,7 +2800,8 @@ test_perf_set_crypto_op_snow3g(struct rte_crypto_op *op, struct rte_mbuf *m, /* Authentication Parameters */ op->sym->auth.digest.data = (uint8_t *)m->buf_addr + (m->data_off + data_len); - op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, data_len); + op->sym->auth.digest.phys_addr = + rte_pktmbuf_mtophys_offset(m, data_len); op->sym->auth.digest.length = digest_len; op->sym->auth.aad.data = snow3g_iv; op->sym->auth.aad.length = SNOW3G_CIPHER_IV_LENGTH; @@ -2508,7 +2822,40 @@ test_perf_set_crypto_op_snow3g(struct rte_crypto_op *op, struct rte_mbuf *m, return op; } +static inline struct rte_crypto_op * +test_perf_set_crypto_op_3des(struct rte_crypto_op *op, struct rte_mbuf *m, + struct rte_cryptodev_sym_session *sess, unsigned int data_len, + unsigned int digest_len) +{ + if (rte_crypto_op_attach_sym_session(op, sess) != 0) { + rte_crypto_op_free(op); + return NULL; + } + + /* Authentication Parameters */ + op->sym->auth.digest.data = (uint8_t *)m->buf_addr + + (m->data_off + data_len); + op->sym->auth.digest.phys_addr = + rte_pktmbuf_mtophys_offset(m, data_len); + op->sym->auth.digest.length = digest_len; + op->sym->auth.aad.data = triple_des_iv; + op->sym->auth.aad.length = TRIPLE_DES_CIPHER_IV_LENGTH; + + /* Cipher Parameters */ + op->sym->cipher.iv.data = triple_des_iv; + op->sym->cipher.iv.length = TRIPLE_DES_CIPHER_IV_LENGTH; + + /* Data lengths/offsets Parameters */ + op->sym->auth.data.offset = 0; + op->sym->auth.data.length = data_len; + + op->sym->cipher.data.offset = TRIPLE_DES_BLOCK_SIZE; + op->sym->cipher.data.length = data_len - TRIPLE_DES_BLOCK_SIZE; + + op->sym->m_src = m; + return op; +} /* An mbuf set is used in each burst. An mbuf can be used by multiple bursts at * same time, i.e. as they're not dereferenced there's no need to wait until @@ -2579,7 +2926,7 @@ test_perf_aes_sha(uint8_t dev_id, uint16_t queue_id, "and free ops below."); } else { for (i = 0; i < ops_needed; i++) - ops[i] = test_perf_set_crypto_op(ops[i], + ops[i] = test_perf_set_crypto_op_aes(ops[i], mbufs[i + (pparams->burst_size * (j % NUM_MBUF_SETS))], sess, pparams->buf_size, digest_length); @@ -2790,6 +3137,155 @@ test_perf_snow3g(uint8_t dev_id, uint16_t queue_id, return TEST_SUCCESS; } +static int +test_perf_libcrypto(uint8_t dev_id, uint16_t queue_id, + struct perf_test_params *pparams) +{ + uint16_t i, k, l, m; + uint16_t j = 0; + uint16_t ops_unused = 0; + + uint64_t burst_enqueued = 0, total_enqueued = 0, burst_dequeued = 0; + uint64_t processed = 0, failed_polls = 0, retries = 0; + uint64_t tsc_start = 0, tsc_end = 0; + + unsigned int digest_length = get_auth_digest_length(pparams->auth_algo); + + struct rte_crypto_op *ops[pparams->burst_size]; + struct rte_crypto_op *proc_ops[pparams->burst_size]; + + struct rte_mbuf *mbufs[pparams->burst_size * NUM_MBUF_SETS]; + + struct crypto_testsuite_params *ts_params = &testsuite_params; + + static struct rte_cryptodev_sym_session *sess; + + static struct rte_crypto_op *(*test_perf_set_crypto_op) + (struct rte_crypto_op *, struct rte_mbuf *, + struct rte_cryptodev_sym_session *, + unsigned int, unsigned int); + + switch (pparams->cipher_algo) { + case RTE_CRYPTO_CIPHER_3DES_CBC: + case RTE_CRYPTO_CIPHER_3DES_CTR: + test_perf_set_crypto_op = test_perf_set_crypto_op_3des; + break; + case RTE_CRYPTO_CIPHER_AES_CBC: + case RTE_CRYPTO_CIPHER_AES_CTR: + test_perf_set_crypto_op = test_perf_set_crypto_op_aes; + break; + case RTE_CRYPTO_CIPHER_AES_GCM: + test_perf_set_crypto_op = test_perf_set_crypto_op_aes_gcm; + break; + default: + return TEST_FAILED; + } + + if (rte_cryptodev_count() == 0) { + printf("\nNo crypto devices found. Is PMD build configured?\n"); + return TEST_FAILED; + } + + /* Create Crypto session*/ + sess = test_perf_create_libcrypto_session(ts_params->dev_id, + pparams->chain, pparams->cipher_algo, + pparams->cipher_key_length, pparams->auth_algo); + TEST_ASSERT_NOT_NULL(sess, "Session creation failed"); + + /* Generate a burst of crypto operations */ + for (i = 0; i < (pparams->burst_size * NUM_MBUF_SETS); i++) { + mbufs[i] = test_perf_create_pktmbuf( + ts_params->mbuf_mp, + pparams->buf_size); + + if (mbufs[i] == NULL) { + printf("\nFailed to get mbuf - freeing the rest.\n"); + for (k = 0; k < i; k++) + rte_pktmbuf_free(mbufs[k]); + return -1; + } + } + + tsc_start = rte_rdtsc_precise(); + + while (total_enqueued < pparams->total_operations) { + uint16_t burst_size = + total_enqueued + pparams->burst_size <= + pparams->total_operations ? pparams->burst_size : + pparams->total_operations - total_enqueued; + uint16_t ops_needed = burst_size - ops_unused; + + if (ops_needed != rte_crypto_op_bulk_alloc(ts_params->op_mpool, + RTE_CRYPTO_OP_TYPE_SYMMETRIC, ops, ops_needed)){ + printf("\nFailed to alloc enough ops, finish dequeuing " + "and free ops below."); + } else { + for (i = 0; i < ops_needed; i++) + ops[i] = test_perf_set_crypto_op(ops[i], + mbufs[i + (pparams->burst_size * + (j % NUM_MBUF_SETS))], + sess, pparams->buf_size, digest_length); + + /* enqueue burst */ + burst_enqueued = rte_cryptodev_enqueue_burst(dev_id, + queue_id, ops, burst_size); + + if (burst_enqueued < burst_size) + retries++; + + ops_unused = burst_size - burst_enqueued; + total_enqueued += burst_enqueued; + } + + /* dequeue burst */ + burst_dequeued = rte_cryptodev_dequeue_burst(dev_id, queue_id, + proc_ops, pparams->burst_size); + if (burst_dequeued == 0) + failed_polls++; + else { + processed += burst_dequeued; + + for (l = 0; l < burst_dequeued; l++) + rte_crypto_op_free(proc_ops[l]); + } + j++; + } + + /* Dequeue any operations still in the crypto device */ + while (processed < pparams->total_operations) { + /* Sending 0 length burst to flush sw crypto device */ + rte_cryptodev_enqueue_burst(dev_id, queue_id, NULL, 0); + + /* dequeue burst */ + burst_dequeued = rte_cryptodev_dequeue_burst(dev_id, queue_id, + proc_ops, pparams->burst_size); + if (burst_dequeued == 0) + failed_polls++; + else { + processed += burst_dequeued; + + for (m = 0; m < burst_dequeued; m++) + rte_crypto_op_free(proc_ops[m]); + } + } + + tsc_end = rte_rdtsc_precise(); + + double ops_s = ((double)processed / (tsc_end - tsc_start)) + * rte_get_tsc_hz(); + double throughput = (ops_s * pparams->buf_size * NUM_MBUF_SETS) + / 1000000000; + + printf("\t%u\t%6.2f\t%10.2f\t%8"PRIu64"\t%8"PRIu64, pparams->buf_size, + ops_s / 1000000, throughput, retries, failed_polls); + + for (i = 0; i < pparams->burst_size * NUM_MBUF_SETS; i++) + rte_pktmbuf_free(mbufs[i]); + + printf("\n"); + return TEST_SUCCESS; +} + /* perf_test_aes_sha("avx2", HASH_CIPHER, 16, CBC, SHA1); @@ -2937,6 +3433,167 @@ test_perf_snow3G_vary_pkt_size(void) } static int +test_perf_libcrypto_vary_pkt_size(void) +{ + unsigned int total_operations = 1000000; + unsigned int burst_size = { 64 }; + unsigned int buf_lengths[] = { 64, 128, 256, 512, 768, 1024, 1280, 1536, + 1792, 2048 }; + uint8_t i, j; + + struct perf_test_params params_set[] = { + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key_length = 24, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key_length = 32, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key_length = 24, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_GCM, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_AES_GCM + }, + }; + + for (i = 0; i < RTE_DIM(params_set); i++) { + params_set[i].total_operations = total_operations; + params_set[i].burst_size = burst_size; + printf("\n%s. cipher algo: %s auth algo: %s cipher key size=%u." + " burst_size: %d ops\n", + chain_mode_name(params_set[i].chain), + cipher_algo_name(params_set[i].cipher_algo), + auth_algo_name(params_set[i].auth_algo), + params_set[i].cipher_key_length, + burst_size); + printf("\nBuffer Size(B)\tOPS(M)\tThroughput(Gbps)\tRetries\t" + "EmptyPolls\n"); + for (j = 0; j < RTE_DIM(buf_lengths); j++) { + params_set[i].buf_size = buf_lengths[j]; + test_perf_libcrypto(testsuite_params.dev_id, 0, + ¶ms_set[i]); + } + } + + return 0; +} + +static int +test_perf_libcrypto_vary_burst_size(void) +{ + unsigned int total_operations = 4096; + uint16_t buf_lengths[] = { 40 }; + uint8_t i, j; + + struct perf_test_params params_set[] = { + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CBC, + .cipher_key_length = 24, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR, + .cipher_key_length = 32, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_3DES_CTR, + .cipher_key_length = 24, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC + }, + { + .chain = CIPHER_HASH, + + .cipher_algo = RTE_CRYPTO_CIPHER_AES_GCM, + .cipher_key_length = 16, + .auth_algo = RTE_CRYPTO_AUTH_AES_GCM + }, + }; + + printf("\n\nStart %s.", __func__); + printf("\nThis Test measures the average IA cycle cost using a " + "constant request(packet) size. "); + printf("Cycle cost is only valid when indicators show device is not" + " busy, i.e. Retries and EmptyPolls = 0"); + + for (i = 0; i < RTE_DIM(params_set); i++) { + printf("\n"); + params_set[i].total_operations = total_operations; + + for (j = 0; j < RTE_DIM(buf_lengths); j++) { + params_set[i].buf_size = buf_lengths[j]; + test_perf_libcrypto_optimise_cyclecount(¶ms_set[i]); + } + } + + return 0; +} + +static int test_perf_aes_cbc_vary_burst_size(void) { return test_perf_crypto_qp_vary_burst_size(testsuite_params.dev_id); @@ -3377,6 +4034,19 @@ static struct unit_test_suite cryptodev_snow3g_testsuite = { } }; +static struct unit_test_suite cryptodev_libcrypto_testsuite = { + .suite_name = "Crypto Device LIBCRYPTO Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, + test_perf_libcrypto_vary_pkt_size), + TEST_CASE_ST(ut_setup, ut_teardown, + test_perf_libcrypto_vary_burst_size), + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + static int perftest_aesni_gcm_cryptodev(void) { @@ -3417,8 +4087,18 @@ perftest_qat_snow3g_cryptodev(void /*argv __rte_unused, int argc __rte_unused*/) return unit_test_suite_runner(&cryptodev_snow3g_testsuite); } +static int +perftest_libcrypto_cryptodev(void /*argv __rte_unused, int argc __rte_unused*/) +{ + gbl_cryptodev_perftest_devtype = RTE_CRYPTODEV_LIBCRYPTO_PMD; + + return unit_test_suite_runner(&cryptodev_libcrypto_testsuite); +} + REGISTER_TEST_COMMAND(cryptodev_aesni_mb_perftest, perftest_aesni_mb_cryptodev); REGISTER_TEST_COMMAND(cryptodev_qat_perftest, perftest_qat_cryptodev); REGISTER_TEST_COMMAND(cryptodev_sw_snow3g_perftest, perftest_sw_snow3g_cryptodev); REGISTER_TEST_COMMAND(cryptodev_qat_snow3g_perftest, perftest_qat_snow3g_cryptodev); REGISTER_TEST_COMMAND(cryptodev_aesni_gcm_perftest, perftest_aesni_gcm_cryptodev); +REGISTER_TEST_COMMAND(cryptodev_libcrypto_perftest, + perftest_libcrypto_cryptodev); -- 2.5.0 ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dpdk-dev] [PATCH v6 3/4] app/test: added tests for libcrypto PMD 2016-10-04 15:11 ` [dpdk-dev] [PATCH v6 3/4] app/test: added tests for libcrypto PMD Slawomir Mrozowicz @ 2016-10-06 13:30 ` Trahe, Fiona 2016-10-06 13:53 ` Azarewicz, PiotrX T 0 siblings, 1 reply; 34+ messages in thread From: Trahe, Fiona @ 2016-10-06 13:30 UTC (permalink / raw) To: Mrozowicz, SlawomirX, dev Cc: Mrozowicz, SlawomirX, Azarewicz, PiotrX T, Kerlin, MarcinX, Mrzyglod, DanielX T, Trahe, Fiona Hi Slawomir, > -----Original Message----- > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Slawomir Mrozowicz > Sent: Tuesday, October 4, 2016 4:11 PM > To: dev@dpdk.org > Cc: Mrozowicz, SlawomirX <slawomirx.mrozowicz@intel.com>; Azarewicz, > PiotrX T <piotrx.t.azarewicz@intel.com>; Kerlin, MarcinX > <marcinx.kerlin@intel.com>; Mrzyglod, DanielX T > <danielx.t.mrzyglod@intel.com> > Subject: [dpdk-dev] [PATCH v6 3/4] app/test: added tests for libcrypto PMD > > This patch contains unit tests for libcrypto PMD. User can > use app/test application to check how to use this pmd and to > verify crypto processing. > > Test name is cryptodev_libcrypto_autotest. > For performance test cryptodev_libcrypto_perftest can be used. > > Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com> > Signed-off-by: Marcin Kerlin <marcinx.kerlin@intel.com> > Signed-off-by: Daniel Mrzyglod <danielx.t.mrzyglod@intel.com> > --- > v2: > - rename AES-named functions to blockcipher > - replace different test cases with blockcipher functions pattern > - add 3DES tests into QuickAssist PMD testsuite > > v3: > - add nagative verification tests > - add big data test > > v4: > - move aes test rework to another patch > - move big data test to another patch > - checking if libcrypto pmd is available > > v5: > - add reduced big data test > > v6: > - fix checkpatch warnings This patch breaks autotests for all PMDs, due to increasing the MBUF size to UNIT16_MAX. USER1: Can't create CRYPTO_MBUFPOOL It needs more than 500MBs in the MBUFPOOL to run this test. Setting this back to MBUF_SIZE fixes the issue, but breaks 2 tests in libcrypto_autotest TestCase create_gmac_operation() line 5060 failed: no room to append aad + TestCase [27] : test_AES_GMAC_authentication_test_case_4 failed TestCase create_gmac_operation() line 5060 failed: no room to append aad + TestCase [28] : test_AES_GMAC_authentication_verify_test_case_4 failed Can you investigate if it's possible to run these 2 tests using a different smaller MBUFPOOL - maybe with only a few large mbufs? ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dpdk-dev] [PATCH v6 3/4] app/test: added tests for libcrypto PMD 2016-10-06 13:30 ` Trahe, Fiona @ 2016-10-06 13:53 ` Azarewicz, PiotrX T 0 siblings, 0 replies; 34+ messages in thread From: Azarewicz, PiotrX T @ 2016-10-06 13:53 UTC (permalink / raw) To: Trahe, Fiona Cc: Mrozowicz, SlawomirX, Kerlin, MarcinX, Mrzyglod, DanielX T, Mrozowicz, SlawomirX, dev Hi Fiona, > This patch breaks autotests for all PMDs, due to increasing the MBUF size to > UNIT16_MAX. > USER1: Can't create CRYPTO_MBUFPOOL > > It needs more than 500MBs in the MBUFPOOL to run this test. > Setting this back to MBUF_SIZE fixes the issue, but breaks 2 tests in > libcrypto_autotest > > TestCase create_gmac_operation() line 5060 failed: no room to append aad > + TestCase [27] : test_AES_GMAC_authentication_test_case_4 failed > TestCase create_gmac_operation() line 5060 failed: no room to append aad > + TestCase [28] : test_AES_GMAC_authentication_verify_test_case_4 failed > > Can you investigate if it's possible to run these 2 tests using a different > smaller MBUFPOOL - maybe with only a few large mbufs? Yes, I think that it is possible to run these 2 tests using a different mempoll. I will make a fix for the issue. Piotr ^ permalink raw reply [flat|nested] 34+ messages in thread
* [dpdk-dev] [PATCH v6 4/4] examples/l2fwd-crypto: updated example for libcrypto PMD 2016-10-04 15:11 ` [dpdk-dev] [PATCH v6 " Slawomir Mrozowicz ` (2 preceding siblings ...) 2016-10-04 15:11 ` [dpdk-dev] [PATCH v6 3/4] app/test: added tests for libcrypto PMD Slawomir Mrozowicz @ 2016-10-04 15:11 ` Slawomir Mrozowicz 2016-10-04 23:36 ` [dpdk-dev] [PATCH v6 0/4] new crypto software based device De Lara Guarch, Pablo 4 siblings, 0 replies; 34+ messages in thread From: Slawomir Mrozowicz @ 2016-10-04 15:11 UTC (permalink / raw) To: dev; +Cc: Slawomir Mrozowicz, Daniel Mrzyglod Libcrypto PMD has support for: Supported cipher algorithms: RTE_CRYPTO_CIPHER_3DES_CBC RTE_CRYPTO_CIPHER_AES_CBC RTE_CRYPTO_CIPHER_AES_CTR RTE_CRYPTO_CIPHER_3DES_CTR RTE_CRYPTO_CIPHER_AES_GCM Supported authentication algorithms: RTE_CRYPTO_AUTH_AES_GMAC RTE_CRYPTO_AUTH_MD5 RTE_CRYPTO_AUTH_SHA1 RTE_CRYPTO_AUTH_SHA224 RTE_CRYPTO_AUTH_SHA256 RTE_CRYPTO_AUTH_SHA384 RTE_CRYPTO_AUTH_SHA512 RTE_CRYPTO_AUTH_MD5_HMAC RTE_CRYPTO_AUTH_SHA1_HMAC RTE_CRYPTO_AUTH_SHA224_HMAC RTE_CRYPTO_AUTH_SHA256_HMAC RTE_CRYPTO_AUTH_SHA384_HMAC RTE_CRYPTO_AUTH_SHA512_HMAC Signed-off-by: Daniel Mrzyglod <danielx.t.mrzyglod@intel.com> --- v3: - change description --- examples/l2fwd-crypto/main.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/examples/l2fwd-crypto/main.c b/examples/l2fwd-crypto/main.c index 0593734..dae45f5 100644 --- a/examples/l2fwd-crypto/main.c +++ b/examples/l2fwd-crypto/main.c @@ -340,15 +340,22 @@ fill_supported_algorithm_tables(void) strcpy(supported_auth_algo[i], "NOT_SUPPORTED"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_AES_GCM], "AES_GCM"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_AES_GMAC], "AES_GMAC"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_MD5_HMAC], "MD5_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_MD5], "MD5"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_NULL], "NULL"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_AES_XCBC_MAC], "AES_XCBC_MAC"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA1_HMAC], "SHA1_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA1], "SHA1"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA224_HMAC], "SHA224_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA224], "SHA224"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA256_HMAC], "SHA256_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA256], "SHA256"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA384_HMAC], "SHA384_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA384], "SHA384"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA512_HMAC], "SHA512_HMAC"); + strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA512], "SHA512"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SNOW3G_UIA2], "SNOW3G_UIA2"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_ZUC_EIA3], "ZUC_EIA3"); strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_KASUMI_F9], "KASUMI_F9"); @@ -363,6 +370,8 @@ fill_supported_algorithm_tables(void) strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_SNOW3G_UEA2], "SNOW3G_UEA2"); strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_ZUC_EEA3], "ZUC_EEA3"); strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_KASUMI_F8], "KASUMI_F8"); + strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_3DES_CTR], "3DES_CTR"); + strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_3DES_CBC], "3DES_CBC"); } -- 2.5.0 ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dpdk-dev] [PATCH v6 0/4] new crypto software based device 2016-10-04 15:11 ` [dpdk-dev] [PATCH v6 " Slawomir Mrozowicz ` (3 preceding siblings ...) 2016-10-04 15:11 ` [dpdk-dev] [PATCH v6 4/4] examples/l2fwd-crypto: updated example " Slawomir Mrozowicz @ 2016-10-04 23:36 ` De Lara Guarch, Pablo 2016-10-05 0:05 ` De Lara Guarch, Pablo 4 siblings, 1 reply; 34+ messages in thread From: De Lara Guarch, Pablo @ 2016-10-04 23:36 UTC (permalink / raw) To: Mrozowicz, SlawomirX, dev; +Cc: Mrozowicz, SlawomirX > -----Original Message----- > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Slawomir Mrozowicz > Sent: Tuesday, October 04, 2016 8:11 AM > To: dev@dpdk.org > Cc: Mrozowicz, SlawomirX > Subject: [dpdk-dev] [PATCH v6 0/4] new crypto software based device > > This code provides the initial implementation of the libcrypto poll mode > driver. > All cryptography operations are using Openssl library crypto API. > Each algorithm uses EVP_ interface from openssl API - which is recommended > by > Openssl maintainers. > > For more information about how to use this driver, go to: > doc/guides/cryptodevs/libcrypto.rst > > Changes in V6: > - fix checkpatch warnings > > Changes in V5: > - reduce source of big data test > > Changes in V4: > - move aes test rework to another patch > - move big data test to another patch > - checking if libcrypto pmd is available > > Changes in V3: > - add nagative verification tests > - add big data test > - fix pmd according to negative verification tests > - change gmac aad max size > - update documentation and commits comments > > Changes in V2: > - add gcm/gmac algorithm correction > - unit test rework > > Slawomir Mrozowicz (1): > libcrypto_pmd: initial implementation of SW crypto device > > Piotr Azarewicz (2) > app/test: cryptodev AES tests rework > app/test: added tests for libcrypto PMD > > Daniel Mrzyglod (1) > examples/l2fwd-crypto: updated example for libcrypto PMD > > MAINTAINERS | 4 + > app/test/Makefile | 2 +- > app/test/test_cryptodev.c | 1584 ++++++++++++++++++-- > app/test/test_cryptodev.h | 1 + > app/test/test_cryptodev_aes.c | 687 --------- > app/test/test_cryptodev_aes.h | 1124 -------------- > app/test/test_cryptodev_aes_test_vectors.h | 1097 ++++++++++++++ > app/test/test_cryptodev_blockcipher.c | 538 +++++++ > app/test/test_cryptodev_blockcipher.h | 125 ++ > app/test/test_cryptodev_des_test_vectors.h | 955 ++++++++++++ > app/test/test_cryptodev_gcm_test_vectors.h | 36 +- > app/test/test_cryptodev_hash_test_vectors.h | 491 ++++++ > app/test/test_cryptodev_perf.c | 712 ++++++++- > config/common_base | 6 + > doc/guides/cryptodevs/index.rst | 1 + > doc/guides/cryptodevs/libcrypto.rst | 116 ++ > doc/guides/rel_notes/release_16_11.rst | 23 +- > drivers/crypto/Makefile | 1 + > drivers/crypto/libcrypto/Makefile | 60 + > drivers/crypto/libcrypto/rte_libcrypto_pmd.c | 1062 +++++++++++++ > drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c | 708 +++++++++ > .../crypto/libcrypto/rte_libcrypto_pmd_private.h | 174 +++ > .../crypto/libcrypto/rte_pmd_libcrypto_version.map | 3 + > examples/l2fwd-crypto/main.c | 9 + > lib/librte_cryptodev/rte_cryptodev.h | 5 +- > mk/rte.app.mk | 23 +- > 26 files changed, 7621 insertions(+), 1926 deletions(-) > delete mode 100644 app/test/test_cryptodev_aes.c > delete mode 100644 app/test/test_cryptodev_aes.h > create mode 100644 app/test/test_cryptodev_aes_test_vectors.h > create mode 100644 app/test/test_cryptodev_blockcipher.c > create mode 100644 app/test/test_cryptodev_blockcipher.h > create mode 100644 app/test/test_cryptodev_des_test_vectors.h > create mode 100644 app/test/test_cryptodev_hash_test_vectors.h > create mode 100644 doc/guides/cryptodevs/libcrypto.rst > create mode 100644 drivers/crypto/libcrypto/Makefile > create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd.c > create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c > create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h > create mode 100644 > drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map > > -- > 2.5.0 Series-acked-by: Pablo de Lara <pablo.de.lara.guarch@intel.com> Thanks for all the rework! ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [dpdk-dev] [PATCH v6 0/4] new crypto software based device 2016-10-04 23:36 ` [dpdk-dev] [PATCH v6 0/4] new crypto software based device De Lara Guarch, Pablo @ 2016-10-05 0:05 ` De Lara Guarch, Pablo 0 siblings, 0 replies; 34+ messages in thread From: De Lara Guarch, Pablo @ 2016-10-05 0:05 UTC (permalink / raw) To: De Lara Guarch, Pablo, Mrozowicz, SlawomirX, dev; +Cc: Mrozowicz, SlawomirX > -----Original Message----- > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of De Lara Guarch, > Pablo > Sent: Tuesday, October 04, 2016 4:37 PM > To: Mrozowicz, SlawomirX; dev@dpdk.org > Cc: Mrozowicz, SlawomirX > Subject: Re: [dpdk-dev] [PATCH v6 0/4] new crypto software based device > > > > > -----Original Message----- > > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Slawomir > Mrozowicz > > Sent: Tuesday, October 04, 2016 8:11 AM > > To: dev@dpdk.org > > Cc: Mrozowicz, SlawomirX > > Subject: [dpdk-dev] [PATCH v6 0/4] new crypto software based device > > > > This code provides the initial implementation of the libcrypto poll mode > > driver. > > All cryptography operations are using Openssl library crypto API. > > Each algorithm uses EVP_ interface from openssl API - which is > recommended > > by > > Openssl maintainers. > > > > For more information about how to use this driver, go to: > > doc/guides/cryptodevs/libcrypto.rst > > > > Changes in V6: > > - fix checkpatch warnings > > > > Changes in V5: > > - reduce source of big data test > > > > Changes in V4: > > - move aes test rework to another patch > > - move big data test to another patch > > - checking if libcrypto pmd is available > > > > Changes in V3: > > - add nagative verification tests > > - add big data test > > - fix pmd according to negative verification tests > > - change gmac aad max size > > - update documentation and commits comments > > > > Changes in V2: > > - add gcm/gmac algorithm correction > > - unit test rework > > > > Slawomir Mrozowicz (1): > > libcrypto_pmd: initial implementation of SW crypto device > > > > Piotr Azarewicz (2) > > app/test: cryptodev AES tests rework > > app/test: added tests for libcrypto PMD > > > > Daniel Mrzyglod (1) > > examples/l2fwd-crypto: updated example for libcrypto PMD > > > > MAINTAINERS | 4 + > > app/test/Makefile | 2 +- > > app/test/test_cryptodev.c | 1584 ++++++++++++++++++-- > > app/test/test_cryptodev.h | 1 + > > app/test/test_cryptodev_aes.c | 687 --------- > > app/test/test_cryptodev_aes.h | 1124 -------------- > > app/test/test_cryptodev_aes_test_vectors.h | 1097 ++++++++++++++ > > app/test/test_cryptodev_blockcipher.c | 538 +++++++ > > app/test/test_cryptodev_blockcipher.h | 125 ++ > > app/test/test_cryptodev_des_test_vectors.h | 955 ++++++++++++ > > app/test/test_cryptodev_gcm_test_vectors.h | 36 +- > > app/test/test_cryptodev_hash_test_vectors.h | 491 ++++++ > > app/test/test_cryptodev_perf.c | 712 ++++++++- > > config/common_base | 6 + > > doc/guides/cryptodevs/index.rst | 1 + > > doc/guides/cryptodevs/libcrypto.rst | 116 ++ > > doc/guides/rel_notes/release_16_11.rst | 23 +- > > drivers/crypto/Makefile | 1 + > > drivers/crypto/libcrypto/Makefile | 60 + > > drivers/crypto/libcrypto/rte_libcrypto_pmd.c | 1062 +++++++++++++ > > drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c | 708 +++++++++ > > .../crypto/libcrypto/rte_libcrypto_pmd_private.h | 174 +++ > > .../crypto/libcrypto/rte_pmd_libcrypto_version.map | 3 + > > examples/l2fwd-crypto/main.c | 9 + > > lib/librte_cryptodev/rte_cryptodev.h | 5 +- > > mk/rte.app.mk | 23 +- > > 26 files changed, 7621 insertions(+), 1926 deletions(-) > > delete mode 100644 app/test/test_cryptodev_aes.c > > delete mode 100644 app/test/test_cryptodev_aes.h > > create mode 100644 app/test/test_cryptodev_aes_test_vectors.h > > create mode 100644 app/test/test_cryptodev_blockcipher.c > > create mode 100644 app/test/test_cryptodev_blockcipher.h > > create mode 100644 app/test/test_cryptodev_des_test_vectors.h > > create mode 100644 app/test/test_cryptodev_hash_test_vectors.h > > create mode 100644 doc/guides/cryptodevs/libcrypto.rst > > create mode 100644 drivers/crypto/libcrypto/Makefile > > create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd.c > > create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c > > create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h > > create mode 100644 > > drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map > > > > -- > > 2.5.0 > > Series-acked-by: Pablo de Lara <pablo.de.lara.guarch@intel.com> > > Thanks for all the rework! Applied to dpdk-next-crypto. I made a small change in the first patch, due to the changes introduced in http://dpdk.org/ml/archives/dev/2016-September/047087.html, which affects driver registration. Thanks, Pablo ^ permalink raw reply [flat|nested] 34+ messages in thread
end of thread, other threads:[~2016-10-06 13:53 UTC | newest] Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2016-09-19 8:59 [dpdk-dev] [PATCH v2 0/4] new crypto software based device Michal Jastrzebski 2016-09-19 8:59 ` [dpdk-dev] [PATCH v2 1/4] libcrypto_pmd: initial implementation of SW crypto device Michal Jastrzebski 2016-09-19 8:59 ` [dpdk-dev] [PATCH v2 2/4] lib/cryptodev: added support to libcrypto PMD Michal Jastrzebski 2016-09-19 22:59 ` De Lara Guarch, Pablo 2016-09-19 8:59 ` [dpdk-dev] [PATCH v2 3/4] app/test: added tests for " Michal Jastrzebski 2016-09-19 8:59 ` [dpdk-dev] [PATCH v2 4/4] examples/l2fwd-crypto: updated example " Michal Jastrzebski 2016-09-19 23:58 ` De Lara Guarch, Pablo 2016-09-29 14:14 ` [dpdk-dev] [PATCH v3 0/3] new crypto software based device Slawomir Mrozowicz 2016-09-29 14:14 ` [dpdk-dev] [PATCH v3 1/3] libcrypto_pmd: initial implementation of SW crypto device Slawomir Mrozowicz 2016-09-29 14:14 ` [dpdk-dev] [PATCH v3 2/3] app/test: added tests for libcrypto PMD Slawomir Mrozowicz 2016-09-29 14:39 ` [dpdk-dev] [PATCH v3 3/3] examples/l2fwd-crypto: updated example " Slawomir Mrozowicz 2016-09-30 16:17 ` [dpdk-dev] [PATCH v4 0/5] new crypto software based device Slawomir Mrozowicz 2016-09-30 16:17 ` [dpdk-dev] [PATCH v4 1/5] libcrypto_pmd: initial implementation of SW crypto device Slawomir Mrozowicz 2016-09-30 16:32 ` [dpdk-dev] [PATCH v4 2/5] app/test: cryptodev AES tests rework Slawomir Mrozowicz 2016-09-30 16:32 ` [dpdk-dev] [PATCH v4 3/5] app/test: added tests for libcrypto PMD Slawomir Mrozowicz 2016-09-30 16:32 ` [dpdk-dev] [PATCH v4 4/5] app/test: added big data GMAC test for libcrypto Slawomir Mrozowicz 2016-09-30 17:18 ` Thomas Monjalon 2016-10-03 8:12 ` Mrozowicz, SlawomirX 2016-09-30 16:32 ` [dpdk-dev] [PATCH v4 5/5] examples/l2fwd-crypto: updated example for libcrypto PMD Slawomir Mrozowicz 2016-10-03 14:26 ` [dpdk-dev] [PATCH v5 0/4] new crypto software based device Slawomir Mrozowicz 2016-10-03 14:45 ` [dpdk-dev] [PATCH v5 1/4] libcrypto_pmd: initial implementation of SW crypto device Slawomir Mrozowicz 2016-10-03 15:02 ` [dpdk-dev] [PATCH v5 2/4] app/test: cryptodev AES tests rework Slawomir Mrozowicz 2016-10-03 15:17 ` [dpdk-dev] [PATCH v5 3/4] app/test: added tests for libcrypto PMD Slawomir Mrozowicz 2016-10-03 15:28 ` [dpdk-dev] [PATCH v5 4/4] examples/l2fwd-crypto: updated example " Slawomir Mrozowicz 2016-10-03 22:36 ` [dpdk-dev] [PATCH v5 0/4] new crypto software based device De Lara Guarch, Pablo 2016-10-04 15:11 ` [dpdk-dev] [PATCH v6 " Slawomir Mrozowicz 2016-10-04 15:11 ` [dpdk-dev] [PATCH v6 1/4] libcrypto_pmd: initial implementation of SW crypto device Slawomir Mrozowicz 2016-10-04 15:11 ` [dpdk-dev] [PATCH v6 2/4] app/test: cryptodev AES tests rework Slawomir Mrozowicz 2016-10-04 15:11 ` [dpdk-dev] [PATCH v6 3/4] app/test: added tests for libcrypto PMD Slawomir Mrozowicz 2016-10-06 13:30 ` Trahe, Fiona 2016-10-06 13:53 ` Azarewicz, PiotrX T 2016-10-04 15:11 ` [dpdk-dev] [PATCH v6 4/4] examples/l2fwd-crypto: updated example " Slawomir Mrozowicz 2016-10-04 23:36 ` [dpdk-dev] [PATCH v6 0/4] new crypto software based device De Lara Guarch, Pablo 2016-10-05 0:05 ` De Lara Guarch, Pablo
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).