linux-fscrypt.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v6 RESEND 0/5] crypto: LEA block cipher implementation
@ 2024-01-12  2:28 Dongsoo Lee
  2024-01-12  2:28 ` [PATCH v6 RESEND 1/5] " Dongsoo Lee
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Dongsoo Lee @ 2024-01-12  2:28 UTC (permalink / raw)
  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, H. Peter Anvin
  Cc: linux-crypto, linux-block, linux-fscrypt, linux-kernel, Dongsoo Lee

This submission contains a generic C implementation of the LEA cipher and test vectors for it. It also includes modifications to use the LEA in fscrypt.

The LEA algorithm is a lightweight block 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. See [2, 5, 7] for details.

LEA is a Korean national standard block cipher, described in "KS X 3246"[1] and is also included in the international standard, "ISO/IEC 29192-2:2019 standard"[2].

It is one of the approved block ciphers for the current Korean Cryptographic Module Validation Program (KCMVP).

At the time of submission, no successful attack on full-round LEA is known. As is typical for iterated block ciphers, reduced-round variants have been attacked. The best published attacks on LEA in the standard attack model (CPA/CCA with unknown key) are boomerang attacks and differential linear attacks. The security margin to the whole rounds ratio is greater than 29% against various existing cryptanalytic techniques for block ciphers. [3]

We expect that the first application of the patch would be the disk encryption on the Gooroom platform ('Gooroom' is a Korean word, meaning 'cloud') [4]. The Gooroom platform is a government-driven Debian-based Linux distribution in South Korea. In Korea, there are many crypto companies that want to bundle Linux into their products and sell them. They create their own Gooroom platforms by modifying the original Gooroom platform for their services. (Of course, the Gooroom platform is not mandatory, and companies wishing to use Linux are free to choose an appropriate distribution.) BTW, in Korea, many crypto companies want to use LEA, because LEA is one of the block ciphers of the KCMVP, a validation program for commercial crypto S/W to be delivered to the Korean government.

Currently, the Gooroom platform uses AES-XTS for disk encryption. The main reason for submitting this patch is to make disk encryption with LEA (e.g. LEA-XTS) available on there. If this submission is accepted, LEA can be used without any additional modifications in dm-crypt, a module that provides disk encryption functionality within the kernel.

This patch also includes a modification to enable LEA for use in fscrypt, another data-at-rest encryption method available within the kernel, and a modification to blk-crypto-fallback to enable the "inlinecrypt" mount option in fscrypt.

The Linux Crypto API already has another Korean block cipher, ARIA, also one of the block ciphers of the KCVMP. However, LEA is more widely used than ARIA in industry nowadays, because LEA is one of the lightweight cryptography standard of ISO/IEC [2] and performs well on low-end devices that support 32-bit operations. So we think they are complementary to each other.

In general, it's obvious that the hardware-accelerated AES is the best performer. However, there exist not only environments where the hardware-accelerated AES is not supported, but also situations where AES is not preferred for various reasons. In these cases, if someone wants to encrypt using a block cipher, LEA could be an alternative.

This submission includes a SIMD implementation for the x86-64 platform. The LEA cipher consists of 32-bit integer addition, rotation, and XOR operations, allowing for 4 blocks (XMM), 8 blocks (YMM), and 16 blocks (ZMM) of parallelism depending on the size of the registers. In addition, AVX2 and AVX-512F have more instructions to increase parallel encryption performance, which can be implemented differently even though they use the same registers. Therefore, lea-x86_64 selects the appropriate implementation in one glue code at module initialization. If additional SIMD instructions are added in the future, such as AVX10, this can be handled as well.

Below are the speedtest performed with the tcrypt module for AES, LEA, ARIA, and Adiantum on three different platforms (AMD Ryzen 9 5950X, Intel(R) Core(TM) i5-12600K, and Intel(R) Xeon(R) Gold 6254).

(4,096-byte block enc/decryption results in the tcrypt speedtest. Unit: cycles)

- AMD Ryzen 9 5950X (Virtual Machine)
  - aesni        ecb 128-bit key:  1,956 /   1,892
  - aesni        ecb 256-bit key:  2,086 /   2,098
  - lea-x86_64   ecb 128-bit key:  5,647 /   6,133
  - lea-x86_64   ecb 256-bit key:  6,702 /   7,444
  - aria-avx2    ecb 128-bit key:  8,316 /   8,153
  - aria-avx2    ecb 256-bit key: 10,539 /  10,550

  - aesni        cbc 128-bit key:  7,758 /   1,830
  - aesni        cbc 256-bit key: 10,660 /   2,071
  - lea-x86_64   cbc 128-bit key: 22,501 /   6,283
  - lea-x86_64   cbc 256-bit key: 28,125 /   7,592

  - aesni        ctr 128-bit key:  1,514 /   1,505
  - aesni        ctr 256-bit key:  1,884 /   1,867
  - lea-x86_64   ctr 128-bit key:  5,804 /   5,792
  - lea-x86_64   ctr 256-bit key:  6,958 /   6,951
  - aria-avx2    ctr 128-bit key:  8,819 /   8,736
  - aria-avx2    ctr 256-bit key: 11,101 /  10,636

  - adiantum(xchacha12-simd,...):  8,390 /   8,427
  - adiantum(xchacha20-simd,...):  9,698 /   9,732

  - aesni        xts 256-bit key:  2,177 /   2,165
  - aesni        xts 512-bit key:  2,589 /   2,527
  - lea-x86_64   xts 256-bit key:  6,488 /   6,745
  - lea-x86_64   xts 512-bit key:  7,484 /   8,083

  - aes-generic  ecb 128-bit key: 35,768 /  36,329
  - aes-generic  ecb 256-bit key: 35,785 /  35,237
  - lea-generic  ecb 128-bit key: 30,719 /  38,092
  - lea-generic  ecb 256-bit key: 35,373 /  46,941
  - aria-generic ecb 128-bit key:186,660 / 188,674
  - aria-generic ecb 256-bit key:247,919 / 245,527

- Intel(R) Core(TM) i5-12600K (microcode 0x15, AVX-512F Enabled)
  - aesni        ecb 128-bit key:  1,436 /   1,441
  - aesni        ecb 256-bit key:  1,984 /   1,987
  - lea-x86_64   ecb 128-bit key:  5,318 /   5,916
  - lea-x86_64   ecb 256-bit key:  6,209 /   7,071
  - aria-avx512  ecb 128-bit key:  4,786 /   4,799
  - aria-avx512  ecb 256-bit key:  5,988 /   5,989

  - aesni        cbc 128-bit key:  8,741 /   1,467
  - aesni        cbc 256-bit key: 11,803 /   1,995
  - lea-x86_64   cbc 128-bit key: 31,070 /   6,063
  - lea-x86_64   cbc 256-bit key: 39,117 /   7,173

  - aesni        ctr 128-bit key:  2,120 /   2,112
  - aesni        ctr 256-bit key:  2,588 /   2,595
  - lea-x86_64   ctr 128-bit key:  4,438 /   4,397
  - lea-x86_64   ctr 256-bit key:  5,217 /   5,196
  - aria-avx512  ctr 128-bit key:  6,270 /   6,272
  - aria-avx512  ctr 256-bit key:  7,469 /   7,473

  - adiantum(xchacha12-simd,...):  7,526 /   7,453
  - adiantum(xchacha20-simd,...):  8,983 /   8,892

  - aesni        xts 256-bit key:  2,234 /   2,241
  - aesni        xts 512-bit key:  2,525 /   2,538
  - lea-x86_64   xts 256-bit key:  6,687 /   7,333
  - lea-x86_64   xts 512-bit key:  7,626 /   8,457

  - aes-generic  ecb 128-bit key: 34,399 /  34,765
  - aes-generic  ecb 256-bit key: 48,568 /  49,245
  - lea-generic  ecb 128-bit key: 23,576 /  36,230
  - lea-generic  ecb 256-bit key: 31,715 /  50,461
  - aria-generic ecb 128-bit key:108,227 / 108,135
  - aria-generic ecb 256-bit key:146,669 / 145,993

- Intel(R) Xeon(R) Gold 6254 (Virtual Machine)
  - aesni        ecb 128-bit key:  3,390 /   3,396
  - aesni        ecb 256-bit key:  4,533 /   4,549
  - lea-x86_64   ecb 128-bit key:  5,500 /   6,594
  - lea-x86_64   ecb 256-bit key:  6,506 /   7,467
  - aria-avx2    ecb 128-bit key: 14,109 /  13,573
  - aria-avx2    ecb 256-bit key: 17,605 /  16,955

  - aesni        cbc 128-bit key: 12,559 /   3,544
  - aesni        cbc 256-bit key: 17,150 /   4,681
  - lea-x86_64   cbc 128-bit key: 33,471 /   5,900
  - lea-x86_64   cbc 256-bit key: 41,024 /   6,948

  - aesni        ctr 128-bit key:  3,099 /   3,095
  - aesni        ctr 256-bit key:  4,126 /   4,124
  - lea-x86_64   ctr 128-bit key:  5,054 /   4,909
  - lea-x86_64   ctr 256-bit key:  5,795 /   5,797
  - aria-avx2    ctr 128-bit key: 13,439 /  13,017
  - aria-avx2    ctr 256-bit key: 17,325 /  16,731

  - adiantum(xchacha12-simd,...):  9,064 /   9,006
  - adiantum(xchacha20-simd,...): 10,702 /  10,628

  - aesni        xts 256-bit key:  3,886 /   3,857
  - aesni        xts 512-bit key:  4,949 /   5,008
  - lea-x86_64   xts 256-bit key:  6,457 /   7,409
  - lea-x86_64   xts 512-bit key:  7,438 /   8,510

  - aes-generic  ecb 128-bit key: 49,438 /  48,803
  - aes-generic  ecb 256-bit key: 72,348 /  73,804
  - lea-generic  ecb 128-bit key: 30,300 /  45,072
  - lea-generic  ecb 256-bit key: 39,054 /  60,472
  - aria-generic ecb 128-bit key:189,850 / 175,073
  - aria-generic ecb 256-bit key:243,704 / 228,347

If this submission is accepted, future submissions may include an LEA implementation for aarch64 and an implementation with masks for AVX-512F.

Although the designers of LEA did not provide test vectors in their paper [5], the ISO/IEC standard [2] and the KS standard [1] do. Furthermore, the Block Cipher LEA Specification("블록암호 LEA 규격서", written in Korean) document on the LEA introduction page [6] and the Wikipedia article on LEA [7] show the same test vectors as in the standards.

The test vectors for ECB, CBC, CTR, and GCM modes included in the testmgr module are taken from the KCMVP Cryptographic Algorithm Verification Criteria V3.0("KCMVP 검증대상 암호알고리즘 검증기준 V3.0", written in Korean) [8]. Test vectors for the XTS mode were generated by ourselves, and we crosschecked them using Crypto++ [9] and testmgr on Linux.

The implementation was tested with kernel module tcrypt.ko and passed the selftest using the above-mentioned test vectors. It also has been tested with CONFIG_CRYPTO_MANAGER_EXTRA_TESTS. The fscrypt patch was tested using a modified tool by forking https://github.com/google/fscrypt.

The AVX2 and AVX-512F implementations were tested on the device that performed the speedtest, while the SSE2 implementation was tested using QEMU's x86-64 binary emulation.

[1] KS X 3246, 128-bit block cipher LEA.
[2] ISO/IEC 29192-2:2019, Information security — Lightweight cryptography — Part 2: Block ciphers.
[3] Yi, Chen, et al. "Differential-Linear Approximation Semi-Unconstrained Searching and Partition Tree: Application to LEA and Speck", Asiacrypt 2023. (eprint 2023/1414)
[4] https://github.com/gooroom https://www.gooroom.kr/
[5] Hong, Deukjo, et al. "LEA: A 128-bit block cipher for fast encryption on common processors.", WISA 2013.
[6] https://seed.kisa.or.kr/kisa/algorithm/EgovLeaInfo.do
[7] https://en.wikipedia.org/wiki/LEA_(cipher)
[8] https://seed.kisa.or.kr/kisa/kcmvp/EgovVerification.do
[9] https://www.cryptopp.com/

Changelog:
v6:
- Resended due to missing subsystem and incorrect title
  - The patch is unchanged from v5.
v5:
- Added SSE2/AVX2/AVX-512F implementation
  - Single glue code to determine proper SIMD acceleration
- Adjusted ordering within structures to align with 16-byte boundaries.
- Added more test vectors.
  - Increased the maximum test-vector length to evaluate 16-block parallelism.
  - Added the CBC-CTS test vector.
v4:
- Removed documentation to describe LEAs in fscrypt.
v3:
- Added implementations to enable LEA in fscrypt and blk-crypt.
v2:
- Reimplemented the Generic C implementation as a Loop version.
  - The decryption code was adapted from an optimized implementation by Eric Biggers.
    https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git/commit/?h=old/wip-lea&id=1d1cbba14380f8a1abc76baf939b9e51de047fb6
- Removed AVX2 SIMD implementation.
- Added comments for functions.
- Improved the description in Kconfig.
- Added test vectors from the standard documentation.

Dongsoo Lee (5):
  crypto: LEA block cipher implementation
  crypto: add LEA testmgr tests
  blk-crypto: Add LEA-256-XTS blk-crypto support
  fscrypt: Add LEA-256-XTS, LEA-256-CTS support
  crypto: LEA block cipher x86_64 optimization

 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 ++++++++
 block/blk-crypto.c                 |    6 +
 crypto/Kconfig                     |   18 +
 crypto/Makefile                    |    1 +
 crypto/lea_generic.c               |  410 ++++
 crypto/tcrypt.c                    |   97 +
 crypto/testmgr.c                   |   38 +
 crypto/testmgr.h                   | 3022 ++++++++++++++++++++++++++++
 fs/crypto/fscrypt_private.h        |    2 +-
 fs/crypto/keysetup.c               |   15 +
 fs/crypto/policy.c                 |    4 +
 include/crypto/lea.h               |   44 +
 include/linux/blk-crypto.h         |    1 +
 include/uapi/linux/fscrypt.h       |    4 +-
 tools/include/uapi/linux/fscrypt.h |    4 +-
 18 files changed, 6787 insertions(+), 3 deletions(-)
 create mode 100644 arch/x86/crypto/lea-x86_64-asm.S
 create mode 100644 arch/x86/crypto/lea-x86_64-glue.c
 create mode 100644 crypto/lea_generic.c
 create mode 100644 include/crypto/lea.h

-- 
2.40.1

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v6 RESEND 1/5] crypto: LEA block cipher implementation
  2024-01-12  2:28 [PATCH v6 RESEND 0/5] crypto: LEA block cipher implementation Dongsoo Lee
@ 2024-01-12  2:28 ` Dongsoo Lee
  2024-01-12  2:28 ` [PATCH v6 RESEND 2/5] crypto: add LEA testmgr tests Dongsoo Lee
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Dongsoo Lee @ 2024-01-12  2:28 UTC (permalink / raw)
  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, H. Peter Anvin
  Cc: linux-crypto, linux-block, linux-fscrypt, linux-kernel, Dongsoo Lee

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 <letrhee@nsr.re.kr>
---
 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 <letrhee@nsr.re.kr>
+ */
+
+#include <asm/unaligned.h>
+#include <linux/module.h>
+#include <crypto/algapi.h>
+#include <crypto/lea.h>
+
+/*
+ * 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 <letrhee@nsr.re.kr>");
+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 <letrhee@nsr.re.kr>
+ */
+
+#ifndef _CRYPTO_LEA_H
+#define _CRYPTO_LEA_H
+
+#include <linux/types.h>
+
+#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
-- 
2.40.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v6 RESEND 2/5] crypto: add LEA testmgr tests
  2024-01-12  2:28 [PATCH v6 RESEND 0/5] crypto: LEA block cipher implementation Dongsoo Lee
  2024-01-12  2:28 ` [PATCH v6 RESEND 1/5] " Dongsoo Lee
@ 2024-01-12  2:28 ` Dongsoo Lee
  2024-01-12  2:28 ` [PATCH v6 RESEND 3/5] blk-crypto: Add LEA-256-XTS blk-crypto support Dongsoo Lee
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Dongsoo Lee @ 2024-01-12  2:28 UTC (permalink / raw)
  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, H. Peter Anvin
  Cc: linux-crypto, linux-block, linux-fscrypt, linux-kernel, Dongsoo Lee

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 <letrhee@nsr.re.kr>
---
 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"
-- 
2.40.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v6 RESEND 3/5] blk-crypto: Add LEA-256-XTS blk-crypto support
  2024-01-12  2:28 [PATCH v6 RESEND 0/5] crypto: LEA block cipher implementation Dongsoo Lee
  2024-01-12  2:28 ` [PATCH v6 RESEND 1/5] " Dongsoo Lee
  2024-01-12  2:28 ` [PATCH v6 RESEND 2/5] crypto: add LEA testmgr tests Dongsoo Lee
@ 2024-01-12  2:28 ` Dongsoo Lee
  2024-01-12  2:28 ` [PATCH v6 RESEND 4/5] fscrypt: Add LEA-256-XTS, LEA-256-CTS support Dongsoo Lee
  2024-01-12  2:28 ` [PATCH v6 RESEND 5/5] crypto: LEA block cipher x86_64 optimization Dongsoo Lee
  4 siblings, 0 replies; 8+ messages in thread
From: Dongsoo Lee @ 2024-01-12  2:28 UTC (permalink / raw)
  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, H. Peter Anvin
  Cc: linux-crypto, linux-block, linux-fscrypt, linux-kernel, Dongsoo Lee

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 <letrhee@nsr.re.kr>
---
 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,
 };
 
-- 
2.40.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v6 RESEND 4/5] fscrypt: Add LEA-256-XTS, LEA-256-CTS support
  2024-01-12  2:28 [PATCH v6 RESEND 0/5] crypto: LEA block cipher implementation Dongsoo Lee
                   ` (2 preceding siblings ...)
  2024-01-12  2:28 ` [PATCH v6 RESEND 3/5] blk-crypto: Add LEA-256-XTS blk-crypto support Dongsoo Lee
@ 2024-01-12  2:28 ` Dongsoo Lee
  2024-01-12  2:28 ` [PATCH v6 RESEND 5/5] crypto: LEA block cipher x86_64 optimization Dongsoo Lee
  4 siblings, 0 replies; 8+ messages in thread
From: Dongsoo Lee @ 2024-01-12  2:28 UTC (permalink / raw)
  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, H. Peter Anvin
  Cc: linux-crypto, linux-block, linux-fscrypt, linux-kernel, Dongsoo Lee

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 <letrhee@nsr.re.kr>
---
 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.
-- 
2.40.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v6 RESEND 5/5] crypto: LEA block cipher x86_64 optimization
  2024-01-12  2:28 [PATCH v6 RESEND 0/5] crypto: LEA block cipher implementation Dongsoo Lee
                   ` (3 preceding siblings ...)
  2024-01-12  2:28 ` [PATCH v6 RESEND 4/5] fscrypt: Add LEA-256-XTS, LEA-256-CTS support Dongsoo Lee
@ 2024-01-12  2:28 ` Dongsoo Lee
  2024-01-12 12:59   ` David Laight
  4 siblings, 1 reply; 8+ messages in thread
From: Dongsoo Lee @ 2024-01-12  2:28 UTC (permalink / raw)
  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, H. Peter Anvin
  Cc: linux-crypto, linux-block, linux-fscrypt, linux-kernel, Dongsoo Lee

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 <letrhee@nsr.re.kr>
---
 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 <letrhee@nsr.re.kr>
+ */
+
+#include <linux/linkage.h>
+#include <asm/frame.h>
+
+.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 <letrhee@nsr.re.kr>
+ */
+
+#include <asm/simd.h>
+#include <asm/unaligned.h>
+#include <crypto/algapi.h>
+#include <crypto/ctr.h>
+#include <crypto/internal/simd.h>
+#include <crypto/scatterwalk.h>
+#include <crypto/skcipher.h>
+#include <crypto/internal/skcipher.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/types.h>
+
+#include <crypto/lea.h>
+#include <crypto/xts.h>
+#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 <letrhee@nsr.re.kr>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_CRYPTO("lea");
+MODULE_ALIAS_CRYPTO("lea-x86_64");
-- 
2.40.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* RE: [PATCH v6 RESEND 5/5] crypto: LEA block cipher x86_64 optimization
  2024-01-12  2:28 ` [PATCH v6 RESEND 5/5] crypto: LEA block cipher x86_64 optimization Dongsoo Lee
@ 2024-01-12 12:59   ` David Laight
  2024-01-15  5:17     ` Dongsoo Lee
  0 siblings, 1 reply; 8+ messages in thread
From: David Laight @ 2024-01-12 12:59 UTC (permalink / raw)
  To: 'Dongsoo Lee',
	Herbert Xu, David S. Miller, Jens Axboe, Eric Biggers,
	Theodore Y. Ts'o, Jaegeuk Kim, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, Dave Hansen, x86, H. Peter Anvin
  Cc: linux-crypto, linux-block, linux-fscrypt, linux-kernel

From: Dongsoo Lee
> Sent: 12 January 2024 02:29
> 
> 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.

Given you say in 0/0:

The LEA algorithm is a lightweight block cipher that processes data blocks of 128-bits and has three different key lengths, each with a different number of rounds:

Just how big is it ?
Doesn't look 'lightweight' to me.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)


^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [PATCH v6 RESEND 5/5] crypto: LEA block cipher x86_64 optimization
  2024-01-12 12:59   ` David Laight
@ 2024-01-15  5:17     ` Dongsoo Lee
  0 siblings, 0 replies; 8+ messages in thread
From: Dongsoo Lee @ 2024-01-15  5:17 UTC (permalink / raw)
  To: 'David Laight', 'Herbert Xu',
	'David S. Miller', 'Jens Axboe',
	'Eric Biggers', 'Theodore Y. Ts'o',
	'Jaegeuk Kim', 'Thomas Gleixner',
	'Ingo Molnar', 'Borislav Petkov',
	'Dave Hansen', x86, 'H. Peter Anvin'
  Cc: linux-crypto, linux-block, linux-fscrypt, linux-kernel

On  Fri, 12 Jan 2024 12:59:56 +0000, David Laight <David.Laight@ACULAB.COM> wrote:
> From: Dongsoo Lee
>> Sent: 12 January 2024 02:29
>>
>> 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.
> 
> Given you say in 0/0:
> 
> The LEA algorithm is a lightweight block cipher that processes data blocks of 128-bits and has three different key lengths, each with a different number of rounds:
> 
> Just how big is it ?
> Doesn't look 'lightweight' to me.
> 
> 	David
> 
> -
> Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
> Registration No: 1397386 (Wales)
> 

Firstly, it's worth mentioning that LEA is an encryption algorithm designed to ensure 128-bit security.

The LEA cipher provides a balance between code size and required memory, allowing for trade-offs with performance. The implementation of LEA that we have submitted is oriented towards achieving optimal performance.

While it's difficult to compare to the most recent implementations of cryptographic algorithms because the test is out of date, you can see the results of a previous FELICS test [1] that implemented LEA for a smaller code size.

For example, a detailed example of skipping the key schedule to reduce memory usage and minimize code size can be found in [2].

Thank you for your interest.

    Dongsoo Lee

[1] https://www.cryptolux.org/index.php/FELICS#Results
[2] https://github.com/cryptolu/FELICS/blob/master/block_ciphers/source/ciphers/LEA_128_128_v03/source/encrypt.c

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2024-01-15  5:18 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-12  2:28 [PATCH v6 RESEND 0/5] crypto: LEA block cipher implementation Dongsoo Lee
2024-01-12  2:28 ` [PATCH v6 RESEND 1/5] " Dongsoo Lee
2024-01-12  2:28 ` [PATCH v6 RESEND 2/5] crypto: add LEA testmgr tests Dongsoo Lee
2024-01-12  2:28 ` [PATCH v6 RESEND 3/5] blk-crypto: Add LEA-256-XTS blk-crypto support Dongsoo Lee
2024-01-12  2:28 ` [PATCH v6 RESEND 4/5] fscrypt: Add LEA-256-XTS, LEA-256-CTS support Dongsoo Lee
2024-01-12  2:28 ` [PATCH v6 RESEND 5/5] crypto: LEA block cipher x86_64 optimization Dongsoo Lee
2024-01-12 12:59   ` David Laight
2024-01-15  5:17     ` Dongsoo Lee

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).