From patchwork Fri Jan 12 02:28:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dongsoo Lee X-Patchwork-Id: 13517906 Received: from mail.nsr.re.kr (unknown [210.104.33.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 26F8B10783; Fri, 12 Jan 2024 02:29:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nsr.re.kr Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nsr.re.kr Received: from 210.104.33.70 (nsr.re.kr) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128 bits)) by mail.nsr.re.kr with SMTP; Fri, 12 Jan 2024 11:29:34 +0900 X-Sender: letrhee@nsr.re.kr Received: from 192.168.155.188 ([192.168.155.188]) by mail.nsr.re.kr (Crinity Message Backbone-7.0.1) with SMTP ID 155; Fri, 12 Jan 2024 11:29:29 +0900 (KST) From: Dongsoo Lee To: Herbert Xu , "David S. Miller" , Jens Axboe , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" Cc: linux-crypto@vger.kernel.org, linux-block@vger.kernel.org, linux-fscrypt@vger.kernel.org, linux-kernel@vger.kernel.org, Dongsoo Lee Subject: [PATCH v6 RESEND 1/5] crypto: LEA block cipher implementation Date: Fri, 12 Jan 2024 02:28:55 +0000 Message-Id: <20240112022859.2384-2-letrhee@nsr.re.kr> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240112022859.2384-1-letrhee@nsr.re.kr> References: <20240112022859.2384-1-letrhee@nsr.re.kr> Precedence: bulk X-Mailing-List: linux-block@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 LEA is a 128-bit block cipher developed by South Korea. LEA is a Korean national standard (KS X 3246) and included in the ISO/IEC 29192-2:2019 standard (Information security - Lightweight cryptography - Part 2: Block ciphers). The LEA algorithm is a symmetric key cipher that processes data blocks of 128-bits and has three different key lengths, each with a different number of rounds: - LEA-128: 128-bit key, 24 rounds, - LEA-192: 192-bit key, 28 rounds, and - LEA-256: 256-bit key, 32 rounds. The round function of LEA consists of 32-bit ARX(modular Addition, bitwise Rotation, and bitwise XOR) operations. - https://seed.kisa.or.kr/kisa/algorithm/EgovLeaInfo.do Signed-off-by: Dongsoo Lee --- crypto/Kconfig | 18 ++ crypto/Makefile | 1 + crypto/lea_generic.c | 410 +++++++++++++++++++++++++++++++++++++++++++ include/crypto/lea.h | 44 +++++ 4 files changed, 473 insertions(+) create mode 100644 crypto/lea_generic.c create mode 100644 include/crypto/lea.h diff --git a/crypto/Kconfig b/crypto/Kconfig index 70661f58ee41..83649a03baf7 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -494,6 +494,24 @@ config CRYPTO_KHAZAD See https://web.archive.org/web/20171011071731/http://www.larc.usp.br/~pbarreto/KhazadPage.html for further information. +config CRYPTO_LEA + tristate "LEA" + select CRYPTO_ALGAPI + help + LEA is a 128-bit lightweight block cipher developed by South Korea. + + LEA is the a Korean standard (KS X 3246) and is included in the + ISO/IEC 29192-2:2019 standard (Information security - Lightweight + cryptography - Part 2: Block ciphers). + + It consists of 32-bit integer addition, rotation, and XOR, which can + be performed effectively on CPUs that support 32-bit operations. + + It supports 128-bit, 192-bit, and 256-bit keys. + + See: + https://seed.kisa.or.kr/kisa/algorithm/EgovLeaInfo.do + config CRYPTO_SEED tristate "SEED" depends on CRYPTO_USER_API_ENABLE_OBSOLETE diff --git a/crypto/Makefile b/crypto/Makefile index 5ac6876f935a..6b6ab104ec82 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -154,6 +154,7 @@ obj-$(CONFIG_CRYPTO_KHAZAD) += khazad.o obj-$(CONFIG_CRYPTO_ANUBIS) += anubis.o obj-$(CONFIG_CRYPTO_SEED) += seed.o obj-$(CONFIG_CRYPTO_ARIA) += aria_generic.o +obj-$(CONFIG_CRYPTO_LEA) += lea_generic.o obj-$(CONFIG_CRYPTO_CHACHA20) += chacha_generic.o obj-$(CONFIG_CRYPTO_POLY1305) += poly1305_generic.o obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o diff --git a/crypto/lea_generic.c b/crypto/lea_generic.c new file mode 100644 index 000000000000..792db01a39e0 --- /dev/null +++ b/crypto/lea_generic.c @@ -0,0 +1,410 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Cryptographic API. + * + * The LEA Cipher Algorithm + * + * LEA is a 128-bit block cipher developed by South Korea. + * + * LEA is a Korean national standard (KS X 3246) and included in the ISO/IEC + * 29192-2:2019 standard (Information security - Lightweight cryptography - + * Part 2: Block ciphers). + * + * Copyright (c) 2023 National Security Research. + * Author: Dongsoo Lee + */ + +#include +#include +#include +#include + +/* + * The eight 32-bit constant values δ[8] are used in the key schedule algorithm. + * They are the first 256-bits of the fractional part of + * sqrt(766965) = sqrt("LEA") + * The actual constant is additionally left-rotated from δ, which is to make the + * key schedule more compact. + * This constant can be calculated in Python as follows: + * + * from decimal import * + * rotl32 = lambda v, i: ((v << i) ^ (v >> (32 - i))) & 0xffffffff + * getcontext().prec = 87 # >= 32 * (8 + 1) / math.log(10, 2) + * + * LEA_ord = int(''.join([str(ord(ch)) for ch in "LEA"])) #766965 + * sqrt_seq = Decimal(LEA_ord).sqrt() + * + * for i in range(8): + * sqrt_seq = (sqrt_seq % 1) * (2 ** 32) + * delta = int(sqrt_seq) #δ[i] + * lea_const = rotl32(delta, i) #actual constant + * print(hex(lea_const)) + */ +static const u32 lea_constants[8] = { + 0xc3efe9db, 0x88c4d604, 0xe789f229, 0xc6f98763, + 0x15ea49e7, 0xf0bb4158, 0x13bc8ab8, 0xe204abf2, +}; + +#define LEA_SET_RK1(V, CV, ROT1, ROT2) (V = rol32(V + rol32(CV, ROT1), ROT2)) + +#define LEA_SET_RK6(V0, V1, V2, V3, V4, V5, CV_ARR, ROT0, CV_IDX) \ + do { \ + const u32 CV_I = CV_ARR[CV_IDX]; \ + CV_ARR[CV_IDX] = rol32(CV_I, ROT0); \ + LEA_SET_RK1(V0, CV_I, 0, 1); \ + LEA_SET_RK1(V1, CV_I, 1, 3); \ + LEA_SET_RK1(V2, CV_I, 2, 6); \ + LEA_SET_RK1(V3, CV_I, 3, 11); \ + LEA_SET_RK1(V4, CV_I, 4, 13); \ + LEA_SET_RK1(V5, CV_I, 5, 17); \ + } while (0) + +#define STORE_RND_KEY6(RK, V0, V1, V2, V3, V4, V5, WAY) \ + do { \ + RK[0] = V0; \ + RK[1] = V1; \ + RK[2] = V2; \ + RK[3] = V3; \ + RK[4] = V4; \ + RK[5] = V5; \ + RK += WAY * LEA_ROUND_KEY_WIDTH; \ + } while (0) + +/** + * LEA-128 can encrypt with four 32-bit integers as a round key. But in order to + * incorporate it with the encryption function for LEA-192 and LEA-256, one + * round key consists of six 32-bit integers. + */ +static void lea128_set_key(struct crypto_lea_ctx *key, const u8 *in_key) +{ + u32 x0 = get_unaligned_le32(&in_key[4 * 0]); + u32 x1 = get_unaligned_le32(&in_key[4 * 1]); + u32 x2 = get_unaligned_le32(&in_key[4 * 2]); + u32 x4 = get_unaligned_le32(&in_key[4 * 3]); + + u32 *rk_enc = key->rk_enc; + u32 *rk_dec = + key->rk_dec + (LEA128_ROUND_CNT - 1) * LEA_ROUND_KEY_WIDTH; + u32 cv[4]; + u32 rnd; + + memcpy(cv, lea_constants, sizeof(cv)); + key->round = LEA128_ROUND_CNT; + + for (rnd = 0; rnd < LEA128_ROUND_CNT; ++rnd) { + const u32 offset = rnd % 4; + const u32 cv_i = cv[offset]; + + cv[offset] = rol32(cv_i, 4); + LEA_SET_RK1(x0, cv_i, 0, 1); + LEA_SET_RK1(x1, cv_i, 1, 3); + LEA_SET_RK1(x2, cv_i, 2, 6); + LEA_SET_RK1(x4, cv_i, 3, 11); + + STORE_RND_KEY6(rk_enc, x0, x1, x2, x1, x4, x1, 1); + STORE_RND_KEY6(rk_dec, x0, x1, x2 ^ x1, x1, x4 ^ x1, x1, -1); + } +} + +/** + * The key schedule for LEA-192 can be represented as follows, + * regarding the round key as an array of 32-bit integers. + * + * T[0:6] = K[0:6] + * for i in range(28): + * T[0] = rotl32(T[0] + rotl32(delta[i % 6], i + 0), 1) + * T[1] = rotl32(T[1] + rotl32(delta[i % 6], i + 1), 3) + * T[2] = rotl32(T[2] + rotl32(delta[i % 6], i + 2), 6) + * T[3] = rotl32(T[3] + rotl32(delta[i % 6], i + 3), 11) + * T[4] = rotl32(T[4] + rotl32(delta[i % 6], i + 4), 13) + * T[5] = rotl32(T[5] + rotl32(delta[i % 6], i + 5), 17) + * RK[i*6:(i+1)*6] = T + * + * The key schedules of the LEA-128 and LEA-256 can be understood as variations + * of this calculation. + * The constants have already been left-rotated, so rotl32 of delta is + * simplified in each iteration. + */ +static void lea192_set_key(struct crypto_lea_ctx *key, const u8 *in_key) +{ + u32 x0 = get_unaligned_le32(&in_key[4 * 0]); + u32 x1 = get_unaligned_le32(&in_key[4 * 1]); + u32 x2 = get_unaligned_le32(&in_key[4 * 2]); + u32 x3 = get_unaligned_le32(&in_key[4 * 3]); + u32 x4 = get_unaligned_le32(&in_key[4 * 4]); + u32 x5 = get_unaligned_le32(&in_key[4 * 5]); + + u32 *rk_enc = key->rk_enc; + u32 *rk_dec = + key->rk_dec + (LEA192_ROUND_CNT - 1) * LEA_ROUND_KEY_WIDTH; + u32 cv[6]; + u32 rnd; + + memcpy(cv, lea_constants, sizeof(cv)); + key->round = LEA192_ROUND_CNT; + + for (rnd = 0; rnd < LEA192_ROUND_CNT; ++rnd) { + const u32 offset = rnd % 6; + + LEA_SET_RK6(x0, x1, x2, x3, x4, x5, cv, 6, offset); + STORE_RND_KEY6(rk_enc, x0, x1, x2, x3, x4, x5, 1); + STORE_RND_KEY6(rk_dec, x0, x1, x2 ^ x1, x3, x4 ^ x3, x5, -1); + } +} + +/** + * In the LEA-256, the encryption key is eight 32-bit integers, which does not + * match LEA's round key width of 6. Therefore, partial loop unrolling is used + * to compute 4 round keys per loop. + */ +static void lea256_set_key(struct crypto_lea_ctx *key, const u8 *in_key) +{ + u32 x0 = get_unaligned_le32(&in_key[4 * 0]); + u32 x1 = get_unaligned_le32(&in_key[4 * 1]); + u32 x2 = get_unaligned_le32(&in_key[4 * 2]); + u32 x3 = get_unaligned_le32(&in_key[4 * 3]); + u32 x4 = get_unaligned_le32(&in_key[4 * 4]); + u32 x5 = get_unaligned_le32(&in_key[4 * 5]); + u32 x6 = get_unaligned_le32(&in_key[4 * 6]); + u32 x7 = get_unaligned_le32(&in_key[4 * 7]); + + u32 *rk_enc = key->rk_enc; + u32 *rk_dec = + key->rk_dec + (LEA256_ROUND_CNT - 1) * LEA_ROUND_KEY_WIDTH; + u32 cv[8]; + u32 rnd; + + memcpy(cv, lea_constants, sizeof(cv)); + key->round = LEA256_ROUND_CNT; + + for (rnd = 0; rnd < LEA256_ROUND_CNT; rnd += 4) { + u32 offset = rnd % 8; + + LEA_SET_RK6(x0, x1, x2, x3, x4, x5, cv, 8, offset); + STORE_RND_KEY6(rk_enc, x0, x1, x2, x3, x4, x5, 1); + STORE_RND_KEY6(rk_dec, x0, x1, x2 ^ x1, x3, x4 ^ x3, x5, -1); + + ++offset; + LEA_SET_RK6(x6, x7, x0, x1, x2, x3, cv, 8, offset); + STORE_RND_KEY6(rk_enc, x6, x7, x0, x1, x2, x3, 1); + STORE_RND_KEY6(rk_dec, x6, x7, x0 ^ x7, x1, x2 ^ x1, x3, -1); + + ++offset; + LEA_SET_RK6(x4, x5, x6, x7, x0, x1, cv, 8, offset); + STORE_RND_KEY6(rk_enc, x4, x5, x6, x7, x0, x1, 1); + STORE_RND_KEY6(rk_dec, x4, x5, x6 ^ x5, x7, x0 ^ x7, x1, -1); + + ++offset; + LEA_SET_RK6(x2, x3, x4, x5, x6, x7, cv, 8, offset); + STORE_RND_KEY6(rk_enc, x2, x3, x4, x5, x6, x7, 1); + STORE_RND_KEY6(rk_dec, x2, x3, x4 ^ x3, x5, x6 ^ x5, x7, -1); + } +} + +int lea_set_key(struct crypto_lea_ctx *key, const u8 *in_key, u32 key_len) +{ + switch (key_len) { + case 16: + lea128_set_key(key, in_key); + return 0; + case 24: + lea192_set_key(key, in_key); + return 0; + case 32: + lea256_set_key(key, in_key); + return 0; + } + + return -EINVAL; +} +EXPORT_SYMBOL_GPL(lea_set_key); + +/** + * The encryption round function can be represented as follows + * + * next_v3 = v0 + * next_v2 = rotr32((v2 ^ RK[4]) + (v3 ^ RK[5]), 3); + * next_v1 = rotr32((v1 ^ RK[2]) + (v2 ^ RK[3]), 5); + * next_v0 = rotl32((v0 ^ RK[0]) + (v1 ^ RK[1]), 9); + * + * It is possible to avoid shuffling by partial unrolling, which unrolls 4 + * rounds in a loop. + */ +#define LEA_ENC_RND(V0, V1, V2, V3, RK) \ + do { \ + V3 = ror32((V2 ^ RK[4]) + (V3 ^ RK[5]), 3); \ + V2 = ror32((V1 ^ RK[2]) + (V2 ^ RK[3]), 5); \ + V1 = rol32((V0 ^ RK[0]) + (V1 ^ RK[1]), 9); \ + RK += LEA_ROUND_KEY_WIDTH; \ + } while (0) + +void lea_encrypt(const struct crypto_lea_ctx *key, u8 *out, const u8 *in) +{ + u32 x0 = get_unaligned_le32(&in[4 * 0]); + u32 x1 = get_unaligned_le32(&in[4 * 1]); + u32 x2 = get_unaligned_le32(&in[4 * 2]); + u32 x3 = get_unaligned_le32(&in[4 * 3]); + + const u32 *rk = key->rk_enc; + const u32 *rk_tail = rk + LEA_ROUND_KEY_WIDTH * key->round; + + while (rk < rk_tail) { + LEA_ENC_RND(x0, x1, x2, x3, rk); + LEA_ENC_RND(x1, x2, x3, x0, rk); + LEA_ENC_RND(x2, x3, x0, x1, rk); + LEA_ENC_RND(x3, x0, x1, x2, rk); + } + + put_unaligned_le32(x0, &out[4 * 0]); + put_unaligned_le32(x1, &out[4 * 1]); + put_unaligned_le32(x2, &out[4 * 2]); + put_unaligned_le32(x3, &out[4 * 3]); +} +EXPORT_SYMBOL_GPL(lea_encrypt); + +/** + * The decryption round function for LEA is the inverse of encryption, + * so it can be represented as follows + * + * next_v0 = v3 + * next_v1 = (rotr32(v0, 9) - (next_v0 ^ RK[0])) ^ RK[1]; + * next_v2 = (rotl32(v1, 5) - (next_v1 ^ RK[2])) ^ RK[3]; + * next_v3 = (rotl32(v2, 3) - (next_v2 ^ RK[4])) ^ RK[5]; + * + * However, in the above expression, all previous steps must be computed to + * calculate next_v3. + * If the process is unpacked, the computation would look like this + * + * next_v0 = v3 + * next_v1 = (rotr32(v0, 9) - (v3 ^ RK[0])) ^ RK[1]; + * next_v2 = (rotl32(v1, 5) - ((rotr32(v0, 9) - (v3 ^ RK[0])) ^ RK[1] ^ RK[2])) + * ^ RK[3]; + * next_v3 = (rotl32(v2, 3) - ((rotl32(v1, 5) + * - ((rotr32(v0, 9) - (v3 ^ RK[0])) ^ RK[1] ^ RK[2])) + * ^ RK[3] ^ RK[4])) ^ RK[5]; + * + * Letting (rotr32(v0, 9) - (v3 ^ RK[0])) be the intermediate value, + * it would look like + * + * next_v0 = v3 + * tmp_v1 = (rotr32(v0, 9) - (v3 ^ RK[0])) + * next_v1 = tmp_v1 ^ RK[1]; + * next_v2 = (rotl32(v1, 5) - (tmp_v1 ^ RK[1] ^ RK[2])) ^ RK[3]; + * next_v3 = (rotl32(v2, 3) - ((rotl32(V1, 5) - (tmp_v1 ^ RK[1] ^ RK[2])) + * ^ RK[3] ^ RK[4])) ^ RK[5]; + * + * Similarly, letting (rotl32(v1, 5) - (tmp_v1 ^ RK[1] ^ RK[2])) be the + * intermediate value, it would look like this + * + * next_v0 = v3 + * tmp_v1 = (rotr32(v0, 9) - (v3 ^ RK[0])) + * next_v1 = tmp_v1 ^ RK[1]; + * tmp_v2 = (rotl32(v1, 5) - (tmp_v1 ^ RK[1] ^ RK[2])) + * next_v2 = tmp_v2 ^ RK[3]; + * next_v3 = (rotl32(v2, 3) - (tmp_v2 ^ RK[3] ^ RK[4])) ^ RK[5]; + * + * To reduce the operation of XORing RK twice to once, try using + * RKdec[0] = RK[0], RKdec[1] = RK[1], RKdec[2] = RK[1] ^ RK[2] + * RKdec[3] = RK[3], RKdec[4] = RK[3] ^ RK[4], RKdec[5] = RK[5] + * + * then the code can be rewritten as follows + * + * next_v0 = v3 + * tmp_v1 = (rotr32(v0, 9) - (v3 ^ RKdec[0])); + * next_v1 = tmp_v1 ^ RKdec[1]; + * tmp_v2 = (rotl32(v1, 5) - (tmp_v1 ^ RKdec[2]); + * next_v2 = tmp_v2 ^ RKdec[3]; + * next_v3 = (rotl32(v2, 3) - (tmp_v2 ^ RKdec[4]) ^ RKdec[5]; + * + * There is no difference in the number of operations, but there is two less + * data-dependent step, some operations can be performed simultaneously in the + * out-of-order processor. + */ +#define LEA_DEC_RND(V0, V1, V2, V3, TMP, RK) \ + do { \ + TMP = (ror32(V0, 9) - (V3 ^ RK[0])); \ + V0 = TMP ^ RK[1]; \ + TMP = (rol32(V1, 5) - (TMP ^ RK[2])); \ + V1 = TMP ^ RK[3]; \ + V2 = (rol32(V2, 3) - (TMP ^ RK[4])) ^ RK[5]; \ + RK += LEA_ROUND_KEY_WIDTH; \ + } while (0) + +void lea_decrypt(const struct crypto_lea_ctx *key, u8 *out, const u8 *in) +{ + const u32 *rk = key->rk_dec; + const u32 *rk_tail = rk + LEA_ROUND_KEY_WIDTH * key->round; + + u32 x0 = get_unaligned_le32(&in[4 * 0]); + u32 x1 = get_unaligned_le32(&in[4 * 1]); + u32 x2 = get_unaligned_le32(&in[4 * 2]); + u32 x3 = get_unaligned_le32(&in[4 * 3]); + u32 tmp; + + while (rk < rk_tail) { + LEA_DEC_RND(x0, x1, x2, x3, tmp, rk); + LEA_DEC_RND(x3, x0, x1, x2, tmp, rk); + LEA_DEC_RND(x2, x3, x0, x1, tmp, rk); + LEA_DEC_RND(x1, x2, x3, x0, tmp, rk); + }; + + put_unaligned_le32(x0, &out[4 * 0]); + put_unaligned_le32(x1, &out[4 * 1]); + put_unaligned_le32(x2, &out[4 * 2]); + put_unaligned_le32(x3, &out[4 * 3]); +} +EXPORT_SYMBOL_GPL(lea_decrypt); + +static int crypto_lea_set_key(struct crypto_tfm *tfm, const u8 *in_key, + u32 key_len) +{ + return lea_set_key(crypto_tfm_ctx(tfm), in_key, key_len); +} + +static void crypto_lea_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) +{ + const struct crypto_lea_ctx *key = crypto_tfm_ctx(tfm); + + lea_encrypt(key, out, in); +} + +static void crypto_lea_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) +{ + const struct crypto_lea_ctx *key = crypto_tfm_ctx(tfm); + + lea_decrypt(key, out, in); +} + +static struct crypto_alg lea_alg = { + .cra_name = "lea", + .cra_driver_name = "lea-generic", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_blocksize = LEA_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct crypto_lea_ctx), + .cra_module = THIS_MODULE, + .cra_u = { .cipher = { .cia_min_keysize = LEA_MIN_KEY_SIZE, + .cia_max_keysize = LEA_MAX_KEY_SIZE, + .cia_setkey = crypto_lea_set_key, + .cia_encrypt = crypto_lea_encrypt, + .cia_decrypt = crypto_lea_decrypt } } +}; + +static int crypto_lea_init(void) +{ + return crypto_register_alg(&lea_alg); +} + +static void crypto_lea_exit(void) +{ + crypto_unregister_alg(&lea_alg); +} + +module_init(crypto_lea_init); +module_exit(crypto_lea_exit); + +MODULE_DESCRIPTION("LEA Cipher Algorithm"); +MODULE_AUTHOR("Dongsoo Lee "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS_CRYPTO("lea"); +MODULE_ALIAS_CRYPTO("lea-generic"); diff --git a/include/crypto/lea.h b/include/crypto/lea.h new file mode 100644 index 000000000000..ce134fa98908 --- /dev/null +++ b/include/crypto/lea.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Cryptographic API. + * + * The LEA Cipher Algorithm + * + * LEA is a 128-bit block cipher developed by South Korea. + * + * LEA is a Korean national standard (KS X 3246) and included in the ISO/IEC + * 29192-2:2019 standard (Information security - Lightweight cryptography - + * Part 2: Block ciphers). + * + * Copyright (c) 2023 National Security Research. + * Author: Dongsoo Lee + */ + +#ifndef _CRYPTO_LEA_H +#define _CRYPTO_LEA_H + +#include + +#define LEA_MIN_KEY_SIZE 16 +#define LEA_MAX_KEY_SIZE 32 +#define LEA_BLOCK_SIZE 16 +#define LEA_ROUND_KEY_WIDTH 6 + +#define LEA128_ROUND_CNT 24 +#define LEA192_ROUND_CNT 28 +#define LEA256_ROUND_CNT 32 + +#define LEA_MAX_KEYLENGTH_U32 (LEA256_ROUND_CNT * LEA_ROUND_KEY_WIDTH) +#define LEA_MAX_KEYLENGTH (LEA_MAX_KEYLENGTH_U32 * sizeof(u32)) + +struct crypto_lea_ctx { + u32 rk_enc[LEA_MAX_KEYLENGTH_U32]; + u32 rk_dec[LEA_MAX_KEYLENGTH_U32]; + u32 round; +}; + +int lea_set_key(struct crypto_lea_ctx *key, const u8 *in_key, u32 key_len); +void lea_encrypt(const struct crypto_lea_ctx *key, u8 *out, const u8 *in); +void lea_decrypt(const struct crypto_lea_ctx *key, u8 *out, const u8 *in); + +#endif From patchwork Fri Jan 12 02:28:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dongsoo Lee X-Patchwork-Id: 13517907 Received: from mail.nsr.re.kr (unknown [210.104.33.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 715A95C82; Fri, 12 Jan 2024 02:30:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nsr.re.kr Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nsr.re.kr Received: from 210.104.33.70 (nsr.re.kr) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128 bits)) by mail.nsr.re.kr with SMTP; Fri, 12 Jan 2024 11:29:54 +0900 X-Sender: letrhee@nsr.re.kr Received: from 192.168.155.188 ([192.168.155.188]) by mail.nsr.re.kr (Crinity Message Backbone-7.0.1) with SMTP ID 155; Fri, 12 Jan 2024 11:29:50 +0900 (KST) From: Dongsoo Lee To: Herbert Xu , "David S. Miller" , Jens Axboe , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" Cc: linux-crypto@vger.kernel.org, linux-block@vger.kernel.org, linux-fscrypt@vger.kernel.org, linux-kernel@vger.kernel.org, Dongsoo Lee Subject: [PATCH v6 RESEND 2/5] crypto: add LEA testmgr tests Date: Fri, 12 Jan 2024 02:28:56 +0000 Message-Id: <20240112022859.2384-3-letrhee@nsr.re.kr> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240112022859.2384-1-letrhee@nsr.re.kr> References: <20240112022859.2384-1-letrhee@nsr.re.kr> Precedence: bulk X-Mailing-List: linux-block@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The single block test vectors are taken from the standard documentation. The test vectors for ECB, CBC, CTR, and GCM are taken from the KCMVP Cryptographic Algorithm Verification Criteria V3.0. Test vectors for the XTS mode were generated by ourselves, and we crosschecked them using Crypto++ and testmgr on Linux. - https://seed.kisa.or.kr/kisa/kcmvp/EgovVerification.do Signed-off-by: Dongsoo Lee --- crypto/tcrypt.c | 97 ++ crypto/testmgr.c | 38 + crypto/testmgr.h | 3022 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 3157 insertions(+) diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 202ca1a3105d..fa3594ed3731 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -1708,6 +1708,14 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb) ret = min(ret, tcrypt_test("cts(cbc(sm4))")); break; + case 60: + ret = min(ret, tcrypt_test("gcm(lea)")); + break; + + case 61: + ret = min(ret, tcrypt_test("cts(cbc(lea))")); + break; + case 100: ret = min(ret, tcrypt_test("hmac(md5)")); break; @@ -1855,6 +1863,12 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb) ret = min(ret, tcrypt_test("cfb(aria)")); ret = min(ret, tcrypt_test("ctr(aria)")); break; + case 193: + ret = min(ret, tcrypt_test("ecb(lea)")); + ret = min(ret, tcrypt_test("cbc(lea)")); + ret = min(ret, tcrypt_test("ctr(lea)")); + ret = min(ret, tcrypt_test("xts(lea)")); + break; case 200: test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0, speed_template_16_24_32); @@ -2222,6 +2236,43 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb) speed_template_16, num_mb); break; + case 230: + test_cipher_speed("ecb(lea)", ENCRYPT, sec, NULL, 0, + speed_template_16_24_32); + test_cipher_speed("ecb(lea)", DECRYPT, sec, NULL, 0, + speed_template_16_24_32); + test_cipher_speed("cbc(lea)", ENCRYPT, sec, NULL, 0, + speed_template_16_24_32); + test_cipher_speed("cbc(lea)", DECRYPT, sec, NULL, 0, + speed_template_16_24_32); + test_cipher_speed("cts(cbc(lea))", ENCRYPT, sec, NULL, 0, + speed_template_16_24_32); + test_cipher_speed("cts(cbc(lea))", DECRYPT, sec, NULL, 0, + speed_template_16_24_32); + test_cipher_speed("ctr(lea)", ENCRYPT, sec, NULL, 0, + speed_template_16_24_32); + test_cipher_speed("ctr(lea)", DECRYPT, sec, NULL, 0, + speed_template_16_24_32); + test_cipher_speed("xts(lea)", ENCRYPT, sec, NULL, 0, + speed_template_32_48_64); + test_cipher_speed("xts(lea)", DECRYPT, sec, NULL, 0, + speed_template_32_48_64); + break; + + case 231: + test_aead_speed("gcm(lea)", ENCRYPT, sec, + NULL, 0, 16, 8, speed_template_16_24_32); + test_aead_speed("gcm(lea)", DECRYPT, sec, + NULL, 0, 16, 8, speed_template_16_24_32); + break; + + case 232: + test_mb_aead_speed("gcm(lea)", ENCRYPT, sec, NULL, 0, 16, 8, + speed_template_16_24_32, num_mb); + test_mb_aead_speed("gcm(lea)", DECRYPT, sec, NULL, 0, 16, 8, + speed_template_16_24_32, num_mb); + break; + case 300: if (alg) { test_hash_speed(alg, sec, generic_hash_speed_template); @@ -2657,6 +2708,29 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb) speed_template_16_24_32); break; + case 520: + test_acipher_speed("ecb(lea)", ENCRYPT, sec, NULL, 0, + speed_template_16_24_32); + test_acipher_speed("ecb(lea)", DECRYPT, sec, NULL, 0, + speed_template_16_24_32); + test_acipher_speed("cbc(lea)", ENCRYPT, sec, NULL, 0, + speed_template_16_24_32); + test_acipher_speed("cbc(lea)", DECRYPT, sec, NULL, 0, + speed_template_16_24_32); + test_acipher_speed("ctr(lea)", ENCRYPT, sec, NULL, 0, + speed_template_16_24_32); + test_acipher_speed("ctr(lea)", DECRYPT, sec, NULL, 0, + speed_template_16_24_32); + test_acipher_speed("xts(lea)", ENCRYPT, sec, NULL, 0, + speed_template_32_48_64); + test_acipher_speed("xts(lea)", DECRYPT, sec, NULL, 0, + speed_template_32_48_64); + test_acipher_speed("cts(cbc(lea))", ENCRYPT, sec, NULL, 0, + speed_template_16_24_32); + test_acipher_speed("cts(cbc(lea))", DECRYPT, sec, NULL, 0, + speed_template_16_24_32); + break; + case 600: test_mb_skcipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0, speed_template_16_24_32, num_mb); @@ -2880,6 +2954,29 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb) speed_template_16_32, num_mb); break; + case 611: + test_mb_skcipher_speed("ecb(lea)", ENCRYPT, sec, NULL, 0, + speed_template_16_24_32, num_mb); + test_mb_skcipher_speed("ecb(lea)", DECRYPT, sec, NULL, 0, + speed_template_16_24_32, num_mb); + test_mb_skcipher_speed("cbc(lea)", ENCRYPT, sec, NULL, 0, + speed_template_16_24_32, num_mb); + test_mb_skcipher_speed("cbc(lea)", DECRYPT, sec, NULL, 0, + speed_template_16_24_32, num_mb); + test_mb_skcipher_speed("ctr(lea)", ENCRYPT, sec, NULL, 0, + speed_template_16_24_32, num_mb); + test_mb_skcipher_speed("ctr(lea)", DECRYPT, sec, NULL, 0, + speed_template_16_24_32, num_mb); + test_mb_skcipher_speed("xts(lea)", ENCRYPT, sec, NULL, 0, + speed_template_32_48_64, num_mb); + test_mb_skcipher_speed("xts(lea)", DECRYPT, sec, NULL, 0, + speed_template_32_48_64, num_mb); + test_mb_skcipher_speed("cts(cbc(lea))", ENCRYPT, sec, NULL, 0, + speed_template_16_24_32, num_mb); + test_mb_skcipher_speed("cts(cbc(lea))", DECRYPT, sec, NULL, 0, + speed_template_16_24_32, num_mb); + break; + } return ret; diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 15c7a3011269..5479dae10fa0 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -4535,6 +4535,12 @@ static const struct alg_test_desc alg_test_descs[] = { .suite = { .cipher = __VECS(des3_ede_cbc_tv_template) }, + }, { + .alg = "cbc(lea)", + .test = alg_test_skcipher, + .suite = { + .cipher = __VECS(lea_cbc_tv_template) + }, }, { /* Same as cbc(aes) except the key is stored in * hardware secure memory which we reference by index @@ -4738,6 +4744,12 @@ static const struct alg_test_desc alg_test_descs[] = { .suite = { .cipher = __VECS(des3_ede_ctr_tv_template) } + }, { + .alg = "ctr(lea)", + .test = alg_test_skcipher, + .suite = { + .cipher = __VECS(lea_ctr_tv_template) + } }, { /* Same as ctr(aes) except the key is stored in * hardware secure memory which we reference by index @@ -4786,6 +4798,12 @@ static const struct alg_test_desc alg_test_descs[] = { .suite = { .cipher = __VECS(cts_mode_tv_template) } + }, { + .alg = "cts(cbc(lea))", + .test = alg_test_skcipher, + .suite = { + .cipher = __VECS(lea_cbc_cts_tv_template) + } }, { /* Same as cts(cbc((aes)) except the key is stored in * hardware secure memory which we reference by index @@ -5025,6 +5043,12 @@ static const struct alg_test_desc alg_test_descs[] = { .suite = { .cipher = __VECS(khazad_tv_template) } + }, { + .alg = "ecb(lea)", + .test = alg_test_skcipher, + .suite = { + .cipher = __VECS(lea_tv_template) + } }, { /* Same as ecb(aes) except the key is stored in * hardware secure memory which we reference by index @@ -5195,6 +5219,13 @@ static const struct alg_test_desc alg_test_descs[] = { .suite = { .aead = __VECS(aria_gcm_tv_template) } + }, { + .alg = "gcm(lea)", + .generic_driver = "gcm_base(ctr(lea-generic),ghash-generic)", + .test = alg_test_aead, + .suite = { + .aead = __VECS(lea_gcm_tv_template) + } }, { .alg = "gcm(sm4)", .generic_driver = "gcm_base(ctr(sm4-generic),ghash-generic)", @@ -5728,6 +5759,13 @@ static const struct alg_test_desc alg_test_descs[] = { .suite = { .cipher = __VECS(cast6_xts_tv_template) } + }, { + .alg = "xts(lea)", + .generic_driver = "xts(ecb(lea-generic))", + .test = alg_test_skcipher, + .suite = { + .cipher = __VECS(lea_xts_tv_template) + } }, { /* Same as xts(aes) except the key is stored in * hardware secure memory which we reference by index diff --git a/crypto/testmgr.h b/crypto/testmgr.h index d7e98397549b..a92ee48a99ce 100644 --- a/crypto/testmgr.h +++ b/crypto/testmgr.h @@ -30364,6 +30364,3028 @@ static const struct aead_testvec aria_gcm_tv_template[] = { } }; +static const struct cipher_testvec lea_tv_template[] = { + { + .key = "\x0f\x1e\x2d\x3c\x4b\x5a\x69\x78" + "\x87\x96\xa5\xb4\xc3\xd2\xe1\xf0", + .klen = 16, + .ptext = "\x10\x11\x12\x13\x14\x15\x16\x17" + "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + .ctext = "\x9f\xc8\x4e\x35\x28\xc6\xc6\x18" + "\x55\x32\xc7\xa7\x04\x64\x8b\xfd", + .len = 16, + }, { + .key = "\x0f\x1e\x2d\x3c\x4b\x5a\x69\x78" + "\x87\x96\xa5\xb4\xc3\xd2\xe1\xf0" + "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87", + .klen = 24, + .ptext = "\x20\x21\x22\x23\x24\x25\x26\x27" + "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f", + .ctext = "\x6f\xb9\x5e\x32\x5a\xad\x1b\x87" + "\x8c\xdc\xf5\x35\x76\x74\xc6\xf2", + .len = 16, + }, { + .key = "\x0f\x1e\x2d\x3c\x4b\x5a\x69\x78" + "\x87\x96\xa5\xb4\xc3\xd2\xe1\xf0" + "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87" + "\x78\x69\x5a\x4b\x3c\x2d\x1e\x0f", + .klen = 32, + .ptext = "\x30\x31\x32\x33\x34\x35\x36\x37" + "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f", + .ctext = "\xd6\x51\xaf\xf6\x47\xb1\x89\xc1" + "\x3a\x89\x00\xca\x27\xf9\xe1\x97", + .len = 16, + }, { + .key = "\x07\xab\x63\x05\xb0\x25\xd8\x3f" + "\x79\xad\xda\xa6\x3a\xc8\xad\x00", + .klen = 16, + .ptext = "\xf2\x8a\xe3\x25\x6a\xad\x23\xb4" + "\x15\xe0\x28\x06\x3b\x61\x0c\x60", + .ctext = "\x64\xd9\x08\xfc\xb7\xeb\xfe\xf9" + "\x0f\xd6\x70\x10\x6d\xe7\xc7\xc5", + .len = 16, + }, { + .key = "\x42\xaf\x3b\xcd\x6c\xbe\xaa\xef" + "\xf1\xa7\xc2\x6e\x61\xcd\x2b\xde", + .klen = 16, + .ptext = "\x51\x83\xbe\x45\xfd\x20\x47\xce" + "\x31\x51\x89\xc2\x69\xb4\x83\xb3" + "\x37\xa2\xf2\xfb\xe5\x4c\x17\x65" + "\x5b\x09\xba\x29\x44\xee\x6f\x1e" + "\x6d\xa0\x18\x2b\x6d\x66\xab\xfe" + "\x8b\x82\x36\x01\xdc\xc2\x20\x8a" + "\xac\x52\xb1\x53\x1f\xd4\xd4\x29" + "\x18\xb2\x1c\xe8\x5a\xb3\x06\xa6" + "\xee\xcd\x7e\x2f\xc4\x3b\xa4\xb2" + "\x9d\xcf\xcf\xb9\x27\x88\xd2\x5e", + .ctext = "\xf3\xb6\xbf\x4a\xfb\xa7\x10\x3e" + "\x32\xb2\xac\x2e\x7b\x46\xff\x91" + "\xe8\x72\xbc\xbb\x93\xcf\x52\xe2" + "\x94\xed\x55\x39\x87\x1c\x48\x93" + "\xd1\x4c\x54\x08\x86\x46\xe2\xfd" + "\x0b\x7c\x62\xd5\x83\xf3\xaf\x67" + "\x18\xb0\xba\x83\xc7\xa2\x9e\x2f" + "\x96\x2d\xf0\x60\x62\x12\x1c\x52" + "\x1b\xb9\xe7\x6d\x70\x35\x07\x07" + "\x19\xed\xfb\x40\x9c\x5b\x83\xc2", + .len = 80, + }, { + .key = "\x9b\x6f\x9f\xba\x56\xe9\x6a\xea" + "\x53\x8b\xf8\x27\x2a\x9f\x39\x2d", + .klen = 16, + .ptext = "\xf6\xde\xcf\xab\xfd\x89\xce\xf4" + "\x93\xb5\xc0\xf7\x3b\xe7\xed\x71" + "\x10\xe0\xd9\x61\x63\xba\x0d\xbd" + "\xa6\x34\x1a\x63\x88\x4b\xdc\x52" + "\x62\x0a\xfc\x1a\xd2\xa2\xb8\x91" + "\xa5\xbd\xe7\xc8\xfb\x10\x37\x3d" + "\xa5\x2f\xba\x52\xd2\xa6\xa1\xfe" + "\xeb\x45\x47\xc3\xbb\xbb\x71\xe0" + "\xd3\x67\xd4\xc7\x2d\x6a\xd7\xd1" + "\x0f\x01\x9b\x31\x32\x12\x38\x27" + "\x24\x04\x4a\x76\xeb\xd4\xad\x17" + "\xeb\x65\x84\x2f\x0a\x18\x80\x3f" + "\x11\x9d\x5f\x9a\x55\x09\xb2\x1d" + "\x98\x28\xe4\x1a\x2a\x14\x78\x95" + "\x53\x06\x92\xb3\xf6\x6d\xb9\x6f" + "\x6e\x3d\xdb\x8f\xbc\x8a\x91\xd6" + "\xe4\x55\xa5\x7c\x94\xa6\xd2\xdb" + "\x07\xdb\xca\x6b\x29\x3f\x7e\xf0" + "\xfc\xde\x99\xf2\x3a\x98\x4d\x6e" + "\x3c\x75\x53\xcb\x1a\x38\x2d\x0f", + .ctext = "\x98\xd8\x5d\x7d\x0d\x13\x6a\x80" + "\xce\x74\x86\x44\x69\xd7\x7a\x03" + "\xef\x56\xec\x9b\x24\xa7\x11\x9d" + "\xe0\x95\x08\xa0\x4d\x6f\x43\x7e" + "\x67\x0b\x54\xb3\x6e\x2c\xbd\xe5" + "\x1c\xdb\xd0\x1e\x2c\xea\x53\x33" + "\x2c\x2a\x14\x87\x9f\xf7\x7e\x02" + "\x00\x0a\x00\xf1\x59\xfb\x18\x65" + "\xe7\xdb\xed\x54\x33\x57\x91\x7d" + "\x78\x3f\x18\xb0\x6f\xd8\xef\xa6" + "\x68\x6d\x2e\x36\x2b\xce\xde\x94" + "\xbb\x76\x87\xec\xfd\x75\x01\xb7" + "\x9f\x91\x27\x40\x84\x06\x83\x72" + "\x24\x66\x44\x0d\x24\x0e\xf0\x35" + "\x56\x04\xbf\xcf\xbc\x30\xf1\x6f" + "\x03\xd0\x05\x43\x58\x2a\x52\x71" + "\x85\x26\x07\x93\x55\x16\x4e\x6b" + "\x8c\xec\x36\xe3\x46\xb9\x09\x2d" + "\x97\x06\xc4\x89\x46\xc4\x97\x62" + "\x9c\x9c\x90\x55\xd9\xd8\x97\x77", + .len = 160, + }, { + .key = "\xec\x19\xa6\xc1\xa3\x1b\x4c\xc0" + "\x97\x6f\x22\x57\x06\x0e\x10\x51", + .klen = 16, + .ptext = "\xb3\x85\xc9\xea\x05\x14\x4c\xa2" + "\x2a\x9b\xb2\x42\x50\x71\xa4\x36" + "\xc8\x08\x57\x02\xd1\x5f\xd6\xae" + "\x26\xc3\x04\x2d\x0d\xcc\x57\x6a" + "\x45\xdc\x50\xce\xe6\xca\x34\xa1" + "\xb8\x70\x31\xda\x2d\xfd\x1d\x29" + "\x03\xb0\x0d\xae\xbe\x68\x9e\x14" + "\x44\x11\xcc\xe9\x45\x5f\xc3\xa6" + "\x4d\xe9\xc9\xde\x95\x01\xcb\x2f" + "\xc7\xe5\x8a\x2c\xe7\xe2\x77\x4a" + "\x2b\xf1\x89\xb3\xfe\x5b\xf4\x6e" + "\x90\x49\xb4\x25\xb7\x94\xdc\x0f" + "\x66\x41\x49\x85\xbb\xf2\x1a\x1a" + "\xec\x1a\x0d\xa4\xf9\xe5\x5e\xd8" + "\x2f\x8d\x66\x90\x51\x60\x8c\x18" + "\xfd\x56\x8b\x16\x66\x05\xbc\xbd" + "\xd0\x6a\x3c\x1c\xc7\x88\x77\x6e" + "\xa6\x35\x6e\xcc\xb5\xa5\xfc\xb7" + "\xf3\x7a\x3e\xd5\x9d\xac\xaf\x73" + "\x0b\x86\x7b\x14\x31\xac\xaa\x98" + "\x1c\x9c\x3a\xe6\x73\x01\x96\xb2" + "\xa5\x03\x95\x5a\xde\x04\x75\x05" + "\x12\xe6\x25\x72\x55\x09\xd2\x22" + "\xd7\xd3\x83\x5a\xa1\xce\xb2\x0e" + "\xbe\x56\x70\x7b\x6e\x97\x99\x43" + "\x4c\x0b\xd6\x07\xb1\x9c\xf8\xf9" + "\x2e\xec\xcc\xe3\xba\x64\x22\x27" + "\x1b\x8e\x83\xaa\xbe\x8f\xe3\x4b" + "\xe5\x07\x64\xed\xb2\xb4\x4c\x9c" + "\x39\x1d\xb2\x88\x7b\x2f\xd2\x3b" + "\x6a\x88\x35\x67\x0e\xb0\x1a\x60" + "\xa7\x48\xbc\xd4\x24\xb7\x78\x01" + "\x1f\x0f\xf2\x68\xa8\x46\xd4\x71" + "\xf2\x41\xb8\x3c\x19\x3a\xa7\x1a" + "\xfc\xd6\xfc\x91\x8c\x35\xcd\xa2" + "\x42\x95\x61\x50\x2e\xa5\x8d\xad" + "\x93\xf0\x4a\x52\x2c\x77\x24\x64" + "\x1c\x3c\xa9\xed\x4d\x99\x77\x35" + "\xff\xdf\x4b\x96\xcf\x06\x68\xfb" + "\xca\xc6\xd5\x0e\x34\x22\xe3\xaa" + "\xbd\x38\xf0\xc0\x0c\x73\x31\xd8" + "\x40\x27\x03\x8c\x3d\x27\x00\x50" + "\xd8\xd2\x51\x85\x85\xf6\x47\x9f" + "\x00\xdb\x0e\x9c\x3e\xdd\xe8\xee" + "\x24\x6f\x87\x13\xcb\x06\x29\xf9" + "\xe2\xa0\x2b\x17\xc0\xdf\x48\x19" + "\xcd\xba\xf1\xce\xde\xc7\xcc\x3b" + "\x96\xa9\x7d\x7a\x84\x46\x25\xbc" + "\xa1\xb4\xb6\x8b\xbf\x84\x9c\xfd" + "\x0f\x0a\x2e\x00\x7c\x3d\xaf\xb2" + "\x32\x6c\xa1\xb9\x72\xf3\x48\x3b" + "\xb7\xcb\x98\x58\x53\x55\x43\x40" + "\x6a\x24\x7c\xbe\xce\x3c\x6a\x5a" + "\xaf\x08\xb6\xd4\x61\x06\x46\xcd" + "\x0a\x3d\x97\x24\xd3\x86\x4d\xcb" + "\xf6\x7e\x23\x04\x8c\xfb\x7f\x89", + .ctext = "\x7f\x2f\x9b\xff\x57\x61\xfb\x43" + "\x32\x68\x27\x54\xc5\x5d\x53\x8e" + "\xc8\x8f\x8b\xc7\xa9\xba\xb8\x67" + "\x81\x1e\xee\xad\x3f\xa5\xbb\xbe" + "\x40\xad\x23\x8a\xdc\xf8\x00\x2a" + "\x0f\x79\xe7\x4d\xd8\x4c\xc7\xec" + "\x83\xb5\x55\xdb\x27\xaa\x72\xc1" + "\xfe\xb5\x6c\xd4\xac\x10\xdd\x7b" + "\xe2\x09\x33\x6f\xa6\x2b\xb4\x26" + "\x58\x28\x56\xa7\xf4\x3c\xaf\x28" + "\x36\xb1\xbb\xfc\x65\xea\xe9\x5f" + "\x67\x03\x33\xa5\x7a\x30\xcd\xeb" + "\x74\xb5\x24\x24\x8a\x02\xf1\xbb" + "\x22\xd7\xcc\xd7\xb8\x04\xb3\xba" + "\x4b\x10\x81\xbb\xd1\xf8\x49\xe5" + "\x50\x21\x4d\x17\x32\x45\xb5\x9a" + "\xa8\xa1\x14\xe0\x99\x35\x8c\xc3" + "\xf2\xf1\x80\xad\xb1\xf8\xc0\x11" + "\x94\xf9\x83\x1b\x41\xb9\x2b\xb0" + "\x08\xd1\x78\x17\x32\xee\xbb\xf4" + "\x23\x54\x12\x70\x02\x15\x8f\xba" + "\xcc\xfc\x11\x8b\xc6\xc0\x18\xa8" + "\x65\x3a\x04\xb4\x0d\x96\x55\x90" + "\xfe\x80\x83\xe5\x46\xff\x0d\x84" + "\x66\x19\x8d\xab\x99\x73\x60\xd9" + "\x71\xbd\x3a\x70\xe3\xa8\x98\xec" + "\x75\x14\xa2\x9a\x99\xd0\x31\x53" + "\x76\x75\x2e\xcd\x83\x38\xe8\x70" + "\x97\xb6\xf6\x7f\x22\xde\x40\x5a" + "\xb9\x23\x97\xbd\x49\xef\x11\x3e" + "\xdf\x15\x00\x31\x9b\xa2\x82\xb0" + "\x58\xa6\x32\xf2\xdf\xf9\xd8\x77" + "\x44\x80\xaf\x77\xc8\x1d\xd9\xf8" + "\xc0\x3f\x48\x1c\xfb\xe5\x0a\x6e" + "\x55\x9f\xc8\xee\x24\x67\xce\xd5" + "\xbb\xa8\xca\x11\x95\xf9\x7f\x56" + "\xf0\x1f\x7c\xb0\x27\x07\x57\x07" + "\x39\x52\xf1\x62\x83\xf2\x8d\x11" + "\x9f\x5c\x69\xf1\x2d\xd2\xb2\x2a" + "\x6c\x81\xd1\xc9\x4d\xab\x3d\x02" + "\xa4\x23\x8d\x69\xef\x46\xfc\x2a" + "\x2d\x99\x1f\x6a\xe2\x5f\xb8\xc5" + "\xb0\x96\xaf\x32\x89\xda\xbd\x6c" + "\x67\xfe\x8b\x8d\x90\xc3\xb7\xd6" + "\xae\x81\xac\x96\xb1\x87\xcf\x9c" + "\x60\xb1\x80\x02\x36\xf9\xe8\x28" + "\x7c\x78\x62\xe4\x6e\xa3\x18\x01" + "\xfa\x4f\x2a\xc9\x1a\x7d\xea\xca" + "\xf7\x62\x66\x59\xab\x97\x09\x4d" + "\x09\x5d\x7d\x84\xcb\xf9\x9b\xd3" + "\x0a\x2c\xd0\x91\xca\xd4\xc6\xa7" + "\xee\x48\x4c\x9b\x57\x52\x4d\x3c" + "\xce\xa6\x1f\x12\x32\xf8\x7a\x03" + "\xf0\xc8\xdd\x62\xab\x10\x39\x12" + "\x32\x20\x21\x67\x6f\x15\x78\x99" + "\x3d\xb7\x01\x9f\x42\x70\x98\xc2", + .len = 448, + }, { + .key = "\x14\x37\xaf\x53\x30\x69\xbd\x75" + "\x25\xc1\x56\x0c\x78\xba\xd2\xa1" + "\xe5\x34\x67\x1c\x00\x7e\xf2\x7c", + .klen = 24, + .ptext = "\x1c\xb4\xf4\xcb\x6c\x4b\xdb\x51" + "\x68\xea\x84\x09\x72\x7b\xfd\x51", + .ctext = "\x69\x72\x5c\x6d\xf9\x12\xf8\xb7" + "\x0e\xb5\x11\xe6\x66\x3c\x58\x70", + .len = 16, + }, { + .key = "\x5e\xdc\x34\x69\x04\xb2\x96\xcf" + "\x6b\xf3\xb4\x18\xe9\xab\x35\xdb" + "\x0a\x47\xa1\x11\x33\xa9\x24\xca", + .klen = 24, + .ptext = "\x85\x7c\x8f\x1f\x04\xc5\xa0\x68" + "\xf9\xbb\x83\xaf\x95\xd9\x98\x64" + "\xd6\x31\x77\x51\xaf\x03\x32\xd1" + "\x63\x8e\xda\x3d\x32\x26\x44\xa8" + "\x37\x87\x0c\xcc\x91\x69\xdb\x43" + "\xc1\x55\xe6\xfb\x53\xb6\xb7\xe4" + "\xc1\x33\x30\xeb\x94\x3c\xcd\x2c" + "\xcc\xe3\x29\x63\x82\xee\xc4\xa4" + "\xcc\x2a\x03\x4d\xe1\x02\x78\x38" + "\x7d\x4f\x64\x35\x87\x72\x7a\xb7", + .ctext = "\x72\x22\x3a\x93\x94\x2f\x73\x59" + "\xfe\x5e\x51\x6a\x05\xc8\xe8\x41" + "\xc5\x9b\xb7\x47\x14\x80\x9b\x13" + "\xa9\x75\x7b\x82\x93\xf9\xb0\xb4" + "\x20\xd1\xc5\xa4\xf4\x40\xf3\x65" + "\xd0\x8f\x94\x25\xe3\x47\xb5\xdd" + "\x23\xa9\xed\x05\xf2\xce\x16\x18" + "\xcc\xb0\x9e\x71\x2c\x59\xb9\x7b" + "\x76\x74\x51\x7f\xc8\x75\xae\x9f" + "\x6f\x18\x8b\xfa\x5a\x42\xba\xc9", + .len = 80, + }, { + .key = "\x51\x4b\x8b\xf1\x41\xf5\x60\x41" + "\x24\x13\xed\x1e\x40\xe3\x4e\xc2" + "\x3a\x89\xe9\x90\x36\xa4\xac\x4a", + .klen = 24, + .ptext = "\x3e\x25\x96\x84\xe8\x61\x79\x59" + "\x33\x65\xfe\x5c\xb3\x89\xe9\xd1" + "\xee\x48\x9e\x1e\x05\x4e\xe4\x7c" + "\x97\xd3\xea\xf2\xe2\x28\x88\x84" + "\x2b\x8f\xc6\xa8\x60\x50\xa2\xf9" + "\xfd\x09\x0e\x2f\x2c\x46\x39\x4f" + "\x30\x51\x0f\x1f\x03\x4c\x03\xdd" + "\x3e\x7c\x0c\x30\x3a\xe8\xed\x5f" + "\x75\x23\xba\xc1\x37\x66\x98\x75" + "\x75\xe1\xc4\x52\xf5\x53\xd7\x21" + "\xb3\xd9\x48\x0a\x84\x03\x32\x4d" + "\xf9\x2d\x57\x33\x86\x0d\x66\x43" + "\xe3\x88\x79\xb8\xb3\xca\xe2\x33" + "\x64\x95\x27\xae\x56\xd9\x4b\xb1" + "\x3f\x86\x4f\xc8\xce\x9e\xf9\x34" + "\x8e\x8e\xd4\xe1\x0e\xbe\x78\x98" + "\x3f\x67\x0b\x76\x1d\xa5\x08\x9d" + "\x91\xcd\x3f\x29\x96\x00\x1e\x66" + "\x9c\x00\x2e\x40\x29\x43\xe0\xfa" + "\xc6\x46\x8a\x23\x19\x24\xad\xc6", + .ctext = "\x62\x39\x86\x7f\x34\xd5\x7b\x91" + "\x72\x94\x10\xf9\x37\x97\xc6\x9e" + "\x45\x52\x6f\x13\x40\x5e\xc2\x22" + "\xed\xfa\xe6\x82\xb6\xc2\xd7\x5b" + "\x33\x24\x30\xd3\x0b\xc2\x47\x97" + "\x35\xec\xcd\x3b\xd9\x85\x65\x7e" + "\xc9\x65\xeb\x93\x39\x4b\xd8\x8c" + "\xdc\xe7\xa7\x6b\xe8\x12\x55\xab" + "\x34\x18\xd5\x70\x82\x77\x01\x29" + "\xc3\x48\x2a\x2b\x1e\x51\xf1\x4e" + "\x2c\x69\xa2\x4e\x64\x05\x94\x44" + "\x87\xb0\x85\x54\xd7\x5a\x35\x04" + "\x3d\x71\x3b\xad\x56\x43\xf6\xc4" + "\xfc\x1c\x5c\xf2\x2b\x3c\x72\x47" + "\x9d\xd0\x60\xab\x92\xb4\xda\x51" + "\xb7\x6d\xca\x85\x57\x69\x14\x36" + "\x08\xa9\x2a\xe8\xde\xd6\x84\xa8" + "\xa6\xd0\x93\x76\x5f\x41\x49\xcf" + "\x1a\x37\x53\xb8\x49\x36\x8e\x99" + "\xd0\x66\xd2\xf7\x11\xc2\x7f\x75", + .len = 160, + }, { + .key = "\xa9\x41\x4a\xfc\xab\xd8\x74\x7a" + "\xbc\x49\x3e\x8b\xc3\xa3\x52\x71" + "\xf3\xac\x62\x9e\x7a\xc3\xaf\xce", + .klen = 24, + .ptext = "\x0b\x99\xf7\xef\xdf\x7f\xbe\x67" + "\xf4\x93\xb6\xab\x43\x74\xfe\x52" + "\xe3\x13\xf8\x39\xa0\xba\xb7\xc9" + "\x2a\x99\x1b\x6e\xbf\x6f\xb0\x73" + "\x9c\xd1\x96\x09\x38\x3f\xce\xb2" + "\xd2\xbb\x95\xcb\xd4\x91\x9b\x5e" + "\x59\xec\x8a\x50\xdb\xdf\x8b\x19" + "\xa5\x28\xdb\x4d\x75\xc6\x32\xd3" + "\xe6\x2f\x7d\xb3\xae\xd2\x20\x2b" + "\x30\xf6\x3d\x0f\xd4\xa0\x8c\x33" + "\xa0\xa9\xb3\xdd\xfc\x06\x39\x27" + "\x39\xa8\x61\x10\x17\xad\xf8\x05" + "\x14\xc1\x4d\xca\xaa\xdf\x0a\x86" + "\x07\x8b\x78\x81\x91\xc2\x9c\x52" + "\x8d\x1b\x51\xbd\x9e\x9b\x95\xa3" + "\x1d\x83\xa3\xe4\xa6\xfb\x62\xeb" + "\x0e\x00\x7c\xec\x30\x56\xfb\xad" + "\x3f\x78\xb2\xe9\x74\x27\x99\xbf" + "\x97\xf0\xf3\xe3\x5b\x6f\xba\x02" + "\xe8\x04\x19\xc9\x31\xa4\x0f\x5e" + "\x68\x8f\xf3\xe6\x67\xac\x8e\xfa" + "\xe6\x7d\x72\x9d\x71\xae\xdc\x27" + "\x49\x5f\xa0\x3f\x77\x55\xbd\x09" + "\x4d\xa3\xf4\xa1\x8b\x95\x70\x9d" + "\x00\x4a\x02\xf9\x1f\x09\xda\x20" + "\x72\x8f\x2f\x9e\x02\x02\x34\xea" + "\x6b\xed\x4a\xb3\xce\x9f\xe8\x10" + "\x3a\x9a\x9e\x9b\x80\xb2\x35\x40" + "\x5e\x81\xbf\xd7\x13\x54\x51\xe2" + "\xdf\x10\x3e\x29\xe1\xa5\x1f\x3b" + "\x3a\x89\xc5\xf2\xa0\x91\xda\xc2" + "\x69\xa1\x3a\x15\x01\xac\xc2\x2b" + "\xca\xbc\x62\x3a\xef\x00\x92\xe5" + "\x39\xd8\xf7\x38\x64\x35\x70\x5e" + "\xf3\xd4\xa8\xc5\xfe\xfe\xf3\xd9" + "\x9d\x22\x73\x58\x12\xfc\x54\x98" + "\x40\x2c\x5f\x14\xde\xd6\x50\x59" + "\xc8\x80\x7d\x1f\xa2\x20\x0b\x2d" + "\x2f\x0d\x8c\x79\x0e\x17\x56\x04" + "\x8b\xd6\x5b\xbb\x58\xdf\xc4\x0d" + "\xb5\xb4\x2a\x8b\xbb\xf7\x55\xfc" + "\x0f\x88\x3f\xe0\x25\x17\xbb\x85" + "\xb8\xc1\xb1\xac\xec\xe0\x7c\x10" + "\x45\xe8\xd4\x96\xba\x44\xfe\xfb" + "\xc2\x5e\xb7\x12\xe8\xe8\x2f\x4c" + "\x0d\x94\x21\x1b\x0b\x20\xa3\x88" + "\x66\xfa\x06\xb8\x28\x77\x35\xa5" + "\xbf\xe8\xa7\x97\xc3\x0e\xfb\x6a" + "\x38\xd8\xd0\x6a\x47\x04\xbe\x64" + "\xb3\xc7\x86\xd2\x7c\x71\x7d\xe8" + "\x9c\xc8\xe0\x34\xa9\xa9\x0b\x59" + "\xca\xda\x34\x74\x01\x28\x81\x99" + "\xba\xec\xd0\x72\xb7\xe6\x8b\xc9" + "\xcc\x69\xd7\xb8\xc0\x28\x86\xf6" + "\x42\x61\xfb\xb2\x99\x77\xc5\x50" + "\xfd\xca\xef\x70\x33\x40\x76\x1f", + .ctext = "\x01\x59\xa1\x8e\x5d\xcb\x65\x01" + "\x18\x78\x0a\xab\x63\x4a\x4b\xd4" + "\x9c\xff\x91\xa3\xb3\x05\xed\x6d" + "\x82\xd5\x3c\x5b\xcc\x37\x6b\x20" + "\x93\x44\x20\xc4\xe0\xca\x61\x54" + "\x1a\xe8\xb6\x4e\xc3\xaf\x7e\xe8" + "\xbe\xff\x58\x9b\x59\x2f\x59\xfb" + "\x34\x7b\x53\x05\x37\x32\x3e\xcc" + "\x87\x20\x28\xa8\xc7\x06\x46\x48" + "\x82\x33\x55\x04\x06\x7f\xb5\xf1" + "\x25\x09\xb8\xce\x99\xfe\xf3\xa2" + "\xbd\x8c\xef\x33\x82\xda\x31\x71" + "\x30\x8c\xc9\x46\xb3\x81\xb3\x90" + "\x30\x91\x2a\x1b\xf4\xbf\x41\x12" + "\xec\xc3\x3b\x38\xe0\xb3\x73\x53" + "\xb7\x2f\x21\x0e\x07\xd6\xb9\x00" + "\x7e\xe2\x54\x0d\x6d\xb7\xd4\x28" + "\x35\xcb\x1d\xe2\x39\x38\x6f\x2a" + "\x4a\xc1\xa0\xc6\x4d\x8e\xc7\x11" + "\x6b\xdf\x1d\x5f\x76\x28\xbb\x11" + "\x09\x7c\x49\xbd\x57\x7f\xcb\x5e" + "\xb7\x44\x55\xab\xe9\x54\x53\xae" + "\x4c\x97\xae\xc9\x40\xc6\xaf\x08" + "\x07\xc8\x3d\x17\xd0\x51\xd5\xef" + "\xd7\xab\x2f\xd9\xc3\x5f\x93\x85" + "\x05\xb7\x98\x62\x50\x79\xc6\x43" + "\x11\x1b\xb5\xc5\xbf\x01\x0b\x6c" + "\x2c\x1c\x7f\xd8\x74\xa6\x35\xb0" + "\xb6\x0b\x76\x45\xd9\xf9\x27\x6a" + "\xd8\xc1\xbe\xcd\x07\x00\x86\x04" + "\x57\x37\x1b\x05\x4c\x35\x42\x9d" + "\xa3\xde\xd5\xeb\x9c\x83\x17\xa2" + "\xe3\x79\x57\x99\xa9\x07\xd7\x24" + "\x53\x8a\x8d\x69\x15\x61\x62\x86" + "\x9d\xd1\xa6\xa7\x75\x26\x57\x0e" + "\xa8\x79\xec\x3b\x5e\xc1\x2a\xf1" + "\xf3\x54\x35\x6e\xa6\xad\xbb\xfd" + "\xa4\x6d\xbb\x80\x78\x20\x87\x9b" + "\x6b\x23\x1a\x2f\xb0\x17\x53\x4d" + "\xdf\xa6\x37\x95\xd1\x7c\xb9\xc0" + "\x27\x75\xb7\x0e\xc9\x49\x74\xac" + "\xfb\x14\xab\x54\x04\x91\xb3\x4d" + "\x11\x10\x33\x04\x1b\x07\x95\x10" + "\xb0\x6e\x36\x28\x92\x79\x87\x75" + "\x3a\xd3\x12\x0a\xf7\x42\xb3\x67" + "\x38\xfc\x96\xb2\x43\x8a\x80\x21" + "\x02\x8c\x74\x67\x43\x3e\xb8\x30" + "\x9c\x49\xd4\x84\xaf\xc7\x94\xc9" + "\x23\xe5\x56\x5f\x0e\x39\xf5\xb6" + "\xee\x0f\x48\x15\x27\xa7\x1e\xac" + "\x67\xed\x05\x6e\x20\x39\x3b\x7b" + "\x5e\x71\x78\x26\x47\x89\xf0\xf8" + "\x8b\x20\x6d\x29\xe9\x5e\xd5\xa7" + "\xf9\x04\xfb\x84\xc5\xb1\x20\x32" + "\x31\x32\x16\x1d\x37\x8e\xb6\x2c" + "\x85\xd6\xd5\x13\x05\xf6\x09\xdb", + .len = 448, + }, { + .key = "\x4f\x67\x79\xe2\xbd\x1e\x93\x19" + "\xc6\x30\x15\xac\xff\xef\xd7\xa7" + "\x91\xf0\xed\x59\xdf\x1b\x70\x07" + "\x69\xfe\x82\xe2\xf0\x66\x8c\x35", + .klen = 32, + .ptext = "\xdc\x31\xca\xe3\xda\x5e\x0a\x11" + "\xc9\x66\xb0\x20\xd7\xcf\xfe\xde", + .ctext = "\xed\xa2\x04\x20\x98\xf6\x67\xe8" + "\x57\xa0\x2d\xb8\xca\xa7\xdf\xf2", + .len = 16, + }, { + .key = "\x90\x98\x09\xcb\x38\x09\xbc\xdd" + "\xb9\x9a\x08\x3d\x12\x61\x7b\xca" + "\xf7\x53\x06\x45\x73\x5a\xbc\x04" + "\xd2\xa8\xd7\xea\xbe\x4a\xfc\x96", + .klen = 32, + .ptext = "\xa8\x00\xc0\xdb\x6a\x4c\x6a\x70" + "\x2a\xc9\xfa\xe9\x81\xbe\x6b\xe6" + "\xdc\xf3\x36\x8b\x23\xc3\x17\x30" + "\x99\x73\x13\x59\x04\xc2\xba\xe8" + "\x0d\xc1\xaa\x91\xe9\xe5\x54\x8f" + "\x39\x5b\x03\x95\x2f\x9b\x1a\x08" + "\xf3\x40\x9c\x6b\x45\x17\xf2\x1b" + "\x63\x76\xe9\x3c\x2d\xcf\xfb\xf3" + "\x87\x84\xcf\xd5\xff\xfd\x03\xa0" + "\xb0\xf9\x28\x29\x65\x21\x0e\x96", + .ctext = "\x2a\x50\xfa\x90\xed\x00\xeb\xfa" + "\x11\x88\xcc\x91\x13\xdd\x43\x37" + "\xb3\x80\xd5\xf8\xc1\x58\x2c\x80" + "\x77\xec\x67\x28\xec\x31\x8a\xb4" + "\x5d\xe5\xef\xd1\xd0\xa6\x2e\x4e" + "\x87\x03\x52\x83\x2b\xec\x22\x3d" + "\x8d\x5d\xcd\x39\x72\x09\xc8\x24" + "\xe4\xa9\x57\xf6\x5d\x78\x5b\xa5" + "\xd7\xf9\xa4\xcc\x5d\x0b\x35\x35" + "\x28\xdb\xcc\xa6\x35\x48\x66\x8a", + .len = 80, + }, { + .key = "\xde\x49\x23\xf2\x61\xac\x74\xcf" + "\x97\xe4\x81\xce\x67\x4a\x0b\x3c" + "\x3e\xa9\x82\x55\xb1\x50\xcb\xff" + "\x64\x66\x41\xb9\x2a\x7e\xfa\xce", + .klen = 32, + .ptext = "\x6d\x6b\x4b\xce\xd1\x56\x8e\x3e" + "\x14\x0e\x22\x8f\x39\x9e\xb4\x4d" + "\xe5\x25\xbd\x99\x09\xe2\x4c\xd9" + "\xc1\x8f\x06\xae\x7c\xf0\x6b\x27" + "\x5e\xab\x5b\x34\xe2\x5a\xd8\x5d" + "\xc4\xdf\x0d\xb3\x1e\xf7\x8f\x07" + "\xd1\x13\xe4\x5b\x26\x63\x42\x96" + "\xb5\x33\x98\x7c\x86\x7a\xd3\xdc" + "\x77\xb0\x5a\x0b\xdd\xe1\xda\x92" + "\x6e\x00\x49\x24\x5f\x7d\x25\xd3" + "\xc9\x19\xfd\x83\x51\xfa\x33\x9e" + "\x08\xfa\x00\x09\x90\x45\xb8\x57" + "\x81\x23\x50\x3d\x0a\x12\x1d\x46" + "\xdc\x18\xde\xc8\x43\x57\xfd\x17" + "\x96\xe2\x12\xf8\xd2\xcf\xa9\x59" + "\x82\x8e\x45\x3f\xe2\x79\xa5\xff" + "\x43\xab\x45\xb1\xb1\x16\x28\xe2" + "\xd4\xd0\xd5\x89\x14\xae\xa0\x3c" + "\x00\x14\x2a\xa4\xf1\x0b\x2b\x2f" + "\xea\x94\x6f\x04\xc3\x3d\x1f\x3c", + .ctext = "\xb7\x3a\x00\x64\xa4\x29\xeb\xe6" + "\xa7\xcf\x35\xd7\xad\xb9\x4f\x24" + "\xa2\xa0\xff\x7a\x1d\x83\x55\x22" + "\x45\x3a\x67\xeb\x8f\xb4\xfe\xd6" + "\x3d\xa5\x1d\x96\x34\xff\x4c\x70" + "\xa7\x64\xdf\x3f\x6f\x37\x63\xe0" + "\xd3\x84\x56\x30\x77\x42\x19\xa8" + "\x19\xc2\x6e\xad\xfd\x3b\x93\x19" + "\x99\x35\xa9\x5b\xd4\xa9\x51\xd4" + "\x46\x77\x23\xe1\x2f\xba\x1c\xa4" + "\xe8\xb1\x35\xfa\x1f\xb9\xed\x9f" + "\xaa\x7f\xdc\x79\xd2\x85\x7f\x78" + "\xac\x8d\x8c\x39\xc1\x1d\x33\xd0" + "\xae\x58\xb6\xe5\xe0\xef\x78\x19" + "\x5c\x0c\x82\x14\xab\x7d\x3a\x82" + "\xb9\x1f\x9a\x7b\xbe\x89\xd6\xa0" + "\x79\x6e\x9d\xeb\xc6\x9a\xee\x88" + "\x11\x01\x1b\x9d\x48\xee\xcd\x8d" + "\xb7\xbf\x71\x56\x6e\xa6\xd8\xa0" + "\x85\x8e\x59\x64\x32\xe1\x80\x3d", + .len = 160, + }, { + .key = "\xc1\x89\x84\x7c\xb3\x1c\xcf\x8a" + "\x65\x09\x58\x21\xcb\x56\xa1\x0a" + "\x96\x07\x42\x35\x81\x4a\x68\x06" + "\xc2\x2c\xb3\x37\x9c\x71\x4d\xe3", + .klen = 32, + .ptext = "\xf8\x08\xc0\x9c\x2b\x34\xd6\xe2" + "\xa0\x06\x36\xc6\x20\x0e\xbc\xba" + "\xe8\x7d\x15\xc3\xd1\xc8\x30\x43" + "\x4c\x14\x73\x64\xb3\x4c\x31\xe2" + "\x0e\x76\x26\x42\xef\x9d\x2e\x32" + "\x2b\x72\xd1\xca\x97\xa1\x88\x09" + "\x31\xce\x0d\x40\x28\xc9\x70\x14" + "\xdf\xf8\x3d\x27\x8e\xc9\x0d\x12" + "\xfc\x07\x1c\xce\xef\x60\x87\xe5" + "\x02\x11\xa0\xc7\x18\x58\xbc\x7a" + "\x71\xdf\x42\x4f\xb0\x6d\x28\x5f" + "\x29\x19\x63\xec\xe6\x15\x74\xe1" + "\xbc\x2d\xfb\x3e\x4a\xae\x6b\x13" + "\x80\x7a\x8e\x0e\x39\x68\xe5\xa3" + "\x60\xbc\x9c\x46\x26\x1d\xfc\xba" + "\xbc\xc1\x14\x45\xd8\xa9\xe7\x74" + "\x78\xdf\x43\xcf\x34\x58\x8b\x21" + "\x3a\xb7\x23\xfb\xf9\x8e\x2f\x38" + "\xd6\x90\xbb\x1f\x79\x00\x43\x52" + "\x92\xc2\x9c\xe7\x11\x3c\xf6\xa7" + "\xb9\x13\x53\x64\xcc\x7b\xe7\x83" + "\x87\xa0\xe4\xd5\x4b\xa2\x38\x30" + "\x0d\xd6\x2c\x61\x98\x48\x1e\x63" + "\x37\x0b\x90\x2a\x42\xe6\xfe\x52" + "\xfa\xd5\xbf\x49\x72\x71\x8c\x0c" + "\x71\x7a\x8e\xd1\x3f\xf3\x07\x09" + "\xa0\x2b\x4f\x6f\x01\x42\xea\x6d" + "\x0b\xf4\x2f\x78\x3a\x3d\xc7\x0f" + "\xb4\x26\x8b\x5c\x43\xe7\x50\xca" + "\xb7\x07\x15\x0c\x6b\x3b\xc1\xdc" + "\xd5\xd9\x75\x24\x02\x2a\x2c\xf7" + "\x2c\xb1\x26\x72\xce\xd0\x8b\xda" + "\x22\xcd\x62\x1d\x3b\x7a\xdc\x13" + "\xd7\x84\xba\xbf\xc0\x99\x7b\x32" + "\xe5\x55\x4f\x10\x4d\x96\x95\xd2" + "\xbb\x1d\xfb\x7e\xa8\x5f\xb7\x25" + "\xf2\xcd\x8f\xae\x11\x0f\xbe\x2d" + "\xe3\x5f\x6d\x0e\x7c\x05\xbb\x8b" + "\x87\x2a\x24\x7f\xd4\x92\x3c\xa2" + "\x7a\x98\x1f\xf8\xb9\x8e\x98\x9b" + "\x3c\x0b\xa9\x86\x3f\xe9\x8e\xc4" + "\x1d\x08\x40\x34\x0d\x01\x58\x5f" + "\x5a\x19\x31\x78\x26\x7f\xef\x20" + "\x26\x03\xe1\xd8\x88\x83\x07\x79" + "\x74\xe8\x69\x29\x22\x02\x6b\x7f" + "\x0b\x47\xef\xec\xbf\xd2\x0b\xb1" + "\x46\x1c\x93\x00\x35\x15\xfd\xb9" + "\x14\xc7\x40\xc4\xf1\x27\x55\xe6" + "\x27\xae\x73\xfe\xe8\x06\xdc\x0e" + "\xd0\xc3\xad\x87\xce\x68\x32\x46" + "\x91\xd9\xd4\x03\xa4\x12\x2e\x41" + "\x2e\xc4\x0f\x07\x4f\xec\x5c\x85" + "\xfe\x64\x53\x35\x4e\x57\x00\xe1" + "\xc6\x9d\xc9\x0d\x0c\x54\x6a\x41" + "\xa1\xdd\xd7\x4d\x07\x19\xe1\x67" + "\x90\x5a\x27\xe9\x5c\x89\x93\x48", + .ctext = "\xba\x26\x31\x42\xe1\x3d\xdb\x1c" + "\x91\xba\x5c\x42\x2c\xb4\x1e\xac" + "\x65\xe4\x9c\xcf\x8d\x46\xc2\x29" + "\x88\x35\x7c\xc8\x45\x13\x5e\x4f" + "\x54\x2b\x8f\xc1\xec\xdc\xe3\x09" + "\x09\xe9\x3e\x6c\x49\x1b\xd7\x14" + "\x31\x7e\xbf\x1f\x0b\x1c\x16\xca" + "\xb7\xb7\x82\x87\x9b\x4a\x5a\x0c" + "\xfe\x62\xd2\xe6\x46\x8d\x6f\xe2" + "\x21\x4b\x4d\xf0\xdf\x7b\x6e\x5d" + "\xb8\xe3\x4d\x3a\x44\x37\xb8\xf3" + "\x1d\x98\x7e\xf5\x8a\x73\x7f\x61" + "\xa7\x5d\xf5\x5e\xab\x8a\x68\x9e" + "\xca\x9d\xb4\x76\x6e\x04\xcd\x79" + "\xa5\x40\x8d\xa8\x65\x3a\xeb\x6f" + "\xff\x5f\xd7\x85\x57\x2d\xde\x31" + "\xf9\x7e\x23\x2a\xf4\xe4\x02\x86" + "\x89\xc7\xa7\xd2\xde\x1e\xa5\x94" + "\xa1\x45\xd2\xaa\xa6\x60\x3e\x02" + "\xdb\xda\xbe\x33\x9e\x46\x2a\x40" + "\xb6\x89\xc1\xdd\xa0\xbb\x5b\x64" + "\xee\x76\x15\xd7\x08\xde\xee\x7f" + "\xc8\x8f\xb4\xc8\x7c\x2e\x3c\xb1" + "\x97\x70\xf6\xda\x56\xc0\x53\x5d" + "\x87\xc2\x30\x34\x74\xb2\xe5\x03" + "\x73\x56\x0b\xcc\xfb\x13\x2d\xd2" + "\x7a\x9f\xd9\x60\x7c\xbe\x60\xf6" + "\x33\xc6\x9a\xf7\xa1\x17\xc3\x3c" + "\x92\xd8\x21\xf1\x80\x20\xd5\x8a" + "\xb8\x41\xb7\xaa\x5d\x76\x71\x5c" + "\x6e\x1a\xa2\xfe\xf6\xd8\x61\x43" + "\x2f\x56\x82\x5d\x4f\x95\xe1\x0d" + "\x47\xdc\x49\x0e\xc9\xe6\x4c\x91" + "\xc1\xb0\x20\x6a\xc2\xa0\xee\x19" + "\x0c\x5c\x6d\xd8\xe1\x8b\x78\x42" + "\xa0\x1b\xce\xb4\xb0\xbb\xb6\x3c" + "\x98\x44\x9d\xa4\xcb\x89\x0a\x3c" + "\x95\xf6\x9e\x04\xcd\x67\x36\x85" + "\x35\x06\xd0\xde\xf6\x09\x72\x02" + "\x84\x41\xd2\x3d\x90\xa4\xfc\x39" + "\xe2\x8c\xcb\x7d\x7e\xc3\xb5\xe2" + "\x1b\x66\x8c\x9b\x99\x0d\xd8\xe1" + "\xd2\x80\x4e\xe6\x36\x72\x6d\x95" + "\x79\x5e\x84\x02\x7c\x41\x97\x89" + "\x19\xf6\x09\x6f\xb7\x12\xd6\x0d" + "\xc3\x5a\x86\x42\x73\x00\x03\x1c" + "\xeb\xd3\xc1\xda\x45\xc6\x2f\x8e" + "\x89\x41\x99\xd1\xf9\x50\xe7\xaf" + "\x8a\x33\xa4\x45\xef\x74\x26\x90" + "\x1d\xb5\xc5\x3c\x58\x5e\x63\x2a" + "\xc0\x07\x96\xc7\x38\x48\x1a\xc7" + "\x23\x09\x7e\xf9\x32\xb9\xb8\x1d" + "\x49\x9f\x8a\xd4\x93\xa5\x22\x59" + "\x2d\x3f\x5c\xd6\x4b\x34\xf4\x8c" + "\xef\xce\xe9\x07\x2a\xaa\x60\xb7" + "\xdd\xa2\x1f\x5e\x01\xd5\x7a\x1b", + .len = 448, + }, +}; + +static const struct cipher_testvec lea_cbc_tv_template[] = { + { + .key = "\x87\xf1\x42\x4f\x1a\x14\x83\xcc" + "\x1f\xd0\x35\x4e\x18\xa9\x94\xab", + .klen = 16, + .iv = "\xcf\x58\x4e\x6e\xf6\xd6\x42\x88" + "\x0a\xb7\x87\x42\x7d\xb9\xb0\x76", + .ptext = "\x13\x9d\x4e\xff\x8d\x35\xb7\x6e" + "\x85\xbf\x06\xfe\x99\x71\x63\xcb", + .ctext = "\x49\xb9\xf3\x22\x6d\xa5\x4b\x4a" + "\x0d\x38\x5a\x9c\x48\x70\x52\x4b", + .len = 16, + }, { + .key = "\x73\x01\x97\xc9\x42\xd9\x7f\xf9" + "\x38\xa8\x3f\x77\xc4\x34\x4e\x6d", + .klen = 16, + .iv = "\xb6\x17\xb2\x59\xed\xcd\xc6\xbb" + "\x2f\x0c\x3a\x10\x58\x53\x5b\x04", + .ptext = "\xb7\xc6\x95\xe4\xb5\x39\x36\x52" + "\xb7\x8b\x74\x3c\x46\x35\xb2\x0f" + "\x6e\x22\xff\x27\x63\xc2\xe0\x8b" + "\x6b\x5a\x4f\xd7\xf7\x9e\x03\x79" + "\x13\x81\xf2\x20\x01\x4c\x15\x72" + "\x21\xed\x6b\xfe\x15\x92\x40\x71" + "\x21\x77\xaf\x0c\xd8\xfc\x66\x55" + "\xf5\xfb\xa9\x0d\x87\x58\x9a\x63" + "\x51\xda\xb7\x67\x70\x39\xa4\xc1" + "\x3e\x78\x2b\xa3\x77\x74\x81\xfc", + .ctext = "\x7c\x96\xf9\x67\x5b\xe0\x38\x54" + "\x70\x0d\xea\xe5\x10\x06\xf4\xfc" + "\xfc\x3a\xda\x33\xba\xe2\x0d\x4f" + "\xf6\x13\xfa\x6b\xa8\x74\xb1\x75" + "\xb7\xde\x71\xdc\xf8\x7a\x18\x26" + "\x7b\x57\x74\x10\xf0\xe8\xb9\xdf" + "\x1e\x05\x37\xa5\x60\xe5\xd1\xef" + "\xfe\xc1\x10\x22\xce\x60\x23\xb4" + "\x98\x5c\x9d\x8d\xa2\x07\x33\x70" + "\x7c\xe7\x6a\x42\x35\x82\xaf\x23", + .len = 80, + }, { + .key = "\xb2\x10\x06\xa2\x47\x18\xd6\xbf" + "\x8a\xc5\xad\xdb\x90\xe5\xf4\x4d", + .klen = 16, + .iv = "\xa5\xa6\xf3\xce\xee\xaa\x93\x2d" + "\x4c\x59\x68\x45\x82\x7b\xee\x2d", + .ptext = "\x9b\x06\x13\xae\x86\x34\xf6\xfa" + "\x04\xd9\xef\x9a\xc4\xf4\xcf\xa9" + "\xcb\x84\x69\x40\x1a\x9d\x51\x31" + "\x8b\xba\xe3\xf8\xfd\x55\x87\xee" + "\xb0\xb5\x34\xc0\xf2\x08\x33\x20" + "\xfc\xb1\x26\xba\x17\xe3\x48\x6a" + "\x03\x6f\xf6\xac\x98\xda\x6f\x54" + "\xae\xb3\xd8\x7f\x3b\x23\x83\xc9" + "\xbb\xc6\x70\xc0\xd5\xb9\x14\x99" + "\x3b\xf5\x5a\x22\xd2\xdb\xe8\xf8" + "\x13\x0f\xa3\xfa\xb1\x8a\x75\xfd" + "\x7b\xeb\x4e\xc2\x85\x0e\x68\x25" + "\x82\xe0\xd0\x96\x75\x72\x22\xcd" + "\x89\x4c\x93\xba\x3c\x03\x35\xbb" + "\xc3\x0e\x77\x12\xaa\xd5\xeb\x96" + "\xbc\x0b\x4d\xa8\x22\x3e\xc0\x69" + "\xcf\xac\x5a\x2b\x1b\x59\xe3\x25" + "\xad\x5e\xda\x6a\x9f\x84\xb9\x1c" + "\xdd\x11\x7b\xdc\xce\xe2\x5a\x86" + "\x37\xba\xdd\x1b\x5c\xda\x12\xff", + .ctext = "\xb2\x25\x29\xec\xc4\x7d\x73\xca" + "\x8c\xf2\x05\xbe\x8e\x88\x94\x77" + "\xd0\x2f\xb6\x5c\x99\x23\x64\x2f" + "\x67\x4f\xaf\x76\x69\x82\x6c\x97" + "\x8f\xb4\x8a\xc7\xdd\x1b\xbe\x01" + "\x35\x07\xdf\xb9\x0f\x0d\x6b\xab" + "\x59\x8f\xdd\x34\xc6\x93\xb1\x66" + "\x13\xf2\xb4\x78\xc0\x1d\xff\xc4" + "\xb7\x0b\x44\x85\xbb\x93\x43\x0e" + "\x40\xe6\xbc\x0e\xbb\xf3\x53\xce" + "\xe5\x1b\x92\xd6\xb4\xa0\x10\xf0" + "\x4b\x1f\xbe\x7c\x2f\x4f\x6f\x24" + "\x69\xa2\xe4\x4b\xad\x79\x68\xf7" + "\xf9\x23\xb8\x31\x6c\x21\xfd\xf8" + "\x47\xe5\x34\x0e\x10\x95\x20\x9b" + "\xfa\xa9\x1e\xa7\x0a\x5a\xc6\x3a" + "\x39\x39\xf9\x92\xed\xe2\x4e\x8d" + "\xba\x21\x24\x50\x88\x80\x89\x8a" + "\xd3\x20\x87\x0f\x74\x7d\x5c\xe6" + "\xc7\x75\xe5\xcf\xf7\xc4\x2d\xca", + .len = 160, + }, { + .key = "\xf5\x5a\xf2\xa8\x7c\x72\x65\x96" + "\x71\x5d\x76\x30\x5c\x0b\x7d\x46", + .klen = 16, + .iv = "\x5c\x73\x26\x8d\x2c\xb8\x42\x21" + "\xb3\xdd\x72\x03\xe0\x87\xd8\x3f", + .ptext = "\x72\xc5\xa4\xc9\x40\x02\x55\x4e" + "\x3e\xc8\x78\x5d\x7f\x12\x3f\x82" + "\xd1\xee\x6d\x14\x51\x84\x56\x4f" + "\x79\x71\x1f\x2e\x14\x5a\x6d\xfe" + "\x39\x47\x81\x43\x76\xf1\x75\x87" + "\x96\x37\xea\xc7\x1a\xe0\x58\x16" + "\x9d\x44\x33\x58\xca\x4e\x09\x55" + "\xb8\x09\x20\x0d\x24\x48\xd4\x3b" + "\x07\x58\x67\xdc\xb5\x4f\x89\x19" + "\x40\xcf\x00\xa7\xa7\x7d\xbb\x77" + "\x3d\x94\xd9\x01\x70\x5a\x6b\x90" + "\xea\xea\x31\x29\xe0\x84\x70\x3f" + "\x8d\x60\x89\x97\xcb\x69\xc4\xdf" + "\x73\x4f\x66\xb7\x6a\x97\x8c\x80" + "\xdf\xcc\x86\x64\x41\x62\xff\x08" + "\x90\x38\x10\x29\x57\xfe\x1a\xaf" + "\x45\xfe\x93\x2a\x4f\x39\x30\xeb" + "\xcc\xbf\xa0\xec\x2c\xa2\xad\x7b" + "\x6b\xd3\xd0\xeb\x82\x4f\xc8\x52" + "\xd7\x87\xe7\x46\xe4\xfc\x88\xbf" + "\x14\xda\x49\x86\x88\x85\x4d\xb9" + "\xf1\x87\x13\x55\x70\x74\x21\x15" + "\xa4\xab\xbc\xbb\x0c\x15\x84\x33" + "\xeb\x06\xb1\x89\xde\xef\xad\x36" + "\x95\x10\xdc\x7e\xde\x8c\xbd\x59" + "\x88\x1c\xef\x05\xda\x68\x96\x1a" + "\xa5\xf0\x27\x17\xf9\x71\xa6\x35" + "\xfd\x11\x9f\x06\x68\x80\x5c\xe9" + "\x87\xae\x79\xd8\xa5\x35\x63\x5f" + "\x54\xa0\xb4\xb0\xa2\xc2\x91\xab" + "\x56\x49\x67\xb6\x28\x95\xb5\xf1" + "\xe0\x70\x53\xd4\x40\x68\xdd\xf1" + "\xda\x6a\x45\x31\x7f\xc3\xb9\xe6" + "\xe3\xe6\x71\x02\x45\xa7\xb1\x2b" + "\x2a\xbf\x24\x27\x70\x39\x41\x8b" + "\x06\x6f\x19\x3a\xfc\xf3\x95\x36" + "\xe4\x03\xab\x17\x60\xdc\x69\x1a" + "\x1d\x84\x43\xf4\xe5\x6f\xf2\xb8" + "\xab\xf3\x3b\x2c\x99\x91\x53\x2b" + "\xd5\xee\xef\xfd\x00\x85\xf4\xba" + "\x13\xd0\xe5\x52\x36\xd3\x18\x4b" + "\xff\x00\xe2\x60\xcf\x0f\xd2\x40" + "\x60\x10\xdf\xaa\xae\xb8\x82\x88" + "\x35\x5f\x5b\x15\xb9\x11\x0f\x74" + "\xc2\x17\xcf\xd4\xfe\x5d\xa7\xdc" + "\x16\xf3\x9b\xb7\x7e\x36\x7e\x64" + "\xf9\x28\xf9\xc6\xf7\x82\x03\x48" + "\x8d\x77\x85\x21\xf8\xaa\x51\x33" + "\xcb\xde\x49\xc1\x6e\x26\x79\xe2" + "\x07\x21\x1e\xaa\x40\x6b\xdb\xa2" + "\xd8\x26\x92\x20\xd8\x43\x1b\xa7" + "\x93\x2b\x8b\xd3\x54\xe2\x06\xb8" + "\x3f\x78\x45\xaf\x93\xec\x63\x4f" + "\x9c\x0a\x65\x8f\x5f\xae\xd0\x9e" + "\x52\x77\xc0\xf5\xbc\x3b\x03\xba" + "\xc6\x4c\x5e\x23\xbf\xc7\xe7\x88", + .ctext = "\x5a\xf9\x42\xbe\x4a\xd1\x30\xd4" + "\xd4\x14\x0f\xc1\xd0\x64\x37\x22" + "\xc9\x58\xd7\xe9\x67\x35\xcf\x5a" + "\x28\x25\x52\xd7\x3c\x25\xb0\xac" + "\xf1\xc0\xaf\x06\x94\x98\x35\x1e" + "\x46\x3e\x1a\xef\xa9\xd2\x24\xed" + "\x8d\xf0\x48\xf4\x74\x13\x01\x0c" + "\x1a\xbc\x2a\x1c\xae\xb8\x44\xc8" + "\x99\x98\xf3\x61\x95\x5b\x5f\xf4" + "\xbe\x8a\xc3\x9f\xf5\xe8\x64\x81" + "\x8b\xa2\x13\xa8\x8a\xe7\xfa\xb9" + "\xa1\xd5\x33\x8c\xf5\x61\xa0\xe8" + "\xac\x6c\x4b\x2d\x5e\xe5\x93\x9e" + "\x2d\x5a\xa8\x36\x2a\x0a\xc4\x23" + "\x0e\xbe\x50\x61\xe6\x1d\x16\x28" + "\x0b\x2e\x83\xf1\x7d\xa0\xf2\xce" + "\x79\x53\xc6\x54\x7b\x78\x79\x2b" + "\xdc\x9b\x00\x46\x39\x4c\xde\xb5" + "\x96\x11\xf5\x53\xa5\xdf\x4f\x98" + "\x41\xac\x2c\x02\x66\xfa\x27\x66" + "\x2d\x45\x36\xdc\x17\xc8\x0d\x2f" + "\x25\x3c\x34\x3f\x29\x48\x88\xc7" + "\x2c\xb4\x49\xfe\xe4\x33\x18\xd1" + "\x23\xd4\xfe\x0d\x02\x3b\x7f\xd9" + "\xb6\x9b\x2b\x69\x30\x04\xc1\x54" + "\xc4\xa4\x5d\x01\x2f\xb1\x2f\x85" + "\x06\x2d\x15\xf2\x94\xda\x53\xbd" + "\xbb\x7a\x19\x9b\xad\x3e\xb0\x9a" + "\x47\x4c\x51\xd9\x10\xf0\x41\x89" + "\xaf\xe6\xe1\xd8\x8c\x5c\x6d\x3c" + "\xfb\x34\x07\x63\x5b\x8b\x5d\x43" + "\x2c\x91\xaf\xd8\xef\x61\x4e\xb9" + "\x38\x13\x75\xba\x5c\x92\xd4\x13" + "\xb7\x45\x79\xaf\x0a\x6a\x27\x14" + "\xf8\x8a\x3a\xbb\x6f\xc1\x5c\x70" + "\xc4\x0b\x5e\xb6\xb0\x0d\x01\x24" + "\xa3\xa1\x44\xce\xe5\x31\xd8\xdc" + "\x4f\xf4\x1a\xb9\x46\x18\x5e\xc1" + "\xc4\x82\x5b\xc4\x18\xbe\x70\xe1" + "\xc5\xe4\xb9\x84\x91\xcf\xcc\x92" + "\xb6\x87\xaa\x8c\x12\xb9\xe0\x3a" + "\xc9\xec\xc2\xa0\xfa\x7e\x14\xcd" + "\x88\x52\x80\x59\x79\x13\x74\x32" + "\x32\xfc\x53\x7c\x38\xbc\xfb\x3a" + "\xd4\x8f\xb2\x5f\x64\x2c\x5a\xd4" + "\x29\x9c\xc5\xd8\xa5\x55\x73\x37" + "\x74\x8a\xe9\x3b\xda\x7e\x21\x20" + "\x47\xa7\xac\x46\x45\x12\x09\x1e" + "\xc0\x48\x62\xc9\x00\xe3\x82\x17" + "\x2c\xff\x5a\x58\x9c\xf7\x8d\x44" + "\x49\x81\x97\x41\xa4\xb8\x81\x3b" + "\x3f\xd5\x3d\xff\xf1\x3a\xc4\xfc" + "\xfb\x20\x4c\x96\x15\x75\x09\x2f" + "\xa3\x85\xb0\x47\x15\x61\x30\x00" + "\x3f\x5f\x0e\xda\x97\xb3\xdf\xfa" + "\xe6\x16\x25\x0c\x12\x22\x17\x57", + .len = 448, + }, { + .key = "\x68\xd2\x18\x65\x0e\x96\xe1\x07" + "\x71\xd4\x36\x1a\x41\x85\xfc\x81" + "\x27\xc3\xb5\x41\x64\xda\x4a\x35", + .klen = 24, + .iv = "\xb5\xa1\x07\x03\x79\x0b\xe7\x4e" + "\x15\xf9\x12\x2d\x98\x52\xa4\xdc", + .ptext = "\x9b\x56\xb0\xb2\x6c\x2f\x85\x53" + "\x6b\xc9\x2f\x27\xb3\xe4\x41\x0b", + .ctext = "\x72\x86\x6a\xa8\xe3\xf1\xa4\x44" + "\x96\x18\xc8\xcf\x62\x3d\x9b\xbe", + .len = 16, + }, { + .key = "\xc2\xe6\x6b\xb9\x2b\xf6\xa3\x1f" + "\x12\x35\x44\x5e\x2f\x92\x57\xed" + "\x6c\x59\xc3\xa5\x8f\x4c\x13\x76", + .klen = 24, + .iv = "\x1a\xf6\x79\x59\x6f\x3c\x13\x85" + "\x38\x35\x6e\xe6\x06\x3c\x49\xcb", + .ptext = "\x38\x43\x9b\xdf\x1f\x6a\xd7\x5a" + "\x60\xd0\x6e\x78\x99\xa8\x95\x2b" + "\x47\x90\x4a\x0c\xe7\x1f\x91\x98" + "\x5b\xbd\x04\x99\x90\xb8\x8a\xe2" + "\x5e\x94\x67\x3f\xaf\xa2\x75\xac" + "\xe4\xd4\xb0\xc5\x74\xcf\xf8\x7e" + "\xd6\x42\x13\x14\xa2\x76\xf2\x44" + "\xf3\x27\x35\xba\x0f\x93\xf1\xcc" + "\x4a\xd0\xb0\x68\x27\x62\xb9\x4b" + "\xc1\x0d\x92\x74\x69\xe8\xc4\xd9", + .ctext = "\x96\xbe\x15\xc3\xb8\xd1\x47\x3b" + "\x4a\x3c\xb8\xf5\x25\x83\xb1\xad" + "\x80\x4f\xe4\x6d\xc1\x43\xfd\x26" + "\xc3\x8c\x4b\x01\x9c\x10\xd6\x0f" + "\x68\x15\x82\x50\x95\x32\xe5\x86" + "\xcc\x23\x71\x8b\x7b\xd7\x50\x45" + "\xd5\x77\xf8\xe7\x78\xca\x4b\xf0" + "\x27\x8e\xb2\x5a\xb7\xcd\x67\x08" + "\x00\xc5\xec\x88\x32\xfe\x91\xb8" + "\x4e\x56\xab\x58\xde\xe8\x49\xa8", + .len = 80, + }, { + .key = "\x60\x4f\xeb\x8b\x42\x88\xe6\xee" + "\x61\x96\xba\xb9\x66\x91\xed\xed" + "\xa4\x8c\x1d\x41\x43\x23\x41\x5b", + .klen = 24, + .iv = "\x9d\x53\x31\x46\xe8\x8f\x69\x21" + "\x16\x0f\x09\x14\xf9\x6c\x21\x89", + .ptext = "\xab\x6a\x2c\x98\x2d\x14\xda\xc2" + "\x4e\x0f\x13\xe3\xce\x28\x38\x62" + "\xc4\x2f\xac\xab\x3d\x08\x93\xdf" + "\x26\xff\xd9\xc9\x6c\x5c\x76\x15" + "\x61\x37\xf1\xbc\x62\x8e\x23\xc3" + "\xb7\x95\x3e\x25\xba\x4d\x0e\x0e" + "\x3b\x58\x7e\x49\x24\x0c\x5d\xfc" + "\x59\xc6\x62\x93\xe2\x81\x6e\xfa" + "\x4c\xa7\x12\x0f\x4c\x26\x51\x57" + "\xa6\xc7\xa7\xef\x4d\xbc\x4a\xc6" + "\xcc\x77\xaf\x0a\xe4\xc3\x50\xe0" + "\x77\x0d\xad\x58\xa5\x02\x90\xa0" + "\x34\x60\x96\x78\x35\x05\xeb\xe5" + "\xe4\x4d\x55\x2a\xd1\x9a\x74\xf4" + "\x3d\x34\x48\xd5\xc7\x54\xf3\xf3" + "\x48\x7b\xc0\x02\xfb\x08\x65\x6f" + "\xe1\x0a\x85\xde\x63\x53\x79\xd7" + "\x3a\xce\x50\xbc\x8c\x12\x14\xff" + "\x57\x36\x4f\x91\x13\xe7\xce\x9e" + "\x93\xb9\xa5\x77\x2d\xbb\x74\xd0", + .ctext = "\x55\x6b\xda\xdc\x75\x31\xee\xe8" + "\x88\xf6\xde\x47\x8f\xb3\x74\x0f" + "\xa2\xbd\x15\x22\x08\x76\x74\xf2" + "\xc6\xe1\x64\xdc\x6f\xb6\x08\x7c" + "\x41\x6b\xcc\x7c\x25\x29\x54\x78" + "\x25\x9d\x4e\xbb\xec\xfd\x42\xd3" + "\x2b\x97\x23\x9e\x45\x91\x02\x68" + "\x0a\x19\x79\x82\xab\x3e\xd6\xd7" + "\x32\xd2\xbc\x8a\x2e\x37\x35\x58" + "\xb4\xc5\xe1\xc9\x12\x30\xb7\x76" + "\xcb\x1f\x02\x60\x78\xbc\xa9\x10" + "\x4c\xf2\x19\xbc\x96\x06\x5e\xef" + "\x44\xda\x86\xa4\xa3\xaa\x99\xf2" + "\xec\xb9\xa6\x09\xd8\x5c\x6f\x4f" + "\x19\x07\xb7\x1d\x49\xdf\x55\x2b" + "\xd1\x43\x43\xb2\xc6\x79\x75\x19" + "\x6a\x25\xd8\xa2\xaf\xdc\x96\xd3" + "\x78\x9e\xeb\x38\x3f\x4d\x5c\xce" + "\x42\x02\x7a\xdb\xcd\xc3\x42\xa3" + "\x41\xc0\x19\x45\xc0\xb3\x89\x95", + .len = 160, + }, { + .key = "\x1d\xbd\x47\x5a\x83\xf2\xf7\x8e" + "\xab\x14\x67\x67\xce\xe1\x5f\x9e" + "\xc1\x7d\xe1\xf9\xbe\x84\xb3\xc1", + .klen = 24, + .iv = "\xb9\x90\x3c\xa3\xad\x93\x64\x1d" + "\x0a\x8f\xb5\xba\xbe\xa0\x09\xef", + .ptext = "\x6f\xe8\x28\x27\x64\x1c\xb5\x1c" + "\xd3\x9f\xec\xbb\x7b\xea\xd2\x65" + "\x53\xc8\xfa\xd2\x46\x5c\xf0\xa5" + "\x92\x60\xc4\x8a\x1c\xa8\xc7\xab" + "\x17\xca\xa5\xac\x83\xcd\x7a\x6d" + "\x4a\x6a\xdd\x22\x5c\x54\x05\xe2" + "\x9c\xc3\x0a\x06\x93\x0a\x11\x2b" + "\x81\xf9\x0e\xa1\x80\xfd\x86\x57" + "\x1f\xca\x07\x67\x7e\x82\x88\x2f" + "\x42\x3a\x92\x99\x35\x5b\xa7\xad" + "\x28\xd2\x71\xb3\x4e\x0c\x36\xc0" + "\x1f\x1a\xa2\xcb\x5e\xd7\x2f\x82" + "\x03\x47\x13\x6f\x8a\xea\x9f\xbe" + "\x54\x6a\x58\x2b\x57\xd7\xc0\x25" + "\x10\xda\x31\x2a\xbe\x08\xc3\x93" + "\x9e\x71\x1a\xa6\xee\xe6\x1a\x6f" + "\xf7\x6e\xf1\x7c\x79\x7f\x23\xa5" + "\x7d\xb4\x42\x34\xbc\xff\x5f\x44" + "\xba\x60\xd2\xb5\xe5\x66\x93\x89" + "\x30\xbd\xb5\x80\x5c\xa7\xf5\x24" + "\xd9\x63\x67\xaf\xf5\x8b\xb0\xa9" + "\x62\x6f\x5f\xe9\x84\x94\xa6\xb9" + "\x30\xfc\x23\x9f\xe4\x37\x86\x74" + "\xfe\xd7\x72\x55\x98\xb6\x1d\x9f" + "\x42\x99\xc9\x10\xf0\xf6\x7f\xa8" + "\x10\x6e\x97\x15\x1c\x1a\x9a\x89" + "\x95\x96\xc2\xb8\x98\x21\x4f\xc8" + "\xca\xb7\xd2\x74\x26\xa1\xd0\x23" + "\xb6\x63\x00\x0c\x1a\x52\x4c\x32" + "\xfa\x32\xeb\xf4\x93\x53\x72\x45" + "\x17\x10\x2e\x6a\x48\xe3\xd4\x4c" + "\x5d\x7d\xaf\x2a\x1d\x79\x6b\x9d" + "\x27\xb9\x3f\xce\x5d\x8c\xbd\x3d" + "\xb5\x47\xa2\x94\xea\xd4\x1f\x1a" + "\xe2\x0e\xe0\x20\xa2\x1a\x2f\x4f" + "\x77\xd5\xd4\x96\x11\x28\x37\xd3" + "\x1f\xdd\xc5\xed\x96\xda\xdd\x22" + "\x88\x91\x0f\xf4\x27\x23\xf4\x7d" + "\xce\x99\xe6\x0a\x51\x96\xb4\x08" + "\x1e\x46\x30\x6c\x20\x33\x53\x25" + "\x04\x53\x83\x95\x90\x34\x7c\x27" + "\x7e\x8f\x02\xe4\xc5\xbc\x52\x97" + "\xde\xc1\xd9\x32\xc3\xe1\x49\x05" + "\x87\xcb\x9f\xa2\x66\x54\x9c\xd4" + "\xe7\x1a\x80\x61\x41\xfb\x4f\xed" + "\x29\x4c\xc0\x55\x11\xf4\xb2\x28" + "\x57\x1f\x26\x5a\x98\x2a\xc4\x84" + "\x45\xe1\xff\x5b\x6b\x38\x60\x06" + "\xdb\x1c\x86\x65\x2d\x0e\x21\x8e" + "\x9b\x58\x23\xea\x59\x4f\x40\xf8" + "\xe2\xdb\xee\xa5\x5b\x9c\xc9\x9e" + "\x52\x2e\x0d\x8a\x1a\xcd\xe9\x44" + "\x45\x52\xa1\xc6\x18\x11\xbf\x76" + "\x7c\x77\xc3\x1c\x18\x5b\xd2\x65" + "\x5c\xe4\xf8\xb4\x47\x05\x62\x04" + "\x90\x9e\x7b\xa0\xa3\x47\x8a\x52", + .ctext = "\x26\x63\x01\xcc\xbd\xb4\x66\x7f" + "\x29\x3f\x59\x6d\x87\x5b\x1b\x8d" + "\x97\xe3\xce\x12\x2d\x3d\xd1\xe6" + "\xf2\xcd\x75\x4e\xad\x64\x9f\x52" + "\x59\x71\xe8\x2e\x87\x6d\x50\xbe" + "\xf9\x98\xa6\xbe\xc6\x17\xd7\x0f" + "\x60\x4f\x10\x30\x79\x34\x69\xc7" + "\x61\x77\x3e\xa3\x7e\x72\xc5\xae" + "\x91\x3f\x58\x7e\x9b\xba\x39\x05" + "\x71\xf7\x02\xe6\x26\x8b\x42\xa2" + "\xda\x98\xbc\x0e\x13\x48\x25\xc0" + "\x1e\xe4\xed\x4f\x70\x8c\x9f\x73" + "\x42\xaa\x5c\x83\x43\x2f\x03\x05" + "\x8a\xa8\xc8\xdc\x52\x04\x85\x05" + "\x29\x69\x9d\x61\xb7\x77\xdb\x88" + "\xa9\xff\x4f\x63\x92\xa3\x1f\xa1" + "\x67\x07\x37\x00\x69\x6f\x29\xfb" + "\xef\x32\xe3\xff\xb8\xd8\x70\x1a" + "\xaf\x9b\x5b\x29\xb5\xe8\xb5\x3b" + "\x93\x49\xc6\x8d\x6e\x15\x7f\x2c" + "\xc0\x8a\x88\x6e\x1a\x73\x05\x91" + "\xea\xc6\x62\x35\xcf\x12\xd6\xcb" + "\xb2\xa1\xcf\x88\x1d\x10\xa3\x11" + "\x45\xb0\xf8\xe3\x38\xf5\xb8\x4c" + "\x55\x59\x1c\xf8\xd0\x0f\xea\x6f" + "\x72\x44\x7b\xee\x14\xf1\x05\x41" + "\xcc\x83\xe4\x9c\x2f\x38\xfc\xa6" + "\x19\xf4\x1c\xd5\xbe\xcd\x32\x95" + "\x01\xb7\x22\xf9\x6b\x56\x93\x3f" + "\x50\x01\x16\xd0\xef\x53\x7f\x1a" + "\xb5\x0c\xde\x94\x5d\x75\x72\xf8" + "\xae\xc5\x26\x1c\xa9\xa6\xe5\xea" + "\x41\x06\xd0\xbc\x8a\x28\xfa\x1d" + "\xb5\x78\x80\x16\x1a\x18\xde\x44" + "\x0e\x8b\xf0\xe1\x34\x08\x0f\xf4" + "\xe8\x11\xb9\x4f\x40\x00\xea\x79" + "\x61\x28\x4b\x69\x80\xac\x73\x9d" + "\x7e\xa1\xe3\x81\x6f\x87\x15\xcc" + "\x8c\x87\x28\x07\x77\xe6\xec\x1b" + "\x5d\xce\x7b\x84\x2d\x0b\x90\x81" + "\x4f\x8a\xc7\xa9\xe0\x98\x2f\xd4" + "\x84\xd6\xba\x65\x71\xe3\xb6\xab" + "\x7c\x3f\xbf\xfa\x33\xd7\x25\x34" + "\x9b\xb6\xfb\x82\x4e\xd2\x1f\x8b" + "\xa0\x90\x94\x27\xb7\x63\xad\x96" + "\x71\xcc\x2d\x97\xaf\xff\x97\xb4" + "\x96\x3d\xba\xde\x6e\x8d\x84\xf1" + "\x00\x0a\xde\xfa\x60\xc6\x46\x72" + "\x6b\x12\xa2\xd1\x70\x77\x4f\x14" + "\x42\x59\x51\x69\x37\xe4\x87\x49" + "\xc6\x3f\xbe\x39\x3e\xce\x87\x4d" + "\x90\x51\xdc\xf3\x1a\x09\x68\x6e" + "\x9d\x24\x0b\xb3\x55\x66\x0c\xd7" + "\xa7\xd7\x40\xdf\x33\xa0\x3c\x80" + "\xae\x74\xd5\x5b\xba\x70\xdd\xb2" + "\x10\xd3\x54\x56\x7b\xea\x63\xa4", + .len = 448, + }, { + .key = "\x1a\x4e\xe8\x2b\x1f\x37\x84\x94" + "\x6d\xf2\xa1\x8f\xc7\x49\xb3\x4f" + "\xe2\x26\xcf\x28\x11\xa6\x6a\x47" + "\x22\x6e\x64\xa1\x82\x42\x45\x29", + .klen = 32, + .iv = "\xa8\xd4\xc6\x46\xb1\xd9\x93\x84" + "\x48\x62\x4f\x8a\xc9\x6a\xd8\x4c", + .ptext = "\xa6\xab\xcd\x81\x09\xb7\x4e\x58" + "\xbb\x43\x03\x66\x44\xc6\x60\xe3", + .ctext = "\x91\xee\x72\xe8\xe2\x6f\xa4\x23" + "\x49\x77\xe4\x64\xca\x48\x72\xca", + .len = 16, + }, { + .key = "\x50\x81\xcf\xf8\x35\x84\xf4\x3b" + "\x8b\x60\x07\x4f\xb2\x05\x08\xbb" + "\x60\x63\xf9\x0b\x44\x7c\xa0\x80" + "\xe9\xbd\x88\x06\xde\x8e\x49\x66", + .klen = 32, + .iv = "\x14\x28\x09\xbd\x87\xa6\x43\x2d" + "\x20\x5f\xc7\xd2\xda\x74\x02\xf8", + .ptext = "\x25\xa5\x80\x8b\x88\x69\xaf\xce" + "\x89\x3d\xe6\x50\xd1\x3c\xa5\x1d" + "\x8c\xf0\x1f\x31\x0f\x68\xf5\x32" + "\xbd\x8a\x45\x5e\x2b\xab\xe3\xc2" + "\x82\x5d\xe6\xac\x25\x88\x67\x64" + "\x94\xbd\x85\x17\x91\xc6\xac\x14" + "\x81\x82\x18\x3b\x14\xf0\x94\xb1" + "\x28\x89\x88\xd9\xeb\xd3\x32\x80" + "\x40\x33\x34\x58\x65\x02\x4f\xa8" + "\xd2\xe4\x6e\x41\x64\x55\xe6\xb4", + .ctext = "\xee\x57\xd3\x98\x7e\x62\xcf\x04" + "\xbb\x11\x21\x91\x20\xb4\xa3\x92" + "\x16\x86\xaf\xa1\x86\x9b\x8a\x4c" + "\x43\x7f\xaf\xcc\x87\x99\x6a\x04" + "\xc0\x06\xb0\xc0\x4d\xe4\x98\xb2" + "\x4b\x24\x34\x87\x3d\x70\xdb\x57" + "\xe3\x71\x8c\x09\x16\x9e\x56\xd0" + "\x9a\xc4\xb7\x25\x40\xcc\xc3\xed" + "\x6d\x23\x11\x29\x39\x8a\x71\x75" + "\x0c\x8f\x0c\xe4\xe4\x2b\x93\x59", + .len = 80, + }, { + .key = "\x26\x7e\x63\x9d\x25\x19\x08\x8a" + "\x05\xbd\x8a\xf4\x31\x3c\x47\x55" + "\x88\x06\xb9\xcb\x03\x42\x40\xc8" + "\x98\x1d\x21\x0b\x5e\x62\xce\xcf", + .klen = 32, + .iv = "\xf1\x4c\x68\x42\x18\x98\x82\x38" + "\xa5\xdd\x28\x21\x9d\x20\x1f\x38", + .ptext = "\x99\xa3\x6f\xfe\x6c\xff\x1f\xe7" + "\x06\x72\x40\x53\x99\x7a\x2d\xbf" + "\xfa\xa3\x10\x3d\x49\x9d\xa8\x21" + "\xd4\x91\x4a\xfe\x39\xb5\x26\xd1" + "\xcb\x1f\xcc\x7b\x37\xd7\xef\x75" + "\x68\x2f\x68\xbf\xa7\x57\x7d\x19" + "\x07\x2c\x64\x76\x00\x51\x03\xae" + "\x5a\x81\xfa\x73\x4c\x23\xe3\x86" + "\xe6\x1f\xd8\x2a\xac\xf1\x36\xda" + "\x84\xfc\xa1\x37\xd2\x20\x49\x44" + "\xe1\x8e\x6b\xd5\x85\xdb\x1a\x45" + "\xfe\x54\x3f\x68\x20\x92\xdf\xc0" + "\xb1\x4e\x9c\xf4\x13\x76\x7f\x7d" + "\x22\x7f\xf4\xa3\x60\xfe\x16\xa8" + "\x50\x72\x2d\x43\x1f\x64\x75\x50" + "\x89\xb3\x22\xc5\xfb\x29\xa0\xe8" + "\xf5\x51\x1f\xbf\xb3\x8d\x4f\xc8" + "\x0c\x63\x68\xeb\x9a\x18\x6e\xad" + "\x1b\x80\xb3\xa6\x17\x14\x9d\x35" + "\xc4\x45\xa9\x72\x26\x10\xb0\x64", + .ctext = "\xb5\x35\x2d\x1b\x32\x1d\x11\x00" + "\x7a\x50\xaa\x50\x0b\x7d\x7d\xd4" + "\x3c\x59\x89\xbf\x12\xe7\x20\x9d" + "\x96\xe4\xe3\x04\xc7\x2a\x53\x44" + "\xe4\x39\x1e\xd4\x25\x89\x2c\x6a" + "\xd4\x05\xda\x1d\x0a\xce\xcc\x67" + "\x7b\x80\x76\xf3\x28\x0c\xb7\x85" + "\xb1\x18\x07\x7b\x78\xbe\x2d\xec" + "\xbe\xf6\x77\x22\x74\x22\xc1\x88" + "\x00\xef\x25\xaf\x03\xcd\x69\x3c" + "\xc1\x31\x17\xab\x92\x5c\xf7\xc3" + "\x90\x0b\xfa\xdf\xf7\xdf\x0a\x6e" + "\x1e\x82\x39\x16\x35\x3b\xa6\x2b" + "\x96\x8d\x9d\xd3\xaa\x56\xae\x7a" + "\xba\x4b\xcb\x46\x8e\xaf\x37\x04" + "\xcc\x06\x21\x72\x52\x0e\x94\x6f" + "\x9b\x6c\x0c\x18\x01\x97\x6d\x31" + "\x85\xb6\xbd\xfd\x50\x4d\x99\x2b" + "\x74\x23\x57\x80\x15\x3f\x69\xa5" + "\xf3\x2c\xcf\xf1\x1e\xc7\xe0\x04", + .len = 160, + }, { + .key = "\x57\x88\x9e\xee\xa3\x45\x14\xf9" + "\xdf\x51\x60\x5a\xed\xfe\xcd\xa7" + "\xb5\x62\x14\x82\x34\x56\xc1\x62" + "\x61\x47\x11\x76\xcc\x68\x40\x43", + .klen = 32, + .iv = "\x53\xe4\x22\xc3\x11\xb1\x52\x02" + "\xcf\x79\x7d\x59\x7d\x84\x46\x4c", + .ptext = "\xb6\x2b\x7d\x75\xb2\x06\xa5\x13" + "\x06\xd0\xab\x88\x25\x33\x9b\xe5" + "\x13\xb9\xa6\x5e\xe1\x43\x54\xf5" + "\xac\x76\xac\x69\x72\xe5\x3d\xb1" + "\x11\x19\x75\xd3\xec\xa0\xf9\x33" + "\x61\x11\x36\xb9\x93\xc5\xd1\xaa" + "\x98\xf9\x5a\x28\x44\x26\x05\xeb" + "\xed\x28\xb3\x76\xea\xcd\x48\xd7" + "\x4b\xd4\x44\xa2\x90\xd9\x51\xbb" + "\xd4\x4a\x25\xa0\x53\x75\x35\x16" + "\xfc\xc1\xc8\xb1\x03\x40\xe5\x3b" + "\x4d\xa2\x1a\x78\x0a\xeb\x75\xf0" + "\x64\x03\x15\xf4\x15\xc7\x58\x83" + "\xb4\x9d\x54\xf0\x10\xc7\xe6\x9d" + "\xf8\x38\xcd\x00\xac\x1c\x51\xf8" + "\x52\x38\x0a\x63\xa0\x89\xbe\xbf" + "\x76\x11\x33\x69\x23\x77\x00\x2c" + "\x93\xe8\x30\x89\xea\x3d\x01\x3d" + "\x41\x51\x9e\x96\x05\x9c\xbc\xa2" + "\x40\xc1\x75\xfb\xa9\x9b\xec\x08" + "\x5f\x16\xa9\xbb\x79\x87\x96\xda" + "\xcc\x59\xac\xb0\xe9\xf8\x85\x01" + "\x6d\x23\x8c\x0e\xa1\x37\xd4\x75" + "\xdd\x63\xc2\x74\x1d\xfd\x02\x89" + "\xd9\x1c\xe2\x60\x25\x16\x91\x87" + "\xca\x5d\x68\xea\x1f\xaf\xc7\x8b" + "\x55\x10\xc4\xd5\x43\x3f\x98\x54" + "\x0c\x32\xa3\x7c\xa8\xfa\x6b\xcb" + "\x7a\xe6\x2b\xa7\x1d\x69\xa5\x80" + "\x93\xeb\x6a\xf7\xa2\x9c\x26\x5a" + "\xf4\xf7\x63\x20\x0b\x6c\x3b\xb0" + "\x44\x6b\xac\x8d\xb5\x80\xaa\x8d" + "\xf5\xe0\x06\xf2\x65\xeb\x65\xe2" + "\x43\x0c\x61\x98\x60\x8d\x18\xd9" + "\x95\x09\x49\xa5\x02\x86\xce\x9e" + "\xb8\x89\x84\x00\x55\x19\x32\x62" + "\x75\xed\x79\x94\x05\xe9\xff\xe4" + "\x42\x68\x7a\x5a\x76\x42\xbe\x43" + "\xab\x5e\x31\xcf\xeb\xe1\xfa\xb0" + "\x3d\xda\x7f\xe9\xdd\x58\x8a\xb8" + "\xad\x04\x97\xf9\xee\x0e\x70\x1d" + "\x54\x64\x47\xdb\xe0\xf0\x85\x5f" + "\x69\x2b\x5c\xba\x7c\xfe\x53\xba" + "\xd5\xc8\x57\xfa\x8c\x4c\x7e\x4a" + "\xbc\x8d\xf9\x8b\x71\xdf\x2a\x9d" + "\xb1\x6a\xec\xb6\x14\xcb\x6d\x4f" + "\x83\xc5\xdc\x24\x94\x83\x8c\x36" + "\xa1\xdb\xe1\x8f\xec\xa3\xde\xdb" + "\x1e\x41\x97\xff\x3c\xef\x79\x91" + "\xfe\x14\x53\x54\x68\x59\x77\xc9" + "\x04\x42\xb9\x64\x52\x36\xaf\x9e" + "\x7e\x7f\x48\xc0\x64\x20\x5e\x2e" + "\x4a\xc1\x43\xcb\x24\x1d\x2e\x91" + "\x89\xed\x4d\x03\xa4\x30\xbb\x6b" + "\x48\xad\xfb\xe8\xf5\xb6\x84\xb1" + "\xd0\x7a\x53\x9f\x0a\x12\x34\x33", + .ctext = "\xb2\xc5\xc7\x5b\xc5\x28\x00\x77" + "\xfa\x1e\x81\x84\xee\x81\x56\xd0" + "\x4d\x16\x96\x82\xc9\x09\xd4\xf5" + "\x90\x17\xa6\x92\x45\x3b\x82\x60" + "\x60\xeb\xd7\xda\x36\x24\x3d\xd3" + "\xed\xbe\x80\x50\xb8\xb5\x93\xff" + "\x54\x2b\x18\x92\x25\xdb\x54\x75" + "\x83\x64\x11\x90\x00\xf2\xeb\x5a" + "\x50\x42\x9a\x4f\x9c\x46\xd0\x37" + "\xef\xdd\xbf\x67\x2f\x81\xd4\x33" + "\x89\x02\x66\x47\xfc\x00\x27\x36" + "\xb0\x0b\x5a\x72\x13\x0c\xf4\xc9" + "\xd6\x70\x3d\x6c\xcb\x65\x25\x46" + "\x01\x15\xc5\xd3\x55\x0b\xa5\x6a" + "\x9b\x6c\x6e\xe5\x68\xa5\x54\xb4" + "\x31\xe9\x4a\xff\xea\x35\xc6\x80" + "\xcd\x17\x9d\x0c\x94\x13\x82\xc4" + "\x89\x6d\xff\xa0\xc5\xac\xad\x3f" + "\xd7\x6b\xc3\xa8\x1b\x3d\xf2\x1a" + "\x5c\x9e\xbd\x68\x2f\x71\x8c\x4d" + "\x17\x49\x0a\xca\x60\x9f\x7c\x4d" + "\xb1\x32\x69\x2e\xd5\x6d\x16\xc5" + "\x9c\x7b\x38\x2b\xf1\x97\xb2\xea" + "\x87\xac\xc7\x17\x9a\x1d\x61\x0a" + "\xdc\x73\xa7\xb3\x50\x4d\xae\x4d" + "\xef\xb2\xc2\x4f\x6b\xc6\x73\x4e" + "\x60\x90\x89\x2e\x30\x85\xc3\xce" + "\x32\xa5\xb6\x14\x18\x7a\x28\x6a" + "\x37\x2e\xf4\x66\x07\x35\xb0\xbf" + "\x00\x1f\x03\xdf\x8f\xa3\x69\x02" + "\xdc\x58\x5d\xad\x86\xb6\x10\x47" + "\x4e\xf5\xb4\xeb\xb7\xa8\xe2\xf5" + "\xb8\x4d\x5c\xae\xc0\x33\xe4\x5a" + "\x43\x2a\x33\x1d\xdc\xd0\xea\x43" + "\xa7\x68\x30\xe9\x2f\x60\xe5\x60" + "\x39\xfa\x29\x1a\x11\x96\x72\xd6" + "\xf6\xaa\xee\x26\xec\x27\x72\xed" + "\xb0\x25\x48\x14\x8f\xba\x30\x95" + "\x2b\x81\xdd\x84\xb2\xbb\x72\xf5" + "\x81\x0f\x5c\xe6\x07\xf8\xd8\xce" + "\x84\x96\xc6\xfe\xa4\x0f\x1b\xaf" + "\x5c\x74\xaf\x92\x32\xd1\xc1\x45" + "\x3b\x76\xfa\xe7\xfe\x4f\xc1\xd8" + "\x7a\x69\xd4\xb9\xd6\xd8\xe8\x6a" + "\xf4\x8c\xd6\xc4\x4a\x8d\x59\xda" + "\x67\xef\x60\xaa\xf9\x31\x38\xc8" + "\x5e\xe8\xdb\x7d\x5a\x63\xc7\x9c" + "\x99\xc1\x0e\x9f\x13\xd6\x49\xf1" + "\xf8\xe4\x54\xd3\x05\x6a\x6a\xa3" + "\xab\xb7\xec\x45\xe6\x9f\x76\x29" + "\x2e\x7c\xc4\x6d\xee\x44\x61\x65" + "\x4a\xd6\xa0\x27\xed\x9d\x01\xb8" + "\x88\x37\x01\x87\x19\x22\xd3\x58" + "\x8e\xa4\x08\x68\x4c\x24\xa9\x22" + "\x6f\x8a\xf2\x94\x37\x25\x89\xea" + "\xb6\x18\x71\x8a\x61\xd7\xe7\x29", + .len = 448, + }, +}; + +static const struct cipher_testvec lea_ctr_tv_template[] = { + { + .key = "\x7a\xd3\x6a\x75\xd5\x5f\x30\x22" + "\x09\x4e\x06\xf7\xc8\x97\xd8\xbb", + .klen = 16, + .iv = "\x0c\x5f\x04\xe8\xb5\x12\x19\x5e" + "\x74\xb3\xde\x57\xe9\x70\x97\x9e", + .ptext = "\x08\x7a\x83\xfc\xc1\x13\xa9\xf3" + "\xe0\xe9\xd5\xaf\x32\xa2\xdd\x3a", + .ctext = "\x2b\x73\x49\x7c\x4f\xc9\xef\x38" + "\xbe\x7a\x0b\xcb\x1a\xab\x87\xa4", + .len = 16, + }, { + .key = "\x74\xba\x38\x82\x43\x53\x9e\xfa" + "\x20\x2d\xfa\x64\xa9\x81\x74\xd9", + .klen = 16, + .iv = "\xe0\x56\xc2\xc6\xd2\x99\xef\x9c" + "\x77\x6f\x5b\xc9\xda\xca\x04\xe8", + .ptext = "\x79\x3b\x03\x34\xef\x07\x5a\x43" + "\xd0\x7c\xec\xf1\xd5\x85\xcd\x9a" + "\x39\x7d\xbc\x8c\x62\x41\xee\xbb" + "\xc4\x89\x0e\xb7\x03\x78\x81\xdc" + "\x57\x71\xee\xc8\x35\x2d\xfe\x13" + "\x2c\x0a\x60\x3a\x0d\xa6\x11\xdb" + "\x4e\xad\xda\x28\xb0\xef\x1a\x96" + "\x20\xb6\xc5\xd5\xdb\x56\xad\x05" + "\xd6\x05\x00\x27\x5d\xed\x12\xd1" + "\xfa\x80\x5d\x26\x98\x0c\xc7\x06", + .ctext = "\xaf\x18\x50\x91\xa0\xa4\xf1\xe2" + "\x5b\xc2\xfc\xb0\x5c\xb6\xdd\x1b" + "\x46\xcb\x01\xd5\x8f\x90\x55\xc6" + "\x1b\x9a\xb5\x49\xd4\x6d\x1c\x55" + "\x9a\xdc\x51\x36\xe0\x6e\xb6\xcc" + "\xd9\xf7\xc8\x5a\x2d\x6d\x3b\x5b" + "\x22\x18\x08\x1c\xfa\x76\x75\x98" + "\x60\x36\x8b\x52\x3a\xd9\xf2\x26" + "\xa3\xa7\x72\x55\x3b\x67\x35\xac" + "\xa4\x75\x6e\x9d\xa2\x0f\x91\xa5", + .len = 80, + }, { + .key = "\xfc\xec\x3e\x94\x9e\x90\xf8\xb5" + "\x93\xe6\x97\x38\x23\x29\x36\x65", + .klen = 16, + .iv = "\xc9\xf8\xca\xe3\xd9\x64\xf0\x73" + "\x65\x48\xe9\xdf\x62\xd9\xe2\x2c", + .ptext = "\x07\x7d\x79\x17\x76\xe1\x7e\xc0" + "\x9e\x45\xf6\xa0\x60\x1b\x66\xc0" + "\xf0\xd1\x4e\x2d\x7f\xeb\xf3\xa7" + "\x17\x54\x61\x99\xc6\xf6\xb1\x4e" + "\xfe\x88\x88\x61\x3c\xa7\xe0\x75" + "\xe8\x29\x0b\x27\x7c\xae\xf4\x41" + "\xe9\x77\xa9\x30\x37\x7c\x16\xb9" + "\x6b\xb8\x13\xe7\xad\xc8\xa2\x48" + "\xaa\xb4\x71\x59\x38\x0d\xa7\x3e" + "\x38\x38\xdd\xb6\xc1\x09\x69\x4f" + "\x7b\x94\xe3\xd6\x48\x3f\xe2\x12" + "\x2a\x1c\x07\xb2\x61\x76\x3d\x83" + "\xd3\xaa\x3e\xe6\xb1\x38\x5a\x82" + "\x58\x1a\x74\x36\x75\x55\x4d\x51" + "\x6d\xcd\x05\x06\xfc\x5d\xde\x1a" + "\x1c\x27\x44\xe0\x28\x29\x0a\x67" + "\x41\x12\xf7\xf2\xf1\x53\x81\xa8" + "\x0e\x78\xd8\x8d\xe1\xb9\x26\xb1" + "\x88\xcc\x15\xa8\x99\xfe\x93\x39" + "\x08\x82\xd2\x5a\x4b\x09\x92\x5d", + .ctext = "\xf8\x67\x10\x0f\x73\x13\x15\x94" + "\xf5\x7f\x40\x3f\x5d\x60\x1a\x2f" + "\x79\xce\xc0\x86\x27\x96\x0d\xfd" + "\x83\x01\x05\xf8\x13\x47\xe9\x9e" + "\x9d\xe2\x14\x90\x75\xed\xd0\x92" + "\x6c\xc8\x74\x6e\x2b\xbd\xaf\xb8" + "\x7f\x60\x52\x75\x39\xcc\x24\xa7" + "\x15\xec\x79\x2f\x67\x5a\xce\xc4" + "\x13\x0a\x3f\x38\x4a\xe3\x99\x14" + "\xc8\x4e\x14\xbe\xd7\x16\x17\xc1" + "\xc9\xf4\xa8\x4a\x19\x04\x90\x48" + "\x81\x6d\x3c\x84\xce\x17\xdd\x27" + "\xe5\x1c\x0e\xd0\x51\x95\xea\x6f" + "\xb5\xc6\x28\x18\x0b\xe9\xe2\x5d" + "\xa8\x35\xde\x16\x7a\x4b\x26\x59" + "\x57\x38\xc8\xde\xa6\x9a\x0a\x63" + "\xcf\x92\x2f\x49\xb3\x68\xb3\x25" + "\xa4\x16\x61\xaf\xb4\xfd\x9e\xb3" + "\xf0\xb6\x7b\x53\xd1\x86\xca\x6a" + "\x1e\xf5\x92\x5d\x22\x0d\x0f\x70", + .len = 160, + }, { + .key = "\xbb\x0e\xce\xec\x8b\x28\x0f\xb0" + "\xbc\x75\x0a\xc8\x03\x2f\x62\xe8", + .klen = 16, + .iv = "\x78\x79\xce\x4f\xef\xce\x3c\x56" + "\x1e\x98\xf0\xdb\x0f\xea\x5b\x35", + .ptext = "\xfe\xfa\xac\xcf\xfc\xe7\xa9\x32" + "\x82\xcd\x3f\x11\xf7\xfa\xa3\x48" + "\x2e\x9d\xbe\x2f\xaf\xc4\xd8\x5e" + "\x65\x59\xac\x55\xce\xaa\xcf\x49" + "\xf2\xe7\xd2\xb4\x3a\x1d\x7a\xb9" + "\x3d\x71\x11\x09\x71\x74\x9e\xea" + "\x25\xd8\xdd\x4e\x26\xba\xe0\xe9" + "\xe9\x6a\x87\xbf\xb9\x7c\x7d\x30" + "\x2a\x1a\xdc\x1f\xcf\xd5\xf6\x89" + "\xf2\xcc\x1a\x9d\x59\x2a\x49\x40" + "\xf1\xfc\x88\x09\xf9\x97\x66\x0f" + "\x54\xf1\x7e\xab\xb7\x90\x39\xdd" + "\xba\x9c\x51\xda\x45\xce\x81\x58" + "\xdc\xa6\xb1\x5f\x1b\xa4\xba\x4f" + "\x22\xb0\x22\xa9\x39\xab\x58\x84" + "\xb3\xd4\x92\x3d\x82\x07\x08\x5e" + "\x6c\xa3\x5d\x32\x24\xe4\xde\x2a" + "\x38\x5b\xbd\x38\x84\x47\xc1\x7f" + "\xa6\xc2\xdf\x32\x32\x9b\xb8\x1a" + "\xcc\x87\x5d\x64\x91\x4e\xa8\xf8" + "\xb2\x2e\x71\x86\xa4\x12\xa5\x41" + "\x83\xa7\x12\x28\x97\xe8\x51\x00" + "\x69\x9c\x99\x8d\xee\x20\x57\x18" + "\xcb\x95\x33\xa2\x5c\xb0\xf8\x93" + "\x39\x59\x1b\x2e\x8a\xb1\xd0\x86" + "\x36\x06\xd2\xb6\xb5\x11\x04\xdd" + "\xf8\xae\x20\x06\x5a\x81\x70\x96" + "\xcb\x76\x58\xe0\x78\xaa\xe7\xce" + "\xb2\xea\xb8\xde\x98\xdd\x83\x63" + "\xa1\x11\xf3\x81\x90\xa8\x9a\xfa" + "\x55\xca\x6e\x15\x7d\x89\x79\xa9" + "\x17\x74\xd1\x53\xaf\xe4\xf8\x40" + "\x8c\x42\x8a\xab\xf8\x68\x74\xa5" + "\xc9\xf5\x2c\x18\xa5\xfd\xa6\x40" + "\xcb\xf2\xa5\xfb\xe3\xbc\x10\x95" + "\x7f\x2c\xeb\x19\xa9\x92\x69\x90" + "\xb2\xdf\xe0\x0f\xe8\xa4\x69\x7a" + "\x0c\x2b\x76\x04\xb5\x38\x3e\x5c" + "\x1c\x16\xb3\x52\x6f\x65\x80\x54" + "\xb2\xf3\x91\x3f\x2f\x2c\x03\x63" + "\xf5\x24\xa7\xbf\xda\x45\xd6\xd4" + "\xbd\x65\xb1\x92\xba\xcd\x60\x99" + "\xd9\x36\x89\xf5\xd7\xa3\x33\xde" + "\x25\x6a\x88\xee\x0c\xf3\x45\x52" + "\x10\x76\x04\xf7\x2c\xa7\xa6\xd0" + "\x27\x01\xa3\x20\xd3\x3c\xec\xdb" + "\xa4\x88\x6a\x78\x15\xd6\x8a\xc5" + "\xa5\x40\x69\x8f\x00\xad\x3a\xd1" + "\x26\x8b\x62\x5f\x0f\x28\xe6\x5a" + "\x07\xb9\xb2\x83\xc4\x34\xab\xad" + "\x86\x09\x75\xb0\x78\x04\x3f\xf5" + "\x2d\xad\x24\x9f\x23\x56\x19\x16" + "\xca\xfd\x2e\x7a\xd4\xfc\x55\x0e" + "\xe7\x44\x03\x3a\x56\x05\xbb\x51" + "\x2f\x7a\xb1\x21\x7a\x33\x17\xa7" + "\x04\x3e\x4c\xef\x0d\x1d\xb7\xd4" + "\xa8\xba\x4a", + .ctext = "\x4c\xc6\xca\x45\xd3\xd0\xc8\xc1" + "\x86\x55\xd5\x51\xe4\xc0\x40\xf1" + "\xe8\x60\xc7\xbd\x32\xe6\x58\x69" + "\x41\xe9\x26\x52\x7b\xf5\xa6\x38" + "\x05\x74\xc7\xd6\x8f\x64\xfa\x14" + "\xc2\x2d\x55\x7d\xc0\x58\xea\x60" + "\x6a\xa7\x2c\x79\x8b\x62\xaa\x49" + "\x09\xf9\xb8\xdf\xf3\x4f\x55\x32" + "\x91\xc3\xf4\x51\xb0\x76\xb5\xc6" + "\x4c\x9d\x8b\xa4\x62\x77\x00\x51" + "\x95\xbe\x19\xba\xea\xa1\x05\x87" + "\x05\xbf\xae\xe4\x92\x6b\x33\xd2" + "\x0c\xc1\x3c\x98\x4d\x59\xb8\xf4" + "\x98\x13\x2c\x37\x90\x1c\xb6\xa8" + "\xc0\x19\x8a\x98\x01\xba\x93\x9d" + "\x9c\x92\x9c\xb8\x07\x50\x6e\xbe" + "\xf4\x25\x96\x1e\x00\x3c\x54\xf6" + "\x33\x47\xa3\xb0\x68\xd4\xd5\xb7" + "\x86\x9f\xb7\x08\x7a\x44\x26\xc1" + "\x78\x9c\x6c\x05\x1f\x8a\x84\x28" + "\x43\x93\x19\x36\xee\x7d\x90\x25" + "\x34\x56\x84\x55\xd8\xea\x39\x97" + "\x91\x9a\x76\xe3\xbb\x16\xbd\x98" + "\x34\xc1\xbb\xd8\x6a\x5f\x62\x98" + "\xc3\x35\x4a\xf9\x2b\xb9\x92\xca" + "\x23\x89\x1f\x77\x12\x24\xe2\x95" + "\x00\x5d\xd8\x56\x06\xdc\xfa\x74" + "\x6d\x07\x65\xf5\xb1\x3c\xc3\x00" + "\x40\x34\x8a\x6b\x66\x8a\xa4\xdc" + "\x72\x9f\xf3\xda\xc3\xfc\x52\x71" + "\xe6\x67\xbd\x68\x29\x07\x6b\x32" + "\x82\xad\xf0\x99\x55\xbf\x7e\x04" + "\x1e\x2f\x88\x6c\x71\xeb\xd7\xc7" + "\x9e\x46\xa4\xdc\x22\x27\xb6\xbd" + "\xf1\xbf\x55\xfa\xaf\x0a\x35\x94" + "\x8b\xa3\xdd\x07\x5f\x4d\x39\x53" + "\x18\x0a\xee\x4c\xae\x24\x56\x83" + "\x8d\xfa\xd7\xf4\xa3\x03\x97\x80" + "\x38\x1e\xa8\x38\xf0\x96\xe7\x51" + "\xc4\x46\x9e\x4e\xd4\x6e\x5f\x5c" + "\x89\xc4\xb2\x31\x16\x7b\x10\x35" + "\xc5\xbf\xdc\x91\x93\x00\x88\xf6" + "\x0c\x42\x78\x99\x80\x53\x53\x24" + "\x1c\xf1\xf5\xc5\xc3\x48\xf8\xfe" + "\x78\x85\x14\x95\x73\xe7\xcf\x14" + "\xdf\x2c\x1e\xaa\x61\x61\x54\xac" + "\x2b\xe7\x57\x1f\xae\xd2\x6d\xa4" + "\xba\x88\x33\x1b\x0e\x8d\x9f\x8e" + "\x4b\x35\x1b\xe1\xbd\xb5\x5f\x7a" + "\xe7\x23\x5e\x22\xc1\x89\xab\x4b" + "\xce\x5d\xdc\xf4\x0f\x36\x8b\x82" + "\x31\xab\x51\x68\x39\x47\x8b\x98" + "\x60\x74\xff\xb0\xd2\x21\x1f\x12" + "\x92\xc9\xd1\x3c\x69\x04\x12\x12" + "\x2b\xc5\x49\xe5\x69\x98\x85\xf7" + "\x86\x5a\x9b\xa4\xbf\x0e\xe0\x71" + "\x68\x08\xf0", + .len = 451, + }, { + .key = "\xbb\x93\xa2\x64\x3e\x84\xa4\x1a" + "\x23\xfa\x12\xa5\x4d\x5e\x7e\xd6" + "\x94\x39\x1e\xa3\x68\x49\x87\xd8", + .klen = 24, + .iv = "\xb7\xd5\xb9\x09\x11\x3d\x5c\xcb" + "\x0b\xd5\x49\x24\xe1\xf3\x4c\x3f", + .ptext = "\x5f\x47\x28\x64\x01\x6b\xdc\x28" + "\x59\xbb\x25\xe1\xb1\x67\x44\x5d", + .ctext = "\xc6\x35\x7a\xbd\x1d\x38\x24\xf2" + "\xc7\x2e\xd6\xef\x4b\x76\xd8\x97", + .len = 16, + }, { + .key = "\x25\x7a\x7c\x23\x19\xa7\x1d\x0d" + "\x33\x0e\x06\x34\x5a\x0e\xf0\xfd" + "\xa8\x63\x72\x33\x12\x3f\xc7\xb4", + .klen = 24, + .iv = "\x4c\x9c\xd2\x6a\xe7\xd1\x5f\x7d" + "\xbd\x64\xac\xc7\x8e\x20\x28\x89", + .ptext = "\xeb\x67\x7a\x5c\x53\xc9\xc5\x6a" + "\x9d\xd5\x2b\xdd\x95\x2e\x90\x98" + "\xea\xe2\xa0\x25\x48\xf8\x13\xef" + "\xc1\x48\x2f\xb2\x71\x90\x8f\x2f" + "\x62\xc3\x24\x24\xad\xa4\x79\x7b" + "\xe2\x94\x3b\xc2\xaa\xa8\xf8\xdb" + "\xab\xff\x27\xf5\xac\x53\x69\xbb" + "\xfa\xcd\x0e\xca\x0a\x1e\xdb\x69" + "\x5f\xcb\x0a\x74\xae\xc8\x93\x9a" + "\x41\x49\xaa\xc9\x99\xd5\x89\xe5", + .ctext = "\xf7\xc2\xde\x82\xdb\x28\xf7\xb7" + "\xe6\x25\x8b\xb5\x31\xb9\x22\x15" + "\x69\xe6\xdb\x58\x97\x29\x02\x50" + "\xc2\xf4\x73\x80\x9d\x43\x49\xcd" + "\x48\xbe\x5c\x54\x7f\x5f\x60\xff" + "\xfd\x42\xbe\x92\xb0\x91\xbc\x96" + "\x3f\x0d\x57\x58\x39\x7d\x3c\x33" + "\xca\x5d\x32\x83\x4e\xc1\x7f\x47" + "\x35\x12\x5c\x32\xac\xfc\xe6\x45" + "\xb6\xdc\xb7\x16\x87\x4f\x19\x00", + .len = 80, + }, { + .key = "\x84\x1e\xca\x09\x74\xee\xc0\x3a" + "\xe8\xbd\x0f\x57\xb8\x16\xeb\x4f" + "\x69\x79\xa3\xca\x51\xf2\xde\x60", + .klen = 24, + .iv = "\xfc\xf0\x24\x08\xcf\x55\xa1\xd3" + "\xeb\xca\x26\xda\x55\x55\x71\x74", + .ptext = "\x53\x2d\xae\xad\x19\xcd\x3e\xf4" + "\xa4\x47\xb6\x14\xe7\xdb\x2b\x66" + "\x25\xc8\xad\x44\x9e\x62\x11\xc0" + "\x6d\x65\xf4\x96\xb1\x89\xfc\x60" + "\xeb\x56\x61\x09\xa7\x3a\xac\x84" + "\x5f\xd9\xbf\xbe\x9c\xa4\x16\xd1" + "\x5e\xad\x4c\x7a\xbe\xb9\xe1\xcd" + "\xd2\x97\x3a\x27\xd1\xb1\xe9\x65" + "\x77\xe1\x2f\x53\xab\x86\xbf\x67" + "\x60\xd6\xc5\xb0\xb9\x76\x27\x09" + "\x70\x48\x0b\x92\x78\x84\x99\x61" + "\xe1\x0a\x02\x74\xfd\xf6\xc1\xea" + "\xc1\x75\x21\x73\x6d\xd8\xff\x06" + "\x70\xe7\xd1\xd2\x85\x78\xe7\x76" + "\x23\x40\xf1\x74\x14\xe8\xc2\xe3" + "\x63\x63\x53\x65\x7c\x80\x0b\x59" + "\x8f\xbb\x3d\x52\x35\x59\xf3\xc7" + "\x56\xb4\xea\x0c\x4a\xd3\xdd\x80" + "\x3e\x3d\x06\x09\xda\x0f\xe3\xbd" + "\x21\x4d\x36\xe2\x98\x76\x4f\x19", + .ctext = "\x3e\x23\xf2\x14\x9f\x53\xe8\x64" + "\xd3\x4e\x6a\xbd\xa7\xad\xf9\xa3" + "\x80\x5f\x27\x75\x2e\xee\xcc\xda" + "\x72\x07\x41\x99\x1d\x37\x34\x3b" + "\x00\xfd\x35\x03\x06\xf3\xba\xd8" + "\xa8\xc0\x31\x0c\x7f\x96\x1f\xcf" + "\x46\x96\x4e\x38\x93\x90\xd0\xfc" + "\xca\x59\x1f\xe0\x5d\xc4\x9b\x48" + "\x8d\xd2\xb4\x29\x18\xfd\xad\x89" + "\x3a\xcf\x2f\xa2\x29\x59\xc6\xc5" + "\x91\x0c\xb7\xe5\x7a\x1e\xc7\xc1" + "\x07\x88\x90\xa1\xb3\xa3\x94\x41" + "\x56\x7e\x03\x6d\x3b\x90\x0a\x83" + "\xed\x40\xb4\xd7\x83\x61\xcd\xb5" + "\xf2\xb7\x83\xbc\x1a\x0a\x41\x6d" + "\xab\xca\xdb\xd8\xde\xd4\x4a\x76" + "\xf7\x3a\xe2\x35\x76\x3b\x6e\x8c" + "\xed\xc2\x37\xb4\x32\x9f\x71\x62" + "\x4e\x55\xdc\x42\xae\xc5\xb3\x80" + "\xd8\x04\x20\xf2\x85\x94\xe6\xb3", + .len = 160, + }, { + .key = "\xe0\xc1\xa2\x85\xa5\x06\x97\xe1" + "\x4b\xee\x98\x7b\x1e\x9b\x8b\xdf" + "\x44\xfb\x1a\x85\x86\x41\xa0\xd8", + .klen = 24, + .iv = "\x50\x88\xd3\x80\x22\x7f\x82\x5c" + "\x59\xfa\x8f\x16\x20\xc0\xdf\x26", + .ptext = "\x50\x26\xfb\x5f\x82\xa2\xe4\x96" + "\xe4\x41\x31\xe5\x96\x00\x4e\x3f" + "\x06\xde\x39\x81\x6e\xa4\x43\x1a" + "\xed\x48\xd3\x5c\x0f\xe5\x32\x93" + "\x02\x5a\x18\x9b\x5e\xeb\xb7\x23" + "\x92\x6b\xca\xaa\x7e\x20\x3d\xf8" + "\x92\xf1\x46\xf7\x20\x4e\x83\x5f" + "\x23\xbb\xb0\x29\x1c\x43\xd1\x36" + "\xb0\x0e\x09\xd6\x8e\x72\x69\x17" + "\x12\xd1\xc1\xc1\x0a\x04\x2f\xa4" + "\xbf\x19\xf0\x20\xe1\xbe\x98\xf9" + "\x7f\x57\xcf\x30\x4a\xf5\xb2\xbe" + "\xc2\xdc\x82\x42\xf8\xce\x34\xbe" + "\x2b\x9e\xbe\xf2\xf7\x6d\x56\x85" + "\x9a\xcc\x0a\xcd\x6f\xaa\x4e\x18" + "\xef\xee\xd0\x89\xa1\x24\xa9\x47" + "\xb3\xc8\x4b\x27\x25\x11\xd2\xf5" + "\x95\x19\x9b\x11\xf9\x81\x10\x21" + "\xd1\xc8\x53\xd9\xd8\xe5\x22\xcd" + "\x53\xa1\xfa\x5e\xc7\x4f\x14\x7c" + "\x3d\x9a\x6a\x59\xd4\x1d\xd4\xc9" + "\x22\x5f\x18\x7d\x54\x9f\x55\x97" + "\x36\xe3\xb2\xcc\x5f\xc8\x54\xf9" + "\x52\xf5\x70\xac\x76\x56\x45\x93" + "\xdf\xd3\x04\xa0\x1b\x32\xbd\x17" + "\xd8\x73\xd2\xab\xd7\xd4\x4d\x38" + "\xfc\x84\x8c\xd7\x4a\x09\x20\xca" + "\x1b\x45\x16\x59\x77\x70\xd1\x68" + "\xda\x4d\x58\xda\xad\x29\x2e\x5d" + "\xef\x81\x74\xee\xe9\xfa\x3a\x7f" + "\xbf\x7c\xeb\xa8\x60\x5c\xce\xf8" + "\x59\xec\xab\x29\xc8\x3b\x88\x02" + "\x85\x66\xc1\x6a\x3b\x5d\xf1\xd7" + "\x72\x66\xb5\x2b\x2d\x77\x11\xe2" + "\x44\x69\xe9\x5b\x1c\xb0\xca\x1a" + "\x0b\x05\x49\x6f\x10\x2b\x1e\xb1" + "\x80\x70\x18\xd4\xc0\x21\xbd\x99" + "\x6b\x0c\x91\x00\x69\x43\x9c\x1d" + "\x10\x28\x02\x49\x41\x4f\x19\x14" + "\x2b\x6f\xc6\x90\xb3\x40\x98\xd6" + "\x81\xff\xf4\xcb\x20\x6e\x83\xab" + "\xd9\x6f\x3c\x60\xb1\xce\x9d\xae" + "\x7a\x99\xd5\x8f\x6b\x82\x8d\x2e" + "\x70\xeb\x2f\x23\x9b\x0d\xc0\x02" + "\x85\x0d\xcc\x99\x2e\x7e\x69\xa3" + "\x23\x3f\xec\x39\x93\x69\x2c\xf6" + "\x6c\x8c\x08\x01\x52\x59\xed\x6a" + "\xd6\x54\x31\x15\x24\x6f\xd0\xb3" + "\xd1\xb6\x04\x16\xac\x7e\xbc\x09" + "\x1e\x0c\x74\xa1\x26\xaf\x5c\x5e" + "\x5d\x99\x5e\x98\x1f\xbb\x70\x29" + "\xad\x0a\x63\xdc\x6e\x8d\x19\x8a" + "\x07\x8f\x07\xa2\x8b\x6d\x38\xfe" + "\x7c\x5f\xcb\x19\x2c\xcd\x33\x86" + "\x8e\x8b\x20\xfa\x22\xca\x44\x98" + "\xa3\xe4\x77\xb8\xdc\x1f\x81\xad" + "\xca\x26\x20\xae\xd7\xb2\x66\x36" + "\x0d\x73\x2f\xe9\xd8", + .ctext = "\x9a\x22\xcb\xa9\x74\x3f\xf1\x3c" + "\x9c\xde\x15\xec\x22\x68\xfd\x90" + "\xef\xd6\x4d\x37\xf2\x07\xed\xfa" + "\x91\x02\x2b\x05\xb8\x22\x62\x99" + "\x80\xee\xb6\x5d\x5c\x72\x27\x3d" + "\xf8\x26\x38\x3d\x1c\x33\xd6\xb7" + "\x06\xac\x2b\xbd\xec\x87\x6a\xaa" + "\x23\x3d\x96\xee\xca\x6d\x47\xbc" + "\xc8\xa7\x28\xf2\x11\x90\x23\x2c" + "\xdc\x60\x28\xfc\x30\x4c\xe9\x32" + "\xea\x64\x10\xf5\xa7\x01\xad\x42" + "\x48\x8d\x3d\xd8\x57\x5c\x15\xf8" + "\x5b\x09\xdf\x63\xcc\x5d\x1b\xe1" + "\x77\x43\xca\x4d\x74\xec\xaf\x82" + "\xe3\x9e\x32\xef\xdf\x04\xbf\x65" + "\xa1\x63\x80\x28\x09\xb5\xfa\x3a" + "\xb1\xbe\x09\xd9\xc1\x22\x2a\x4a" + "\xa1\x72\x31\x0d\xdb\x09\xd4\x22" + "\x47\x73\x92\x60\xc0\x3c\x2c\x9b" + "\x7e\x3b\x83\xb9\x29\x17\x32\x3e" + "\x64\x85\xeb\xf1\x5c\xb8\x08\x43" + "\xd6\xc7\x95\x4c\xc9\x43\x93\x33" + "\x77\x0c\xf6\x83\x4b\xfb\xbe\xab" + "\xff\x90\x0a\xcf\x0d\xfb\xe6\x75" + "\x87\x57\xb4\xe4\x01\x12\x31\x1b" + "\x28\xc2\x1e\xaa\x38\x6a\xaa\x3a" + "\x6d\x83\x65\xf2\xa5\x13\xfd\x67" + "\x3e\x3f\xd1\x7a\x1b\x63\xad\xb4" + "\xb1\xfc\x46\x7e\xa0\xdd\xab\x21" + "\x06\x75\xb1\xe9\x49\xbb\xfa\xf3" + "\xea\x88\x6d\x08\x5d\xdb\xfd\x54" + "\x76\x85\xb7\x72\x8a\xe0\xfd\x67" + "\xcc\x73\x6d\xe4\x1f\x5c\xf3\x06" + "\x52\x94\x04\x05\x49\xe6\x9e\xe1" + "\xdf\xf3\x9c\xce\xde\x8f\xca\x72" + "\x6f\x1e\x4e\x4e\x8b\x3d\x00\x31" + "\xb4\x1a\x55\x0d\x8b\x53\xbb\x5e" + "\xc7\x8f\x98\x34\x88\xdf\x30\xd3" + "\xb4\x03\x09\x17\x5f\x36\xff\x02" + "\xc2\xa0\x07\xcd\x26\x97\x56\x74" + "\x5a\x90\xa6\xad\x47\x9c\xcd\x52" + "\x95\xab\x82\x2a\xe8\x22\xaa\xab" + "\xc9\x40\x05\x8d\x30\xc5\x41\xaf" + "\x54\xef\x7a\xc4\x9f\x7d\x07\x45" + "\x28\xdf\xdb\xf0\xf9\x4e\x56\x56" + "\x00\xac\x98\x40\x3f\x75\x48\x0c" + "\x09\xce\xe9\x68\xb9\x62\x9c\x00" + "\x70\x78\x04\xeb\xec\xef\x97\x71" + "\x0a\xc4\x87\x94\x6e\xd8\xd3\xef" + "\x4d\x1d\x15\x05\xf8\x39\xbf\x85" + "\x49\x55\xd7\x23\x52\x3d\x19\x50" + "\x05\x84\xab\x7d\x81\x8f\x9c\xd7" + "\x7f\x4a\x05\x5f\x3e\xa7\x04\x88" + "\x88\xfd\x4d\x1f\x00\x85\x4c\x7d" + "\x40\xec\xc3\xca\x86\xa2\x93\x59" + "\x57\xb2\xef\xdd\x7d\x03\xba\xc9" + "\x71\xdc\x4a\x02\xec\xc6\x79\x58" + "\x16\xce\x4a\x47\x6d", + .len = 461, + }, { + .key = "\xaa\x5b\x8d\xd6\x4b\x30\x23\x13" + "\xdc\xe4\x18\x46\x4e\xae\x92\x90" + "\x8b\xe9\x53\x37\x11\x21\x84\x56" + "\xe0\x6e\xb1\xd3\x97\x00\x16\x92", + .klen = 32, + .iv = "\xda\xfc\x19\xe8\xf6\x87\x17\x53" + "\xc8\x1f\x63\x68\xdb\x32\x8c\x0c", + .ptext = "\xd0\xe9\xdf\xe7\x03\x45\x2d\x16" + "\x6b\x6e\xcf\x20\xc2\x48\xe6\x2c", + .ctext = "\xfc\x9a\x78\xba\x8f\x08\xae\xa8" + "\x2f\x9a\x37\xe5\xbd\x2c\x04\xd8", + .len = 16, + }, { + .key = "\x11\xfc\x29\x85\xb9\x74\xb0\x65" + "\xf9\x50\x82\xf8\x62\xf0\x52\xb7" + "\xd9\xb4\xd2\x1c\x3c\x0e\x76\x5a" + "\x49\xdb\x7a\x4b\xbb\xf3\x26\xaa", + .klen = 32, + .iv = "\xb5\xfe\x51\x82\x64\x8a\x24\xe6" + "\xe1\x5b\x20\xe3\x54\x02\x62\xb3", + .ptext = "\x5f\xb2\x26\x33\xba\x4e\x8b\x98" + "\x1a\xc6\x96\x5d\x58\xa4\x78\x7f" + "\xcf\xe2\x14\xed\x06\xff\xbc\x3a" + "\x8f\x52\x3b\x96\x2e\x9d\x19\xfc" + "\x3e\xe5\x1a\xad\x51\x81\x08\xdc" + "\x17\x72\xb2\xab\x81\xf2\x35\x56" + "\x25\x4f\x7a\xae\xe5\xfa\x00\xca" + "\xcb\xdb\xdc\xf9\x38\xe8\xfe\xfa" + "\x3e\xf6\xb5\x70\x4a\xcf\x76\x90" + "\x06\x84\xd9\x1d\x7d\x05\xe4\x96", + .ctext = "\xa0\x03\x29\xcc\xfd\x82\xbd\x62" + "\x39\x1c\xc9\xe0\xc8\x69\x46\x45" + "\x31\xc8\x1e\x6b\x5f\x37\x97\xa2" + "\xcb\x93\x19\x4a\x02\x42\x09\x2a" + "\x85\x5c\x78\x43\xb5\xe1\x1b\x69" + "\x67\x08\x79\xa3\xd5\x2d\xcb\xd5" + "\x30\x3e\x9b\xf2\x1b\xa7\x0b\x72" + "\x5f\xe5\xf8\xd8\x40\x45\xab\x8e" + "\x8e\x14\xf6\x0a\x85\xc1\x41\x3c" + "\x88\x56\xf0\x7d\x4d\xfd\x7e\x0e", + .len = 80, + }, { + .key = "\xeb\xe8\xee\x96\x66\xd0\x6d\xb7" + "\x69\xcd\xa8\xb9\x8f\x1e\xab\x04" + "\xe7\xa6\xa4\xa8\x99\xfb\x9f\x05" + "\xcd\xbb\x95\xcb\xc8\x1f\xa5\x26", + .klen = 32, + .iv = "\x58\xd2\xa1\x32\x73\x03\xcc\xb5" + "\x1b\xb9\xe2\x0d\x84\x66\x59\x67", + .ptext = "\x79\xc0\xe7\x32\xfc\xcc\x44\xd4" + "\x2d\x3b\x31\x9b\x6d\xfa\xb9\xf6" + "\xc2\x05\xb7\xe5\x7d\x7c\x98\xae" + "\x1b\xf8\x62\xd2\x6a\x1f\xf5\x3f" + "\xed\x76\x92\xc7\x80\x77\x99\xd1" + "\x3f\xe4\x97\x4e\xa5\x5a\x7f\xef" + "\xf1\x29\x38\x95\xce\x63\x58\x0a" + "\x32\x33\x30\xee\x87\x70\x08\xf4" + "\x09\x72\xab\x4e\x6f\x25\x27\x65" + "\xcd\x5b\xce\xce\xb9\x67\x80\x79" + "\xad\xe7\x2d\x2c\xac\xe1\x95\x30" + "\x28\x12\x52\x4b\x24\x82\x19\xee" + "\x96\x5c\x3d\xae\x0f\xfd\x74\xf8" + "\x9d\x4b\xde\x01\xf1\x48\x43\xfd" + "\xbd\xe7\x9d\x91\x60\x1e\xd6\x8a" + "\xc5\x3c\xd2\xcf\x88\x7d\xb0\x94" + "\x5b\xdb\x4d\xd1\xa9\x28\x0a\xf3" + "\x79\x5a\xd0\xd1\x94\x26\x51\xe1" + "\xea\xd0\x90\xac\x32\x41\xa3\x7f" + "\xd1\x5a\xb7\x64\xfd\x88\x56\x50", + .ctext = "\xca\xdd\x51\xe5\xbf\x4a\x97\x8f" + "\x79\x7a\x1c\x0a\x63\x0b\x2f\xc4" + "\x67\x40\x0d\x77\x44\x30\x3c\x87" + "\x3d\xbe\x2b\x52\xb1\xe3\x13\x7c" + "\xd3\x6b\xa5\x23\x2a\x5e\xd3\x32" + "\xb0\x2f\x20\xad\x25\x76\xba\x76" + "\x2e\xc1\x66\x18\xec\x4e\xc8\x1a" + "\x33\x4b\x20\x1a\x0a\x24\x41\x38" + "\x5c\xb9\xa9\x33\x5e\x91\x4f\xcd" + "\x1e\x00\x0b\x8c\x61\x04\x07\x7f" + "\x57\x4c\x21\xc0\x61\x82\x57\x1d" + "\x69\x34\xa4\x7b\x93\xf2\x7a\x86" + "\xd2\x0b\x0b\x7b\xa6\xac\xbb\x7b" + "\x0d\x56\x24\x31\x0a\x82\x81\x58" + "\xc1\xf3\x36\xca\x04\xa0\xfa\x01" + "\xa6\x45\x1f\x0e\x87\x69\x33\xe5" + "\x4c\xdc\x32\x89\x4a\xb2\xd3\x9b" + "\x23\x2c\x30\x16\x38\xab\xe0\xbf" + "\x50\xce\x33\x34\x45\x88\xd0\xa7" + "\x31\xbf\x31\xdb\x42\x7f\xe2\x76", + .len = 160, + }, { + .key = "\x67\xeb\x2d\xe3\xb7\xe6\x21\xe2" + "\x1a\xff\xcf\x73\xaa\x2a\x9d\x22" + "\xa0\xfe\xad\xaf\x1e\xb1\xaf\x63" + "\x1b\xb9\x84\x84\x8c\xe3\x89\x0e", + .klen = 32, + .iv = "\xf6\x4f\x72\x0c\xd9\x13\xc3\xe3" + "\x16\x15\x0f\x30\x4f\x78\xe7\x98", + .ptext = "\x95\x39\xa2\x67\x68\xf3\x01\x53" + "\x67\xbc\x20\x3d\x39\x4f\x05\xab" + "\xc9\xcd\xa0\x14\x4a\x34\xfb\x07" + "\xd4\x86\x39\xcb\x54\xab\x13\xee" + "\xec\x00\x33\xc4\x85\x15\x40\x5d" + "\x29\xe0\xce\xea\x7e\xfa\x76\xd0" + "\x03\x0f\xad\xcc\x48\x6a\x68\xcc" + "\xd6\x8c\x90\x8a\x53\x9b\xb2\x0d" + "\x77\xd2\x36\x42\xc7\xe7\xff\x64" + "\xeb\xa4\x27\x18\xf4\x45\x8a\x98" + "\x33\x59\x18\x23\xf7\x43\x0b\xde" + "\x84\x58\xfe\x65\x2c\x5b\xa3\xa7" + "\x3c\x64\x27\xf9\x94\xdb\xdb\x4e" + "\xf4\xd7\x32\x54\x04\xf8\x29\x37" + "\xda\xad\x86\xff\x73\x7b\x9a\xa8" + "\x0f\xa9\x91\xbe\x03\x49\xff\xd6" + "\xb7\x0b\x8b\x0a\xd3\x3d\x40\x1a" + "\x58\x85\x26\x0f\x78\x93\x58\xba" + "\x9c\x9c\x3c\xa4\xcd\xe2\x6a\x6f" + "\x45\x0e\x16\x85\xc5\xe5\xf8\xae" + "\x6a\xc7\x11\x7e\x39\x77\xae\x62" + "\xe0\x46\x2a\xad\x21\xaf\x8a\x73" + "\xf7\x5b\xf4\xf0\xfb\x2e\xec\x48" + "\xb1\x35\x9a\xf8\x6f\x50\x8b\xad" + "\xe2\xfb\x16\x92\xe6\xee\x2f\xf8" + "\x8f\xb4\x13\xc1\x84\x4e\x63\x4b" + "\x56\x38\xf5\x3a\x1b\x9b\x71\xb9" + "\x1b\x98\x26\xe4\xd4\x80\xe0\xfc" + "\x2a\xce\x15\x4e\xe3\x14\xe1\x14" + "\xe7\xfa\xb2\xa8\x23\x42\xe1\xb8" + "\x2f\xce\x12\x9b\x4a\x8e\x0e\x72" + "\xce\x61\x4a\x5b\x21\xa4\x42\xdc" + "\x25\xf7\xa9\xb8\xea\x7e\xa0\x4a" + "\xf3\xce\xf8\x6b\xa0\x98\x50\x4f" + "\x4a\xb1\x1e\x65\x88\x66\x78\xce" + "\x37\x34\xe0\x9d\x1d\x33\x0a\xa8" + "\xb8\x93\x31\x7d\xbd\x59\xea\xa1" + "\x96\x91\xd7\xe6\x0e\x90\x5d\xc4" + "\xb0\x5d\x81\xf8\xf1\xb4\xa3\x3f" + "\x32\xa1\x7c\x26\xf0\x72\xe7\xc2" + "\xac\x3f\x65\xfe\x6f\xab\x98\x3d" + "\xd0\xd7\x86\xd3\x38\xcd\x43\x2e" + "\x44\xd9\xbd\x80\xab\x19\xa4\x4b" + "\xb6\xa7\x04\x47\x3b\x2c\xb3\x73" + "\xc0\xca\xa8\xdd\x36\x7d\xca\xa9" + "\x6b\x5a\x78\x0d\x8b\xb7\x91\x14" + "\x59\xfd\xe7\x10\xca\xcd\xc4\x3b" + "\x35\x36\x96\x56\xc7\xff\xd5\x67" + "\xfe\x75\x79\x1e\x39\xb1\x48\xfc" + "\x4f\x9d\x64\xea\xc5\x65\x74\xa1" + "\x4e\xef\x41\x6e\xc9\x50\xd8\xab" + "\x9a\x0e\x05\xdc\x0e\x4d\x4f\x6e" + "\x57\x93\x5e\xa6\x79\x54\x27\x41" + "\x41\x65\x2f\x97\xc8\x87\xeb\xb5" + "\x0e\x0d\xc1\xeb\xa9\x12\xd6\xdb" + "\xa0\xcf\xad\x6b\xad\xe5\x3c\x41" + "\xc5\x23\x26\xcf\x74\xa7\xb8", + .ctext = "\x24\xed\xac\x16\x7c\x43\x1d\xd5" + "\x3a\xe1\xdb\xa4\x63\x0e\x81\xd6" + "\x49\xd1\xdf\xde\xbb\xa3\x58\x4e" + "\x6f\x9c\x44\x41\xb2\x8d\x28\xd2" + "\xf2\x5d\xac\x21\x8b\xda\x42\xbd" + "\x3a\x99\xfb\x47\x5d\xdb\xa3\x4c" + "\x78\x65\x5d\x2b\xe0\xd8\xe0\xc8" + "\xd0\x86\xf0\x5e\xd6\xe8\x87\xc6" + "\x03\x1e\x83\x5f\x2c\x8b\x42\xec" + "\x34\xc2\x15\x63\x98\xc0\xef\x4a" + "\x3d\x43\x55\x12\xa0\x9a\xaf\x82" + "\x04\xc0\x02\x24\x6b\xec\x1d\x6d" + "\xda\x0f\x0b\xda\xa5\x81\x66\xc1" + "\x4f\xa5\x12\xac\x33\xd2\xd4\xcf" + "\x6d\x55\x9a\x06\x0a\xf8\xbf\x5f" + "\xf5\x5f\xf7\xff\x9b\x48\x00\xed" + "\x1b\xba\x0d\x30\x18\x41\xb5\xe7" + "\x7e\xe1\xc2\x42\xfd\xb5\x8d\x56" + "\xbb\x3d\x7c\xe5\xaa\xfe\x42\xcf" + "\x62\xf8\x7e\xa1\x54\x37\xaa\x4e" + "\xe9\x52\xb3\x49\x50\x72\xd0\xe4" + "\x57\x02\xd0\xd7\x4d\xd6\x12\x2a" + "\x79\x15\x7e\x9c\x7c\x66\xd0\x5d" + "\xec\x37\x7e\xab\xaa\xd7\x88\x1e" + "\xeb\x8e\x75\x33\xa4\xfe\xb6\x6f" + "\x4b\xfb\x32\xa5\xfb\x9b\xb6\xe0" + "\x3f\x1c\x43\x8c\x83\x95\x18\x20" + "\x02\xf5\x2d\xa4\x19\x5f\x48\x3e" + "\x48\x32\x43\x04\xfb\xe8\x58\x23" + "\xa0\x69\x57\x81\x06\xb5\x81\x4f" + "\xf4\x11\x80\x18\xfe\x41\x67\x3c" + "\x13\x22\x5e\x9f\x4b\x30\x8c\x73" + "\x2e\x3c\xc1\x06\x59\x71\x66\xef" + "\x47\x2d\xb4\xf3\x49\xf5\xb6\xc8" + "\xf4\x2f\xb3\x2d\x7d\xbb\x14\xd1" + "\x41\xa0\x61\x03\x1f\x94\x08\x0c" + "\xa5\x72\x4e\xf9\xe5\x45\xf1\xea" + "\xed\x4c\x7c\x1a\x72\x34\xb7\xd7" + "\xd3\x63\x1f\xc9\x18\xde\xc4\xf1" + "\x35\x55\xe1\xbb\x2a\x04\xe7\x38" + "\xf6\x0e\x40\xf6\x04\x01\x85\x07" + "\xa0\x4f\x7e\x71\x82\x67\xd7\x66" + "\xe4\x7a\x57\xfb\xda\xbb\x3a\xa8" + "\xa5\xdd\x0d\x61\x27\xcb\xe6\x28" + "\xb3\x04\x02\x7d\x8a\x17\xa4\x52" + "\x50\x4e\x65\x39\xa0\x50\x3c\x6c" + "\x1b\x9e\x12\xad\xfa\x82\x60\xa0" + "\x04\x9e\xc7\x91\xf6\xdb\xf5\x1a" + "\xa1\x5a\x56\x2c\x9c\xb4\x69\x11" + "\x57\x71\xb4\xb6\xf4\xd2\x62\x1c" + "\x33\xa6\x67\x0b\xc8\x68\x43\x49" + "\xef\xac\x38\x7b\xe5\x4c\xb6\xe6" + "\xb5\xb3\x5b\xcf\xd1\x72\x2d\x4e" + "\x19\xf6\xec\xb0\xa8\x6d\x1d\x40" + "\x8e\xe2\x74\xc2\x56\x2c\xa1\xae" + "\x52\x42\x5d\x06\x29\xee\x52\x74" + "\x00\x51\x37\x3a\xf6\x9d\xd0", + .len = 455, + }, +}; + +static const struct cipher_testvec lea_xts_tv_template[] = { + { + .key = "\x13\x1d\xbb\xbf\xf9\x7d\xcc\x8c" + "\x82\x99\x52\x1d\xaf\x04\x1a\x0a" + "\x75\x36\x73\x96\xc5\x4f\x9e\xac" + "\x8a\xf0\xef\x06\x49\xc8\x7c\x0a", + .klen = 32, + .iv = "\x03\xb2\x44\xdf\x7b\xa4\x34\xd1" + "\x19\xa6\x30\x9d\x91\xc5\x65\x3b", + .ptext = "\x31\xb7\x63\x5b\x36\x2f\x93\x86" + "\xcc\xe7\x56\xf3\x3a\xed\x64\xd1", + .ctext = "\x36\x53\x37\xbd\x47\x42\x5c\xe7" + "\xf9\xc4\x0a\xfc\x38\x70\xdb\x93", + .len = 16, + }, { + .key = "\xf3\x9c\x37\xe3\x80\x12\xff\xd7" + "\x7b\x09\xd5\xd6\x9a\x0b\xf1\x37" + "\x43\xe7\xef\x84\x91\xa9\xeb\x08" + "\x06\xf0\x99\x7c\xc4\x8b\xbc\xa9", + .klen = 32, + .iv = "\x23\x66\x4c\xe3\x08\xfa\xdc\x21" + "\x18\x0e\xac\xd0\xbc\x20\x20\xdd", + .ptext = "\x51\x27\x06\x5b\x8e\xaf\x6b\xf4" + "\x73\x89\x16\x60\x6a\x6a\xfa\x80" + "\x7a\x26\x99\xce\x18\xb2\x96\x25" + "\xf1\xec\x37\xb4\x1d\x6b\x2b\xfe" + "\x81\xeb\xef\x12\x2c\xe5\x10\x6a" + "\xe5\x03\x00\x65\x34\xe0\x1e\x2a" + "\x6d\x0c\xb8\x4b\xa5\x74\x23\x02" + "\xe7\x48\xd3\x0e\xc9\xeb\xbf\x49" + "\x64\xd9\x92\xcf\x29\x43\xb7\x33" + "\x11\x4c\x9b\x76\x94\xaa\x17\x8c" + "\x9d\xa9\x13\x05\x83\x10\xce\xb5" + "\x48\xa8\x02\xae\x93\x7c\x61\xba" + "\x68\xf8\xf2\x5f\xcd\x7c\xfd\xb6" + "\x06\x28\x1e\x52\x02\x25\x7f\x7a" + "\x84\x31\x62\x2a\xbb\x5a\x3c\x25" + "\x1e\x8f\x46\x32\x52\x8d\x94\x7d" + "\x35\x4e\xfd\x01\xa4\xc7\xd1\x8a" + "\x12\xf9\x05\xfd\x31\xac\xfa\xd3" + "\x18\x71\x3a\x3b\xe2\xfa\xac\xec" + "\x04\x94\x29\x07\x77\x17\x0a\x30" + "\x0d\xd7\x6c\x99\x64\xb6\x48\xe1" + "\x32\x1f\xe7\x76\xb4\x93\x39\x6f", + .ctext = "\xe2\x08\x85\x96\xd5\xcd\x2b\xd0" + "\xb0\xff\xa4\x54\x78\x04\xcf\x5a" + "\x59\x56\xf6\xd8\x8a\x9a\x04\x98" + "\x72\xa3\xe1\x68\x84\xee\x4a\xa1" + "\x0e\x39\xc0\x77\x4f\x69\x1d\x8b" + "\x0f\xcb\x1d\x98\xd3\xa0\xc2\x81" + "\x7d\x7f\x51\xbf\x6e\x1b\xd1\x73" + "\xd5\x68\x72\x72\x1c\x21\x78\x37" + "\x59\x11\x30\x59\x46\x9c\xd3\x0e" + "\x2f\x66\x56\x5c\x4b\x43\xd7\xa3" + "\x85\xce\x32\xc1\x36\xdf\x7b\x3a" + "\x24\x80\xd5\x51\x3a\x84\x71\x8f" + "\x49\x6c\x05\xc5\x06\xa5\x13\xaa" + "\x8c\x32\xe2\x61\xd8\xae\x26\x23" + "\x2f\x32\x94\x92\x5f\x37\xd9\x05" + "\x32\xb6\x34\x29\x3e\xae\xd7\xfa" + "\xa7\x4b\xd6\x7a\x71\x00\xc7\xf0" + "\x91\x17\x18\xf8\x0f\xa7\x41\x86" + "\xb3\x0f\xa2\xd0\xd9\x3c\xf3\x2b" + "\x0e\x0b\xd8\x7f\xdc\x51\x1f\xf8" + "\xbe\x42\x41\x3d\x53\xdb\x1e\x6f" + "\x91\x7a\x4d\x56\x70\x5a\xd9\x19", + .len = 176, + }, { + .key = "\x39\xa1\x40\xca\x04\x1f\xab\x0d" + "\x30\x9e\x6d\x2b\xf3\x52\x06\x87" + "\x9f\x5b\xd8\xdf\xac\xf6\xcd\x48" + "\x7b\x6d\xfd\x78\x06\xa5\x2d\x85", + .klen = 32, + .iv = "\x14\x6c\xdf\xce\x8a\xa1\x78\x42" + "\xbe\xad\xb0\xc9\xcc\x45\x8b\x1c", + .ptext = "\x9d\xea\xc3\xbd\xa6\x57\x82\x4d" + "\x02\x6e\x38\x09\x2e\x92\xd4\x93" + "\xe2\x70\xc9\x52\xe3\x64\x3c\x17" + "\xa8\x33\x92\x07\x53\x1f\x23\xc2" + "\x94\x8a\x22\xe6\x22\xd6\x31\xee" + "\xce\x9f\xbb\xa1\xb5\xdf\x99\x26" + "\xae\x23\x7f\x77\xd8\xa6\xec\xcd" + "\x91\xa6\x08\x24\x88\x7f\xf2\xee" + "\x30\x27\xff\x4b\x4d\x06\xd4\x6c" + "\x97\x85\x2e\x87\x5f\x7f\xcc\xda" + "\x7c\x74\x7e\xaa\xf7\x53\x20\xbe" + "\xf6\x51\xe4\xeb\x24\xde\x1d\xa6" + "\x9b\x4d\xca\xdc\xdd\x0e\xeb\x2b" + "\x9b\x07\xfd\xa3\x6d\xa9\x9a\xb5" + "\x0b\xe2\xf9\x72\x69\x90\xec\xf7" + "\x7b\x17\xdc\x8d\x4f\xf3\xaf\xed" + "\xf6\x6a\xdc\x19\x39\x82\xe2\x84" + "\x7b\x4c\x5f\x7e\x3e\x55\x8b\x11" + "\xdc\xe7\x11\x5a\x52\x02\xe4\xd7" + "\xf7\x90\xd7\xdf\x94\xf1\xe4\xd5" + "\xe4\x49\xe8\x19\x33\x22\x66\x19" + "\xc6\xf5\xdc\xad\x7c\xf0\xf3\xea" + "\xe2\xa4\xa2\x57\x53\x28\x28\xb5" + "\x32\x6b\xfc\xa2\x86\xee\x8e\x0a" + "\x25\x76\x20\x94\xff\x50\x73\x5d" + "\x2c\xb4\x66\xd2\x59\x95\xa0\x37" + "\xc4\x96\x47", + .ctext = "\xc0\x48\x1b\xcf\x4a\xbd\x7b\xb2" + "\x18\xe8\x2a\x31\xaf\x7f\x7e\x3f" + "\x7f\x79\xc7\x03\x4b\x24\xc8\xfb" + "\xaa\x8b\x6b\x4d\x51\x80\x95\x60" + "\xb2\x9c\x3b\x80\xf3\x23\x93\xd3" + "\xef\x55\xc3\x9b\xae\xa0\x13\xe0" + "\x36\x6f\x4e\xc8\x06\x99\x12\x81" + "\xf2\x70\x28\x42\x8f\x00\x79\xb2" + "\xb9\x7d\xfe\x3a\x6a\x45\xea\x1d" + "\x83\x8e\xbc\x07\xf3\xaf\x73\xb9" + "\xbd\x6c\x40\x59\x43\xc2\x54\x2a" + "\xb2\x9e\x06\x52\x7f\x35\xf9\xdf" + "\x7e\xa0\xf9\x27\x2d\x0d\xb7\x6a" + "\x5e\x17\xf5\xf3\x26\xc1\xd0\x0c" + "\x1b\x57\xbe\xf3\xf0\xa0\xe4\x36" + "\x7b\x5b\x0f\xc1\x47\xac\x96\xa1" + "\xd9\x01\xac\xf3\x2a\xa2\xc2\x6e" + "\x82\x83\x00\xff\x5d\x57\x98\xac" + "\x8b\xaa\x05\xcd\xe9\x08\x90\xd6" + "\x21\x84\xd1\x33\xd0\x2b\xc4\xa7" + "\xe9\x59\x4f\x2f\xb4\x19\x97\x7c" + "\xe4\x2d\xe9\x02\x7b\xb3\x58\xf6" + "\xab\x5a\x33\xfa\x53\xc7\x61\xc7" + "\x71\xc6\x0f\xdc\x3e\x18\x6c\xe8" + "\xb8\xd2\x21\x15\x1e\x82\x20\x69" + "\xf2\x92\x7f\xa4\x64\xb9\xf4\xa5" + "\x61\x3b\xb9", + .len = 211, + }, { + .key = "\xae\xf5\x94\x42\xea\x02\xeb\x8f" + "\x41\x74\x00\x8c\x55\x12\x72\x5f" + "\x0d\x4e\x9d\x3a\x90\xb7\x73\x0c" + "\xc8\x93\x59\x07\xe8\x95\x8c\x86" + "\x99\x76\xeb\x5c\xd7\xc7\xf0\x2f" + "\xac\x5e\xa0\x75\xd2\xbf\xa7\xb6", + .klen = 48, + .iv = "\x78\x38\x47\xb2\x56\x55\x3d\x82" + "\x93\x7e\x34\xd7\xc2\xe6\x0c\x66", + .ptext = "\xd4\x7b\x83\x78\x74\xba\xd9\x5b" + "\x27\x61\x31\x74\xa4\x00\x03\x59" + "\x61\xc9\x23\x2e\xcb\x3d\xaf\xf5" + "\x3d\xa5\x2a\x02\x7d\x12\x11\x6e" + "\xec\x59\xfd\x95\x93\x59\x5e\x68" + "\x9e\x9d\x10\x74\x96\x9a\xac\x51" + "\x4b\xd3\x91\xaf\xbe\x33\x78\x3a" + "\x77\x61\xd8\x24\xa8\xfd\xbf\x2e" + "\xd8\x45\xee\x53\x2e\x91\x22\x0e" + "\x43\xe6\xb7\x2a\x1c\xb6\x1a\xd4" + "\x74\x46\xfd\x70\xcf\x42\x5e\x4f" + "\x4e\xd8\x4e\x91\x75\x2e\x6d\x02" + "\x7a\xf2\xdb\x69\x43", + .ctext = "\x48\xda\x19\x0e\x4c\xa5\x9d\xc4" + "\xa5\x34\x37\x81\xde\x1b\x8c\x61" + "\x5c\x70\x92\xf6\x66\x28\x88\xe4" + "\xa2\x36\xc9\x66\xcf\x85\x45\x56" + "\x2d\xbc\x44\x19\xe9\x75\xec\x61" + "\xbb\x1a\x11\xdf\x3c\x2b\xa4\x49" + "\x80\xdd\x3b\x6e\xd3\xd4\x29\xd2" + "\x01\x11\xf8\x2f\x83\x96\x60\xef" + "\x9d\x33\xc5\xde\x5e\x48\x10\xaf" + "\x02\x47\xda\x91\x88\x2a\x9f\x44" + "\x31\x68\x73\x1b\x12\xc0\x91\xc4" + "\xc1\xdd\xf3\x43\xba\x05\x66\xb6" + "\x04\x4e\xea\xea\x1f", + .len = 101, + }, { + .key = "\x3f\xa4\x4e\x46\x47\x13\x19\xbe" + "\x8b\x5b\xea\xcb\x8f\x0f\x55\x19" + "\xaf\xea\x38\x15\x9a\x9f\xa1\xda" + "\xb1\x24\xb9\x45\xfb\x1e\xa7\x50" + "\xff\x25\x21\x65\x17\x34\xab\xec" + "\x72\x65\xc2\x07\x7c\xbe\x6f\x65" + "\x51\x57\x9e\xd2\x88\x43\xbc\x9e" + "\x44\x9b\x54\x4a\x3d\x4a\x8c\x40", + .klen = 64, + .iv = "\x71\x60\xda\x95\x7b\x60\x1d\x7e" + "\x96\x0c\xca\xe9\x47\x58\x1b\x54", + .ptext = "\x10\x1b\x67\x8f\x11\xf6\xf9\xcd" + "\x1d\x72\xa7\x1a\x55\x82\xb4\xef" + "\x16\x53\x05\x4a\xa7\xa8\x02\x82" + "\x07\x33\x6a\x63\x45\x55\xac\x51" + "\xa3\x44\xbd\x6c\x9b\x56\xb3\xef" + "\xab\x45\x6b\x0a\x18\xf0\xe8\x35" + "\x3d\x19\xb9\xd2\x7e\x46\x37\x04" + "\x2e\x3b\x3c\x0d\xd8\xcf\x25\x4a" + "\xd7\x63\xeb\x74\xa9\x5a\x95\x4c" + "\x9f\xfb\xe3\x5f\x9e\x41\x14\x03" + "\x48\x8b\xde\x0c\xe6\x70\xd0\x22" + "\x07\xd5\x7f\x88\x8b\xcc\x5a\x12" + "\x9d\xfb\xa6\x84\x97\x3e\xad\x44" + "\x3e\xfa\x3c\xd0\x99\xb0\x0c\x6b" + "\x32\x57\x73\x4a\xfb\xc7\x8d\x01" + "\xe7\xdd\x7c\x7e\x53\x80\xe3\xbb" + "\xdc\x39\x73\x4a\x6f\x11\x3e\xa1" + "\x33\xfa\xb9\x5a\x63\xc7\xdd\xe7" + "\x9d\x00\x89\x6c\x8b\x2c\xc6\x0c" + "\x51\xa4\x29\x80\xae\x97\x67\x7f" + "\xc0\x30\x8c\x5c\x00\xb3\xc9\xe7" + "\x90\xf5\x26\xb7\x55\xad\x5b\x5e" + "\xaf\xf7\x6a\xc8\x22\xc0\x08\x9f" + "\x09\xd0\x8c\x77\x5a\xad\x7c\x2c" + "\xc2\xd7\x3c\x76\xc9\x08\xbd\x83" + "\x09\xf2\xcc\x65\x7a\x84\xf2\x49" + "\x04\x69\xd2\x1c\x72\x01\xec\xa8" + "\xf8\x58\x2a\x65\x4a\x12\x3d\xfe" + "\x82\x4f\x02\x97\xb6\x9e\x54\x8c" + "\x79\x43\x23\x6c\xc4\x67\x33\xce" + "\x37\x4e\xfe\x0f\x66\xa7\x16\x1c" + "\xba\xbf\x75\x2c\x74\x30\xcd\x9c" + "\x34\x04\x5f\x44\xac\x06\x0a\x9f" + "\xe3\x68\x92\x4f\x20\x89\x35\x82" + "\x2e\xe9\xdc\xbf\x79\xc3\xb8\x9b" + "\x18\xe2\xaa\xed\xa4\x6b\xd3\xe7" + "\xb7\xfb\x8a\x10\x7a\x23\x1d\x5b" + "\x89\xa3\xe9\x26\x0e\x31\x3a\x4d" + "\x99\xee\x14\x1b\x4c\x90\xf5\xf3" + "\x70\xeb\x78\x9d\x6a\x20\xb9\x60" + "\x3e\x24\x42\xd0\x62\x93\x94\x4e" + "\xbb\x21\xce\x0e\xcc\x4c\xd7\x04", + .ctext = "\xf2\x90\x24\x8d\xba\x6f\x31\x5c" + "\x3e\x5a\x2d\xf1\x72\xe0\x99\x17" + "\xf9\x9e\xf9\x3e\x6c\x8e\x43\xd9" + "\x41\xbe\x74\x94\x4d\xf9\x73\x7d" + "\xe0\xa6\x62\xd1\x9e\x27\x80\x7d" + "\x40\x4c\x92\x50\xe9\x4e\x6b\x67" + "\xa7\x48\x8c\xd5\xcf\x4b\x2b\xe8" + "\x8c\xd5\x90\x7e\x52\x83\x36\xd6" + "\x20\xf5\x78\x31\xeb\x65\x55\xc7" + "\x49\x9c\x7a\xe3\xa8\xad\xe3\x6a" + "\xc2\x3d\xbc\x45\x2f\x8f\x6a\xc1" + "\x61\x9c\xbb\xf9\xe7\x1d\x06\x94" + "\x49\x36\x77\x95\x52\xfa\x3a\x2c" + "\x92\xf3\x77\x38\xbe\xf2\x54\xe9" + "\x5d\x1c\x9e\xc8\x5a\x29\x24\x1f" + "\x3c\xbc\x71\x5e\x73\xdb\xf6\x22" + "\x27\x6d\xe7\x18\x82\xb1\x51\x1c" + "\xdb\x50\x58\xd3\xf5\xf2\xb1\x7f" + "\x67\x71\x67\x01\xe0\x23\x04\xfc" + "\x91\x81\x04\x75\x55\x7b\x01\xc8" + "\x21\x57\x60\x61\x38\x2c\x42\x9a" + "\x9e\xd3\xd7\x16\x2c\xe6\x7e\xe6" + "\xdc\x3c\xbe\x31\x77\x0d\xc4\xfe" + "\xa3\x69\x05\xdf\x70\xe8\x44\x48" + "\x69\x40\x56\x64\x0c\x1f\x72\x89" + "\x15\xb8\xbd\x10\x2a\x75\xb8\x1b" + "\x42\xcc\x75\x50\xc7\xe6\xcf\x13" + "\x2e\xda\x18\x36\x6f\x41\xd7\x14" + "\x2d\xb6\x6d\xce\xe3\x38\x9a\xd0" + "\x14\x94\x4c\x93\xd3\x11\xcc\x59" + "\x6e\x2c\xb1\xf5\xa0\x6c\xec\x9b" + "\xcc\x5c\x26\xbe\x5f\x90\x9a\xb1" + "\x97\xea\x33\x1e\x6c\x91\x57\x7d" + "\xd7\xf8\x4f\x93\x62\xec\xb6\x18" + "\x65\xe3\xe2\xfe\xd7\xb0\xf1\xc1" + "\xea\xa1\x98\xe9\x0a\xd8\x05\x79" + "\x7b\xb5\x85\xd0\x5b\x71\xbc\x77" + "\xd2\xb5\x8f\xb9\xd8\xdf\x50\xc1" + "\xe7\x1d\xe6\x73\x11\xf5\x99\x0d" + "\x91\x18\x92\xef\xe2\x33\x97\x03" + "\x65\xbd\xf4\xe4\xab\x55\x71\x7c" + "\xa2\xb6\xce\x1d\x48\x3d\x65\xa7", + .len = 336, + }, +}; + +static const struct aead_testvec lea_gcm_tv_template[] = { + { + .key = "\xa4\x94\x52\x9d\x9c\xac\x44\x59" + "\xf0\x57\x8c\xdf\x7f\x87\xa8\xc9", + .klen = 16, + .iv = "\x4b\xc3\x50\xf9\x7f\x1d\xa1\x2c" + "\xb1\x64\x7b\xd2", + .assoc = "", + .alen = 0, + .ptext = "\x64\x9a\x28\x1e\xd1\xa8\x3e\x59", + .plen = 8, + .ctext = "\xe8\xea\xa3\x5e\xb6\x2e\x25\xcb" + "\x9d\xfe\x1e\xd1\xdc\x53\x3c\x11" + "\x4f\x06\x50\x8b\x18\x9c\xc6\x52", + .clen = 24, + }, { + .key = "\x07\x0c\x3c\x1f\x8d\xad\x00\x1e" + "\xee\xb3\xb7\xe2\x28\xb4\xed\xd5", + .klen = 16, + .iv = "\xcf\x80\x82\x6c\x54\x57\x07\xfb" + "\x87\x5a\x6a\xcd", + .assoc = "\x5b\x40\xd6\x74\xe9\x4a\xd5\x5e" + "\xb8\x79\xb8\xa9\x3c\xfe\x38\x38" + "\x9c\xf2\x5d\x07\xb9\x47\x9f\xbb" + "\x6b\xff\x4c\x7e\x0d\x9b\x29\x09" + "\x3d\xd7\x5c\x02", + .alen = 36, + .ptext = "\xdd\x94\x89\x89\x5d\x16\x3c\x0e" + "\x3d\x6f\x87\x65\xcd\x3b\xec\x1c" + "\x38\x8e\x7c\x0c\xc0\x2b\x41\x2e" + "\x4b\xf7\xda\xb0\x1f\xad\x65\x48" + "\xea\xd2\xa2\xc9\x05\xec\x54\xf4" + "\xf9\xef\xeb\x90\x43\xf8\x61\xbd" + "\x54\x3d\x62\x85\xdc\x44\xaf\xb4" + "\x48\x54\xc4\xe9\x89\x2a\xb9\xee" + "\x18\xec\x66\x45\x37\x63\xca\x03" + "\x79\x64\xae\xe2\x84\x8f\x85\x91", + .plen = 80, + .ctext = "\xb6\x34\x2e\x35\x28\xa0\x34\x30" + "\xf3\x98\x25\x37\xc8\xb6\xa1\x84" + "\xe9\x79\x9e\x80\xc0\x87\x5b\xa4" + "\x9a\x0c\x93\x00\x08\x3f\x51\x25" + "\x6d\x73\x9d\x34\xa2\x63\x3e\x5b" + "\x47\x53\x94\xf8\x1c\x78\x64\x6d" + "\x3a\x96\xdd\x11\xef\x23\x5b\xd4" + "\x75\x8f\x6c\x6f\x97\xea\x0b\x89" + "\xe9\x8b\xfb\x8a\x99\x66\x4e\x33" + "\x17\x0a\x63\xc4\xfe\x5c\xa3\xf8" + "\x87\xaf\x9d\x1b\xd0\x20\x8c\x0d" + "\x42\xcb\x77\x88\xdd\x3f\xe2\xdb", + .clen = 96, + }, { + .key = "\xa8\x70\xc1\x07\xf7\x8c\x92\x65" + "\xa8\x57\xd6\xe6\x7a\x23\xe9\x8a" + "\x3d\x14\xad\xb5\x91\xd4\x75\x85", + .klen = 24, + .iv = "\xf0\x89\x21\x63\xef\x04\x8a\xd8" + "\xc0\x3b\x20\xa2", + .assoc = "\xfc\xfa\xd1\x08\x9f\xd5\x2d\x6a" + "\x55\x61\xc8\x1c", + .alen = 12, + .ptext = "\xf4\xa4\xe0\x75\x49\xc9\x40\x22" + "\x17\x18\x64\xc0\x5d\x26\xde\xab" + "\xd8\x49\xf9\x10\xc9\x4f\x9b\x4a" + "\xf8\x70\x70\x6b\xf9\x80\x44\x18", + .plen = 32, + .ctext = "\xeb\x0a\xd2\x9b\xbd\xf1\xfe\x5c" + "\xb5\x7e\x82\xfe\xef\x98\xcd\x20" + "\xb8\x26\x46\x1f\xa7\xc4\xb1\xba" + "\x04\x27\xbc\xe8\x28\x8b\xe2\x9c" + "\x68\x49\x11\x0a\x5b\x8d\x2e\x55" + "\xb3\x73\xf9\x78\x4b\xd4\x34\x5f", + .clen = 48, + }, { + .key = "\x3b\xe7\x4c\x0c\x71\x08\xe0\xae" + "\xb8\xe9\x57\x41\x54\x52\xa2\x03" + "\x5d\x8a\x45\x7d\x07\x83\xb7\x59", + .klen = 24, + .iv = "\x27\x51\x07\x73\xf2\xe0\xc5\x33" + "\x07\xe7\x20\x19", + .assoc = "\xb0\x18\x4c\x99\x64\x9a\x27\x2a" + "\x91\xb8\x1b\x9a\x99\xdb\x46\xa4" + "\x1a\xb5\xd8\xc4\x73\xc0\xbd\x4a" + "\x84\xe7\x7d\xae\xb5\x82\x60\x23", + .alen = 32, + .ptext = "\x39\x88\xd5\x6e\x94\x00\x14\xf9" + "\x5a\xb9\x03\x23\x3a\x3b\x56\xdb" + "\x3c\xfd\xfb\x6d\x47\xd9\xb5\x9b" + "\xe6\xbc\x07\xf0\x4b\xa2\x53\x51" + "\x95\xc2\x43\xd5\x4e\x05\x68\xd7" + "\x38\xbd\x21\x49\x49\x94\xbf\x4a" + "\xf4\xc2\xe6\xfb\xaa\x84\x36\x8f" + "\xa1\xc9\x2b\xa2\xd4\x2e\x42\xcc" + "\x4b\x2c\x5e\x75\x9c\x90\x69\xeb", + .plen = 72, + .ctext = "\x84\xe1\x22\x8e\x1d\xd6\x26\xe0" + "\xfc\xbb\x5e\x50\x43\x66\x4e\xb1" + "\x2c\xa2\xb4\x8d\x2a\x57\x52\x1e" + "\xe1\x90\x25\x0b\x12\x1d\x8f\xcb" + "\x81\xae\xdc\x06\xc6\xa8\x4b\xd7" + "\xa5\xbf\xbb\x84\xa9\x9b\x49\xa5" + "\xcd\x8e\xec\x3b\x89\xce\x99\x86" + "\x1f\xed\xfc\x08\x17\xd9\xe5\x9c" + "\x8a\x29\x0b\x7f\x32\x6c\x9a\x99" + "\x53\x5e\xcd\xe5\x6e\x60\xf3\x3e" + "\x3a\x50\x5b\x39\x0b\x06\xf4\x0b", + .clen = 88, + }, { + .key = "\xad\x4a\x74\x23\x04\x47\xbc\xd4" + "\x92\xf2\xf8\xa8\xc5\x94\xa0\x43" + "\x79\x27\x16\x90\xbf\x0c\x8a\x13" + "\xdd\xfc\x1b\x7b\x96\x41\x3e\x77", + .klen = 32, + .iv = "\xab\x26\x64\xcb\xa1\xac\xd7\xa3" + "\xc5\x7e\xe5\x27", + .assoc = "\x6e\x27\x41\x4f", + .alen = 4, + .ptext = "\x82\x83\xa6\xf9\x3b\x73\xbd\x39" + "\x2b\xd5\x41\xf0\x7e\xb4\x61\xa0", + .plen = 16, + .ctext = "\x62\xb3\xc9\x62\x84\xee\x7c\x7c" + "\xf3\x85\x42\x76\x47\xe4\xf2\xd1" + "\xe8\x2f\x67\x8a\x38\xcc\x02\x1a" + "\x03\xc8\x3f\xb7\x94\xaf\x01\xb0", + .clen = 32, + }, { + .key = "\x77\xaa\xa2\x33\x82\x3e\x00\x08" + "\x76\x4f\x49\xfa\x78\xf8\x7a\x21" + "\x18\x1f\x33\xae\x8e\xa8\x17\xc3" + "\x43\xe8\x76\x88\x94\x5d\x2a\x7b", + .klen = 32, + .iv = "\xd2\x9c\xbe\x07\x8d\x8a\xd6\x59" + "\x12\xcf\xca\x6f", + .assoc = "\x32\x88\x95\x71\x45\x3c\xee\x45" + "\x6f\x12\xb4\x5e\x22\x41\x8f\xd4" + "\xe4\xc7\xd5\xba\x53\x5e\xaa\xac", + .alen = 24, + .ptext = "\x66\xac\x6c\xa7\xf5\xba\x4e\x1d" + "\x7c\xa7\x42\x49\x1c\x9e\x1d\xc1" + "\xe2\x05\xf5\x4a\x4c\xf7\xce\xef" + "\x09\xf5\x76\x55\x01\xd8\xae\x49" + "\x95\x0a\x8a\x9b\x28\xf6\x1b\x2f" + "\xde\xbd\x4b\x51\xa3\x2b\x07\x49" + "\x70\xe9\xa4\x2f\xc9\xf4\x7b\x01", + .plen = 56, + .ctext = "\x1e\x98\x0b\xc3\xd9\x70\xec\x90" + "\x04\x17\x7f\x5e\xe0\xe9\xba\xca" + "\x2f\x49\x28\x36\x71\x08\x69\xe5" + "\x91\xa2\x0c\x0f\xa4\x12\xff\xae" + "\xd9\x5f\x98\x50\xcf\x93\xb4\xfb" + "\x9f\x43\x1a\xd8\x55\x5f\x4b\x3a" + "\xe7\xc8\x1e\xae\x61\x29\x81\x1f" + "\xe3\xee\x8a\x8e\x04\xee\x49\x4b" + "\x2b\x54\xd7\xdc\xea\xcd\xba\xd6", + .clen = 72, + }, +}; + +static const struct cipher_testvec lea_cbc_cts_tv_template[] = { + { + .key = "\x35\x13\xa7\xb3\xea\x5f\x44\x6b" + "\x25\x25\x31\xbf\x78\x9b\x91\x85", + .klen = 16, + .iv = "\x88\x0d\x1f\xb0\xe4\x73\xd7\xcf" + "\xce\x25\x03\xc6\x84\x1f\xad\x51", + .ptext = "\x33\x2b\xcf\xda\xb4\x61\x27\x9b" + "\xe0\xd5\xf2\x50\x5f\x2b\x02\x2b" + "\x8c\x06", + .ctext = "\xa9\x21\xdd\x75\x99\x5b\x30\x7d" + "\x6d\x2d\x58\x70\xb0\x16\xee\x6a" + "\x37\x52", + .len = 18, + }, { + .key = "\x1f\x7d\x92\x5f\xb0\xc3\x5a\xff" + "\xb1\x2f\x30\x8a\x78\x61\xa2\xf8", + .klen = 16, + .iv = "\x45\xea\x8e\x45\x49\x49\xc0\xec" + "\x33\x17\xd2\x5c\x42\x40\xb5\x40", + .ptext = "\xc8\x22\x50\xe8\x6b\xff\x95\x65" + "\xd3\xab\x4e\x9b\x78\x6d\x9c\x82" + "\x97\xb8\xb4\x94\x65\x1d\x48\xb5" + "\x60\xcc\x19\x90\xd3\xaf\x05\x6e" + "\xc7\x06\xd0\x6f\xeb\x1c\xf4\xb3" + "\xa2\xf0\x02\x71\x61\xa4\x33\xf0" + "\x25\x97\x98\x75\x27\x57\xb9\xec" + "\x82\xcf\xd5\xed\x8d\x16\x4f\x35" + "\x48\xf4\xb0\xb4\x52\x62\xfe\xdc" + "\x3e\xcb\xd5\x33\x7a\x60\xce\xff" + "\x1d\xa7\x93\x70\x8e\xd7\x3e\x5f" + "\x70\x7e\xcc\x70\x4a\x85\x36\xc5", + .ctext = "\xc9\xbd\x46\x34\xc7\x19\xd9\x7a" + "\x13\xfe\x6a\x19\xc0\x80\x61\x8b" + "\x2f\x6b\x8c\xc8\x60\x95\xe5\xe5" + "\xf2\xa4\xf3\xb6\x91\xae\xf1\x0e" + "\xc1\xf3\x9a\xa5\xdc\xa4\x42\x2d" + "\x42\x11\x03\xe7\x4b\x74\xdd\xf4" + "\xa6\x47\x03\xb5\x4a\x08\xa0\x1f" + "\x63\x6a\x1d\x5b\x84\x73\xe6\xa0" + "\x96\x4c\x8c\x0e\x95\xfc\xf0\x0c" + "\xd2\x28\x55\xcc\x0b\x3b\x8b\x10" + "\x75\xfb\x85\xe5\x26\xc7\x78\x25" + "\x89\xd1\xe9\x1c\xcf\x15\x1c\xe5", + .len = 96, + }, { + .key = "\x81\xeb\xf0\x43\xcb\xde\x8c\xa0" + "\x8d\xf4\x71\x1d\x0a\xf7\x95\xae", + .klen = 16, + .iv = "\xfc\x1f\xec\x16\x48\x4f\x3c\xda" + "\xff\xb9\x4c\x8f\xd9\x57\x20\x2f", + .ptext = "\x8a\x93\x35\x6b\x86\x37\x2d\x20" + "\x65\xde\x4c\x25\xa5\xbb\xdf\xec" + "\x15\x3d\x97\xc3\xab\xb9\xdb\x5f" + "\x54\x81\x34\x80\xb7\x74\x33\x9e" + "\x2f\x15\xfc\x52\x48\x76\x13\x49" + "\x7b\xdc\xb9\xba\x9e\x34\x40\xe8" + "\x86\xf9\xc2\x67\xf5\xed\x64\xda" + "\xdb\x2b\x4c\x6a\xab\xe7\xa8\xdf" + "\x43\x51\xa5\xb5\x2d\x35\x15\x30" + "\x48\xec\x0b\xd8\xcd\x6b\x7a\xc0" + "\xe2\xcb\x73\xaf\xbd\xd2\x42\xbd" + "\xeb\xc7\xb5\xaf\x54\xbf\xf9\xee" + "\x16\xed\x83\xd0\xb8\x16\xcd\x57" + "\xe8\xef\x4f\x95\x71\x44\x54\xad" + "\xf5\xe8\x66\x9a\x52\x8b\x59\xcb" + "\x8d\x09\xe2\x5d\x7b\xda\x5c\x80" + "\x07\x67\x41\x4d\x3b\xb8\x69\xa6" + "\xb4\x6e\x26\x32\x6a\xdb\x11\x53" + "\xfd\xd1\x54\xdd\x0f\xae\xb7\xd4" + "\x42\x00\xdd\x36\x42\x93\x2d\xcc" + "\x7e\xd9\x26\xd8\x96\x39\x64\x93" + "\x0e\xfc\xad\x9a\xb7\xc6\x76\xe6" + "\xed\x48\xe0\x67\x9b\xb1\x74\xc8" + "\xd7\x8b\x13\x1b\x80\x9f\x61\xa6", + .ctext = "\x0b\x1f\xff\x1f\x09\x5f\xb0\x8a" + "\xa9\xd8\x11\x17\xb6\xb2\xec\x10" + "\xbd\xc5\xe2\x95\x12\x01\x15\xcd" + "\x70\xed\x35\x43\x33\xfd\xeb\x5e" + "\x2e\x20\xf0\x12\x71\x49\xb0\x6e" + "\x36\xd5\xe3\x12\x52\x0c\x24\x4c" + "\x29\xf3\x5d\x84\x45\xf9\xea\x10" + "\xc1\x9e\xbd\xb9\x26\x7f\x7d\xd3" + "\x89\xaf\xc6\xea\x54\x12\x1a\xae" + "\xfc\xc6\xc0\x2d\x0a\xe0\xee\x92" + "\x7d\x27\xa1\xb0\x5e\x0c\x42\x1d" + "\x43\xd4\x7f\xeb\x72\x2b\x62\x17" + "\x49\x4f\xe1\x8e\xc0\xfa\x07\x94" + "\x3b\x55\xcf\xeb\x03\x6e\x8a\x28" + "\x3b\x05\x2d\xb7\xe1\x83\x18\x41" + "\x52\xf6\xd7\x7d\x25\x16\x72\x12" + "\x36\x94\x80\xcc\x9e\xe3\xec\xd0" + "\xae\x4a\x6c\xe3\x6e\x40\xf2\x4c" + "\x3f\xb1\x9b\x91\x2f\xba\x13\x16" + "\x0a\x32\xc6\xa1\x07\x04\xa1\x17" + "\xed\xa4\xbc\xf2\xf7\x42\x44\x75" + "\x58\x69\x7f\xcf\xee\xdc\x36\x66" + "\x78\x94\x77\xb8\x6f\x68\x04\x47" + "\x6e\x55\xb6\x45\x33\x0b\x03\x54", + .len = 192, + }, { + .key = "\xe2\x5c\x6a\x42\x20\xd3\x73\x76" + "\x82\xd4\xac\xb1\x1a\x94\xcd\x37", + .klen = 16, + .iv = "\x20\x3a\x6f\x9e\xd9\x2e\x36\x1e" + "\x54\x9e\xb1\x55\x4b\x17\x3b\x38", + .ptext = "\x10\x39\xe2\x84\xff\xf6\x13\x61" + "\xd8\xe3\xdc\x59\x58\x22\xab\x34" + "\xb3\x0d\x50\x02\xa3\xbf\xe9\xe2" + "\x8d\x81\x28\xb4\x8b\xb7\xa7\x33" + "\xd5\x6b\xc6\x10\x43\x66\xbf\xfc" + "\xa9\xb6\x42\x76\xa2\x23\x84\x5b" + "\x70\xd6\x58\x9c\x4e\x77\x42\x0a" + "\x68\x0a\x73\xc4\x3d\x5a\x19\x98" + "\xd9\x41\x8f\x84\xe2\x7e\x30\x6c" + "\x04\x24\x88\x0f\x9d\x6a\x3b\xce" + "\xa8\xd2\x1f\x38\x39\x6c\x14\x7a" + "\xd8\xd0\xc4\xa3\x76\x73\xd7\x0d" + "\x3e\x6c\x36\x4b\x00\x17\x3e\x9e" + "\x1b\x32\x91\x1c\xa2\x22\x04\x01" + "\x6f\x58\xe8\x9e\x0e\xb2\x5e\x92" + "\x4e\xeb\xb1\xc5\x15\xd5\x10\x4e" + "\x52\x20\xe3\x37\x6e\x44\xdb\x20" + "\xae\xbd\x6d\x04\xcc\x58\xd2\x62" + "\x93\x6b\xd6\xd6\x74\x62\x9c\xd3" + "\x9a\x30\x91\x31\x9e\x50\x42\x3f" + "\xc5\x3b\x56\x7f\x29\x99\x0a\x08" + "\x20\x4a\xa8\xb3\x32\xdb\x57\x86" + "\xbf\x2f\xa0\x56\x9e\xee\xd9\xe5" + "\xb6\x14\xc5\x9b\xb1\x52\x11\xe0" + "\xe2\xe0\x8b\xbe\x8b\x61\x4b\xc3" + "\xde\x28\x50\x56\x73\x78\x16\xfd" + "\x97\x24\x46\x2b\xe4\x56\xd7\xd7" + "\xe8\xb7\x03\xd1\x61\xc6\x17\x77" + "\x33\x67\x2d\xe3\x84\x00\xed\x85" + "\x2d\x59\xc3\x32\x11\xcf\x90\x52" + "\xd5\xcb\x67\x66\xac\xd8\xe2\x14" + "\x5b\xc9\xa5\x87\x7f\x59\x12\x7f" + "\x22\xde\xf8\xc3\xe6\xad\x92\x8a" + "\x74\xa4\x6f\x24\xa5\xd4\x56\x46" + "\x71\xf9\xfb\x46\x6c\x97\xe9\x12" + "\xd1\x95\xe6\x3d\x51\x67\xe8\x18" + "\x3b\x22\xc2\x9e\x73\xd7\xf5\x10" + "\xe3\x06\x4e\x92\xbb\x5c\xda\xb5" + "\xb3\x7d\x87\xa7\x5e\xcc\x44\xcc" + "\x36\xe3\x4b\xc0\xdb\xee\xab\xc5" + "\xe9\x50\xf4\x62\x95\xad\xde\x68" + "\xa8\x14\x61\x6f\xd0\xc3\xa5\x05" + "\x16\xd1\x02\xad\x22\xba\x3a\xfd" + "\x0d\x01\x10\xf2\x70\xfd\x73\xfd" + "\x02\x87\x8c\x1a\x66\xe7\x86\x72" + "\x3a\x1c\xd7\x9e\x4b\xac\xfa\x5e" + "\xec\xf1\x96\xca\x24\x48\x56\x78" + "\x4e\xd3\x0c\x16\xce\xab\xb3\xdf" + "\x97\x5f\xce\xea\xa6\xf2\xf9\x41" + "\xd3\x97\x5a\x5f\x06\x19\x79\x04" + "\x82\xac\xdd\xfa\xc3\x81\xbe\x8a" + "\xae\x08\x06\x97\xe9\x9b\xa6\x82" + "\xe8\xc4\xb6\xd1\x17\x74\x1d\x5e" + "\x34\xac\xd8\xc8\xba\x13\xd4\x23" + "\x33\x38\xf9\x76\x72\x0e\xe2\xef" + "\xb5\x55\x68\xe3\x44\x31\xb4\x9c" + "\x22\x17\xd8\x8d\x92\xf7\xaf\xac" + "\x53\xd2\x60\x5b\x40\x40\x45", + .ctext = "\x73\xfa\xb8\xc9\xd7\xd8\xef\x60" + "\x4f\x70\x03\x50\xa1\xef\x46\xd1" + "\x87\xff\xe1\x2e\x8a\x4f\x6e\x17" + "\x70\x09\x52\x87\x78\xd0\x4b\xbf" + "\xb9\xae\x14\xd1\xad\xc4\x2a\x02" + "\xe0\x2d\x6b\x50\x84\xc1\xb9\x8b" + "\x0c\x7b\x27\x23\x1f\x30\xb3\x4b" + "\x83\x86\xbd\x33\xdc\xf0\x41\x84" + "\xed\xec\xfc\x79\xe6\xa7\xf6\x91" + "\xa6\x5f\x9f\x72\x2b\xfe\x28\xf1" + "\x62\xa2\x3f\xa0\x4f\x65\x10\xce" + "\x96\xbd\x4d\xeb\x33\x88\x42\xef" + "\x2c\x8c\x3c\x99\xbe\x2b\x9a\x1b" + "\xf7\x06\xee\x26\x80\x63\xf3\xf1" + "\x7a\x4f\xae\x46\x59\xb4\x29\xda" + "\x4e\xe9\xa0\x6e\xa4\x57\xb2\x8c" + "\x4d\x57\x9f\xd2\x9d\x4e\x72\xc4" + "\x68\x60\xdf\x7b\xae\xb3\xb3\x8b" + "\xaa\x9a\xb9\xe8\xb2\x21\x1b\x36" + "\xdc\x9a\x88\xab\xa7\x37\x7b\x87" + "\x32\x28\xf2\x07\x78\xb0\xef\xe9" + "\xdc\xb9\xa9\xdf\xf8\xa0\x2b\xdd" + "\x93\x41\xa3\x9c\x6c\xe1\xbc\x79" + "\x58\x61\xac\x36\x10\x37\xd9\x3f" + "\x49\xfa\x51\x04\x1b\x35\x97\x7e" + "\x09\xff\x7a\x3d\x9c\xf4\xaf\xad" + "\x49\x2e\x0c\x94\xb4\x8b\xe4\xc6" + "\x24\x67\xb7\x15\x5c\x7f\x19\x05" + "\x25\x68\xe9\x42\xa7\xb0\x6e\x29" + "\xd4\xe1\xb1\x22\xb6\xc5\xaa\x0b" + "\x4d\x3f\xe5\x20\x3e\x74\x15\xab" + "\xc5\x3b\xf7\xe9\xb2\x37\x50\x6a" + "\x6c\x2f\xb7\xed\x9b\xf2\x1a\xa8" + "\x12\x7d\x86\xe1\x2f\x19\xe2\x6c" + "\x66\x9a\x65\x1a\xb6\x88\xa5\x13" + "\x4e\x1b\x51\x10\x34\xb7\x46\x54" + "\x77\x17\xbd\x49\x46\x90\x24\x49" + "\x07\xd9\xab\x58\x59\x0e\x3e\xb2" + "\xbc\xf7\xd2\x10\x81\x0e\x11\x0f" + "\xb3\x2c\x4f\x6e\xad\xb4\x18\x45" + "\x4d\x6e\x2a\x00\x7c\xac\x06\xc5" + "\xcc\x58\x23\xcf\x76\x0c\xad\xa9" + "\x4b\x88\x58\xa3\x78\x10\x17\xb6" + "\xe0\x85\x50\xff\x45\xd6\x81\xac" + "\x04\x62\x65\xb3\x18\x98\x39\x43" + "\x62\x43\xfc\x02\x21\x53\xc9\x0e" + "\xc3\xa6\x87\x4f\x9b\x81\xe1\xa6" + "\x65\xc2\x6d\x44\x42\xa2\x58\xe9" + "\x5f\xdb\x2d\x06\x2b\x90\x29\x4d" + "\x3a\x75\xc6\x93\x5f\xcb\xe2\x32" + "\x53\x98\x26\x5f\x2d\xdf\x51\x64" + "\x52\x69\xaf\xb7\x51\x9b\xf5\xd5" + "\x61\x2b\x8b\xfe\xc5\xbe\x92\x86" + "\xff\xcb\x53\x8d\x58\xb5\x54\x61" + "\xf5\x8e\xf3\x08\x3b\x9f\x43\x6a" + "\x32\x13\x6b\x98\x1e\xed\xb5\x23" + "\x2c\x1f\x34\xd1\x8f\xc0\x94\xf5" + "\x64\x4e\x31\x18\xe1\xf3\xa2", + .len = 463, + }, { + .key = "\x29\x0a\xcd\xc9\xa0\x77\x23\x7c" + "\xd1\x59\xca\xe3\x22\x82\x15\x0a" + "\x74\x44\xcb\x4a\xa3\x46\x17\xed", + .klen = 24, + .iv = "\x97\x87\xec\x82\xfb\x4b\x45\xd4" + "\xf5\x3c\xf6\x23\xe9\x75\xac\x2b", + .ptext = "\xd4\x46\x6c\xe4\xf9\xd7\xed\x73" + "\xd8\x27\xa7\xd5\x92\xc2\xad\x2f" + "\x9d\x46\xee\xdc\x70", + .ctext = "\xed\x39\x3d\xfb\x9d\x1e\x03\x3d" + "\x0f\x65\xa0\xe5\xc7\x3e\x06\xb2" + "\xf2\x5b\xf6\x81\x68", + .len = 21, + }, { + .key = "\x68\xe7\x99\x43\x34\xbc\x59\xd9" + "\xe9\xe1\x09\x92\x54\x15\x71\x79" + "\xbf\xb6\x91\x9f\x47\x1b\x5b\x89", + .klen = 24, + .iv = "\xf5\xfb\x6b\xdd\x07\x19\xa3\x72" + "\x59\xe0\x1d\xd6\xb4\xc1\x42\x46", + .ptext = "\x54\x41\x55\x20\x76\x98\xb3\xbd" + "\x99\x05\x1d\x54\x06\xdd\x16\x38" + "\x60\x3c\x41\x1c\xd5\xb7\x43\xa9" + "\xa5\x2d\xb1\xd0\xbd\x35\x5c\x4b" + "\xd6\x1d\x48\xef\xc3\xe7\x30\xd1" + "\x9e\x2b\xe4\xc8\x39\x0b\x05\x13" + "\xda\xa9\x54\x6d\x63\x16\x5d\xeb" + "\x02\x80\x3b\x09\x70\x9a\x58\x17" + "\x92\xbf\x2f\x78\x99\xeb\xb8\xd6" + "\xdd\xcd\xcb\x00\x51\xc8\x9d\xba" + "\x52\x60\xae\x03\x75\xf6\x90\xe9" + "\x89\xcd\xf1\x6e\x67\x9d\xbd\x7a", + .ctext = "\xd5\x89\x3b\xa1\x25\x59\x6c\xeb" + "\xfb\xa1\x84\x9e\x23\xa7\x6b\xa7" + "\x7b\x55\x99\xf1\xf8\xcf\x95\xc9" + "\x70\x35\xf7\x08\x8a\xb0\xa7\xf2" + "\xa6\xfc\xb4\xe5\x73\xd0\xba\x51" + "\xc2\xda\x31\x86\x35\xae\x98\x75" + "\x16\x06\xb7\xe2\x76\x23\x3e\x9d" + "\x3e\x1a\xbb\x41\xde\xc0\x34\x13" + "\xef\x5d\xdf\x9f\x14\x50\x2a\x5c" + "\xc0\xb3\x5f\x3c\xbc\x09\x6b\xd7" + "\xbb\x64\xea\xa1\x36\x3e\x1f\xf3" + "\xe3\xbe\xcd\xa6\xdc\x9a\xd6\x2b", + .len = 96, + }, { + .key = "\xaf\xf2\x33\x94\xe0\x62\x6f\xb0" + "\x7b\x63\xdc\xf5\x96\xdc\x6d\x7a" + "\xa7\x99\xf2\xaa\x3b\xa7\x4a\xfa", + .klen = 24, + .iv = "\x49\x72\x29\x12\x4b\xe2\x92\xea" + "\xcd\x8e\x3a\xd6\x50\x26\x51\xa4", + .ptext = "\x7e\x73\x73\xb6\x99\x6e\x08\x53" + "\x1a\x18\x18\x6e\x5f\x90\x5e\x14" + "\xf5\xfc\xa0\x9a\xea\x21\x4b\x42" + "\xd9\x46\x9b\x83\x24\xf2\x55\xb3" + "\x78\xd0\x65\x37\xb0\xdd\xa7\x44" + "\x56\x54\x2a\x1a\x64\xa8\xd0\x0a" + "\x9a\xae\xe2\x8f\x43\x12\x0b\xc1" + "\xdd\x7c\x63\x3e\xd0\x0f\x34\xc0" + "\x1f\x5f\x10\x0d\x3f\xb1\xc5\x85" + "\x37\xcf\x2c\xb0\x4b\x52\xf4\x1b" + "\x84\x4f\xf0\x69\x0f\x07\x49\x7a" + "\xd4\xb2\x10\xc7\xc5\x96\xb3\x54" + "\xc0\xf1\xfd\x41\x8f\x05\x01\x12" + "\xf2\x51\x14\x2c\x8f\xe9\x8b\x78" + "\x7e\x9f\x94\x27\x74\xb1\x7b\xcb" + "\x26\x7a\xb5\x37\x00\xdb\x9c\xe2" + "\xc7\x2d\xe0\xaf\x75\xa5\xa0\x05" + "\xa9\x48\xfb\xb2\x5a\x51\x5c\x3c" + "\x1c\xa9\x2d\x99\xff\xd5\xf1\xd1" + "\x4b\x57\x89\xbf\x08\x83\xf8\xeb" + "\x59\xb0\x3a\x77\xfd\x07\x44\xa2" + "\xbd\x02\x29\xf3\x2b\xe9\x87\xec" + "\x30\x67\x0e\x49\x85\x16\x60\x9b" + "\x56\x3e\x50\x98\xf2\xec\x9f\xfd", + .ctext = "\x41\x75\xfe\x75\xce\x49\x41\xd1" + "\x45\xad\xd2\x04\xb1\x3d\x07\x92" + "\x9e\x90\x91\x68\xe0\x03\xa2\x71" + "\x1a\x29\x2e\x19\x0a\x83\x53\x3b" + "\xa6\x2b\xe2\x50\xc5\x56\x54\x52" + "\x40\x2e\x25\x51\xb0\x84\x8a\x1a" + "\xd8\x2f\xed\x8f\x50\x53\xe3\xc3" + "\xaf\xe2\xb5\x40\x5d\x80\x96\x44" + "\xb9\x41\xde\x5d\x31\x39\xf5\x68" + "\xa6\x24\xdf\x80\xb6\x9a\x71\xa0" + "\x6b\xdc\xf9\x8a\xfd\x4e\xf5\x3b" + "\x62\xd4\x5b\x13\xf5\x22\x69\x5f" + "\x9c\x0f\x8c\x39\x04\x6d\xe4\x8a" + "\x89\x89\xc0\xbb\x6b\xc0\xcb\xb4" + "\x31\x5e\xfd\xad\x65\xde\x47\xc0" + "\x08\xa9\xcf\xab\x00\xb1\x74\x45" + "\x7d\xaf\x80\xe1\x18\xce\xfd\x4a" + "\xa1\x3c\x1a\xbf\x12\xbb\xbd\xe2" + "\x06\x98\x81\x8c\xfc\x98\x75\xd4" + "\xdb\x6c\x0c\x95\x19\x3c\xf4\x6f" + "\x76\xd7\x38\xa6\xc8\x6a\x90\xdd" + "\xd5\x2c\x5a\x3d\x74\xd2\x5a\xf7" + "\xaa\x4a\x5e\xcc\x55\xc6\x86\xe1" + "\x71\xcd\xa4\xb9\x06\x8f\x96\xc5", + .len = 192, + }, { + .key = "\xef\x87\xd9\xdf\x0f\xf1\x36\xca" + "\x7c\x49\xe0\xc4\x41\x9c\xa4\x2b" + "\x23\x74\x83\xb0\x33\xaa\x05\x4f", + .klen = 24, + .iv = "\x50\x0d\x63\x90\xb7\x9b\xd8\xa0" + "\x3b\xb0\x73\xe5\x5a\x5c\xb7\x0d", + .ptext = "\x41\xe5\x67\x26\xb4\x52\xff\x43" + "\x27\x6a\x1d\x88\x11\xe7\x23\x40" + "\x3a\x6e\xdf\x01\xf9\xbf\xd3\x99" + "\xfe\x7a\xb7\xff\x3b\x58\x53\x06" + "\xca\x97\xa4\xf2\xc7\x51\x44\x32" + "\x88\xcd\x52\xbf\xe2\xd0\x7e\x62" + "\x5f\x5f\xc5\x5f\x36\x2d\xe9\x1e" + "\x0b\x16\xa7\x82\xcc\xd2\xdc\x2e" + "\x33\xa1\x97\x2f\x5d\x35\x4b\x23" + "\xcf\xe0\xf3\x4e\x8b\xa9\x54\x64" + "\x0e\xc0\x1e\x9f\x83\xdf\xe8\x1c" + "\x66\x2e\x96\x05\xce\x17\x5a\x15" + "\xaa\x7a\xd1\xb4\xab\x79\x87\xaa" + "\x02\xc6\x25\xaf\xa2\x27\xa2\x58" + "\xea\x3c\xa0\xb0\x0b\xf1\x72\x56" + "\x49\xaa\x7f\x93\x93\x72\x8e\x38" + "\xc4\x23\xee\x53\x07\x7a\x33\x2e" + "\xc3\x15\x2f\xd4\xe1\x7f\x27\xec" + "\x43\xed\x74\x09\x9a\x12\xa0\xf8" + "\x30\xd9\x64\xb7\xdb\x28\x4a\xd2" + "\x0a\x30\xf7\x37\x6e\xd6\xcf\x79" + "\x8d\x3b\x69\x6b\xe9\x7c\x15\xce" + "\x1c\x1a\x29\x89\x73\xb3\xa2\xe1" + "\x19\x21\xbe\xed\x61\xf7\x1e\x70" + "\x7b\xaf\x7b\xa6\xb4\x40\xe5\x23" + "\xfd\xdd\x81\xa7\xfd\x61\x7d\x50" + "\x67\x5f\x50\x5b\x02\xa5\xda\xe0" + "\x95\xfe\xcd\x83\x89\x92\xeb\x5c" + "\x6e\xad\x65\x5f\x3c\xc7\x6e\x52" + "\x90\x23\x63\x5e\xa1\x8f\x44\xd9" + "\xc1\x2b\x49\x83\x7a\xfe\x2b\xa9" + "\x4d\x35\xfe\x5a\x58\x25\x59\x1c" + "\x3e\xf5\xcc\xf6\x01\xa8\x0a\x6a" + "\x0d\x6f\x38\xaf\xfb\x1c\xa6\x63" + "\xaf\x97\xcd\x24\xda\x57\xd3\xfa" + "\xc0\x42\xb1\xb9\xa4\xc2\x0b\xc2" + "\x2c\x18\xc5\x06\xce\x93\x5d\x6f" + "\x80\x61\x8f\x5a\x0a\x7d\x47\xb0" + "\x61\x57\x56\x0a\x29\x46\x95\x5c" + "\xf9\xda\x65\x2f\xe1\xc3\x88\x32" + "\x69\xe9\xb0\x76\xa9\x59\x57\x74" + "\xe2\xb6\x27\x8e\x71\x6a\x19\xc3" + "\xda\xe9\x5e\xb3\x3a\x93\x60\xfc" + "\x23\x3e\xd5\x89\xd6\x57\x84\x38" + "\x90\x3f\xda\xc8\x32\x62\x63\x78" + "\x61\x70\x61\xbd\x4b\xdc\x55\x98" + "\xc9\x66\xb4\x43\x34\x51\x7c\x85" + "\x0e\xf1\x4b\x6d\x65\x92\x4c\x6c" + "\xbb\x1a\xe3\x67\xdd\x8c\x3e\x96" + "\x22\xf4\x2f\xc1\x04\x22\xf8\xf6" + "\x70\xd6\x5d\xeb\x68\x63\x5a\xd4" + "\x0b\x98\x82\xc1\xa5\x85\x78\x61" + "\x6a\x05\xed\x56\xc9\x85\xef\xb7" + "\x3f\x1a\xee\x5d\xfd\xf3\xbb\x91" + "\x71\x3a\xc1\xc6\xeb\x01\x60\xb8" + "\x9c\xfd\x2b\xad\xd5\xbc\x6f\x06" + "\xfe\x6a", + .ctext = "\x9a\xcc\x13\x42\xb7\xc4\x64\x79" + "\x32\xcb\x14\x48\xac\x4b\x4d\xc0" + "\xd5\x18\x9a\xb1\xaf\x63\x85\x1d" + "\x49\x3f\x20\x5b\x18\x48\x58\x8d" + "\xf1\xa1\xa1\x9b\x35\x27\x25\x52" + "\x7b\x8d\xb4\xcb\x05\x86\xbe\x18" + "\xa1\x6d\xab\x85\xa3\xcd\x6a\x02" + "\xf8\x17\x0a\xe4\x38\x44\xcd\x4a" + "\x8c\x42\xaa\x12\xb4\x9d\xd2\x3a" + "\xf1\x85\x9b\x84\x44\x45\x1a\x17" + "\x7e\xae\xa4\x22\x4e\xed\x2f\xeb" + "\x51\x9e\x9d\x2c\xbd\xbb\xf1\xf0" + "\x62\xe5\xc5\xbf\xe0\x82\xfa\x15" + "\xb4\xde\x93\xed\x34\x2a\x3f\x21" + "\xe0\xa0\x11\x2a\x02\xff\xf4\xde" + "\x50\xee\xc2\x4f\x0b\xcc\xb4\xd6" + "\xe7\x98\xf0\xf2\x62\xcc\xea\xaa" + "\x5d\x4f\xb2\x47\xb9\x64\xb2\x72" + "\xe7\x9f\x4f\xe3\x1b\x39\x90\x3e" + "\x0c\x08\xbf\x8e\x8d\x35\xe3\xe5" + "\x7d\x35\xe7\xe4\x2b\x4c\x56\x46" + "\x87\xac\x54\x2f\x93\x6d\x50\xa9" + "\x5a\xe5\xaa\x9e\x2a\x93\xae\xb0" + "\x78\xb1\x88\xf6\x96\x6d\xc3\x4e" + "\xcd\xef\x7b\xfd\xd8\xd0\x24\x6e" + "\xe7\x7b\x45\x63\x0d\x66\x60\x4d" + "\xd2\xee\x64\x9e\x35\x55\x81\x20" + "\x30\xf9\x36\xa0\x9a\x76\x32\x83" + "\x76\x21\xdd\xf4\xb9\xf7\x3e\x27" + "\x93\x10\xa9\x80\x08\x0c\x2f\x4a" + "\x89\xf3\x52\x51\x81\x12\x22\x00" + "\x5f\x2f\x0d\x61\xcb\x29\x96\x1d" + "\x96\x76\x64\x39\x9c\x1a\x43\xdd" + "\xda\x54\xb3\x76\x89\x5a\x08\x21" + "\x9e\x86\x64\x1f\x44\x33\xbc\xe6" + "\x12\x79\xf8\x70\xdc\x7f\x3c\x01" + "\x83\xc8\x49\x77\x81\x41\xad\x97" + "\xb1\xad\x10\x38\x79\x77\xcc\xcc" + "\xaa\x48\xa7\x2e\xe4\xb7\xf2\x96" + "\x68\xc9\x65\x67\x40\xdd\xbd\x40" + "\x29\xeb\xfd\xdb\xb4\x07\xa3\x04" + "\xee\x24\x9a\x6b\xfb\x5c\x37\xee" + "\xc2\x48\xcf\x2d\x9a\xbe\x4d\x84" + "\xca\xee\x1f\x19\x9a\xec\x52\x25" + "\x82\xa1\x48\x54\xe9\x75\x94\x47" + "\xee\xef\xaf\xad\xcb\x8c\xbd\x55" + "\x2c\xfc\xd9\x7b\xb7\xcf\xa6\x18" + "\xb4\x5d\x54\x7b\x30\xac\x5f\x0d" + "\x2c\x07\x8d\xe0\x91\xb1\xf2\xd2" + "\xf7\x23\x9b\xb7\x84\xac\x9a\x80" + "\x64\xf0\xb1\x8c\x31\x24\x36\xb9" + "\xc5\x25\x4d\x84\x66\x2e\x5a\x7c" + "\x07\x2a\x01\xb5\xa8\xb3\xa8\x2d" + "\xea\xb7\xba\x51\x17\xca\xe7\x25" + "\x37\x75\x31\x1f\xcc\xdd\x1a\x96" + "\x75\x4a\x6b\x71\xd8\x23\x27\x57" + "\x82\x3f", + .len = 450, + }, { + .key = "\xdf\xe9\x57\xd2\x91\x00\x7e\x82" + "\x54\x8c\xfc\xf9\x4a\xe0\x43\x7c" + "\x0f\xae\x77\xca\x35\x67\x4a\xc9" + "\x37\xab\xf4\xf7\xb7\x63\x7b\x4a", + .klen = 32, + .iv = "\x5e\xf0\xd6\x94\x17\xc0\x62\x86" + "\xe7\x95\x5b\x1c\x74\xe2\xe8\x33", + .ptext = "\x8c\xba\x8a\x89\xf8\x60\xf9\x4b" + "\xe1\x21\xd0\x24\xd8\xb1\xeb\xe8" + "\x3e\xb2\xbe\x87\x76\x7b\xaa\x58" + "\x85\x3b\x5e\xeb\x9a\xa8\x19\x52", + .ctext = "\x13\x7a\x36\x09\x9a\x50\x73\xc5" + "\x9e\xbc\xdd\xd6\x27\xcf\x86\xce" + "\xb2\x28\x04\xb5\x5e\x40\x7e\xb1" + "\xcf\xce\x66\xf4\xbd\x89\xa8\x78", + .len = 32, + }, { + .key = "\xdf\xe9\x57\xd2\x91\x00\x7e\x82" + "\x54\x8c\xfc\xf9\x4a\xe0\x43\x7c" + "\x0f\xae\x77\xca\x35\x67\x4a\xc9" + "\x37\xab\xf4\xf7\xb7\x63\x7b\x4a", + .klen = 32, + .iv = "\x5e\xf0\xd6\x94\x17\xc0\x62\x86" + "\xe7\x95\x5b\x1c\x74\xe2\xe8\x33", + .ptext = "\x8c\xba\x8a\x89\xf8\x60\xf9\x4b" + "\xe1\x21\xd0\x24\xd8\xb1\xeb\xe8" + "\x3e\xb2\xbe\x87\x76\x7b\xaa\x58" + "\x85\x3b\x5e\xeb\x9a\xa8\x19\x52", + .ctext = "\x13\x7a\x36\x09\x9a\x50\x73\xc5" + "\x9e\xbc\xdd\xd6\x27\xcf\x86\xce" + "\xb2\x28\x04\xb5\x5e\x40\x7e\xb1" + "\xcf\xce\x66\xf4\xbd\x89\xa8\x78", + .len = 32, + }, { + .key = "\x3a\xa8\x9f\x14\x8b\xfb\x9e\x07" + "\x9f\x9e\x42\x38\x6d\xc3\xa6\x9c" + "\x0f\x4c\x7e\xb5\x76\xa5\x03\xc5" + "\xc6\x64\xbb\x31\x96\xda\x2d\x0c", + .klen = 32, + .iv = "\xe4\x2b\x11\xdc\xcf\x50\xb1\x2d" + "\x92\x58\xd4\x74\x88\xd3\x5b\xbf", + .ptext = "\x51\x2b\x7d\xa5\xa8\xfe\xbe\xfc" + "\x8c\x61\xdd\x6d\x36\x9d\x28\x5a" + "\xd3\x9b\xd9\x93\x2e\x38\xe9\x39" + "\x69\xa5\xeb\x59\xbc\xcd\x1d\x41" + "\x9e\x3d\x5e\x5c\xf5\x0b\xa5\x6e" + "\x4f\x55\xcb\x09\xb4\x4d\x7b\xfb" + "\x18\x0c\x15\x90\x56\x00\x58\x9a" + "\x55\x1b\xba\x31\x37\xae\x0b\x0a" + "\xd8\x79\x89\xcc\x3b\xc0\x03\x6c" + "\x10\xc4\xd4\xf2\x85\x33\xe5\x94" + "\x27\x71\x7f\xa1\x82\x62\x04\xa4" + "\xb7\xe4\x6c\xbb\x0f\xb6\x52\xaf", + .ctext = "\x05\xbf\x55\x98\x49\xce\x74\x28" + "\xe1\x36\x6e\x71\x37\x91\x2f\xe3" + "\xcb\x9c\x5e\xcf\x2d\x72\x87\x91" + "\x37\xce\xcb\xd6\xac\x6a\x78\xf1" + "\x49\x8c\xdb\x0d\x68\x75\x90\xf8" + "\xcf\x5f\x31\xf8\x1e\xb7\xa3\x2b" + "\x93\x4d\x79\x0e\xc1\x3d\x3f\x57" + "\xaf\x65\xb9\xf8\x7e\x9f\x68\x48" + "\x72\xe9\x87\xd8\xf5\x9f\x4c\xb4" + "\x2c\x0e\x6a\xe6\x80\x0a\x7e\x96" + "\x1d\xbf\x11\x75\x19\x46\x1d\xd0" + "\xf0\x7c\xd5\x6a\x12\x06\xa5\xe9", + .len = 96, + }, { + .key = "\xdf\x69\x43\xe7\x81\xbb\x1f\xab" + "\x37\x6a\xe1\xbf\x66\x10\x58\xbb" + "\x35\xf1\x1c\x99\x26\xf7\xf1\x01" + "\x6c\x4b\xea\x85\x6c\xae\x09\x5f", + .klen = 32, + .iv = "\x44\x31\xfd\xcb\xc4\xe2\x63\x11" + "\x01\x18\xb6\x77\xe0\x71\xd4\xb4", + .ptext = "\xe0\x72\x90\x0a\xfa\x59\x73\xed" + "\xff\xdb\xa3\x86\x83\x44\x4b\xc2" + "\x16\x40\x82\xf2\x6e\xf1\xd8\x38" + "\x92\x3f\xd6\x3f\x65\xb5\x1b\x95" + "\x41\x21\xa1\x49\x4a\x5d\xf3\x9c" + "\xc4\xd6\x04\x45\x62\xfd\x43\x17" + "\xe6\xc9\x6e\xaf\xcd\x0a\x49\xfd" + "\x55\x7a\xc6\x00\xed\x3e\x48\x56" + "\xab\x02\xe0\xcd\x20\x93\xe4\x91" + "\x9a\x11\x05\x8b\xee\xdf\x2d\x8a" + "\xc7\xff\x0d\xeb\xff\x58\x22\xfc" + "\x92\xa4\x82\x5f\xfd\xd8\xaf\xc3" + "\xdd\x03\xa3\xa6\x22\x77\x20\xde" + "\x73\xb2\x77\x93\x60\x2e\x2c\x7f" + "\xc9\x54\x8f\x39\x6b\x84\xa1\x2b" + "\x54\x7a\x6f\x9e\x00\x56\xa4\x58" + "\x3b\x0b\x49\xb1\xf6\x7c\x9f\x42" + "\x5f\x43\x40\x85\x2a\x78\x24\x66" + "\x28\x26\x49\x9a\x25\x78\xca\x3a" + "\x15\xe9\xe5\x61\x58\xfb\x04\xac" + "\x8a\x44\xb7\x54\x47\x15\xeb\x1d" + "\xad\xc8\x9a\x3a\x38\x89\xfd\xcc" + "\x2b\x96\x42\x68\x76\xd8\xd3\x6b" + "\x67\x81\xa6\x44\x18\xae\xc6\xa0", + .ctext = "\x1a\xe7\x49\x97\x78\x92\x76\x46" + "\xd4\xc5\x20\x6e\x88\xe6\xb9\xe3" + "\x26\xab\xc3\xa8\xb8\xb8\x84\x7c" + "\xc6\x8a\x94\x8e\x3b\xb4\xca\x0a" + "\xe0\xfd\xcf\x3e\x2f\xef\xcf\x59" + "\x0f\x5f\xca\x07\xe7\x0a\xa6\xb2" + "\xe8\x47\x9b\x79\x66\x22\x20\x58" + "\x07\xe5\x48\x1c\x26\x9e\xd0\x13" + "\x1c\xa0\x2c\x2e\x5f\x5d\x06\x88" + "\xca\xf1\x5e\x91\xe5\xb6\x60\xaa" + "\x3c\xab\x1f\xfd\x8a\xe5\x99\x50" + "\x36\xf3\xb7\xf0\xa3\x19\x62\xb0" + "\x6a\x59\x4a\x34\xdd\x78\x4b\xfe" + "\x6a\x64\x09\xdf\x0e\xd0\xbe\xae" + "\x91\x2f\x85\xd6\x09\xc5\x8e\xe9" + "\xcf\xb4\x00\x41\xac\x81\x2e\x06" + "\x7c\x8e\xf8\x8e\x5e\xef\x29\x2a" + "\x93\x6c\xb7\x24\x78\xa6\x3e\x1b" + "\x02\xb4\xc3\xb7\x81\xdf\x4f\xf0" + "\x44\x8a\x4d\x1b\x70\x3b\x6d\x89" + "\x3d\xab\xc5\x96\x94\x1c\x27\x82" + "\x76\xc4\x44\x80\xaa\x9a\xf1\xb1" + "\x39\x06\x67\xb4\x8a\x23\xfe\x39" + "\xa4\x9f\xa6\xeb\x78\x4b\x81\xb7", + .len = 192, + }, { + .key = "\x8e\xde\x71\x65\x4d\x51\x07\x67" + "\x28\x85\xb5\x93\x95\xcc\x93\xf8" + "\x85\xb6\x71\x0d\x80\xd5\xed\xa9" + "\x87\x47\x0d\x3a\x8d\x42\xee\x32", + .klen = 32, + .iv = "\xb1\xfb\x43\x0e\xdc\x09\x31\xf4" + "\x44\x47\xbd\xdc\x40\x2b\xf4\x7c", + .ptext = "\x59\x02\x6b\x4e\x45\xde\xe5\xa0" + "\x84\xfd\x08\x05\xe2\xac\x0f\x11" + "\x3a\x9e\xfa\xa1\x1a\xfe\x3c\x35" + "\x0c\x48\x2c\x85\x37\x02\xdf\xad" + "\x1b\xb2\x84\xa8\x12\x84\x7e\x8a" + "\x03\x0d\x52\x96\x79\x29\xca\x61" + "\x12\x60\x42\x71\xfe\x31\xbd\x88" + "\xfd\x52\xaa\x37\xa8\x48\xd5\x77" + "\x78\x9b\x15\x08\x07\x17\x73\xd7" + "\x9f\x2b\x55\x00\x4f\x39\xa9\x03" + "\x93\xaa\x26\x1d\x54\xf0\x0b\xcf" + "\x73\x10\xca\x9e\x44\x89\xd7\x15" + "\x5d\x11\x73\xda\x01\x2b\x6d\x04" + "\x23\x99\xa6\x0b\xf5\xca\x77\x4b" + "\xd4\xf3\xd7\x8c\x55\x91\xe7\xb0" + "\x57\xb0\xc1\x8a\x5c\x54\x58\xbc" + "\x8c\xe1\x55\xa0\xa0\x37\xa6\x8d" + "\x38\x2c\xf0\xe4\xab\x1e\x57\xe9" + "\x15\x12\x67\x1e\x2f\xe8\x77\x5d" + "\x34\x96\x07\x39\x82\x2b\x23\x4b" + "\x97\x90\x71\x0e\xe9\x39\xa3\x9f" + "\xf6\xf3\xe7\x1b\xdd\x79\x41\xb3" + "\xa6\x64\x51\x29\x89\x24\x37\xeb" + "\x86\xd7\x83\xa4\xa8\x2c\xf5\x5e" + "\xa7\x5d\x4c\x7f\x71\x38\x5c\x18" + "\x43\xe0\xe2\xb9\xcd\xcd\x8a\x12" + "\xe0\xa6\xd2\x53\x2b\xcf\xe8\x52" + "\x02\x01\x40\x42\x24\xba\x30\x56" + "\x95\x4b\x34\x59\x69\xa3\x1f\xd1" + "\xca\xf2\x99\x3f\xcd\x19\xb3\x7a" + "\xc2\x33\x50\xaf\xa0\x32\x02\xcb" + "\x6d\xc4\x41\xbd\x8d\x53\x6b\x33" + "\x18\x89\x89\xc1\xc6\x8e\x01\xf5" + "\x85\xc6\xbc\xe8\x92\xae\xce\xe5" + "\x49\x84\x51\x7b\xee\xeb\x76\x84" + "\x49\x90\x84\x0b\x3f\x1b\xcf\xe6" + "\x64\x64\x4f\x06\x01\x20\xc8\xae" + "\x0b\x3c\xfb\x9d\xc3\x9c\x14\xba" + "\xb3\xa9\xb4\xae\xb7\x1d\xae\xc6" + "\xe9\x3c\x80\x28\xee\x7c\x63\x4d" + "\x53\x65\x7f\xfb\xb5\x4e\x68\xb1" + "\xc9\x1f\xcd\xcc\x94\x68\x58\x3f" + "\x6e\x4c\x40\x0d\x6a\x73\x16\x67" + "\xa6\x23\x8b\x80\x9a\x83\x51\x23" + "\x25\x2d\xf1\x39\x7e\x29\x92\x11" + "\xb0\x1e\xa5\x20\xec\x13\x91\x56" + "\xe9\xb0\x24\x68\xe4\x34\x94\x69" + "\x0c\xe4\x08\xbb\x49\x90\x26\xa3" + "\x1d\xde\x26\xbc\xe5\x4b\xe7\x0d" + "\xc2\xd1\x24\x07\xb9\xcd\x39\xf0" + "\xc3\x86\x31\x80\x9b\x2f\x83\xec" + "\x33\x1e\x92\x44\x21\x3d\xcc\x76" + "\xdc\xc5\xb7\xc9\xc2\xe7\xc7\x6d" + "\xeb\x8e\xdf\x50\xf7\x10\x20\x9c" + "\x07\x86\x62\x58\x70\x9d\xc7\x39" + "\x52\x8d\xef\xdd\xff\xcb\x1b\x35" + "\x1e\x74\x02\x05\x42\xef\x8a\x36" + "\x3f\x06\x01\x02\xbb\xc3", + .ctext = "\x8a\x31\x37\xc0\x55\x9e\x01\x47" + "\xa1\x37\x1c\x62\x7e\x79\x93\x69" + "\x6a\x76\x8b\x49\xe1\x5f\x14\x46" + "\x4f\xd1\x17\x24\xb4\x19\x05\x32" + "\xdb\x36\xa0\x52\x6e\x21\x48\x95" + "\x51\x99\xc2\xa3\x52\xdb\x45\x9f" + "\x03\x67\xc0\xe9\xdd\xf5\x44\x2b" + "\xa3\xcf\xe3\x68\x53\x7d\xf9\xf0" + "\x1a\xac\xb0\x60\xce\x60\xea\xf2" + "\xf0\x43\x8f\x03\x90\x31\x6a\xd8" + "\xe9\x8e\x8a\x6e\x58\x02\xa5\xa5" + "\x35\x68\xb3\x32\x3d\x22\xdf\x8d" + "\xda\xe2\x33\x5f\x82\xc3\xd9\x88" + "\x8d\x3e\x2c\xa9\x75\x4b\x62\x3f" + "\x39\xe6\x93\xa3\x05\xd7\xdd\xa8" + "\xac\x2a\xf4\x41\xec\xc5\xa6\xb3" + "\x2e\x3d\xb3\xa2\x88\xd2\xb2\x10" + "\x7d\x58\x89\xee\x55\x47\xb8\x5b" + "\x58\xde\x2b\x79\xb7\x38\xd6\x80" + "\x23\x72\xff\x17\x79\x02\x2b\xaa" + "\x40\xdf\xc1\x40\x56\xed\xcb\x48" + "\x19\x29\x5e\x2b\xac\xfa\x16\x2e" + "\xd5\x00\x09\x72\xb4\x24\x76\x22" + "\xcd\x11\x48\xdc\x29\x6c\xf6\x22" + "\xac\xbc\xba\x17\x35\x07\x5c\x72" + "\x36\x31\x28\xd5\xf5\x23\x4b\xe4" + "\xfe\xe5\x1c\x55\x8c\x59\x8a\x7b" + "\x2b\xbc\x1e\x8d\xf2\xf7\x8f\xc5" + "\xd3\x45\xc5\x8b\x4f\xfe\x4e\xc8" + "\x7b\x09\xd9\x5e\x80\x48\xf8\x68" + "\x19\x37\x4b\xa5\x8c\xb7\x04\x22" + "\x83\x87\x3f\x50\x0c\x16\x4a\xbe" + "\x34\x66\xd1\xd2\x55\xeb\xc1\x32" + "\x1f\xa6\xe5\x5b\x2a\x72\xfe\x83" + "\xa2\xb6\x70\x04\x65\xe9\xd9\xc7" + "\x1e\xeb\xba\x2d\x95\x58\xcd\x06" + "\x7c\xaf\x3c\x18\x3e\xdf\x2d\xc4" + "\xd7\x66\xe6\x73\x37\x57\xff\x57" + "\x4a\x5f\x60\xcd\x6a\x45\x89\x4b" + "\xd0\x1f\x8d\x86\x15\x0c\x4b\x14" + "\x14\xa0\xfb\x65\xc1\x5d\xa4\x56" + "\x30\x3f\x1c\x1d\x5b\xea\x54\x5c" + "\x28\x35\x89\x2c\x60\x29\xc5\x28" + "\x13\x7c\x8a\xff\x89\xeb\x09\x09" + "\x7b\xda\x8c\x8d\xa3\x68\xa8\x7e" + "\x90\xe5\xd9\xe0\x74\x00\x0e\xf9" + "\x1b\x97\xc0\xde\xc6\x99\xe9\xff" + "\x4a\x0d\xde\x81\x61\x99\x02\xe7" + "\x34\x86\x41\x5a\x7d\xd7\x5c\x32" + "\xe8\x54\xe6\xd0\x67\xa5\xa7\xc9" + "\x1a\xde\xbe\x1f\x81\xb9\x10\x1b" + "\x18\xd1\x6f\x58\x2f\x38\x93\xfc" + "\x97\xde\xe8\xd1\x5e\x8e\x34\x34" + "\xe0\x32\xb2\x84\x27\x02\x0c\x51" + "\x7d\xd2\x77\xb8\xa5\x76\xb7\x06" + "\xb0\x03\x71\x03\x07\x91\x73\xc7" + "\x90\xd7\x13\xfa\xbf\x27\x2a\xaa" + "\xb6\x73\x19\x0e\xbb\xd6", + .len = 462, + }, +}; + static const struct cipher_testvec chacha20_tv_template[] = { { /* RFC7539 A.2. Test Vector #1 */ .key = "\x00\x00\x00\x00\x00\x00\x00\x00" From patchwork Fri Jan 12 02:28:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dongsoo Lee X-Patchwork-Id: 13517908 Received: from mail.nsr.re.kr (unknown [210.104.33.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 45AA1D285; Fri, 12 Jan 2024 02:30:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nsr.re.kr Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nsr.re.kr Received: from 210.104.33.70 (nsr.re.kr) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128 bits)) by mail.nsr.re.kr with SMTP; Fri, 12 Jan 2024 11:30:08 +0900 X-Sender: letrhee@nsr.re.kr Received: from 192.168.155.188 ([192.168.155.188]) by mail.nsr.re.kr (Crinity Message Backbone-7.0.1) with SMTP ID 155; Fri, 12 Jan 2024 11:30:03 +0900 (KST) From: Dongsoo Lee To: Herbert Xu , "David S. Miller" , Jens Axboe , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" Cc: linux-crypto@vger.kernel.org, linux-block@vger.kernel.org, linux-fscrypt@vger.kernel.org, linux-kernel@vger.kernel.org, Dongsoo Lee Subject: [PATCH v6 RESEND 3/5] blk-crypto: Add LEA-256-XTS blk-crypto support Date: Fri, 12 Jan 2024 02:28:57 +0000 Message-Id: <20240112022859.2384-4-letrhee@nsr.re.kr> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240112022859.2384-1-letrhee@nsr.re.kr> References: <20240112022859.2384-1-letrhee@nsr.re.kr> Precedence: bulk X-Mailing-List: linux-block@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add LEA-256-XTS blk-crypto support LEA is a 128-bit block cipher developed by South Korea. LEA is a Korean national standard (KS X 3246) and included in the ISO/IEC 29192-2:2019 standard (Information security - Lightweight cryptography - Part 2: Block ciphers). Enable the LEA to be used in block inline encryption. This can be used via blk-crypto-fallback, when using the "inlinecrypt" mount option in fscrypt. Signed-off-by: Dongsoo Lee --- block/blk-crypto.c | 6 ++++++ include/linux/blk-crypto.h | 1 + 2 files changed, 7 insertions(+) diff --git a/block/blk-crypto.c b/block/blk-crypto.c index 4d760b092deb..b847706bbc59 100644 --- a/block/blk-crypto.c +++ b/block/blk-crypto.c @@ -43,6 +43,12 @@ const struct blk_crypto_mode blk_crypto_modes[] = { .keysize = 32, .ivsize = 16, }, + [BLK_ENCRYPTION_MODE_LEA_256_XTS] = { + .name = "LEA-256-XTS", + .cipher_str = "xts(lea)", + .keysize = 64, + .ivsize = 16, + }, }; /* diff --git a/include/linux/blk-crypto.h b/include/linux/blk-crypto.h index 5e5822c18ee4..b6bf2a5c58ed 100644 --- a/include/linux/blk-crypto.h +++ b/include/linux/blk-crypto.h @@ -14,6 +14,7 @@ enum blk_crypto_mode_num { BLK_ENCRYPTION_MODE_AES_128_CBC_ESSIV, BLK_ENCRYPTION_MODE_ADIANTUM, BLK_ENCRYPTION_MODE_SM4_XTS, + BLK_ENCRYPTION_MODE_LEA_256_XTS, BLK_ENCRYPTION_MODE_MAX, }; From patchwork Fri Jan 12 02:28:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dongsoo Lee X-Patchwork-Id: 13517909 Received: from mail.nsr.re.kr (unknown [210.104.33.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B5F9814A80; Fri, 12 Jan 2024 02:30:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nsr.re.kr Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nsr.re.kr Received: from 210.104.33.70 (nsr.re.kr) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128 bits)) by mail.nsr.re.kr with SMTP; Fri, 12 Jan 2024 11:30:21 +0900 X-Sender: letrhee@nsr.re.kr Received: from 192.168.155.188 ([192.168.155.188]) by mail.nsr.re.kr (Crinity Message Backbone-7.0.1) with SMTP ID 155; Fri, 12 Jan 2024 11:30:17 +0900 (KST) From: Dongsoo Lee To: Herbert Xu , "David S. Miller" , Jens Axboe , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" Cc: linux-crypto@vger.kernel.org, linux-block@vger.kernel.org, linux-fscrypt@vger.kernel.org, linux-kernel@vger.kernel.org, Dongsoo Lee Subject: [PATCH v6 RESEND 4/5] fscrypt: Add LEA-256-XTS, LEA-256-CTS support Date: Fri, 12 Jan 2024 02:28:58 +0000 Message-Id: <20240112022859.2384-5-letrhee@nsr.re.kr> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240112022859.2384-1-letrhee@nsr.re.kr> References: <20240112022859.2384-1-letrhee@nsr.re.kr> Precedence: bulk X-Mailing-List: linux-block@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 It uses LEA-256-XTS for file encryption and LEA-256-CTS-CBC for filename encryption. Includes constant changes as the number of supported ciphers increases. Signed-off-by: Dongsoo Lee --- fs/crypto/fscrypt_private.h | 2 +- fs/crypto/keysetup.c | 15 +++++++++++++++ fs/crypto/policy.c | 4 ++++ include/uapi/linux/fscrypt.h | 4 +++- tools/include/uapi/linux/fscrypt.h | 4 +++- 5 files changed, 26 insertions(+), 3 deletions(-) diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h index 1892356cf924..1f0502999804 100644 --- a/fs/crypto/fscrypt_private.h +++ b/fs/crypto/fscrypt_private.h @@ -31,7 +31,7 @@ #define FSCRYPT_CONTEXT_V2 2 /* Keep this in sync with include/uapi/linux/fscrypt.h */ -#define FSCRYPT_MODE_MAX FSCRYPT_MODE_AES_256_HCTR2 +#define FSCRYPT_MODE_MAX FSCRYPT_MODE_LEA_256_CTS struct fscrypt_context_v1 { u8 version; /* FSCRYPT_CONTEXT_V1 */ diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c index d71f7c799e79..f8b0116e43a3 100644 --- a/fs/crypto/keysetup.c +++ b/fs/crypto/keysetup.c @@ -74,6 +74,21 @@ struct fscrypt_mode fscrypt_modes[] = { .security_strength = 32, .ivsize = 32, }, + [FSCRYPT_MODE_LEA_256_XTS] = { + .friendly_name = "LEA-256-XTS", + .cipher_str = "xts(lea)", + .keysize = 64, + .security_strength = 32, + .ivsize = 16, + .blk_crypto_mode = BLK_ENCRYPTION_MODE_LEA_256_XTS, + }, + [FSCRYPT_MODE_LEA_256_CTS] = { + .friendly_name = "LEA-256-CTS-CBC", + .cipher_str = "cts(cbc(lea))", + .keysize = 32, + .security_strength = 32, + .ivsize = 16, + }, }; static DEFINE_MUTEX(fscrypt_mode_key_setup_mutex); diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c index 701259991277..b9bb175a11c7 100644 --- a/fs/crypto/policy.c +++ b/fs/crypto/policy.c @@ -94,6 +94,10 @@ static bool fscrypt_valid_enc_modes_v2(u32 contents_mode, u32 filenames_mode) filenames_mode == FSCRYPT_MODE_SM4_CTS) return true; + if (contents_mode == FSCRYPT_MODE_LEA_256_XTS && + filenames_mode == FSCRYPT_MODE_LEA_256_CTS) + return true; + return fscrypt_valid_enc_modes_v1(contents_mode, filenames_mode); } diff --git a/include/uapi/linux/fscrypt.h b/include/uapi/linux/fscrypt.h index 7a8f4c290187..c3c5a04f85c8 100644 --- a/include/uapi/linux/fscrypt.h +++ b/include/uapi/linux/fscrypt.h @@ -30,7 +30,9 @@ #define FSCRYPT_MODE_SM4_CTS 8 #define FSCRYPT_MODE_ADIANTUM 9 #define FSCRYPT_MODE_AES_256_HCTR2 10 -/* If adding a mode number > 10, update FSCRYPT_MODE_MAX in fscrypt_private.h */ +#define FSCRYPT_MODE_LEA_256_XTS 11 +#define FSCRYPT_MODE_LEA_256_CTS 12 +/* If adding a mode number > 12, update FSCRYPT_MODE_MAX in fscrypt_private.h */ /* * Legacy policy version; ad-hoc KDF and no key verification. diff --git a/tools/include/uapi/linux/fscrypt.h b/tools/include/uapi/linux/fscrypt.h index 7a8f4c290187..c3c5a04f85c8 100644 --- a/tools/include/uapi/linux/fscrypt.h +++ b/tools/include/uapi/linux/fscrypt.h @@ -30,7 +30,9 @@ #define FSCRYPT_MODE_SM4_CTS 8 #define FSCRYPT_MODE_ADIANTUM 9 #define FSCRYPT_MODE_AES_256_HCTR2 10 -/* If adding a mode number > 10, update FSCRYPT_MODE_MAX in fscrypt_private.h */ +#define FSCRYPT_MODE_LEA_256_XTS 11 +#define FSCRYPT_MODE_LEA_256_CTS 12 +/* If adding a mode number > 12, update FSCRYPT_MODE_MAX in fscrypt_private.h */ /* * Legacy policy version; ad-hoc KDF and no key verification. From patchwork Fri Jan 12 02:28:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dongsoo Lee X-Patchwork-Id: 13517910 Received: from mail.nsr.re.kr (unknown [210.104.33.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7377C171C8; Fri, 12 Jan 2024 02:30:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nsr.re.kr Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nsr.re.kr Received: from 210.104.33.70 (nsr.re.kr) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128 bits)) by mail.nsr.re.kr with SMTP; Fri, 12 Jan 2024 11:30:34 +0900 X-Sender: letrhee@nsr.re.kr Received: from 192.168.155.188 ([192.168.155.188]) by mail.nsr.re.kr (Crinity Message Backbone-7.0.1) with SMTP ID 155; Fri, 12 Jan 2024 11:30:30 +0900 (KST) From: Dongsoo Lee To: Herbert Xu , "David S. Miller" , Jens Axboe , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" Cc: linux-crypto@vger.kernel.org, linux-block@vger.kernel.org, linux-fscrypt@vger.kernel.org, linux-kernel@vger.kernel.org, Dongsoo Lee Subject: [PATCH v6 RESEND 5/5] crypto: LEA block cipher x86_64 optimization Date: Fri, 12 Jan 2024 02:28:59 +0000 Message-Id: <20240112022859.2384-6-letrhee@nsr.re.kr> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240112022859.2384-1-letrhee@nsr.re.kr> References: <20240112022859.2384-1-letrhee@nsr.re.kr> Precedence: bulk X-Mailing-List: linux-block@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 For the x86_64 environment, we use AVX-512F/AVX2/SSE2 instructions. Since LEA uses 128-bit blocks of four 32-bit integers, for optimization, SSE2 encrypts 4 blocks, AVX2 encrypts 4/8 blocks, and AVX-512F encrypts 4/8/16 blocks at a time. Our submission provides a optimized implementation of ECB, CBC decryption, CTR, and XTS cipher operation modes on x86_64 CPUs supporting. Signed-off-by: Dongsoo Lee --- arch/x86/crypto/Kconfig | 29 + arch/x86/crypto/Makefile | 3 + arch/x86/crypto/lea-x86_64-asm.S | 2272 +++++++++++++++++++++++++++++ arch/x86/crypto/lea-x86_64-glue.c | 820 +++++++++++ 4 files changed, 3124 insertions(+) create mode 100644 arch/x86/crypto/lea-x86_64-asm.S create mode 100644 arch/x86/crypto/lea-x86_64-glue.c diff --git a/arch/x86/crypto/Kconfig b/arch/x86/crypto/Kconfig index 9bbfd01cfa2f..5acd8794cab4 100644 --- a/arch/x86/crypto/Kconfig +++ b/arch/x86/crypto/Kconfig @@ -342,6 +342,35 @@ config CRYPTO_ARIA_GFNI_AVX512_X86_64 Processes 64 blocks in parallel. +config CRYPTO_LEA_X86_64 + tristate "Ciphers: LEA with modes: ECB, CBC, CTR, XTS (SSE2/AVX2/AVX-512F)" + depends on X86 && 64BIT + select CRYPTO_LEA + imply CRYPTO_XTS + imply CRYPTO_CTR + help + LEA is a 128-bit lightweight block cipher developed by South Korea. + + LEA is the a Korean standard (KS X 3246) and is included in the + ISO/IEC 29192-2:2019 standard (Information security - Lightweight + cryptography - Part 2: Block ciphers). + + It consists of 32-bit integer addition, rotation, and XOR, which can + be performed effectively on CPUs that support 32-bit operations. + + It supports 128-bit, 192-bit, and 256-bit keys. + + See: + https://seed.kisa.or.kr/kisa/algorithm/EgovLeaInfo.do + + Architecture: x86_64 using: + - SSE2 (Streaming SIMD Extensions 2) + - AVX2 (Advanced Vector Extensions) + - AVX-512F (Advanced Vector Extensions-512F) + + Processes 4(SSE2, AVX2, AVX-512F), 8(AVX2, AVX-512F), 16(AVX-512F) + blocks in parallel. + config CRYPTO_CHACHA20_X86_64 tristate "Ciphers: ChaCha20, XChaCha20, XChaCha12 (SSSE3/AVX2/AVX-512VL)" depends on X86 && 64BIT diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile index 9aa46093c91b..3c44d43d155d 100644 --- a/arch/x86/crypto/Makefile +++ b/arch/x86/crypto/Makefile @@ -109,6 +109,9 @@ aria-aesni-avx2-x86_64-y := aria-aesni-avx2-asm_64.o aria_aesni_avx2_glue.o obj-$(CONFIG_CRYPTO_ARIA_GFNI_AVX512_X86_64) += aria-gfni-avx512-x86_64.o aria-gfni-avx512-x86_64-y := aria-gfni-avx512-asm_64.o aria_gfni_avx512_glue.o +obj-$(CONFIG_CRYPTO_LEA_X86_64) += lea-x86_64.o +lea-x86_64-y := lea-x86_64-asm.o lea-x86_64-glue.o + quiet_cmd_perlasm = PERLASM $@ cmd_perlasm = $(PERL) $< > $@ $(obj)/%.S: $(src)/%.pl FORCE diff --git a/arch/x86/crypto/lea-x86_64-asm.S b/arch/x86/crypto/lea-x86_64-asm.S new file mode 100644 index 000000000000..97e29e1158b8 --- /dev/null +++ b/arch/x86/crypto/lea-x86_64-asm.S @@ -0,0 +1,2272 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * LEA Cipher SSE2/AVX2/AVX-512F parallel algorithm. + * + * - SSE2: 4 parallel blocks + * - AVX2: 8/4 parallel blocks + * - AVX-512F: 16/8/4 parallel blocks + * + * Copyright (c) 2023 National Security Research. + * Author: Dongsoo Lee + */ + +#include +#include + +.file "lea_x86_64-asm.S" + + +.section .text + +#define PASTE1(a,b) a##b + +#define LEA_MAX_KEYLENGTH (32 * 6 * 4) + +#define LEA_CTX_RK_ENC (0) +#define LEA_CTX_RK_DEC (LEA_MAX_KEYLENGTH) +#define LEA_CTX_ROUND (LEA_MAX_KEYLENGTH * 2) + +#define LOAD_CTR(addr, high, low) \ + mov (addr), high; \ + mov 8(addr), low; \ + bswap high; \ + bswap low + +#define ADD_CTR_AND_STORE(high, low, addr, val) \ + add val, low; \ + adc $0, high; \ + bswap high; \ + bswap low; \ + mov high, (addr); \ + mov low, 8(addr) + +#define XTS_TW_X0 %xmm12 +#define XTS_TW_X1 %xmm13 +#define XTS_TW_I2 %xmm0 +#define XTS_TW_O2 %xmm14 +#define XTS_TW_X3 %xmm15 +#define XTS_TW_X4 %xmm8 +#define XTS_TW_X5 %xmm9 +#define XTS_TW_I6 %xmm1 +#define XTS_TW_O6 %xmm10 +#define XTS_TW_X7 %xmm11 +#define XTS_TW_X8 %xmm2 +#define XTS_MASK %xmm7 + +#define XTS_TW_Y0 %ymm12 +#define XTS_TW_Y1 %ymm13 +#define XTS_TW_Y2 %ymm14 +#define XTS_TW_Y3 %ymm15 + + +#define BSWAPMASK_XMM %xmm7 +#define CTRCONST_XMM %xmm8 + +#define BSWAPMASK_YMM %ymm7 +#define CTRCONST_YMM %ymm8 + +#define CTR_64_low_src %rax +#define CTR_64_high_src %r9 +#define CTR_64_low %r10 +#define CTR_64_high %r11 + +#define XMM(n) PASTE1(%xmm, n) +#define YMM(n) PASTE1(%ymm, n) + +#ifdef CONFIG_AS_AVX512 + +#define ZMM(n) PASTE1(%zmm, n) + +#define XTS_TW_Z0 %zmm12 +#define XTS_TW_Z1 %zmm13 +#define XTS_TW_Z2 %zmm14 +#define XTS_TW_Z3 %zmm15 + +#define BSWAPMASK_ZMM %zmm7 +#define CTRCONST_ZMM %zmm8 + +#endif + +/* XOR, ADD, ROTR */ +#define XAR_SSE2(v0, v1, cur, pre, tmp1, tmp2, rk1, rk2)\ + movd rk1, tmp1; \ + movd rk2, tmp2; \ + pshufd $0, tmp1, tmp1; \ + pshufd $0, tmp2, tmp2; \ + pxor pre, tmp1; \ + pxor tmp2, cur; \ + paddd cur, tmp1; \ + movdqa tmp1, cur; \ + psrld v0, tmp1; \ + pslld v1, cur; \ + pxor tmp1, cur; + +#define XAR_AVX2(v0, v1, cur, pre, tmp1, tmp2, rk1, rk2)\ + vpbroadcastd rk1, tmp1; \ + vpbroadcastd rk2, tmp2; \ + vpxor pre, tmp1, tmp1; \ + vpxor tmp2, cur, cur; \ + vpaddd cur, tmp1, tmp1; \ + vpsrld v0, tmp1, cur; \ + vpslld v1, tmp1, tmp1; \ + vpxor tmp1, cur, cur; + +#ifdef CONFIG_AS_AVX512 +#define XAR_AVX512(v0, _v1, cur, pre, tmp1, tmp2, rk1, rk2) \ + vpbroadcastd rk1, tmp1; \ + vpbroadcastd rk2, tmp2; \ + vpxord pre, tmp1, tmp1; \ + vpxord tmp2, cur, cur; \ + vpaddd cur, tmp1, tmp1; \ + vprord v0, tmp1, cur; +#endif + +/* XOR, SUB, ROTR */ +#define XSR9_SSE2(v0, v3, tnext, tmp1, tmp2, rk1, rk2) \ + movd rk1, tmp1; \ + movdqa v0, tnext; \ + psrld $9, v0; \ + pslld $23, tnext; \ + pshufd $0, tmp1, tmp1; \ + pxor v0, tnext; \ + movd rk2, v0; \ + pxor v3, tmp1; \ + pshufd $0, v0, v0; \ + psubd tmp1, tnext; \ + pxor tnext, v0; + +#define XSR5_SSE2(v1, tnext, tmp1, tmp2, rk1, rk2) \ + movd rk1, tmp1; \ + pshufd $0, tmp1, tmp1; \ + pxor tnext, tmp1; \ + movdqa v1, tnext; \ + psrld $27, v1; \ + pslld $5, tnext; \ + pxor v1, tnext; \ + movd rk2, v1; \ + pshufd $0, v1, v1; \ + psubd tmp1, tnext; \ + pxor tnext, v1; + +#define XSR3_SSE2(v2, tnext, tmp1, tmp2, rk1, rk2) \ + movd rk1, tmp1; \ + movdqa v2, tmp2; \ + psrld $29, v2; \ + pslld $3, tmp2; \ + pshufd $0, tmp1, tmp1; \ + pxor tmp2, v2; \ + movd rk2, tmp2; \ + pxor tnext, tmp1; \ + pshufd $0, tmp2, tmp2; \ + psubd tmp1, v2; \ + pxor tmp2, v2; + +#define XSR9_AVX2(v0, v3, tnext, tmp1, tmp2, rk1, rk2) \ + vpbroadcastd rk1, tmp1; \ + vpsrld $9, v0, tmp2; \ + vpslld $23, v0, v0; \ + vpxor v3, tmp1, tmp1; \ + vpxor tmp2, v0, v0; \ + vpbroadcastd rk2, tmp2; \ + vpsubd tmp1, v0, tnext; \ + vpxor tmp2, tnext, v0; + +#define XSR5_AVX2(v1, tnext, tmp1, tmp2, rk1, rk2) \ + vpbroadcastd rk1, tmp1; \ + vpsrld $27, v1, tmp2; \ + vpslld $5, v1, v1; \ + vpxor tnext, tmp1, tmp1; \ + vpxor tmp2, v1, v1; \ + vpbroadcastd rk2, tmp2; \ + vpsubd tmp1, v1, tnext; \ + vpxor tmp2, tnext, v1; + +#define XSR3_AVX2(v2, tnext, tmp1, tmp2, rk1, rk2) \ + vpbroadcastd rk1, tmp1; \ + vpsrld $29, v2, tmp2; \ + vpslld $3, v2, v2; \ + vpxor tnext, tmp1, tmp1; \ + vpxor tmp2, v2, v2; \ + vpbroadcastd rk2, tmp2; \ + vpsubd tmp1, v2, v2; \ + vpxor tmp2, v2, v2; + +#ifdef CONFIG_AS_AVX512 +#define XSR9_AVX512(v0, v3, tnext, tmp1, tmp2, rk1, rk2)\ + vpbroadcastd rk1, tmp1; \ + vpbroadcastd rk2, tmp2; \ + vprord $9, v0, v0; \ + vpxord v3, tmp1, tmp1; \ + vpsubd tmp1, v0, tnext; \ + vpxord tmp2, tnext, v0 + +#define XSR5_AVX512(v1, tnext, tmp1, tmp2, rk1, rk2) \ + vpbroadcastd rk1, tmp1; \ + vpbroadcastd rk2, tmp2; \ + vprold $5, v1, v1; \ + vpxord tnext, tmp1, tmp1; \ + vpsubd tmp1, v1, tnext; \ + vpxord tmp2, tnext, v1 + +#define XSR3_AVX512(v2, tnext, tmp1, tmp2, rk1, rk2) \ + vpbroadcastd rk1, tmp1; \ + vpbroadcastd rk2, tmp2; \ + vprold $3, v2, v2; \ + vpxord tnext, tmp1, tmp1; \ + vpsubd tmp1, v2, tnext; \ + vpxord tmp2, tnext, v2 +#endif + +#define XAR3(SIMD, cur, pre, tmp1, tmp2, rk1, rk2) \ + PASTE1(XAR_,SIMD)($3, $29, cur, pre, tmp1, tmp2, rk1, rk2) + +#define XAR5(SIMD, cur, pre, tmp1, tmp2, rk1, rk2) \ + PASTE1(XAR_,SIMD)($5, $27, cur, pre, tmp1, tmp2, rk1, rk2) + +#define XAR9(SIMD, cur, pre, tmp1, tmp2, rk1, rk2) \ + PASTE1(XAR_,SIMD)($23, $9, cur, pre, tmp1, tmp2, rk1, rk2) + +#define XSR9(SIMD, v0, v3, tnext, tmp1, tmp2, rk1, rk2) \ + PASTE1(XSR9_,SIMD)(v0, v3, tnext, tmp1, tmp2, rk1, rk2) + +#define XSR5(SIMD, v1, tnext, tmp1, tmp2, rk1, rk2) \ + PASTE1(XSR5_,SIMD)(v1, tnext, tmp1, tmp2, rk1, rk2) + +#define XSR3(SIMD, v2, tnext, tmp1, tmp2, rk1, rk2) \ + PASTE1(XSR3_,SIMD)(v2, tnext, tmp1, tmp2, rk1, rk2) + +/* Could be replaced by the VPGATHERDD command, + * but was not used because it is known to have a non-optimized architecture. +*/ +#define GATHER4_AVX2(i, j, mem) \ + vmovd (j + 0 * 16)(mem), XMM(i); \ + vpinsrd $0x1, (j + 1 * 16)(mem), XMM(i), XMM(i);\ + vpinsrd $0x2, (j + 2 * 16)(mem), XMM(i), XMM(i);\ + vpinsrd $0x3, (j + 3 * 16)(mem), XMM(i), XMM(i); + +#define GATHER8_AVX2(i, ti, j, mem) \ + vmovd (j + 0 * 16)(mem), XMM(i); \ + vpinsrd $0x1, (j + 1 * 16)(mem), XMM(i), XMM(i); \ + vpinsrd $0x2, (j + 2 * 16)(mem), XMM(i), XMM(i); \ + vpinsrd $0x3, (j + 3 * 16)(mem), XMM(i), XMM(i); \ + vmovd (j + 4 * 16)(mem), XMM(ti); \ + vpinsrd $0x1, (j + 5 * 16)(mem), XMM(ti), XMM(ti); \ + vpinsrd $0x2, (j + 6 * 16)(mem), XMM(ti), XMM(ti); \ + vpinsrd $0x3, (j + 7 * 16)(mem), XMM(ti), XMM(ti); \ + vinserti128 $0x1, XMM(ti), YMM(i), YMM(i); + +#ifdef CONFIG_AS_AVX512 +#define GATHER16_AVX512(i, ti, j, mem) \ + vmovd (j + 0 * 16)(mem), XMM(i); \ + vpinsrd $0x1, (j + 1 * 16)(mem), XMM(i), XMM(i); \ + vpinsrd $0x2, (j + 2 * 16)(mem), XMM(i), XMM(i); \ + vpinsrd $0x3, (j + 3 * 16)(mem), XMM(i), XMM(i); \ + vmovd (j + 4 * 16)(mem), XMM(ti); \ + vpinsrd $0x1, (j + 5 * 16)(mem), XMM(ti), XMM(ti); \ + vpinsrd $0x2, (j + 6 * 16)(mem), XMM(ti), XMM(ti); \ + vpinsrd $0x3, (j + 7 * 16)(mem), XMM(ti), XMM(ti); \ + vinserti32x4 $0x1, XMM(ti), ZMM(i), ZMM(i); \ + vmovd (j + 8 * 16)(mem), XMM(ti); \ + vpinsrd $0x1, (j + 9 * 16)(mem), XMM(ti), XMM(ti); \ + vpinsrd $0x2, (j + 10 * 16)(mem), XMM(ti), XMM(ti); \ + vpinsrd $0x3, (j + 11 * 16)(mem), XMM(ti), XMM(ti); \ + vinserti32x4 $0x2, XMM(ti), ZMM(i), ZMM(i); \ + vmovd (j + 12 * 16)(mem), XMM(ti); \ + vpinsrd $0x1, (j + 13 * 16)(mem), XMM(ti), XMM(ti); \ + vpinsrd $0x2, (j + 14 * 16)(mem), XMM(ti), XMM(ti); \ + vpinsrd $0x3, (j + 15 * 16)(mem), XMM(ti), XMM(ti); \ + vinserti32x4 $0x3, XMM(ti), ZMM(i), ZMM(i); +#endif + +#define GATHER_BLOCK4_AVX2(i0, i1, i2, i3, mem) \ + GATHER4_AVX2(i0, 0, mem); \ + GATHER4_AVX2(i1, 4, mem); \ + GATHER4_AVX2(i2, 8, mem); \ + GATHER4_AVX2(i3, 12, mem); + +#define GATHER_BLOCK8_AVX2(i0, i1, i2, i3, ti0, mem) \ + GATHER8_AVX2(i0, ti0, 0, mem); \ + GATHER8_AVX2(i1, ti0, 4, mem); \ + GATHER8_AVX2(i2, ti0, 8, mem); \ + GATHER8_AVX2(i3, ti0, 12, mem); + +#ifdef CONFIG_AS_AVX512 +#define GATHER_BLOCK8_AVX512(i0, i1, i2, i3, mask, mem) \ + GATHER8_AVX512(i0, mask, 0, mem); \ + GATHER8_AVX512(i1, mask, 4, mem); \ + GATHER8_AVX512(i2, mask, 8, mem); \ + GATHER8_AVX512(i3, mask, 12, mem); + +#define GATHER_BLOCK16_AVX512(i0, i1, i2, i3, ti1, mem) \ + GATHER16_AVX512(i0, ti1, 0, mem); \ + GATHER16_AVX512(i1, ti1, 4, mem); \ + GATHER16_AVX512(i2, ti1, 8, mem); \ + GATHER16_AVX512(i3, ti1, 12, mem); +#endif + +#define SCATTER4_AVX2(i, j, mem) \ + vpextrd $0x0, XMM(i), (j + 0 * 16)(mem);\ + vpextrd $0x1, XMM(i), (j + 1 * 16)(mem);\ + vpextrd $0x2, XMM(i), (j + 2 * 16)(mem);\ + vpextrd $0x3, XMM(i), (j + 3 * 16)(mem); + +#define SCATTER8_AVX2(i, j, mem) \ + vpextrd $0x0, XMM(i), (j + 0 * 16)(mem);\ + vpextrd $0x1, XMM(i), (j + 1 * 16)(mem);\ + vpextrd $0x2, XMM(i), (j + 2 * 16)(mem);\ + vpextrd $0x3, XMM(i), (j + 3 * 16)(mem);\ + vextracti128 $0x1, YMM(i), XMM(i); \ + vpextrd $0x0, XMM(i), (j + 4 * 16)(mem);\ + vpextrd $0x1, XMM(i), (j + 5 * 16)(mem);\ + vpextrd $0x2, XMM(i), (j + 6 * 16)(mem);\ + vpextrd $0x3, XMM(i), (j + 7 * 16)(mem); + +#ifdef CONFIG_AS_AVX512 +/* Could be replaced by the VPSCATTERDD command */ +#define SCATTER16_AVX512(i, ti, j, mem) \ + vpextrd $0x0, XMM(i), (j + 0 * 16)(mem); \ + vpextrd $0x1, XMM(i), (j + 1 * 16)(mem); \ + vpextrd $0x2, XMM(i), (j + 2 * 16)(mem); \ + vpextrd $0x3, XMM(i), (j + 3 * 16)(mem); \ + vextracti32x4 $0x1, ZMM(i), XMM(ti); \ + vpextrd $0x0, XMM(ti), (j + 4 * 16)(mem); \ + vpextrd $0x1, XMM(ti), (j + 5 * 16)(mem); \ + vpextrd $0x2, XMM(ti), (j + 6 * 16)(mem); \ + vpextrd $0x3, XMM(ti), (j + 7 * 16)(mem); \ + vextracti32x4 $0x2, ZMM(i), XMM(ti); \ + vpextrd $0x0, XMM(ti), (j + 8 * 16)(mem); \ + vpextrd $0x1, XMM(ti), (j + 9 * 16)(mem); \ + vpextrd $0x2, XMM(ti), (j + 10 * 16)(mem); \ + vpextrd $0x3, XMM(ti), (j + 11 * 16)(mem); \ + vextracti32x4 $0x3, ZMM(i), XMM(ti); \ + vpextrd $0x0, XMM(ti), (j + 12 * 16)(mem); \ + vpextrd $0x1, XMM(ti), (j + 13 * 16)(mem); \ + vpextrd $0x2, XMM(ti), (j + 14 * 16)(mem); \ + vpextrd $0x3, XMM(ti), (j + 15 * 16)(mem); +#endif + +#define SCATTER_BLOCK4_AVX2(i0, i1, i2, i3, mem)\ + SCATTER4_AVX2(i0, 0, mem); \ + SCATTER4_AVX2(i1, 4, mem); \ + SCATTER4_AVX2(i2, 8, mem); \ + SCATTER4_AVX2(i3, 12, mem); + +#define SCATTER_BLOCK8_AVX2(i0, i1, i2, i3, mem)\ + SCATTER8_AVX2(i0, 0, mem); \ + SCATTER8_AVX2(i1, 4, mem); \ + SCATTER8_AVX2(i2, 8, mem); \ + SCATTER8_AVX2(i3, 12, mem); + +#ifdef CONFIG_AS_AVX512 +#define SCATTER_BLOCK16_AVX512(i0, i1, i2, i3, ti, mem) \ + SCATTER16_AVX512(i0, ti, 0, mem);\ + SCATTER16_AVX512(i1, ti, 4, mem);\ + SCATTER16_AVX512(i2, ti, 8, mem);\ + SCATTER16_AVX512(i3, ti, 12, mem); +#endif + +#define LOAD_BLOCK4_SSE2(x0, x1, x2, x3, mem) \ + movdqu 0 * 16(mem), x0; \ + movdqu 1 * 16(mem), x1; \ + movdqu 2 * 16(mem), x2; \ + movdqu 3 * 16(mem), x3; + +#define LOAD_BLOCK4_AVX2(x0, x1, x2, x3, mem) \ + vmovdqu 0 * 16(mem), x0; \ + vmovdqu 1 * 16(mem), x1; \ + vmovdqu 2 * 16(mem), x2; \ + vmovdqu 3 * 16(mem), x3; + +#define STORE_BLOCK4_SSE2(x0, x1, x2, x3, mem) \ + movdqu x0, 0 * 16(mem); \ + movdqu x1, 1 * 16(mem); \ + movdqu x2, 2 * 16(mem); \ + movdqu x3, 3 * 16(mem); + +#define STORE_BLOCK4_AVX2(x0, x1, x2, x3, mem) \ + vmovdqu x0, 0 * 16(mem); \ + vmovdqu x1, 1 * 16(mem); \ + vmovdqu x2, 2 * 16(mem); \ + vmovdqu x3, 3 * 16(mem); + +#define TRANSPOSE_BLOCK4_SSE2(x0, x1, out_x2, x3, tmp, in_x2) \ + movdqa x0, out_x2; \ + movdqa in_x2, tmp; \ + punpckldq x1, x0; \ + punpckhdq x1, out_x2; \ + punpckldq x3, tmp; \ + punpckhdq x3, in_x2; \ + \ + movdqa x0, x1; \ + movdqa out_x2, x3; \ + punpcklqdq tmp, x0; \ + punpckhqdq tmp, x1; \ + punpcklqdq in_x2, out_x2; \ + punpckhqdq in_x2, x3; + +#define TRANSPOSE_BLOCK4_AVX2(x0, x1, out_x2, x3, tmp, in_x2) \ + vpunpckhdq x1, x0, out_x2; \ + vpunpckldq x1, x0, x0; \ + vpunpckldq x3, in_x2, tmp; \ + vpunpckhdq x3, in_x2, in_x2; \ + \ + vpunpckhqdq tmp, x0, x1; \ + vpunpcklqdq tmp, x0, x0; \ + vpunpckhqdq in_x2, out_x2, x3; \ + vpunpcklqdq in_x2, out_x2, out_x2; + +#define XOR_BLOCK3_SSE2(x0, x1, x2, mem)\ + pxor 0 * 16(mem), x0; \ + pxor 1 * 16(mem), x1; \ + pxor 2 * 16(mem), x2; + +#define XOR_BLOCK3_AVX2(x0, x1, x2, mem)\ + vpxor 0 * 16(mem), x0, x0; \ + vpxor 1 * 16(mem), x1, x1; \ + vpxor 2 * 16(mem), x2, x2; + +#define GEN_CTR_BLOCK_AVX2(x0, x1, x2, x3, xtmp, xcarry, bswapmask, ctrconst, ctr) \ + vpbroadcastd (3 * 4)(ctr), x3; \ + vpbroadcastd (2 * 4)(ctr), x2; \ + vpbroadcastd (1 * 4)(ctr), x1; \ + vpbroadcastd (0 * 4)(ctr), x0; \ + vpshufb bswapmask, x3, x3; \ + vpshufb bswapmask, x2, x2; \ + vpshufb bswapmask, x1, x1; \ + vpshufb bswapmask, x0, x0; \ + \ + vpaddd ctrconst, x3, xtmp; \ + vpandn x3, xtmp, xcarry; \ + vpsrld $31, xcarry, xcarry; \ + vpshufb bswapmask, xtmp, x3; \ + \ + vpaddd xcarry, x2, xtmp; \ + vpandn x2, xtmp, xcarry; \ + vpsrld $31, xcarry, xcarry; \ + vpshufb bswapmask, xtmp, x2; \ + \ + vpaddd xcarry, x1, xtmp; \ + vpandn x1, xtmp, xcarry; \ + vpsrld $31, xcarry, xcarry; \ + vpshufb bswapmask, xtmp, x1; \ + \ + vpaddd xcarry, x0, x0; \ + vpshufb bswapmask, x0, x0; + +#ifdef CONFIG_AS_AVX512 +#define GEN_CTR_BLOCK_AVX512(x0, x1, x2, x3, xtmp, xcarry, bswapmask, ctrconst, ctr) \ + vpbroadcastd (3 * 4)(ctr), x3; \ + vpbroadcastd (2 * 4)(ctr), x2; \ + vpbroadcastd (1 * 4)(ctr), x1; \ + vpbroadcastd (0 * 4)(ctr), x0; \ + vpshufb bswapmask, x3, x3; \ + vpshufb bswapmask, x2, x2; \ + vpshufb bswapmask, x1, x1; \ + vpshufb bswapmask, x0, x0; \ + \ + vpaddd ctrconst, x3, xtmp; \ + vpandnd x3, xtmp, xcarry; \ + vpsrld $0x1f, xcarry, xcarry; \ + vpshufb bswapmask, xtmp, x3; \ + \ + vpaddd xcarry, x2, xtmp; \ + vpandnd x2, xtmp, xcarry; \ + vpsrld $0x1f, xcarry, xcarry; \ + vpshufb bswapmask, xtmp, x2; \ + \ + vpaddd xcarry, x1, xtmp; \ + vpandnd x1, xtmp, xcarry; \ + vpsrld $0x1f, xcarry, xcarry; \ + vpshufb bswapmask, xtmp, x1; \ + \ + vpaddd xcarry, x0, x0; \ + vpshufb bswapmask, x0, x0; +#endif + +#define LEA_1ROUND_ENC(SIMD, i0, i1, i2, i3, tmp1, tmp2, rk, rnd_num) \ + XAR3(SIMD, i3, i2, tmp1, tmp2, \ + (LEA_CTX_RK_ENC + ((rnd_num) * 6 + 4) * 4)(rk), \ + (LEA_CTX_RK_ENC + ((rnd_num) * 6 + 5) * 4)(rk)); \ + XAR5(SIMD, i2, i1, tmp1, tmp2, \ + (LEA_CTX_RK_ENC + ((rnd_num) * 6 + 2) * 4)(rk), \ + (LEA_CTX_RK_ENC + ((rnd_num) * 6 + 3) * 4)(rk)); \ + XAR9(SIMD, i1, i0, tmp1, tmp2, \ + (LEA_CTX_RK_ENC + ((rnd_num) * 6 + 0) * 4)(rk), \ + (LEA_CTX_RK_ENC + ((rnd_num) * 6 + 1) * 4)(rk)) + +#define LEA_4ROUND_ENC(SIMD, i0, i1, i2, i3, tmp1, tmp2, rk, rnd_num) \ + LEA_1ROUND_ENC(SIMD, i0, i1, i2, i3, tmp1, tmp2, rk, rnd_num + 0); \ + LEA_1ROUND_ENC(SIMD, i1, i2, i3, i0, tmp1, tmp2, rk, rnd_num + 1); \ + LEA_1ROUND_ENC(SIMD, i2, i3, i0, i1, tmp1, tmp2, rk, rnd_num + 2); \ + LEA_1ROUND_ENC(SIMD, i3, i0, i1, i2, tmp1, tmp2, rk, rnd_num + 3) + +#define LEA_1ROUND_DEC(SIMD, i0, i1, i2, i3, tnext, tmp1, tmp2, rk, rnd_num) \ + XSR9(SIMD, i0, i3, tnext, tmp1, tmp2, \ + (LEA_CTX_RK_DEC + ((rnd_num) * 6 + 0) * 4)(rk), \ + (LEA_CTX_RK_DEC + ((rnd_num) * 6 + 1) * 4)(rk)); \ + XSR5(SIMD, i1, tnext, tmp1, tmp2, \ + (LEA_CTX_RK_DEC + ((rnd_num) * 6 + 2) * 4)(rk), \ + (LEA_CTX_RK_DEC + ((rnd_num) * 6 + 3) * 4)(rk)); \ + XSR3(SIMD, i2, tnext, tmp1, tmp2, \ + (LEA_CTX_RK_DEC + ((rnd_num) * 6 + 4) * 4)(rk), \ + (LEA_CTX_RK_DEC + ((rnd_num) * 6 + 5) * 4)(rk)); + +#define LEA_4ROUND_DEC(SIMD, i0, i1, i2, i3, tnext, tmp1, tmp2, rk, rnd_num) \ + LEA_1ROUND_DEC(SIMD, i0, i1, i2, i3, tnext, tmp1, tmp2, rk, rnd_num + 0);\ + LEA_1ROUND_DEC(SIMD, i3, i0, i1, i2, tnext, tmp1, tmp2, rk, rnd_num + 1);\ + LEA_1ROUND_DEC(SIMD, i2, i3, i0, i1, tnext, tmp1, tmp2, rk, rnd_num + 2);\ + LEA_1ROUND_DEC(SIMD, i1, i2, i3, i0, tnext, tmp1, tmp2, rk, rnd_num + 3); + + +#define XTS_LOAD_TWEAK_MASK_SSE2(mask) \ + movdqa .Lxts_tweak_mask(%rip), mask + +#define XTS_LOAD_TWEAK_MASK_AVX2(mask) \ + vmovdqa .Lxts_tweak_mask(%rip), mask + +#define CBC_LOAD_SHUFFLE_MASK_AVX2(mask) \ + vmovdqa .Lcbc_shuffle_mask(%rip), mask + +#define LOAD_BSWAP_MASK_AVX2(mask) \ + vmovdqa .Lbswap_mask(%rip), mask + +#define LOAD_CTR_CONST_AVX2(val) \ + vmovdqa .Lctr_add_const(%rip), val + +#ifdef CONFIG_AS_AVX512 + +#define CBC_LOAD_SHUFFLE_MASK_AVX512(mask) \ + vmovdqa64 .Lcbc_shuffle_mask16(%rip), mask + +#define LOAD_BSWAP_MASK_AVX512(mask) \ + vmovdqa64 .Lbswap_mask(%rip), mask + +#define LOAD_CTR_CONST_AVX512(val) \ + vmovdqa64 .Lctr_add_const(%rip), val + +#endif + +#define XTS_NEXT_TWEAK_1BLOCK_SSE2(out0, in0, tmp0, mask) \ + pshufd $0x13, in0, tmp0; \ + movdqa in0, out0; \ + psrad $31, tmp0; \ + pand mask, tmp0; \ + psllq $1, out0; \ + pxor tmp0, out0; + +#define XTS_NEXT_TWEAK_1BLOCK_AVX2(out0, in0, tmp0, mask) \ + vpshufd $0x13, in0, tmp0; \ + vpsrad $31, tmp0, tmp0; \ + vpand mask, tmp0, tmp0; \ + vpsllq $1, in0, out0; \ + vpxor tmp0, out0, out0; + +.align 8 +SYM_FUNC_START_LOCAL(__lea_x86_64_enc_4way_sse2) + /* input: + * %rdi: ctx, CTX + * %xmm0..%xmm3: 4 plaintext blocks + * output: + * %xmm0..%xmm3: 4 encrypted blocks + * temporary: + * $xmm4..%xmm5 + */ + LEA_4ROUND_ENC(SSE2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %rdi, 0); + LEA_4ROUND_ENC(SSE2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %rdi, 4); + LEA_4ROUND_ENC(SSE2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %rdi, 8); + LEA_4ROUND_ENC(SSE2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %rdi, 12); + LEA_4ROUND_ENC(SSE2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %rdi, 16); + LEA_4ROUND_ENC(SSE2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %rdi, 20); + + cmpl $24, LEA_CTX_ROUND(%rdi); + je .Lenc4_sse2_done; + LEA_4ROUND_ENC(SSE2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %rdi, 24); + + cmpl $28, LEA_CTX_ROUND(%rdi); + je .Lenc4_sse2_done; + LEA_4ROUND_ENC(SSE2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %rdi, 28); + +.Lenc4_sse2_done: + RET; +SYM_FUNC_END(__lea_x86_64_enc_4way_sse2) + +.align 8 +SYM_FUNC_START_LOCAL(__lea_x86_64_dec_4way_sse2) + /* input: + * %rdi: ctx, CTX + * %xmm0..%xmm3: 4 encrypted blocks + * output: + * %xmm0..%xmm3: 4 plaintext blocks + * temporary: + * $xmm4..%xmm6 + */ + LEA_4ROUND_DEC(SSE2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %rdi, 0); + LEA_4ROUND_DEC(SSE2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %rdi, 4); + LEA_4ROUND_DEC(SSE2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %rdi, 8); + LEA_4ROUND_DEC(SSE2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %rdi, 12); + LEA_4ROUND_DEC(SSE2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %rdi, 16); + LEA_4ROUND_DEC(SSE2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %rdi, 20); + + cmpl $24, LEA_CTX_ROUND(%rdi); + je .Ldec4_sse2_done; + LEA_4ROUND_DEC(SSE2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %rdi, 24); + + cmpl $28, LEA_CTX_ROUND(%rdi); + je .Ldec4_sse2_done; + LEA_4ROUND_DEC(SSE2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %rdi, 28); + +.Ldec4_sse2_done: + RET; +SYM_FUNC_END(__lea_x86_64_dec_4way_sse2) + +.align 16 +SYM_FUNC_START_LOCAL(__lea_x86_64_enc_4way_avx2) + /* input: + * %rdi: ctx, CTX + * %xmm0..%xmm3: 4 plaintext blocks + * output: + * %xmm0..%xmm3: 4 encrypted blocks + * temporary: + * $xmm4..%xmm5 + */ + LEA_4ROUND_ENC(AVX2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %rdi, 0); + LEA_4ROUND_ENC(AVX2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %rdi, 4); + LEA_4ROUND_ENC(AVX2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %rdi, 8); + LEA_4ROUND_ENC(AVX2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %rdi, 12); + LEA_4ROUND_ENC(AVX2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %rdi, 16); + LEA_4ROUND_ENC(AVX2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %rdi, 20); + + cmpl $24, LEA_CTX_ROUND(%rdi); + je .Lenc4_avx2_done; + LEA_4ROUND_ENC(AVX2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %rdi, 24); + + cmpl $28, LEA_CTX_ROUND(%rdi); + je .Lenc4_avx2_done; + LEA_4ROUND_ENC(AVX2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %rdi, 28); + +.Lenc4_avx2_done: + RET; +SYM_FUNC_END(__lea_x86_64_enc_4way_avx2) + +.align 16 +SYM_FUNC_START_LOCAL(__lea_x86_64_dec_4way_avx2) + /* input: + * %rdi: ctx, CTX + * %xmm0..%xmm3: 4 encrypted blocks + * output: + * %xmm0..%xmm3: 4 plaintext blocks + * temporary: + * $xmm4..%xmm6 + */ + LEA_4ROUND_DEC(AVX2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %rdi, 0); + LEA_4ROUND_DEC(AVX2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %rdi, 4); + LEA_4ROUND_DEC(AVX2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %rdi, 8); + LEA_4ROUND_DEC(AVX2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %rdi, 12); + LEA_4ROUND_DEC(AVX2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %rdi, 16); + LEA_4ROUND_DEC(AVX2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %rdi, 20); + + cmpl $24, LEA_CTX_ROUND(%rdi); + je .Ldec4_avx2_done; + LEA_4ROUND_DEC(AVX2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %rdi, 24); + + cmpl $28, LEA_CTX_ROUND(%rdi); + je .Ldec4_avx2_done; + LEA_4ROUND_DEC(AVX2, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %rdi, 28); +.Ldec4_avx2_done: + RET; +SYM_FUNC_END(__lea_x86_64_dec_4way_avx2) + +.align 16 +SYM_FUNC_START_LOCAL(__lea_x86_64_enc_8way_avx2) + /* input: + * %rdi: ctx, CTX + * %ymm0..%ymm3: 8 plaintext blocks + * output: + * %ymm0..%ymm3: 8 encrypted blocks + * temporary: + * $ymm4..%ymm5 + */ + LEA_4ROUND_ENC(AVX2, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %rdi, 0); + LEA_4ROUND_ENC(AVX2, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %rdi, 4); + LEA_4ROUND_ENC(AVX2, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %rdi, 8); + LEA_4ROUND_ENC(AVX2, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %rdi, 12); + LEA_4ROUND_ENC(AVX2, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %rdi, 16); + LEA_4ROUND_ENC(AVX2, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %rdi, 20); + + cmpl $24, LEA_CTX_ROUND(%rdi); + je .Lenc8_avx2_done; + LEA_4ROUND_ENC(AVX2, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %rdi, 24); + + cmpl $28, LEA_CTX_ROUND(%rdi); + je .Lenc8_avx2_done; + LEA_4ROUND_ENC(AVX2, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %rdi, 28); + +.Lenc8_avx2_done: + RET; +SYM_FUNC_END(__lea_x86_64_enc_8way_avx2) + +.align 16 +SYM_FUNC_START_LOCAL(__lea_x86_64_dec_8way_avx2) + /* input: + * %rdi: ctx, CTX + * %ymm0..%ymm3: 8 encrypted blocks + * output: + * %ymm0..%ymm3: 8 plaintext blocks + * temporary: + * $ymm4..%ymm6 + */ + LEA_4ROUND_DEC(AVX2, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %rdi, 0); + LEA_4ROUND_DEC(AVX2, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %rdi, 4); + LEA_4ROUND_DEC(AVX2, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %rdi, 8); + LEA_4ROUND_DEC(AVX2, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %rdi, 12); + LEA_4ROUND_DEC(AVX2, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %rdi, 16); + LEA_4ROUND_DEC(AVX2, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %rdi, 20); + + cmpl $24, LEA_CTX_ROUND(%rdi); + je .Ldec8_avx2_done; + LEA_4ROUND_DEC(AVX2, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %rdi, 24); + + cmpl $28, LEA_CTX_ROUND(%rdi); + je .Ldec8_avx2_done; + LEA_4ROUND_DEC(AVX2, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %rdi, 28); +.Ldec8_avx2_done: + RET; +SYM_FUNC_END(__lea_x86_64_dec_8way_avx2) + +#ifdef CONFIG_AS_AVX512 +.align 16 +SYM_FUNC_START_LOCAL(__lea_x86_64_enc_4way_avx512) + /* input: + * %rdi: ctx, CTX + * %xmm0..%xmm3: 4 plaintext blocks + * output: + * %xmm0..%xmm3: 4 encrypted blocks + * temporary: + * $xmm4..%xmm5 + */ + LEA_4ROUND_ENC(AVX512, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %rdi, 0); + LEA_4ROUND_ENC(AVX512, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %rdi, 4); + LEA_4ROUND_ENC(AVX512, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %rdi, 8); + LEA_4ROUND_ENC(AVX512, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %rdi, 12); + LEA_4ROUND_ENC(AVX512, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %rdi, 16); + LEA_4ROUND_ENC(AVX512, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %rdi, 20); + + cmpl $24, LEA_CTX_ROUND(%rdi); + je .Lenc4_avx512_done; + LEA_4ROUND_ENC(AVX512, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %rdi, 24); + + cmpl $28, LEA_CTX_ROUND(%rdi); + je .Lenc4_avx512_done; + LEA_4ROUND_ENC(AVX512, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %rdi, 28); + +.Lenc4_avx512_done: + RET; +SYM_FUNC_END(__lea_x86_64_enc_4way_avx512) + +.align 16 +SYM_FUNC_START_LOCAL(__lea_x86_64_dec_4way_avx512) + /* input: + * %rdi: ctx, CTX + * %xmm0..%xmm3: 4 encrypted blocks + * output: + * %xmm0..%xmm3: 4 plaintext blocks + * temporary: + * $xmm4..%xmm6 + */ + LEA_4ROUND_DEC(AVX512, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %rdi, 0); + LEA_4ROUND_DEC(AVX512, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %rdi, 4); + LEA_4ROUND_DEC(AVX512, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %rdi, 8); + LEA_4ROUND_DEC(AVX512, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %rdi, 12); + LEA_4ROUND_DEC(AVX512, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %rdi, 16); + LEA_4ROUND_DEC(AVX512, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %rdi, 20); + + cmpl $24, LEA_CTX_ROUND(%rdi); + je .Ldec4_avx512_done; + LEA_4ROUND_DEC(AVX512, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %rdi, 24); + + cmpl $28, LEA_CTX_ROUND(%rdi); + je .Ldec4_avx512_done; + LEA_4ROUND_DEC(AVX512, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %rdi, 28); + +.Ldec4_avx512_done: + RET; +SYM_FUNC_END(__lea_x86_64_dec_4way_avx512) + +.align 16 +SYM_FUNC_START_LOCAL(__lea_x86_64_enc_8way_avx512) + /* input: + * %rdi: ctx, CTX + * %ymm0..%ymm3: 8 plaintext blocks + * output: + * %ymm0..%ymm3: 8 encrypted blocks + * temporary: + * $ymm4..%ymm5 + */ + LEA_4ROUND_ENC(AVX2, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %rdi, 0); + LEA_4ROUND_ENC(AVX2, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %rdi, 4); + LEA_4ROUND_ENC(AVX2, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %rdi, 8); + LEA_4ROUND_ENC(AVX2, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %rdi, 12); + LEA_4ROUND_ENC(AVX2, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %rdi, 16); + LEA_4ROUND_ENC(AVX2, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %rdi, 20); + + cmpl $24, LEA_CTX_ROUND(%rdi); + je .Lenc8_avx512_done; + LEA_4ROUND_ENC(AVX2, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %rdi, 24); + + cmpl $28, LEA_CTX_ROUND(%rdi); + je .Lenc8_avx512_done; + LEA_4ROUND_ENC(AVX2, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %rdi, 28); + +.Lenc8_avx512_done: + RET; +SYM_FUNC_END(__lea_x86_64_enc_8way_avx512) + +.align 16 +SYM_FUNC_START_LOCAL(__lea_x86_64_dec_8way_avx512) + /* input: + * %rdi: ctx, CTX + * %ymm0..%ymm3: 8 encrypted blocks + * output: + * %ymm0..%ymm3: 8 plaintext blocks + * temporary: + * $ymm4..%ymm6 + */ + LEA_4ROUND_DEC(AVX512, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %rdi, 0); + LEA_4ROUND_DEC(AVX512, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %rdi, 4); + LEA_4ROUND_DEC(AVX512, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %rdi, 8); + LEA_4ROUND_DEC(AVX512, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %rdi, 12); + LEA_4ROUND_DEC(AVX512, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %rdi, 16); + LEA_4ROUND_DEC(AVX512, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %rdi, 20); + + cmpl $24, LEA_CTX_ROUND(%rdi); + je .Ldec8_avx512_done; + LEA_4ROUND_DEC(AVX512, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %rdi, 24); + + cmpl $28, LEA_CTX_ROUND(%rdi); + je .Ldec8_avx512_done; + LEA_4ROUND_DEC(AVX512, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %rdi, 28); +.Ldec8_avx512_done: + RET; +SYM_FUNC_END(__lea_x86_64_dec_8way_avx512) + +.align 16 +SYM_FUNC_START_LOCAL(__lea_x86_64_enc_16way_avx512) + /* input: + * %rdi: ctx, CTX + * %zmm0..%zmm3: 16 plaintext blocks + * output: + * %zmm0..%zmm3: 16 encrypted blocks + * temporary: + * $zmm4..%zmm5 + */ + LEA_4ROUND_ENC(AVX512, %zmm0, %zmm1, %zmm2, %zmm3, %zmm4, %zmm5, %rdi, 0); + LEA_4ROUND_ENC(AVX512, %zmm0, %zmm1, %zmm2, %zmm3, %zmm4, %zmm5, %rdi, 4); + LEA_4ROUND_ENC(AVX512, %zmm0, %zmm1, %zmm2, %zmm3, %zmm4, %zmm5, %rdi, 8); + LEA_4ROUND_ENC(AVX512, %zmm0, %zmm1, %zmm2, %zmm3, %zmm4, %zmm5, %rdi, 12); + LEA_4ROUND_ENC(AVX512, %zmm0, %zmm1, %zmm2, %zmm3, %zmm4, %zmm5, %rdi, 16); + LEA_4ROUND_ENC(AVX512, %zmm0, %zmm1, %zmm2, %zmm3, %zmm4, %zmm5, %rdi, 20); + + cmpl $24, LEA_CTX_ROUND(%rdi); + je .Lenc16_avx512_done; + LEA_4ROUND_ENC(AVX512, %zmm0, %zmm1, %zmm2, %zmm3, %zmm4, %zmm5, %rdi, 24); + + cmpl $28, LEA_CTX_ROUND(%rdi); + je .Lenc16_avx512_done; + LEA_4ROUND_ENC(AVX512, %zmm0, %zmm1, %zmm2, %zmm3, %zmm4, %zmm5, %rdi, 28); + +.Lenc16_avx512_done: + RET; +SYM_FUNC_END(__lea_x86_64_enc_16way_avx512) + +.align 16 +SYM_FUNC_START_LOCAL(__lea_x86_64_dec_16way_avx512) + /* input: + * %rdi: ctx, CTX + * %zmm0..%zmm3: 16 encrypted blocks + * output: + * %zmm0..%zmm3: 16 plaintext blocks + * temporary: + * $zmm4..%zmm6 + */ + LEA_4ROUND_DEC(AVX512, %zmm0, %zmm1, %zmm2, %zmm3, %zmm4, %zmm5, %zmm6, %rdi, 0); + LEA_4ROUND_DEC(AVX512, %zmm0, %zmm1, %zmm2, %zmm3, %zmm4, %zmm5, %zmm6, %rdi, 4); + LEA_4ROUND_DEC(AVX512, %zmm0, %zmm1, %zmm2, %zmm3, %zmm4, %zmm5, %zmm6, %rdi, 8); + LEA_4ROUND_DEC(AVX512, %zmm0, %zmm1, %zmm2, %zmm3, %zmm4, %zmm5, %zmm6, %rdi, 12); + LEA_4ROUND_DEC(AVX512, %zmm0, %zmm1, %zmm2, %zmm3, %zmm4, %zmm5, %zmm6, %rdi, 16); + LEA_4ROUND_DEC(AVX512, %zmm0, %zmm1, %zmm2, %zmm3, %zmm4, %zmm5, %zmm6, %rdi, 20); + + cmpl $24, LEA_CTX_ROUND(%rdi); + je .Ldec16_avx512_done; + LEA_4ROUND_DEC(AVX512, %zmm0, %zmm1, %zmm2, %zmm3, %zmm4, %zmm5, %zmm6, %rdi, 24); + + cmpl $28, LEA_CTX_ROUND(%rdi); + je .Ldec16_avx512_done; + LEA_4ROUND_DEC(AVX512, %zmm0, %zmm1, %zmm2, %zmm3, %zmm4, %zmm5, %zmm6, %rdi, 28); +.Ldec16_avx512_done: + RET; +SYM_FUNC_END(__lea_x86_64_dec_16way_avx512) +#endif + +SYM_FUNC_START(lea_x86_64_ecb_enc_4way_sse2) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (4 blocks) + * %rdx: src (4 blocks) + */ + FRAME_BEGIN + + LOAD_BLOCK4_SSE2(%xmm0, %xmm1, %xmm5, %xmm3, %rdx); + TRANSPOSE_BLOCK4_SSE2(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5); + + call __lea_x86_64_enc_4way_sse2 + + TRANSPOSE_BLOCK4_SSE2(%xmm0, %xmm1, %xmm5, %xmm3, %xmm4, %xmm2); + STORE_BLOCK4_SSE2(%xmm0, %xmm1, %xmm5, %xmm3, %rsi); + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_ecb_enc_4way_sse2) + +SYM_FUNC_START(lea_x86_64_ecb_enc_4way_avx2) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (4 blocks) + * %rdx: src (4 blocks) + */ + FRAME_BEGIN + + GATHER_BLOCK4_AVX2(0, 1, 2, 3, %rdx); + + call __lea_x86_64_enc_4way_avx2 + + SCATTER_BLOCK4_AVX2(0, 1, 2, 3, %rsi); + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_ecb_enc_4way_avx2) + +SYM_FUNC_START(lea_x86_64_ecb_enc_8way_avx2) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (8 blocks) + * %rdx: src (8 blocks) + */ + FRAME_BEGIN + + vzeroupper; + + GATHER_BLOCK8_AVX2(0, 1, 2, 3, 4, %rdx); + + call __lea_x86_64_enc_8way_avx2; + + SCATTER_BLOCK8_AVX2(0, 1, 2, 3, %rsi); + + vzeroupper; + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_ecb_enc_8way_avx2) + +#ifdef CONFIG_AS_AVX512 +SYM_FUNC_START(lea_x86_64_ecb_enc_4way_avx512) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (4 blocks) + * %rdx: src (4 blocks) + */ + FRAME_BEGIN + + GATHER_BLOCK4_AVX2(0, 1, 2, 3, %rdx); + + call __lea_x86_64_enc_4way_avx512 + + SCATTER_BLOCK4_AVX2(0, 1, 2, 3, %rsi); + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_ecb_enc_4way_avx512) + +SYM_FUNC_START(lea_x86_64_ecb_enc_8way_avx512) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (8 blocks) + * %rdx: src (8 blocks) + */ + FRAME_BEGIN + + vzeroupper; + + GATHER_BLOCK8_AVX2(0, 1, 2, 3, 4, %rdx); + + call __lea_x86_64_enc_8way_avx512; + + SCATTER_BLOCK8_AVX2(0, 1, 2, 3, %rsi); + + vzeroupper; + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_ecb_enc_8way_avx512) + +SYM_FUNC_START(lea_x86_64_ecb_enc_16way_avx512) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (16 blocks) + * %rdx: src (16 blocks) + */ + FRAME_BEGIN + + vzeroupper; + + GATHER_BLOCK16_AVX512(0, 1, 2, 3, 4, %rdx); + + call __lea_x86_64_enc_16way_avx512; + + SCATTER_BLOCK16_AVX512(0, 1, 2, 3, 4, %rsi); + + vzeroupper; + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_ecb_enc_16way_avx512) +#endif + +SYM_FUNC_START(lea_x86_64_ecb_dec_4way_sse2) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (4 blocks) + * %rdx: src (4 blocks) + */ + FRAME_BEGIN + + LOAD_BLOCK4_SSE2(%xmm0, %xmm1, %xmm5, %xmm3, %rdx); + TRANSPOSE_BLOCK4_SSE2(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5); + + call __lea_x86_64_dec_4way_sse2 + + TRANSPOSE_BLOCK4_SSE2(%xmm0, %xmm1, %xmm5, %xmm3, %xmm4, %xmm2); + STORE_BLOCK4_SSE2(%xmm0, %xmm1, %xmm5, %xmm3, %rsi); + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_ecb_dec_4way_sse2) + +SYM_FUNC_START(lea_x86_64_ecb_dec_4way_avx2) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (4 blocks) + * %rdx: src (4 blocks) + */ + FRAME_BEGIN + + GATHER_BLOCK4_AVX2(0, 1, 2, 3, %rdx); + + call __lea_x86_64_dec_4way_avx2 + + SCATTER_BLOCK4_AVX2(0, 1, 2, 3, %rsi); + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_ecb_dec_4way_avx2) + +SYM_FUNC_START(lea_x86_64_ecb_dec_8way_avx2) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (8 blocks) + * %rdx: src (8 blocks) + */ + FRAME_BEGIN + + vzeroupper; + + GATHER_BLOCK8_AVX2(0, 1, 2, 3, 4, %rdx); + + call __lea_x86_64_dec_8way_avx2 + + SCATTER_BLOCK8_AVX2(0, 1, 2, 3, %rsi); + + vzeroupper; + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_ecb_dec_8way_avx2) + +#ifdef CONFIG_AS_AVX512 +SYM_FUNC_START(lea_x86_64_ecb_dec_4way_avx512) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (4 blocks) + * %rdx: src (4 blocks) + */ + FRAME_BEGIN + + GATHER_BLOCK4_AVX2(0, 1, 2, 3, %rdx); + + call __lea_x86_64_dec_4way_avx512 + + SCATTER_BLOCK4_AVX2(0, 1, 2, 3, %rsi); + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_ecb_dec_4way_avx512) + +SYM_FUNC_START(lea_x86_64_ecb_dec_8way_avx512) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (8 blocks) + * %rdx: src (8 blocks) + */ + FRAME_BEGIN + + vzeroupper; + + GATHER_BLOCK8_AVX2(0, 1, 2, 3, 4, %rdx); + + call __lea_x86_64_dec_8way_avx512 + + SCATTER_BLOCK8_AVX2(0, 1, 2, 3, %rsi); + + vzeroupper; + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_ecb_dec_8way_avx512) + +SYM_FUNC_START(lea_x86_64_ecb_dec_16way_avx512) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (16 blocks) + * %rdx: src (16 blocks) + */ + FRAME_BEGIN + + vzeroupper; + + GATHER_BLOCK16_AVX512(0, 1, 2, 3, 4, %rdx); + + call __lea_x86_64_dec_16way_avx512 + + SCATTER_BLOCK16_AVX512(0, 1, 2, 3, 4, %rsi); + + vzeroupper; + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_ecb_dec_16way_avx512) +#endif + +SYM_FUNC_START(lea_x86_64_cbc_dec_4way_sse2) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (4 blocks) + * %rdx: src (4 blocks) + */ + FRAME_BEGIN + + LOAD_BLOCK4_SSE2(%xmm0, %xmm1, %xmm5, %xmm3, %rdx); + TRANSPOSE_BLOCK4_SSE2(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5); + + call __lea_x86_64_dec_4way_sse2 + + TRANSPOSE_BLOCK4_SSE2(%xmm0, %xmm1, %xmm5, %xmm3, %xmm4, %xmm2); + XOR_BLOCK3_SSE2(%xmm1, %xmm5, %xmm3, %rdx); + STORE_BLOCK4_SSE2(%xmm0, %xmm1, %xmm5, %xmm3, %rsi); + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_cbc_dec_4way_sse2) + +SYM_FUNC_START(lea_x86_64_cbc_dec_4way_avx2) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (4 blocks) + * %rdx: src (4 blocks) + */ + FRAME_BEGIN + + GATHER_BLOCK4_AVX2(0, 1, 2, 3, %rdx); + + call __lea_x86_64_dec_4way_avx2 + + TRANSPOSE_BLOCK4_AVX2(%xmm0, %xmm1, %xmm5, %xmm3, %xmm4, %xmm2); + XOR_BLOCK3_AVX2(%xmm1, %xmm5, %xmm3, %rdx); + STORE_BLOCK4_AVX2(%xmm0, %xmm1, %xmm5, %xmm3, %rsi); + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_cbc_dec_4way_avx2) + +SYM_FUNC_START(lea_x86_64_cbc_dec_8way_avx2) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (8 blocks) + * %rdx: src (8 blocks) + */ + FRAME_BEGIN + + vzeroupper; + + GATHER_BLOCK8_AVX2(0, 1, 2, 3, 4, %rdx); + + CBC_LOAD_SHUFFLE_MASK_AVX2(%ymm7); + vpxor %ymm4, %ymm4, %ymm4; + + vpermd %ymm0, %ymm7, %ymm8; + vpermd %ymm1, %ymm7, %ymm9; + vpermd %ymm2, %ymm7, %ymm10; + vpermd %ymm3, %ymm7, %ymm11; + + vpblendd $0x1, %ymm4, %ymm8, %ymm8; + vpblendd $0x1, %ymm4, %ymm9, %ymm9; + vpblendd $0x1, %ymm4, %ymm10, %ymm10; + vpblendd $0x1, %ymm4, %ymm11, %ymm11; + + call __lea_x86_64_dec_8way_avx2 + + vpxor %ymm8, %ymm0, %ymm0; + vpxor %ymm9, %ymm1, %ymm1; + vpxor %ymm10, %ymm2, %ymm2; + vpxor %ymm11, %ymm3, %ymm3; + + SCATTER_BLOCK8_AVX2(0, 1, 2, 3, %rsi); + + vzeroupper; + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_cbc_dec_8way_avx2) + +#ifdef CONFIG_AS_AVX512 +SYM_FUNC_START(lea_x86_64_cbc_dec_4way_avx512) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (4 blocks) + * %rdx: src (4 blocks) + */ + FRAME_BEGIN + + GATHER_BLOCK4_AVX2(0, 1, 2, 3, %rdx); + + call __lea_x86_64_dec_4way_avx512 + + TRANSPOSE_BLOCK4_AVX2(%xmm0, %xmm1, %xmm5, %xmm3, %xmm4, %xmm2); + XOR_BLOCK3_AVX2(%xmm1, %xmm5, %xmm3, %rdx); + STORE_BLOCK4_AVX2(%xmm0, %xmm1, %xmm5, %xmm3, %rsi); + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_cbc_dec_4way_avx512) + +SYM_FUNC_START(lea_x86_64_cbc_dec_8way_avx512) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (8 blocks) + * %rdx: src (8 blocks) + */ + FRAME_BEGIN + + vzeroupper; + + GATHER_BLOCK8_AVX2(0, 1, 2, 3, 4, %rdx); + + CBC_LOAD_SHUFFLE_MASK_AVX2(%ymm7); + vpxor %ymm4, %ymm4, %ymm4; + + vpermd %ymm0, %ymm7, %ymm8; + vpermd %ymm1, %ymm7, %ymm9; + vpermd %ymm2, %ymm7, %ymm10; + vpermd %ymm3, %ymm7, %ymm11; + + vpblendd $0x1, %ymm4, %ymm8, %ymm8; + vpblendd $0x1, %ymm4, %ymm9, %ymm9; + vpblendd $0x1, %ymm4, %ymm10, %ymm10; + vpblendd $0x1, %ymm4, %ymm11, %ymm11; + + call __lea_x86_64_dec_8way_avx512 + + vpxor %ymm8, %ymm0, %ymm0; + vpxor %ymm9, %ymm1, %ymm1; + vpxor %ymm10, %ymm2, %ymm2; + vpxor %ymm11, %ymm3, %ymm3; + + SCATTER_BLOCK8_AVX2(0, 1, 2, 3, %rsi); + + vzeroupper; + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_cbc_dec_8way_avx512) + +SYM_FUNC_START(lea_x86_64_cbc_dec_16way_avx512) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (16 blocks) + * %rdx: src (16 blocks) + */ + FRAME_BEGIN + + vzeroupper; + + GATHER_BLOCK16_AVX512(0, 1, 2, 3, 4, %rdx); + + CBC_LOAD_SHUFFLE_MASK_AVX512(%zmm7); + vpxord %zmm4, %zmm4, %zmm4; + + mov $0x1, %eax; + kmovw %eax, %k1; + + vpermd %zmm0, %zmm7, %zmm8; + vpermd %zmm1, %zmm7, %zmm9; + vpermd %zmm2, %zmm7, %zmm10; + vpermd %zmm3, %zmm7, %zmm11; + + vpblendmd %zmm4, %zmm8, %zmm8{%k1}; + vpblendmd %zmm4, %zmm9, %zmm9{%k1}; + vpblendmd %zmm4, %zmm10, %zmm10{%k1}; + vpblendmd %zmm4, %zmm11, %zmm11{%k1}; + + call __lea_x86_64_dec_16way_avx512 + + vpxord %zmm8, %zmm0, %zmm0; + vpxord %zmm9, %zmm1, %zmm1; + vpxord %zmm10, %zmm2, %zmm2; + vpxord %zmm11, %zmm3, %zmm3; + + SCATTER_BLOCK16_AVX512(0, 1, 2, 3, 4, %rsi); + + vzeroupper; + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_cbc_dec_16way_avx512) +#endif + +SYM_FUNC_START(lea_x86_64_ctr_enc_4way_sse2) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (4 blocks) + * %rdx: src (4 blocks) + * %rcx: ctr + * temporary: + * CTR_64_high_src(%r9) + * CTR_64_low_src(%rax) + * CTR_64_high(%r11) + * CTR_64_low(%r10) + */ + FRAME_BEGIN + + mov (%rcx), CTR_64_high_src; + mov 8(%rcx), CTR_64_low_src; + bswap CTR_64_high_src; + bswap CTR_64_low_src; + + movdqu (%rcx), %xmm0; + mov CTR_64_low_src, CTR_64_low; + mov CTR_64_high_src, CTR_64_high; + ADD_CTR_AND_STORE(CTR_64_high, CTR_64_low, %rcx, $1); + movdqu (%rcx), %xmm1; + mov CTR_64_low_src, CTR_64_low; + mov CTR_64_high_src, CTR_64_high; + ADD_CTR_AND_STORE(CTR_64_high, CTR_64_low, %rcx, $2); + movdqu (%rcx), %xmm5; + mov CTR_64_low_src, CTR_64_low; + mov CTR_64_high_src, CTR_64_high; + ADD_CTR_AND_STORE(CTR_64_high, CTR_64_low, %rcx, $3); + movdqu (%rcx), %xmm3; + mov CTR_64_low_src, CTR_64_low; + mov CTR_64_high_src, CTR_64_high; + ADD_CTR_AND_STORE(CTR_64_high, CTR_64_low, %rcx, $4); + + TRANSPOSE_BLOCK4_SSE2(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5); + LOAD_BLOCK4_SSE2(%xmm7, %xmm8, %xmm9, %xmm10, %rdx); + + call __lea_x86_64_enc_4way_sse2; + + TRANSPOSE_BLOCK4_SSE2(%xmm0, %xmm1, %xmm5, %xmm3, %xmm4, %xmm2); + + pxor %xmm7, %xmm0; + pxor %xmm8, %xmm1; + pxor %xmm9, %xmm5; + pxor %xmm10, %xmm3; + + STORE_BLOCK4_SSE2(%xmm0, %xmm1, %xmm5, %xmm3, %rsi); + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_ctr_enc_4way_sse2) + +SYM_FUNC_START(lea_x86_64_ctr_enc_4way_avx2) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (4 blocks) + * %rdx: src (4 blocks) + * %rcx: ctr + * temporary: + * %r9 + * %rax + */ + FRAME_BEGIN + + LOAD_BSWAP_MASK_AVX2(BSWAPMASK_XMM); + LOAD_CTR_CONST_AVX2(CTRCONST_XMM); + + GEN_CTR_BLOCK_AVX2(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, + BSWAPMASK_XMM, CTRCONST_XMM, %rcx); + + LOAD_CTR(%rcx, %r9, %rax); + ADD_CTR_AND_STORE(%r9, %rax, %rcx, $4); + + GATHER_BLOCK4_AVX2(7, 8, 9, 10, %rdx); + + call __lea_x86_64_enc_4way_avx2; + + vpxor %ymm7, %ymm0, %ymm0; + vpxor %ymm8, %ymm1, %ymm1; + vpxor %ymm9, %ymm2, %ymm2; + vpxor %ymm10, %ymm3, %ymm3; + + SCATTER_BLOCK4_AVX2(0, 1, 2, 3, %rsi); + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_ctr_enc_4way_avx2) + +SYM_FUNC_START(lea_x86_64_ctr_enc_8way_avx2) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (8 blocks) + * %rdx: src (8 blocks) + * %rcx: ctr + * temporary: + * %r9 + * %rax + */ + FRAME_BEGIN + + vzeroupper; + + + LOAD_BSWAP_MASK_AVX2(BSWAPMASK_YMM); + LOAD_CTR_CONST_AVX2(CTRCONST_YMM); + + GEN_CTR_BLOCK_AVX2(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, + BSWAPMASK_YMM, CTRCONST_YMM, %rcx); + LOAD_CTR(%rcx, %r9, %rax); + ADD_CTR_AND_STORE(%r9, %rax, %rcx, $8); + + GATHER_BLOCK8_AVX2(7, 8, 9, 10, 4, %rdx); + + call __lea_x86_64_enc_8way_avx2; + + vpxor %ymm7, %ymm0, %ymm0; + vpxor %ymm8, %ymm1, %ymm1; + vpxor %ymm9, %ymm2, %ymm2; + vpxor %ymm10, %ymm3, %ymm3; + + SCATTER_BLOCK8_AVX2(0, 1, 2, 3, %rsi); + + vzeroupper; + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_ctr_enc_8way_avx2) + +#ifdef CONFIG_AS_AVX512 +SYM_FUNC_START(lea_x86_64_ctr_enc_4way_avx512) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (4 blocks) + * %rdx: src (4 blocks) + * %rcx: ctr + * temporary: + * %r9 + * %rax + */ + FRAME_BEGIN + + LOAD_BSWAP_MASK_AVX2(BSWAPMASK_XMM); + LOAD_CTR_CONST_AVX2(CTRCONST_XMM); + + GEN_CTR_BLOCK_AVX2(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, + BSWAPMASK_XMM, CTRCONST_XMM, %rcx); + + LOAD_CTR(%rcx, %r9, %rax); + ADD_CTR_AND_STORE(%r9, %rax, %rcx, $4); + + GATHER_BLOCK4_AVX2(7, 8, 9, 10, %rdx); + + call __lea_x86_64_enc_4way_avx512; + + vpxor %ymm7, %ymm0, %ymm0; + vpxor %ymm8, %ymm1, %ymm1; + vpxor %ymm9, %ymm2, %ymm2; + vpxor %ymm10, %ymm3, %ymm3; + + SCATTER_BLOCK4_AVX2(0, 1, 2, 3, %rsi); + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_ctr_enc_4way_avx512) + +SYM_FUNC_START(lea_x86_64_ctr_enc_8way_avx512) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (8 blocks) + * %rdx: src (8 blocks) + * %rcx: ctr + * temporary: + * %r9 + * %rax + */ + FRAME_BEGIN + + vzeroupper; + + + LOAD_BSWAP_MASK_AVX2(BSWAPMASK_YMM); + LOAD_CTR_CONST_AVX2(CTRCONST_YMM); + + GEN_CTR_BLOCK_AVX2(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, + BSWAPMASK_YMM, CTRCONST_YMM, %rcx); + LOAD_CTR(%rcx, %r9, %rax); + ADD_CTR_AND_STORE(%r9, %rax, %rcx, $8); + + GATHER_BLOCK8_AVX2(7, 8, 9, 10, 4, %rdx); + + call __lea_x86_64_enc_8way_avx512; + + vpxor %ymm7, %ymm0, %ymm0; + vpxor %ymm8, %ymm1, %ymm1; + vpxor %ymm9, %ymm2, %ymm2; + vpxor %ymm10, %ymm3, %ymm3; + + SCATTER_BLOCK8_AVX2(0, 1, 2, 3, %rsi); + + vzeroupper; + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_ctr_enc_8way_avx512) + +SYM_FUNC_START(lea_x86_64_ctr_enc_16way_avx512) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (16 blocks) + * %rdx: src (16 blocks) + * %rcx: ctr + * temporary: + * %r9 + * %rax + */ + FRAME_BEGIN + + vzeroupper; + + + LOAD_BSWAP_MASK_AVX512(BSWAPMASK_ZMM); + LOAD_CTR_CONST_AVX512(CTRCONST_ZMM); + + GEN_CTR_BLOCK_AVX512(%zmm0, %zmm1, %zmm2, %zmm3, %zmm4, %zmm5, + BSWAPMASK_ZMM, CTRCONST_ZMM, %rcx); + LOAD_CTR(%rcx, %r9, %rax); + ADD_CTR_AND_STORE(%r9, %rax, %rcx, $16); + + GATHER_BLOCK16_AVX512(8, 9, 10, 11, 4, %rdx); + + call __lea_x86_64_enc_16way_avx512; + + vpxord %zmm8, %zmm0, %zmm0; + vpxord %zmm9, %zmm1, %zmm1; + vpxord %zmm10, %zmm2, %zmm2; + vpxord %zmm11, %zmm3, %zmm3; + + SCATTER_BLOCK16_AVX512(0, 1, 2, 3, 4, %rsi); + + vzeroupper; + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_ctr_enc_16way_avx512) +#endif + +SYM_FUNC_START(lea_x86_64_xts_enc_4way_sse2) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (4 blocks) + * %rdx: src (4 blocks) + * %rcx: tweak + */ + FRAME_BEGIN + + LOAD_BLOCK4_SSE2(%xmm0, %xmm1, %xmm5, %xmm3, %rdx); + movdqu (%rcx), XTS_TW_X0; + XTS_LOAD_TWEAK_MASK_SSE2(XTS_MASK); + pxor XTS_TW_X0, %xmm0; + XTS_NEXT_TWEAK_1BLOCK_SSE2(XTS_TW_X1, XTS_TW_X0, %xmm4, XTS_MASK); + pxor XTS_TW_X1, %xmm1; + XTS_NEXT_TWEAK_1BLOCK_SSE2(XTS_TW_O2, XTS_TW_X1, %xmm4, XTS_MASK); + pxor XTS_TW_O2, %xmm5; + XTS_NEXT_TWEAK_1BLOCK_SSE2(XTS_TW_X3, XTS_TW_O2, %xmm4, XTS_MASK); + pxor XTS_TW_X3, %xmm3; + + TRANSPOSE_BLOCK4_SSE2(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5); + + call __lea_x86_64_enc_4way_sse2; + + TRANSPOSE_BLOCK4_SSE2(%xmm0, %xmm1, %xmm5, %xmm3, %xmm4, %xmm2); + + pxor XTS_TW_X0, %xmm0; + pxor XTS_TW_X1, %xmm1; + pxor XTS_TW_O2, %xmm5; + pxor XTS_TW_X3, %xmm3; + + XTS_NEXT_TWEAK_1BLOCK_SSE2(XTS_TW_X0, XTS_TW_X3, %xmm4, XTS_MASK); + movdqu XTS_TW_X0, (%rcx); + STORE_BLOCK4_SSE2(%xmm0, %xmm1, %xmm5, %xmm3, %rsi); + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_xts_enc_4way_sse2) + +SYM_FUNC_START(lea_x86_64_xts_enc_4way_avx2) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (4 blocks) + * %rdx: src (4 blocks) + * %rcx: tweak + */ + FRAME_BEGIN + + LOAD_BLOCK4_AVX2(%xmm0, %xmm1, %xmm5, %xmm3, %rdx); + vmovdqu (%rcx), XTS_TW_X0; + XTS_LOAD_TWEAK_MASK_AVX2(XTS_MASK); + vpxor XTS_TW_X0, %xmm0, %xmm0; + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X1, XTS_TW_X0, %xmm4, XTS_MASK); + vpxor XTS_TW_X1, %xmm1, %xmm1; + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_O2, XTS_TW_X1, %xmm4, XTS_MASK); + vpxor XTS_TW_O2, %xmm5, %xmm5; + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X3, XTS_TW_O2, %xmm4, XTS_MASK); + vpxor XTS_TW_X3, %xmm3, %xmm3; + + + TRANSPOSE_BLOCK4_AVX2(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5); + + call __lea_x86_64_enc_4way_avx2 + + TRANSPOSE_BLOCK4_AVX2(%xmm0, %xmm1, %xmm5, %xmm3, %xmm4, %xmm2); + + vpxor XTS_TW_X0, %xmm0, %xmm0; + vpxor XTS_TW_X1, %xmm1, %xmm1; + vpxor XTS_TW_O2, %xmm5, %xmm5; + vpxor XTS_TW_X3, %xmm3, %xmm3; + + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X0, XTS_TW_X3, %xmm4, XTS_MASK); + vmovdqu XTS_TW_X0, (%rcx); + STORE_BLOCK4_AVX2(%xmm0, %xmm1, %xmm5, %xmm3, %rsi); + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_xts_enc_4way_avx2) + +SYM_FUNC_START(lea_x86_64_xts_enc_8way_avx2) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (8 blocks) + * %rdx: src (8 blocks) + * %rcx: tweak + */ + FRAME_BEGIN + + vzeroupper; + + vmovdqu (%rcx), XTS_TW_X0; + XTS_LOAD_TWEAK_MASK_AVX2(XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X1, XTS_TW_X0, %xmm6, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_I2, XTS_TW_X1, %xmm6, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X3, XTS_TW_I2, %xmm6, XTS_MASK); + + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X4, XTS_TW_X3, %xmm6, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X5, XTS_TW_X4, %xmm6, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_I6, XTS_TW_X5, %xmm6, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X7, XTS_TW_I6, %xmm6, XTS_MASK); + + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X8, XTS_TW_X7, %xmm6, XTS_MASK); + vmovdqu XTS_TW_X8, (%rcx); + + TRANSPOSE_BLOCK4_AVX2(XTS_TW_X0, XTS_TW_X1, XTS_TW_O2, XTS_TW_X3, %xmm5, XTS_TW_I2); + TRANSPOSE_BLOCK4_AVX2(XTS_TW_X4, XTS_TW_X5, XTS_TW_O6, XTS_TW_X7, %xmm5, XTS_TW_I6); + + vinserti128 $0x1, XTS_TW_X4, XTS_TW_Y0, XTS_TW_Y0; + vinserti128 $0x1, XTS_TW_X5, XTS_TW_Y1, XTS_TW_Y1; + vinserti128 $0x1, XTS_TW_O6, XTS_TW_Y2, XTS_TW_Y2; + vinserti128 $0x1, XTS_TW_X7, XTS_TW_Y3, XTS_TW_Y3; + + GATHER_BLOCK8_AVX2(0, 1, 2, 3, 4, %rdx); + + vpxor XTS_TW_Y0, %ymm0, %ymm0; + vpxor XTS_TW_Y1, %ymm1, %ymm1; + vpxor XTS_TW_Y2, %ymm2, %ymm2; + vpxor XTS_TW_Y3, %ymm3, %ymm3; + + call __lea_x86_64_enc_8way_avx2 + + vpxor XTS_TW_Y0, %ymm0, %ymm0; + vpxor XTS_TW_Y1, %ymm1, %ymm1; + vpxor XTS_TW_Y2, %ymm2, %ymm2; + vpxor XTS_TW_Y3, %ymm3, %ymm3; + + SCATTER_BLOCK8_AVX2(0, 1, 2, 3, %rsi); + + vzeroupper; + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_xts_enc_8way_avx2) + +#ifdef CONFIG_AS_AVX512 +SYM_FUNC_START(lea_x86_64_xts_enc_4way_avx512) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (4 blocks) + * %rdx: src (4 blocks) + * %rcx: tweak + */ + FRAME_BEGIN + + LOAD_BLOCK4_AVX2(%xmm0, %xmm1, %xmm5, %xmm3, %rdx); + vmovdqu (%rcx), XTS_TW_X0; + XTS_LOAD_TWEAK_MASK_AVX2(XTS_MASK); + vpxor XTS_TW_X0, %xmm0, %xmm0; + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X1, XTS_TW_X0, %xmm4, XTS_MASK); + vpxor XTS_TW_X1, %xmm1, %xmm1; + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_O2, XTS_TW_X1, %xmm4, XTS_MASK); + vpxor XTS_TW_O2, %xmm5, %xmm5; + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X3, XTS_TW_O2, %xmm4, XTS_MASK); + vpxor XTS_TW_X3, %xmm3, %xmm3; + + + TRANSPOSE_BLOCK4_AVX2(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5); + + call __lea_x86_64_enc_4way_avx512 + + TRANSPOSE_BLOCK4_AVX2(%xmm0, %xmm1, %xmm5, %xmm3, %xmm4, %xmm2); + + vpxor XTS_TW_X0, %xmm0, %xmm0; + vpxor XTS_TW_X1, %xmm1, %xmm1; + vpxor XTS_TW_O2, %xmm5, %xmm5; + vpxor XTS_TW_X3, %xmm3, %xmm3; + + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X0, XTS_TW_X3, %xmm4, XTS_MASK); + vmovdqu XTS_TW_X0, (%rcx); + STORE_BLOCK4_AVX2(%xmm0, %xmm1, %xmm5, %xmm3, %rsi); + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_xts_enc_4way_avx512) + +SYM_FUNC_START(lea_x86_64_xts_enc_8way_avx512) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (8 blocks) + * %rdx: src (8 blocks) + * %rcx: tweak + */ + FRAME_BEGIN + + vzeroupper; + + vmovdqu (%rcx), XTS_TW_X0; + XTS_LOAD_TWEAK_MASK_AVX2(XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X1, XTS_TW_X0, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_I2, XTS_TW_X1, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X3, XTS_TW_I2, %xmm5, XTS_MASK); + + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X4, XTS_TW_X3, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X5, XTS_TW_X4, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_I6, XTS_TW_X5, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X7, XTS_TW_I6, %xmm5, XTS_MASK); + + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X8, XTS_TW_X7, %xmm5, XTS_MASK); + vmovdqu XTS_TW_X8, (%rcx); + + TRANSPOSE_BLOCK4_AVX2(XTS_TW_X0, XTS_TW_X1, XTS_TW_O2, XTS_TW_X3, %xmm5, XTS_TW_I2); + TRANSPOSE_BLOCK4_AVX2(XTS_TW_X4, XTS_TW_X5, XTS_TW_O6, XTS_TW_X7, %xmm5, XTS_TW_I6); + + vinserti128 $0x1, XTS_TW_X4, XTS_TW_Y0, XTS_TW_Y0; + vinserti128 $0x1, XTS_TW_X5, XTS_TW_Y1, XTS_TW_Y1; + vinserti128 $0x1, XTS_TW_O6, XTS_TW_Y2, XTS_TW_Y2; + vinserti128 $0x1, XTS_TW_X7, XTS_TW_Y3, XTS_TW_Y3; + + GATHER_BLOCK8_AVX2(0, 1, 2, 3, 4, %rdx); + + vpxor XTS_TW_Y0, %ymm0, %ymm0; + vpxor XTS_TW_Y1, %ymm1, %ymm1; + vpxor XTS_TW_Y2, %ymm2, %ymm2; + vpxor XTS_TW_Y3, %ymm3, %ymm3; + + call __lea_x86_64_enc_8way_avx512 + + vpxor XTS_TW_Y0, %ymm0, %ymm0; + vpxor XTS_TW_Y1, %ymm1, %ymm1; + vpxor XTS_TW_Y2, %ymm2, %ymm2; + vpxor XTS_TW_Y3, %ymm3, %ymm3; + + SCATTER_BLOCK8_AVX2(0, 1, 2, 3, %rsi); + + vzeroupper; + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_xts_enc_8way_avx512) + +SYM_FUNC_START(lea_x86_64_xts_enc_16way_avx512) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (16 blocks) + * %rdx: src (16 blocks) + * %rcx: tweak + */ + FRAME_BEGIN + + vzeroupper; + + vmovdqu (%rcx), XTS_TW_X0; + XTS_LOAD_TWEAK_MASK_AVX2(XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X1, XTS_TW_X0, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_I2, XTS_TW_X1, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X3, XTS_TW_I2, %xmm5, XTS_MASK); + + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X4, XTS_TW_X3, %xmm5, XTS_MASK); + + TRANSPOSE_BLOCK4_AVX2(XTS_TW_X0, XTS_TW_X1, XTS_TW_O2, XTS_TW_X3, %xmm5, XTS_TW_I2); + + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X5, XTS_TW_X4, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_I6, XTS_TW_X5, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X7, XTS_TW_I6, %xmm5, XTS_MASK); + + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X8, XTS_TW_X7, %xmm5, XTS_MASK); + + TRANSPOSE_BLOCK4_AVX2(XTS_TW_X4, XTS_TW_X5, XTS_TW_O6, XTS_TW_X7, %xmm5, XTS_TW_I6); + + vinserti32x4 $0x1, XTS_TW_X4, XTS_TW_Z0, XTS_TW_Z0; + vinserti32x4 $0x1, XTS_TW_X5, XTS_TW_Z1, XTS_TW_Z1; + vinserti32x4 $0x1, XTS_TW_O6, XTS_TW_Z2, XTS_TW_Z2; + vinserti32x4 $0x1, XTS_TW_X7, XTS_TW_Z3, XTS_TW_Z3; + + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X5, XTS_TW_X8, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_I6, XTS_TW_X5, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X7, XTS_TW_I6, %xmm5, XTS_MASK); + + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X4, XTS_TW_X7, %xmm5, XTS_MASK); + + TRANSPOSE_BLOCK4_AVX2(XTS_TW_X8, XTS_TW_X5, XTS_TW_O6, XTS_TW_X7, %xmm5, XTS_TW_I6); + + vinserti32x4 $0x2, XTS_TW_X8, XTS_TW_Z0, XTS_TW_Z0; + vinserti32x4 $0x2, XTS_TW_X5, XTS_TW_Z1, XTS_TW_Z1; + vinserti32x4 $0x2, XTS_TW_O6, XTS_TW_Z2, XTS_TW_Z2; + vinserti32x4 $0x2, XTS_TW_X7, XTS_TW_Z3, XTS_TW_Z3; + + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X5, XTS_TW_X4, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_I6, XTS_TW_X5, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X7, XTS_TW_I6, %xmm5, XTS_MASK); + + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X8, XTS_TW_X7, %xmm5, XTS_MASK); + + TRANSPOSE_BLOCK4_AVX2(XTS_TW_X4, XTS_TW_X5, XTS_TW_O6, XTS_TW_X7, %xmm5, XTS_TW_I6); + + vinserti32x4 $0x3, XTS_TW_X4, XTS_TW_Z0, XTS_TW_Z0; + vinserti32x4 $0x3, XTS_TW_X5, XTS_TW_Z1, XTS_TW_Z1; + vinserti32x4 $0x3, XTS_TW_O6, XTS_TW_Z2, XTS_TW_Z2; + vinserti32x4 $0x3, XTS_TW_X7, XTS_TW_Z3, XTS_TW_Z3; + + vmovdqu XTS_TW_X8, (%rcx); + + GATHER_BLOCK16_AVX512(0, 1, 2, 3, 4, %rdx); + + vpxord XTS_TW_Z0, %zmm0, %zmm0; + vpxord XTS_TW_Z1, %zmm1, %zmm1; + vpxord XTS_TW_Z2, %zmm2, %zmm2; + vpxord XTS_TW_Z3, %zmm3, %zmm3; + + call __lea_x86_64_enc_16way_avx512 + + vpxord XTS_TW_Z0, %zmm0, %zmm0; + vpxord XTS_TW_Z1, %zmm1, %zmm1; + vpxord XTS_TW_Z2, %zmm2, %zmm2; + vpxord XTS_TW_Z3, %zmm3, %zmm3; + + SCATTER_BLOCK16_AVX512(0, 1, 2, 3, 4, %rsi); + + vzeroupper; + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_xts_enc_16way_avx512) +#endif + +SYM_FUNC_START(lea_x86_64_xts_dec_4way_sse2) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (4 blocks) + * %rdx: src (4 blocks) + * %rcx: tweak + */ + FRAME_BEGIN + + LOAD_BLOCK4_SSE2(%xmm0, %xmm1, %xmm5, %xmm3, %rdx); + movdqu (%rcx), XTS_TW_X0; + XTS_LOAD_TWEAK_MASK_SSE2(XTS_MASK); + pxor XTS_TW_X0, %xmm0; + XTS_NEXT_TWEAK_1BLOCK_SSE2(XTS_TW_X1, XTS_TW_X0, %xmm4, XTS_MASK); + pxor XTS_TW_X1, %xmm1; + XTS_NEXT_TWEAK_1BLOCK_SSE2(XTS_TW_O2, XTS_TW_X1, %xmm4, XTS_MASK); + pxor XTS_TW_O2, %xmm5; + XTS_NEXT_TWEAK_1BLOCK_SSE2(XTS_TW_X3, XTS_TW_O2, %xmm4, XTS_MASK); + pxor XTS_TW_X3, %xmm3; + + TRANSPOSE_BLOCK4_SSE2(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5); + + call __lea_x86_64_dec_4way_sse2 + + TRANSPOSE_BLOCK4_SSE2(%xmm0, %xmm1, %xmm5, %xmm3, %xmm4, %xmm2); + + pxor XTS_TW_X0, %xmm0; + pxor XTS_TW_X1, %xmm1; + pxor XTS_TW_O2, %xmm5; + pxor XTS_TW_X3, %xmm3; + + XTS_NEXT_TWEAK_1BLOCK_SSE2(XTS_TW_X0, XTS_TW_X3, %xmm4, XTS_MASK); + movdqu XTS_TW_X0, (%rcx); + STORE_BLOCK4_SSE2(%xmm0, %xmm1, %xmm5, %xmm3, %rsi); + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_xts_dec_4way_sse2) + +SYM_FUNC_START(lea_x86_64_xts_dec_4way_avx2) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (4 blocks) + * %rdx: src (4 blocks) + * %rcx: tweak + */ + FRAME_BEGIN + + LOAD_BLOCK4_AVX2(%xmm0, %xmm1, %xmm5, %xmm3, %rdx); + vmovdqu (%rcx), XTS_TW_X0; + XTS_LOAD_TWEAK_MASK_AVX2(XTS_MASK); + vpxor XTS_TW_X0, %xmm0, %xmm0; + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X1, XTS_TW_X0, %xmm4, XTS_MASK); + vpxor XTS_TW_X1, %xmm1, %xmm1; + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_O2, XTS_TW_X1, %xmm4, XTS_MASK); + vpxor XTS_TW_O2, %xmm5, %xmm5; + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X3, XTS_TW_O2, %xmm4, XTS_MASK); + vpxor XTS_TW_X3, %xmm3, %xmm3; + + TRANSPOSE_BLOCK4_AVX2(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5); + + call __lea_x86_64_dec_4way_avx2 + + TRANSPOSE_BLOCK4_AVX2(%xmm0, %xmm1, %xmm5, %xmm3, %xmm4, %xmm2); + + vpxor XTS_TW_X0, %xmm0, %xmm0; + vpxor XTS_TW_X1, %xmm1, %xmm1; + vpxor XTS_TW_O2, %xmm5, %xmm5; + vpxor XTS_TW_X3, %xmm3, %xmm3; + + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X0, XTS_TW_X3, %xmm4, XTS_MASK); + vmovdqu XTS_TW_X0, (%rcx); + STORE_BLOCK4_AVX2(%xmm0, %xmm1, %xmm5, %xmm3, %rsi); + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_xts_dec_4way_avx2) + +SYM_FUNC_START(lea_x86_64_xts_dec_8way_avx2) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (8 blocks) + * %rdx: src (8 blocks) + * %rcx: tweak + */ + FRAME_BEGIN + + vzeroupper; + + vmovdqu (%rcx), XTS_TW_X0; + XTS_LOAD_TWEAK_MASK_AVX2(XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X1, XTS_TW_X0, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_I2, XTS_TW_X1, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X3, XTS_TW_I2, %xmm5, XTS_MASK); + + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X4, XTS_TW_X3, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X5, XTS_TW_X4, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_I6, XTS_TW_X5, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X7, XTS_TW_I6, %xmm5, XTS_MASK); + + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X8, XTS_TW_X7, %xmm5, XTS_MASK); + vmovdqu XTS_TW_X8, (%rcx); + + TRANSPOSE_BLOCK4_AVX2(XTS_TW_X0, XTS_TW_X1, XTS_TW_O2, XTS_TW_X3, %xmm5, XTS_TW_I2); + TRANSPOSE_BLOCK4_AVX2(XTS_TW_X4, XTS_TW_X5, XTS_TW_O6, XTS_TW_X7, %xmm5, XTS_TW_I6); + + vinserti128 $0x1, XTS_TW_X4, XTS_TW_Y0, XTS_TW_Y0; + vinserti128 $0x1, XTS_TW_X5, XTS_TW_Y1, XTS_TW_Y1; + vinserti128 $0x1, XTS_TW_O6, XTS_TW_Y2, XTS_TW_Y2; + vinserti128 $0x1, XTS_TW_X7, XTS_TW_Y3, XTS_TW_Y3; + + GATHER_BLOCK8_AVX2(0, 1, 2, 3, 4, %rdx); + + vpxor XTS_TW_Y0, %ymm0, %ymm0; + vpxor XTS_TW_Y1, %ymm1, %ymm1; + vpxor XTS_TW_Y2, %ymm2, %ymm2; + vpxor XTS_TW_Y3, %ymm3, %ymm3; + + call __lea_x86_64_dec_8way_avx2 + + vpxor XTS_TW_Y0, %ymm0, %ymm0; + vpxor XTS_TW_Y1, %ymm1, %ymm1; + vpxor XTS_TW_Y2, %ymm2, %ymm2; + vpxor XTS_TW_Y3, %ymm3, %ymm3; + + SCATTER_BLOCK8_AVX2(0, 1, 2, 3, %rsi); + + vzeroupper; + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_xts_dec_8way_avx2) + +#ifdef CONFIG_AS_AVX512 +SYM_FUNC_START(lea_x86_64_xts_dec_4way_avx512) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (4 blocks) + * %rdx: src (4 blocks) + * %rcx: tweak + */ + FRAME_BEGIN + + LOAD_BLOCK4_AVX2(%xmm0, %xmm1, %xmm5, %xmm3, %rdx); + vmovdqu (%rcx), XTS_TW_X0; + XTS_LOAD_TWEAK_MASK_AVX2(XTS_MASK); + vpxor XTS_TW_X0, %xmm0, %xmm0; + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X1, XTS_TW_X0, %xmm4, XTS_MASK); + vpxor XTS_TW_X1, %xmm1, %xmm1; + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_O2, XTS_TW_X1, %xmm4, XTS_MASK); + vpxor XTS_TW_O2, %xmm5, %xmm5; + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X3, XTS_TW_O2, %xmm4, XTS_MASK); + vpxor XTS_TW_X3, %xmm3, %xmm3; + + TRANSPOSE_BLOCK4_AVX2(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5); + + call __lea_x86_64_dec_4way_avx512 + + TRANSPOSE_BLOCK4_AVX2(%xmm0, %xmm1, %xmm5, %xmm3, %xmm4, %xmm2); + + vpxor XTS_TW_X0, %xmm0, %xmm0; + vpxor XTS_TW_X1, %xmm1, %xmm1; + vpxor XTS_TW_O2, %xmm5, %xmm5; + vpxor XTS_TW_X3, %xmm3, %xmm3; + + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X0, XTS_TW_X3, %xmm4, XTS_MASK); + vmovdqu XTS_TW_X0, (%rcx); + STORE_BLOCK4_AVX2(%xmm0, %xmm1, %xmm5, %xmm3, %rsi); + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_xts_dec_4way_avx512) + +SYM_FUNC_START(lea_x86_64_xts_dec_8way_avx512) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (8 blocks) + * %rdx: src (8 blocks) + * %rcx: tweak + */ + FRAME_BEGIN + + vzeroupper; + + vmovdqu (%rcx), XTS_TW_X0; + XTS_LOAD_TWEAK_MASK_AVX2(XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X1, XTS_TW_X0, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_I2, XTS_TW_X1, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X3, XTS_TW_I2, %xmm5, XTS_MASK); + + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X4, XTS_TW_X3, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X5, XTS_TW_X4, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_I6, XTS_TW_X5, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X7, XTS_TW_I6, %xmm5, XTS_MASK); + + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X8, XTS_TW_X7, %xmm5, XTS_MASK); + vmovdqu XTS_TW_X8, (%rcx); + + TRANSPOSE_BLOCK4_AVX2(XTS_TW_X0, XTS_TW_X1, XTS_TW_O2, XTS_TW_X3, %xmm5, XTS_TW_I2); + TRANSPOSE_BLOCK4_AVX2(XTS_TW_X4, XTS_TW_X5, XTS_TW_O6, XTS_TW_X7, %xmm5, XTS_TW_I6); + + vinserti128 $0x1, XTS_TW_X4, XTS_TW_Y0, XTS_TW_Y0; + vinserti128 $0x1, XTS_TW_X5, XTS_TW_Y1, XTS_TW_Y1; + vinserti128 $0x1, XTS_TW_O6, XTS_TW_Y2, XTS_TW_Y2; + vinserti128 $0x1, XTS_TW_X7, XTS_TW_Y3, XTS_TW_Y3; + + GATHER_BLOCK8_AVX2(0, 1, 2, 3, 4, %rdx); + + vpxor XTS_TW_Y0, %ymm0, %ymm0; + vpxor XTS_TW_Y1, %ymm1, %ymm1; + vpxor XTS_TW_Y2, %ymm2, %ymm2; + vpxor XTS_TW_Y3, %ymm3, %ymm3; + + call __lea_x86_64_dec_8way_avx512 + + vpxor XTS_TW_Y0, %ymm0, %ymm0; + vpxor XTS_TW_Y1, %ymm1, %ymm1; + vpxor XTS_TW_Y2, %ymm2, %ymm2; + vpxor XTS_TW_Y3, %ymm3, %ymm3; + + SCATTER_BLOCK8_AVX2(0, 1, 2, 3, %rsi); + + vzeroupper; + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_xts_dec_8way_avx512) + +SYM_FUNC_START(lea_x86_64_xts_dec_16way_avx512) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (16 blocks) + * %rdx: src (16 blocks) + * %rcx: tweak + */ + FRAME_BEGIN + + vzeroupper; + + vmovdqu (%rcx), XTS_TW_X0; + XTS_LOAD_TWEAK_MASK_AVX2(XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X1, XTS_TW_X0, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_I2, XTS_TW_X1, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X3, XTS_TW_I2, %xmm5, XTS_MASK); + + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X4, XTS_TW_X3, %xmm5, XTS_MASK); + + TRANSPOSE_BLOCK4_AVX2(XTS_TW_X0, XTS_TW_X1, XTS_TW_O2, XTS_TW_X3, %xmm5, XTS_TW_I2); + + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X5, XTS_TW_X4, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_I6, XTS_TW_X5, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X7, XTS_TW_I6, %xmm5, XTS_MASK); + + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X8, XTS_TW_X7, %xmm5, XTS_MASK); + + TRANSPOSE_BLOCK4_AVX2(XTS_TW_X4, XTS_TW_X5, XTS_TW_O6, XTS_TW_X7, %xmm5, XTS_TW_I6); + + vinserti32x4 $0x1, XTS_TW_X4, XTS_TW_Z0, XTS_TW_Z0; + vinserti32x4 $0x1, XTS_TW_X5, XTS_TW_Z1, XTS_TW_Z1; + vinserti32x4 $0x1, XTS_TW_O6, XTS_TW_Z2, XTS_TW_Z2; + vinserti32x4 $0x1, XTS_TW_X7, XTS_TW_Z3, XTS_TW_Z3; + + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X5, XTS_TW_X8, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_I6, XTS_TW_X5, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X7, XTS_TW_I6, %xmm5, XTS_MASK); + + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X4, XTS_TW_X7, %xmm5, XTS_MASK); + + TRANSPOSE_BLOCK4_AVX2(XTS_TW_X8, XTS_TW_X5, XTS_TW_O6, XTS_TW_X7, %xmm5, XTS_TW_I6); + + vinserti32x4 $0x2, XTS_TW_X8, XTS_TW_Z0, XTS_TW_Z0; + vinserti32x4 $0x2, XTS_TW_X5, XTS_TW_Z1, XTS_TW_Z1; + vinserti32x4 $0x2, XTS_TW_O6, XTS_TW_Z2, XTS_TW_Z2; + vinserti32x4 $0x2, XTS_TW_X7, XTS_TW_Z3, XTS_TW_Z3; + + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X5, XTS_TW_X4, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_I6, XTS_TW_X5, %xmm5, XTS_MASK); + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X7, XTS_TW_I6, %xmm5, XTS_MASK); + + XTS_NEXT_TWEAK_1BLOCK_AVX2(XTS_TW_X8, XTS_TW_X7, %xmm5, XTS_MASK); + + TRANSPOSE_BLOCK4_AVX2(XTS_TW_X4, XTS_TW_X5, XTS_TW_O6, XTS_TW_X7, %xmm5, XTS_TW_I6); + + vinserti32x4 $0x3, XTS_TW_X4, XTS_TW_Z0, XTS_TW_Z0; + vinserti32x4 $0x3, XTS_TW_X5, XTS_TW_Z1, XTS_TW_Z1; + vinserti32x4 $0x3, XTS_TW_O6, XTS_TW_Z2, XTS_TW_Z2; + vinserti32x4 $0x3, XTS_TW_X7, XTS_TW_Z3, XTS_TW_Z3; + + vmovdqu XTS_TW_X8, (%rcx); + + GATHER_BLOCK16_AVX512(0, 1, 2, 3, 4, %rdx); + + vpxord XTS_TW_Z0, %zmm0, %zmm0; + vpxord XTS_TW_Z1, %zmm1, %zmm1; + vpxord XTS_TW_Z2, %zmm2, %zmm2; + vpxord XTS_TW_Z3, %zmm3, %zmm3; + + call __lea_x86_64_dec_16way_avx512 + + vpxord XTS_TW_Z0, %zmm0, %zmm0; + vpxord XTS_TW_Z1, %zmm1, %zmm1; + vpxord XTS_TW_Z2, %zmm2, %zmm2; + vpxord XTS_TW_Z3, %zmm3, %zmm3; + + SCATTER_BLOCK16_AVX512(0, 1, 2, 3, 4, %rsi); + + vzeroupper; + + FRAME_END + RET; +SYM_FUNC_END(lea_x86_64_xts_dec_16way_avx512) +#endif + +#ifdef CONFIG_AS_AVX512 + +.section .rodata.cst64.bswap_shuffle_mask, "aM", @progbits, 64 +.align 64 +.Lbswap_mask: + .byte 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12 + .byte 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12 + .byte 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12 + .byte 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12 + + +.section .rodata.cst64.ctr_add_const, "aM", @progbits, 64 +.align 64 +.Lctr_add_const: + .octa 0x00000003000000020000000100000000 + .octa 0x00000007000000060000000500000004 + .octa 0x0000000b0000000a0000000900000008 + .octa 0x0000000f0000000e0000000d0000000c + +.section .rodata.cst64.cbc_shuffle_mask16, "aM", @progbits, 64 +.align 64 +.Lcbc_shuffle_mask16: + .octa 0x0000000200000001000000000000000f + .octa 0x00000006000000050000000400000003 + .octa 0x0000000a000000090000000800000007 + .octa 0x0000000e0000000d0000000c0000000b + +#else + +.section .rodata.cst32.bswap_shuffle_mask, "aM", @progbits, 32 +.align 32 +.Lbswap_mask: + .byte 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12 + .byte 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12 + +.section .rodata.cst32.ctr_add_const, "aM", @progbits, 32 +.align 32 +.Lctr_add_const: + .octa 0x00000003000000020000000100000000 + .octa 0x00000007000000060000000500000004 + +#endif + +.section .rodata.cst32.cbc_shuffle_mask, "aM", @progbits, 32 +.align 32 +.Lcbc_shuffle_mask: + .octa 0x00000002000000010000000000000007 + .octa 0x00000006000000050000000400000003 + +.section .rodata.cst16.xts_tweak_mask, "aM", @progbits, 16 +.align 16 +.Lxts_tweak_mask: + .octa 0x00000000000000010000000000000087 diff --git a/arch/x86/crypto/lea-x86_64-glue.c b/arch/x86/crypto/lea-x86_64-glue.c new file mode 100644 index 000000000000..a28d89960090 --- /dev/null +++ b/arch/x86/crypto/lea-x86_64-glue.c @@ -0,0 +1,820 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Glue Code for the SSE2/AVX2/AVX-512F assembler instructions + * for the LEA Cipher + * + * - SSE2: 4 parallel blocks + * - AVX2: 8/4 parallel blocks + * - AVX-512F: 16/8/4 parallel blocks + * + * Copyright (c) 2023 National Security Research. + * Author: Dongsoo Lee + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "ecb_cbc_helpers.h" + +struct crypto_lea_xts_ctx { + struct crypto_lea_ctx crypt_ctx; + struct crypto_lea_ctx __aligned(LEA_BLOCK_SIZE) tweak_ctx; +}; + +#define LEA_AVX512_MAX_PARALLEL_BLOCKS 16 +#define LEA_AVX2_MAX_PARALLEL_BLOCKS 8 +#define LEA_SSE2_MAX_PARALLEL_BLOCKS 4 +#define LEA_MIN_PARALLEL_BLOCKS LEA_SSE2_MAX_PARALLEL_BLOCKS + +typedef void (*lea_ecb_enc_nway)(const void *ctx, u8 *dst, const u8 *src); +typedef void (*lea_ecb_dec_nway)(const void *ctx, u8 *dst, const u8 *src); + +typedef void (*lea_cbc_dec_nway)(const void *ctx, u8 *dst, const u8 *src); + +typedef void (*lea_ctr_enc_nway)(const void *ctx, u8 *dst, const u8 *src, + u8 *ctr); + +typedef void (*lea_xts_enc_nway)(const void *ctx, u8 *dst, const u8 *src, + u8 *tweak); +typedef void (*lea_xts_dec_nway)(const void *ctx, u8 *dst, const u8 *src, + u8 *tweak); + +struct lea_func_map_t { + lea_ecb_enc_nway ecb_enc_4way; + lea_ecb_dec_nway ecb_dec_4way; + lea_cbc_dec_nway cbc_dec_4way; + lea_ctr_enc_nway ctr_enc_4way; + lea_xts_enc_nway xts_enc_4way; + lea_xts_dec_nway xts_dec_4way; + + lea_ecb_enc_nway ecb_enc_8way; + lea_ecb_dec_nway ecb_dec_8way; + lea_cbc_dec_nway cbc_dec_8way; + lea_ctr_enc_nway ctr_enc_8way; + lea_xts_enc_nway xts_enc_8way; + lea_xts_dec_nway xts_dec_8way; + +#ifdef CONFIG_AS_AVX512 + lea_ecb_enc_nway ecb_enc_16way; + lea_ecb_dec_nway ecb_dec_16way; + lea_cbc_dec_nway cbc_dec_16way; + lea_ctr_enc_nway ctr_enc_16way; + lea_xts_enc_nway xts_enc_16way; + lea_xts_dec_nway xts_dec_16way; +#endif + int proc_blocks; +}; + +#ifdef CONFIG_AS_AVX512 +asmlinkage void lea_x86_64_ecb_enc_16way_avx512(const void *ctx, u8 *dst, + const u8 *src); +asmlinkage void lea_x86_64_ecb_dec_16way_avx512(const void *ctx, u8 *dst, + const u8 *src); +asmlinkage void lea_x86_64_ecb_enc_8way_avx512(const void *ctx, u8 *dst, + const u8 *src); +asmlinkage void lea_x86_64_ecb_dec_8way_avx512(const void *ctx, u8 *dst, + const u8 *src); +asmlinkage void lea_x86_64_ecb_enc_4way_avx512(const void *ctx, u8 *dst, + const u8 *src); +asmlinkage void lea_x86_64_ecb_dec_4way_avx512(const void *ctx, u8 *dst, + const u8 *src); +#endif + +asmlinkage void lea_x86_64_ecb_enc_8way_avx2(const void *ctx, u8 *dst, + const u8 *src); +asmlinkage void lea_x86_64_ecb_dec_8way_avx2(const void *ctx, u8 *dst, + const u8 *src); +asmlinkage void lea_x86_64_ecb_enc_4way_avx2(const void *ctx, u8 *dst, + const u8 *src); +asmlinkage void lea_x86_64_ecb_dec_4way_avx2(const void *ctx, u8 *dst, + const u8 *src); + +asmlinkage void lea_x86_64_ecb_enc_4way_sse2(const void *ctx, u8 *dst, + const u8 *src); +asmlinkage void lea_x86_64_ecb_dec_4way_sse2(const void *ctx, u8 *dst, + const u8 *src); + +#ifdef CONFIG_AS_AVX512 +asmlinkage void lea_x86_64_cbc_dec_16way_avx512(const void *ctx, u8 *dst, + const u8 *src); +asmlinkage void lea_x86_64_cbc_dec_8way_avx512(const void *ctx, u8 *dst, + const u8 *src); +asmlinkage void lea_x86_64_cbc_dec_4way_avx512(const void *ctx, u8 *dst, + const u8 *src); +#endif + +asmlinkage void lea_x86_64_cbc_dec_8way_avx2(const void *ctx, u8 *dst, + const u8 *src); +asmlinkage void lea_x86_64_cbc_dec_4way_avx2(const void *ctx, u8 *dst, + const u8 *src); + +asmlinkage void lea_x86_64_cbc_dec_4way_sse2(const void *ctx, u8 *dst, + const u8 *src); + +#ifdef CONFIG_AS_AVX512 +asmlinkage void lea_x86_64_ctr_enc_16way_avx512(const void *ctx, u8 *dst, + const u8 *src, u8 *ctr); +asmlinkage void lea_x86_64_ctr_enc_8way_avx512(const void *ctx, u8 *dst, + const u8 *src, u8 *ctr); +asmlinkage void lea_x86_64_ctr_enc_4way_avx512(const void *ctx, u8 *dst, + const u8 *src, u8 *ctr); +#endif + +asmlinkage void lea_x86_64_ctr_enc_8way_avx2(const void *ctx, u8 *dst, + const u8 *src, u8 *ctr); +asmlinkage void lea_x86_64_ctr_enc_4way_avx2(const void *ctx, u8 *dst, + const u8 *src, u8 *ctr); + +asmlinkage void lea_x86_64_ctr_enc_4way_sse2(const void *ctx, u8 *dst, + const u8 *src, u8 *ctr); + +#ifdef CONFIG_AS_AVX512 +asmlinkage void lea_x86_64_xts_enc_16way_avx512(const void *ctx, u8 *dst, + const u8 *src, u8 *tweak); +asmlinkage void lea_x86_64_xts_dec_16way_avx512(const void *ctx, u8 *dst, + const u8 *src, u8 *tweak); +asmlinkage void lea_x86_64_xts_enc_8way_avx512(const void *ctx, u8 *dst, + const u8 *src, u8 *tweak); +asmlinkage void lea_x86_64_xts_dec_8way_avx512(const void *ctx, u8 *dst, + const u8 *src, u8 *tweak); +asmlinkage void lea_x86_64_xts_enc_4way_avx512(const void *ctx, u8 *dst, + const u8 *src, u8 *tweak); +asmlinkage void lea_x86_64_xts_dec_4way_avx512(const void *ctx, u8 *dst, + const u8 *src, u8 *tweak); +#endif + +asmlinkage void lea_x86_64_xts_enc_8way_avx2(const void *ctx, u8 *dst, + const u8 *src, u8 *tweak); +asmlinkage void lea_x86_64_xts_dec_8way_avx2(const void *ctx, u8 *dst, + const u8 *src, u8 *tweak); +asmlinkage void lea_x86_64_xts_enc_4way_avx2(const void *ctx, u8 *dst, + const u8 *src, u8 *tweak); +asmlinkage void lea_x86_64_xts_dec_4way_avx2(const void *ctx, u8 *dst, + const u8 *src, u8 *tweak); + +asmlinkage void lea_x86_64_xts_enc_4way_sse2(const void *ctx, u8 *dst, + const u8 *src, u8 *tweak); +asmlinkage void lea_x86_64_xts_dec_4way_sse2(const void *ctx, u8 *dst, + const u8 *src, u8 *tweak); + +#ifdef CONFIG_AS_AVX512 +static const struct lea_func_map_t lea_avx512_func_map = { + .ecb_enc_4way = lea_x86_64_ecb_enc_4way_avx512, + .ecb_dec_4way = lea_x86_64_ecb_dec_4way_avx512, + .cbc_dec_4way = lea_x86_64_cbc_dec_4way_avx512, + .ctr_enc_4way = lea_x86_64_ctr_enc_4way_avx512, + .xts_enc_4way = lea_x86_64_xts_enc_4way_avx512, + .xts_dec_4way = lea_x86_64_xts_dec_4way_avx512, + + .ecb_enc_8way = lea_x86_64_ecb_enc_8way_avx512, + .ecb_dec_8way = lea_x86_64_ecb_dec_8way_avx512, + .cbc_dec_8way = lea_x86_64_cbc_dec_8way_avx512, + .ctr_enc_8way = lea_x86_64_ctr_enc_8way_avx512, + .xts_enc_8way = lea_x86_64_xts_enc_8way_avx512, + .xts_dec_8way = lea_x86_64_xts_dec_8way_avx512, + + .ecb_enc_16way = lea_x86_64_ecb_enc_16way_avx512, + .ecb_dec_16way = lea_x86_64_ecb_dec_16way_avx512, + .cbc_dec_16way = lea_x86_64_cbc_dec_16way_avx512, + .ctr_enc_16way = lea_x86_64_ctr_enc_16way_avx512, + .xts_enc_16way = lea_x86_64_xts_enc_16way_avx512, + .xts_dec_16way = lea_x86_64_xts_dec_16way_avx512, + + .proc_blocks = LEA_AVX512_MAX_PARALLEL_BLOCKS, +}; +#endif + +static const struct lea_func_map_t lea_avx2_func_map = { + .ecb_enc_4way = lea_x86_64_ecb_enc_4way_avx2, + .ecb_dec_4way = lea_x86_64_ecb_dec_4way_avx2, + .cbc_dec_4way = lea_x86_64_cbc_dec_4way_avx2, + .ctr_enc_4way = lea_x86_64_ctr_enc_4way_avx2, + .xts_enc_4way = lea_x86_64_xts_enc_4way_avx2, + .xts_dec_4way = lea_x86_64_xts_dec_4way_avx2, + + .ecb_enc_8way = lea_x86_64_ecb_enc_8way_avx2, + .ecb_dec_8way = lea_x86_64_ecb_dec_8way_avx2, + .cbc_dec_8way = lea_x86_64_cbc_dec_8way_avx2, + .ctr_enc_8way = lea_x86_64_ctr_enc_8way_avx2, + .xts_enc_8way = lea_x86_64_xts_enc_8way_avx2, + .xts_dec_8way = lea_x86_64_xts_dec_8way_avx2, + + .proc_blocks = LEA_AVX2_MAX_PARALLEL_BLOCKS, +}; + +/* default SSE2 */ +static struct lea_func_map_t lea_func_map = { + .ecb_enc_4way = lea_x86_64_ecb_enc_4way_sse2, + .ecb_dec_4way = lea_x86_64_ecb_dec_4way_sse2, + .cbc_dec_4way = lea_x86_64_cbc_dec_4way_sse2, + .ctr_enc_4way = lea_x86_64_ctr_enc_4way_sse2, + .xts_enc_4way = lea_x86_64_xts_enc_4way_sse2, + .xts_dec_4way = lea_x86_64_xts_dec_4way_sse2, + + .proc_blocks = LEA_SSE2_MAX_PARALLEL_BLOCKS, +}; + +static int ecb_encrypt_nway(struct skcipher_request *req) +{ + ECB_WALK_START(req, LEA_BLOCK_SIZE, LEA_MIN_PARALLEL_BLOCKS); + if (lea_func_map.ecb_enc_16way) + ECB_BLOCK(16, lea_func_map.ecb_enc_16way); + if (lea_func_map.ecb_enc_8way) + ECB_BLOCK(8, lea_func_map.ecb_enc_8way); + ECB_BLOCK(4, lea_func_map.ecb_enc_4way); + ECB_BLOCK(1, lea_encrypt); + ECB_WALK_END(); +} + +static int ecb_decrypt_nway(struct skcipher_request *req) +{ + ECB_WALK_START(req, LEA_BLOCK_SIZE, LEA_MIN_PARALLEL_BLOCKS); + if (lea_func_map.ecb_dec_16way) + ECB_BLOCK(16, lea_func_map.ecb_dec_16way); + if (lea_func_map.ecb_dec_8way) + ECB_BLOCK(8, lea_func_map.ecb_dec_8way); + ECB_BLOCK(4, lea_x86_64_ecb_dec_4way_avx2); + ECB_BLOCK(1, lea_decrypt); + ECB_WALK_END(); +} + +static int cbc_encrypt(struct skcipher_request *req) +{ + CBC_WALK_START(req, LEA_BLOCK_SIZE, -1); + CBC_ENC_BLOCK(lea_encrypt); + CBC_WALK_END(); +} + +static int cbc_decrypt_nway(struct skcipher_request *req) +{ + CBC_WALK_START(req, LEA_BLOCK_SIZE, LEA_MIN_PARALLEL_BLOCKS); + if (lea_func_map.cbc_dec_16way) + CBC_DEC_BLOCK(16, lea_func_map.cbc_dec_16way); + if (lea_func_map.cbc_dec_8way) + CBC_DEC_BLOCK(8, lea_func_map.cbc_dec_8way); + CBC_DEC_BLOCK(4, lea_func_map.cbc_dec_4way); + CBC_DEC_BLOCK(1, lea_decrypt); + CBC_WALK_END(); +} + +static inline void xor_1blk(u8 *out, const u8 *in1, const u8 *in2) +{ + const u64 *_in1 = (const u64 *)in1; + const u64 *_in2 = (const u64 *)in2; + u64 *_out = (u64 *)out; + + _out[0] = _in1[0] ^ _in2[0]; + _out[1] = _in1[1] ^ _in2[1]; +} + +static inline void xts_next_tweak(u8 *out, const u8 *in) +{ + const u64 *_in = (const u64 *)in; + u64 *_out = (u64 *)out; + u64 v0 = _in[0]; + u64 v1 = _in[1]; + u64 carry = (u64)(((s64)v1) >> 63); + + v1 = (v1 << 1) ^ (v0 >> 63); + v0 = (v0 << 1) ^ ((u64)carry & 0x87); + + _out[0] = v0; + _out[1] = v1; +} + +#define CTR_NWAY(NWAY, FUNC) \ + while (nbytes >= NWAY * LEA_BLOCK_SIZE) { \ + FUNC(ctx, dst, src, walk.iv); \ + src += NWAY * LEA_BLOCK_SIZE; \ + dst += NWAY * LEA_BLOCK_SIZE; \ + nbytes -= NWAY * LEA_BLOCK_SIZE; \ + } + +#define XTS_NWAY(NWAY, FUNC) \ + for (; nblocks >= NWAY; nblocks -= NWAY) { \ + FUNC(&ctx->crypt_ctx, dst, src, walk.iv); \ + src += NWAY * LEA_BLOCK_SIZE; \ + dst += NWAY * LEA_BLOCK_SIZE; \ + nbytes -= NWAY * LEA_BLOCK_SIZE; \ + } + +#define XTS_SINGLE(FUNC) \ + for (; nblocks > 0; nblocks -= 1) { \ + u8 __aligned(16) buffer[LEA_BLOCK_SIZE]; \ + xor_1blk(buffer, walk.iv, src); \ + FUNC(&ctx->crypt_ctx, buffer, buffer); \ + xor_1blk(dst, walk.iv, buffer); \ + xts_next_tweak(walk.iv, walk.iv); \ + src += LEA_BLOCK_SIZE; \ + dst += LEA_BLOCK_SIZE; \ + nbytes -= LEA_BLOCK_SIZE; \ + } + +#define XTS_TAIL_ENCRYPT(FUNC) \ + do { \ + u8 __aligned(16) buffer[LEA_BLOCK_SIZE]; \ + xor_1blk(buffer, walk.iv, src); \ + FUNC(&ctx->crypt_ctx, buffer, buffer); \ + xor_1blk(buffer, walk.iv, buffer); \ + memcpy(dst, buffer, LEA_BLOCK_SIZE); \ + memcpy(buffer, src + LEA_BLOCK_SIZE, tail); \ + memcpy(dst + LEA_BLOCK_SIZE, dst, tail); \ + xts_next_tweak(walk.iv, walk.iv); \ + xor_1blk(buffer, walk.iv, buffer); \ + FUNC(&ctx->crypt_ctx, buffer, buffer); \ + xor_1blk(dst, walk.iv, buffer); \ + nbytes -= LEA_BLOCK_SIZE + tail; \ + } while (0) + +#define XTS_TAIL_DECRYPT(FUNC) \ + do { \ + u8 __aligned(16) ntweak[LEA_BLOCK_SIZE]; \ + u8 __aligned(16) buffer[LEA_BLOCK_SIZE]; \ + memcpy(ntweak, walk.iv, LEA_BLOCK_SIZE); \ + xts_next_tweak(walk.iv, ntweak); \ + xor_1blk(buffer, walk.iv, src); \ + FUNC(&ctx->crypt_ctx, buffer, buffer); \ + xor_1blk(buffer, walk.iv, buffer); \ + memcpy(dst, buffer, LEA_BLOCK_SIZE); \ + memcpy(buffer, src + 16, tail); \ + memcpy(dst + 16, dst, tail); \ + xor_1blk(buffer, ntweak, buffer); \ + FUNC(&ctx->crypt_ctx, buffer, buffer); \ + xor_1blk(dst, ntweak, buffer); \ + nbytes -= LEA_BLOCK_SIZE + tail; \ + } while (0) + +static inline int xts_edge_tail_encrypt(struct crypto_lea_xts_ctx *ctx, + struct skcipher_request *req, + struct skcipher_walk *walk, + int edge_tail) +{ + u8 __aligned(16) buffer[LEA_BLOCK_SIZE]; + struct scatterlist sg_src[2]; + struct scatterlist sg_dst[2]; + struct scatterlist *scatter_src; + struct scatterlist *scatter_dst; + const u8 *src; + u8 *dst; + + scatter_src = scatterwalk_ffwd(sg_src, req->src, req->cryptlen); + if (req->src == req->dst) + scatter_dst = scatter_src; + else + scatter_dst = scatterwalk_ffwd(sg_dst, req->dst, req->cryptlen); + + skcipher_request_set_crypt(req, scatter_src, scatter_dst, + LEA_BLOCK_SIZE + edge_tail, req->iv); + + skcipher_walk_virt(walk, req, false); + + src = walk->src.virt.addr; + dst = walk->dst.virt.addr; + + kernel_fpu_begin(); + + xor_1blk(buffer, walk->iv, src); + lea_encrypt(&ctx->crypt_ctx, buffer, buffer); + xor_1blk(buffer, walk->iv, buffer); + + memcpy(dst, buffer, LEA_BLOCK_SIZE); + memcpy(buffer, src + LEA_BLOCK_SIZE, edge_tail); + memcpy(dst + LEA_BLOCK_SIZE, dst, edge_tail); + + xts_next_tweak(walk->iv, walk->iv); + + xor_1blk(buffer, walk->iv, buffer); + lea_encrypt(&ctx->crypt_ctx, buffer, buffer); + xor_1blk(dst, walk->iv, buffer); + + kernel_fpu_end(); + return skcipher_walk_done(walk, 0); +} + +static inline int xts_edge_tail_decrypt(struct crypto_lea_xts_ctx *ctx, + struct skcipher_request *req, + struct skcipher_walk *walk, + int edge_tail) +{ + u8 __aligned(16) buffer[LEA_BLOCK_SIZE]; + u8 __aligned(16) ntweak[LEA_BLOCK_SIZE]; + struct scatterlist sg_src[2]; + struct scatterlist sg_dst[2]; + struct scatterlist *scatter_src; + struct scatterlist *scatter_dst; + + const u8 *src; + u8 *dst; + int ret; + + scatter_src = scatterwalk_ffwd(sg_src, req->src, req->cryptlen); + if (req->src == req->dst) + scatter_dst = scatter_src; + else + scatter_dst = scatterwalk_ffwd(sg_dst, req->dst, req->cryptlen); + + skcipher_request_set_crypt(req, scatter_src, scatter_dst, + LEA_BLOCK_SIZE + edge_tail, req->iv); + + ret = skcipher_walk_virt(walk, req, false); + + src = walk->src.virt.addr; + dst = walk->dst.virt.addr; + + kernel_fpu_begin(); + + memcpy(ntweak, walk->iv, LEA_BLOCK_SIZE); + xts_next_tweak(walk->iv, ntweak); + + xor_1blk(buffer, walk->iv, src); + lea_decrypt(&ctx->crypt_ctx, buffer, buffer); + xor_1blk(buffer, walk->iv, buffer); + + memcpy(dst, buffer, LEA_BLOCK_SIZE); + + memcpy(buffer, src + 16, edge_tail); + memcpy(dst + 16, dst, edge_tail); + + xor_1blk(buffer, ntweak, buffer); + lea_decrypt(&ctx->crypt_ctx, buffer, buffer); + xor_1blk(dst, ntweak, buffer); + + kernel_fpu_end(); + + return skcipher_walk_done(walk, 0); +} + +static int xts_encrypt_nway(struct skcipher_request *req) +{ + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct crypto_lea_xts_ctx *ctx = crypto_skcipher_ctx(tfm); + struct skcipher_request subreq; + struct skcipher_walk walk; + + int ret; + u32 nblocks; + u32 tail = req->cryptlen % LEA_BLOCK_SIZE; + u32 edge_tail = 0; + + if (req->cryptlen < LEA_BLOCK_SIZE) + return -EINVAL; + + ret = skcipher_walk_virt(&walk, req, false); + if (ret) + return ret; + + if (unlikely(tail != 0 && walk.nbytes < walk.total)) { + u32 req_len = req->cryptlen - LEA_BLOCK_SIZE - tail; + + skcipher_walk_abort(&walk); + + skcipher_request_set_tfm(&subreq, tfm); + skcipher_request_set_callback( + &subreq, skcipher_request_flags(req), NULL, NULL); + skcipher_request_set_crypt(&subreq, req->src, req->dst, req_len, + req->iv); + req = &subreq; + ret = skcipher_walk_virt(&walk, req, false); + if (ret) + return ret; + edge_tail = tail; + tail = 0; + } + + lea_encrypt(&ctx->tweak_ctx, walk.iv, walk.iv); + + while ((nblocks = walk.nbytes / LEA_BLOCK_SIZE) > 0) { + u32 nbytes = walk.nbytes; + const u8 *src = walk.src.virt.addr; + u8 *dst = walk.dst.virt.addr; + bool is_tail = tail != 0 && + (nblocks + 1) * LEA_BLOCK_SIZE > walk.total; + + if (unlikely(is_tail)) + nblocks -= 1; + + kernel_fpu_begin(); + + if (lea_func_map.xts_enc_16way) + XTS_NWAY(16, lea_func_map.xts_enc_16way); + if (lea_func_map.xts_enc_8way) + XTS_NWAY(8, lea_func_map.xts_enc_8way); + XTS_NWAY(4, lea_func_map.xts_enc_4way); + XTS_SINGLE(lea_encrypt); + + if (unlikely(is_tail)) { + XTS_TAIL_ENCRYPT(lea_encrypt); + kernel_fpu_end(); + return skcipher_walk_done(&walk, nbytes); + } + + kernel_fpu_end(); + ret = skcipher_walk_done(&walk, nbytes); + if (ret) + return ret; + } + + if (unlikely(edge_tail != 0)) + ret = xts_edge_tail_encrypt(ctx, req, &walk, edge_tail); + + return ret; +} + +static int xts_decrypt_nway(struct skcipher_request *req) +{ + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct crypto_lea_xts_ctx *ctx = crypto_skcipher_ctx(tfm); + struct skcipher_request subreq; + struct skcipher_walk walk; + + int ret; + u32 nblocks; + u32 tail = req->cryptlen % LEA_BLOCK_SIZE; + u32 edge_tail = 0; + + if (req->cryptlen < LEA_BLOCK_SIZE) + return -EINVAL; + + ret = skcipher_walk_virt(&walk, req, false); + + if (ret) + return ret; + + if (unlikely(tail != 0 && walk.nbytes < walk.total)) { + u32 req_len = req->cryptlen - LEA_BLOCK_SIZE - tail; + + skcipher_walk_abort(&walk); + + skcipher_request_set_tfm(&subreq, tfm); + skcipher_request_set_callback( + &subreq, skcipher_request_flags(req), NULL, NULL); + skcipher_request_set_crypt(&subreq, req->src, req->dst, req_len, + req->iv); + req = &subreq; + ret = skcipher_walk_virt(&walk, req, false); + if (ret) + return ret; + + edge_tail = tail; + tail = 0; + } + + lea_encrypt(&ctx->tweak_ctx, walk.iv, walk.iv); + + while ((nblocks = walk.nbytes / LEA_BLOCK_SIZE) > 0) { + u32 nbytes = walk.nbytes; + const u8 *src = walk.src.virt.addr; + u8 *dst = walk.dst.virt.addr; + bool is_tail = tail != 0 && + (nblocks + 1) * LEA_BLOCK_SIZE > walk.total; + + if (unlikely(is_tail)) + nblocks -= 1; + + kernel_fpu_begin(); + + if (lea_func_map.xts_dec_16way) + XTS_NWAY(16, lea_func_map.xts_dec_16way); + if (lea_func_map.xts_dec_8way) + XTS_NWAY(8, lea_func_map.xts_dec_8way); + XTS_NWAY(4, lea_func_map.xts_dec_4way); + XTS_SINGLE(lea_decrypt); + + if (unlikely(is_tail)) { + XTS_TAIL_DECRYPT(lea_decrypt); + kernel_fpu_end(); + return skcipher_walk_done(&walk, nbytes); + } + + kernel_fpu_end(); + + ret = skcipher_walk_done(&walk, nbytes); + if (ret) + return ret; + } + + if (unlikely(edge_tail != 0)) + xts_edge_tail_decrypt(ctx, req, &walk, edge_tail); + + return ret; +} + +static int ctr_encrypt_nway(struct skcipher_request *req) +{ + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct crypto_lea_ctx *ctx = crypto_skcipher_ctx(tfm); + struct skcipher_walk walk; + + u8 __aligned(16) buffer[LEA_BLOCK_SIZE]; + + int ret; + + ret = skcipher_walk_virt(&walk, req, false); + if (ret) + return ret; + + while (walk.nbytes > 0) { + u32 nbytes = walk.nbytes; + const u8 *src = walk.src.virt.addr; + u8 *dst = walk.dst.virt.addr; + + kernel_fpu_begin(); + + if (lea_func_map.ctr_enc_16way) + CTR_NWAY(16, lea_func_map.ctr_enc_16way); + if (lea_func_map.ctr_enc_8way) + CTR_NWAY(8, lea_func_map.ctr_enc_8way); + CTR_NWAY(4, lea_func_map.ctr_enc_4way); + + while (nbytes >= LEA_BLOCK_SIZE) { + lea_encrypt(ctx, buffer, walk.iv); + xor_1blk(dst, buffer, src); + crypto_inc(walk.iv, LEA_BLOCK_SIZE); + + src += LEA_BLOCK_SIZE; + dst += LEA_BLOCK_SIZE; + nbytes -= LEA_BLOCK_SIZE; + } + + if (unlikely(walk.nbytes == walk.total && nbytes != 0)) { + lea_encrypt(ctx, buffer, walk.iv); + crypto_xor_cpy(dst, src, buffer, nbytes); + crypto_inc(walk.iv, LEA_BLOCK_SIZE); + + nbytes = 0; + } + + kernel_fpu_end(); + ret = skcipher_walk_done(&walk, nbytes); + if (ret) + return ret; + } + + return ret; +} + +static int xts_lea_set_key(struct crypto_skcipher *tfm, const u8 *key, + u32 keylen) +{ + struct crypto_lea_xts_ctx *ctx = crypto_skcipher_ctx(tfm); + + struct crypto_lea_ctx *crypt_key = &ctx->crypt_ctx; + struct crypto_lea_ctx *tweak_key = &ctx->tweak_ctx; + + int result; + + result = xts_verify_key(tfm, key, keylen); + if (result) + return result; + + result = lea_set_key(crypt_key, key, keylen / 2); + + if (result) + return result; + + return lea_set_key(tweak_key, key + (keylen / 2), keylen / 2); +} + +static int _lea_set_key(struct crypto_skcipher *tfm, const u8 *key, u32 keylen) +{ + return lea_set_key(crypto_skcipher_ctx(tfm), key, keylen); +} + +static struct skcipher_alg lea_x86_64_algs[] = { + { + .base.cra_name = "__ecb(lea)", + .base.cra_driver_name = "__ecb-lea-x86_64", + .base.cra_priority = 300, + .base.cra_flags = CRYPTO_ALG_INTERNAL, + .base.cra_blocksize = LEA_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct crypto_lea_ctx), + .base.cra_module = THIS_MODULE, + .min_keysize = LEA_MIN_KEY_SIZE, + .max_keysize = LEA_MAX_KEY_SIZE, + .walksize = LEA_SSE2_MAX_PARALLEL_BLOCKS * LEA_BLOCK_SIZE, + .setkey = _lea_set_key, + .encrypt = ecb_encrypt_nway, + .decrypt = ecb_decrypt_nway, + }, + { + .base.cra_name = "__ctr(lea)", + .base.cra_driver_name = "__ctr-lea-x86_64", + .base.cra_priority = 300, + .base.cra_flags = CRYPTO_ALG_INTERNAL, + .base.cra_blocksize = 1, + .base.cra_ctxsize = sizeof(struct crypto_lea_ctx), + .base.cra_module = THIS_MODULE, + .min_keysize = LEA_MIN_KEY_SIZE, + .max_keysize = LEA_MAX_KEY_SIZE, + .chunksize = LEA_BLOCK_SIZE, + .walksize = LEA_SSE2_MAX_PARALLEL_BLOCKS * LEA_BLOCK_SIZE, + .ivsize = LEA_BLOCK_SIZE, + .setkey = _lea_set_key, + .encrypt = ctr_encrypt_nway, + .decrypt = ctr_encrypt_nway, + }, + { + .base.cra_name = "__cbc(lea)", + .base.cra_driver_name = "__cbc-lea-x86_64", + .base.cra_priority = 300, + .base.cra_flags = CRYPTO_ALG_INTERNAL, + .base.cra_blocksize = LEA_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct crypto_lea_ctx), + .base.cra_module = THIS_MODULE, + .min_keysize = LEA_MIN_KEY_SIZE, + .max_keysize = LEA_MAX_KEY_SIZE, + .walksize = LEA_SSE2_MAX_PARALLEL_BLOCKS * LEA_BLOCK_SIZE, + .ivsize = LEA_BLOCK_SIZE, + .setkey = _lea_set_key, + .encrypt = cbc_encrypt, + .decrypt = cbc_decrypt_nway, + }, + { + .base.cra_name = "__xts(lea)", + .base.cra_driver_name = "__xts-lea-x86_64", + .base.cra_priority = 300, + .base.cra_flags = CRYPTO_ALG_INTERNAL, + .base.cra_blocksize = LEA_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct crypto_lea_xts_ctx), + .base.cra_module = THIS_MODULE, + .min_keysize = LEA_MIN_KEY_SIZE * 2, + .max_keysize = LEA_MAX_KEY_SIZE * 2, + .walksize = LEA_SSE2_MAX_PARALLEL_BLOCKS * LEA_BLOCK_SIZE, + .ivsize = LEA_BLOCK_SIZE, + .setkey = xts_lea_set_key, + .encrypt = xts_encrypt_nway, + .decrypt = xts_decrypt_nway, + }, +}; + +static struct simd_skcipher_alg *lea_x86_64_sk_algs[ARRAY_SIZE(lea_x86_64_algs)]; + +static int __init crypto_lea_x86_64_init(void) +{ + const char *feature_name; + int i; + const struct lea_func_map_t *target_call_map; + + target_call_map = &lea_avx512_func_map; + + if (!boot_cpu_has(X86_FEATURE_AVX512F)) + target_call_map = &lea_avx2_func_map; + else if (!cpu_has_xfeatures(XFEATURE_MASK_ZMM_Hi256 | + XFEATURE_MASK_OPMASK, + &feature_name)) + target_call_map = &lea_avx2_func_map; + + if (!boot_cpu_has(X86_FEATURE_AVX2) || !boot_cpu_has(X86_FEATURE_AVX)) + target_call_map = NULL; + else if (!cpu_has_xfeatures(XFEATURE_MASK_YMM, &feature_name)) + target_call_map = NULL; + + if (!boot_cpu_has(X86_FEATURE_XMM2)) { + pr_info("SSE2 instructions are not detected.\n"); + return -ENODEV; + } + + if (!cpu_has_xfeatures(XFEATURE_MASK_SSE, &feature_name)) { + pr_info("CPU feature '%s' is not supported.\n", feature_name); + return -ENODEV; + } + + if (target_call_map != NULL) { + lea_func_map = *target_call_map; + for (i = 0; i < ARRAY_SIZE(lea_x86_64_algs); i++) { + lea_x86_64_algs[i].walksize = + lea_func_map.proc_blocks * LEA_BLOCK_SIZE; + } + } + + return simd_register_skciphers_compat(lea_x86_64_algs, + ARRAY_SIZE(lea_x86_64_sk_algs), + lea_x86_64_sk_algs); +} + +static void __exit crypto_lea_x86_64_exit(void) +{ + simd_unregister_skciphers(lea_x86_64_algs, + ARRAY_SIZE(lea_x86_64_sk_algs), + lea_x86_64_sk_algs); +} + +module_init(crypto_lea_x86_64_init); +module_exit(crypto_lea_x86_64_exit); + +MODULE_DESCRIPTION("LEA Cipher Algorithm, AVX-512F, AVX2, SSE2 SIMD"); +MODULE_AUTHOR("Dongsoo Lee "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS_CRYPTO("lea"); +MODULE_ALIAS_CRYPTO("lea-x86_64");