]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
crypto: arm/aes - replace bit-sliced OpenSSL NEON code
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Wed, 11 Jan 2017 16:41:54 +0000 (16:41 +0000)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 13 Jan 2017 10:27:31 +0000 (18:27 +0800)
This replaces the unwieldy generated implementation of bit-sliced AES
in CBC/CTR/XTS modes that originated in the OpenSSL project with a
new version that is heavily based on the OpenSSL implementation, but
has a number of advantages over the old version:
- it does not rely on the scalar AES cipher that also originated in the
  OpenSSL project and contains redundant lookup tables and key schedule
  generation routines (which we already have in crypto/aes_generic.)
- it uses the same expanded key schedule for encryption and decryption,
  reducing the size of the per-key data structure by 1696 bytes
- it adds an implementation of AES in ECB mode, which can be wrapped by
  other generic chaining mode implementations
- it moves the handling of corner cases that are non critical to performance
  to the glue layer written in C
- it was written directly in assembler rather than generated from a Perl
  script

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
arch/arm/crypto/Kconfig
arch/arm/crypto/Makefile
arch/arm/crypto/aes-armv4.S [deleted file]
arch/arm/crypto/aes-neonbs-core.S [new file with mode: 0644]
arch/arm/crypto/aes-neonbs-glue.c [new file with mode: 0644]
arch/arm/crypto/aes_glue.h [deleted file]
arch/arm/crypto/aesbs-core.S_shipped [deleted file]
arch/arm/crypto/aesbs-glue.c [deleted file]
arch/arm/crypto/bsaes-armv7.pl [deleted file]

index f1de658c3c8f99a1288dc6da93fee3755ceb26f5..a8fce93137fbddeae96e7f38cfed3b2dbb52e824 100644 (file)
@@ -73,6 +73,7 @@ config CRYPTO_AES_ARM_BS
        depends on KERNEL_MODE_NEON
        select CRYPTO_BLKCIPHER
        select CRYPTO_SIMD
+       select CRYPTO_AES_ARM
        help
          Use a faster and more secure NEON based implementation of AES in CBC,
          CTR and XTS modes
index 8f5de2db701c310356c9b0a68c072fa3cfd74deb..1822c4697278cbe9aeb3ac7125ac04ec438a5345 100644 (file)
@@ -28,7 +28,7 @@ endif
 endif
 
 aes-arm-y      := aes-cipher-core.o aes-cipher-glue.o
-aes-arm-bs-y   := aes-armv4.o aesbs-core.o aesbs-glue.o
+aes-arm-bs-y   := aes-neonbs-core.o aes-neonbs-glue.o
 sha1-arm-y     := sha1-armv4-large.o sha1_glue.o
 sha1-arm-neon-y        := sha1-armv7-neon.o sha1_neon_glue.o
 sha256-arm-neon-$(CONFIG_KERNEL_MODE_NEON) := sha256_neon_glue.o
@@ -46,13 +46,10 @@ chacha20-neon-y := chacha20-neon-core.o chacha20-neon-glue.o
 quiet_cmd_perl = PERL    $@
       cmd_perl = $(PERL) $(<) > $(@)
 
-$(src)/aesbs-core.S_shipped: $(src)/bsaes-armv7.pl
-       $(call cmd,perl)
-
 $(src)/sha256-core.S_shipped: $(src)/sha256-armv4.pl
        $(call cmd,perl)
 
 $(src)/sha512-core.S_shipped: $(src)/sha512-armv4.pl
        $(call cmd,perl)
 
-.PRECIOUS: $(obj)/aesbs-core.S $(obj)/sha256-core.S $(obj)/sha512-core.S
+.PRECIOUS: $(obj)/sha256-core.S $(obj)/sha512-core.S
diff --git a/arch/arm/crypto/aes-armv4.S b/arch/arm/crypto/aes-armv4.S
deleted file mode 100644 (file)
index ebb9761..0000000
+++ /dev/null
@@ -1,1089 +0,0 @@
-#define __ARM_ARCH__ __LINUX_ARM_ARCH__
-@ ====================================================================
-@ Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
-@ project. The module is, however, dual licensed under OpenSSL and
-@ CRYPTOGAMS licenses depending on where you obtain it. For further
-@ details see http://www.openssl.org/~appro/cryptogams/.
-@ ====================================================================
-
-@ AES for ARMv4
-
-@ January 2007.
-@
-@ Code uses single 1K S-box and is >2 times faster than code generated
-@ by gcc-3.4.1. This is thanks to unique feature of ARMv4 ISA, which
-@ allows to merge logical or arithmetic operation with shift or rotate
-@ in one instruction and emit combined result every cycle. The module
-@ is endian-neutral. The performance is ~42 cycles/byte for 128-bit
-@ key [on single-issue Xscale PXA250 core].
-
-@ May 2007.
-@
-@ AES_set_[en|de]crypt_key is added.
-
-@ July 2010.
-@
-@ Rescheduling for dual-issue pipeline resulted in 12% improvement on
-@ Cortex A8 core and ~25 cycles per byte processed with 128-bit key.
-
-@ February 2011.
-@
-@ Profiler-assisted and platform-specific optimization resulted in 16%
-@ improvement on Cortex A8 core and ~21.5 cycles per byte.
-
-@ A little glue here to select the correct code below for the ARM CPU
-@ that is being targetted.
-
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-
-.text
-
-.type  AES_Te,%object
-.align 5
-AES_Te:
-.word  0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d
-.word  0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554
-.word  0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d
-.word  0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a
-.word  0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87
-.word  0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b
-.word  0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea
-.word  0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b
-.word  0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a
-.word  0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f
-.word  0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108
-.word  0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f
-.word  0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e
-.word  0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5
-.word  0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d
-.word  0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f
-.word  0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e
-.word  0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb
-.word  0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce
-.word  0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497
-.word  0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c
-.word  0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed
-.word  0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b
-.word  0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a
-.word  0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16
-.word  0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594
-.word  0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81
-.word  0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3
-.word  0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a
-.word  0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504
-.word  0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163
-.word  0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d
-.word  0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f
-.word  0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739
-.word  0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47
-.word  0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395
-.word  0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f
-.word  0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883
-.word  0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c
-.word  0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76
-.word  0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e
-.word  0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4
-.word  0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6
-.word  0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b
-.word  0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7
-.word  0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0
-.word  0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25
-.word  0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818
-.word  0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72
-.word  0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651
-.word  0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21
-.word  0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85
-.word  0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa
-.word  0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12
-.word  0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0
-.word  0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9
-.word  0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133
-.word  0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7
-.word  0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920
-.word  0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a
-.word  0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17
-.word  0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8
-.word  0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11
-.word  0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a
-@ Te4[256]
-.byte  0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
-.byte  0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
-.byte  0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
-.byte  0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
-.byte  0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
-.byte  0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
-.byte  0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
-.byte  0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
-.byte  0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
-.byte  0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
-.byte  0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
-.byte  0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
-.byte  0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
-.byte  0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
-.byte  0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
-.byte  0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
-.byte  0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
-.byte  0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
-.byte  0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
-.byte  0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
-.byte  0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
-.byte  0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
-.byte  0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
-.byte  0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
-.byte  0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
-.byte  0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
-.byte  0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
-.byte  0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
-.byte  0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
-.byte  0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
-.byte  0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
-.byte  0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-@ rcon[]
-.word  0x01000000, 0x02000000, 0x04000000, 0x08000000
-.word  0x10000000, 0x20000000, 0x40000000, 0x80000000
-.word  0x1B000000, 0x36000000, 0, 0, 0, 0, 0, 0
-.size  AES_Te,.-AES_Te
-
-@ void AES_encrypt(const unsigned char *in, unsigned char *out,
-@               const AES_KEY *key) {
-.align 5
-ENTRY(AES_encrypt)
-       adr     r3,AES_encrypt
-       stmdb   sp!,{r1,r4-r12,lr}
-       mov     r12,r0          @ inp
-       mov     r11,r2
-       sub     r10,r3,#AES_encrypt-AES_Te      @ Te
-#if __ARM_ARCH__<7
-       ldrb    r0,[r12,#3]     @ load input data in endian-neutral
-       ldrb    r4,[r12,#2]     @ manner...
-       ldrb    r5,[r12,#1]
-       ldrb    r6,[r12,#0]
-       orr     r0,r0,r4,lsl#8
-       ldrb    r1,[r12,#7]
-       orr     r0,r0,r5,lsl#16
-       ldrb    r4,[r12,#6]
-       orr     r0,r0,r6,lsl#24
-       ldrb    r5,[r12,#5]
-       ldrb    r6,[r12,#4]
-       orr     r1,r1,r4,lsl#8
-       ldrb    r2,[r12,#11]
-       orr     r1,r1,r5,lsl#16
-       ldrb    r4,[r12,#10]
-       orr     r1,r1,r6,lsl#24
-       ldrb    r5,[r12,#9]
-       ldrb    r6,[r12,#8]
-       orr     r2,r2,r4,lsl#8
-       ldrb    r3,[r12,#15]
-       orr     r2,r2,r5,lsl#16
-       ldrb    r4,[r12,#14]
-       orr     r2,r2,r6,lsl#24
-       ldrb    r5,[r12,#13]
-       ldrb    r6,[r12,#12]
-       orr     r3,r3,r4,lsl#8
-       orr     r3,r3,r5,lsl#16
-       orr     r3,r3,r6,lsl#24
-#else
-       ldr     r0,[r12,#0]
-       ldr     r1,[r12,#4]
-       ldr     r2,[r12,#8]
-       ldr     r3,[r12,#12]
-#ifdef __ARMEL__
-       rev     r0,r0
-       rev     r1,r1
-       rev     r2,r2
-       rev     r3,r3
-#endif
-#endif
-       bl      _armv4_AES_encrypt
-
-       ldr     r12,[sp],#4             @ pop out
-#if __ARM_ARCH__>=7
-#ifdef __ARMEL__
-       rev     r0,r0
-       rev     r1,r1
-       rev     r2,r2
-       rev     r3,r3
-#endif
-       str     r0,[r12,#0]
-       str     r1,[r12,#4]
-       str     r2,[r12,#8]
-       str     r3,[r12,#12]
-#else
-       mov     r4,r0,lsr#24            @ write output in endian-neutral
-       mov     r5,r0,lsr#16            @ manner...
-       mov     r6,r0,lsr#8
-       strb    r4,[r12,#0]
-       strb    r5,[r12,#1]
-       mov     r4,r1,lsr#24
-       strb    r6,[r12,#2]
-       mov     r5,r1,lsr#16
-       strb    r0,[r12,#3]
-       mov     r6,r1,lsr#8
-       strb    r4,[r12,#4]
-       strb    r5,[r12,#5]
-       mov     r4,r2,lsr#24
-       strb    r6,[r12,#6]
-       mov     r5,r2,lsr#16
-       strb    r1,[r12,#7]
-       mov     r6,r2,lsr#8
-       strb    r4,[r12,#8]
-       strb    r5,[r12,#9]
-       mov     r4,r3,lsr#24
-       strb    r6,[r12,#10]
-       mov     r5,r3,lsr#16
-       strb    r2,[r12,#11]
-       mov     r6,r3,lsr#8
-       strb    r4,[r12,#12]
-       strb    r5,[r12,#13]
-       strb    r6,[r12,#14]
-       strb    r3,[r12,#15]
-#endif
-       ldmia   sp!,{r4-r12,pc}
-ENDPROC(AES_encrypt)
-
-.type   _armv4_AES_encrypt,%function
-.align 2
-_armv4_AES_encrypt:
-       str     lr,[sp,#-4]!            @ push lr
-       ldmia   r11!,{r4-r7}
-       eor     r0,r0,r4
-       ldr     r12,[r11,#240-16]
-       eor     r1,r1,r5
-       eor     r2,r2,r6
-       eor     r3,r3,r7
-       sub     r12,r12,#1
-       mov     lr,#255
-
-       and     r7,lr,r0
-       and     r8,lr,r0,lsr#8
-       and     r9,lr,r0,lsr#16
-       mov     r0,r0,lsr#24
-.Lenc_loop:
-       ldr     r4,[r10,r7,lsl#2]       @ Te3[s0>>0]
-       and     r7,lr,r1,lsr#16 @ i0
-       ldr     r5,[r10,r8,lsl#2]       @ Te2[s0>>8]
-       and     r8,lr,r1
-       ldr     r6,[r10,r9,lsl#2]       @ Te1[s0>>16]
-       and     r9,lr,r1,lsr#8
-       ldr     r0,[r10,r0,lsl#2]       @ Te0[s0>>24]
-       mov     r1,r1,lsr#24
-
-       ldr     r7,[r10,r7,lsl#2]       @ Te1[s1>>16]
-       ldr     r8,[r10,r8,lsl#2]       @ Te3[s1>>0]
-       ldr     r9,[r10,r9,lsl#2]       @ Te2[s1>>8]
-       eor     r0,r0,r7,ror#8
-       ldr     r1,[r10,r1,lsl#2]       @ Te0[s1>>24]
-       and     r7,lr,r2,lsr#8  @ i0
-       eor     r5,r5,r8,ror#8
-       and     r8,lr,r2,lsr#16 @ i1
-       eor     r6,r6,r9,ror#8
-       and     r9,lr,r2
-       ldr     r7,[r10,r7,lsl#2]       @ Te2[s2>>8]
-       eor     r1,r1,r4,ror#24
-       ldr     r8,[r10,r8,lsl#2]       @ Te1[s2>>16]
-       mov     r2,r2,lsr#24
-
-       ldr     r9,[r10,r9,lsl#2]       @ Te3[s2>>0]
-       eor     r0,r0,r7,ror#16
-       ldr     r2,[r10,r2,lsl#2]       @ Te0[s2>>24]
-       and     r7,lr,r3                @ i0
-       eor     r1,r1,r8,ror#8
-       and     r8,lr,r3,lsr#8  @ i1
-       eor     r6,r6,r9,ror#16
-       and     r9,lr,r3,lsr#16 @ i2
-       ldr     r7,[r10,r7,lsl#2]       @ Te3[s3>>0]
-       eor     r2,r2,r5,ror#16
-       ldr     r8,[r10,r8,lsl#2]       @ Te2[s3>>8]
-       mov     r3,r3,lsr#24
-
-       ldr     r9,[r10,r9,lsl#2]       @ Te1[s3>>16]
-       eor     r0,r0,r7,ror#24
-       ldr     r7,[r11],#16
-       eor     r1,r1,r8,ror#16
-       ldr     r3,[r10,r3,lsl#2]       @ Te0[s3>>24]
-       eor     r2,r2,r9,ror#8
-       ldr     r4,[r11,#-12]
-       eor     r3,r3,r6,ror#8
-
-       ldr     r5,[r11,#-8]
-       eor     r0,r0,r7
-       ldr     r6,[r11,#-4]
-       and     r7,lr,r0
-       eor     r1,r1,r4
-       and     r8,lr,r0,lsr#8
-       eor     r2,r2,r5
-       and     r9,lr,r0,lsr#16
-       eor     r3,r3,r6
-       mov     r0,r0,lsr#24
-
-       subs    r12,r12,#1
-       bne     .Lenc_loop
-
-       add     r10,r10,#2
-
-       ldrb    r4,[r10,r7,lsl#2]       @ Te4[s0>>0]
-       and     r7,lr,r1,lsr#16 @ i0
-       ldrb    r5,[r10,r8,lsl#2]       @ Te4[s0>>8]
-       and     r8,lr,r1
-       ldrb    r6,[r10,r9,lsl#2]       @ Te4[s0>>16]
-       and     r9,lr,r1,lsr#8
-       ldrb    r0,[r10,r0,lsl#2]       @ Te4[s0>>24]
-       mov     r1,r1,lsr#24
-
-       ldrb    r7,[r10,r7,lsl#2]       @ Te4[s1>>16]
-       ldrb    r8,[r10,r8,lsl#2]       @ Te4[s1>>0]
-       ldrb    r9,[r10,r9,lsl#2]       @ Te4[s1>>8]
-       eor     r0,r7,r0,lsl#8
-       ldrb    r1,[r10,r1,lsl#2]       @ Te4[s1>>24]
-       and     r7,lr,r2,lsr#8  @ i0
-       eor     r5,r8,r5,lsl#8
-       and     r8,lr,r2,lsr#16 @ i1
-       eor     r6,r9,r6,lsl#8
-       and     r9,lr,r2
-       ldrb    r7,[r10,r7,lsl#2]       @ Te4[s2>>8]
-       eor     r1,r4,r1,lsl#24
-       ldrb    r8,[r10,r8,lsl#2]       @ Te4[s2>>16]
-       mov     r2,r2,lsr#24
-
-       ldrb    r9,[r10,r9,lsl#2]       @ Te4[s2>>0]
-       eor     r0,r7,r0,lsl#8
-       ldrb    r2,[r10,r2,lsl#2]       @ Te4[s2>>24]
-       and     r7,lr,r3                @ i0
-       eor     r1,r1,r8,lsl#16
-       and     r8,lr,r3,lsr#8  @ i1
-       eor     r6,r9,r6,lsl#8
-       and     r9,lr,r3,lsr#16 @ i2
-       ldrb    r7,[r10,r7,lsl#2]       @ Te4[s3>>0]
-       eor     r2,r5,r2,lsl#24
-       ldrb    r8,[r10,r8,lsl#2]       @ Te4[s3>>8]
-       mov     r3,r3,lsr#24
-
-       ldrb    r9,[r10,r9,lsl#2]       @ Te4[s3>>16]
-       eor     r0,r7,r0,lsl#8
-       ldr     r7,[r11,#0]
-       ldrb    r3,[r10,r3,lsl#2]       @ Te4[s3>>24]
-       eor     r1,r1,r8,lsl#8
-       ldr     r4,[r11,#4]
-       eor     r2,r2,r9,lsl#16
-       ldr     r5,[r11,#8]
-       eor     r3,r6,r3,lsl#24
-       ldr     r6,[r11,#12]
-
-       eor     r0,r0,r7
-       eor     r1,r1,r4
-       eor     r2,r2,r5
-       eor     r3,r3,r6
-
-       sub     r10,r10,#2
-       ldr     pc,[sp],#4              @ pop and return
-.size  _armv4_AES_encrypt,.-_armv4_AES_encrypt
-
-.align 5
-ENTRY(private_AES_set_encrypt_key)
-_armv4_AES_set_encrypt_key:
-       adr     r3,_armv4_AES_set_encrypt_key
-       teq     r0,#0
-       moveq   r0,#-1
-       beq     .Labrt
-       teq     r2,#0
-       moveq   r0,#-1
-       beq     .Labrt
-
-       teq     r1,#128
-       beq     .Lok
-       teq     r1,#192
-       beq     .Lok
-       teq     r1,#256
-       movne   r0,#-1
-       bne     .Labrt
-
-.Lok:  stmdb   sp!,{r4-r12,lr}
-       sub     r10,r3,#_armv4_AES_set_encrypt_key-AES_Te-1024  @ Te4
-
-       mov     r12,r0          @ inp
-       mov     lr,r1                   @ bits
-       mov     r11,r2                  @ key
-
-#if __ARM_ARCH__<7
-       ldrb    r0,[r12,#3]     @ load input data in endian-neutral
-       ldrb    r4,[r12,#2]     @ manner...
-       ldrb    r5,[r12,#1]
-       ldrb    r6,[r12,#0]
-       orr     r0,r0,r4,lsl#8
-       ldrb    r1,[r12,#7]
-       orr     r0,r0,r5,lsl#16
-       ldrb    r4,[r12,#6]
-       orr     r0,r0,r6,lsl#24
-       ldrb    r5,[r12,#5]
-       ldrb    r6,[r12,#4]
-       orr     r1,r1,r4,lsl#8
-       ldrb    r2,[r12,#11]
-       orr     r1,r1,r5,lsl#16
-       ldrb    r4,[r12,#10]
-       orr     r1,r1,r6,lsl#24
-       ldrb    r5,[r12,#9]
-       ldrb    r6,[r12,#8]
-       orr     r2,r2,r4,lsl#8
-       ldrb    r3,[r12,#15]
-       orr     r2,r2,r5,lsl#16
-       ldrb    r4,[r12,#14]
-       orr     r2,r2,r6,lsl#24
-       ldrb    r5,[r12,#13]
-       ldrb    r6,[r12,#12]
-       orr     r3,r3,r4,lsl#8
-       str     r0,[r11],#16
-       orr     r3,r3,r5,lsl#16
-       str     r1,[r11,#-12]
-       orr     r3,r3,r6,lsl#24
-       str     r2,[r11,#-8]
-       str     r3,[r11,#-4]
-#else
-       ldr     r0,[r12,#0]
-       ldr     r1,[r12,#4]
-       ldr     r2,[r12,#8]
-       ldr     r3,[r12,#12]
-#ifdef __ARMEL__
-       rev     r0,r0
-       rev     r1,r1
-       rev     r2,r2
-       rev     r3,r3
-#endif
-       str     r0,[r11],#16
-       str     r1,[r11,#-12]
-       str     r2,[r11,#-8]
-       str     r3,[r11,#-4]
-#endif
-
-       teq     lr,#128
-       bne     .Lnot128
-       mov     r12,#10
-       str     r12,[r11,#240-16]
-       add     r6,r10,#256                     @ rcon
-       mov     lr,#255
-
-.L128_loop:
-       and     r5,lr,r3,lsr#24
-       and     r7,lr,r3,lsr#16
-       ldrb    r5,[r10,r5]
-       and     r8,lr,r3,lsr#8
-       ldrb    r7,[r10,r7]
-       and     r9,lr,r3
-       ldrb    r8,[r10,r8]
-       orr     r5,r5,r7,lsl#24
-       ldrb    r9,[r10,r9]
-       orr     r5,r5,r8,lsl#16
-       ldr     r4,[r6],#4                      @ rcon[i++]
-       orr     r5,r5,r9,lsl#8
-       eor     r5,r5,r4
-       eor     r0,r0,r5                        @ rk[4]=rk[0]^...
-       eor     r1,r1,r0                        @ rk[5]=rk[1]^rk[4]
-       str     r0,[r11],#16
-       eor     r2,r2,r1                        @ rk[6]=rk[2]^rk[5]
-       str     r1,[r11,#-12]
-       eor     r3,r3,r2                        @ rk[7]=rk[3]^rk[6]
-       str     r2,[r11,#-8]
-       subs    r12,r12,#1
-       str     r3,[r11,#-4]
-       bne     .L128_loop
-       sub     r2,r11,#176
-       b       .Ldone
-
-.Lnot128:
-#if __ARM_ARCH__<7
-       ldrb    r8,[r12,#19]
-       ldrb    r4,[r12,#18]
-       ldrb    r5,[r12,#17]
-       ldrb    r6,[r12,#16]
-       orr     r8,r8,r4,lsl#8
-       ldrb    r9,[r12,#23]
-       orr     r8,r8,r5,lsl#16
-       ldrb    r4,[r12,#22]
-       orr     r8,r8,r6,lsl#24
-       ldrb    r5,[r12,#21]
-       ldrb    r6,[r12,#20]
-       orr     r9,r9,r4,lsl#8
-       orr     r9,r9,r5,lsl#16
-       str     r8,[r11],#8
-       orr     r9,r9,r6,lsl#24
-       str     r9,[r11,#-4]
-#else
-       ldr     r8,[r12,#16]
-       ldr     r9,[r12,#20]
-#ifdef __ARMEL__
-       rev     r8,r8
-       rev     r9,r9
-#endif
-       str     r8,[r11],#8
-       str     r9,[r11,#-4]
-#endif
-
-       teq     lr,#192
-       bne     .Lnot192
-       mov     r12,#12
-       str     r12,[r11,#240-24]
-       add     r6,r10,#256                     @ rcon
-       mov     lr,#255
-       mov     r12,#8
-
-.L192_loop:
-       and     r5,lr,r9,lsr#24
-       and     r7,lr,r9,lsr#16
-       ldrb    r5,[r10,r5]
-       and     r8,lr,r9,lsr#8
-       ldrb    r7,[r10,r7]
-       and     r9,lr,r9
-       ldrb    r8,[r10,r8]
-       orr     r5,r5,r7,lsl#24
-       ldrb    r9,[r10,r9]
-       orr     r5,r5,r8,lsl#16
-       ldr     r4,[r6],#4                      @ rcon[i++]
-       orr     r5,r5,r9,lsl#8
-       eor     r9,r5,r4
-       eor     r0,r0,r9                        @ rk[6]=rk[0]^...
-       eor     r1,r1,r0                        @ rk[7]=rk[1]^rk[6]
-       str     r0,[r11],#24
-       eor     r2,r2,r1                        @ rk[8]=rk[2]^rk[7]
-       str     r1,[r11,#-20]
-       eor     r3,r3,r2                        @ rk[9]=rk[3]^rk[8]
-       str     r2,[r11,#-16]
-       subs    r12,r12,#1
-       str     r3,[r11,#-12]
-       subeq   r2,r11,#216
-       beq     .Ldone
-
-       ldr     r7,[r11,#-32]
-       ldr     r8,[r11,#-28]
-       eor     r7,r7,r3                        @ rk[10]=rk[4]^rk[9]
-       eor     r9,r8,r7                        @ rk[11]=rk[5]^rk[10]
-       str     r7,[r11,#-8]
-       str     r9,[r11,#-4]
-       b       .L192_loop
-
-.Lnot192:
-#if __ARM_ARCH__<7
-       ldrb    r8,[r12,#27]
-       ldrb    r4,[r12,#26]
-       ldrb    r5,[r12,#25]
-       ldrb    r6,[r12,#24]
-       orr     r8,r8,r4,lsl#8
-       ldrb    r9,[r12,#31]
-       orr     r8,r8,r5,lsl#16
-       ldrb    r4,[r12,#30]
-       orr     r8,r8,r6,lsl#24
-       ldrb    r5,[r12,#29]
-       ldrb    r6,[r12,#28]
-       orr     r9,r9,r4,lsl#8
-       orr     r9,r9,r5,lsl#16
-       str     r8,[r11],#8
-       orr     r9,r9,r6,lsl#24
-       str     r9,[r11,#-4]
-#else
-       ldr     r8,[r12,#24]
-       ldr     r9,[r12,#28]
-#ifdef __ARMEL__
-       rev     r8,r8
-       rev     r9,r9
-#endif
-       str     r8,[r11],#8
-       str     r9,[r11,#-4]
-#endif
-
-       mov     r12,#14
-       str     r12,[r11,#240-32]
-       add     r6,r10,#256                     @ rcon
-       mov     lr,#255
-       mov     r12,#7
-
-.L256_loop:
-       and     r5,lr,r9,lsr#24
-       and     r7,lr,r9,lsr#16
-       ldrb    r5,[r10,r5]
-       and     r8,lr,r9,lsr#8
-       ldrb    r7,[r10,r7]
-       and     r9,lr,r9
-       ldrb    r8,[r10,r8]
-       orr     r5,r5,r7,lsl#24
-       ldrb    r9,[r10,r9]
-       orr     r5,r5,r8,lsl#16
-       ldr     r4,[r6],#4                      @ rcon[i++]
-       orr     r5,r5,r9,lsl#8
-       eor     r9,r5,r4
-       eor     r0,r0,r9                        @ rk[8]=rk[0]^...
-       eor     r1,r1,r0                        @ rk[9]=rk[1]^rk[8]
-       str     r0,[r11],#32
-       eor     r2,r2,r1                        @ rk[10]=rk[2]^rk[9]
-       str     r1,[r11,#-28]
-       eor     r3,r3,r2                        @ rk[11]=rk[3]^rk[10]
-       str     r2,[r11,#-24]
-       subs    r12,r12,#1
-       str     r3,[r11,#-20]
-       subeq   r2,r11,#256
-       beq     .Ldone
-
-       and     r5,lr,r3
-       and     r7,lr,r3,lsr#8
-       ldrb    r5,[r10,r5]
-       and     r8,lr,r3,lsr#16
-       ldrb    r7,[r10,r7]
-       and     r9,lr,r3,lsr#24
-       ldrb    r8,[r10,r8]
-       orr     r5,r5,r7,lsl#8
-       ldrb    r9,[r10,r9]
-       orr     r5,r5,r8,lsl#16
-       ldr     r4,[r11,#-48]
-       orr     r5,r5,r9,lsl#24
-
-       ldr     r7,[r11,#-44]
-       ldr     r8,[r11,#-40]
-       eor     r4,r4,r5                        @ rk[12]=rk[4]^...
-       ldr     r9,[r11,#-36]
-       eor     r7,r7,r4                        @ rk[13]=rk[5]^rk[12]
-       str     r4,[r11,#-16]
-       eor     r8,r8,r7                        @ rk[14]=rk[6]^rk[13]
-       str     r7,[r11,#-12]
-       eor     r9,r9,r8                        @ rk[15]=rk[7]^rk[14]
-       str     r8,[r11,#-8]
-       str     r9,[r11,#-4]
-       b       .L256_loop
-
-.Ldone:        mov     r0,#0
-       ldmia   sp!,{r4-r12,lr}
-.Labrt:        ret     lr
-ENDPROC(private_AES_set_encrypt_key)
-
-.align 5
-ENTRY(private_AES_set_decrypt_key)
-       str     lr,[sp,#-4]!            @ push lr
-#if 0
-       @ kernel does both of these in setkey so optimise this bit out by
-       @ expecting the key to already have the enc_key work done (see aes_glue.c)
-       bl      _armv4_AES_set_encrypt_key
-#else
-       mov     r0,#0
-#endif
-       teq     r0,#0
-       ldrne   lr,[sp],#4              @ pop lr
-       bne     .Labrt
-
-       stmdb   sp!,{r4-r12}
-
-       ldr     r12,[r2,#240]   @ AES_set_encrypt_key preserves r2,
-       mov     r11,r2                  @ which is AES_KEY *key
-       mov     r7,r2
-       add     r8,r2,r12,lsl#4
-
-.Linv: ldr     r0,[r7]
-       ldr     r1,[r7,#4]
-       ldr     r2,[r7,#8]
-       ldr     r3,[r7,#12]
-       ldr     r4,[r8]
-       ldr     r5,[r8,#4]
-       ldr     r6,[r8,#8]
-       ldr     r9,[r8,#12]
-       str     r0,[r8],#-16
-       str     r1,[r8,#16+4]
-       str     r2,[r8,#16+8]
-       str     r3,[r8,#16+12]
-       str     r4,[r7],#16
-       str     r5,[r7,#-12]
-       str     r6,[r7,#-8]
-       str     r9,[r7,#-4]
-       teq     r7,r8
-       bne     .Linv
-       ldr     r0,[r11,#16]!           @ prefetch tp1
-       mov     r7,#0x80
-       mov     r8,#0x1b
-       orr     r7,r7,#0x8000
-       orr     r8,r8,#0x1b00
-       orr     r7,r7,r7,lsl#16
-       orr     r8,r8,r8,lsl#16
-       sub     r12,r12,#1
-       mvn     r9,r7
-       mov     r12,r12,lsl#2   @ (rounds-1)*4
-
-.Lmix: and     r4,r0,r7
-       and     r1,r0,r9
-       sub     r4,r4,r4,lsr#7
-       and     r4,r4,r8
-       eor     r1,r4,r1,lsl#1  @ tp2
-
-       and     r4,r1,r7
-       and     r2,r1,r9
-       sub     r4,r4,r4,lsr#7
-       and     r4,r4,r8
-       eor     r2,r4,r2,lsl#1  @ tp4
-
-       and     r4,r2,r7
-       and     r3,r2,r9
-       sub     r4,r4,r4,lsr#7
-       and     r4,r4,r8
-       eor     r3,r4,r3,lsl#1  @ tp8
-
-       eor     r4,r1,r2
-       eor     r5,r0,r3                @ tp9
-       eor     r4,r4,r3                @ tpe
-       eor     r4,r4,r1,ror#24
-       eor     r4,r4,r5,ror#24 @ ^= ROTATE(tpb=tp9^tp2,8)
-       eor     r4,r4,r2,ror#16
-       eor     r4,r4,r5,ror#16 @ ^= ROTATE(tpd=tp9^tp4,16)
-       eor     r4,r4,r5,ror#8  @ ^= ROTATE(tp9,24)
-
-       ldr     r0,[r11,#4]             @ prefetch tp1
-       str     r4,[r11],#4
-       subs    r12,r12,#1
-       bne     .Lmix
-
-       mov     r0,#0
-       ldmia   sp!,{r4-r12,pc}
-ENDPROC(private_AES_set_decrypt_key)
-
-.type  AES_Td,%object
-.align 5
-AES_Td:
-.word  0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96
-.word  0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393
-.word  0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25
-.word  0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f
-.word  0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1
-.word  0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6
-.word  0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da
-.word  0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844
-.word  0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd
-.word  0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4
-.word  0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45
-.word  0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94
-.word  0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7
-.word  0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a
-.word  0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5
-.word  0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c
-.word  0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1
-.word  0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a
-.word  0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75
-.word  0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051
-.word  0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46
-.word  0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff
-.word  0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77
-.word  0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb
-.word  0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000
-.word  0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e
-.word  0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927
-.word  0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a
-.word  0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e
-.word  0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16
-.word  0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d
-.word  0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8
-.word  0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd
-.word  0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34
-.word  0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163
-.word  0xd731dcca, 0x42638510, 0x13972240, 0x84c61120
-.word  0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d
-.word  0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0
-.word  0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422
-.word  0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef
-.word  0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36
-.word  0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4
-.word  0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662
-.word  0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5
-.word  0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3
-.word  0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b
-.word  0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8
-.word  0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6
-.word  0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6
-.word  0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0
-.word  0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815
-.word  0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f
-.word  0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df
-.word  0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f
-.word  0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e
-.word  0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713
-.word  0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89
-.word  0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c
-.word  0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf
-.word  0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86
-.word  0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f
-.word  0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541
-.word  0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190
-.word  0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742
-@ Td4[256]
-.byte  0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
-.byte  0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
-.byte  0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
-.byte  0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
-.byte  0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
-.byte  0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
-.byte  0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
-.byte  0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
-.byte  0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
-.byte  0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
-.byte  0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
-.byte  0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
-.byte  0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
-.byte  0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
-.byte  0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
-.byte  0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
-.byte  0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
-.byte  0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
-.byte  0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
-.byte  0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
-.byte  0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
-.byte  0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
-.byte  0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
-.byte  0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
-.byte  0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
-.byte  0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
-.byte  0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
-.byte  0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
-.byte  0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
-.byte  0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
-.byte  0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
-.byte  0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
-.size  AES_Td,.-AES_Td
-
-@ void AES_decrypt(const unsigned char *in, unsigned char *out,
-@               const AES_KEY *key) {
-.align 5
-ENTRY(AES_decrypt)
-       adr     r3,AES_decrypt
-       stmdb   sp!,{r1,r4-r12,lr}
-       mov     r12,r0          @ inp
-       mov     r11,r2
-       sub     r10,r3,#AES_decrypt-AES_Td              @ Td
-#if __ARM_ARCH__<7
-       ldrb    r0,[r12,#3]     @ load input data in endian-neutral
-       ldrb    r4,[r12,#2]     @ manner...
-       ldrb    r5,[r12,#1]
-       ldrb    r6,[r12,#0]
-       orr     r0,r0,r4,lsl#8
-       ldrb    r1,[r12,#7]
-       orr     r0,r0,r5,lsl#16
-       ldrb    r4,[r12,#6]
-       orr     r0,r0,r6,lsl#24
-       ldrb    r5,[r12,#5]
-       ldrb    r6,[r12,#4]
-       orr     r1,r1,r4,lsl#8
-       ldrb    r2,[r12,#11]
-       orr     r1,r1,r5,lsl#16
-       ldrb    r4,[r12,#10]
-       orr     r1,r1,r6,lsl#24
-       ldrb    r5,[r12,#9]
-       ldrb    r6,[r12,#8]
-       orr     r2,r2,r4,lsl#8
-       ldrb    r3,[r12,#15]
-       orr     r2,r2,r5,lsl#16
-       ldrb    r4,[r12,#14]
-       orr     r2,r2,r6,lsl#24
-       ldrb    r5,[r12,#13]
-       ldrb    r6,[r12,#12]
-       orr     r3,r3,r4,lsl#8
-       orr     r3,r3,r5,lsl#16
-       orr     r3,r3,r6,lsl#24
-#else
-       ldr     r0,[r12,#0]
-       ldr     r1,[r12,#4]
-       ldr     r2,[r12,#8]
-       ldr     r3,[r12,#12]
-#ifdef __ARMEL__
-       rev     r0,r0
-       rev     r1,r1
-       rev     r2,r2
-       rev     r3,r3
-#endif
-#endif
-       bl      _armv4_AES_decrypt
-
-       ldr     r12,[sp],#4             @ pop out
-#if __ARM_ARCH__>=7
-#ifdef __ARMEL__
-       rev     r0,r0
-       rev     r1,r1
-       rev     r2,r2
-       rev     r3,r3
-#endif
-       str     r0,[r12,#0]
-       str     r1,[r12,#4]
-       str     r2,[r12,#8]
-       str     r3,[r12,#12]
-#else
-       mov     r4,r0,lsr#24            @ write output in endian-neutral
-       mov     r5,r0,lsr#16            @ manner...
-       mov     r6,r0,lsr#8
-       strb    r4,[r12,#0]
-       strb    r5,[r12,#1]
-       mov     r4,r1,lsr#24
-       strb    r6,[r12,#2]
-       mov     r5,r1,lsr#16
-       strb    r0,[r12,#3]
-       mov     r6,r1,lsr#8
-       strb    r4,[r12,#4]
-       strb    r5,[r12,#5]
-       mov     r4,r2,lsr#24
-       strb    r6,[r12,#6]
-       mov     r5,r2,lsr#16
-       strb    r1,[r12,#7]
-       mov     r6,r2,lsr#8
-       strb    r4,[r12,#8]
-       strb    r5,[r12,#9]
-       mov     r4,r3,lsr#24
-       strb    r6,[r12,#10]
-       mov     r5,r3,lsr#16
-       strb    r2,[r12,#11]
-       mov     r6,r3,lsr#8
-       strb    r4,[r12,#12]
-       strb    r5,[r12,#13]
-       strb    r6,[r12,#14]
-       strb    r3,[r12,#15]
-#endif
-       ldmia   sp!,{r4-r12,pc}
-ENDPROC(AES_decrypt)
-
-.type   _armv4_AES_decrypt,%function
-.align 2
-_armv4_AES_decrypt:
-       str     lr,[sp,#-4]!            @ push lr
-       ldmia   r11!,{r4-r7}
-       eor     r0,r0,r4
-       ldr     r12,[r11,#240-16]
-       eor     r1,r1,r5
-       eor     r2,r2,r6
-       eor     r3,r3,r7
-       sub     r12,r12,#1
-       mov     lr,#255
-
-       and     r7,lr,r0,lsr#16
-       and     r8,lr,r0,lsr#8
-       and     r9,lr,r0
-       mov     r0,r0,lsr#24
-.Ldec_loop:
-       ldr     r4,[r10,r7,lsl#2]       @ Td1[s0>>16]
-       and     r7,lr,r1                @ i0
-       ldr     r5,[r10,r8,lsl#2]       @ Td2[s0>>8]
-       and     r8,lr,r1,lsr#16
-       ldr     r6,[r10,r9,lsl#2]       @ Td3[s0>>0]
-       and     r9,lr,r1,lsr#8
-       ldr     r0,[r10,r0,lsl#2]       @ Td0[s0>>24]
-       mov     r1,r1,lsr#24
-
-       ldr     r7,[r10,r7,lsl#2]       @ Td3[s1>>0]
-       ldr     r8,[r10,r8,lsl#2]       @ Td1[s1>>16]
-       ldr     r9,[r10,r9,lsl#2]       @ Td2[s1>>8]
-       eor     r0,r0,r7,ror#24
-       ldr     r1,[r10,r1,lsl#2]       @ Td0[s1>>24]
-       and     r7,lr,r2,lsr#8  @ i0
-       eor     r5,r8,r5,ror#8
-       and     r8,lr,r2                @ i1
-       eor     r6,r9,r6,ror#8
-       and     r9,lr,r2,lsr#16
-       ldr     r7,[r10,r7,lsl#2]       @ Td2[s2>>8]
-       eor     r1,r1,r4,ror#8
-       ldr     r8,[r10,r8,lsl#2]       @ Td3[s2>>0]
-       mov     r2,r2,lsr#24
-
-       ldr     r9,[r10,r9,lsl#2]       @ Td1[s2>>16]
-       eor     r0,r0,r7,ror#16
-       ldr     r2,[r10,r2,lsl#2]       @ Td0[s2>>24]
-       and     r7,lr,r3,lsr#16 @ i0
-       eor     r1,r1,r8,ror#24
-       and     r8,lr,r3,lsr#8  @ i1
-       eor     r6,r9,r6,ror#8
-       and     r9,lr,r3                @ i2
-       ldr     r7,[r10,r7,lsl#2]       @ Td1[s3>>16]
-       eor     r2,r2,r5,ror#8
-       ldr     r8,[r10,r8,lsl#2]       @ Td2[s3>>8]
-       mov     r3,r3,lsr#24
-
-       ldr     r9,[r10,r9,lsl#2]       @ Td3[s3>>0]
-       eor     r0,r0,r7,ror#8
-       ldr     r7,[r11],#16
-       eor     r1,r1,r8,ror#16
-       ldr     r3,[r10,r3,lsl#2]       @ Td0[s3>>24]
-       eor     r2,r2,r9,ror#24
-
-       ldr     r4,[r11,#-12]
-       eor     r0,r0,r7
-       ldr     r5,[r11,#-8]
-       eor     r3,r3,r6,ror#8
-       ldr     r6,[r11,#-4]
-       and     r7,lr,r0,lsr#16
-       eor     r1,r1,r4
-       and     r8,lr,r0,lsr#8
-       eor     r2,r2,r5
-       and     r9,lr,r0
-       eor     r3,r3,r6
-       mov     r0,r0,lsr#24
-
-       subs    r12,r12,#1
-       bne     .Ldec_loop
-
-       add     r10,r10,#1024
-
-       ldr     r5,[r10,#0]             @ prefetch Td4
-       ldr     r6,[r10,#32]
-       ldr     r4,[r10,#64]
-       ldr     r5,[r10,#96]
-       ldr     r6,[r10,#128]
-       ldr     r4,[r10,#160]
-       ldr     r5,[r10,#192]
-       ldr     r6,[r10,#224]
-
-       ldrb    r0,[r10,r0]             @ Td4[s0>>24]
-       ldrb    r4,[r10,r7]             @ Td4[s0>>16]
-       and     r7,lr,r1                @ i0
-       ldrb    r5,[r10,r8]             @ Td4[s0>>8]
-       and     r8,lr,r1,lsr#16
-       ldrb    r6,[r10,r9]             @ Td4[s0>>0]
-       and     r9,lr,r1,lsr#8
-
-       ldrb    r7,[r10,r7]             @ Td4[s1>>0]
- ARM(  ldrb    r1,[r10,r1,lsr#24]  )   @ Td4[s1>>24]
- THUMB(        add     r1,r10,r1,lsr#24    )   @ Td4[s1>>24]
- THUMB(        ldrb    r1,[r1]             )
-       ldrb    r8,[r10,r8]             @ Td4[s1>>16]
-       eor     r0,r7,r0,lsl#24
-       ldrb    r9,[r10,r9]             @ Td4[s1>>8]
-       eor     r1,r4,r1,lsl#8
-       and     r7,lr,r2,lsr#8  @ i0
-       eor     r5,r5,r8,lsl#8
-       and     r8,lr,r2                @ i1
-       ldrb    r7,[r10,r7]             @ Td4[s2>>8]
-       eor     r6,r6,r9,lsl#8
-       ldrb    r8,[r10,r8]             @ Td4[s2>>0]
-       and     r9,lr,r2,lsr#16
-
- ARM(  ldrb    r2,[r10,r2,lsr#24]  )   @ Td4[s2>>24]
- THUMB(        add     r2,r10,r2,lsr#24    )   @ Td4[s2>>24]
- THUMB(        ldrb    r2,[r2]             )
-       eor     r0,r0,r7,lsl#8
-       ldrb    r9,[r10,r9]             @ Td4[s2>>16]
-       eor     r1,r8,r1,lsl#16
-       and     r7,lr,r3,lsr#16 @ i0
-       eor     r2,r5,r2,lsl#16
-       and     r8,lr,r3,lsr#8  @ i1
-       ldrb    r7,[r10,r7]             @ Td4[s3>>16]
-       eor     r6,r6,r9,lsl#16
-       ldrb    r8,[r10,r8]             @ Td4[s3>>8]
-       and     r9,lr,r3                @ i2
-
-       ldrb    r9,[r10,r9]             @ Td4[s3>>0]
- ARM(  ldrb    r3,[r10,r3,lsr#24]  )   @ Td4[s3>>24]
- THUMB(        add     r3,r10,r3,lsr#24    )   @ Td4[s3>>24]
- THUMB(        ldrb    r3,[r3]             )
-       eor     r0,r0,r7,lsl#16
-       ldr     r7,[r11,#0]
-       eor     r1,r1,r8,lsl#8
-       ldr     r4,[r11,#4]
-       eor     r2,r9,r2,lsl#8
-       ldr     r5,[r11,#8]
-       eor     r3,r6,r3,lsl#24
-       ldr     r6,[r11,#12]
-
-       eor     r0,r0,r7
-       eor     r1,r1,r4
-       eor     r2,r2,r5
-       eor     r3,r3,r6
-
-       sub     r10,r10,#1024
-       ldr     pc,[sp],#4              @ pop and return
-.size  _armv4_AES_decrypt,.-_armv4_AES_decrypt
-.asciz "AES for ARMv4, CRYPTOGAMS by <appro@openssl.org>"
-.align 2
diff --git a/arch/arm/crypto/aes-neonbs-core.S b/arch/arm/crypto/aes-neonbs-core.S
new file mode 100644 (file)
index 0000000..c947704
--- /dev/null
@@ -0,0 +1,1021 @@
+/*
+ * Bit sliced AES using NEON instructions
+ *
+ * Copyright (C) 2017 Linaro Ltd.
+ * Author: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * The algorithm implemented here is described in detail by the paper
+ * 'Faster and Timing-Attack Resistant AES-GCM' by Emilia Kaesper and
+ * Peter Schwabe (https://eprint.iacr.org/2009/129.pdf)
+ *
+ * This implementation is based primarily on the OpenSSL implementation
+ * for 32-bit ARM written by Andy Polyakov <appro@openssl.org>
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+       .text
+       .fpu            neon
+
+       rounds          .req    ip
+       bskey           .req    r4
+
+       q0l             .req    d0
+       q0h             .req    d1
+       q1l             .req    d2
+       q1h             .req    d3
+       q2l             .req    d4
+       q2h             .req    d5
+       q3l             .req    d6
+       q3h             .req    d7
+       q4l             .req    d8
+       q4h             .req    d9
+       q5l             .req    d10
+       q5h             .req    d11
+       q6l             .req    d12
+       q6h             .req    d13
+       q7l             .req    d14
+       q7h             .req    d15
+       q8l             .req    d16
+       q8h             .req    d17
+       q9l             .req    d18
+       q9h             .req    d19
+       q10l            .req    d20
+       q10h            .req    d21
+       q11l            .req    d22
+       q11h            .req    d23
+       q12l            .req    d24
+       q12h            .req    d25
+       q13l            .req    d26
+       q13h            .req    d27
+       q14l            .req    d28
+       q14h            .req    d29
+       q15l            .req    d30
+       q15h            .req    d31
+
+       .macro          __tbl, out, tbl, in, tmp
+       .ifc            \out, \tbl
+       .ifb            \tmp
+       .error          __tbl needs temp register if out == tbl
+       .endif
+       vmov            \tmp, \out
+       .endif
+       vtbl.8          \out\()l, {\tbl}, \in\()l
+       .ifc            \out, \tbl
+       vtbl.8          \out\()h, {\tmp}, \in\()h
+       .else
+       vtbl.8          \out\()h, {\tbl}, \in\()h
+       .endif
+       .endm
+
+       .macro          __ldr, out, sym
+       vldr            \out\()l, \sym
+       vldr            \out\()h, \sym + 8
+       .endm
+
+       .macro          __adr, reg, lbl
+       adr             \reg, \lbl
+THUMB( orr             \reg, \reg, #1          )
+       .endm
+
+       .macro          in_bs_ch, b0, b1, b2, b3, b4, b5, b6, b7
+       veor            \b2, \b2, \b1
+       veor            \b5, \b5, \b6
+       veor            \b3, \b3, \b0
+       veor            \b6, \b6, \b2
+       veor            \b5, \b5, \b0
+       veor            \b6, \b6, \b3
+       veor            \b3, \b3, \b7
+       veor            \b7, \b7, \b5
+       veor            \b3, \b3, \b4
+       veor            \b4, \b4, \b5
+       veor            \b2, \b2, \b7
+       veor            \b3, \b3, \b1
+       veor            \b1, \b1, \b5
+       .endm
+
+       .macro          out_bs_ch, b0, b1, b2, b3, b4, b5, b6, b7
+       veor            \b0, \b0, \b6
+       veor            \b1, \b1, \b4
+       veor            \b4, \b4, \b6
+       veor            \b2, \b2, \b0
+       veor            \b6, \b6, \b1
+       veor            \b1, \b1, \b5
+       veor            \b5, \b5, \b3
+       veor            \b3, \b3, \b7
+       veor            \b7, \b7, \b5
+       veor            \b2, \b2, \b5
+       veor            \b4, \b4, \b7
+       .endm
+
+       .macro          inv_in_bs_ch, b6, b1, b2, b4, b7, b0, b3, b5
+       veor            \b1, \b1, \b7
+       veor            \b4, \b4, \b7
+       veor            \b7, \b7, \b5
+       veor            \b1, \b1, \b3
+       veor            \b2, \b2, \b5
+       veor            \b3, \b3, \b7
+       veor            \b6, \b6, \b1
+       veor            \b2, \b2, \b0
+       veor            \b5, \b5, \b3
+       veor            \b4, \b4, \b6
+       veor            \b0, \b0, \b6
+       veor            \b1, \b1, \b4
+       .endm
+
+       .macro          inv_out_bs_ch, b6, b5, b0, b3, b7, b1, b4, b2
+       veor            \b1, \b1, \b5
+       veor            \b2, \b2, \b7
+       veor            \b3, \b3, \b1
+       veor            \b4, \b4, \b5
+       veor            \b7, \b7, \b5
+       veor            \b3, \b3, \b4
+       veor            \b5, \b5, \b0
+       veor            \b3, \b3, \b7
+       veor            \b6, \b6, \b2
+       veor            \b2, \b2, \b1
+       veor            \b6, \b6, \b3
+       veor            \b3, \b3, \b0
+       veor            \b5, \b5, \b6
+       .endm
+
+       .macro          mul_gf4, x0, x1, y0, y1, t0, t1
+       veor            \t0, \y0, \y1
+       vand            \t0, \t0, \x0
+       veor            \x0, \x0, \x1
+       vand            \t1, \x1, \y0
+       vand            \x0, \x0, \y1
+       veor            \x1, \t1, \t0
+       veor            \x0, \x0, \t1
+       .endm
+
+       .macro          mul_gf4_n_gf4, x0, x1, y0, y1, t0, x2, x3, y2, y3, t1
+       veor            \t0, \y0, \y1
+       veor            \t1, \y2, \y3
+       vand            \t0, \t0, \x0
+       vand            \t1, \t1, \x2
+       veor            \x0, \x0, \x1
+       veor            \x2, \x2, \x3
+       vand            \x1, \x1, \y0
+       vand            \x3, \x3, \y2
+       vand            \x0, \x0, \y1
+       vand            \x2, \x2, \y3
+       veor            \x1, \x1, \x0
+       veor            \x2, \x2, \x3
+       veor            \x0, \x0, \t0
+       veor            \x3, \x3, \t1
+       .endm
+
+       .macro          mul_gf16_2, x0, x1, x2, x3, x4, x5, x6, x7, \
+                                   y0, y1, y2, y3, t0, t1, t2, t3
+       veor            \t0, \x0, \x2
+       veor            \t1, \x1, \x3
+       mul_gf4         \x0, \x1, \y0, \y1, \t2, \t3
+       veor            \y0, \y0, \y2
+       veor            \y1, \y1, \y3
+       mul_gf4_n_gf4   \t0, \t1, \y0, \y1, \t3, \x2, \x3, \y2, \y3, \t2
+       veor            \x0, \x0, \t0
+       veor            \x2, \x2, \t0
+       veor            \x1, \x1, \t1
+       veor            \x3, \x3, \t1
+       veor            \t0, \x4, \x6
+       veor            \t1, \x5, \x7
+       mul_gf4_n_gf4   \t0, \t1, \y0, \y1, \t3, \x6, \x7, \y2, \y3, \t2
+       veor            \y0, \y0, \y2
+       veor            \y1, \y1, \y3
+       mul_gf4         \x4, \x5, \y0, \y1, \t2, \t3
+       veor            \x4, \x4, \t0
+       veor            \x6, \x6, \t0
+       veor            \x5, \x5, \t1
+       veor            \x7, \x7, \t1
+       .endm
+
+       .macro          inv_gf256, x0, x1, x2, x3, x4, x5, x6, x7, \
+                                  t0, t1, t2, t3, s0, s1, s2, s3
+       veor            \t3, \x4, \x6
+       veor            \t0, \x5, \x7
+       veor            \t1, \x1, \x3
+       veor            \s1, \x7, \x6
+       veor            \s0, \x0, \x2
+       veor            \s3, \t3, \t0
+       vorr            \t2, \t0, \t1
+       vand            \s2, \t3, \s0
+       vorr            \t3, \t3, \s0
+       veor            \s0, \s0, \t1
+       vand            \t0, \t0, \t1
+       veor            \t1, \x3, \x2
+       vand            \s3, \s3, \s0
+       vand            \s1, \s1, \t1
+       veor            \t1, \x4, \x5
+       veor            \s0, \x1, \x0
+       veor            \t3, \t3, \s1
+       veor            \t2, \t2, \s1
+       vand            \s1, \t1, \s0
+       vorr            \t1, \t1, \s0
+       veor            \t3, \t3, \s3
+       veor            \t0, \t0, \s1
+       veor            \t2, \t2, \s2
+       veor            \t1, \t1, \s3
+       veor            \t0, \t0, \s2
+       vand            \s0, \x7, \x3
+       veor            \t1, \t1, \s2
+       vand            \s1, \x6, \x2
+       vand            \s2, \x5, \x1
+       vorr            \s3, \x4, \x0
+       veor            \t3, \t3, \s0
+       veor            \t1, \t1, \s2
+       veor            \s0, \t0, \s3
+       veor            \t2, \t2, \s1
+       vand            \s2, \t3, \t1
+       veor            \s1, \t2, \s2
+       veor            \s3, \s0, \s2
+       vbsl            \s1, \t1, \s0
+       vmvn            \t0, \s0
+       vbsl            \s0, \s1, \s3
+       vbsl            \t0, \s1, \s3
+       vbsl            \s3, \t3, \t2
+       veor            \t3, \t3, \t2
+       vand            \s2, \s0, \s3
+       veor            \t1, \t1, \t0
+       veor            \s2, \s2, \t3
+       mul_gf16_2      \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \
+                       \s3, \s2, \s1, \t1, \s0, \t0, \t2, \t3
+       .endm
+
+       .macro          sbox, b0, b1, b2, b3, b4, b5, b6, b7, \
+                             t0, t1, t2, t3, s0, s1, s2, s3
+       in_bs_ch        \b0, \b1, \b2, \b3, \b4, \b5, \b6, \b7
+       inv_gf256       \b6, \b5, \b0, \b3, \b7, \b1, \b4, \b2, \
+                       \t0, \t1, \t2, \t3, \s0, \s1, \s2, \s3
+       out_bs_ch       \b7, \b1, \b4, \b2, \b6, \b5, \b0, \b3
+       .endm
+
+       .macro          inv_sbox, b0, b1, b2, b3, b4, b5, b6, b7, \
+                                 t0, t1, t2, t3, s0, s1, s2, s3
+       inv_in_bs_ch    \b0, \b1, \b2, \b3, \b4, \b5, \b6, \b7
+       inv_gf256       \b5, \b1, \b2, \b6, \b3, \b7, \b0, \b4, \
+                       \t0, \t1, \t2, \t3, \s0, \s1, \s2, \s3
+       inv_out_bs_ch   \b3, \b7, \b0, \b4, \b5, \b1, \b2, \b6
+       .endm
+
+       .macro          shift_rows, x0, x1, x2, x3, x4, x5, x6, x7, \
+                                   t0, t1, t2, t3, mask
+       vld1.8          {\t0-\t1}, [bskey, :256]!
+       veor            \t0, \t0, \x0
+       vld1.8          {\t2-\t3}, [bskey, :256]!
+       veor            \t1, \t1, \x1
+       __tbl           \x0, \t0, \mask
+       veor            \t2, \t2, \x2
+       __tbl           \x1, \t1, \mask
+       vld1.8          {\t0-\t1}, [bskey, :256]!
+       veor            \t3, \t3, \x3
+       __tbl           \x2, \t2, \mask
+       __tbl           \x3, \t3, \mask
+       vld1.8          {\t2-\t3}, [bskey, :256]!
+       veor            \t0, \t0, \x4
+       veor            \t1, \t1, \x5
+       __tbl           \x4, \t0, \mask
+       veor            \t2, \t2, \x6
+       __tbl           \x5, \t1, \mask
+       veor            \t3, \t3, \x7
+       __tbl           \x6, \t2, \mask
+       __tbl           \x7, \t3, \mask
+       .endm
+
+       .macro          inv_shift_rows, x0, x1, x2, x3, x4, x5, x6, x7, \
+                                       t0, t1, t2, t3, mask
+       __tbl           \x0, \x0, \mask, \t0
+       __tbl           \x1, \x1, \mask, \t1
+       __tbl           \x2, \x2, \mask, \t2
+       __tbl           \x3, \x3, \mask, \t3
+       __tbl           \x4, \x4, \mask, \t0
+       __tbl           \x5, \x5, \mask, \t1
+       __tbl           \x6, \x6, \mask, \t2
+       __tbl           \x7, \x7, \mask, \t3
+       .endm
+
+       .macro          mix_cols, x0, x1, x2, x3, x4, x5, x6, x7, \
+                                 t0, t1, t2, t3, t4, t5, t6, t7, inv
+       vext.8          \t0, \x0, \x0, #12
+       vext.8          \t1, \x1, \x1, #12
+       veor            \x0, \x0, \t0
+       vext.8          \t2, \x2, \x2, #12
+       veor            \x1, \x1, \t1
+       vext.8          \t3, \x3, \x3, #12
+       veor            \x2, \x2, \t2
+       vext.8          \t4, \x4, \x4, #12
+       veor            \x3, \x3, \t3
+       vext.8          \t5, \x5, \x5, #12
+       veor            \x4, \x4, \t4
+       vext.8          \t6, \x6, \x6, #12
+       veor            \x5, \x5, \t5
+       vext.8          \t7, \x7, \x7, #12
+       veor            \x6, \x6, \t6
+       veor            \t1, \t1, \x0
+       veor.8          \x7, \x7, \t7
+       vext.8          \x0, \x0, \x0, #8
+       veor            \t2, \t2, \x1
+       veor            \t0, \t0, \x7
+       veor            \t1, \t1, \x7
+       vext.8          \x1, \x1, \x1, #8
+       veor            \t5, \t5, \x4
+       veor            \x0, \x0, \t0
+       veor            \t6, \t6, \x5
+       veor            \x1, \x1, \t1
+       vext.8          \t0, \x4, \x4, #8
+       veor            \t4, \t4, \x3
+       vext.8          \t1, \x5, \x5, #8
+       veor            \t7, \t7, \x6
+       vext.8          \x4, \x3, \x3, #8
+       veor            \t3, \t3, \x2
+       vext.8          \x5, \x7, \x7, #8
+       veor            \t4, \t4, \x7
+       vext.8          \x3, \x6, \x6, #8
+       veor            \t3, \t3, \x7
+       vext.8          \x6, \x2, \x2, #8
+       veor            \x7, \t1, \t5
+       .ifb            \inv
+       veor            \x2, \t0, \t4
+       veor            \x4, \x4, \t3
+       veor            \x5, \x5, \t7
+       veor            \x3, \x3, \t6
+       veor            \x6, \x6, \t2
+       .else
+       veor            \t3, \t3, \x4
+       veor            \x5, \x5, \t7
+       veor            \x2, \x3, \t6
+       veor            \x3, \t0, \t4
+       veor            \x4, \x6, \t2
+       vmov            \x6, \t3
+       .endif
+       .endm
+
+       .macro          inv_mix_cols, x0, x1, x2, x3, x4, x5, x6, x7, \
+                                     t0, t1, t2, t3, t4, t5, t6, t7
+       vld1.8          {\t0-\t1}, [bskey, :256]!
+       veor            \x0, \x0, \t0
+       vld1.8          {\t2-\t3}, [bskey, :256]!
+       veor            \x1, \x1, \t1
+       vld1.8          {\t4-\t5}, [bskey, :256]!
+       veor            \x2, \x2, \t2
+       vld1.8          {\t6-\t7}, [bskey, :256]
+       sub             bskey, bskey, #224
+       veor            \x3, \x3, \t3
+       veor            \x4, \x4, \t4
+       veor            \x5, \x5, \t5
+       veor            \x6, \x6, \t6
+       veor            \x7, \x7, \t7
+       vext.8          \t0, \x0, \x0, #8
+       vext.8          \t6, \x6, \x6, #8
+       vext.8          \t7, \x7, \x7, #8
+       veor            \t0, \t0, \x0
+       vext.8          \t1, \x1, \x1, #8
+       veor            \t6, \t6, \x6
+       vext.8          \t2, \x2, \x2, #8
+       veor            \t7, \t7, \x7
+       vext.8          \t3, \x3, \x3, #8
+       veor            \t1, \t1, \x1
+       vext.8          \t4, \x4, \x4, #8
+       veor            \t2, \t2, \x2
+       vext.8          \t5, \x5, \x5, #8
+       veor            \t3, \t3, \x3
+       veor            \t4, \t4, \x4
+       veor            \t5, \t5, \x5
+       veor            \x0, \x0, \t6
+       veor            \x1, \x1, \t6
+       veor            \x2, \x2, \t0
+       veor            \x4, \x4, \t2
+       veor            \x3, \x3, \t1
+       veor            \x1, \x1, \t7
+       veor            \x2, \x2, \t7
+       veor            \x4, \x4, \t6
+       veor            \x5, \x5, \t3
+       veor            \x3, \x3, \t6
+       veor            \x6, \x6, \t4
+       veor            \x4, \x4, \t7
+       veor            \x5, \x5, \t7
+       veor            \x7, \x7, \t5
+       mix_cols        \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \
+                       \t0, \t1, \t2, \t3, \t4, \t5, \t6, \t7, 1
+       .endm
+
+       .macro          swapmove_2x, a0, b0, a1, b1, n, mask, t0, t1
+       vshr.u64        \t0, \b0, #\n
+       vshr.u64        \t1, \b1, #\n
+       veor            \t0, \t0, \a0
+       veor            \t1, \t1, \a1
+       vand            \t0, \t0, \mask
+       vand            \t1, \t1, \mask
+       veor            \a0, \a0, \t0
+       vshl.s64        \t0, \t0, #\n
+       veor            \a1, \a1, \t1
+       vshl.s64        \t1, \t1, #\n
+       veor            \b0, \b0, \t0
+       veor            \b1, \b1, \t1
+       .endm
+
+       .macro          bitslice, x7, x6, x5, x4, x3, x2, x1, x0, t0, t1, t2, t3
+       vmov.i8         \t0, #0x55
+       vmov.i8         \t1, #0x33
+       swapmove_2x     \x0, \x1, \x2, \x3, 1, \t0, \t2, \t3
+       swapmove_2x     \x4, \x5, \x6, \x7, 1, \t0, \t2, \t3
+       vmov.i8         \t0, #0x0f
+       swapmove_2x     \x0, \x2, \x1, \x3, 2, \t1, \t2, \t3
+       swapmove_2x     \x4, \x6, \x5, \x7, 2, \t1, \t2, \t3
+       swapmove_2x     \x0, \x4, \x1, \x5, 4, \t0, \t2, \t3
+       swapmove_2x     \x2, \x6, \x3, \x7, 4, \t0, \t2, \t3
+       .endm
+
+       .align          4
+M0:    .quad           0x02060a0e03070b0f, 0x0004080c0105090d
+
+       /*
+        * void aesbs_convert_key(u8 out[], u32 const rk[], int rounds)
+        */
+ENTRY(aesbs_convert_key)
+       vld1.32         {q7}, [r1]!             // load round 0 key
+       vld1.32         {q15}, [r1]!            // load round 1 key
+
+       vmov.i8         q8,  #0x01              // bit masks
+       vmov.i8         q9,  #0x02
+       vmov.i8         q10, #0x04
+       vmov.i8         q11, #0x08
+       vmov.i8         q12, #0x10
+       vmov.i8         q13, #0x20
+       __ldr           q14, M0
+
+       sub             r2, r2, #1
+       vst1.8          {q7}, [r0, :128]!       // save round 0 key
+
+.Lkey_loop:
+       __tbl           q7, q15, q14
+       vmov.i8         q6, #0x40
+       vmov.i8         q15, #0x80
+
+       vtst.8          q0, q7, q8
+       vtst.8          q1, q7, q9
+       vtst.8          q2, q7, q10
+       vtst.8          q3, q7, q11
+       vtst.8          q4, q7, q12
+       vtst.8          q5, q7, q13
+       vtst.8          q6, q7, q6
+       vtst.8          q7, q7, q15
+       vld1.32         {q15}, [r1]!            // load next round key
+       vmvn            q0, q0
+       vmvn            q1, q1
+       vmvn            q5, q5
+       vmvn            q6, q6
+
+       subs            r2, r2, #1
+       vst1.8          {q0-q1}, [r0, :256]!
+       vst1.8          {q2-q3}, [r0, :256]!
+       vst1.8          {q4-q5}, [r0, :256]!
+       vst1.8          {q6-q7}, [r0, :256]!
+       bne             .Lkey_loop
+
+       vmov.i8         q7, #0x63               // compose .L63
+       veor            q15, q15, q7
+       vst1.8          {q15}, [r0, :128]
+       bx              lr
+ENDPROC(aesbs_convert_key)
+
+       .align          4
+M0SR:  .quad           0x0a0e02060f03070b, 0x0004080c05090d01
+
+aesbs_encrypt8:
+       vld1.8          {q9}, [bskey, :128]!    // round 0 key
+       __ldr           q8, M0SR
+
+       veor            q10, q0, q9             // xor with round0 key
+       veor            q11, q1, q9
+       __tbl           q0, q10, q8
+       veor            q12, q2, q9
+       __tbl           q1, q11, q8
+       veor            q13, q3, q9
+       __tbl           q2, q12, q8
+       veor            q14, q4, q9
+       __tbl           q3, q13, q8
+       veor            q15, q5, q9
+       __tbl           q4, q14, q8
+       veor            q10, q6, q9
+       __tbl           q5, q15, q8
+       veor            q11, q7, q9
+       __tbl           q6, q10, q8
+       __tbl           q7, q11, q8
+
+       bitslice        q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11
+
+       sub             rounds, rounds, #1
+       b               .Lenc_sbox
+
+       .align          5
+SR:    .quad           0x0504070600030201, 0x0f0e0d0c0a09080b
+SRM0:  .quad           0x0304090e00050a0f, 0x01060b0c0207080d
+
+.Lenc_last:
+       __ldr           q12, SRM0
+.Lenc_loop:
+       shift_rows      q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12
+.Lenc_sbox:
+       sbox            q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12, \
+                                                               q13, q14, q15
+       subs            rounds, rounds, #1
+       bcc             .Lenc_done
+
+       mix_cols        q0, q1, q4, q6, q3, q7, q2, q5, q8, q9, q10, q11, q12, \
+                                                               q13, q14, q15
+
+       beq             .Lenc_last
+       __ldr           q12, SR
+       b               .Lenc_loop
+
+.Lenc_done:
+       vld1.8          {q12}, [bskey, :128]    // last round key
+
+       bitslice        q0, q1, q4, q6, q3, q7, q2, q5, q8, q9, q10, q11
+
+       veor            q0, q0, q12
+       veor            q1, q1, q12
+       veor            q4, q4, q12
+       veor            q6, q6, q12
+       veor            q3, q3, q12
+       veor            q7, q7, q12
+       veor            q2, q2, q12
+       veor            q5, q5, q12
+       bx              lr
+ENDPROC(aesbs_encrypt8)
+
+       .align          4
+M0ISR: .quad           0x0a0e0206070b0f03, 0x0004080c0d010509
+
+aesbs_decrypt8:
+       add             bskey, bskey, rounds, lsl #7
+       sub             bskey, bskey, #112
+       vld1.8          {q9}, [bskey, :128]     // round 0 key
+       sub             bskey, bskey, #128
+       __ldr           q8, M0ISR
+
+       veor            q10, q0, q9             // xor with round0 key
+       veor            q11, q1, q9
+       __tbl           q0, q10, q8
+       veor            q12, q2, q9
+       __tbl           q1, q11, q8
+       veor            q13, q3, q9
+       __tbl           q2, q12, q8
+       veor            q14, q4, q9
+       __tbl           q3, q13, q8
+       veor            q15, q5, q9
+       __tbl           q4, q14, q8
+       veor            q10, q6, q9
+       __tbl           q5, q15, q8
+       veor            q11, q7, q9
+       __tbl           q6, q10, q8
+       __tbl           q7, q11, q8
+
+       bitslice        q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11
+
+       sub             rounds, rounds, #1
+       b               .Ldec_sbox
+
+       .align          5
+ISR:   .quad           0x0504070602010003, 0x0f0e0d0c080b0a09
+ISRM0: .quad           0x01040b0e0205080f, 0x0306090c00070a0d
+
+.Ldec_last:
+       __ldr           q12, ISRM0
+.Ldec_loop:
+       inv_shift_rows  q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12
+.Ldec_sbox:
+       inv_sbox        q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12, \
+                                                               q13, q14, q15
+       subs            rounds, rounds, #1
+       bcc             .Ldec_done
+
+       inv_mix_cols    q0, q1, q6, q4, q2, q7, q3, q5, q8, q9, q10, q11, q12, \
+                                                               q13, q14, q15
+
+       beq             .Ldec_last
+       __ldr           q12, ISR
+       b               .Ldec_loop
+
+.Ldec_done:
+       add             bskey, bskey, #112
+       vld1.8          {q12}, [bskey, :128]    // last round key
+
+       bitslice        q0, q1, q6, q4, q2, q7, q3, q5, q8, q9, q10, q11
+
+       veor            q0, q0, q12
+       veor            q1, q1, q12
+       veor            q6, q6, q12
+       veor            q4, q4, q12
+       veor            q2, q2, q12
+       veor            q7, q7, q12
+       veor            q3, q3, q12
+       veor            q5, q5, q12
+       bx              lr
+ENDPROC(aesbs_decrypt8)
+
+       /*
+        * aesbs_ecb_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
+        *                   int blocks)
+        * aesbs_ecb_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
+        *                   int blocks)
+        */
+       .macro          __ecb_crypt, do8, o0, o1, o2, o3, o4, o5, o6, o7
+       push            {r4-r6, lr}
+       ldr             r5, [sp, #16]           // number of blocks
+
+99:    __adr           ip, 0f
+       and             lr, r5, #7
+       cmp             r5, #8
+       sub             ip, ip, lr, lsl #2
+       bxlt            ip                      // computed goto if blocks < 8
+
+       vld1.8          {q0}, [r1]!
+       vld1.8          {q1}, [r1]!
+       vld1.8          {q2}, [r1]!
+       vld1.8          {q3}, [r1]!
+       vld1.8          {q4}, [r1]!
+       vld1.8          {q5}, [r1]!
+       vld1.8          {q6}, [r1]!
+       vld1.8          {q7}, [r1]!
+
+0:     mov             bskey, r2
+       mov             rounds, r3
+       bl              \do8
+
+       __adr           ip, 1f
+       and             lr, r5, #7
+       cmp             r5, #8
+       sub             ip, ip, lr, lsl #2
+       bxlt            ip                      // computed goto if blocks < 8
+
+       vst1.8          {\o0}, [r0]!
+       vst1.8          {\o1}, [r0]!
+       vst1.8          {\o2}, [r0]!
+       vst1.8          {\o3}, [r0]!
+       vst1.8          {\o4}, [r0]!
+       vst1.8          {\o5}, [r0]!
+       vst1.8          {\o6}, [r0]!
+       vst1.8          {\o7}, [r0]!
+
+1:     subs            r5, r5, #8
+       bgt             99b
+
+       pop             {r4-r6, pc}
+       .endm
+
+       .align          4
+ENTRY(aesbs_ecb_encrypt)
+       __ecb_crypt     aesbs_encrypt8, q0, q1, q4, q6, q3, q7, q2, q5
+ENDPROC(aesbs_ecb_encrypt)
+
+       .align          4
+ENTRY(aesbs_ecb_decrypt)
+       __ecb_crypt     aesbs_decrypt8, q0, q1, q6, q4, q2, q7, q3, q5
+ENDPROC(aesbs_ecb_decrypt)
+
+       /*
+        * aesbs_cbc_decrypt(u8 out[], u8 const in[], u8 const rk[],
+        *                   int rounds, int blocks, u8 iv[])
+        */
+       .align          4
+ENTRY(aesbs_cbc_decrypt)
+       mov             ip, sp
+       push            {r4-r6, lr}
+       ldm             ip, {r5-r6}             // load args 4-5
+
+99:    __adr           ip, 0f
+       and             lr, r5, #7
+       cmp             r5, #8
+       sub             ip, ip, lr, lsl #2
+       mov             lr, r1
+       bxlt            ip                      // computed goto if blocks < 8
+
+       vld1.8          {q0}, [lr]!
+       vld1.8          {q1}, [lr]!
+       vld1.8          {q2}, [lr]!
+       vld1.8          {q3}, [lr]!
+       vld1.8          {q4}, [lr]!
+       vld1.8          {q5}, [lr]!
+       vld1.8          {q6}, [lr]!
+       vld1.8          {q7}, [lr]
+
+0:     mov             bskey, r2
+       mov             rounds, r3
+       bl              aesbs_decrypt8
+
+       vld1.8          {q8}, [r6]
+       vmov            q9, q8
+       vmov            q10, q8
+       vmov            q11, q8
+       vmov            q12, q8
+       vmov            q13, q8
+       vmov            q14, q8
+       vmov            q15, q8
+
+       __adr           ip, 1f
+       and             lr, r5, #7
+       cmp             r5, #8
+       sub             ip, ip, lr, lsl #2
+       bxlt            ip                      // computed goto if blocks < 8
+
+       vld1.8          {q9}, [r1]!
+       vld1.8          {q10}, [r1]!
+       vld1.8          {q11}, [r1]!
+       vld1.8          {q12}, [r1]!
+       vld1.8          {q13}, [r1]!
+       vld1.8          {q14}, [r1]!
+       vld1.8          {q15}, [r1]!
+       W(nop)
+
+1:     __adr           ip, 2f
+       sub             ip, ip, lr, lsl #3
+       bxlt            ip                      // computed goto if blocks < 8
+
+       veor            q0, q0, q8
+       vst1.8          {q0}, [r0]!
+       veor            q1, q1, q9
+       vst1.8          {q1}, [r0]!
+       veor            q6, q6, q10
+       vst1.8          {q6}, [r0]!
+       veor            q4, q4, q11
+       vst1.8          {q4}, [r0]!
+       veor            q2, q2, q12
+       vst1.8          {q2}, [r0]!
+       veor            q7, q7, q13
+       vst1.8          {q7}, [r0]!
+       veor            q3, q3, q14
+       vst1.8          {q3}, [r0]!
+       veor            q5, q5, q15
+       vld1.8          {q8}, [r1]!             // load next round's iv
+2:     vst1.8          {q5}, [r0]!
+
+       subs            r5, r5, #8
+       vst1.8          {q8}, [r6]              // store next round's iv
+       bgt             99b
+
+       pop             {r4-r6, pc}
+ENDPROC(aesbs_cbc_decrypt)
+
+       .macro          next_ctr, q
+       vmov            \q\()h[1], r10
+       adds            r10, r10, #1
+       vmov            \q\()h[0], r9
+       adcs            r9, r9, #0
+       vmov            \q\()l[1], r8
+       adcs            r8, r8, #0
+       vmov            \q\()l[0], r7
+       adc             r7, r7, #0
+       vrev32.8        \q, \q
+       .endm
+
+       /*
+        * aesbs_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[],
+        *                   int rounds, int blocks, u8 ctr[], bool final)
+        */
+ENTRY(aesbs_ctr_encrypt)
+       mov             ip, sp
+       push            {r4-r10, lr}
+
+       ldm             ip, {r5-r7}             // load args 4-6
+       add             r5, r5, r7              // one extra block if final == 1
+
+       vld1.8          {q0}, [r6]              // load counter
+       vrev32.8        q1, q0
+       vmov            r9, r10, d3
+       vmov            r7, r8, d2
+
+       adds            r10, r10, #1
+       adcs            r9, r9, #0
+       adcs            r8, r8, #0
+       adc             r7, r7, #0
+
+99:    vmov            q1, q0
+       vmov            q2, q0
+       vmov            q3, q0
+       vmov            q4, q0
+       vmov            q5, q0
+       vmov            q6, q0
+       vmov            q7, q0
+
+       __adr           ip, 0f
+       sub             lr, r5, #1
+       and             lr, lr, #7
+       cmp             r5, #8
+       sub             ip, ip, lr, lsl #5
+       sub             ip, ip, lr, lsl #2
+       bxlt            ip                      // computed goto if blocks < 8
+
+       next_ctr        q1
+       next_ctr        q2
+       next_ctr        q3
+       next_ctr        q4
+       next_ctr        q5
+       next_ctr        q6
+       next_ctr        q7
+
+0:     mov             bskey, r2
+       mov             rounds, r3
+       bl              aesbs_encrypt8
+
+       __adr           ip, 1f
+       and             lr, r5, #7
+       cmp             r5, #8
+       movgt           r4, #0
+       ldrle           r4, [sp, #40]           // load final in the last round
+       sub             ip, ip, lr, lsl #2
+       bxlt            ip                      // computed goto if blocks < 8
+
+       vld1.8          {q8}, [r1]!
+       vld1.8          {q9}, [r1]!
+       vld1.8          {q10}, [r1]!
+       vld1.8          {q11}, [r1]!
+       vld1.8          {q12}, [r1]!
+       vld1.8          {q13}, [r1]!
+       vld1.8          {q14}, [r1]!
+       teq             r4, #0                  // skip last block if 'final'
+1:     bne             2f
+       vld1.8          {q15}, [r1]!
+
+2:     __adr           ip, 3f
+       cmp             r5, #8
+       sub             ip, ip, lr, lsl #3
+       bxlt            ip                      // computed goto if blocks < 8
+
+       veor            q0, q0, q8
+       vst1.8          {q0}, [r0]!
+       veor            q1, q1, q9
+       vst1.8          {q1}, [r0]!
+       veor            q4, q4, q10
+       vst1.8          {q4}, [r0]!
+       veor            q6, q6, q11
+       vst1.8          {q6}, [r0]!
+       veor            q3, q3, q12
+       vst1.8          {q3}, [r0]!
+       veor            q7, q7, q13
+       vst1.8          {q7}, [r0]!
+       veor            q2, q2, q14
+       vst1.8          {q2}, [r0]!
+       teq             r4, #0                  // skip last block if 'final'
+       W(bne)          4f
+3:     veor            q5, q5, q15
+       vst1.8          {q5}, [r0]!
+
+       next_ctr        q0
+
+       subs            r5, r5, #8
+       bgt             99b
+
+       vmov            q5, q0
+
+4:     vst1.8          {q5}, [r6]
+       pop             {r4-r10, pc}
+ENDPROC(aesbs_ctr_encrypt)
+
+       .macro          next_tweak, out, in, const, tmp
+       vshr.s64        \tmp, \in, #63
+       vand            \tmp, \tmp, \const
+       vadd.u64        \out, \in, \in
+       vext.8          \tmp, \tmp, \tmp, #8
+       veor            \out, \out, \tmp
+       .endm
+
+       .align          4
+.Lxts_mul_x:
+       .quad           1, 0x87
+
+       /*
+        * aesbs_xts_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
+        *                   int blocks, u8 iv[])
+        * aesbs_xts_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
+        *                   int blocks, u8 iv[])
+        */
+__xts_prepare8:
+       vld1.8          {q14}, [r7]             // load iv
+       __ldr           q15, .Lxts_mul_x        // load tweak mask
+       vmov            q12, q14
+
+       __adr           ip, 0f
+       and             r4, r6, #7
+       cmp             r6, #8
+       sub             ip, ip, r4, lsl #5
+       mov             r4, sp
+       bxlt            ip                      // computed goto if blocks < 8
+
+       vld1.8          {q0}, [r1]!
+       next_tweak      q12, q14, q15, q13
+       veor            q0, q0, q14
+       vst1.8          {q14}, [r4, :128]!
+
+       vld1.8          {q1}, [r1]!
+       next_tweak      q14, q12, q15, q13
+       veor            q1, q1, q12
+       vst1.8          {q12}, [r4, :128]!
+
+       vld1.8          {q2}, [r1]!
+       next_tweak      q12, q14, q15, q13
+       veor            q2, q2, q14
+       vst1.8          {q14}, [r4, :128]!
+
+       vld1.8          {q3}, [r1]!
+       next_tweak      q14, q12, q15, q13
+       veor            q3, q3, q12
+       vst1.8          {q12}, [r4, :128]!
+
+       vld1.8          {q4}, [r1]!
+       next_tweak      q12, q14, q15, q13
+       veor            q4, q4, q14
+       vst1.8          {q14}, [r4, :128]!
+
+       vld1.8          {q5}, [r1]!
+       next_tweak      q14, q12, q15, q13
+       veor            q5, q5, q12
+       vst1.8          {q12}, [r4, :128]!
+
+       vld1.8          {q6}, [r1]!
+       next_tweak      q12, q14, q15, q13
+       veor            q6, q6, q14
+       vst1.8          {q14}, [r4, :128]!
+
+       vld1.8          {q7}, [r1]!
+       next_tweak      q14, q12, q15, q13
+       veor            q7, q7, q12
+       vst1.8          {q12}, [r4, :128]
+
+0:     vst1.8          {q14}, [r7]             // store next iv
+       bx              lr
+ENDPROC(__xts_prepare8)
+
+       .macro          __xts_crypt, do8, o0, o1, o2, o3, o4, o5, o6, o7
+       push            {r4-r8, lr}
+       mov             r5, sp                  // preserve sp
+       ldrd            r6, r7, [sp, #24]       // get blocks and iv args
+       sub             ip, sp, #128            // make room for 8x tweak
+       bic             ip, ip, #0xf            // align sp to 16 bytes
+       mov             sp, ip
+
+99:    bl              __xts_prepare8
+
+       mov             bskey, r2
+       mov             rounds, r3
+       bl              \do8
+
+       __adr           ip, 0f
+       and             lr, r6, #7
+       cmp             r6, #8
+       sub             ip, ip, lr, lsl #2
+       mov             r4, sp
+       bxlt            ip                      // computed goto if blocks < 8
+
+       vld1.8          {q8}, [r4, :128]!
+       vld1.8          {q9}, [r4, :128]!
+       vld1.8          {q10}, [r4, :128]!
+       vld1.8          {q11}, [r4, :128]!
+       vld1.8          {q12}, [r4, :128]!
+       vld1.8          {q13}, [r4, :128]!
+       vld1.8          {q14}, [r4, :128]!
+       vld1.8          {q15}, [r4, :128]
+
+0:     __adr           ip, 1f
+       sub             ip, ip, lr, lsl #3
+       bxlt            ip                      // computed goto if blocks < 8
+
+       veor            \o0, \o0, q8
+       vst1.8          {\o0}, [r0]!
+       veor            \o1, \o1, q9
+       vst1.8          {\o1}, [r0]!
+       veor            \o2, \o2, q10
+       vst1.8          {\o2}, [r0]!
+       veor            \o3, \o3, q11
+       vst1.8          {\o3}, [r0]!
+       veor            \o4, \o4, q12
+       vst1.8          {\o4}, [r0]!
+       veor            \o5, \o5, q13
+       vst1.8          {\o5}, [r0]!
+       veor            \o6, \o6, q14
+       vst1.8          {\o6}, [r0]!
+       veor            \o7, \o7, q15
+       vst1.8          {\o7}, [r0]!
+
+1:     subs            r6, r6, #8
+       bgt             99b
+
+       mov             sp, r5
+       pop             {r4-r8, pc}
+       .endm
+
+ENTRY(aesbs_xts_encrypt)
+       __xts_crypt     aesbs_encrypt8, q0, q1, q4, q6, q3, q7, q2, q5
+ENDPROC(aesbs_xts_encrypt)
+
+ENTRY(aesbs_xts_decrypt)
+       __xts_crypt     aesbs_decrypt8, q0, q1, q6, q4, q2, q7, q3, q5
+ENDPROC(aesbs_xts_decrypt)
diff --git a/arch/arm/crypto/aes-neonbs-glue.c b/arch/arm/crypto/aes-neonbs-glue.c
new file mode 100644 (file)
index 0000000..e262f99
--- /dev/null
@@ -0,0 +1,405 @@
+/*
+ * Bit sliced AES using NEON instructions
+ *
+ * Copyright (C) 2017 Linaro Ltd <ard.biesheuvel@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <asm/neon.h>
+#include <crypto/aes.h>
+#include <crypto/cbc.h>
+#include <crypto/internal/simd.h>
+#include <crypto/internal/skcipher.h>
+#include <crypto/xts.h>
+#include <linux/module.h>
+
+MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
+MODULE_LICENSE("GPL v2");
+
+MODULE_ALIAS_CRYPTO("ecb(aes)");
+MODULE_ALIAS_CRYPTO("cbc(aes)");
+MODULE_ALIAS_CRYPTO("ctr(aes)");
+MODULE_ALIAS_CRYPTO("xts(aes)");
+
+asmlinkage void aesbs_convert_key(u8 out[], u32 const rk[], int rounds);
+
+asmlinkage void aesbs_ecb_encrypt(u8 out[], u8 const in[], u8 const rk[],
+                                 int rounds, int blocks);
+asmlinkage void aesbs_ecb_decrypt(u8 out[], u8 const in[], u8 const rk[],
+                                 int rounds, int blocks);
+
+asmlinkage void aesbs_cbc_decrypt(u8 out[], u8 const in[], u8 const rk[],
+                                 int rounds, int blocks, u8 iv[]);
+
+asmlinkage void aesbs_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[],
+                                 int rounds, int blocks, u8 ctr[], bool final);
+
+asmlinkage void aesbs_xts_encrypt(u8 out[], u8 const in[], u8 const rk[],
+                                 int rounds, int blocks, u8 iv[]);
+asmlinkage void aesbs_xts_decrypt(u8 out[], u8 const in[], u8 const rk[],
+                                 int rounds, int blocks, u8 iv[]);
+
+asmlinkage void __aes_arm_encrypt(const u32 rk[], int rounds, const u8 in[],
+                                 u8 out[]);
+
+struct aesbs_ctx {
+       int     rounds;
+       u8      rk[13 * (8 * AES_BLOCK_SIZE) + 32] __aligned(AES_BLOCK_SIZE);
+};
+
+struct aesbs_cbc_ctx {
+       struct aesbs_ctx        key;
+       u32                     enc[AES_MAX_KEYLENGTH_U32];
+};
+
+struct aesbs_xts_ctx {
+       struct aesbs_ctx        key;
+       u32                     twkey[AES_MAX_KEYLENGTH_U32];
+};
+
+static int aesbs_setkey(struct crypto_skcipher *tfm, const u8 *in_key,
+                       unsigned int key_len)
+{
+       struct aesbs_ctx *ctx = crypto_skcipher_ctx(tfm);
+       struct crypto_aes_ctx rk;
+       int err;
+
+       err = crypto_aes_expand_key(&rk, in_key, key_len);
+       if (err)
+               return err;
+
+       ctx->rounds = 6 + key_len / 4;
+
+       kernel_neon_begin();
+       aesbs_convert_key(ctx->rk, rk.key_enc, ctx->rounds);
+       kernel_neon_end();
+
+       return 0;
+}
+
+static int __ecb_crypt(struct skcipher_request *req,
+                      void (*fn)(u8 out[], u8 const in[], u8 const rk[],
+                                 int rounds, int blocks))
+{
+       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+       struct aesbs_ctx *ctx = crypto_skcipher_ctx(tfm);
+       struct skcipher_walk walk;
+       int err;
+
+       err = skcipher_walk_virt(&walk, req, true);
+
+       kernel_neon_begin();
+       while (walk.nbytes >= AES_BLOCK_SIZE) {
+               unsigned int blocks = walk.nbytes / AES_BLOCK_SIZE;
+
+               if (walk.nbytes < walk.total)
+                       blocks = round_down(blocks,
+                                           walk.stride / AES_BLOCK_SIZE);
+
+               fn(walk.dst.virt.addr, walk.src.virt.addr, ctx->rk,
+                  ctx->rounds, blocks);
+               err = skcipher_walk_done(&walk,
+                                        walk.nbytes - blocks * AES_BLOCK_SIZE);
+       }
+       kernel_neon_end();
+
+       return err;
+}
+
+static int ecb_encrypt(struct skcipher_request *req)
+{
+       return __ecb_crypt(req, aesbs_ecb_encrypt);
+}
+
+static int ecb_decrypt(struct skcipher_request *req)
+{
+       return __ecb_crypt(req, aesbs_ecb_decrypt);
+}
+
+static int aesbs_cbc_setkey(struct crypto_skcipher *tfm, const u8 *in_key,
+                           unsigned int key_len)
+{
+       struct aesbs_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
+       struct crypto_aes_ctx rk;
+       int err;
+
+       err = crypto_aes_expand_key(&rk, in_key, key_len);
+       if (err)
+               return err;
+
+       ctx->key.rounds = 6 + key_len / 4;
+
+       memcpy(ctx->enc, rk.key_enc, sizeof(ctx->enc));
+
+       kernel_neon_begin();
+       aesbs_convert_key(ctx->key.rk, rk.key_enc, ctx->key.rounds);
+       kernel_neon_end();
+
+       return 0;
+}
+
+static void cbc_encrypt_one(struct crypto_skcipher *tfm, const u8 *src, u8 *dst)
+{
+       struct aesbs_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
+
+       __aes_arm_encrypt(ctx->enc, ctx->key.rounds, src, dst);
+}
+
+static int cbc_encrypt(struct skcipher_request *req)
+{
+       return crypto_cbc_encrypt_walk(req, cbc_encrypt_one);
+}
+
+static int cbc_decrypt(struct skcipher_request *req)
+{
+       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+       struct aesbs_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
+       struct skcipher_walk walk;
+       int err;
+
+       err = skcipher_walk_virt(&walk, req, true);
+
+       kernel_neon_begin();
+       while (walk.nbytes >= AES_BLOCK_SIZE) {
+               unsigned int blocks = walk.nbytes / AES_BLOCK_SIZE;
+
+               if (walk.nbytes < walk.total)
+                       blocks = round_down(blocks,
+                                           walk.stride / AES_BLOCK_SIZE);
+
+               aesbs_cbc_decrypt(walk.dst.virt.addr, walk.src.virt.addr,
+                                 ctx->key.rk, ctx->key.rounds, blocks,
+                                 walk.iv);
+               err = skcipher_walk_done(&walk,
+                                        walk.nbytes - blocks * AES_BLOCK_SIZE);
+       }
+       kernel_neon_end();
+
+       return err;
+}
+
+static int ctr_encrypt(struct skcipher_request *req)
+{
+       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+       struct aesbs_ctx *ctx = crypto_skcipher_ctx(tfm);
+       struct skcipher_walk walk;
+       int err;
+
+       err = skcipher_walk_virt(&walk, req, true);
+
+       kernel_neon_begin();
+       while (walk.nbytes > 0) {
+               unsigned int blocks = walk.nbytes / AES_BLOCK_SIZE;
+               bool final = (walk.total % AES_BLOCK_SIZE) != 0;
+
+               if (walk.nbytes < walk.total) {
+                       blocks = round_down(blocks,
+                                           walk.stride / AES_BLOCK_SIZE);
+                       final = false;
+               }
+
+               aesbs_ctr_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
+                                 ctx->rk, ctx->rounds, blocks, walk.iv, final);
+
+               if (final) {
+                       u8 *dst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE;
+                       u8 *src = walk.src.virt.addr + blocks * AES_BLOCK_SIZE;
+
+                       if (dst != src)
+                               memcpy(dst, src, walk.total % AES_BLOCK_SIZE);
+                       crypto_xor(dst, walk.iv, walk.total % AES_BLOCK_SIZE);
+
+                       err = skcipher_walk_done(&walk, 0);
+                       break;
+               }
+               err = skcipher_walk_done(&walk,
+                                        walk.nbytes - blocks * AES_BLOCK_SIZE);
+       }
+       kernel_neon_end();
+
+       return err;
+}
+
+static int aesbs_xts_setkey(struct crypto_skcipher *tfm, const u8 *in_key,
+                           unsigned int key_len)
+{
+       struct aesbs_xts_ctx *ctx = crypto_skcipher_ctx(tfm);
+       struct crypto_aes_ctx rk;
+       int err;
+
+       err = xts_verify_key(tfm, in_key, key_len);
+       if (err)
+               return err;
+
+       key_len /= 2;
+       err = crypto_aes_expand_key(&rk, in_key + key_len, key_len);
+       if (err)
+               return err;
+
+       memcpy(ctx->twkey, rk.key_enc, sizeof(ctx->twkey));
+
+       return aesbs_setkey(tfm, in_key, key_len);
+}
+
+static int __xts_crypt(struct skcipher_request *req,
+                      void (*fn)(u8 out[], u8 const in[], u8 const rk[],
+                                 int rounds, int blocks, u8 iv[]))
+{
+       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+       struct aesbs_xts_ctx *ctx = crypto_skcipher_ctx(tfm);
+       struct skcipher_walk walk;
+       int err;
+
+       err = skcipher_walk_virt(&walk, req, true);
+
+       __aes_arm_encrypt(ctx->twkey, ctx->key.rounds, walk.iv, walk.iv);
+
+       kernel_neon_begin();
+       while (walk.nbytes >= AES_BLOCK_SIZE) {
+               unsigned int blocks = walk.nbytes / AES_BLOCK_SIZE;
+
+               if (walk.nbytes < walk.total)
+                       blocks = round_down(blocks,
+                                           walk.stride / AES_BLOCK_SIZE);
+
+               fn(walk.dst.virt.addr, walk.src.virt.addr, ctx->key.rk,
+                  ctx->key.rounds, blocks, walk.iv);
+               err = skcipher_walk_done(&walk,
+                                        walk.nbytes - blocks * AES_BLOCK_SIZE);
+       }
+       kernel_neon_end();
+
+       return err;
+}
+
+static int xts_encrypt(struct skcipher_request *req)
+{
+       return __xts_crypt(req, aesbs_xts_encrypt);
+}
+
+static int xts_decrypt(struct skcipher_request *req)
+{
+       return __xts_crypt(req, aesbs_xts_decrypt);
+}
+
+static struct skcipher_alg aes_algs[] = { {
+       .base.cra_name          = "__ecb(aes)",
+       .base.cra_driver_name   = "__ecb-aes-neonbs",
+       .base.cra_priority      = 250,
+       .base.cra_blocksize     = AES_BLOCK_SIZE,
+       .base.cra_ctxsize       = sizeof(struct aesbs_ctx),
+       .base.cra_module        = THIS_MODULE,
+       .base.cra_flags         = CRYPTO_ALG_INTERNAL,
+
+       .min_keysize            = AES_MIN_KEY_SIZE,
+       .max_keysize            = AES_MAX_KEY_SIZE,
+       .walksize               = 8 * AES_BLOCK_SIZE,
+       .setkey                 = aesbs_setkey,
+       .encrypt                = ecb_encrypt,
+       .decrypt                = ecb_decrypt,
+}, {
+       .base.cra_name          = "__cbc(aes)",
+       .base.cra_driver_name   = "__cbc-aes-neonbs",
+       .base.cra_priority      = 250,
+       .base.cra_blocksize     = AES_BLOCK_SIZE,
+       .base.cra_ctxsize       = sizeof(struct aesbs_cbc_ctx),
+       .base.cra_module        = THIS_MODULE,
+       .base.cra_flags         = CRYPTO_ALG_INTERNAL,
+
+       .min_keysize            = AES_MIN_KEY_SIZE,
+       .max_keysize            = AES_MAX_KEY_SIZE,
+       .walksize               = 8 * AES_BLOCK_SIZE,
+       .ivsize                 = AES_BLOCK_SIZE,
+       .setkey                 = aesbs_cbc_setkey,
+       .encrypt                = cbc_encrypt,
+       .decrypt                = cbc_decrypt,
+}, {
+       .base.cra_name          = "__ctr(aes)",
+       .base.cra_driver_name   = "__ctr-aes-neonbs",
+       .base.cra_priority      = 250,
+       .base.cra_blocksize     = 1,
+       .base.cra_ctxsize       = sizeof(struct aesbs_ctx),
+       .base.cra_module        = THIS_MODULE,
+       .base.cra_flags         = CRYPTO_ALG_INTERNAL,
+
+       .min_keysize            = AES_MIN_KEY_SIZE,
+       .max_keysize            = AES_MAX_KEY_SIZE,
+       .chunksize              = AES_BLOCK_SIZE,
+       .walksize               = 8 * AES_BLOCK_SIZE,
+       .ivsize                 = AES_BLOCK_SIZE,
+       .setkey                 = aesbs_setkey,
+       .encrypt                = ctr_encrypt,
+       .decrypt                = ctr_encrypt,
+}, {
+       .base.cra_name          = "__xts(aes)",
+       .base.cra_driver_name   = "__xts-aes-neonbs",
+       .base.cra_priority      = 250,
+       .base.cra_blocksize     = AES_BLOCK_SIZE,
+       .base.cra_ctxsize       = sizeof(struct aesbs_xts_ctx),
+       .base.cra_module        = THIS_MODULE,
+       .base.cra_flags         = CRYPTO_ALG_INTERNAL,
+
+       .min_keysize            = 2 * AES_MIN_KEY_SIZE,
+       .max_keysize            = 2 * AES_MAX_KEY_SIZE,
+       .walksize               = 8 * AES_BLOCK_SIZE,
+       .ivsize                 = AES_BLOCK_SIZE,
+       .setkey                 = aesbs_xts_setkey,
+       .encrypt                = xts_encrypt,
+       .decrypt                = xts_decrypt,
+} };
+
+static struct simd_skcipher_alg *aes_simd_algs[ARRAY_SIZE(aes_algs)];
+
+static void aes_exit(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(aes_simd_algs); i++)
+               if (aes_simd_algs[i])
+                       simd_skcipher_free(aes_simd_algs[i]);
+
+       crypto_unregister_skciphers(aes_algs, ARRAY_SIZE(aes_algs));
+}
+
+static int __init aes_init(void)
+{
+       struct simd_skcipher_alg *simd;
+       const char *basename;
+       const char *algname;
+       const char *drvname;
+       int err;
+       int i;
+
+       if (!(elf_hwcap & HWCAP_NEON))
+               return -ENODEV;
+
+       err = crypto_register_skciphers(aes_algs, ARRAY_SIZE(aes_algs));
+       if (err)
+               return err;
+
+       for (i = 0; i < ARRAY_SIZE(aes_algs); i++) {
+               if (!(aes_algs[i].base.cra_flags & CRYPTO_ALG_INTERNAL))
+                       continue;
+
+               algname = aes_algs[i].base.cra_name + 2;
+               drvname = aes_algs[i].base.cra_driver_name + 2;
+               basename = aes_algs[i].base.cra_driver_name;
+               simd = simd_skcipher_create_compat(algname, drvname, basename);
+               err = PTR_ERR(simd);
+               if (IS_ERR(simd))
+                       goto unregister_simds;
+
+               aes_simd_algs[i] = simd;
+       }
+       return 0;
+
+unregister_simds:
+       aes_exit();
+       return err;
+}
+
+module_init(aes_init);
+module_exit(aes_exit);
diff --git a/arch/arm/crypto/aes_glue.h b/arch/arm/crypto/aes_glue.h
deleted file mode 100644 (file)
index cca3e51..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-
-#define AES_MAXNR 14
-
-struct AES_KEY {
-       unsigned int rd_key[4 * (AES_MAXNR + 1)];
-       int rounds;
-};
-
-struct AES_CTX {
-       struct AES_KEY enc_key;
-       struct AES_KEY dec_key;
-};
-
-asmlinkage void AES_encrypt(const u8 *in, u8 *out, struct AES_KEY *ctx);
-asmlinkage void AES_decrypt(const u8 *in, u8 *out, struct AES_KEY *ctx);
-asmlinkage int private_AES_set_decrypt_key(const unsigned char *userKey,
-                                          const int bits, struct AES_KEY *key);
-asmlinkage int private_AES_set_encrypt_key(const unsigned char *userKey,
-                                          const int bits, struct AES_KEY *key);
diff --git a/arch/arm/crypto/aesbs-core.S_shipped b/arch/arm/crypto/aesbs-core.S_shipped
deleted file mode 100644 (file)
index 1d1800f..0000000
+++ /dev/null
@@ -1,2548 +0,0 @@
-
-@ ====================================================================
-@ Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
-@ project. The module is, however, dual licensed under OpenSSL and
-@ CRYPTOGAMS licenses depending on where you obtain it. For further
-@ details see http://www.openssl.org/~appro/cryptogams/.
-@
-@ Specific modes and adaptation for Linux kernel by Ard Biesheuvel
-@ <ard.biesheuvel@linaro.org>. Permission to use under GPL terms is
-@ granted.
-@ ====================================================================
-
-@ Bit-sliced AES for ARM NEON
-@
-@ February 2012.
-@
-@ This implementation is direct adaptation of bsaes-x86_64 module for
-@ ARM NEON. Except that this module is endian-neutral [in sense that
-@ it can be compiled for either endianness] by courtesy of vld1.8's
-@ neutrality. Initial version doesn't implement interface to OpenSSL,
-@ only low-level primitives and unsupported entry points, just enough
-@ to collect performance results, which for Cortex-A8 core are:
-@
-@ encrypt      19.5 cycles per byte processed with 128-bit key
-@ decrypt      22.1 cycles per byte processed with 128-bit key
-@ key conv.    440  cycles per 128-bit key/0.18 of 8x block
-@
-@ Snapdragon S4 encrypts byte in 17.6 cycles and decrypts in 19.7,
-@ which is [much] worse than anticipated (for further details see
-@ http://www.openssl.org/~appro/Snapdragon-S4.html).
-@
-@ Cortex-A15 manages in 14.2/16.1 cycles [when integer-only code
-@ manages in 20.0 cycles].
-@
-@ When comparing to x86_64 results keep in mind that NEON unit is
-@ [mostly] single-issue and thus can't [fully] benefit from
-@ instruction-level parallelism. And when comparing to aes-armv4
-@ results keep in mind key schedule conversion overhead (see
-@ bsaes-x86_64.pl for further details)...
-@
-@                                              <appro@openssl.org>
-
-@ April-August 2013
-@
-@ Add CBC, CTR and XTS subroutines, adapt for kernel use.
-@
-@                                      <ard.biesheuvel@linaro.org>
-
-#ifndef __KERNEL__
-# include "arm_arch.h"
-
-# define VFP_ABI_PUSH  vstmdb  sp!,{d8-d15}
-# define VFP_ABI_POP   vldmia  sp!,{d8-d15}
-# define VFP_ABI_FRAME 0x40
-#else
-# define VFP_ABI_PUSH
-# define VFP_ABI_POP
-# define VFP_ABI_FRAME 0
-# define BSAES_ASM_EXTENDED_KEY
-# define XTS_CHAIN_TWEAK
-# define __ARM_ARCH__ __LINUX_ARM_ARCH__
-# define __ARM_MAX_ARCH__ 7
-#endif
-
-#ifdef __thumb__
-# define adrl adr
-#endif
-
-#if __ARM_MAX_ARCH__>=7
-.arch  armv7-a
-.fpu   neon
-
-.text
-.syntax        unified         @ ARMv7-capable assembler is expected to handle this
-#ifdef __thumb2__
-.thumb
-#else
-.code   32
-#endif
-
-.type  _bsaes_decrypt8,%function
-.align 4
-_bsaes_decrypt8:
-       adr     r6,_bsaes_decrypt8
-       vldmia  r4!, {q9}               @ round 0 key
-       add     r6,r6,#.LM0ISR-_bsaes_decrypt8
-
-       vldmia  r6!, {q8}               @ .LM0ISR
-       veor    q10, q0, q9     @ xor with round0 key
-       veor    q11, q1, q9
-        vtbl.8 d0, {q10}, d16
-        vtbl.8 d1, {q10}, d17
-       veor    q12, q2, q9
-        vtbl.8 d2, {q11}, d16
-        vtbl.8 d3, {q11}, d17
-       veor    q13, q3, q9
-        vtbl.8 d4, {q12}, d16
-        vtbl.8 d5, {q12}, d17
-       veor    q14, q4, q9
-        vtbl.8 d6, {q13}, d16
-        vtbl.8 d7, {q13}, d17
-       veor    q15, q5, q9
-        vtbl.8 d8, {q14}, d16
-        vtbl.8 d9, {q14}, d17
-       veor    q10, q6, q9
-        vtbl.8 d10, {q15}, d16
-        vtbl.8 d11, {q15}, d17
-       veor    q11, q7, q9
-        vtbl.8 d12, {q10}, d16
-        vtbl.8 d13, {q10}, d17
-        vtbl.8 d14, {q11}, d16
-        vtbl.8 d15, {q11}, d17
-       vmov.i8 q8,#0x55                        @ compose .LBS0
-       vmov.i8 q9,#0x33                        @ compose .LBS1
-       vshr.u64        q10, q6, #1
-        vshr.u64       q11, q4, #1
-       veor            q10, q10, q7
-        veor           q11, q11, q5
-       vand            q10, q10, q8
-        vand           q11, q11, q8
-       veor            q7, q7, q10
-       vshl.u64        q10, q10, #1
-        veor           q5, q5, q11
-        vshl.u64       q11, q11, #1
-       veor            q6, q6, q10
-        veor           q4, q4, q11
-       vshr.u64        q10, q2, #1
-        vshr.u64       q11, q0, #1
-       veor            q10, q10, q3
-        veor           q11, q11, q1
-       vand            q10, q10, q8
-        vand           q11, q11, q8
-       veor            q3, q3, q10
-       vshl.u64        q10, q10, #1
-        veor           q1, q1, q11
-        vshl.u64       q11, q11, #1
-       veor            q2, q2, q10
-        veor           q0, q0, q11
-       vmov.i8 q8,#0x0f                        @ compose .LBS2
-       vshr.u64        q10, q5, #2
-        vshr.u64       q11, q4, #2
-       veor            q10, q10, q7
-        veor           q11, q11, q6
-       vand            q10, q10, q9
-        vand           q11, q11, q9
-       veor            q7, q7, q10
-       vshl.u64        q10, q10, #2
-        veor           q6, q6, q11
-        vshl.u64       q11, q11, #2
-       veor            q5, q5, q10
-        veor           q4, q4, q11
-       vshr.u64        q10, q1, #2
-        vshr.u64       q11, q0, #2
-       veor            q10, q10, q3
-        veor           q11, q11, q2
-       vand            q10, q10, q9
-        vand           q11, q11, q9
-       veor            q3, q3, q10
-       vshl.u64        q10, q10, #2
-        veor           q2, q2, q11
-        vshl.u64       q11, q11, #2
-       veor            q1, q1, q10
-        veor           q0, q0, q11
-       vshr.u64        q10, q3, #4
-        vshr.u64       q11, q2, #4
-       veor            q10, q10, q7
-        veor           q11, q11, q6
-       vand            q10, q10, q8
-        vand           q11, q11, q8
-       veor            q7, q7, q10
-       vshl.u64        q10, q10, #4
-        veor           q6, q6, q11
-        vshl.u64       q11, q11, #4
-       veor            q3, q3, q10
-        veor           q2, q2, q11
-       vshr.u64        q10, q1, #4
-        vshr.u64       q11, q0, #4
-       veor            q10, q10, q5
-        veor           q11, q11, q4
-       vand            q10, q10, q8
-        vand           q11, q11, q8
-       veor            q5, q5, q10
-       vshl.u64        q10, q10, #4
-        veor           q4, q4, q11
-        vshl.u64       q11, q11, #4
-       veor            q1, q1, q10
-        veor           q0, q0, q11
-       sub     r5,r5,#1
-       b       .Ldec_sbox
-.align 4
-.Ldec_loop:
-       vldmia  r4!, {q8-q11}
-       veor    q8, q8, q0
-       veor    q9, q9, q1
-       vtbl.8  d0, {q8}, d24
-       vtbl.8  d1, {q8}, d25
-       vldmia  r4!, {q8}
-       veor    q10, q10, q2
-       vtbl.8  d2, {q9}, d24
-       vtbl.8  d3, {q9}, d25
-       vldmia  r4!, {q9}
-       veor    q11, q11, q3
-       vtbl.8  d4, {q10}, d24
-       vtbl.8  d5, {q10}, d25
-       vldmia  r4!, {q10}
-       vtbl.8  d6, {q11}, d24
-       vtbl.8  d7, {q11}, d25
-       vldmia  r4!, {q11}
-       veor    q8, q8, q4
-       veor    q9, q9, q5
-       vtbl.8  d8, {q8}, d24
-       vtbl.8  d9, {q8}, d25
-       veor    q10, q10, q6
-       vtbl.8  d10, {q9}, d24
-       vtbl.8  d11, {q9}, d25
-       veor    q11, q11, q7
-       vtbl.8  d12, {q10}, d24
-       vtbl.8  d13, {q10}, d25
-       vtbl.8  d14, {q11}, d24
-       vtbl.8  d15, {q11}, d25
-.Ldec_sbox:
-        veor   q1, q1, q4
-       veor    q3, q3, q4
-
-       veor    q4, q4, q7
-        veor   q1, q1, q6
-       veor    q2, q2, q7
-       veor    q6, q6, q4
-
-       veor    q0, q0, q1
-       veor    q2, q2, q5
-        veor   q7, q7, q6
-       veor    q3, q3, q0
-       veor    q5, q5, q0
-       veor    q1, q1, q3
-       veor    q11, q3, q0
-       veor    q10, q7, q4
-       veor    q9, q1, q6
-       veor    q13, q4, q0
-        vmov   q8, q10
-       veor    q12, q5, q2
-
-       vorr    q10, q10, q9
-       veor    q15, q11, q8
-       vand    q14, q11, q12
-       vorr    q11, q11, q12
-       veor    q12, q12, q9
-       vand    q8, q8, q9
-       veor    q9, q6, q2
-       vand    q15, q15, q12
-       vand    q13, q13, q9
-       veor    q9, q3, q7
-       veor    q12, q1, q5
-       veor    q11, q11, q13
-       veor    q10, q10, q13
-       vand    q13, q9, q12
-       vorr    q9, q9, q12
-       veor    q11, q11, q15
-       veor    q8, q8, q13
-       veor    q10, q10, q14
-       veor    q9, q9, q15
-       veor    q8, q8, q14
-       vand    q12, q4, q6
-       veor    q9, q9, q14
-       vand    q13, q0, q2
-       vand    q14, q7, q1
-       vorr    q15, q3, q5
-       veor    q11, q11, q12
-       veor    q9, q9, q14
-       veor    q8, q8, q15
-       veor    q10, q10, q13
-
-       @ Inv_GF16      0,      1,      2,      3, s0, s1, s2, s3
-
-       @ new smaller inversion
-
-       vand    q14, q11, q9
-       vmov    q12, q8
-
-       veor    q13, q10, q14
-       veor    q15, q8, q14
-       veor    q14, q8, q14    @ q14=q15
-
-       vbsl    q13, q9, q8
-       vbsl    q15, q11, q10
-       veor    q11, q11, q10
-
-       vbsl    q12, q13, q14
-       vbsl    q8, q14, q13
-
-       vand    q14, q12, q15
-       veor    q9, q9, q8
-
-       veor    q14, q14, q11
-       veor    q12, q5, q2
-       veor    q8, q1, q6
-       veor    q10, q15, q14
-       vand    q10, q10, q5
-       veor    q5, q5, q1
-       vand    q11, q1, q15
-       vand    q5, q5, q14
-       veor    q1, q11, q10
-       veor    q5, q5, q11
-       veor    q15, q15, q13
-       veor    q14, q14, q9
-       veor    q11, q15, q14
-        veor   q10, q13, q9
-       vand    q11, q11, q12
-        vand   q10, q10, q2
-       veor    q12, q12, q8
-        veor   q2, q2, q6
-       vand    q8, q8, q15
-        vand   q6, q6, q13
-       vand    q12, q12, q14
-        vand   q2, q2, q9
-       veor    q8, q8, q12
-        veor   q2, q2, q6
-       veor    q12, q12, q11
-        veor   q6, q6, q10
-       veor    q5, q5, q12
-       veor    q2, q2, q12
-       veor    q1, q1, q8
-       veor    q6, q6, q8
-
-       veor    q12, q3, q0
-       veor    q8, q7, q4
-       veor    q11, q15, q14
-        veor   q10, q13, q9
-       vand    q11, q11, q12
-        vand   q10, q10, q0
-       veor    q12, q12, q8
-        veor   q0, q0, q4
-       vand    q8, q8, q15
-        vand   q4, q4, q13
-       vand    q12, q12, q14
-        vand   q0, q0, q9
-       veor    q8, q8, q12
-        veor   q0, q0, q4
-       veor    q12, q12, q11
-        veor   q4, q4, q10
-       veor    q15, q15, q13
-       veor    q14, q14, q9
-       veor    q10, q15, q14
-       vand    q10, q10, q3
-       veor    q3, q3, q7
-       vand    q11, q7, q15
-       vand    q3, q3, q14
-       veor    q7, q11, q10
-       veor    q3, q3, q11
-       veor    q3, q3, q12
-       veor    q0, q0, q12
-       veor    q7, q7, q8
-       veor    q4, q4, q8
-       veor    q1, q1, q7
-       veor    q6, q6, q5
-
-       veor    q4, q4, q1
-       veor    q2, q2, q7
-       veor    q5, q5, q7
-       veor    q4, q4, q2
-        veor   q7, q7, q0
-       veor    q4, q4, q5
-        veor   q3, q3, q6
-        veor   q6, q6, q1
-       veor    q3, q3, q4
-
-       veor    q4, q4, q0
-       veor    q7, q7, q3
-       subs    r5,r5,#1
-       bcc     .Ldec_done
-       @ multiplication by 0x05-0x00-0x04-0x00
-       vext.8  q8, q0, q0, #8
-       vext.8  q14, q3, q3, #8
-       vext.8  q15, q5, q5, #8
-       veor    q8, q8, q0
-       vext.8  q9, q1, q1, #8
-       veor    q14, q14, q3
-       vext.8  q10, q6, q6, #8
-       veor    q15, q15, q5
-       vext.8  q11, q4, q4, #8
-       veor    q9, q9, q1
-       vext.8  q12, q2, q2, #8
-       veor    q10, q10, q6
-       vext.8  q13, q7, q7, #8
-       veor    q11, q11, q4
-       veor    q12, q12, q2
-       veor    q13, q13, q7
-
-        veor   q0, q0, q14
-        veor   q1, q1, q14
-        veor   q6, q6, q8
-        veor   q2, q2, q10
-        veor   q4, q4, q9
-        veor   q1, q1, q15
-        veor   q6, q6, q15
-        veor   q2, q2, q14
-        veor   q7, q7, q11
-        veor   q4, q4, q14
-        veor   q3, q3, q12
-        veor   q2, q2, q15
-        veor   q7, q7, q15
-        veor   q5, q5, q13
-       vext.8  q8, q0, q0, #12 @ x0 <<< 32
-       vext.8  q9, q1, q1, #12
-        veor   q0, q0, q8              @ x0 ^ (x0 <<< 32)
-       vext.8  q10, q6, q6, #12
-        veor   q1, q1, q9
-       vext.8  q11, q4, q4, #12
-        veor   q6, q6, q10
-       vext.8  q12, q2, q2, #12
-        veor   q4, q4, q11
-       vext.8  q13, q7, q7, #12
-        veor   q2, q2, q12
-       vext.8  q14, q3, q3, #12
-        veor   q7, q7, q13
-       vext.8  q15, q5, q5, #12
-        veor   q3, q3, q14
-
-       veor    q9, q9, q0
-        veor   q5, q5, q15
-        vext.8 q0, q0, q0, #8          @ (x0 ^ (x0 <<< 32)) <<< 64)
-       veor    q10, q10, q1
-       veor    q8, q8, q5
-       veor    q9, q9, q5
-        vext.8 q1, q1, q1, #8
-       veor    q13, q13, q2
-        veor   q0, q0, q8
-       veor    q14, q14, q7
-        veor   q1, q1, q9
-        vext.8 q8, q2, q2, #8
-       veor    q12, q12, q4
-        vext.8 q9, q7, q7, #8
-       veor    q15, q15, q3
-        vext.8 q2, q4, q4, #8
-       veor    q11, q11, q6
-        vext.8 q7, q5, q5, #8
-       veor    q12, q12, q5
-        vext.8 q4, q3, q3, #8
-       veor    q11, q11, q5
-        vext.8 q3, q6, q6, #8
-       veor    q5, q9, q13
-       veor    q11, q11, q2
-       veor    q7, q7, q15
-       veor    q6, q4, q14
-       veor    q4, q8, q12
-       veor    q2, q3, q10
-       vmov    q3, q11
-        @ vmov q5, q9
-       vldmia  r6, {q12}               @ .LISR
-       ite     eq                              @ Thumb2 thing, sanity check in ARM
-       addeq   r6,r6,#0x10
-       bne     .Ldec_loop
-       vldmia  r6, {q12}               @ .LISRM0
-       b       .Ldec_loop
-.align 4
-.Ldec_done:
-       vmov.i8 q8,#0x55                        @ compose .LBS0
-       vmov.i8 q9,#0x33                        @ compose .LBS1
-       vshr.u64        q10, q3, #1
-        vshr.u64       q11, q2, #1
-       veor            q10, q10, q5
-        veor           q11, q11, q7
-       vand            q10, q10, q8
-        vand           q11, q11, q8
-       veor            q5, q5, q10
-       vshl.u64        q10, q10, #1
-        veor           q7, q7, q11
-        vshl.u64       q11, q11, #1
-       veor            q3, q3, q10
-        veor           q2, q2, q11
-       vshr.u64        q10, q6, #1
-        vshr.u64       q11, q0, #1
-       veor            q10, q10, q4
-        veor           q11, q11, q1
-       vand            q10, q10, q8
-        vand           q11, q11, q8
-       veor            q4, q4, q10
-       vshl.u64        q10, q10, #1
-        veor           q1, q1, q11
-        vshl.u64       q11, q11, #1
-       veor            q6, q6, q10
-        veor           q0, q0, q11
-       vmov.i8 q8,#0x0f                        @ compose .LBS2
-       vshr.u64        q10, q7, #2
-        vshr.u64       q11, q2, #2
-       veor            q10, q10, q5
-        veor           q11, q11, q3
-       vand            q10, q10, q9
-        vand           q11, q11, q9
-       veor            q5, q5, q10
-       vshl.u64        q10, q10, #2
-        veor           q3, q3, q11
-        vshl.u64       q11, q11, #2
-       veor            q7, q7, q10
-        veor           q2, q2, q11
-       vshr.u64        q10, q1, #2
-        vshr.u64       q11, q0, #2
-       veor            q10, q10, q4
-        veor           q11, q11, q6
-       vand            q10, q10, q9
-        vand           q11, q11, q9
-       veor            q4, q4, q10
-       vshl.u64        q10, q10, #2
-        veor           q6, q6, q11
-        vshl.u64       q11, q11, #2
-       veor            q1, q1, q10
-        veor           q0, q0, q11
-       vshr.u64        q10, q4, #4
-        vshr.u64       q11, q6, #4
-       veor            q10, q10, q5
-        veor           q11, q11, q3
-       vand            q10, q10, q8
-        vand           q11, q11, q8
-       veor            q5, q5, q10
-       vshl.u64        q10, q10, #4
-        veor           q3, q3, q11
-        vshl.u64       q11, q11, #4
-       veor            q4, q4, q10
-        veor           q6, q6, q11
-       vshr.u64        q10, q1, #4
-        vshr.u64       q11, q0, #4
-       veor            q10, q10, q7
-        veor           q11, q11, q2
-       vand            q10, q10, q8
-        vand           q11, q11, q8
-       veor            q7, q7, q10
-       vshl.u64        q10, q10, #4
-        veor           q2, q2, q11
-        vshl.u64       q11, q11, #4
-       veor            q1, q1, q10
-        veor           q0, q0, q11
-       vldmia  r4, {q8}                        @ last round key
-       veor    q6, q6, q8
-       veor    q4, q4, q8
-       veor    q2, q2, q8
-       veor    q7, q7, q8
-       veor    q3, q3, q8
-       veor    q5, q5, q8
-       veor    q0, q0, q8
-       veor    q1, q1, q8
-       bx      lr
-.size  _bsaes_decrypt8,.-_bsaes_decrypt8
-
-.type  _bsaes_const,%object
-.align 6
-_bsaes_const:
-.LM0ISR:       @ InvShiftRows constants
-       .quad   0x0a0e0206070b0f03, 0x0004080c0d010509
-.LISR:
-       .quad   0x0504070602010003, 0x0f0e0d0c080b0a09
-.LISRM0:
-       .quad   0x01040b0e0205080f, 0x0306090c00070a0d
-.LM0SR:                @ ShiftRows constants
-       .quad   0x0a0e02060f03070b, 0x0004080c05090d01
-.LSR:
-       .quad   0x0504070600030201, 0x0f0e0d0c0a09080b
-.LSRM0:
-       .quad   0x0304090e00050a0f, 0x01060b0c0207080d
-.LM0:
-       .quad   0x02060a0e03070b0f, 0x0004080c0105090d
-.LREVM0SR:
-       .quad   0x090d01050c000408, 0x03070b0f060a0e02
-.asciz "Bit-sliced AES for NEON, CRYPTOGAMS by <appro@openssl.org>"
-.align 6
-.size  _bsaes_const,.-_bsaes_const
-
-.type  _bsaes_encrypt8,%function
-.align 4
-_bsaes_encrypt8:
-       adr     r6,_bsaes_encrypt8
-       vldmia  r4!, {q9}               @ round 0 key
-       sub     r6,r6,#_bsaes_encrypt8-.LM0SR
-
-       vldmia  r6!, {q8}               @ .LM0SR
-_bsaes_encrypt8_alt:
-       veor    q10, q0, q9     @ xor with round0 key
-       veor    q11, q1, q9
-        vtbl.8 d0, {q10}, d16
-        vtbl.8 d1, {q10}, d17
-       veor    q12, q2, q9
-        vtbl.8 d2, {q11}, d16
-        vtbl.8 d3, {q11}, d17
-       veor    q13, q3, q9
-        vtbl.8 d4, {q12}, d16
-        vtbl.8 d5, {q12}, d17
-       veor    q14, q4, q9
-        vtbl.8 d6, {q13}, d16
-        vtbl.8 d7, {q13}, d17
-       veor    q15, q5, q9
-        vtbl.8 d8, {q14}, d16
-        vtbl.8 d9, {q14}, d17
-       veor    q10, q6, q9
-        vtbl.8 d10, {q15}, d16
-        vtbl.8 d11, {q15}, d17
-       veor    q11, q7, q9
-        vtbl.8 d12, {q10}, d16
-        vtbl.8 d13, {q10}, d17
-        vtbl.8 d14, {q11}, d16
-        vtbl.8 d15, {q11}, d17
-_bsaes_encrypt8_bitslice:
-       vmov.i8 q8,#0x55                        @ compose .LBS0
-       vmov.i8 q9,#0x33                        @ compose .LBS1
-       vshr.u64        q10, q6, #1
-        vshr.u64       q11, q4, #1
-       veor            q10, q10, q7
-        veor           q11, q11, q5
-       vand            q10, q10, q8
-        vand           q11, q11, q8
-       veor            q7, q7, q10
-       vshl.u64        q10, q10, #1
-        veor           q5, q5, q11
-        vshl.u64       q11, q11, #1
-       veor            q6, q6, q10
-        veor           q4, q4, q11
-       vshr.u64        q10, q2, #1
-        vshr.u64       q11, q0, #1
-       veor            q10, q10, q3
-        veor           q11, q11, q1
-       vand            q10, q10, q8
-        vand           q11, q11, q8
-       veor            q3, q3, q10
-       vshl.u64        q10, q10, #1
-        veor           q1, q1, q11
-        vshl.u64       q11, q11, #1
-       veor            q2, q2, q10
-        veor           q0, q0, q11
-       vmov.i8 q8,#0x0f                        @ compose .LBS2
-       vshr.u64        q10, q5, #2
-        vshr.u64       q11, q4, #2
-       veor            q10, q10, q7
-        veor           q11, q11, q6
-       vand            q10, q10, q9
-        vand           q11, q11, q9
-       veor            q7, q7, q10
-       vshl.u64        q10, q10, #2
-        veor           q6, q6, q11
-        vshl.u64       q11, q11, #2
-       veor            q5, q5, q10
-        veor           q4, q4, q11
-       vshr.u64        q10, q1, #2
-        vshr.u64       q11, q0, #2
-       veor            q10, q10, q3
-        veor           q11, q11, q2
-       vand            q10, q10, q9
-        vand           q11, q11, q9
-       veor            q3, q3, q10
-       vshl.u64        q10, q10, #2
-        veor           q2, q2, q11
-        vshl.u64       q11, q11, #2
-       veor            q1, q1, q10
-        veor           q0, q0, q11
-       vshr.u64        q10, q3, #4
-        vshr.u64       q11, q2, #4
-       veor            q10, q10, q7
-        veor           q11, q11, q6
-       vand            q10, q10, q8
-        vand           q11, q11, q8
-       veor            q7, q7, q10
-       vshl.u64        q10, q10, #4
-        veor           q6, q6, q11
-        vshl.u64       q11, q11, #4
-       veor            q3, q3, q10
-        veor           q2, q2, q11
-       vshr.u64        q10, q1, #4
-        vshr.u64       q11, q0, #4
-       veor            q10, q10, q5
-        veor           q11, q11, q4
-       vand            q10, q10, q8
-        vand           q11, q11, q8
-       veor            q5, q5, q10
-       vshl.u64        q10, q10, #4
-        veor           q4, q4, q11
-        vshl.u64       q11, q11, #4
-       veor            q1, q1, q10
-        veor           q0, q0, q11
-       sub     r5,r5,#1
-       b       .Lenc_sbox
-.align 4
-.Lenc_loop:
-       vldmia  r4!, {q8-q11}
-       veor    q8, q8, q0
-       veor    q9, q9, q1
-       vtbl.8  d0, {q8}, d24
-       vtbl.8  d1, {q8}, d25
-       vldmia  r4!, {q8}
-       veor    q10, q10, q2
-       vtbl.8  d2, {q9}, d24
-       vtbl.8  d3, {q9}, d25
-       vldmia  r4!, {q9}
-       veor    q11, q11, q3
-       vtbl.8  d4, {q10}, d24
-       vtbl.8  d5, {q10}, d25
-       vldmia  r4!, {q10}
-       vtbl.8  d6, {q11}, d24
-       vtbl.8  d7, {q11}, d25
-       vldmia  r4!, {q11}
-       veor    q8, q8, q4
-       veor    q9, q9, q5
-       vtbl.8  d8, {q8}, d24
-       vtbl.8  d9, {q8}, d25
-       veor    q10, q10, q6
-       vtbl.8  d10, {q9}, d24
-       vtbl.8  d11, {q9}, d25
-       veor    q11, q11, q7
-       vtbl.8  d12, {q10}, d24
-       vtbl.8  d13, {q10}, d25
-       vtbl.8  d14, {q11}, d24
-       vtbl.8  d15, {q11}, d25
-.Lenc_sbox:
-       veor    q2, q2, q1
-       veor    q5, q5, q6
-       veor    q3, q3, q0
-       veor    q6, q6, q2
-       veor    q5, q5, q0
-
-       veor    q6, q6, q3
-       veor    q3, q3, q7
-       veor    q7, q7, q5
-       veor    q3, q3, q4
-       veor    q4, q4, q5
-
-       veor    q2, q2, q7
-       veor    q3, q3, q1
-       veor    q1, q1, q5
-       veor    q11, q7, q4
-       veor    q10, q1, q2
-       veor    q9, q5, q3
-       veor    q13, q2, q4
-        vmov   q8, q10
-       veor    q12, q6, q0
-
-       vorr    q10, q10, q9
-       veor    q15, q11, q8
-       vand    q14, q11, q12
-       vorr    q11, q11, q12
-       veor    q12, q12, q9
-       vand    q8, q8, q9
-       veor    q9, q3, q0
-       vand    q15, q15, q12
-       vand    q13, q13, q9
-       veor    q9, q7, q1
-       veor    q12, q5, q6
-       veor    q11, q11, q13
-       veor    q10, q10, q13
-       vand    q13, q9, q12
-       vorr    q9, q9, q12
-       veor    q11, q11, q15
-       veor    q8, q8, q13
-       veor    q10, q10, q14
-       veor    q9, q9, q15
-       veor    q8, q8, q14
-       vand    q12, q2, q3
-       veor    q9, q9, q14
-       vand    q13, q4, q0
-       vand    q14, q1, q5
-       vorr    q15, q7, q6
-       veor    q11, q11, q12
-       veor    q9, q9, q14
-       veor    q8, q8, q15
-       veor    q10, q10, q13
-
-       @ Inv_GF16      0,      1,      2,      3, s0, s1, s2, s3
-
-       @ new smaller inversion
-
-       vand    q14, q11, q9
-       vmov    q12, q8
-
-       veor    q13, q10, q14
-       veor    q15, q8, q14
-       veor    q14, q8, q14    @ q14=q15
-
-       vbsl    q13, q9, q8
-       vbsl    q15, q11, q10
-       veor    q11, q11, q10
-
-       vbsl    q12, q13, q14
-       vbsl    q8, q14, q13
-
-       vand    q14, q12, q15
-       veor    q9, q9, q8
-
-       veor    q14, q14, q11
-       veor    q12, q6, q0
-       veor    q8, q5, q3
-       veor    q10, q15, q14
-       vand    q10, q10, q6
-       veor    q6, q6, q5
-       vand    q11, q5, q15
-       vand    q6, q6, q14
-       veor    q5, q11, q10
-       veor    q6, q6, q11
-       veor    q15, q15, q13
-       veor    q14, q14, q9
-       veor    q11, q15, q14
-        veor   q10, q13, q9
-       vand    q11, q11, q12
-        vand   q10, q10, q0
-       veor    q12, q12, q8
-        veor   q0, q0, q3
-       vand    q8, q8, q15
-        vand   q3, q3, q13
-       vand    q12, q12, q14
-        vand   q0, q0, q9
-       veor    q8, q8, q12
-        veor   q0, q0, q3
-       veor    q12, q12, q11
-        veor   q3, q3, q10
-       veor    q6, q6, q12
-       veor    q0, q0, q12
-       veor    q5, q5, q8
-       veor    q3, q3, q8
-
-       veor    q12, q7, q4
-       veor    q8, q1, q2
-       veor    q11, q15, q14
-        veor   q10, q13, q9
-       vand    q11, q11, q12
-        vand   q10, q10, q4
-       veor    q12, q12, q8
-        veor   q4, q4, q2
-       vand    q8, q8, q15
-        vand   q2, q2, q13
-       vand    q12, q12, q14
-        vand   q4, q4, q9
-       veor    q8, q8, q12
-        veor   q4, q4, q2
-       veor    q12, q12, q11
-        veor   q2, q2, q10
-       veor    q15, q15, q13
-       veor    q14, q14, q9
-       veor    q10, q15, q14
-       vand    q10, q10, q7
-       veor    q7, q7, q1
-       vand    q11, q1, q15
-       vand    q7, q7, q14
-       veor    q1, q11, q10
-       veor    q7, q7, q11
-       veor    q7, q7, q12
-       veor    q4, q4, q12
-       veor    q1, q1, q8
-       veor    q2, q2, q8
-       veor    q7, q7, q0
-       veor    q1, q1, q6
-       veor    q6, q6, q0
-       veor    q4, q4, q7
-       veor    q0, q0, q1
-
-       veor    q1, q1, q5
-       veor    q5, q5, q2
-       veor    q2, q2, q3
-       veor    q3, q3, q5
-       veor    q4, q4, q5
-
-       veor    q6, q6, q3
-       subs    r5,r5,#1
-       bcc     .Lenc_done
-       vext.8  q8, q0, q0, #12 @ x0 <<< 32
-       vext.8  q9, q1, q1, #12
-        veor   q0, q0, q8              @ x0 ^ (x0 <<< 32)
-       vext.8  q10, q4, q4, #12
-        veor   q1, q1, q9
-       vext.8  q11, q6, q6, #12
-        veor   q4, q4, q10
-       vext.8  q12, q3, q3, #12
-        veor   q6, q6, q11
-       vext.8  q13, q7, q7, #12
-        veor   q3, q3, q12
-       vext.8  q14, q2, q2, #12
-        veor   q7, q7, q13
-       vext.8  q15, q5, q5, #12
-        veor   q2, q2, q14
-
-       veor    q9, q9, q0
-        veor   q5, q5, q15
-        vext.8 q0, q0, q0, #8          @ (x0 ^ (x0 <<< 32)) <<< 64)
-       veor    q10, q10, q1
-       veor    q8, q8, q5
-       veor    q9, q9, q5
-        vext.8 q1, q1, q1, #8
-       veor    q13, q13, q3
-        veor   q0, q0, q8
-       veor    q14, q14, q7
-        veor   q1, q1, q9
-        vext.8 q8, q3, q3, #8
-       veor    q12, q12, q6
-        vext.8 q9, q7, q7, #8
-       veor    q15, q15, q2
-        vext.8 q3, q6, q6, #8
-       veor    q11, q11, q4
-        vext.8 q7, q5, q5, #8
-       veor    q12, q12, q5
-        vext.8 q6, q2, q2, #8
-       veor    q11, q11, q5
-        vext.8 q2, q4, q4, #8
-       veor    q5, q9, q13
-       veor    q4, q8, q12
-       veor    q3, q3, q11
-       veor    q7, q7, q15
-       veor    q6, q6, q14
-        @ vmov q4, q8
-       veor    q2, q2, q10
-        @ vmov q5, q9
-       vldmia  r6, {q12}               @ .LSR
-       ite     eq                              @ Thumb2 thing, samity check in ARM
-       addeq   r6,r6,#0x10
-       bne     .Lenc_loop
-       vldmia  r6, {q12}               @ .LSRM0
-       b       .Lenc_loop
-.align 4
-.Lenc_done:
-       vmov.i8 q8,#0x55                        @ compose .LBS0
-       vmov.i8 q9,#0x33                        @ compose .LBS1
-       vshr.u64        q10, q2, #1
-        vshr.u64       q11, q3, #1
-       veor            q10, q10, q5
-        veor           q11, q11, q7
-       vand            q10, q10, q8
-        vand           q11, q11, q8
-       veor            q5, q5, q10
-       vshl.u64        q10, q10, #1
-        veor           q7, q7, q11
-        vshl.u64       q11, q11, #1
-       veor            q2, q2, q10
-        veor           q3, q3, q11
-       vshr.u64        q10, q4, #1
-        vshr.u64       q11, q0, #1
-       veor            q10, q10, q6
-        veor           q11, q11, q1
-       vand            q10, q10, q8
-        vand           q11, q11, q8
-       veor            q6, q6, q10
-       vshl.u64        q10, q10, #1
-        veor           q1, q1, q11
-        vshl.u64       q11, q11, #1
-       veor            q4, q4, q10
-        veor           q0, q0, q11
-       vmov.i8 q8,#0x0f                        @ compose .LBS2
-       vshr.u64        q10, q7, #2
-        vshr.u64       q11, q3, #2
-       veor            q10, q10, q5
-        veor           q11, q11, q2
-       vand            q10, q10, q9
-        vand           q11, q11, q9
-       veor            q5, q5, q10
-       vshl.u64        q10, q10, #2
-        veor           q2, q2, q11
-        vshl.u64       q11, q11, #2
-       veor            q7, q7, q10
-        veor           q3, q3, q11
-       vshr.u64        q10, q1, #2
-        vshr.u64       q11, q0, #2
-       veor            q10, q10, q6
-        veor           q11, q11, q4
-       vand            q10, q10, q9
-        vand           q11, q11, q9
-       veor            q6, q6, q10
-       vshl.u64        q10, q10, #2
-        veor           q4, q4, q11
-        vshl.u64       q11, q11, #2
-       veor            q1, q1, q10
-        veor           q0, q0, q11
-       vshr.u64        q10, q6, #4
-        vshr.u64       q11, q4, #4
-       veor            q10, q10, q5
-        veor           q11, q11, q2
-       vand            q10, q10, q8
-        vand           q11, q11, q8
-       veor            q5, q5, q10
-       vshl.u64        q10, q10, #4
-        veor           q2, q2, q11
-        vshl.u64       q11, q11, #4
-       veor            q6, q6, q10
-        veor           q4, q4, q11
-       vshr.u64        q10, q1, #4
-        vshr.u64       q11, q0, #4
-       veor            q10, q10, q7
-        veor           q11, q11, q3
-       vand            q10, q10, q8
-        vand           q11, q11, q8
-       veor            q7, q7, q10
-       vshl.u64        q10, q10, #4
-        veor           q3, q3, q11
-        vshl.u64       q11, q11, #4
-       veor            q1, q1, q10
-        veor           q0, q0, q11
-       vldmia  r4, {q8}                        @ last round key
-       veor    q4, q4, q8
-       veor    q6, q6, q8
-       veor    q3, q3, q8
-       veor    q7, q7, q8
-       veor    q2, q2, q8
-       veor    q5, q5, q8
-       veor    q0, q0, q8
-       veor    q1, q1, q8
-       bx      lr
-.size  _bsaes_encrypt8,.-_bsaes_encrypt8
-.type  _bsaes_key_convert,%function
-.align 4
-_bsaes_key_convert:
-       adr     r6,_bsaes_key_convert
-       vld1.8  {q7},  [r4]!            @ load round 0 key
-       sub     r6,r6,#_bsaes_key_convert-.LM0
-       vld1.8  {q15}, [r4]!            @ load round 1 key
-
-       vmov.i8 q8,  #0x01                      @ bit masks
-       vmov.i8 q9,  #0x02
-       vmov.i8 q10, #0x04
-       vmov.i8 q11, #0x08
-       vmov.i8 q12, #0x10
-       vmov.i8 q13, #0x20
-       vldmia  r6, {q14}               @ .LM0
-
-#ifdef __ARMEL__
-       vrev32.8        q7,  q7
-       vrev32.8        q15, q15
-#endif
-       sub     r5,r5,#1
-       vstmia  r12!, {q7}              @ save round 0 key
-       b       .Lkey_loop
-
-.align 4
-.Lkey_loop:
-       vtbl.8  d14,{q15},d28
-       vtbl.8  d15,{q15},d29
-       vmov.i8 q6,  #0x40
-       vmov.i8 q15, #0x80
-
-       vtst.8  q0, q7, q8
-       vtst.8  q1, q7, q9
-       vtst.8  q2, q7, q10
-       vtst.8  q3, q7, q11
-       vtst.8  q4, q7, q12
-       vtst.8  q5, q7, q13
-       vtst.8  q6, q7, q6
-       vtst.8  q7, q7, q15
-       vld1.8  {q15}, [r4]!            @ load next round key
-       vmvn    q0, q0          @ "pnot"
-       vmvn    q1, q1
-       vmvn    q5, q5
-       vmvn    q6, q6
-#ifdef __ARMEL__
-       vrev32.8        q15, q15
-#endif
-       subs    r5,r5,#1
-       vstmia  r12!,{q0-q7}            @ write bit-sliced round key
-       bne     .Lkey_loop
-
-       vmov.i8 q7,#0x63                        @ compose .L63
-       @ don't save last round key
-       bx      lr
-.size  _bsaes_key_convert,.-_bsaes_key_convert
-.extern AES_cbc_encrypt
-.extern AES_decrypt
-
-.global        bsaes_cbc_encrypt
-.type  bsaes_cbc_encrypt,%function
-.align 5
-bsaes_cbc_encrypt:
-#ifndef        __KERNEL__
-       cmp     r2, #128
-#ifndef        __thumb__
-       blo     AES_cbc_encrypt
-#else
-       bhs     1f
-       b       AES_cbc_encrypt
-1:
-#endif
-#endif
-
-       @ it is up to the caller to make sure we are called with enc == 0
-
-       mov     ip, sp
-       stmdb   sp!, {r4-r10, lr}
-       VFP_ABI_PUSH
-       ldr     r8, [ip]                        @ IV is 1st arg on the stack
-       mov     r2, r2, lsr#4           @ len in 16 byte blocks
-       sub     sp, #0x10                       @ scratch space to carry over the IV
-       mov     r9, sp                          @ save sp
-
-       ldr     r10, [r3, #240]         @ get # of rounds
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       @ allocate the key schedule on the stack
-       sub     r12, sp, r10, lsl#7             @ 128 bytes per inner round key
-       add     r12, #96                        @ sifze of bit-slices key schedule
-
-       @ populate the key schedule
-       mov     r4, r3                  @ pass key
-       mov     r5, r10                 @ pass # of rounds
-       mov     sp, r12                         @ sp is sp
-       bl      _bsaes_key_convert
-       vldmia  sp, {q6}
-       vstmia  r12,  {q15}             @ save last round key
-       veor    q7, q7, q6      @ fix up round 0 key
-       vstmia  sp, {q7}
-#else
-       ldr     r12, [r3, #244]
-       eors    r12, #1
-       beq     0f
-
-       @ populate the key schedule
-       str     r12, [r3, #244]
-       mov     r4, r3                  @ pass key
-       mov     r5, r10                 @ pass # of rounds
-       add     r12, r3, #248                   @ pass key schedule
-       bl      _bsaes_key_convert
-       add     r4, r3, #248
-       vldmia  r4, {q6}
-       vstmia  r12, {q15}                      @ save last round key
-       veor    q7, q7, q6      @ fix up round 0 key
-       vstmia  r4, {q7}
-
-.align 2
-0:
-#endif
-
-       vld1.8  {q15}, [r8]             @ load IV
-       b       .Lcbc_dec_loop
-
-.align 4
-.Lcbc_dec_loop:
-       subs    r2, r2, #0x8
-       bmi     .Lcbc_dec_loop_finish
-
-       vld1.8  {q0-q1}, [r0]!  @ load input
-       vld1.8  {q2-q3}, [r0]!
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       mov     r4, sp                  @ pass the key
-#else
-       add     r4, r3, #248
-#endif
-       vld1.8  {q4-q5}, [r0]!
-       mov     r5, r10
-       vld1.8  {q6-q7}, [r0]
-       sub     r0, r0, #0x60
-       vstmia  r9, {q15}                       @ put aside IV
-
-       bl      _bsaes_decrypt8
-
-       vldmia  r9, {q14}                       @ reload IV
-       vld1.8  {q8-q9}, [r0]!  @ reload input
-       veor    q0, q0, q14     @ ^= IV
-       vld1.8  {q10-q11}, [r0]!
-       veor    q1, q1, q8
-       veor    q6, q6, q9
-       vld1.8  {q12-q13}, [r0]!
-       veor    q4, q4, q10
-       veor    q2, q2, q11
-       vld1.8  {q14-q15}, [r0]!
-       veor    q7, q7, q12
-       vst1.8  {q0-q1}, [r1]!  @ write output
-       veor    q3, q3, q13
-       vst1.8  {q6}, [r1]!
-       veor    q5, q5, q14
-       vst1.8  {q4}, [r1]!
-       vst1.8  {q2}, [r1]!
-       vst1.8  {q7}, [r1]!
-       vst1.8  {q3}, [r1]!
-       vst1.8  {q5}, [r1]!
-
-       b       .Lcbc_dec_loop
-
-.Lcbc_dec_loop_finish:
-       adds    r2, r2, #8
-       beq     .Lcbc_dec_done
-
-       vld1.8  {q0}, [r0]!             @ load input
-       cmp     r2, #2
-       blo     .Lcbc_dec_one
-       vld1.8  {q1}, [r0]!
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       mov     r4, sp                  @ pass the key
-#else
-       add     r4, r3, #248
-#endif
-       mov     r5, r10
-       vstmia  r9, {q15}                       @ put aside IV
-       beq     .Lcbc_dec_two
-       vld1.8  {q2}, [r0]!
-       cmp     r2, #4
-       blo     .Lcbc_dec_three
-       vld1.8  {q3}, [r0]!
-       beq     .Lcbc_dec_four
-       vld1.8  {q4}, [r0]!
-       cmp     r2, #6
-       blo     .Lcbc_dec_five
-       vld1.8  {q5}, [r0]!
-       beq     .Lcbc_dec_six
-       vld1.8  {q6}, [r0]!
-       sub     r0, r0, #0x70
-
-       bl      _bsaes_decrypt8
-
-       vldmia  r9, {q14}                       @ reload IV
-       vld1.8  {q8-q9}, [r0]!  @ reload input
-       veor    q0, q0, q14     @ ^= IV
-       vld1.8  {q10-q11}, [r0]!
-       veor    q1, q1, q8
-       veor    q6, q6, q9
-       vld1.8  {q12-q13}, [r0]!
-       veor    q4, q4, q10
-       veor    q2, q2, q11
-       vld1.8  {q15}, [r0]!
-       veor    q7, q7, q12
-       vst1.8  {q0-q1}, [r1]!  @ write output
-       veor    q3, q3, q13
-       vst1.8  {q6}, [r1]!
-       vst1.8  {q4}, [r1]!
-       vst1.8  {q2}, [r1]!
-       vst1.8  {q7}, [r1]!
-       vst1.8  {q3}, [r1]!
-       b       .Lcbc_dec_done
-.align 4
-.Lcbc_dec_six:
-       sub     r0, r0, #0x60
-       bl      _bsaes_decrypt8
-       vldmia  r9,{q14}                        @ reload IV
-       vld1.8  {q8-q9}, [r0]!  @ reload input
-       veor    q0, q0, q14     @ ^= IV
-       vld1.8  {q10-q11}, [r0]!
-       veor    q1, q1, q8
-       veor    q6, q6, q9
-       vld1.8  {q12}, [r0]!
-       veor    q4, q4, q10
-       veor    q2, q2, q11
-       vld1.8  {q15}, [r0]!
-       veor    q7, q7, q12
-       vst1.8  {q0-q1}, [r1]!  @ write output
-       vst1.8  {q6}, [r1]!
-       vst1.8  {q4}, [r1]!
-       vst1.8  {q2}, [r1]!
-       vst1.8  {q7}, [r1]!
-       b       .Lcbc_dec_done
-.align 4
-.Lcbc_dec_five:
-       sub     r0, r0, #0x50
-       bl      _bsaes_decrypt8
-       vldmia  r9, {q14}                       @ reload IV
-       vld1.8  {q8-q9}, [r0]!  @ reload input
-       veor    q0, q0, q14     @ ^= IV
-       vld1.8  {q10-q11}, [r0]!
-       veor    q1, q1, q8
-       veor    q6, q6, q9
-       vld1.8  {q15}, [r0]!
-       veor    q4, q4, q10
-       vst1.8  {q0-q1}, [r1]!  @ write output
-       veor    q2, q2, q11
-       vst1.8  {q6}, [r1]!
-       vst1.8  {q4}, [r1]!
-       vst1.8  {q2}, [r1]!
-       b       .Lcbc_dec_done
-.align 4
-.Lcbc_dec_four:
-       sub     r0, r0, #0x40
-       bl      _bsaes_decrypt8
-       vldmia  r9, {q14}                       @ reload IV
-       vld1.8  {q8-q9}, [r0]!  @ reload input
-       veor    q0, q0, q14     @ ^= IV
-       vld1.8  {q10}, [r0]!
-       veor    q1, q1, q8
-       veor    q6, q6, q9
-       vld1.8  {q15}, [r0]!
-       veor    q4, q4, q10
-       vst1.8  {q0-q1}, [r1]!  @ write output
-       vst1.8  {q6}, [r1]!
-       vst1.8  {q4}, [r1]!
-       b       .Lcbc_dec_done
-.align 4
-.Lcbc_dec_three:
-       sub     r0, r0, #0x30
-       bl      _bsaes_decrypt8
-       vldmia  r9, {q14}                       @ reload IV
-       vld1.8  {q8-q9}, [r0]!  @ reload input
-       veor    q0, q0, q14     @ ^= IV
-       vld1.8  {q15}, [r0]!
-       veor    q1, q1, q8
-       veor    q6, q6, q9
-       vst1.8  {q0-q1}, [r1]!  @ write output
-       vst1.8  {q6}, [r1]!
-       b       .Lcbc_dec_done
-.align 4
-.Lcbc_dec_two:
-       sub     r0, r0, #0x20
-       bl      _bsaes_decrypt8
-       vldmia  r9, {q14}                       @ reload IV
-       vld1.8  {q8}, [r0]!             @ reload input
-       veor    q0, q0, q14     @ ^= IV
-       vld1.8  {q15}, [r0]!            @ reload input
-       veor    q1, q1, q8
-       vst1.8  {q0-q1}, [r1]!  @ write output
-       b       .Lcbc_dec_done
-.align 4
-.Lcbc_dec_one:
-       sub     r0, r0, #0x10
-       mov     r10, r1                 @ save original out pointer
-       mov     r1, r9                  @ use the iv scratch space as out buffer
-       mov     r2, r3
-       vmov    q4,q15          @ just in case ensure that IV
-       vmov    q5,q0                   @ and input are preserved
-       bl      AES_decrypt
-       vld1.8  {q0}, [r9,:64]          @ load result
-       veor    q0, q0, q4      @ ^= IV
-       vmov    q15, q5         @ q5 holds input
-       vst1.8  {q0}, [r10]             @ write output
-
-.Lcbc_dec_done:
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       vmov.i32        q0, #0
-       vmov.i32        q1, #0
-.Lcbc_dec_bzero:                               @ wipe key schedule [if any]
-       vstmia          sp!, {q0-q1}
-       cmp             sp, r9
-       bne             .Lcbc_dec_bzero
-#endif
-
-       mov     sp, r9
-       add     sp, #0x10                       @ add sp,r9,#0x10 is no good for thumb
-       vst1.8  {q15}, [r8]             @ return IV
-       VFP_ABI_POP
-       ldmia   sp!, {r4-r10, pc}
-.size  bsaes_cbc_encrypt,.-bsaes_cbc_encrypt
-.extern        AES_encrypt
-.global        bsaes_ctr32_encrypt_blocks
-.type  bsaes_ctr32_encrypt_blocks,%function
-.align 5
-bsaes_ctr32_encrypt_blocks:
-       cmp     r2, #8                  @ use plain AES for
-       blo     .Lctr_enc_short                 @ small sizes
-
-       mov     ip, sp
-       stmdb   sp!, {r4-r10, lr}
-       VFP_ABI_PUSH
-       ldr     r8, [ip]                        @ ctr is 1st arg on the stack
-       sub     sp, sp, #0x10                   @ scratch space to carry over the ctr
-       mov     r9, sp                          @ save sp
-
-       ldr     r10, [r3, #240]         @ get # of rounds
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       @ allocate the key schedule on the stack
-       sub     r12, sp, r10, lsl#7             @ 128 bytes per inner round key
-       add     r12, #96                        @ size of bit-sliced key schedule
-
-       @ populate the key schedule
-       mov     r4, r3                  @ pass key
-       mov     r5, r10                 @ pass # of rounds
-       mov     sp, r12                         @ sp is sp
-       bl      _bsaes_key_convert
-       veor    q7,q7,q15       @ fix up last round key
-       vstmia  r12, {q7}                       @ save last round key
-
-       vld1.8  {q0}, [r8]              @ load counter
-       add     r8, r6, #.LREVM0SR-.LM0 @ borrow r8
-       vldmia  sp, {q4}                @ load round0 key
-#else
-       ldr     r12, [r3, #244]
-       eors    r12, #1
-       beq     0f
-
-       @ populate the key schedule
-       str     r12, [r3, #244]
-       mov     r4, r3                  @ pass key
-       mov     r5, r10                 @ pass # of rounds
-       add     r12, r3, #248                   @ pass key schedule
-       bl      _bsaes_key_convert
-       veor    q7,q7,q15       @ fix up last round key
-       vstmia  r12, {q7}                       @ save last round key
-
-.align 2
-0:     add     r12, r3, #248
-       vld1.8  {q0}, [r8]              @ load counter
-       adrl    r8, .LREVM0SR                   @ borrow r8
-       vldmia  r12, {q4}                       @ load round0 key
-       sub     sp, #0x10                       @ place for adjusted round0 key
-#endif
-
-       vmov.i32        q8,#1           @ compose 1<<96
-       veor            q9,q9,q9
-       vrev32.8        q0,q0
-       vext.8          q8,q9,q8,#4
-       vrev32.8        q4,q4
-       vadd.u32        q9,q8,q8        @ compose 2<<96
-       vstmia  sp, {q4}                @ save adjusted round0 key
-       b       .Lctr_enc_loop
-
-.align 4
-.Lctr_enc_loop:
-       vadd.u32        q10, q8, q9     @ compose 3<<96
-       vadd.u32        q1, q0, q8      @ +1
-       vadd.u32        q2, q0, q9      @ +2
-       vadd.u32        q3, q0, q10     @ +3
-       vadd.u32        q4, q1, q10
-       vadd.u32        q5, q2, q10
-       vadd.u32        q6, q3, q10
-       vadd.u32        q7, q4, q10
-       vadd.u32        q10, q5, q10    @ next counter
-
-       @ Borrow prologue from _bsaes_encrypt8 to use the opportunity
-       @ to flip byte order in 32-bit counter
-
-       vldmia          sp, {q9}                @ load round0 key
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x10           @ pass next round key
-#else
-       add             r4, r3, #264
-#endif
-       vldmia          r8, {q8}                        @ .LREVM0SR
-       mov             r5, r10                 @ pass rounds
-       vstmia          r9, {q10}                       @ save next counter
-       sub             r6, r8, #.LREVM0SR-.LSR @ pass constants
-
-       bl              _bsaes_encrypt8_alt
-
-       subs            r2, r2, #8
-       blo             .Lctr_enc_loop_done
-
-       vld1.8          {q8-q9}, [r0]!  @ load input
-       vld1.8          {q10-q11}, [r0]!
-       veor            q0, q8
-       veor            q1, q9
-       vld1.8          {q12-q13}, [r0]!
-       veor            q4, q10
-       veor            q6, q11
-       vld1.8          {q14-q15}, [r0]!
-       veor            q3, q12
-       vst1.8          {q0-q1}, [r1]!  @ write output
-       veor            q7, q13
-       veor            q2, q14
-       vst1.8          {q4}, [r1]!
-       veor            q5, q15
-       vst1.8          {q6}, [r1]!
-       vmov.i32        q8, #1                  @ compose 1<<96
-       vst1.8          {q3}, [r1]!
-       veor            q9, q9, q9
-       vst1.8          {q7}, [r1]!
-       vext.8          q8, q9, q8, #4
-       vst1.8          {q2}, [r1]!
-       vadd.u32        q9,q8,q8                @ compose 2<<96
-       vst1.8          {q5}, [r1]!
-       vldmia          r9, {q0}                        @ load counter
-
-       bne             .Lctr_enc_loop
-       b               .Lctr_enc_done
-
-.align 4
-.Lctr_enc_loop_done:
-       add             r2, r2, #8
-       vld1.8          {q8}, [r0]!     @ load input
-       veor            q0, q8
-       vst1.8          {q0}, [r1]!     @ write output
-       cmp             r2, #2
-       blo             .Lctr_enc_done
-       vld1.8          {q9}, [r0]!
-       veor            q1, q9
-       vst1.8          {q1}, [r1]!
-       beq             .Lctr_enc_done
-       vld1.8          {q10}, [r0]!
-       veor            q4, q10
-       vst1.8          {q4}, [r1]!
-       cmp             r2, #4
-       blo             .Lctr_enc_done
-       vld1.8          {q11}, [r0]!
-       veor            q6, q11
-       vst1.8          {q6}, [r1]!
-       beq             .Lctr_enc_done
-       vld1.8          {q12}, [r0]!
-       veor            q3, q12
-       vst1.8          {q3}, [r1]!
-       cmp             r2, #6
-       blo             .Lctr_enc_done
-       vld1.8          {q13}, [r0]!
-       veor            q7, q13
-       vst1.8          {q7}, [r1]!
-       beq             .Lctr_enc_done
-       vld1.8          {q14}, [r0]
-       veor            q2, q14
-       vst1.8          {q2}, [r1]!
-
-.Lctr_enc_done:
-       vmov.i32        q0, #0
-       vmov.i32        q1, #0
-#ifndef        BSAES_ASM_EXTENDED_KEY
-.Lctr_enc_bzero:                       @ wipe key schedule [if any]
-       vstmia          sp!, {q0-q1}
-       cmp             sp, r9
-       bne             .Lctr_enc_bzero
-#else
-       vstmia          sp, {q0-q1}
-#endif
-
-       mov     sp, r9
-       add     sp, #0x10               @ add sp,r9,#0x10 is no good for thumb
-       VFP_ABI_POP
-       ldmia   sp!, {r4-r10, pc}       @ return
-
-.align 4
-.Lctr_enc_short:
-       ldr     ip, [sp]                @ ctr pointer is passed on stack
-       stmdb   sp!, {r4-r8, lr}
-
-       mov     r4, r0          @ copy arguments
-       mov     r5, r1
-       mov     r6, r2
-       mov     r7, r3
-       ldr     r8, [ip, #12]           @ load counter LSW
-       vld1.8  {q1}, [ip]              @ load whole counter value
-#ifdef __ARMEL__
-       rev     r8, r8
-#endif
-       sub     sp, sp, #0x10
-       vst1.8  {q1}, [sp,:64]  @ copy counter value
-       sub     sp, sp, #0x10
-
-.Lctr_enc_short_loop:
-       add     r0, sp, #0x10           @ input counter value
-       mov     r1, sp                  @ output on the stack
-       mov     r2, r7                  @ key
-
-       bl      AES_encrypt
-
-       vld1.8  {q0}, [r4]!     @ load input
-       vld1.8  {q1}, [sp,:64]  @ load encrypted counter
-       add     r8, r8, #1
-#ifdef __ARMEL__
-       rev     r0, r8
-       str     r0, [sp, #0x1c]         @ next counter value
-#else
-       str     r8, [sp, #0x1c]         @ next counter value
-#endif
-       veor    q0,q0,q1
-       vst1.8  {q0}, [r5]!     @ store output
-       subs    r6, r6, #1
-       bne     .Lctr_enc_short_loop
-
-       vmov.i32        q0, #0
-       vmov.i32        q1, #0
-       vstmia          sp!, {q0-q1}
-
-       ldmia   sp!, {r4-r8, pc}
-.size  bsaes_ctr32_encrypt_blocks,.-bsaes_ctr32_encrypt_blocks
-.globl bsaes_xts_encrypt
-.type  bsaes_xts_encrypt,%function
-.align 4
-bsaes_xts_encrypt:
-       mov     ip, sp
-       stmdb   sp!, {r4-r10, lr}               @ 0x20
-       VFP_ABI_PUSH
-       mov     r6, sp                          @ future r3
-
-       mov     r7, r0
-       mov     r8, r1
-       mov     r9, r2
-       mov     r10, r3
-
-       sub     r0, sp, #0x10                   @ 0x10
-       bic     r0, #0xf                        @ align at 16 bytes
-       mov     sp, r0
-
-#ifdef XTS_CHAIN_TWEAK
-       ldr     r0, [ip]                        @ pointer to input tweak
-#else
-       @ generate initial tweak
-       ldr     r0, [ip, #4]                    @ iv[]
-       mov     r1, sp
-       ldr     r2, [ip, #0]                    @ key2
-       bl      AES_encrypt
-       mov     r0,sp                           @ pointer to initial tweak
-#endif
-
-       ldr     r1, [r10, #240]         @ get # of rounds
-       mov     r3, r6
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       @ allocate the key schedule on the stack
-       sub     r12, sp, r1, lsl#7              @ 128 bytes per inner round key
-       @ add   r12, #96                        @ size of bit-sliced key schedule
-       sub     r12, #48                        @ place for tweak[9]
-
-       @ populate the key schedule
-       mov     r4, r10                 @ pass key
-       mov     r5, r1                  @ pass # of rounds
-       mov     sp, r12
-       add     r12, #0x90                      @ pass key schedule
-       bl      _bsaes_key_convert
-       veor    q7, q7, q15     @ fix up last round key
-       vstmia  r12, {q7}                       @ save last round key
-#else
-       ldr     r12, [r10, #244]
-       eors    r12, #1
-       beq     0f
-
-       str     r12, [r10, #244]
-       mov     r4, r10                 @ pass key
-       mov     r5, r1                  @ pass # of rounds
-       add     r12, r10, #248                  @ pass key schedule
-       bl      _bsaes_key_convert
-       veor    q7, q7, q15     @ fix up last round key
-       vstmia  r12, {q7}
-
-.align 2
-0:     sub     sp, #0x90                       @ place for tweak[9]
-#endif
-
-       vld1.8  {q8}, [r0]                      @ initial tweak
-       adr     r2, .Lxts_magic
-
-       subs    r9, #0x80
-       blo     .Lxts_enc_short
-       b       .Lxts_enc_loop
-
-.align 4
-.Lxts_enc_loop:
-       vldmia          r2, {q5}        @ load XTS magic
-       vshr.s64        q6, q8, #63
-       mov             r0, sp
-       vand            q6, q6, q5
-       vadd.u64        q9, q8, q8
-       vst1.64         {q8}, [r0,:128]!
-       vswp            d13,d12
-       vshr.s64        q7, q9, #63
-       veor            q9, q9, q6
-       vand            q7, q7, q5
-       vadd.u64        q10, q9, q9
-       vst1.64         {q9}, [r0,:128]!
-       vswp            d15,d14
-       vshr.s64        q6, q10, #63
-       veor            q10, q10, q7
-       vand            q6, q6, q5
-       vld1.8          {q0}, [r7]!
-       vadd.u64        q11, q10, q10
-       vst1.64         {q10}, [r0,:128]!
-       vswp            d13,d12
-       vshr.s64        q7, q11, #63
-       veor            q11, q11, q6
-       vand            q7, q7, q5
-       vld1.8          {q1}, [r7]!
-       veor            q0, q0, q8
-       vadd.u64        q12, q11, q11
-       vst1.64         {q11}, [r0,:128]!
-       vswp            d15,d14
-       vshr.s64        q6, q12, #63
-       veor            q12, q12, q7
-       vand            q6, q6, q5
-       vld1.8          {q2}, [r7]!
-       veor            q1, q1, q9
-       vadd.u64        q13, q12, q12
-       vst1.64         {q12}, [r0,:128]!
-       vswp            d13,d12
-       vshr.s64        q7, q13, #63
-       veor            q13, q13, q6
-       vand            q7, q7, q5
-       vld1.8          {q3}, [r7]!
-       veor            q2, q2, q10
-       vadd.u64        q14, q13, q13
-       vst1.64         {q13}, [r0,:128]!
-       vswp            d15,d14
-       vshr.s64        q6, q14, #63
-       veor            q14, q14, q7
-       vand            q6, q6, q5
-       vld1.8          {q4}, [r7]!
-       veor            q3, q3, q11
-       vadd.u64        q15, q14, q14
-       vst1.64         {q14}, [r0,:128]!
-       vswp            d13,d12
-       vshr.s64        q7, q15, #63
-       veor            q15, q15, q6
-       vand            q7, q7, q5
-       vld1.8          {q5}, [r7]!
-       veor            q4, q4, q12
-       vadd.u64        q8, q15, q15
-       vst1.64         {q15}, [r0,:128]!
-       vswp            d15,d14
-       veor            q8, q8, q7
-       vst1.64         {q8}, [r0,:128]         @ next round tweak
-
-       vld1.8          {q6-q7}, [r7]!
-       veor            q5, q5, q13
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x90                   @ pass key schedule
-#else
-       add             r4, r10, #248                   @ pass key schedule
-#endif
-       veor            q6, q6, q14
-       mov             r5, r1                  @ pass rounds
-       veor            q7, q7, q15
-       mov             r0, sp
-
-       bl              _bsaes_encrypt8
-
-       vld1.64         {q8-q9}, [r0,:128]!
-       vld1.64         {q10-q11}, [r0,:128]!
-       veor            q0, q0, q8
-       vld1.64         {q12-q13}, [r0,:128]!
-       veor            q1, q1, q9
-       veor            q8, q4, q10
-       vst1.8          {q0-q1}, [r8]!
-       veor            q9, q6, q11
-       vld1.64         {q14-q15}, [r0,:128]!
-       veor            q10, q3, q12
-       vst1.8          {q8-q9}, [r8]!
-       veor            q11, q7, q13
-       veor            q12, q2, q14
-       vst1.8          {q10-q11}, [r8]!
-       veor            q13, q5, q15
-       vst1.8          {q12-q13}, [r8]!
-
-       vld1.64         {q8}, [r0,:128]         @ next round tweak
-
-       subs            r9, #0x80
-       bpl             .Lxts_enc_loop
-
-.Lxts_enc_short:
-       adds            r9, #0x70
-       bmi             .Lxts_enc_done
-
-       vldmia          r2, {q5}        @ load XTS magic
-       vshr.s64        q7, q8, #63
-       mov             r0, sp
-       vand            q7, q7, q5
-       vadd.u64        q9, q8, q8
-       vst1.64         {q8}, [r0,:128]!
-       vswp            d15,d14
-       vshr.s64        q6, q9, #63
-       veor            q9, q9, q7
-       vand            q6, q6, q5
-       vadd.u64        q10, q9, q9
-       vst1.64         {q9}, [r0,:128]!
-       vswp            d13,d12
-       vshr.s64        q7, q10, #63
-       veor            q10, q10, q6
-       vand            q7, q7, q5
-       vld1.8          {q0}, [r7]!
-       subs            r9, #0x10
-       bmi             .Lxts_enc_1
-       vadd.u64        q11, q10, q10
-       vst1.64         {q10}, [r0,:128]!
-       vswp            d15,d14
-       vshr.s64        q6, q11, #63
-       veor            q11, q11, q7
-       vand            q6, q6, q5
-       vld1.8          {q1}, [r7]!
-       subs            r9, #0x10
-       bmi             .Lxts_enc_2
-       veor            q0, q0, q8
-       vadd.u64        q12, q11, q11
-       vst1.64         {q11}, [r0,:128]!
-       vswp            d13,d12
-       vshr.s64        q7, q12, #63
-       veor            q12, q12, q6
-       vand            q7, q7, q5
-       vld1.8          {q2}, [r7]!
-       subs            r9, #0x10
-       bmi             .Lxts_enc_3
-       veor            q1, q1, q9
-       vadd.u64        q13, q12, q12
-       vst1.64         {q12}, [r0,:128]!
-       vswp            d15,d14
-       vshr.s64        q6, q13, #63
-       veor            q13, q13, q7
-       vand            q6, q6, q5
-       vld1.8          {q3}, [r7]!
-       subs            r9, #0x10
-       bmi             .Lxts_enc_4
-       veor            q2, q2, q10
-       vadd.u64        q14, q13, q13
-       vst1.64         {q13}, [r0,:128]!
-       vswp            d13,d12
-       vshr.s64        q7, q14, #63
-       veor            q14, q14, q6
-       vand            q7, q7, q5
-       vld1.8          {q4}, [r7]!
-       subs            r9, #0x10
-       bmi             .Lxts_enc_5
-       veor            q3, q3, q11
-       vadd.u64        q15, q14, q14
-       vst1.64         {q14}, [r0,:128]!
-       vswp            d15,d14
-       vshr.s64        q6, q15, #63
-       veor            q15, q15, q7
-       vand            q6, q6, q5
-       vld1.8          {q5}, [r7]!
-       subs            r9, #0x10
-       bmi             .Lxts_enc_6
-       veor            q4, q4, q12
-       sub             r9, #0x10
-       vst1.64         {q15}, [r0,:128]                @ next round tweak
-
-       vld1.8          {q6}, [r7]!
-       veor            q5, q5, q13
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x90                   @ pass key schedule
-#else
-       add             r4, r10, #248                   @ pass key schedule
-#endif
-       veor            q6, q6, q14
-       mov             r5, r1                  @ pass rounds
-       mov             r0, sp
-
-       bl              _bsaes_encrypt8
-
-       vld1.64         {q8-q9}, [r0,:128]!
-       vld1.64         {q10-q11}, [r0,:128]!
-       veor            q0, q0, q8
-       vld1.64         {q12-q13}, [r0,:128]!
-       veor            q1, q1, q9
-       veor            q8, q4, q10
-       vst1.8          {q0-q1}, [r8]!
-       veor            q9, q6, q11
-       vld1.64         {q14}, [r0,:128]!
-       veor            q10, q3, q12
-       vst1.8          {q8-q9}, [r8]!
-       veor            q11, q7, q13
-       veor            q12, q2, q14
-       vst1.8          {q10-q11}, [r8]!
-       vst1.8          {q12}, [r8]!
-
-       vld1.64         {q8}, [r0,:128]         @ next round tweak
-       b               .Lxts_enc_done
-.align 4
-.Lxts_enc_6:
-       vst1.64         {q14}, [r0,:128]                @ next round tweak
-
-       veor            q4, q4, q12
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x90                   @ pass key schedule
-#else
-       add             r4, r10, #248                   @ pass key schedule
-#endif
-       veor            q5, q5, q13
-       mov             r5, r1                  @ pass rounds
-       mov             r0, sp
-
-       bl              _bsaes_encrypt8
-
-       vld1.64         {q8-q9}, [r0,:128]!
-       vld1.64         {q10-q11}, [r0,:128]!
-       veor            q0, q0, q8
-       vld1.64         {q12-q13}, [r0,:128]!
-       veor            q1, q1, q9
-       veor            q8, q4, q10
-       vst1.8          {q0-q1}, [r8]!
-       veor            q9, q6, q11
-       veor            q10, q3, q12
-       vst1.8          {q8-q9}, [r8]!
-       veor            q11, q7, q13
-       vst1.8          {q10-q11}, [r8]!
-
-       vld1.64         {q8}, [r0,:128]         @ next round tweak
-       b               .Lxts_enc_done
-
-@ put this in range for both ARM and Thumb mode adr instructions
-.align 5
-.Lxts_magic:
-       .quad   1, 0x87
-
-.align 5
-.Lxts_enc_5:
-       vst1.64         {q13}, [r0,:128]                @ next round tweak
-
-       veor            q3, q3, q11
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x90                   @ pass key schedule
-#else
-       add             r4, r10, #248                   @ pass key schedule
-#endif
-       veor            q4, q4, q12
-       mov             r5, r1                  @ pass rounds
-       mov             r0, sp
-
-       bl              _bsaes_encrypt8
-
-       vld1.64         {q8-q9}, [r0,:128]!
-       vld1.64         {q10-q11}, [r0,:128]!
-       veor            q0, q0, q8
-       vld1.64         {q12}, [r0,:128]!
-       veor            q1, q1, q9
-       veor            q8, q4, q10
-       vst1.8          {q0-q1}, [r8]!
-       veor            q9, q6, q11
-       veor            q10, q3, q12
-       vst1.8          {q8-q9}, [r8]!
-       vst1.8          {q10}, [r8]!
-
-       vld1.64         {q8}, [r0,:128]         @ next round tweak
-       b               .Lxts_enc_done
-.align 4
-.Lxts_enc_4:
-       vst1.64         {q12}, [r0,:128]                @ next round tweak
-
-       veor            q2, q2, q10
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x90                   @ pass key schedule
-#else
-       add             r4, r10, #248                   @ pass key schedule
-#endif
-       veor            q3, q3, q11
-       mov             r5, r1                  @ pass rounds
-       mov             r0, sp
-
-       bl              _bsaes_encrypt8
-
-       vld1.64         {q8-q9}, [r0,:128]!
-       vld1.64         {q10-q11}, [r0,:128]!
-       veor            q0, q0, q8
-       veor            q1, q1, q9
-       veor            q8, q4, q10
-       vst1.8          {q0-q1}, [r8]!
-       veor            q9, q6, q11
-       vst1.8          {q8-q9}, [r8]!
-
-       vld1.64         {q8}, [r0,:128]         @ next round tweak
-       b               .Lxts_enc_done
-.align 4
-.Lxts_enc_3:
-       vst1.64         {q11}, [r0,:128]                @ next round tweak
-
-       veor            q1, q1, q9
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x90                   @ pass key schedule
-#else
-       add             r4, r10, #248                   @ pass key schedule
-#endif
-       veor            q2, q2, q10
-       mov             r5, r1                  @ pass rounds
-       mov             r0, sp
-
-       bl              _bsaes_encrypt8
-
-       vld1.64         {q8-q9}, [r0,:128]!
-       vld1.64         {q10}, [r0,:128]!
-       veor            q0, q0, q8
-       veor            q1, q1, q9
-       veor            q8, q4, q10
-       vst1.8          {q0-q1}, [r8]!
-       vst1.8          {q8}, [r8]!
-
-       vld1.64         {q8}, [r0,:128]         @ next round tweak
-       b               .Lxts_enc_done
-.align 4
-.Lxts_enc_2:
-       vst1.64         {q10}, [r0,:128]                @ next round tweak
-
-       veor            q0, q0, q8
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x90                   @ pass key schedule
-#else
-       add             r4, r10, #248                   @ pass key schedule
-#endif
-       veor            q1, q1, q9
-       mov             r5, r1                  @ pass rounds
-       mov             r0, sp
-
-       bl              _bsaes_encrypt8
-
-       vld1.64         {q8-q9}, [r0,:128]!
-       veor            q0, q0, q8
-       veor            q1, q1, q9
-       vst1.8          {q0-q1}, [r8]!
-
-       vld1.64         {q8}, [r0,:128]         @ next round tweak
-       b               .Lxts_enc_done
-.align 4
-.Lxts_enc_1:
-       mov             r0, sp
-       veor            q0, q8
-       mov             r1, sp
-       vst1.8          {q0}, [sp,:128]
-       mov             r2, r10
-       mov             r4, r3                          @ preserve fp
-
-       bl              AES_encrypt
-
-       vld1.8          {q0}, [sp,:128]
-       veor            q0, q0, q8
-       vst1.8          {q0}, [r8]!
-       mov             r3, r4
-
-       vmov            q8, q9          @ next round tweak
-
-.Lxts_enc_done:
-#ifndef        XTS_CHAIN_TWEAK
-       adds            r9, #0x10
-       beq             .Lxts_enc_ret
-       sub             r6, r8, #0x10
-
-.Lxts_enc_steal:
-       ldrb            r0, [r7], #1
-       ldrb            r1, [r8, #-0x10]
-       strb            r0, [r8, #-0x10]
-       strb            r1, [r8], #1
-
-       subs            r9, #1
-       bhi             .Lxts_enc_steal
-
-       vld1.8          {q0}, [r6]
-       mov             r0, sp
-       veor            q0, q0, q8
-       mov             r1, sp
-       vst1.8          {q0}, [sp,:128]
-       mov             r2, r10
-       mov             r4, r3                  @ preserve fp
-
-       bl              AES_encrypt
-
-       vld1.8          {q0}, [sp,:128]
-       veor            q0, q0, q8
-       vst1.8          {q0}, [r6]
-       mov             r3, r4
-#endif
-
-.Lxts_enc_ret:
-       bic             r0, r3, #0xf
-       vmov.i32        q0, #0
-       vmov.i32        q1, #0
-#ifdef XTS_CHAIN_TWEAK
-       ldr             r1, [r3, #0x20+VFP_ABI_FRAME]   @ chain tweak
-#endif
-.Lxts_enc_bzero:                               @ wipe key schedule [if any]
-       vstmia          sp!, {q0-q1}
-       cmp             sp, r0
-       bne             .Lxts_enc_bzero
-
-       mov             sp, r3
-#ifdef XTS_CHAIN_TWEAK
-       vst1.8          {q8}, [r1]
-#endif
-       VFP_ABI_POP
-       ldmia           sp!, {r4-r10, pc}       @ return
-
-.size  bsaes_xts_encrypt,.-bsaes_xts_encrypt
-
-.globl bsaes_xts_decrypt
-.type  bsaes_xts_decrypt,%function
-.align 4
-bsaes_xts_decrypt:
-       mov     ip, sp
-       stmdb   sp!, {r4-r10, lr}               @ 0x20
-       VFP_ABI_PUSH
-       mov     r6, sp                          @ future r3
-
-       mov     r7, r0
-       mov     r8, r1
-       mov     r9, r2
-       mov     r10, r3
-
-       sub     r0, sp, #0x10                   @ 0x10
-       bic     r0, #0xf                        @ align at 16 bytes
-       mov     sp, r0
-
-#ifdef XTS_CHAIN_TWEAK
-       ldr     r0, [ip]                        @ pointer to input tweak
-#else
-       @ generate initial tweak
-       ldr     r0, [ip, #4]                    @ iv[]
-       mov     r1, sp
-       ldr     r2, [ip, #0]                    @ key2
-       bl      AES_encrypt
-       mov     r0, sp                          @ pointer to initial tweak
-#endif
-
-       ldr     r1, [r10, #240]         @ get # of rounds
-       mov     r3, r6
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       @ allocate the key schedule on the stack
-       sub     r12, sp, r1, lsl#7              @ 128 bytes per inner round key
-       @ add   r12, #96                        @ size of bit-sliced key schedule
-       sub     r12, #48                        @ place for tweak[9]
-
-       @ populate the key schedule
-       mov     r4, r10                 @ pass key
-       mov     r5, r1                  @ pass # of rounds
-       mov     sp, r12
-       add     r12, #0x90                      @ pass key schedule
-       bl      _bsaes_key_convert
-       add     r4, sp, #0x90
-       vldmia  r4, {q6}
-       vstmia  r12,  {q15}             @ save last round key
-       veor    q7, q7, q6      @ fix up round 0 key
-       vstmia  r4, {q7}
-#else
-       ldr     r12, [r10, #244]
-       eors    r12, #1
-       beq     0f
-
-       str     r12, [r10, #244]
-       mov     r4, r10                 @ pass key
-       mov     r5, r1                  @ pass # of rounds
-       add     r12, r10, #248                  @ pass key schedule
-       bl      _bsaes_key_convert
-       add     r4, r10, #248
-       vldmia  r4, {q6}
-       vstmia  r12,  {q15}             @ save last round key
-       veor    q7, q7, q6      @ fix up round 0 key
-       vstmia  r4, {q7}
-
-.align 2
-0:     sub     sp, #0x90                       @ place for tweak[9]
-#endif
-       vld1.8  {q8}, [r0]                      @ initial tweak
-       adr     r2, .Lxts_magic
-
-#ifndef        XTS_CHAIN_TWEAK
-       tst     r9, #0xf                        @ if not multiple of 16
-       it      ne                              @ Thumb2 thing, sanity check in ARM
-       subne   r9, #0x10                       @ subtract another 16 bytes
-#endif
-       subs    r9, #0x80
-
-       blo     .Lxts_dec_short
-       b       .Lxts_dec_loop
-
-.align 4
-.Lxts_dec_loop:
-       vldmia          r2, {q5}        @ load XTS magic
-       vshr.s64        q6, q8, #63
-       mov             r0, sp
-       vand            q6, q6, q5
-       vadd.u64        q9, q8, q8
-       vst1.64         {q8}, [r0,:128]!
-       vswp            d13,d12
-       vshr.s64        q7, q9, #63
-       veor            q9, q9, q6
-       vand            q7, q7, q5
-       vadd.u64        q10, q9, q9
-       vst1.64         {q9}, [r0,:128]!
-       vswp            d15,d14
-       vshr.s64        q6, q10, #63
-       veor            q10, q10, q7
-       vand            q6, q6, q5
-       vld1.8          {q0}, [r7]!
-       vadd.u64        q11, q10, q10
-       vst1.64         {q10}, [r0,:128]!
-       vswp            d13,d12
-       vshr.s64        q7, q11, #63
-       veor            q11, q11, q6
-       vand            q7, q7, q5
-       vld1.8          {q1}, [r7]!
-       veor            q0, q0, q8
-       vadd.u64        q12, q11, q11
-       vst1.64         {q11}, [r0,:128]!
-       vswp            d15,d14
-       vshr.s64        q6, q12, #63
-       veor            q12, q12, q7
-       vand            q6, q6, q5
-       vld1.8          {q2}, [r7]!
-       veor            q1, q1, q9
-       vadd.u64        q13, q12, q12
-       vst1.64         {q12}, [r0,:128]!
-       vswp            d13,d12
-       vshr.s64        q7, q13, #63
-       veor            q13, q13, q6
-       vand            q7, q7, q5
-       vld1.8          {q3}, [r7]!
-       veor            q2, q2, q10
-       vadd.u64        q14, q13, q13
-       vst1.64         {q13}, [r0,:128]!
-       vswp            d15,d14
-       vshr.s64        q6, q14, #63
-       veor            q14, q14, q7
-       vand            q6, q6, q5
-       vld1.8          {q4}, [r7]!
-       veor            q3, q3, q11
-       vadd.u64        q15, q14, q14
-       vst1.64         {q14}, [r0,:128]!
-       vswp            d13,d12
-       vshr.s64        q7, q15, #63
-       veor            q15, q15, q6
-       vand            q7, q7, q5
-       vld1.8          {q5}, [r7]!
-       veor            q4, q4, q12
-       vadd.u64        q8, q15, q15
-       vst1.64         {q15}, [r0,:128]!
-       vswp            d15,d14
-       veor            q8, q8, q7
-       vst1.64         {q8}, [r0,:128]         @ next round tweak
-
-       vld1.8          {q6-q7}, [r7]!
-       veor            q5, q5, q13
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x90                   @ pass key schedule
-#else
-       add             r4, r10, #248                   @ pass key schedule
-#endif
-       veor            q6, q6, q14
-       mov             r5, r1                  @ pass rounds
-       veor            q7, q7, q15
-       mov             r0, sp
-
-       bl              _bsaes_decrypt8
-
-       vld1.64         {q8-q9}, [r0,:128]!
-       vld1.64         {q10-q11}, [r0,:128]!
-       veor            q0, q0, q8
-       vld1.64         {q12-q13}, [r0,:128]!
-       veor            q1, q1, q9
-       veor            q8, q6, q10
-       vst1.8          {q0-q1}, [r8]!
-       veor            q9, q4, q11
-       vld1.64         {q14-q15}, [r0,:128]!
-       veor            q10, q2, q12
-       vst1.8          {q8-q9}, [r8]!
-       veor            q11, q7, q13
-       veor            q12, q3, q14
-       vst1.8          {q10-q11}, [r8]!
-       veor            q13, q5, q15
-       vst1.8          {q12-q13}, [r8]!
-
-       vld1.64         {q8}, [r0,:128]         @ next round tweak
-
-       subs            r9, #0x80
-       bpl             .Lxts_dec_loop
-
-.Lxts_dec_short:
-       adds            r9, #0x70
-       bmi             .Lxts_dec_done
-
-       vldmia          r2, {q5}        @ load XTS magic
-       vshr.s64        q7, q8, #63
-       mov             r0, sp
-       vand            q7, q7, q5
-       vadd.u64        q9, q8, q8
-       vst1.64         {q8}, [r0,:128]!
-       vswp            d15,d14
-       vshr.s64        q6, q9, #63
-       veor            q9, q9, q7
-       vand            q6, q6, q5
-       vadd.u64        q10, q9, q9
-       vst1.64         {q9}, [r0,:128]!
-       vswp            d13,d12
-       vshr.s64        q7, q10, #63
-       veor            q10, q10, q6
-       vand            q7, q7, q5
-       vld1.8          {q0}, [r7]!
-       subs            r9, #0x10
-       bmi             .Lxts_dec_1
-       vadd.u64        q11, q10, q10
-       vst1.64         {q10}, [r0,:128]!
-       vswp            d15,d14
-       vshr.s64        q6, q11, #63
-       veor            q11, q11, q7
-       vand            q6, q6, q5
-       vld1.8          {q1}, [r7]!
-       subs            r9, #0x10
-       bmi             .Lxts_dec_2
-       veor            q0, q0, q8
-       vadd.u64        q12, q11, q11
-       vst1.64         {q11}, [r0,:128]!
-       vswp            d13,d12
-       vshr.s64        q7, q12, #63
-       veor            q12, q12, q6
-       vand            q7, q7, q5
-       vld1.8          {q2}, [r7]!
-       subs            r9, #0x10
-       bmi             .Lxts_dec_3
-       veor            q1, q1, q9
-       vadd.u64        q13, q12, q12
-       vst1.64         {q12}, [r0,:128]!
-       vswp            d15,d14
-       vshr.s64        q6, q13, #63
-       veor            q13, q13, q7
-       vand            q6, q6, q5
-       vld1.8          {q3}, [r7]!
-       subs            r9, #0x10
-       bmi             .Lxts_dec_4
-       veor            q2, q2, q10
-       vadd.u64        q14, q13, q13
-       vst1.64         {q13}, [r0,:128]!
-       vswp            d13,d12
-       vshr.s64        q7, q14, #63
-       veor            q14, q14, q6
-       vand            q7, q7, q5
-       vld1.8          {q4}, [r7]!
-       subs            r9, #0x10
-       bmi             .Lxts_dec_5
-       veor            q3, q3, q11
-       vadd.u64        q15, q14, q14
-       vst1.64         {q14}, [r0,:128]!
-       vswp            d15,d14
-       vshr.s64        q6, q15, #63
-       veor            q15, q15, q7
-       vand            q6, q6, q5
-       vld1.8          {q5}, [r7]!
-       subs            r9, #0x10
-       bmi             .Lxts_dec_6
-       veor            q4, q4, q12
-       sub             r9, #0x10
-       vst1.64         {q15}, [r0,:128]                @ next round tweak
-
-       vld1.8          {q6}, [r7]!
-       veor            q5, q5, q13
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x90                   @ pass key schedule
-#else
-       add             r4, r10, #248                   @ pass key schedule
-#endif
-       veor            q6, q6, q14
-       mov             r5, r1                  @ pass rounds
-       mov             r0, sp
-
-       bl              _bsaes_decrypt8
-
-       vld1.64         {q8-q9}, [r0,:128]!
-       vld1.64         {q10-q11}, [r0,:128]!
-       veor            q0, q0, q8
-       vld1.64         {q12-q13}, [r0,:128]!
-       veor            q1, q1, q9
-       veor            q8, q6, q10
-       vst1.8          {q0-q1}, [r8]!
-       veor            q9, q4, q11
-       vld1.64         {q14}, [r0,:128]!
-       veor            q10, q2, q12
-       vst1.8          {q8-q9}, [r8]!
-       veor            q11, q7, q13
-       veor            q12, q3, q14
-       vst1.8          {q10-q11}, [r8]!
-       vst1.8          {q12}, [r8]!
-
-       vld1.64         {q8}, [r0,:128]         @ next round tweak
-       b               .Lxts_dec_done
-.align 4
-.Lxts_dec_6:
-       vst1.64         {q14}, [r0,:128]                @ next round tweak
-
-       veor            q4, q4, q12
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x90                   @ pass key schedule
-#else
-       add             r4, r10, #248                   @ pass key schedule
-#endif
-       veor            q5, q5, q13
-       mov             r5, r1                  @ pass rounds
-       mov             r0, sp
-
-       bl              _bsaes_decrypt8
-
-       vld1.64         {q8-q9}, [r0,:128]!
-       vld1.64         {q10-q11}, [r0,:128]!
-       veor            q0, q0, q8
-       vld1.64         {q12-q13}, [r0,:128]!
-       veor            q1, q1, q9
-       veor            q8, q6, q10
-       vst1.8          {q0-q1}, [r8]!
-       veor            q9, q4, q11
-       veor            q10, q2, q12
-       vst1.8          {q8-q9}, [r8]!
-       veor            q11, q7, q13
-       vst1.8          {q10-q11}, [r8]!
-
-       vld1.64         {q8}, [r0,:128]         @ next round tweak
-       b               .Lxts_dec_done
-.align 4
-.Lxts_dec_5:
-       vst1.64         {q13}, [r0,:128]                @ next round tweak
-
-       veor            q3, q3, q11
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x90                   @ pass key schedule
-#else
-       add             r4, r10, #248                   @ pass key schedule
-#endif
-       veor            q4, q4, q12
-       mov             r5, r1                  @ pass rounds
-       mov             r0, sp
-
-       bl              _bsaes_decrypt8
-
-       vld1.64         {q8-q9}, [r0,:128]!
-       vld1.64         {q10-q11}, [r0,:128]!
-       veor            q0, q0, q8
-       vld1.64         {q12}, [r0,:128]!
-       veor            q1, q1, q9
-       veor            q8, q6, q10
-       vst1.8          {q0-q1}, [r8]!
-       veor            q9, q4, q11
-       veor            q10, q2, q12
-       vst1.8          {q8-q9}, [r8]!
-       vst1.8          {q10}, [r8]!
-
-       vld1.64         {q8}, [r0,:128]         @ next round tweak
-       b               .Lxts_dec_done
-.align 4
-.Lxts_dec_4:
-       vst1.64         {q12}, [r0,:128]                @ next round tweak
-
-       veor            q2, q2, q10
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x90                   @ pass key schedule
-#else
-       add             r4, r10, #248                   @ pass key schedule
-#endif
-       veor            q3, q3, q11
-       mov             r5, r1                  @ pass rounds
-       mov             r0, sp
-
-       bl              _bsaes_decrypt8
-
-       vld1.64         {q8-q9}, [r0,:128]!
-       vld1.64         {q10-q11}, [r0,:128]!
-       veor            q0, q0, q8
-       veor            q1, q1, q9
-       veor            q8, q6, q10
-       vst1.8          {q0-q1}, [r8]!
-       veor            q9, q4, q11
-       vst1.8          {q8-q9}, [r8]!
-
-       vld1.64         {q8}, [r0,:128]         @ next round tweak
-       b               .Lxts_dec_done
-.align 4
-.Lxts_dec_3:
-       vst1.64         {q11}, [r0,:128]                @ next round tweak
-
-       veor            q1, q1, q9
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x90                   @ pass key schedule
-#else
-       add             r4, r10, #248                   @ pass key schedule
-#endif
-       veor            q2, q2, q10
-       mov             r5, r1                  @ pass rounds
-       mov             r0, sp
-
-       bl              _bsaes_decrypt8
-
-       vld1.64         {q8-q9}, [r0,:128]!
-       vld1.64         {q10}, [r0,:128]!
-       veor            q0, q0, q8
-       veor            q1, q1, q9
-       veor            q8, q6, q10
-       vst1.8          {q0-q1}, [r8]!
-       vst1.8          {q8}, [r8]!
-
-       vld1.64         {q8}, [r0,:128]         @ next round tweak
-       b               .Lxts_dec_done
-.align 4
-.Lxts_dec_2:
-       vst1.64         {q10}, [r0,:128]                @ next round tweak
-
-       veor            q0, q0, q8
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x90                   @ pass key schedule
-#else
-       add             r4, r10, #248                   @ pass key schedule
-#endif
-       veor            q1, q1, q9
-       mov             r5, r1                  @ pass rounds
-       mov             r0, sp
-
-       bl              _bsaes_decrypt8
-
-       vld1.64         {q8-q9}, [r0,:128]!
-       veor            q0, q0, q8
-       veor            q1, q1, q9
-       vst1.8          {q0-q1}, [r8]!
-
-       vld1.64         {q8}, [r0,:128]         @ next round tweak
-       b               .Lxts_dec_done
-.align 4
-.Lxts_dec_1:
-       mov             r0, sp
-       veor            q0, q8
-       mov             r1, sp
-       vst1.8          {q0}, [sp,:128]
-       mov             r2, r10
-       mov             r4, r3                          @ preserve fp
-       mov             r5, r2                  @ preserve magic
-
-       bl              AES_decrypt
-
-       vld1.8          {q0}, [sp,:128]
-       veor            q0, q0, q8
-       vst1.8          {q0}, [r8]!
-       mov             r3, r4
-       mov             r2, r5
-
-       vmov            q8, q9          @ next round tweak
-
-.Lxts_dec_done:
-#ifndef        XTS_CHAIN_TWEAK
-       adds            r9, #0x10
-       beq             .Lxts_dec_ret
-
-       @ calculate one round of extra tweak for the stolen ciphertext
-       vldmia          r2, {q5}
-       vshr.s64        q6, q8, #63
-       vand            q6, q6, q5
-       vadd.u64        q9, q8, q8
-       vswp            d13,d12
-       veor            q9, q9, q6
-
-       @ perform the final decryption with the last tweak value
-       vld1.8          {q0}, [r7]!
-       mov             r0, sp
-       veor            q0, q0, q9
-       mov             r1, sp
-       vst1.8          {q0}, [sp,:128]
-       mov             r2, r10
-       mov             r4, r3                  @ preserve fp
-
-       bl              AES_decrypt
-
-       vld1.8          {q0}, [sp,:128]
-       veor            q0, q0, q9
-       vst1.8          {q0}, [r8]
-
-       mov             r6, r8
-.Lxts_dec_steal:
-       ldrb            r1, [r8]
-       ldrb            r0, [r7], #1
-       strb            r1, [r8, #0x10]
-       strb            r0, [r8], #1
-
-       subs            r9, #1
-       bhi             .Lxts_dec_steal
-
-       vld1.8          {q0}, [r6]
-       mov             r0, sp
-       veor            q0, q8
-       mov             r1, sp
-       vst1.8          {q0}, [sp,:128]
-       mov             r2, r10
-
-       bl              AES_decrypt
-
-       vld1.8          {q0}, [sp,:128]
-       veor            q0, q0, q8
-       vst1.8          {q0}, [r6]
-       mov             r3, r4
-#endif
-
-.Lxts_dec_ret:
-       bic             r0, r3, #0xf
-       vmov.i32        q0, #0
-       vmov.i32        q1, #0
-#ifdef XTS_CHAIN_TWEAK
-       ldr             r1, [r3, #0x20+VFP_ABI_FRAME]   @ chain tweak
-#endif
-.Lxts_dec_bzero:                               @ wipe key schedule [if any]
-       vstmia          sp!, {q0-q1}
-       cmp             sp, r0
-       bne             .Lxts_dec_bzero
-
-       mov             sp, r3
-#ifdef XTS_CHAIN_TWEAK
-       vst1.8          {q8}, [r1]
-#endif
-       VFP_ABI_POP
-       ldmia           sp!, {r4-r10, pc}       @ return
-
-.size  bsaes_xts_decrypt,.-bsaes_xts_decrypt
-#endif
diff --git a/arch/arm/crypto/aesbs-glue.c b/arch/arm/crypto/aesbs-glue.c
deleted file mode 100644 (file)
index d8e06de..0000000
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- * linux/arch/arm/crypto/aesbs-glue.c - glue code for NEON bit sliced AES
- *
- * Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <asm/neon.h>
-#include <crypto/aes.h>
-#include <crypto/cbc.h>
-#include <crypto/internal/simd.h>
-#include <crypto/internal/skcipher.h>
-#include <linux/module.h>
-#include <crypto/xts.h>
-
-#include "aes_glue.h"
-
-#define BIT_SLICED_KEY_MAXSIZE (128 * (AES_MAXNR - 1) + 2 * AES_BLOCK_SIZE)
-
-struct BS_KEY {
-       struct AES_KEY  rk;
-       int             converted;
-       u8 __aligned(8) bs[BIT_SLICED_KEY_MAXSIZE];
-} __aligned(8);
-
-asmlinkage void bsaes_enc_key_convert(u8 out[], struct AES_KEY const *in);
-asmlinkage void bsaes_dec_key_convert(u8 out[], struct AES_KEY const *in);
-
-asmlinkage void bsaes_cbc_encrypt(u8 const in[], u8 out[], u32 bytes,
-                                 struct BS_KEY *key, u8 iv[]);
-
-asmlinkage void bsaes_ctr32_encrypt_blocks(u8 const in[], u8 out[], u32 blocks,
-                                          struct BS_KEY *key, u8 const iv[]);
-
-asmlinkage void bsaes_xts_encrypt(u8 const in[], u8 out[], u32 bytes,
-                                 struct BS_KEY *key, u8 tweak[]);
-
-asmlinkage void bsaes_xts_decrypt(u8 const in[], u8 out[], u32 bytes,
-                                 struct BS_KEY *key, u8 tweak[]);
-
-struct aesbs_cbc_ctx {
-       struct AES_KEY  enc;
-       struct BS_KEY   dec;
-};
-
-struct aesbs_ctr_ctx {
-       struct BS_KEY   enc;
-};
-
-struct aesbs_xts_ctx {
-       struct BS_KEY   enc;
-       struct BS_KEY   dec;
-       struct AES_KEY  twkey;
-};
-
-static int aesbs_cbc_set_key(struct crypto_skcipher *tfm, const u8 *in_key,
-                            unsigned int key_len)
-{
-       struct aesbs_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
-       int bits = key_len * 8;
-
-       if (private_AES_set_encrypt_key(in_key, bits, &ctx->enc)) {
-               crypto_skcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
-               return -EINVAL;
-       }
-       ctx->dec.rk = ctx->enc;
-       private_AES_set_decrypt_key(in_key, bits, &ctx->dec.rk);
-       ctx->dec.converted = 0;
-       return 0;
-}
-
-static int aesbs_ctr_set_key(struct crypto_skcipher *tfm, const u8 *in_key,
-                            unsigned int key_len)
-{
-       struct aesbs_ctr_ctx *ctx = crypto_skcipher_ctx(tfm);
-       int bits = key_len * 8;
-
-       if (private_AES_set_encrypt_key(in_key, bits, &ctx->enc.rk)) {
-               crypto_skcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
-               return -EINVAL;
-       }
-       ctx->enc.converted = 0;
-       return 0;
-}
-
-static int aesbs_xts_set_key(struct crypto_skcipher *tfm, const u8 *in_key,
-                            unsigned int key_len)
-{
-       struct aesbs_xts_ctx *ctx = crypto_skcipher_ctx(tfm);
-       int bits = key_len * 4;
-       int err;
-
-       err = xts_verify_key(tfm, in_key, key_len);
-       if (err)
-               return err;
-
-       if (private_AES_set_encrypt_key(in_key, bits, &ctx->enc.rk)) {
-               crypto_skcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
-               return -EINVAL;
-       }
-       ctx->dec.rk = ctx->enc.rk;
-       private_AES_set_decrypt_key(in_key, bits, &ctx->dec.rk);
-       private_AES_set_encrypt_key(in_key + key_len / 2, bits, &ctx->twkey);
-       ctx->enc.converted = ctx->dec.converted = 0;
-       return 0;
-}
-
-static inline void aesbs_encrypt_one(struct crypto_skcipher *tfm,
-                                    const u8 *src, u8 *dst)
-{
-       struct aesbs_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
-
-       AES_encrypt(src, dst, &ctx->enc);
-}
-
-static int aesbs_cbc_encrypt(struct skcipher_request *req)
-{
-       return crypto_cbc_encrypt_walk(req, aesbs_encrypt_one);
-}
-
-static inline void aesbs_decrypt_one(struct crypto_skcipher *tfm,
-                                    const u8 *src, u8 *dst)
-{
-       struct aesbs_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
-
-       AES_decrypt(src, dst, &ctx->dec.rk);
-}
-
-static int aesbs_cbc_decrypt(struct skcipher_request *req)
-{
-       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
-       struct aesbs_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
-       struct skcipher_walk walk;
-       unsigned int nbytes;
-       int err;
-
-       for (err = skcipher_walk_virt(&walk, req, false);
-            (nbytes = walk.nbytes); err = skcipher_walk_done(&walk, nbytes)) {
-               u32 blocks = nbytes / AES_BLOCK_SIZE;
-               u8 *dst = walk.dst.virt.addr;
-               u8 *src = walk.src.virt.addr;
-               u8 *iv = walk.iv;
-
-               if (blocks >= 8) {
-                       kernel_neon_begin();
-                       bsaes_cbc_encrypt(src, dst, nbytes, &ctx->dec, iv);
-                       kernel_neon_end();
-                       nbytes %= AES_BLOCK_SIZE;
-                       continue;
-               }
-
-               nbytes = crypto_cbc_decrypt_blocks(&walk, tfm,
-                                                  aesbs_decrypt_one);
-       }
-       return err;
-}
-
-static void inc_be128_ctr(__be32 ctr[], u32 addend)
-{
-       int i;
-
-       for (i = 3; i >= 0; i--, addend = 1) {
-               u32 n = be32_to_cpu(ctr[i]) + addend;
-
-               ctr[i] = cpu_to_be32(n);
-               if (n >= addend)
-                       break;
-       }
-}
-
-static int aesbs_ctr_encrypt(struct skcipher_request *req)
-{
-       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
-       struct aesbs_ctr_ctx *ctx = crypto_skcipher_ctx(tfm);
-       struct skcipher_walk walk;
-       u32 blocks;
-       int err;
-
-       err = skcipher_walk_virt(&walk, req, false);
-
-       while ((blocks = walk.nbytes / AES_BLOCK_SIZE)) {
-               u32 tail = walk.nbytes % AES_BLOCK_SIZE;
-               __be32 *ctr = (__be32 *)walk.iv;
-               u32 headroom = UINT_MAX - be32_to_cpu(ctr[3]);
-
-               /* avoid 32 bit counter overflow in the NEON code */
-               if (unlikely(headroom < blocks)) {
-                       blocks = headroom + 1;
-                       tail = walk.nbytes - blocks * AES_BLOCK_SIZE;
-               }
-               kernel_neon_begin();
-               bsaes_ctr32_encrypt_blocks(walk.src.virt.addr,
-                                          walk.dst.virt.addr, blocks,
-                                          &ctx->enc, walk.iv);
-               kernel_neon_end();
-               inc_be128_ctr(ctr, blocks);
-
-               err = skcipher_walk_done(&walk, tail);
-       }
-       if (walk.nbytes) {
-               u8 *tdst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE;
-               u8 *tsrc = walk.src.virt.addr + blocks * AES_BLOCK_SIZE;
-               u8 ks[AES_BLOCK_SIZE];
-
-               AES_encrypt(walk.iv, ks, &ctx->enc.rk);
-               if (tdst != tsrc)
-                       memcpy(tdst, tsrc, walk.nbytes);
-               crypto_xor(tdst, ks, walk.nbytes);
-               err = skcipher_walk_done(&walk, 0);
-       }
-       return err;
-}
-
-static int aesbs_xts_encrypt(struct skcipher_request *req)
-{
-       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
-       struct aesbs_xts_ctx *ctx = crypto_skcipher_ctx(tfm);
-       struct skcipher_walk walk;
-       int err;
-
-       err = skcipher_walk_virt(&walk, req, false);
-
-       /* generate the initial tweak */
-       AES_encrypt(walk.iv, walk.iv, &ctx->twkey);
-
-       while (walk.nbytes) {
-               kernel_neon_begin();
-               bsaes_xts_encrypt(walk.src.virt.addr, walk.dst.virt.addr,
-                                 walk.nbytes, &ctx->enc, walk.iv);
-               kernel_neon_end();
-               err = skcipher_walk_done(&walk, walk.nbytes % AES_BLOCK_SIZE);
-       }
-       return err;
-}
-
-static int aesbs_xts_decrypt(struct skcipher_request *req)
-{
-       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
-       struct aesbs_xts_ctx *ctx = crypto_skcipher_ctx(tfm);
-       struct skcipher_walk walk;
-       int err;
-
-       err = skcipher_walk_virt(&walk, req, false);
-
-       /* generate the initial tweak */
-       AES_encrypt(walk.iv, walk.iv, &ctx->twkey);
-
-       while (walk.nbytes) {
-               kernel_neon_begin();
-               bsaes_xts_decrypt(walk.src.virt.addr, walk.dst.virt.addr,
-                                 walk.nbytes, &ctx->dec, walk.iv);
-               kernel_neon_end();
-               err = skcipher_walk_done(&walk, walk.nbytes % AES_BLOCK_SIZE);
-       }
-       return err;
-}
-
-static struct skcipher_alg aesbs_algs[] = { {
-       .base = {
-               .cra_name               = "__cbc(aes)",
-               .cra_driver_name        = "__cbc-aes-neonbs",
-               .cra_priority           = 300,
-               .cra_flags              = CRYPTO_ALG_INTERNAL,
-               .cra_blocksize          = AES_BLOCK_SIZE,
-               .cra_ctxsize            = sizeof(struct aesbs_cbc_ctx),
-               .cra_alignmask          = 7,
-               .cra_module             = THIS_MODULE,
-       },
-       .min_keysize    = AES_MIN_KEY_SIZE,
-       .max_keysize    = AES_MAX_KEY_SIZE,
-       .ivsize         = AES_BLOCK_SIZE,
-       .setkey         = aesbs_cbc_set_key,
-       .encrypt        = aesbs_cbc_encrypt,
-       .decrypt        = aesbs_cbc_decrypt,
-}, {
-       .base = {
-               .cra_name               = "__ctr(aes)",
-               .cra_driver_name        = "__ctr-aes-neonbs",
-               .cra_priority           = 300,
-               .cra_flags              = CRYPTO_ALG_INTERNAL,
-               .cra_blocksize          = 1,
-               .cra_ctxsize            = sizeof(struct aesbs_ctr_ctx),
-               .cra_alignmask          = 7,
-               .cra_module             = THIS_MODULE,
-       },
-       .min_keysize    = AES_MIN_KEY_SIZE,
-       .max_keysize    = AES_MAX_KEY_SIZE,
-       .ivsize         = AES_BLOCK_SIZE,
-       .chunksize      = AES_BLOCK_SIZE,
-       .setkey         = aesbs_ctr_set_key,
-       .encrypt        = aesbs_ctr_encrypt,
-       .decrypt        = aesbs_ctr_encrypt,
-}, {
-       .base = {
-               .cra_name               = "__xts(aes)",
-               .cra_driver_name        = "__xts-aes-neonbs",
-               .cra_priority           = 300,
-               .cra_flags              = CRYPTO_ALG_INTERNAL,
-               .cra_blocksize          = AES_BLOCK_SIZE,
-               .cra_ctxsize            = sizeof(struct aesbs_xts_ctx),
-               .cra_alignmask          = 7,
-               .cra_module             = THIS_MODULE,
-       },
-       .min_keysize    = 2 * AES_MIN_KEY_SIZE,
-       .max_keysize    = 2 * AES_MAX_KEY_SIZE,
-       .ivsize         = AES_BLOCK_SIZE,
-       .setkey         = aesbs_xts_set_key,
-       .encrypt        = aesbs_xts_encrypt,
-       .decrypt        = aesbs_xts_decrypt,
-} };
-
-struct simd_skcipher_alg *aesbs_simd_algs[ARRAY_SIZE(aesbs_algs)];
-
-static void aesbs_mod_exit(void)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(aesbs_simd_algs) && aesbs_simd_algs[i]; i++)
-               simd_skcipher_free(aesbs_simd_algs[i]);
-
-       crypto_unregister_skciphers(aesbs_algs, ARRAY_SIZE(aesbs_algs));
-}
-
-static int __init aesbs_mod_init(void)
-{
-       struct simd_skcipher_alg *simd;
-       const char *basename;
-       const char *algname;
-       const char *drvname;
-       int err;
-       int i;
-
-       if (!cpu_has_neon())
-               return -ENODEV;
-
-       err = crypto_register_skciphers(aesbs_algs, ARRAY_SIZE(aesbs_algs));
-       if (err)
-               return err;
-
-       for (i = 0; i < ARRAY_SIZE(aesbs_algs); i++) {
-               algname = aesbs_algs[i].base.cra_name + 2;
-               drvname = aesbs_algs[i].base.cra_driver_name + 2;
-               basename = aesbs_algs[i].base.cra_driver_name;
-               simd = simd_skcipher_create_compat(algname, drvname, basename);
-               err = PTR_ERR(simd);
-               if (IS_ERR(simd))
-                       goto unregister_simds;
-
-               aesbs_simd_algs[i] = simd;
-       }
-
-       return 0;
-
-unregister_simds:
-       aesbs_mod_exit();
-       return err;
-}
-
-module_init(aesbs_mod_init);
-module_exit(aesbs_mod_exit);
-
-MODULE_DESCRIPTION("Bit sliced AES in CBC/CTR/XTS modes using NEON");
-MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
-MODULE_LICENSE("GPL");
diff --git a/arch/arm/crypto/bsaes-armv7.pl b/arch/arm/crypto/bsaes-armv7.pl
deleted file mode 100644 (file)
index a4d3856..0000000
+++ /dev/null
@@ -1,2471 +0,0 @@
-#!/usr/bin/env perl
-
-# ====================================================================
-# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
-# project. The module is, however, dual licensed under OpenSSL and
-# CRYPTOGAMS licenses depending on where you obtain it. For further
-# details see http://www.openssl.org/~appro/cryptogams/.
-#
-# Specific modes and adaptation for Linux kernel by Ard Biesheuvel
-# <ard.biesheuvel@linaro.org>. Permission to use under GPL terms is
-# granted.
-# ====================================================================
-
-# Bit-sliced AES for ARM NEON
-#
-# February 2012.
-#
-# This implementation is direct adaptation of bsaes-x86_64 module for
-# ARM NEON. Except that this module is endian-neutral [in sense that
-# it can be compiled for either endianness] by courtesy of vld1.8's
-# neutrality. Initial version doesn't implement interface to OpenSSL,
-# only low-level primitives and unsupported entry points, just enough
-# to collect performance results, which for Cortex-A8 core are:
-#
-# encrypt      19.5 cycles per byte processed with 128-bit key
-# decrypt      22.1 cycles per byte processed with 128-bit key
-# key conv.    440  cycles per 128-bit key/0.18 of 8x block
-#
-# Snapdragon S4 encrypts byte in 17.6 cycles and decrypts in 19.7,
-# which is [much] worse than anticipated (for further details see
-# http://www.openssl.org/~appro/Snapdragon-S4.html).
-#
-# Cortex-A15 manages in 14.2/16.1 cycles [when integer-only code
-# manages in 20.0 cycles].
-#
-# When comparing to x86_64 results keep in mind that NEON unit is
-# [mostly] single-issue and thus can't [fully] benefit from
-# instruction-level parallelism. And when comparing to aes-armv4
-# results keep in mind key schedule conversion overhead (see
-# bsaes-x86_64.pl for further details)...
-#
-#                                              <appro@openssl.org>
-
-# April-August 2013
-#
-# Add CBC, CTR and XTS subroutines, adapt for kernel use.
-#
-#                                      <ard.biesheuvel@linaro.org>
-
-while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
-open STDOUT,">$output";
-
-my ($inp,$out,$len,$key)=("r0","r1","r2","r3");
-my @XMM=map("q$_",(0..15));
-
-{
-my ($key,$rounds,$const)=("r4","r5","r6");
-
-sub Dlo()   { shift=~m|q([1]?[0-9])|?"d".($1*2):"";     }
-sub Dhi()   { shift=~m|q([1]?[0-9])|?"d".($1*2+1):"";   }
-
-sub Sbox {
-# input in  lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
-# output in lsb > [b0, b1, b4, b6, b3, b7, b2, b5] < msb
-my @b=@_[0..7];
-my @t=@_[8..11];
-my @s=@_[12..15];
-       &InBasisChange  (@b);
-       &Inv_GF256      (@b[6,5,0,3,7,1,4,2],@t,@s);
-       &OutBasisChange (@b[7,1,4,2,6,5,0,3]);
-}
-
-sub InBasisChange {
-# input in  lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
-# output in lsb > [b6, b5, b0, b3, b7, b1, b4, b2] < msb 
-my @b=@_[0..7];
-$code.=<<___;
-       veor    @b[2], @b[2], @b[1]
-       veor    @b[5], @b[5], @b[6]
-       veor    @b[3], @b[3], @b[0]
-       veor    @b[6], @b[6], @b[2]
-       veor    @b[5], @b[5], @b[0]
-
-       veor    @b[6], @b[6], @b[3]
-       veor    @b[3], @b[3], @b[7]
-       veor    @b[7], @b[7], @b[5]
-       veor    @b[3], @b[3], @b[4]
-       veor    @b[4], @b[4], @b[5]
-
-       veor    @b[2], @b[2], @b[7]
-       veor    @b[3], @b[3], @b[1]
-       veor    @b[1], @b[1], @b[5]
-___
-}
-
-sub OutBasisChange {
-# input in  lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
-# output in lsb > [b6, b1, b2, b4, b7, b0, b3, b5] < msb
-my @b=@_[0..7];
-$code.=<<___;
-       veor    @b[0], @b[0], @b[6]
-       veor    @b[1], @b[1], @b[4]
-       veor    @b[4], @b[4], @b[6]
-       veor    @b[2], @b[2], @b[0]
-       veor    @b[6], @b[6], @b[1]
-
-       veor    @b[1], @b[1], @b[5]
-       veor    @b[5], @b[5], @b[3]
-       veor    @b[3], @b[3], @b[7]
-       veor    @b[7], @b[7], @b[5]
-       veor    @b[2], @b[2], @b[5]
-
-       veor    @b[4], @b[4], @b[7]
-___
-}
-
-sub InvSbox {
-# input in lsb         > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
-# output in lsb        > [b0, b1, b6, b4, b2, b7, b3, b5] < msb
-my @b=@_[0..7];
-my @t=@_[8..11];
-my @s=@_[12..15];
-       &InvInBasisChange       (@b);
-       &Inv_GF256              (@b[5,1,2,6,3,7,0,4],@t,@s);
-       &InvOutBasisChange      (@b[3,7,0,4,5,1,2,6]);
-}
-
-sub InvInBasisChange {         # OutBasisChange in reverse (with twist)
-my @b=@_[5,1,2,6,3,7,0,4];
-$code.=<<___
-        veor   @b[1], @b[1], @b[7]
-       veor    @b[4], @b[4], @b[7]
-
-       veor    @b[7], @b[7], @b[5]
-        veor   @b[1], @b[1], @b[3]
-       veor    @b[2], @b[2], @b[5]
-       veor    @b[3], @b[3], @b[7]
-
-       veor    @b[6], @b[6], @b[1]
-       veor    @b[2], @b[2], @b[0]
-        veor   @b[5], @b[5], @b[3]
-       veor    @b[4], @b[4], @b[6]
-       veor    @b[0], @b[0], @b[6]
-       veor    @b[1], @b[1], @b[4]
-___
-}
-
-sub InvOutBasisChange {                # InBasisChange in reverse
-my @b=@_[2,5,7,3,6,1,0,4];
-$code.=<<___;
-       veor    @b[1], @b[1], @b[5]
-       veor    @b[2], @b[2], @b[7]
-
-       veor    @b[3], @b[3], @b[1]
-       veor    @b[4], @b[4], @b[5]
-       veor    @b[7], @b[7], @b[5]
-       veor    @b[3], @b[3], @b[4]
-        veor   @b[5], @b[5], @b[0]
-       veor    @b[3], @b[3], @b[7]
-        veor   @b[6], @b[6], @b[2]
-        veor   @b[2], @b[2], @b[1]
-       veor    @b[6], @b[6], @b[3]
-
-       veor    @b[3], @b[3], @b[0]
-       veor    @b[5], @b[5], @b[6]
-___
-}
-
-sub Mul_GF4 {
-#;*************************************************************
-#;* Mul_GF4: Input x0-x1,y0-y1 Output x0-x1 Temp t0 (8) *
-#;*************************************************************
-my ($x0,$x1,$y0,$y1,$t0,$t1)=@_;
-$code.=<<___;
-       veor    $t0, $y0, $y1
-       vand    $t0, $t0, $x0
-       veor    $x0, $x0, $x1
-       vand    $t1, $x1, $y0
-       vand    $x0, $x0, $y1
-       veor    $x1, $t1, $t0
-       veor    $x0, $x0, $t1
-___
-}
-
-sub Mul_GF4_N {                                # not used, see next subroutine
-# multiply and scale by N
-my ($x0,$x1,$y0,$y1,$t0)=@_;
-$code.=<<___;
-       veor    $t0, $y0, $y1
-       vand    $t0, $t0, $x0
-       veor    $x0, $x0, $x1
-       vand    $x1, $x1, $y0
-       vand    $x0, $x0, $y1
-       veor    $x1, $x1, $x0
-       veor    $x0, $x0, $t0
-___
-}
-
-sub Mul_GF4_N_GF4 {
-# interleaved Mul_GF4_N and Mul_GF4
-my ($x0,$x1,$y0,$y1,$t0,
-    $x2,$x3,$y2,$y3,$t1)=@_;
-$code.=<<___;
-       veor    $t0, $y0, $y1
-        veor   $t1, $y2, $y3
-       vand    $t0, $t0, $x0
-        vand   $t1, $t1, $x2
-       veor    $x0, $x0, $x1
-        veor   $x2, $x2, $x3
-       vand    $x1, $x1, $y0
-        vand   $x3, $x3, $y2
-       vand    $x0, $x0, $y1
-        vand   $x2, $x2, $y3
-       veor    $x1, $x1, $x0
-        veor   $x2, $x2, $x3
-       veor    $x0, $x0, $t0
-        veor   $x3, $x3, $t1
-___
-}
-sub Mul_GF16_2 {
-my @x=@_[0..7];
-my @y=@_[8..11];
-my @t=@_[12..15];
-$code.=<<___;
-       veor    @t[0], @x[0], @x[2]
-       veor    @t[1], @x[1], @x[3]
-___
-       &Mul_GF4        (@x[0], @x[1], @y[0], @y[1], @t[2..3]);
-$code.=<<___;
-       veor    @y[0], @y[0], @y[2]
-       veor    @y[1], @y[1], @y[3]
-___
-       Mul_GF4_N_GF4   (@t[0], @t[1], @y[0], @y[1], @t[3],
-                        @x[2], @x[3], @y[2], @y[3], @t[2]);
-$code.=<<___;
-       veor    @x[0], @x[0], @t[0]
-       veor    @x[2], @x[2], @t[0]
-       veor    @x[1], @x[1], @t[1]
-       veor    @x[3], @x[3], @t[1]
-
-       veor    @t[0], @x[4], @x[6]
-       veor    @t[1], @x[5], @x[7]
-___
-       &Mul_GF4_N_GF4  (@t[0], @t[1], @y[0], @y[1], @t[3],
-                        @x[6], @x[7], @y[2], @y[3], @t[2]);
-$code.=<<___;
-       veor    @y[0], @y[0], @y[2]
-       veor    @y[1], @y[1], @y[3]
-___
-       &Mul_GF4        (@x[4], @x[5], @y[0], @y[1], @t[2..3]);
-$code.=<<___;
-       veor    @x[4], @x[4], @t[0]
-       veor    @x[6], @x[6], @t[0]
-       veor    @x[5], @x[5], @t[1]
-       veor    @x[7], @x[7], @t[1]
-___
-}
-sub Inv_GF256 {
-#;********************************************************************
-#;* Inv_GF256: Input x0-x7 Output x0-x7 Temp t0-t3,s0-s3 (144)       *
-#;********************************************************************
-my @x=@_[0..7];
-my @t=@_[8..11];
-my @s=@_[12..15];
-# direct optimizations from hardware
-$code.=<<___;
-       veor    @t[3], @x[4], @x[6]
-       veor    @t[2], @x[5], @x[7]
-       veor    @t[1], @x[1], @x[3]
-       veor    @s[1], @x[7], @x[6]
-        vmov   @t[0], @t[2]
-       veor    @s[0], @x[0], @x[2]
-
-       vorr    @t[2], @t[2], @t[1]
-       veor    @s[3], @t[3], @t[0]
-       vand    @s[2], @t[3], @s[0]
-       vorr    @t[3], @t[3], @s[0]
-       veor    @s[0], @s[0], @t[1]
-       vand    @t[0], @t[0], @t[1]
-       veor    @t[1], @x[3], @x[2]
-       vand    @s[3], @s[3], @s[0]
-       vand    @s[1], @s[1], @t[1]
-       veor    @t[1], @x[4], @x[5]
-       veor    @s[0], @x[1], @x[0]
-       veor    @t[3], @t[3], @s[1]
-       veor    @t[2], @t[2], @s[1]
-       vand    @s[1], @t[1], @s[0]
-       vorr    @t[1], @t[1], @s[0]
-       veor    @t[3], @t[3], @s[3]
-       veor    @t[0], @t[0], @s[1]
-       veor    @t[2], @t[2], @s[2]
-       veor    @t[1], @t[1], @s[3]
-       veor    @t[0], @t[0], @s[2]
-       vand    @s[0], @x[7], @x[3]
-       veor    @t[1], @t[1], @s[2]
-       vand    @s[1], @x[6], @x[2]
-       vand    @s[2], @x[5], @x[1]
-       vorr    @s[3], @x[4], @x[0]
-       veor    @t[3], @t[3], @s[0]
-       veor    @t[1], @t[1], @s[2]
-       veor    @t[0], @t[0], @s[3]
-       veor    @t[2], @t[2], @s[1]
-
-       @ Inv_GF16 \t0, \t1, \t2, \t3, \s0, \s1, \s2, \s3
-
-       @ new smaller inversion
-
-       vand    @s[2], @t[3], @t[1]
-       vmov    @s[0], @t[0]
-
-       veor    @s[1], @t[2], @s[2]
-       veor    @s[3], @t[0], @s[2]
-       veor    @s[2], @t[0], @s[2]     @ @s[2]=@s[3]
-
-       vbsl    @s[1], @t[1], @t[0]
-       vbsl    @s[3], @t[3], @t[2]
-       veor    @t[3], @t[3], @t[2]
-
-       vbsl    @s[0], @s[1], @s[2]
-       vbsl    @t[0], @s[2], @s[1]
-
-       vand    @s[2], @s[0], @s[3]
-       veor    @t[1], @t[1], @t[0]
-
-       veor    @s[2], @s[2], @t[3]
-___
-# output in s3, s2, s1, t1
-
-# Mul_GF16_2 \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \t2, \t3, \t0, \t1, \s0, \s1, \s2, \s3
-
-# Mul_GF16_2 \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \s3, \s2, \s1, \t1, \s0, \t0, \t2, \t3
-       &Mul_GF16_2(@x,@s[3,2,1],@t[1],@s[0],@t[0,2,3]);
-
-### output msb > [x3,x2,x1,x0,x7,x6,x5,x4] < lsb
-}
-
-# AES linear components
-
-sub ShiftRows {
-my @x=@_[0..7];
-my @t=@_[8..11];
-my $mask=pop;
-$code.=<<___;
-       vldmia  $key!, {@t[0]-@t[3]}
-       veor    @t[0], @t[0], @x[0]
-       veor    @t[1], @t[1], @x[1]
-       vtbl.8  `&Dlo(@x[0])`, {@t[0]}, `&Dlo($mask)`
-       vtbl.8  `&Dhi(@x[0])`, {@t[0]}, `&Dhi($mask)`
-       vldmia  $key!, {@t[0]}
-       veor    @t[2], @t[2], @x[2]
-       vtbl.8  `&Dlo(@x[1])`, {@t[1]}, `&Dlo($mask)`
-       vtbl.8  `&Dhi(@x[1])`, {@t[1]}, `&Dhi($mask)`
-       vldmia  $key!, {@t[1]}
-       veor    @t[3], @t[3], @x[3]
-       vtbl.8  `&Dlo(@x[2])`, {@t[2]}, `&Dlo($mask)`
-       vtbl.8  `&Dhi(@x[2])`, {@t[2]}, `&Dhi($mask)`
-       vldmia  $key!, {@t[2]}
-       vtbl.8  `&Dlo(@x[3])`, {@t[3]}, `&Dlo($mask)`
-       vtbl.8  `&Dhi(@x[3])`, {@t[3]}, `&Dhi($mask)`
-       vldmia  $key!, {@t[3]}
-       veor    @t[0], @t[0], @x[4]
-       veor    @t[1], @t[1], @x[5]
-       vtbl.8  `&Dlo(@x[4])`, {@t[0]}, `&Dlo($mask)`
-       vtbl.8  `&Dhi(@x[4])`, {@t[0]}, `&Dhi($mask)`
-       veor    @t[2], @t[2], @x[6]
-       vtbl.8  `&Dlo(@x[5])`, {@t[1]}, `&Dlo($mask)`
-       vtbl.8  `&Dhi(@x[5])`, {@t[1]}, `&Dhi($mask)`
-       veor    @t[3], @t[3], @x[7]
-       vtbl.8  `&Dlo(@x[6])`, {@t[2]}, `&Dlo($mask)`
-       vtbl.8  `&Dhi(@x[6])`, {@t[2]}, `&Dhi($mask)`
-       vtbl.8  `&Dlo(@x[7])`, {@t[3]}, `&Dlo($mask)`
-       vtbl.8  `&Dhi(@x[7])`, {@t[3]}, `&Dhi($mask)`
-___
-}
-
-sub MixColumns {
-# modified to emit output in order suitable for feeding back to aesenc[last]
-my @x=@_[0..7];
-my @t=@_[8..15];
-my $inv=@_[16];        # optional
-$code.=<<___;
-       vext.8  @t[0], @x[0], @x[0], #12        @ x0 <<< 32
-       vext.8  @t[1], @x[1], @x[1], #12
-        veor   @x[0], @x[0], @t[0]             @ x0 ^ (x0 <<< 32)
-       vext.8  @t[2], @x[2], @x[2], #12
-        veor   @x[1], @x[1], @t[1]
-       vext.8  @t[3], @x[3], @x[3], #12
-        veor   @x[2], @x[2], @t[2]
-       vext.8  @t[4], @x[4], @x[4], #12
-        veor   @x[3], @x[3], @t[3]
-       vext.8  @t[5], @x[5], @x[5], #12
-        veor   @x[4], @x[4], @t[4]
-       vext.8  @t[6], @x[6], @x[6], #12
-        veor   @x[5], @x[5], @t[5]
-       vext.8  @t[7], @x[7], @x[7], #12
-        veor   @x[6], @x[6], @t[6]
-
-       veor    @t[1], @t[1], @x[0]
-        veor   @x[7], @x[7], @t[7]
-        vext.8 @x[0], @x[0], @x[0], #8         @ (x0 ^ (x0 <<< 32)) <<< 64)
-       veor    @t[2], @t[2], @x[1]
-       veor    @t[0], @t[0], @x[7]
-       veor    @t[1], @t[1], @x[7]
-        vext.8 @x[1], @x[1], @x[1], #8
-       veor    @t[5], @t[5], @x[4]
-        veor   @x[0], @x[0], @t[0]
-       veor    @t[6], @t[6], @x[5]
-        veor   @x[1], @x[1], @t[1]
-        vext.8 @t[0], @x[4], @x[4], #8
-       veor    @t[4], @t[4], @x[3]
-        vext.8 @t[1], @x[5], @x[5], #8
-       veor    @t[7], @t[7], @x[6]
-        vext.8 @x[4], @x[3], @x[3], #8
-       veor    @t[3], @t[3], @x[2]
-        vext.8 @x[5], @x[7], @x[7], #8
-       veor    @t[4], @t[4], @x[7]
-        vext.8 @x[3], @x[6], @x[6], #8
-       veor    @t[3], @t[3], @x[7]
-        vext.8 @x[6], @x[2], @x[2], #8
-       veor    @x[7], @t[1], @t[5]
-___
-$code.=<<___ if (!$inv);
-       veor    @x[2], @t[0], @t[4]
-       veor    @x[4], @x[4], @t[3]
-       veor    @x[5], @x[5], @t[7]
-       veor    @x[3], @x[3], @t[6]
-        @ vmov @x[2], @t[0]
-       veor    @x[6], @x[6], @t[2]
-        @ vmov @x[7], @t[1]
-___
-$code.=<<___ if ($inv);
-       veor    @t[3], @t[3], @x[4]
-       veor    @x[5], @x[5], @t[7]
-       veor    @x[2], @x[3], @t[6]
-       veor    @x[3], @t[0], @t[4]
-       veor    @x[4], @x[6], @t[2]
-       vmov    @x[6], @t[3]
-        @ vmov @x[7], @t[1]
-___
-}
-
-sub InvMixColumns_orig {
-my @x=@_[0..7];
-my @t=@_[8..15];
-
-$code.=<<___;
-       @ multiplication by 0x0e
-       vext.8  @t[7], @x[7], @x[7], #12
-       vmov    @t[2], @x[2]
-       veor    @x[2], @x[2], @x[5]             @ 2 5
-       veor    @x[7], @x[7], @x[5]             @ 7 5
-       vext.8  @t[0], @x[0], @x[0], #12
-       vmov    @t[5], @x[5]
-       veor    @x[5], @x[5], @x[0]             @ 5 0           [1]
-       veor    @x[0], @x[0], @x[1]             @ 0 1
-       vext.8  @t[1], @x[1], @x[1], #12
-       veor    @x[1], @x[1], @x[2]             @ 1 25
-       veor    @x[0], @x[0], @x[6]             @ 01 6          [2]
-       vext.8  @t[3], @x[3], @x[3], #12
-       veor    @x[1], @x[1], @x[3]             @ 125 3         [4]
-       veor    @x[2], @x[2], @x[0]             @ 25 016        [3]
-       veor    @x[3], @x[3], @x[7]             @ 3 75
-       veor    @x[7], @x[7], @x[6]             @ 75 6          [0]
-       vext.8  @t[6], @x[6], @x[6], #12
-       vmov    @t[4], @x[4]
-       veor    @x[6], @x[6], @x[4]             @ 6 4
-       veor    @x[4], @x[4], @x[3]             @ 4 375         [6]
-       veor    @x[3], @x[3], @x[7]             @ 375 756=36
-       veor    @x[6], @x[6], @t[5]             @ 64 5          [7]
-       veor    @x[3], @x[3], @t[2]             @ 36 2
-       vext.8  @t[5], @t[5], @t[5], #12
-       veor    @x[3], @x[3], @t[4]             @ 362 4         [5]
-___
-                                       my @y = @x[7,5,0,2,1,3,4,6];
-$code.=<<___;
-       @ multiplication by 0x0b
-       veor    @y[1], @y[1], @y[0]
-       veor    @y[0], @y[0], @t[0]
-       vext.8  @t[2], @t[2], @t[2], #12
-       veor    @y[1], @y[1], @t[1]
-       veor    @y[0], @y[0], @t[5]
-       vext.8  @t[4], @t[4], @t[4], #12
-       veor    @y[1], @y[1], @t[6]
-       veor    @y[0], @y[0], @t[7]
-       veor    @t[7], @t[7], @t[6]             @ clobber t[7]
-
-       veor    @y[3], @y[3], @t[0]
-        veor   @y[1], @y[1], @y[0]
-       vext.8  @t[0], @t[0], @t[0], #12
-       veor    @y[2], @y[2], @t[1]
-       veor    @y[4], @y[4], @t[1]
-       vext.8  @t[1], @t[1], @t[1], #12
-       veor    @y[2], @y[2], @t[2]
-       veor    @y[3], @y[3], @t[2]
-       veor    @y[5], @y[5], @t[2]
-       veor    @y[2], @y[2], @t[7]
-       vext.8  @t[2], @t[2], @t[2], #12
-       veor    @y[3], @y[3], @t[3]
-       veor    @y[6], @y[6], @t[3]
-       veor    @y[4], @y[4], @t[3]
-       veor    @y[7], @y[7], @t[4]
-       vext.8  @t[3], @t[3], @t[3], #12
-       veor    @y[5], @y[5], @t[4]
-       veor    @y[7], @y[7], @t[7]
-       veor    @t[7], @t[7], @t[5]             @ clobber t[7] even more
-       veor    @y[3], @y[3], @t[5]
-       veor    @y[4], @y[4], @t[4]
-
-       veor    @y[5], @y[5], @t[7]
-       vext.8  @t[4], @t[4], @t[4], #12
-       veor    @y[6], @y[6], @t[7]
-       veor    @y[4], @y[4], @t[7]
-
-       veor    @t[7], @t[7], @t[5]
-       vext.8  @t[5], @t[5], @t[5], #12
-
-       @ multiplication by 0x0d
-       veor    @y[4], @y[4], @y[7]
-        veor   @t[7], @t[7], @t[6]             @ restore t[7]
-       veor    @y[7], @y[7], @t[4]
-       vext.8  @t[6], @t[6], @t[6], #12
-       veor    @y[2], @y[2], @t[0]
-       veor    @y[7], @y[7], @t[5]
-       vext.8  @t[7], @t[7], @t[7], #12
-       veor    @y[2], @y[2], @t[2]
-
-       veor    @y[3], @y[3], @y[1]
-       veor    @y[1], @y[1], @t[1]
-       veor    @y[0], @y[0], @t[0]
-       veor    @y[3], @y[3], @t[0]
-       veor    @y[1], @y[1], @t[5]
-       veor    @y[0], @y[0], @t[5]
-       vext.8  @t[0], @t[0], @t[0], #12
-       veor    @y[1], @y[1], @t[7]
-       veor    @y[0], @y[0], @t[6]
-       veor    @y[3], @y[3], @y[1]
-       veor    @y[4], @y[4], @t[1]
-       vext.8  @t[1], @t[1], @t[1], #12
-
-       veor    @y[7], @y[7], @t[7]
-       veor    @y[4], @y[4], @t[2]
-       veor    @y[5], @y[5], @t[2]
-       veor    @y[2], @y[2], @t[6]
-       veor    @t[6], @t[6], @t[3]             @ clobber t[6]
-       vext.8  @t[2], @t[2], @t[2], #12
-       veor    @y[4], @y[4], @y[7]
-       veor    @y[3], @y[3], @t[6]
-
-       veor    @y[6], @y[6], @t[6]
-       veor    @y[5], @y[5], @t[5]
-       vext.8  @t[5], @t[5], @t[5], #12
-       veor    @y[6], @y[6], @t[4]
-       vext.8  @t[4], @t[4], @t[4], #12
-       veor    @y[5], @y[5], @t[6]
-       veor    @y[6], @y[6], @t[7]
-       vext.8  @t[7], @t[7], @t[7], #12
-       veor    @t[6], @t[6], @t[3]             @ restore t[6]
-       vext.8  @t[3], @t[3], @t[3], #12
-
-       @ multiplication by 0x09
-       veor    @y[4], @y[4], @y[1]
-       veor    @t[1], @t[1], @y[1]             @ t[1]=y[1]
-       veor    @t[0], @t[0], @t[5]             @ clobber t[0]
-       vext.8  @t[6], @t[6], @t[6], #12
-       veor    @t[1], @t[1], @t[5]
-       veor    @y[3], @y[3], @t[0]
-       veor    @t[0], @t[0], @y[0]             @ t[0]=y[0]
-       veor    @t[1], @t[1], @t[6]
-       veor    @t[6], @t[6], @t[7]             @ clobber t[6]
-       veor    @y[4], @y[4], @t[1]
-       veor    @y[7], @y[7], @t[4]
-       veor    @y[6], @y[6], @t[3]
-       veor    @y[5], @y[5], @t[2]
-       veor    @t[4], @t[4], @y[4]             @ t[4]=y[4]
-       veor    @t[3], @t[3], @y[3]             @ t[3]=y[3]
-       veor    @t[5], @t[5], @y[5]             @ t[5]=y[5]
-       veor    @t[2], @t[2], @y[2]             @ t[2]=y[2]
-       veor    @t[3], @t[3], @t[7]
-       veor    @XMM[5], @t[5], @t[6]
-       veor    @XMM[6], @t[6], @y[6]           @ t[6]=y[6]
-       veor    @XMM[2], @t[2], @t[6]
-       veor    @XMM[7], @t[7], @y[7]           @ t[7]=y[7]
-
-       vmov    @XMM[0], @t[0]
-       vmov    @XMM[1], @t[1]
-       @ vmov  @XMM[2], @t[2]
-       vmov    @XMM[3], @t[3]
-       vmov    @XMM[4], @t[4]
-       @ vmov  @XMM[5], @t[5]
-       @ vmov  @XMM[6], @t[6]
-       @ vmov  @XMM[7], @t[7]
-___
-}
-
-sub InvMixColumns {
-my @x=@_[0..7];
-my @t=@_[8..15];
-
-# Thanks to Jussi Kivilinna for providing pointer to
-#
-# | 0e 0b 0d 09 |   | 02 03 01 01 |   | 05 00 04 00 |
-# | 09 0e 0b 0d | = | 01 02 03 01 | x | 00 05 00 04 |
-# | 0d 09 0e 0b |   | 01 01 02 03 |   | 04 00 05 00 |
-# | 0b 0d 09 0e |   | 03 01 01 02 |   | 00 04 00 05 |
-
-$code.=<<___;
-       @ multiplication by 0x05-0x00-0x04-0x00
-       vext.8  @t[0], @x[0], @x[0], #8
-       vext.8  @t[6], @x[6], @x[6], #8
-       vext.8  @t[7], @x[7], @x[7], #8
-       veor    @t[0], @t[0], @x[0]
-       vext.8  @t[1], @x[1], @x[1], #8
-       veor    @t[6], @t[6], @x[6]
-       vext.8  @t[2], @x[2], @x[2], #8
-       veor    @t[7], @t[7], @x[7]
-       vext.8  @t[3], @x[3], @x[3], #8
-       veor    @t[1], @t[1], @x[1]
-       vext.8  @t[4], @x[4], @x[4], #8
-       veor    @t[2], @t[2], @x[2]
-       vext.8  @t[5], @x[5], @x[5], #8
-       veor    @t[3], @t[3], @x[3]
-       veor    @t[4], @t[4], @x[4]
-       veor    @t[5], @t[5], @x[5]
-
-        veor   @x[0], @x[0], @t[6]
-        veor   @x[1], @x[1], @t[6]
-        veor   @x[2], @x[2], @t[0]
-        veor   @x[4], @x[4], @t[2]
-        veor   @x[3], @x[3], @t[1]
-        veor   @x[1], @x[1], @t[7]
-        veor   @x[2], @x[2], @t[7]
-        veor   @x[4], @x[4], @t[6]
-        veor   @x[5], @x[5], @t[3]
-        veor   @x[3], @x[3], @t[6]
-        veor   @x[6], @x[6], @t[4]
-        veor   @x[4], @x[4], @t[7]
-        veor   @x[5], @x[5], @t[7]
-        veor   @x[7], @x[7], @t[5]
-___
-       &MixColumns     (@x,@t,1);      # flipped 2<->3 and 4<->6
-}
-
-sub swapmove {
-my ($a,$b,$n,$mask,$t)=@_;
-$code.=<<___;
-       vshr.u64        $t, $b, #$n
-       veor            $t, $t, $a
-       vand            $t, $t, $mask
-       veor            $a, $a, $t
-       vshl.u64        $t, $t, #$n
-       veor            $b, $b, $t
-___
-}
-sub swapmove2x {
-my ($a0,$b0,$a1,$b1,$n,$mask,$t0,$t1)=@_;
-$code.=<<___;
-       vshr.u64        $t0, $b0, #$n
-        vshr.u64       $t1, $b1, #$n
-       veor            $t0, $t0, $a0
-        veor           $t1, $t1, $a1
-       vand            $t0, $t0, $mask
-        vand           $t1, $t1, $mask
-       veor            $a0, $a0, $t0
-       vshl.u64        $t0, $t0, #$n
-        veor           $a1, $a1, $t1
-        vshl.u64       $t1, $t1, #$n
-       veor            $b0, $b0, $t0
-        veor           $b1, $b1, $t1
-___
-}
-
-sub bitslice {
-my @x=reverse(@_[0..7]);
-my ($t0,$t1,$t2,$t3)=@_[8..11];
-$code.=<<___;
-       vmov.i8 $t0,#0x55                       @ compose .LBS0
-       vmov.i8 $t1,#0x33                       @ compose .LBS1
-___
-       &swapmove2x(@x[0,1,2,3],1,$t0,$t2,$t3);
-       &swapmove2x(@x[4,5,6,7],1,$t0,$t2,$t3);
-$code.=<<___;
-       vmov.i8 $t0,#0x0f                       @ compose .LBS2
-___
-       &swapmove2x(@x[0,2,1,3],2,$t1,$t2,$t3);
-       &swapmove2x(@x[4,6,5,7],2,$t1,$t2,$t3);
-
-       &swapmove2x(@x[0,4,1,5],4,$t0,$t2,$t3);
-       &swapmove2x(@x[2,6,3,7],4,$t0,$t2,$t3);
-}
-
-$code.=<<___;
-#ifndef __KERNEL__
-# include "arm_arch.h"
-
-# define VFP_ABI_PUSH  vstmdb  sp!,{d8-d15}
-# define VFP_ABI_POP   vldmia  sp!,{d8-d15}
-# define VFP_ABI_FRAME 0x40
-#else
-# define VFP_ABI_PUSH
-# define VFP_ABI_POP
-# define VFP_ABI_FRAME 0
-# define BSAES_ASM_EXTENDED_KEY
-# define XTS_CHAIN_TWEAK
-# define __ARM_ARCH__ __LINUX_ARM_ARCH__
-# define __ARM_MAX_ARCH__ 7
-#endif
-
-#ifdef __thumb__
-# define adrl adr
-#endif
-
-#if __ARM_MAX_ARCH__>=7
-.arch  armv7-a
-.fpu   neon
-
-.text
-.syntax        unified         @ ARMv7-capable assembler is expected to handle this
-#ifdef __thumb2__
-.thumb
-#else
-.code   32
-#endif
-
-.type  _bsaes_decrypt8,%function
-.align 4
-_bsaes_decrypt8:
-       adr     $const,_bsaes_decrypt8
-       vldmia  $key!, {@XMM[9]}                @ round 0 key
-       add     $const,$const,#.LM0ISR-_bsaes_decrypt8
-
-       vldmia  $const!, {@XMM[8]}              @ .LM0ISR
-       veor    @XMM[10], @XMM[0], @XMM[9]      @ xor with round0 key
-       veor    @XMM[11], @XMM[1], @XMM[9]
-        vtbl.8 `&Dlo(@XMM[0])`, {@XMM[10]}, `&Dlo(@XMM[8])`
-        vtbl.8 `&Dhi(@XMM[0])`, {@XMM[10]}, `&Dhi(@XMM[8])`
-       veor    @XMM[12], @XMM[2], @XMM[9]
-        vtbl.8 `&Dlo(@XMM[1])`, {@XMM[11]}, `&Dlo(@XMM[8])`
-        vtbl.8 `&Dhi(@XMM[1])`, {@XMM[11]}, `&Dhi(@XMM[8])`
-       veor    @XMM[13], @XMM[3], @XMM[9]
-        vtbl.8 `&Dlo(@XMM[2])`, {@XMM[12]}, `&Dlo(@XMM[8])`
-        vtbl.8 `&Dhi(@XMM[2])`, {@XMM[12]}, `&Dhi(@XMM[8])`
-       veor    @XMM[14], @XMM[4], @XMM[9]
-        vtbl.8 `&Dlo(@XMM[3])`, {@XMM[13]}, `&Dlo(@XMM[8])`
-        vtbl.8 `&Dhi(@XMM[3])`, {@XMM[13]}, `&Dhi(@XMM[8])`
-       veor    @XMM[15], @XMM[5], @XMM[9]
-        vtbl.8 `&Dlo(@XMM[4])`, {@XMM[14]}, `&Dlo(@XMM[8])`
-        vtbl.8 `&Dhi(@XMM[4])`, {@XMM[14]}, `&Dhi(@XMM[8])`
-       veor    @XMM[10], @XMM[6], @XMM[9]
-        vtbl.8 `&Dlo(@XMM[5])`, {@XMM[15]}, `&Dlo(@XMM[8])`
-        vtbl.8 `&Dhi(@XMM[5])`, {@XMM[15]}, `&Dhi(@XMM[8])`
-       veor    @XMM[11], @XMM[7], @XMM[9]
-        vtbl.8 `&Dlo(@XMM[6])`, {@XMM[10]}, `&Dlo(@XMM[8])`
-        vtbl.8 `&Dhi(@XMM[6])`, {@XMM[10]}, `&Dhi(@XMM[8])`
-        vtbl.8 `&Dlo(@XMM[7])`, {@XMM[11]}, `&Dlo(@XMM[8])`
-        vtbl.8 `&Dhi(@XMM[7])`, {@XMM[11]}, `&Dhi(@XMM[8])`
-___
-       &bitslice       (@XMM[0..7, 8..11]);
-$code.=<<___;
-       sub     $rounds,$rounds,#1
-       b       .Ldec_sbox
-.align 4
-.Ldec_loop:
-___
-       &ShiftRows      (@XMM[0..7, 8..12]);
-$code.=".Ldec_sbox:\n";
-       &InvSbox        (@XMM[0..7, 8..15]);
-$code.=<<___;
-       subs    $rounds,$rounds,#1
-       bcc     .Ldec_done
-___
-       &InvMixColumns  (@XMM[0,1,6,4,2,7,3,5, 8..15]);
-$code.=<<___;
-       vldmia  $const, {@XMM[12]}              @ .LISR
-       ite     eq                              @ Thumb2 thing, sanity check in ARM
-       addeq   $const,$const,#0x10
-       bne     .Ldec_loop
-       vldmia  $const, {@XMM[12]}              @ .LISRM0
-       b       .Ldec_loop
-.align 4
-.Ldec_done:
-___
-       &bitslice       (@XMM[0,1,6,4,2,7,3,5, 8..11]);
-$code.=<<___;
-       vldmia  $key, {@XMM[8]}                 @ last round key
-       veor    @XMM[6], @XMM[6], @XMM[8]
-       veor    @XMM[4], @XMM[4], @XMM[8]
-       veor    @XMM[2], @XMM[2], @XMM[8]
-       veor    @XMM[7], @XMM[7], @XMM[8]
-       veor    @XMM[3], @XMM[3], @XMM[8]
-       veor    @XMM[5], @XMM[5], @XMM[8]
-       veor    @XMM[0], @XMM[0], @XMM[8]
-       veor    @XMM[1], @XMM[1], @XMM[8]
-       bx      lr
-.size  _bsaes_decrypt8,.-_bsaes_decrypt8
-
-.type  _bsaes_const,%object
-.align 6
-_bsaes_const:
-.LM0ISR:       @ InvShiftRows constants
-       .quad   0x0a0e0206070b0f03, 0x0004080c0d010509
-.LISR:
-       .quad   0x0504070602010003, 0x0f0e0d0c080b0a09
-.LISRM0:
-       .quad   0x01040b0e0205080f, 0x0306090c00070a0d
-.LM0SR:                @ ShiftRows constants
-       .quad   0x0a0e02060f03070b, 0x0004080c05090d01
-.LSR:
-       .quad   0x0504070600030201, 0x0f0e0d0c0a09080b
-.LSRM0:
-       .quad   0x0304090e00050a0f, 0x01060b0c0207080d
-.LM0:
-       .quad   0x02060a0e03070b0f, 0x0004080c0105090d
-.LREVM0SR:
-       .quad   0x090d01050c000408, 0x03070b0f060a0e02
-.asciz "Bit-sliced AES for NEON, CRYPTOGAMS by <appro\@openssl.org>"
-.align 6
-.size  _bsaes_const,.-_bsaes_const
-
-.type  _bsaes_encrypt8,%function
-.align 4
-_bsaes_encrypt8:
-       adr     $const,_bsaes_encrypt8
-       vldmia  $key!, {@XMM[9]}                @ round 0 key
-       sub     $const,$const,#_bsaes_encrypt8-.LM0SR
-
-       vldmia  $const!, {@XMM[8]}              @ .LM0SR
-_bsaes_encrypt8_alt:
-       veor    @XMM[10], @XMM[0], @XMM[9]      @ xor with round0 key
-       veor    @XMM[11], @XMM[1], @XMM[9]
-        vtbl.8 `&Dlo(@XMM[0])`, {@XMM[10]}, `&Dlo(@XMM[8])`
-        vtbl.8 `&Dhi(@XMM[0])`, {@XMM[10]}, `&Dhi(@XMM[8])`
-       veor    @XMM[12], @XMM[2], @XMM[9]
-        vtbl.8 `&Dlo(@XMM[1])`, {@XMM[11]}, `&Dlo(@XMM[8])`
-        vtbl.8 `&Dhi(@XMM[1])`, {@XMM[11]}, `&Dhi(@XMM[8])`
-       veor    @XMM[13], @XMM[3], @XMM[9]
-        vtbl.8 `&Dlo(@XMM[2])`, {@XMM[12]}, `&Dlo(@XMM[8])`
-        vtbl.8 `&Dhi(@XMM[2])`, {@XMM[12]}, `&Dhi(@XMM[8])`
-       veor    @XMM[14], @XMM[4], @XMM[9]
-        vtbl.8 `&Dlo(@XMM[3])`, {@XMM[13]}, `&Dlo(@XMM[8])`
-        vtbl.8 `&Dhi(@XMM[3])`, {@XMM[13]}, `&Dhi(@XMM[8])`
-       veor    @XMM[15], @XMM[5], @XMM[9]
-        vtbl.8 `&Dlo(@XMM[4])`, {@XMM[14]}, `&Dlo(@XMM[8])`
-        vtbl.8 `&Dhi(@XMM[4])`, {@XMM[14]}, `&Dhi(@XMM[8])`
-       veor    @XMM[10], @XMM[6], @XMM[9]
-        vtbl.8 `&Dlo(@XMM[5])`, {@XMM[15]}, `&Dlo(@XMM[8])`
-        vtbl.8 `&Dhi(@XMM[5])`, {@XMM[15]}, `&Dhi(@XMM[8])`
-       veor    @XMM[11], @XMM[7], @XMM[9]
-        vtbl.8 `&Dlo(@XMM[6])`, {@XMM[10]}, `&Dlo(@XMM[8])`
-        vtbl.8 `&Dhi(@XMM[6])`, {@XMM[10]}, `&Dhi(@XMM[8])`
-        vtbl.8 `&Dlo(@XMM[7])`, {@XMM[11]}, `&Dlo(@XMM[8])`
-        vtbl.8 `&Dhi(@XMM[7])`, {@XMM[11]}, `&Dhi(@XMM[8])`
-_bsaes_encrypt8_bitslice:
-___
-       &bitslice       (@XMM[0..7, 8..11]);
-$code.=<<___;
-       sub     $rounds,$rounds,#1
-       b       .Lenc_sbox
-.align 4
-.Lenc_loop:
-___
-       &ShiftRows      (@XMM[0..7, 8..12]);
-$code.=".Lenc_sbox:\n";
-       &Sbox           (@XMM[0..7, 8..15]);
-$code.=<<___;
-       subs    $rounds,$rounds,#1
-       bcc     .Lenc_done
-___
-       &MixColumns     (@XMM[0,1,4,6,3,7,2,5, 8..15]);
-$code.=<<___;
-       vldmia  $const, {@XMM[12]}              @ .LSR
-       ite     eq                              @ Thumb2 thing, samity check in ARM
-       addeq   $const,$const,#0x10
-       bne     .Lenc_loop
-       vldmia  $const, {@XMM[12]}              @ .LSRM0
-       b       .Lenc_loop
-.align 4
-.Lenc_done:
-___
-       # output in lsb > [t0, t1, t4, t6, t3, t7, t2, t5] < msb
-       &bitslice       (@XMM[0,1,4,6,3,7,2,5, 8..11]);
-$code.=<<___;
-       vldmia  $key, {@XMM[8]}                 @ last round key
-       veor    @XMM[4], @XMM[4], @XMM[8]
-       veor    @XMM[6], @XMM[6], @XMM[8]
-       veor    @XMM[3], @XMM[3], @XMM[8]
-       veor    @XMM[7], @XMM[7], @XMM[8]
-       veor    @XMM[2], @XMM[2], @XMM[8]
-       veor    @XMM[5], @XMM[5], @XMM[8]
-       veor    @XMM[0], @XMM[0], @XMM[8]
-       veor    @XMM[1], @XMM[1], @XMM[8]
-       bx      lr
-.size  _bsaes_encrypt8,.-_bsaes_encrypt8
-___
-}
-{
-my ($out,$inp,$rounds,$const)=("r12","r4","r5","r6");
-
-sub bitslice_key {
-my @x=reverse(@_[0..7]);
-my ($bs0,$bs1,$bs2,$t2,$t3)=@_[8..12];
-
-       &swapmove       (@x[0,1],1,$bs0,$t2,$t3);
-$code.=<<___;
-       @ &swapmove(@x[2,3],1,$t0,$t2,$t3);
-       vmov    @x[2], @x[0]
-       vmov    @x[3], @x[1]
-___
-       #&swapmove2x(@x[4,5,6,7],1,$t0,$t2,$t3);
-
-       &swapmove2x     (@x[0,2,1,3],2,$bs1,$t2,$t3);
-$code.=<<___;
-       @ &swapmove2x(@x[4,6,5,7],2,$t1,$t2,$t3);
-       vmov    @x[4], @x[0]
-       vmov    @x[6], @x[2]
-       vmov    @x[5], @x[1]
-       vmov    @x[7], @x[3]
-___
-       &swapmove2x     (@x[0,4,1,5],4,$bs2,$t2,$t3);
-       &swapmove2x     (@x[2,6,3,7],4,$bs2,$t2,$t3);
-}
-
-$code.=<<___;
-.type  _bsaes_key_convert,%function
-.align 4
-_bsaes_key_convert:
-       adr     $const,_bsaes_key_convert
-       vld1.8  {@XMM[7]},  [$inp]!             @ load round 0 key
-       sub     $const,$const,#_bsaes_key_convert-.LM0
-       vld1.8  {@XMM[15]}, [$inp]!             @ load round 1 key
-
-       vmov.i8 @XMM[8],  #0x01                 @ bit masks
-       vmov.i8 @XMM[9],  #0x02
-       vmov.i8 @XMM[10], #0x04
-       vmov.i8 @XMM[11], #0x08
-       vmov.i8 @XMM[12], #0x10
-       vmov.i8 @XMM[13], #0x20
-       vldmia  $const, {@XMM[14]}              @ .LM0
-
-#ifdef __ARMEL__
-       vrev32.8        @XMM[7],  @XMM[7]
-       vrev32.8        @XMM[15], @XMM[15]
-#endif
-       sub     $rounds,$rounds,#1
-       vstmia  $out!, {@XMM[7]}                @ save round 0 key
-       b       .Lkey_loop
-
-.align 4
-.Lkey_loop:
-       vtbl.8  `&Dlo(@XMM[7])`,{@XMM[15]},`&Dlo(@XMM[14])`
-       vtbl.8  `&Dhi(@XMM[7])`,{@XMM[15]},`&Dhi(@XMM[14])`
-       vmov.i8 @XMM[6],  #0x40
-       vmov.i8 @XMM[15], #0x80
-
-       vtst.8  @XMM[0], @XMM[7], @XMM[8]
-       vtst.8  @XMM[1], @XMM[7], @XMM[9]
-       vtst.8  @XMM[2], @XMM[7], @XMM[10]
-       vtst.8  @XMM[3], @XMM[7], @XMM[11]
-       vtst.8  @XMM[4], @XMM[7], @XMM[12]
-       vtst.8  @XMM[5], @XMM[7], @XMM[13]
-       vtst.8  @XMM[6], @XMM[7], @XMM[6]
-       vtst.8  @XMM[7], @XMM[7], @XMM[15]
-       vld1.8  {@XMM[15]}, [$inp]!             @ load next round key
-       vmvn    @XMM[0], @XMM[0]                @ "pnot"
-       vmvn    @XMM[1], @XMM[1]
-       vmvn    @XMM[5], @XMM[5]
-       vmvn    @XMM[6], @XMM[6]
-#ifdef __ARMEL__
-       vrev32.8        @XMM[15], @XMM[15]
-#endif
-       subs    $rounds,$rounds,#1
-       vstmia  $out!,{@XMM[0]-@XMM[7]}         @ write bit-sliced round key
-       bne     .Lkey_loop
-
-       vmov.i8 @XMM[7],#0x63                   @ compose .L63
-       @ don't save last round key
-       bx      lr
-.size  _bsaes_key_convert,.-_bsaes_key_convert
-___
-}
-
-if (0) {               # following four functions are unsupported interface
-                       # used for benchmarking...
-$code.=<<___;
-.globl bsaes_enc_key_convert
-.type  bsaes_enc_key_convert,%function
-.align 4
-bsaes_enc_key_convert:
-       stmdb   sp!,{r4-r6,lr}
-       vstmdb  sp!,{d8-d15}            @ ABI specification says so
-
-       ldr     r5,[$inp,#240]                  @ pass rounds
-       mov     r4,$inp                         @ pass key
-       mov     r12,$out                        @ pass key schedule
-       bl      _bsaes_key_convert
-       veor    @XMM[7],@XMM[7],@XMM[15]        @ fix up last round key
-       vstmia  r12, {@XMM[7]}                  @ save last round key
-
-       vldmia  sp!,{d8-d15}
-       ldmia   sp!,{r4-r6,pc}
-.size  bsaes_enc_key_convert,.-bsaes_enc_key_convert
-
-.globl bsaes_encrypt_128
-.type  bsaes_encrypt_128,%function
-.align 4
-bsaes_encrypt_128:
-       stmdb   sp!,{r4-r6,lr}
-       vstmdb  sp!,{d8-d15}            @ ABI specification says so
-.Lenc128_loop:
-       vld1.8  {@XMM[0]-@XMM[1]}, [$inp]!      @ load input
-       vld1.8  {@XMM[2]-@XMM[3]}, [$inp]!
-       mov     r4,$key                         @ pass the key
-       vld1.8  {@XMM[4]-@XMM[5]}, [$inp]!
-       mov     r5,#10                          @ pass rounds
-       vld1.8  {@XMM[6]-@XMM[7]}, [$inp]!
-
-       bl      _bsaes_encrypt8
-
-       vst1.8  {@XMM[0]-@XMM[1]}, [$out]!      @ write output
-       vst1.8  {@XMM[4]}, [$out]!
-       vst1.8  {@XMM[6]}, [$out]!
-       vst1.8  {@XMM[3]}, [$out]!
-       vst1.8  {@XMM[7]}, [$out]!
-       vst1.8  {@XMM[2]}, [$out]!
-       subs    $len,$len,#0x80
-       vst1.8  {@XMM[5]}, [$out]!
-       bhi     .Lenc128_loop
-
-       vldmia  sp!,{d8-d15}
-       ldmia   sp!,{r4-r6,pc}
-.size  bsaes_encrypt_128,.-bsaes_encrypt_128
-
-.globl bsaes_dec_key_convert
-.type  bsaes_dec_key_convert,%function
-.align 4
-bsaes_dec_key_convert:
-       stmdb   sp!,{r4-r6,lr}
-       vstmdb  sp!,{d8-d15}            @ ABI specification says so
-
-       ldr     r5,[$inp,#240]                  @ pass rounds
-       mov     r4,$inp                         @ pass key
-       mov     r12,$out                        @ pass key schedule
-       bl      _bsaes_key_convert
-       vldmia  $out, {@XMM[6]}
-       vstmia  r12,  {@XMM[15]}                @ save last round key
-       veor    @XMM[7], @XMM[7], @XMM[6]       @ fix up round 0 key
-       vstmia  $out, {@XMM[7]}
-
-       vldmia  sp!,{d8-d15}
-       ldmia   sp!,{r4-r6,pc}
-.size  bsaes_dec_key_convert,.-bsaes_dec_key_convert
-
-.globl bsaes_decrypt_128
-.type  bsaes_decrypt_128,%function
-.align 4
-bsaes_decrypt_128:
-       stmdb   sp!,{r4-r6,lr}
-       vstmdb  sp!,{d8-d15}            @ ABI specification says so
-.Ldec128_loop:
-       vld1.8  {@XMM[0]-@XMM[1]}, [$inp]!      @ load input
-       vld1.8  {@XMM[2]-@XMM[3]}, [$inp]!
-       mov     r4,$key                         @ pass the key
-       vld1.8  {@XMM[4]-@XMM[5]}, [$inp]!
-       mov     r5,#10                          @ pass rounds
-       vld1.8  {@XMM[6]-@XMM[7]}, [$inp]!
-
-       bl      _bsaes_decrypt8
-
-       vst1.8  {@XMM[0]-@XMM[1]}, [$out]!      @ write output
-       vst1.8  {@XMM[6]}, [$out]!
-       vst1.8  {@XMM[4]}, [$out]!
-       vst1.8  {@XMM[2]}, [$out]!
-       vst1.8  {@XMM[7]}, [$out]!
-       vst1.8  {@XMM[3]}, [$out]!
-       subs    $len,$len,#0x80
-       vst1.8  {@XMM[5]}, [$out]!
-       bhi     .Ldec128_loop
-
-       vldmia  sp!,{d8-d15}
-       ldmia   sp!,{r4-r6,pc}
-.size  bsaes_decrypt_128,.-bsaes_decrypt_128
-___
-}
-{
-my ($inp,$out,$len,$key, $ivp,$fp,$rounds)=map("r$_",(0..3,8..10));
-my ($keysched)=("sp");
-
-$code.=<<___;
-.extern AES_cbc_encrypt
-.extern AES_decrypt
-
-.global        bsaes_cbc_encrypt
-.type  bsaes_cbc_encrypt,%function
-.align 5
-bsaes_cbc_encrypt:
-#ifndef        __KERNEL__
-       cmp     $len, #128
-#ifndef        __thumb__
-       blo     AES_cbc_encrypt
-#else
-       bhs     1f
-       b       AES_cbc_encrypt
-1:
-#endif
-#endif
-
-       @ it is up to the caller to make sure we are called with enc == 0
-
-       mov     ip, sp
-       stmdb   sp!, {r4-r10, lr}
-       VFP_ABI_PUSH
-       ldr     $ivp, [ip]                      @ IV is 1st arg on the stack
-       mov     $len, $len, lsr#4               @ len in 16 byte blocks
-       sub     sp, #0x10                       @ scratch space to carry over the IV
-       mov     $fp, sp                         @ save sp
-
-       ldr     $rounds, [$key, #240]           @ get # of rounds
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       @ allocate the key schedule on the stack
-       sub     r12, sp, $rounds, lsl#7         @ 128 bytes per inner round key
-       add     r12, #`128-32`                  @ sifze of bit-slices key schedule
-
-       @ populate the key schedule
-       mov     r4, $key                        @ pass key
-       mov     r5, $rounds                     @ pass # of rounds
-       mov     sp, r12                         @ sp is $keysched
-       bl      _bsaes_key_convert
-       vldmia  $keysched, {@XMM[6]}
-       vstmia  r12,  {@XMM[15]}                @ save last round key
-       veor    @XMM[7], @XMM[7], @XMM[6]       @ fix up round 0 key
-       vstmia  $keysched, {@XMM[7]}
-#else
-       ldr     r12, [$key, #244]
-       eors    r12, #1
-       beq     0f
-
-       @ populate the key schedule
-       str     r12, [$key, #244]
-       mov     r4, $key                        @ pass key
-       mov     r5, $rounds                     @ pass # of rounds
-       add     r12, $key, #248                 @ pass key schedule
-       bl      _bsaes_key_convert
-       add     r4, $key, #248
-       vldmia  r4, {@XMM[6]}
-       vstmia  r12, {@XMM[15]}                 @ save last round key
-       veor    @XMM[7], @XMM[7], @XMM[6]       @ fix up round 0 key
-       vstmia  r4, {@XMM[7]}
-
-.align 2
-0:
-#endif
-
-       vld1.8  {@XMM[15]}, [$ivp]              @ load IV
-       b       .Lcbc_dec_loop
-
-.align 4
-.Lcbc_dec_loop:
-       subs    $len, $len, #0x8
-       bmi     .Lcbc_dec_loop_finish
-
-       vld1.8  {@XMM[0]-@XMM[1]}, [$inp]!      @ load input
-       vld1.8  {@XMM[2]-@XMM[3]}, [$inp]!
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       mov     r4, $keysched                   @ pass the key
-#else
-       add     r4, $key, #248
-#endif
-       vld1.8  {@XMM[4]-@XMM[5]}, [$inp]!
-       mov     r5, $rounds
-       vld1.8  {@XMM[6]-@XMM[7]}, [$inp]
-       sub     $inp, $inp, #0x60
-       vstmia  $fp, {@XMM[15]}                 @ put aside IV
-
-       bl      _bsaes_decrypt8
-
-       vldmia  $fp, {@XMM[14]}                 @ reload IV
-       vld1.8  {@XMM[8]-@XMM[9]}, [$inp]!      @ reload input
-       veor    @XMM[0], @XMM[0], @XMM[14]      @ ^= IV
-       vld1.8  {@XMM[10]-@XMM[11]}, [$inp]!
-       veor    @XMM[1], @XMM[1], @XMM[8]
-       veor    @XMM[6], @XMM[6], @XMM[9]
-       vld1.8  {@XMM[12]-@XMM[13]}, [$inp]!
-       veor    @XMM[4], @XMM[4], @XMM[10]
-       veor    @XMM[2], @XMM[2], @XMM[11]
-       vld1.8  {@XMM[14]-@XMM[15]}, [$inp]!
-       veor    @XMM[7], @XMM[7], @XMM[12]
-       vst1.8  {@XMM[0]-@XMM[1]}, [$out]!      @ write output
-       veor    @XMM[3], @XMM[3], @XMM[13]
-       vst1.8  {@XMM[6]}, [$out]!
-       veor    @XMM[5], @XMM[5], @XMM[14]
-       vst1.8  {@XMM[4]}, [$out]!
-       vst1.8  {@XMM[2]}, [$out]!
-       vst1.8  {@XMM[7]}, [$out]!
-       vst1.8  {@XMM[3]}, [$out]!
-       vst1.8  {@XMM[5]}, [$out]!
-
-       b       .Lcbc_dec_loop
-
-.Lcbc_dec_loop_finish:
-       adds    $len, $len, #8
-       beq     .Lcbc_dec_done
-
-       vld1.8  {@XMM[0]}, [$inp]!              @ load input
-       cmp     $len, #2
-       blo     .Lcbc_dec_one
-       vld1.8  {@XMM[1]}, [$inp]!
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       mov     r4, $keysched                   @ pass the key
-#else
-       add     r4, $key, #248
-#endif
-       mov     r5, $rounds
-       vstmia  $fp, {@XMM[15]}                 @ put aside IV
-       beq     .Lcbc_dec_two
-       vld1.8  {@XMM[2]}, [$inp]!
-       cmp     $len, #4
-       blo     .Lcbc_dec_three
-       vld1.8  {@XMM[3]}, [$inp]!
-       beq     .Lcbc_dec_four
-       vld1.8  {@XMM[4]}, [$inp]!
-       cmp     $len, #6
-       blo     .Lcbc_dec_five
-       vld1.8  {@XMM[5]}, [$inp]!
-       beq     .Lcbc_dec_six
-       vld1.8  {@XMM[6]}, [$inp]!
-       sub     $inp, $inp, #0x70
-
-       bl      _bsaes_decrypt8
-
-       vldmia  $fp, {@XMM[14]}                 @ reload IV
-       vld1.8  {@XMM[8]-@XMM[9]}, [$inp]!      @ reload input
-       veor    @XMM[0], @XMM[0], @XMM[14]      @ ^= IV
-       vld1.8  {@XMM[10]-@XMM[11]}, [$inp]!
-       veor    @XMM[1], @XMM[1], @XMM[8]
-       veor    @XMM[6], @XMM[6], @XMM[9]
-       vld1.8  {@XMM[12]-@XMM[13]}, [$inp]!
-       veor    @XMM[4], @XMM[4], @XMM[10]
-       veor    @XMM[2], @XMM[2], @XMM[11]
-       vld1.8  {@XMM[15]}, [$inp]!
-       veor    @XMM[7], @XMM[7], @XMM[12]
-       vst1.8  {@XMM[0]-@XMM[1]}, [$out]!      @ write output
-       veor    @XMM[3], @XMM[3], @XMM[13]
-       vst1.8  {@XMM[6]}, [$out]!
-       vst1.8  {@XMM[4]}, [$out]!
-       vst1.8  {@XMM[2]}, [$out]!
-       vst1.8  {@XMM[7]}, [$out]!
-       vst1.8  {@XMM[3]}, [$out]!
-       b       .Lcbc_dec_done
-.align 4
-.Lcbc_dec_six:
-       sub     $inp, $inp, #0x60
-       bl      _bsaes_decrypt8
-       vldmia  $fp,{@XMM[14]}                  @ reload IV
-       vld1.8  {@XMM[8]-@XMM[9]}, [$inp]!      @ reload input
-       veor    @XMM[0], @XMM[0], @XMM[14]      @ ^= IV
-       vld1.8  {@XMM[10]-@XMM[11]}, [$inp]!
-       veor    @XMM[1], @XMM[1], @XMM[8]
-       veor    @XMM[6], @XMM[6], @XMM[9]
-       vld1.8  {@XMM[12]}, [$inp]!
-       veor    @XMM[4], @XMM[4], @XMM[10]
-       veor    @XMM[2], @XMM[2], @XMM[11]
-       vld1.8  {@XMM[15]}, [$inp]!
-       veor    @XMM[7], @XMM[7], @XMM[12]
-       vst1.8  {@XMM[0]-@XMM[1]}, [$out]!      @ write output
-       vst1.8  {@XMM[6]}, [$out]!
-       vst1.8  {@XMM[4]}, [$out]!
-       vst1.8  {@XMM[2]}, [$out]!
-       vst1.8  {@XMM[7]}, [$out]!
-       b       .Lcbc_dec_done
-.align 4
-.Lcbc_dec_five:
-       sub     $inp, $inp, #0x50
-       bl      _bsaes_decrypt8
-       vldmia  $fp, {@XMM[14]}                 @ reload IV
-       vld1.8  {@XMM[8]-@XMM[9]}, [$inp]!      @ reload input
-       veor    @XMM[0], @XMM[0], @XMM[14]      @ ^= IV
-       vld1.8  {@XMM[10]-@XMM[11]}, [$inp]!
-       veor    @XMM[1], @XMM[1], @XMM[8]
-       veor    @XMM[6], @XMM[6], @XMM[9]
-       vld1.8  {@XMM[15]}, [$inp]!
-       veor    @XMM[4], @XMM[4], @XMM[10]
-       vst1.8  {@XMM[0]-@XMM[1]}, [$out]!      @ write output
-       veor    @XMM[2], @XMM[2], @XMM[11]
-       vst1.8  {@XMM[6]}, [$out]!
-       vst1.8  {@XMM[4]}, [$out]!
-       vst1.8  {@XMM[2]}, [$out]!
-       b       .Lcbc_dec_done
-.align 4
-.Lcbc_dec_four:
-       sub     $inp, $inp, #0x40
-       bl      _bsaes_decrypt8
-       vldmia  $fp, {@XMM[14]}                 @ reload IV
-       vld1.8  {@XMM[8]-@XMM[9]}, [$inp]!      @ reload input
-       veor    @XMM[0], @XMM[0], @XMM[14]      @ ^= IV
-       vld1.8  {@XMM[10]}, [$inp]!
-       veor    @XMM[1], @XMM[1], @XMM[8]
-       veor    @XMM[6], @XMM[6], @XMM[9]
-       vld1.8  {@XMM[15]}, [$inp]!
-       veor    @XMM[4], @XMM[4], @XMM[10]
-       vst1.8  {@XMM[0]-@XMM[1]}, [$out]!      @ write output
-       vst1.8  {@XMM[6]}, [$out]!
-       vst1.8  {@XMM[4]}, [$out]!
-       b       .Lcbc_dec_done
-.align 4
-.Lcbc_dec_three:
-       sub     $inp, $inp, #0x30
-       bl      _bsaes_decrypt8
-       vldmia  $fp, {@XMM[14]}                 @ reload IV
-       vld1.8  {@XMM[8]-@XMM[9]}, [$inp]!      @ reload input
-       veor    @XMM[0], @XMM[0], @XMM[14]      @ ^= IV
-       vld1.8  {@XMM[15]}, [$inp]!
-       veor    @XMM[1], @XMM[1], @XMM[8]
-       veor    @XMM[6], @XMM[6], @XMM[9]
-       vst1.8  {@XMM[0]-@XMM[1]}, [$out]!      @ write output
-       vst1.8  {@XMM[6]}, [$out]!
-       b       .Lcbc_dec_done
-.align 4
-.Lcbc_dec_two:
-       sub     $inp, $inp, #0x20
-       bl      _bsaes_decrypt8
-       vldmia  $fp, {@XMM[14]}                 @ reload IV
-       vld1.8  {@XMM[8]}, [$inp]!              @ reload input
-       veor    @XMM[0], @XMM[0], @XMM[14]      @ ^= IV
-       vld1.8  {@XMM[15]}, [$inp]!             @ reload input
-       veor    @XMM[1], @XMM[1], @XMM[8]
-       vst1.8  {@XMM[0]-@XMM[1]}, [$out]!      @ write output
-       b       .Lcbc_dec_done
-.align 4
-.Lcbc_dec_one:
-       sub     $inp, $inp, #0x10
-       mov     $rounds, $out                   @ save original out pointer
-       mov     $out, $fp                       @ use the iv scratch space as out buffer
-       mov     r2, $key
-       vmov    @XMM[4],@XMM[15]                @ just in case ensure that IV
-       vmov    @XMM[5],@XMM[0]                 @ and input are preserved
-       bl      AES_decrypt
-       vld1.8  {@XMM[0]}, [$fp,:64]            @ load result
-       veor    @XMM[0], @XMM[0], @XMM[4]       @ ^= IV
-       vmov    @XMM[15], @XMM[5]               @ @XMM[5] holds input
-       vst1.8  {@XMM[0]}, [$rounds]            @ write output
-
-.Lcbc_dec_done:
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       vmov.i32        q0, #0
-       vmov.i32        q1, #0
-.Lcbc_dec_bzero:                               @ wipe key schedule [if any]
-       vstmia          $keysched!, {q0-q1}
-       cmp             $keysched, $fp
-       bne             .Lcbc_dec_bzero
-#endif
-
-       mov     sp, $fp
-       add     sp, #0x10                       @ add sp,$fp,#0x10 is no good for thumb
-       vst1.8  {@XMM[15]}, [$ivp]              @ return IV
-       VFP_ABI_POP
-       ldmia   sp!, {r4-r10, pc}
-.size  bsaes_cbc_encrypt,.-bsaes_cbc_encrypt
-___
-}
-{
-my ($inp,$out,$len,$key, $ctr,$fp,$rounds)=(map("r$_",(0..3,8..10)));
-my $const = "r6";      # shared with _bsaes_encrypt8_alt
-my $keysched = "sp";
-
-$code.=<<___;
-.extern        AES_encrypt
-.global        bsaes_ctr32_encrypt_blocks
-.type  bsaes_ctr32_encrypt_blocks,%function
-.align 5
-bsaes_ctr32_encrypt_blocks:
-       cmp     $len, #8                        @ use plain AES for
-       blo     .Lctr_enc_short                 @ small sizes
-
-       mov     ip, sp
-       stmdb   sp!, {r4-r10, lr}
-       VFP_ABI_PUSH
-       ldr     $ctr, [ip]                      @ ctr is 1st arg on the stack
-       sub     sp, sp, #0x10                   @ scratch space to carry over the ctr
-       mov     $fp, sp                         @ save sp
-
-       ldr     $rounds, [$key, #240]           @ get # of rounds
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       @ allocate the key schedule on the stack
-       sub     r12, sp, $rounds, lsl#7         @ 128 bytes per inner round key
-       add     r12, #`128-32`                  @ size of bit-sliced key schedule
-
-       @ populate the key schedule
-       mov     r4, $key                        @ pass key
-       mov     r5, $rounds                     @ pass # of rounds
-       mov     sp, r12                         @ sp is $keysched
-       bl      _bsaes_key_convert
-       veor    @XMM[7],@XMM[7],@XMM[15]        @ fix up last round key
-       vstmia  r12, {@XMM[7]}                  @ save last round key
-
-       vld1.8  {@XMM[0]}, [$ctr]               @ load counter
-       add     $ctr, $const, #.LREVM0SR-.LM0   @ borrow $ctr
-       vldmia  $keysched, {@XMM[4]}            @ load round0 key
-#else
-       ldr     r12, [$key, #244]
-       eors    r12, #1
-       beq     0f
-
-       @ populate the key schedule
-       str     r12, [$key, #244]
-       mov     r4, $key                        @ pass key
-       mov     r5, $rounds                     @ pass # of rounds
-       add     r12, $key, #248                 @ pass key schedule
-       bl      _bsaes_key_convert
-       veor    @XMM[7],@XMM[7],@XMM[15]        @ fix up last round key
-       vstmia  r12, {@XMM[7]}                  @ save last round key
-
-.align 2
-0:     add     r12, $key, #248
-       vld1.8  {@XMM[0]}, [$ctr]               @ load counter
-       adrl    $ctr, .LREVM0SR                 @ borrow $ctr
-       vldmia  r12, {@XMM[4]}                  @ load round0 key
-       sub     sp, #0x10                       @ place for adjusted round0 key
-#endif
-
-       vmov.i32        @XMM[8],#1              @ compose 1<<96
-       veor            @XMM[9],@XMM[9],@XMM[9]
-       vrev32.8        @XMM[0],@XMM[0]
-       vext.8          @XMM[8],@XMM[9],@XMM[8],#4
-       vrev32.8        @XMM[4],@XMM[4]
-       vadd.u32        @XMM[9],@XMM[8],@XMM[8] @ compose 2<<96
-       vstmia  $keysched, {@XMM[4]}            @ save adjusted round0 key
-       b       .Lctr_enc_loop
-
-.align 4
-.Lctr_enc_loop:
-       vadd.u32        @XMM[10], @XMM[8], @XMM[9]      @ compose 3<<96
-       vadd.u32        @XMM[1], @XMM[0], @XMM[8]       @ +1
-       vadd.u32        @XMM[2], @XMM[0], @XMM[9]       @ +2
-       vadd.u32        @XMM[3], @XMM[0], @XMM[10]      @ +3
-       vadd.u32        @XMM[4], @XMM[1], @XMM[10]
-       vadd.u32        @XMM[5], @XMM[2], @XMM[10]
-       vadd.u32        @XMM[6], @XMM[3], @XMM[10]
-       vadd.u32        @XMM[7], @XMM[4], @XMM[10]
-       vadd.u32        @XMM[10], @XMM[5], @XMM[10]     @ next counter
-
-       @ Borrow prologue from _bsaes_encrypt8 to use the opportunity
-       @ to flip byte order in 32-bit counter
-
-       vldmia          $keysched, {@XMM[9]}            @ load round0 key
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, $keysched, #0x10            @ pass next round key
-#else
-       add             r4, $key, #`248+16`
-#endif
-       vldmia          $ctr, {@XMM[8]}                 @ .LREVM0SR
-       mov             r5, $rounds                     @ pass rounds
-       vstmia          $fp, {@XMM[10]}                 @ save next counter
-       sub             $const, $ctr, #.LREVM0SR-.LSR   @ pass constants
-
-       bl              _bsaes_encrypt8_alt
-
-       subs            $len, $len, #8
-       blo             .Lctr_enc_loop_done
-
-       vld1.8          {@XMM[8]-@XMM[9]}, [$inp]!      @ load input
-       vld1.8          {@XMM[10]-@XMM[11]}, [$inp]!
-       veor            @XMM[0], @XMM[8]
-       veor            @XMM[1], @XMM[9]
-       vld1.8          {@XMM[12]-@XMM[13]}, [$inp]!
-       veor            @XMM[4], @XMM[10]
-       veor            @XMM[6], @XMM[11]
-       vld1.8          {@XMM[14]-@XMM[15]}, [$inp]!
-       veor            @XMM[3], @XMM[12]
-       vst1.8          {@XMM[0]-@XMM[1]}, [$out]!      @ write output
-       veor            @XMM[7], @XMM[13]
-       veor            @XMM[2], @XMM[14]
-       vst1.8          {@XMM[4]}, [$out]!
-       veor            @XMM[5], @XMM[15]
-       vst1.8          {@XMM[6]}, [$out]!
-       vmov.i32        @XMM[8], #1                     @ compose 1<<96
-       vst1.8          {@XMM[3]}, [$out]!
-       veor            @XMM[9], @XMM[9], @XMM[9]
-       vst1.8          {@XMM[7]}, [$out]!
-       vext.8          @XMM[8], @XMM[9], @XMM[8], #4
-       vst1.8          {@XMM[2]}, [$out]!
-       vadd.u32        @XMM[9],@XMM[8],@XMM[8]         @ compose 2<<96
-       vst1.8          {@XMM[5]}, [$out]!
-       vldmia          $fp, {@XMM[0]}                  @ load counter
-
-       bne             .Lctr_enc_loop
-       b               .Lctr_enc_done
-
-.align 4
-.Lctr_enc_loop_done:
-       add             $len, $len, #8
-       vld1.8          {@XMM[8]}, [$inp]!      @ load input
-       veor            @XMM[0], @XMM[8]
-       vst1.8          {@XMM[0]}, [$out]!      @ write output
-       cmp             $len, #2
-       blo             .Lctr_enc_done
-       vld1.8          {@XMM[9]}, [$inp]!
-       veor            @XMM[1], @XMM[9]
-       vst1.8          {@XMM[1]}, [$out]!
-       beq             .Lctr_enc_done
-       vld1.8          {@XMM[10]}, [$inp]!
-       veor            @XMM[4], @XMM[10]
-       vst1.8          {@XMM[4]}, [$out]!
-       cmp             $len, #4
-       blo             .Lctr_enc_done
-       vld1.8          {@XMM[11]}, [$inp]!
-       veor            @XMM[6], @XMM[11]
-       vst1.8          {@XMM[6]}, [$out]!
-       beq             .Lctr_enc_done
-       vld1.8          {@XMM[12]}, [$inp]!
-       veor            @XMM[3], @XMM[12]
-       vst1.8          {@XMM[3]}, [$out]!
-       cmp             $len, #6
-       blo             .Lctr_enc_done
-       vld1.8          {@XMM[13]}, [$inp]!
-       veor            @XMM[7], @XMM[13]
-       vst1.8          {@XMM[7]}, [$out]!
-       beq             .Lctr_enc_done
-       vld1.8          {@XMM[14]}, [$inp]
-       veor            @XMM[2], @XMM[14]
-       vst1.8          {@XMM[2]}, [$out]!
-
-.Lctr_enc_done:
-       vmov.i32        q0, #0
-       vmov.i32        q1, #0
-#ifndef        BSAES_ASM_EXTENDED_KEY
-.Lctr_enc_bzero:                       @ wipe key schedule [if any]
-       vstmia          $keysched!, {q0-q1}
-       cmp             $keysched, $fp
-       bne             .Lctr_enc_bzero
-#else
-       vstmia          $keysched, {q0-q1}
-#endif
-
-       mov     sp, $fp
-       add     sp, #0x10               @ add sp,$fp,#0x10 is no good for thumb
-       VFP_ABI_POP
-       ldmia   sp!, {r4-r10, pc}       @ return
-
-.align 4
-.Lctr_enc_short:
-       ldr     ip, [sp]                @ ctr pointer is passed on stack
-       stmdb   sp!, {r4-r8, lr}
-
-       mov     r4, $inp                @ copy arguments
-       mov     r5, $out
-       mov     r6, $len
-       mov     r7, $key
-       ldr     r8, [ip, #12]           @ load counter LSW
-       vld1.8  {@XMM[1]}, [ip]         @ load whole counter value
-#ifdef __ARMEL__
-       rev     r8, r8
-#endif
-       sub     sp, sp, #0x10
-       vst1.8  {@XMM[1]}, [sp,:64]     @ copy counter value
-       sub     sp, sp, #0x10
-
-.Lctr_enc_short_loop:
-       add     r0, sp, #0x10           @ input counter value
-       mov     r1, sp                  @ output on the stack
-       mov     r2, r7                  @ key
-
-       bl      AES_encrypt
-
-       vld1.8  {@XMM[0]}, [r4]!        @ load input
-       vld1.8  {@XMM[1]}, [sp,:64]     @ load encrypted counter
-       add     r8, r8, #1
-#ifdef __ARMEL__
-       rev     r0, r8
-       str     r0, [sp, #0x1c]         @ next counter value
-#else
-       str     r8, [sp, #0x1c]         @ next counter value
-#endif
-       veor    @XMM[0],@XMM[0],@XMM[1]
-       vst1.8  {@XMM[0]}, [r5]!        @ store output
-       subs    r6, r6, #1
-       bne     .Lctr_enc_short_loop
-
-       vmov.i32        q0, #0
-       vmov.i32        q1, #0
-       vstmia          sp!, {q0-q1}
-
-       ldmia   sp!, {r4-r8, pc}
-.size  bsaes_ctr32_encrypt_blocks,.-bsaes_ctr32_encrypt_blocks
-___
-}
-{
-######################################################################
-# void bsaes_xts_[en|de]crypt(const char *inp,char *out,size_t len,
-#      const AES_KEY *key1, const AES_KEY *key2,
-#      const unsigned char iv[16]);
-#
-my ($inp,$out,$len,$key,$rounds,$magic,$fp)=(map("r$_",(7..10,1..3)));
-my $const="r6";                # returned by _bsaes_key_convert
-my $twmask=@XMM[5];
-my @T=@XMM[6..7];
-
-$code.=<<___;
-.globl bsaes_xts_encrypt
-.type  bsaes_xts_encrypt,%function
-.align 4
-bsaes_xts_encrypt:
-       mov     ip, sp
-       stmdb   sp!, {r4-r10, lr}               @ 0x20
-       VFP_ABI_PUSH
-       mov     r6, sp                          @ future $fp
-
-       mov     $inp, r0
-       mov     $out, r1
-       mov     $len, r2
-       mov     $key, r3
-
-       sub     r0, sp, #0x10                   @ 0x10
-       bic     r0, #0xf                        @ align at 16 bytes
-       mov     sp, r0
-
-#ifdef XTS_CHAIN_TWEAK
-       ldr     r0, [ip]                        @ pointer to input tweak
-#else
-       @ generate initial tweak
-       ldr     r0, [ip, #4]                    @ iv[]
-       mov     r1, sp
-       ldr     r2, [ip, #0]                    @ key2
-       bl      AES_encrypt
-       mov     r0,sp                           @ pointer to initial tweak
-#endif
-
-       ldr     $rounds, [$key, #240]           @ get # of rounds
-       mov     $fp, r6
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       @ allocate the key schedule on the stack
-       sub     r12, sp, $rounds, lsl#7         @ 128 bytes per inner round key
-       @ add   r12, #`128-32`                  @ size of bit-sliced key schedule
-       sub     r12, #`32+16`                   @ place for tweak[9]
-
-       @ populate the key schedule
-       mov     r4, $key                        @ pass key
-       mov     r5, $rounds                     @ pass # of rounds
-       mov     sp, r12
-       add     r12, #0x90                      @ pass key schedule
-       bl      _bsaes_key_convert
-       veor    @XMM[7], @XMM[7], @XMM[15]      @ fix up last round key
-       vstmia  r12, {@XMM[7]}                  @ save last round key
-#else
-       ldr     r12, [$key, #244]
-       eors    r12, #1
-       beq     0f
-
-       str     r12, [$key, #244]
-       mov     r4, $key                        @ pass key
-       mov     r5, $rounds                     @ pass # of rounds
-       add     r12, $key, #248                 @ pass key schedule
-       bl      _bsaes_key_convert
-       veor    @XMM[7], @XMM[7], @XMM[15]      @ fix up last round key
-       vstmia  r12, {@XMM[7]}
-
-.align 2
-0:     sub     sp, #0x90                       @ place for tweak[9]
-#endif
-
-       vld1.8  {@XMM[8]}, [r0]                 @ initial tweak
-       adr     $magic, .Lxts_magic
-
-       subs    $len, #0x80
-       blo     .Lxts_enc_short
-       b       .Lxts_enc_loop
-
-.align 4
-.Lxts_enc_loop:
-       vldmia          $magic, {$twmask}       @ load XTS magic
-       vshr.s64        @T[0], @XMM[8], #63
-       mov             r0, sp
-       vand            @T[0], @T[0], $twmask
-___
-for($i=9;$i<16;$i++) {
-$code.=<<___;
-       vadd.u64        @XMM[$i], @XMM[$i-1], @XMM[$i-1]
-       vst1.64         {@XMM[$i-1]}, [r0,:128]!
-       vswp            `&Dhi("@T[0]")`,`&Dlo("@T[0]")`
-       vshr.s64        @T[1], @XMM[$i], #63
-       veor            @XMM[$i], @XMM[$i], @T[0]
-       vand            @T[1], @T[1], $twmask
-___
-       @T=reverse(@T);
-
-$code.=<<___ if ($i>=10);
-       vld1.8          {@XMM[$i-10]}, [$inp]!
-___
-$code.=<<___ if ($i>=11);
-       veor            @XMM[$i-11], @XMM[$i-11], @XMM[$i-3]
-___
-}
-$code.=<<___;
-       vadd.u64        @XMM[8], @XMM[15], @XMM[15]
-       vst1.64         {@XMM[15]}, [r0,:128]!
-       vswp            `&Dhi("@T[0]")`,`&Dlo("@T[0]")`
-       veor            @XMM[8], @XMM[8], @T[0]
-       vst1.64         {@XMM[8]}, [r0,:128]            @ next round tweak
-
-       vld1.8          {@XMM[6]-@XMM[7]}, [$inp]!
-       veor            @XMM[5], @XMM[5], @XMM[13]
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x90                   @ pass key schedule
-#else
-       add             r4, $key, #248                  @ pass key schedule
-#endif
-       veor            @XMM[6], @XMM[6], @XMM[14]
-       mov             r5, $rounds                     @ pass rounds
-       veor            @XMM[7], @XMM[7], @XMM[15]
-       mov             r0, sp
-
-       bl              _bsaes_encrypt8
-
-       vld1.64         {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
-       vld1.64         {@XMM[10]-@XMM[11]}, [r0,:128]!
-       veor            @XMM[0], @XMM[0], @XMM[ 8]
-       vld1.64         {@XMM[12]-@XMM[13]}, [r0,:128]!
-       veor            @XMM[1], @XMM[1], @XMM[ 9]
-       veor            @XMM[8], @XMM[4], @XMM[10]
-       vst1.8          {@XMM[0]-@XMM[1]}, [$out]!
-       veor            @XMM[9], @XMM[6], @XMM[11]
-       vld1.64         {@XMM[14]-@XMM[15]}, [r0,:128]!
-       veor            @XMM[10], @XMM[3], @XMM[12]
-       vst1.8          {@XMM[8]-@XMM[9]}, [$out]!
-       veor            @XMM[11], @XMM[7], @XMM[13]
-       veor            @XMM[12], @XMM[2], @XMM[14]
-       vst1.8          {@XMM[10]-@XMM[11]}, [$out]!
-       veor            @XMM[13], @XMM[5], @XMM[15]
-       vst1.8          {@XMM[12]-@XMM[13]}, [$out]!
-
-       vld1.64         {@XMM[8]}, [r0,:128]            @ next round tweak
-
-       subs            $len, #0x80
-       bpl             .Lxts_enc_loop
-
-.Lxts_enc_short:
-       adds            $len, #0x70
-       bmi             .Lxts_enc_done
-
-       vldmia          $magic, {$twmask}       @ load XTS magic
-       vshr.s64        @T[0], @XMM[8], #63
-       mov             r0, sp
-       vand            @T[0], @T[0], $twmask
-___
-for($i=9;$i<16;$i++) {
-$code.=<<___;
-       vadd.u64        @XMM[$i], @XMM[$i-1], @XMM[$i-1]
-       vst1.64         {@XMM[$i-1]}, [r0,:128]!
-       vswp            `&Dhi("@T[0]")`,`&Dlo("@T[0]")`
-       vshr.s64        @T[1], @XMM[$i], #63
-       veor            @XMM[$i], @XMM[$i], @T[0]
-       vand            @T[1], @T[1], $twmask
-___
-       @T=reverse(@T);
-
-$code.=<<___ if ($i>=10);
-       vld1.8          {@XMM[$i-10]}, [$inp]!
-       subs            $len, #0x10
-       bmi             .Lxts_enc_`$i-9`
-___
-$code.=<<___ if ($i>=11);
-       veor            @XMM[$i-11], @XMM[$i-11], @XMM[$i-3]
-___
-}
-$code.=<<___;
-       sub             $len, #0x10
-       vst1.64         {@XMM[15]}, [r0,:128]           @ next round tweak
-
-       vld1.8          {@XMM[6]}, [$inp]!
-       veor            @XMM[5], @XMM[5], @XMM[13]
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x90                   @ pass key schedule
-#else
-       add             r4, $key, #248                  @ pass key schedule
-#endif
-       veor            @XMM[6], @XMM[6], @XMM[14]
-       mov             r5, $rounds                     @ pass rounds
-       mov             r0, sp
-
-       bl              _bsaes_encrypt8
-
-       vld1.64         {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
-       vld1.64         {@XMM[10]-@XMM[11]}, [r0,:128]!
-       veor            @XMM[0], @XMM[0], @XMM[ 8]
-       vld1.64         {@XMM[12]-@XMM[13]}, [r0,:128]!
-       veor            @XMM[1], @XMM[1], @XMM[ 9]
-       veor            @XMM[8], @XMM[4], @XMM[10]
-       vst1.8          {@XMM[0]-@XMM[1]}, [$out]!
-       veor            @XMM[9], @XMM[6], @XMM[11]
-       vld1.64         {@XMM[14]}, [r0,:128]!
-       veor            @XMM[10], @XMM[3], @XMM[12]
-       vst1.8          {@XMM[8]-@XMM[9]}, [$out]!
-       veor            @XMM[11], @XMM[7], @XMM[13]
-       veor            @XMM[12], @XMM[2], @XMM[14]
-       vst1.8          {@XMM[10]-@XMM[11]}, [$out]!
-       vst1.8          {@XMM[12]}, [$out]!
-
-       vld1.64         {@XMM[8]}, [r0,:128]            @ next round tweak
-       b               .Lxts_enc_done
-.align 4
-.Lxts_enc_6:
-       vst1.64         {@XMM[14]}, [r0,:128]           @ next round tweak
-
-       veor            @XMM[4], @XMM[4], @XMM[12]
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x90                   @ pass key schedule
-#else
-       add             r4, $key, #248                  @ pass key schedule
-#endif
-       veor            @XMM[5], @XMM[5], @XMM[13]
-       mov             r5, $rounds                     @ pass rounds
-       mov             r0, sp
-
-       bl              _bsaes_encrypt8
-
-       vld1.64         {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
-       vld1.64         {@XMM[10]-@XMM[11]}, [r0,:128]!
-       veor            @XMM[0], @XMM[0], @XMM[ 8]
-       vld1.64         {@XMM[12]-@XMM[13]}, [r0,:128]!
-       veor            @XMM[1], @XMM[1], @XMM[ 9]
-       veor            @XMM[8], @XMM[4], @XMM[10]
-       vst1.8          {@XMM[0]-@XMM[1]}, [$out]!
-       veor            @XMM[9], @XMM[6], @XMM[11]
-       veor            @XMM[10], @XMM[3], @XMM[12]
-       vst1.8          {@XMM[8]-@XMM[9]}, [$out]!
-       veor            @XMM[11], @XMM[7], @XMM[13]
-       vst1.8          {@XMM[10]-@XMM[11]}, [$out]!
-
-       vld1.64         {@XMM[8]}, [r0,:128]            @ next round tweak
-       b               .Lxts_enc_done
-
-@ put this in range for both ARM and Thumb mode adr instructions
-.align 5
-.Lxts_magic:
-       .quad   1, 0x87
-
-.align 5
-.Lxts_enc_5:
-       vst1.64         {@XMM[13]}, [r0,:128]           @ next round tweak
-
-       veor            @XMM[3], @XMM[3], @XMM[11]
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x90                   @ pass key schedule
-#else
-       add             r4, $key, #248                  @ pass key schedule
-#endif
-       veor            @XMM[4], @XMM[4], @XMM[12]
-       mov             r5, $rounds                     @ pass rounds
-       mov             r0, sp
-
-       bl              _bsaes_encrypt8
-
-       vld1.64         {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
-       vld1.64         {@XMM[10]-@XMM[11]}, [r0,:128]!
-       veor            @XMM[0], @XMM[0], @XMM[ 8]
-       vld1.64         {@XMM[12]}, [r0,:128]!
-       veor            @XMM[1], @XMM[1], @XMM[ 9]
-       veor            @XMM[8], @XMM[4], @XMM[10]
-       vst1.8          {@XMM[0]-@XMM[1]}, [$out]!
-       veor            @XMM[9], @XMM[6], @XMM[11]
-       veor            @XMM[10], @XMM[3], @XMM[12]
-       vst1.8          {@XMM[8]-@XMM[9]}, [$out]!
-       vst1.8          {@XMM[10]}, [$out]!
-
-       vld1.64         {@XMM[8]}, [r0,:128]            @ next round tweak
-       b               .Lxts_enc_done
-.align 4
-.Lxts_enc_4:
-       vst1.64         {@XMM[12]}, [r0,:128]           @ next round tweak
-
-       veor            @XMM[2], @XMM[2], @XMM[10]
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x90                   @ pass key schedule
-#else
-       add             r4, $key, #248                  @ pass key schedule
-#endif
-       veor            @XMM[3], @XMM[3], @XMM[11]
-       mov             r5, $rounds                     @ pass rounds
-       mov             r0, sp
-
-       bl              _bsaes_encrypt8
-
-       vld1.64         {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
-       vld1.64         {@XMM[10]-@XMM[11]}, [r0,:128]!
-       veor            @XMM[0], @XMM[0], @XMM[ 8]
-       veor            @XMM[1], @XMM[1], @XMM[ 9]
-       veor            @XMM[8], @XMM[4], @XMM[10]
-       vst1.8          {@XMM[0]-@XMM[1]}, [$out]!
-       veor            @XMM[9], @XMM[6], @XMM[11]
-       vst1.8          {@XMM[8]-@XMM[9]}, [$out]!
-
-       vld1.64         {@XMM[8]}, [r0,:128]            @ next round tweak
-       b               .Lxts_enc_done
-.align 4
-.Lxts_enc_3:
-       vst1.64         {@XMM[11]}, [r0,:128]           @ next round tweak
-
-       veor            @XMM[1], @XMM[1], @XMM[9]
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x90                   @ pass key schedule
-#else
-       add             r4, $key, #248                  @ pass key schedule
-#endif
-       veor            @XMM[2], @XMM[2], @XMM[10]
-       mov             r5, $rounds                     @ pass rounds
-       mov             r0, sp
-
-       bl              _bsaes_encrypt8
-
-       vld1.64         {@XMM[8]-@XMM[9]}, [r0,:128]!
-       vld1.64         {@XMM[10]}, [r0,:128]!
-       veor            @XMM[0], @XMM[0], @XMM[ 8]
-       veor            @XMM[1], @XMM[1], @XMM[ 9]
-       veor            @XMM[8], @XMM[4], @XMM[10]
-       vst1.8          {@XMM[0]-@XMM[1]}, [$out]!
-       vst1.8          {@XMM[8]}, [$out]!
-
-       vld1.64         {@XMM[8]}, [r0,:128]            @ next round tweak
-       b               .Lxts_enc_done
-.align 4
-.Lxts_enc_2:
-       vst1.64         {@XMM[10]}, [r0,:128]           @ next round tweak
-
-       veor            @XMM[0], @XMM[0], @XMM[8]
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x90                   @ pass key schedule
-#else
-       add             r4, $key, #248                  @ pass key schedule
-#endif
-       veor            @XMM[1], @XMM[1], @XMM[9]
-       mov             r5, $rounds                     @ pass rounds
-       mov             r0, sp
-
-       bl              _bsaes_encrypt8
-
-       vld1.64         {@XMM[8]-@XMM[9]}, [r0,:128]!
-       veor            @XMM[0], @XMM[0], @XMM[ 8]
-       veor            @XMM[1], @XMM[1], @XMM[ 9]
-       vst1.8          {@XMM[0]-@XMM[1]}, [$out]!
-
-       vld1.64         {@XMM[8]}, [r0,:128]            @ next round tweak
-       b               .Lxts_enc_done
-.align 4
-.Lxts_enc_1:
-       mov             r0, sp
-       veor            @XMM[0], @XMM[8]
-       mov             r1, sp
-       vst1.8          {@XMM[0]}, [sp,:128]
-       mov             r2, $key
-       mov             r4, $fp                         @ preserve fp
-
-       bl              AES_encrypt
-
-       vld1.8          {@XMM[0]}, [sp,:128]
-       veor            @XMM[0], @XMM[0], @XMM[8]
-       vst1.8          {@XMM[0]}, [$out]!
-       mov             $fp, r4
-
-       vmov            @XMM[8], @XMM[9]                @ next round tweak
-
-.Lxts_enc_done:
-#ifndef        XTS_CHAIN_TWEAK
-       adds            $len, #0x10
-       beq             .Lxts_enc_ret
-       sub             r6, $out, #0x10
-
-.Lxts_enc_steal:
-       ldrb            r0, [$inp], #1
-       ldrb            r1, [$out, #-0x10]
-       strb            r0, [$out, #-0x10]
-       strb            r1, [$out], #1
-
-       subs            $len, #1
-       bhi             .Lxts_enc_steal
-
-       vld1.8          {@XMM[0]}, [r6]
-       mov             r0, sp
-       veor            @XMM[0], @XMM[0], @XMM[8]
-       mov             r1, sp
-       vst1.8          {@XMM[0]}, [sp,:128]
-       mov             r2, $key
-       mov             r4, $fp                 @ preserve fp
-
-       bl              AES_encrypt
-
-       vld1.8          {@XMM[0]}, [sp,:128]
-       veor            @XMM[0], @XMM[0], @XMM[8]
-       vst1.8          {@XMM[0]}, [r6]
-       mov             $fp, r4
-#endif
-
-.Lxts_enc_ret:
-       bic             r0, $fp, #0xf
-       vmov.i32        q0, #0
-       vmov.i32        q1, #0
-#ifdef XTS_CHAIN_TWEAK
-       ldr             r1, [$fp, #0x20+VFP_ABI_FRAME]  @ chain tweak
-#endif
-.Lxts_enc_bzero:                               @ wipe key schedule [if any]
-       vstmia          sp!, {q0-q1}
-       cmp             sp, r0
-       bne             .Lxts_enc_bzero
-
-       mov             sp, $fp
-#ifdef XTS_CHAIN_TWEAK
-       vst1.8          {@XMM[8]}, [r1]
-#endif
-       VFP_ABI_POP
-       ldmia           sp!, {r4-r10, pc}       @ return
-
-.size  bsaes_xts_encrypt,.-bsaes_xts_encrypt
-
-.globl bsaes_xts_decrypt
-.type  bsaes_xts_decrypt,%function
-.align 4
-bsaes_xts_decrypt:
-       mov     ip, sp
-       stmdb   sp!, {r4-r10, lr}               @ 0x20
-       VFP_ABI_PUSH
-       mov     r6, sp                          @ future $fp
-
-       mov     $inp, r0
-       mov     $out, r1
-       mov     $len, r2
-       mov     $key, r3
-
-       sub     r0, sp, #0x10                   @ 0x10
-       bic     r0, #0xf                        @ align at 16 bytes
-       mov     sp, r0
-
-#ifdef XTS_CHAIN_TWEAK
-       ldr     r0, [ip]                        @ pointer to input tweak
-#else
-       @ generate initial tweak
-       ldr     r0, [ip, #4]                    @ iv[]
-       mov     r1, sp
-       ldr     r2, [ip, #0]                    @ key2
-       bl      AES_encrypt
-       mov     r0, sp                          @ pointer to initial tweak
-#endif
-
-       ldr     $rounds, [$key, #240]           @ get # of rounds
-       mov     $fp, r6
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       @ allocate the key schedule on the stack
-       sub     r12, sp, $rounds, lsl#7         @ 128 bytes per inner round key
-       @ add   r12, #`128-32`                  @ size of bit-sliced key schedule
-       sub     r12, #`32+16`                   @ place for tweak[9]
-
-       @ populate the key schedule
-       mov     r4, $key                        @ pass key
-       mov     r5, $rounds                     @ pass # of rounds
-       mov     sp, r12
-       add     r12, #0x90                      @ pass key schedule
-       bl      _bsaes_key_convert
-       add     r4, sp, #0x90
-       vldmia  r4, {@XMM[6]}
-       vstmia  r12,  {@XMM[15]}                @ save last round key
-       veor    @XMM[7], @XMM[7], @XMM[6]       @ fix up round 0 key
-       vstmia  r4, {@XMM[7]}
-#else
-       ldr     r12, [$key, #244]
-       eors    r12, #1
-       beq     0f
-
-       str     r12, [$key, #244]
-       mov     r4, $key                        @ pass key
-       mov     r5, $rounds                     @ pass # of rounds
-       add     r12, $key, #248                 @ pass key schedule
-       bl      _bsaes_key_convert
-       add     r4, $key, #248
-       vldmia  r4, {@XMM[6]}
-       vstmia  r12,  {@XMM[15]}                @ save last round key
-       veor    @XMM[7], @XMM[7], @XMM[6]       @ fix up round 0 key
-       vstmia  r4, {@XMM[7]}
-
-.align 2
-0:     sub     sp, #0x90                       @ place for tweak[9]
-#endif
-       vld1.8  {@XMM[8]}, [r0]                 @ initial tweak
-       adr     $magic, .Lxts_magic
-
-#ifndef        XTS_CHAIN_TWEAK
-       tst     $len, #0xf                      @ if not multiple of 16
-       it      ne                              @ Thumb2 thing, sanity check in ARM
-       subne   $len, #0x10                     @ subtract another 16 bytes
-#endif
-       subs    $len, #0x80
-
-       blo     .Lxts_dec_short
-       b       .Lxts_dec_loop
-
-.align 4
-.Lxts_dec_loop:
-       vldmia          $magic, {$twmask}       @ load XTS magic
-       vshr.s64        @T[0], @XMM[8], #63
-       mov             r0, sp
-       vand            @T[0], @T[0], $twmask
-___
-for($i=9;$i<16;$i++) {
-$code.=<<___;
-       vadd.u64        @XMM[$i], @XMM[$i-1], @XMM[$i-1]
-       vst1.64         {@XMM[$i-1]}, [r0,:128]!
-       vswp            `&Dhi("@T[0]")`,`&Dlo("@T[0]")`
-       vshr.s64        @T[1], @XMM[$i], #63
-       veor            @XMM[$i], @XMM[$i], @T[0]
-       vand            @T[1], @T[1], $twmask
-___
-       @T=reverse(@T);
-
-$code.=<<___ if ($i>=10);
-       vld1.8          {@XMM[$i-10]}, [$inp]!
-___
-$code.=<<___ if ($i>=11);
-       veor            @XMM[$i-11], @XMM[$i-11], @XMM[$i-3]
-___
-}
-$code.=<<___;
-       vadd.u64        @XMM[8], @XMM[15], @XMM[15]
-       vst1.64         {@XMM[15]}, [r0,:128]!
-       vswp            `&Dhi("@T[0]")`,`&Dlo("@T[0]")`
-       veor            @XMM[8], @XMM[8], @T[0]
-       vst1.64         {@XMM[8]}, [r0,:128]            @ next round tweak
-
-       vld1.8          {@XMM[6]-@XMM[7]}, [$inp]!
-       veor            @XMM[5], @XMM[5], @XMM[13]
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x90                   @ pass key schedule
-#else
-       add             r4, $key, #248                  @ pass key schedule
-#endif
-       veor            @XMM[6], @XMM[6], @XMM[14]
-       mov             r5, $rounds                     @ pass rounds
-       veor            @XMM[7], @XMM[7], @XMM[15]
-       mov             r0, sp
-
-       bl              _bsaes_decrypt8
-
-       vld1.64         {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
-       vld1.64         {@XMM[10]-@XMM[11]}, [r0,:128]!
-       veor            @XMM[0], @XMM[0], @XMM[ 8]
-       vld1.64         {@XMM[12]-@XMM[13]}, [r0,:128]!
-       veor            @XMM[1], @XMM[1], @XMM[ 9]
-       veor            @XMM[8], @XMM[6], @XMM[10]
-       vst1.8          {@XMM[0]-@XMM[1]}, [$out]!
-       veor            @XMM[9], @XMM[4], @XMM[11]
-       vld1.64         {@XMM[14]-@XMM[15]}, [r0,:128]!
-       veor            @XMM[10], @XMM[2], @XMM[12]
-       vst1.8          {@XMM[8]-@XMM[9]}, [$out]!
-       veor            @XMM[11], @XMM[7], @XMM[13]
-       veor            @XMM[12], @XMM[3], @XMM[14]
-       vst1.8          {@XMM[10]-@XMM[11]}, [$out]!
-       veor            @XMM[13], @XMM[5], @XMM[15]
-       vst1.8          {@XMM[12]-@XMM[13]}, [$out]!
-
-       vld1.64         {@XMM[8]}, [r0,:128]            @ next round tweak
-
-       subs            $len, #0x80
-       bpl             .Lxts_dec_loop
-
-.Lxts_dec_short:
-       adds            $len, #0x70
-       bmi             .Lxts_dec_done
-
-       vldmia          $magic, {$twmask}       @ load XTS magic
-       vshr.s64        @T[0], @XMM[8], #63
-       mov             r0, sp
-       vand            @T[0], @T[0], $twmask
-___
-for($i=9;$i<16;$i++) {
-$code.=<<___;
-       vadd.u64        @XMM[$i], @XMM[$i-1], @XMM[$i-1]
-       vst1.64         {@XMM[$i-1]}, [r0,:128]!
-       vswp            `&Dhi("@T[0]")`,`&Dlo("@T[0]")`
-       vshr.s64        @T[1], @XMM[$i], #63
-       veor            @XMM[$i], @XMM[$i], @T[0]
-       vand            @T[1], @T[1], $twmask
-___
-       @T=reverse(@T);
-
-$code.=<<___ if ($i>=10);
-       vld1.8          {@XMM[$i-10]}, [$inp]!
-       subs            $len, #0x10
-       bmi             .Lxts_dec_`$i-9`
-___
-$code.=<<___ if ($i>=11);
-       veor            @XMM[$i-11], @XMM[$i-11], @XMM[$i-3]
-___
-}
-$code.=<<___;
-       sub             $len, #0x10
-       vst1.64         {@XMM[15]}, [r0,:128]           @ next round tweak
-
-       vld1.8          {@XMM[6]}, [$inp]!
-       veor            @XMM[5], @XMM[5], @XMM[13]
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x90                   @ pass key schedule
-#else
-       add             r4, $key, #248                  @ pass key schedule
-#endif
-       veor            @XMM[6], @XMM[6], @XMM[14]
-       mov             r5, $rounds                     @ pass rounds
-       mov             r0, sp
-
-       bl              _bsaes_decrypt8
-
-       vld1.64         {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
-       vld1.64         {@XMM[10]-@XMM[11]}, [r0,:128]!
-       veor            @XMM[0], @XMM[0], @XMM[ 8]
-       vld1.64         {@XMM[12]-@XMM[13]}, [r0,:128]!
-       veor            @XMM[1], @XMM[1], @XMM[ 9]
-       veor            @XMM[8], @XMM[6], @XMM[10]
-       vst1.8          {@XMM[0]-@XMM[1]}, [$out]!
-       veor            @XMM[9], @XMM[4], @XMM[11]
-       vld1.64         {@XMM[14]}, [r0,:128]!
-       veor            @XMM[10], @XMM[2], @XMM[12]
-       vst1.8          {@XMM[8]-@XMM[9]}, [$out]!
-       veor            @XMM[11], @XMM[7], @XMM[13]
-       veor            @XMM[12], @XMM[3], @XMM[14]
-       vst1.8          {@XMM[10]-@XMM[11]}, [$out]!
-       vst1.8          {@XMM[12]}, [$out]!
-
-       vld1.64         {@XMM[8]}, [r0,:128]            @ next round tweak
-       b               .Lxts_dec_done
-.align 4
-.Lxts_dec_6:
-       vst1.64         {@XMM[14]}, [r0,:128]           @ next round tweak
-
-       veor            @XMM[4], @XMM[4], @XMM[12]
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x90                   @ pass key schedule
-#else
-       add             r4, $key, #248                  @ pass key schedule
-#endif
-       veor            @XMM[5], @XMM[5], @XMM[13]
-       mov             r5, $rounds                     @ pass rounds
-       mov             r0, sp
-
-       bl              _bsaes_decrypt8
-
-       vld1.64         {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
-       vld1.64         {@XMM[10]-@XMM[11]}, [r0,:128]!
-       veor            @XMM[0], @XMM[0], @XMM[ 8]
-       vld1.64         {@XMM[12]-@XMM[13]}, [r0,:128]!
-       veor            @XMM[1], @XMM[1], @XMM[ 9]
-       veor            @XMM[8], @XMM[6], @XMM[10]
-       vst1.8          {@XMM[0]-@XMM[1]}, [$out]!
-       veor            @XMM[9], @XMM[4], @XMM[11]
-       veor            @XMM[10], @XMM[2], @XMM[12]
-       vst1.8          {@XMM[8]-@XMM[9]}, [$out]!
-       veor            @XMM[11], @XMM[7], @XMM[13]
-       vst1.8          {@XMM[10]-@XMM[11]}, [$out]!
-
-       vld1.64         {@XMM[8]}, [r0,:128]            @ next round tweak
-       b               .Lxts_dec_done
-.align 4
-.Lxts_dec_5:
-       vst1.64         {@XMM[13]}, [r0,:128]           @ next round tweak
-
-       veor            @XMM[3], @XMM[3], @XMM[11]
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x90                   @ pass key schedule
-#else
-       add             r4, $key, #248                  @ pass key schedule
-#endif
-       veor            @XMM[4], @XMM[4], @XMM[12]
-       mov             r5, $rounds                     @ pass rounds
-       mov             r0, sp
-
-       bl              _bsaes_decrypt8
-
-       vld1.64         {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
-       vld1.64         {@XMM[10]-@XMM[11]}, [r0,:128]!
-       veor            @XMM[0], @XMM[0], @XMM[ 8]
-       vld1.64         {@XMM[12]}, [r0,:128]!
-       veor            @XMM[1], @XMM[1], @XMM[ 9]
-       veor            @XMM[8], @XMM[6], @XMM[10]
-       vst1.8          {@XMM[0]-@XMM[1]}, [$out]!
-       veor            @XMM[9], @XMM[4], @XMM[11]
-       veor            @XMM[10], @XMM[2], @XMM[12]
-       vst1.8          {@XMM[8]-@XMM[9]}, [$out]!
-       vst1.8          {@XMM[10]}, [$out]!
-
-       vld1.64         {@XMM[8]}, [r0,:128]            @ next round tweak
-       b               .Lxts_dec_done
-.align 4
-.Lxts_dec_4:
-       vst1.64         {@XMM[12]}, [r0,:128]           @ next round tweak
-
-       veor            @XMM[2], @XMM[2], @XMM[10]
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x90                   @ pass key schedule
-#else
-       add             r4, $key, #248                  @ pass key schedule
-#endif
-       veor            @XMM[3], @XMM[3], @XMM[11]
-       mov             r5, $rounds                     @ pass rounds
-       mov             r0, sp
-
-       bl              _bsaes_decrypt8
-
-       vld1.64         {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
-       vld1.64         {@XMM[10]-@XMM[11]}, [r0,:128]!
-       veor            @XMM[0], @XMM[0], @XMM[ 8]
-       veor            @XMM[1], @XMM[1], @XMM[ 9]
-       veor            @XMM[8], @XMM[6], @XMM[10]
-       vst1.8          {@XMM[0]-@XMM[1]}, [$out]!
-       veor            @XMM[9], @XMM[4], @XMM[11]
-       vst1.8          {@XMM[8]-@XMM[9]}, [$out]!
-
-       vld1.64         {@XMM[8]}, [r0,:128]            @ next round tweak
-       b               .Lxts_dec_done
-.align 4
-.Lxts_dec_3:
-       vst1.64         {@XMM[11]}, [r0,:128]           @ next round tweak
-
-       veor            @XMM[1], @XMM[1], @XMM[9]
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x90                   @ pass key schedule
-#else
-       add             r4, $key, #248                  @ pass key schedule
-#endif
-       veor            @XMM[2], @XMM[2], @XMM[10]
-       mov             r5, $rounds                     @ pass rounds
-       mov             r0, sp
-
-       bl              _bsaes_decrypt8
-
-       vld1.64         {@XMM[8]-@XMM[9]}, [r0,:128]!
-       vld1.64         {@XMM[10]}, [r0,:128]!
-       veor            @XMM[0], @XMM[0], @XMM[ 8]
-       veor            @XMM[1], @XMM[1], @XMM[ 9]
-       veor            @XMM[8], @XMM[6], @XMM[10]
-       vst1.8          {@XMM[0]-@XMM[1]}, [$out]!
-       vst1.8          {@XMM[8]}, [$out]!
-
-       vld1.64         {@XMM[8]}, [r0,:128]            @ next round tweak
-       b               .Lxts_dec_done
-.align 4
-.Lxts_dec_2:
-       vst1.64         {@XMM[10]}, [r0,:128]           @ next round tweak
-
-       veor            @XMM[0], @XMM[0], @XMM[8]
-#ifndef        BSAES_ASM_EXTENDED_KEY
-       add             r4, sp, #0x90                   @ pass key schedule
-#else
-       add             r4, $key, #248                  @ pass key schedule
-#endif
-       veor            @XMM[1], @XMM[1], @XMM[9]
-       mov             r5, $rounds                     @ pass rounds
-       mov             r0, sp
-
-       bl              _bsaes_decrypt8
-
-       vld1.64         {@XMM[8]-@XMM[9]}, [r0,:128]!
-       veor            @XMM[0], @XMM[0], @XMM[ 8]
-       veor            @XMM[1], @XMM[1], @XMM[ 9]
-       vst1.8          {@XMM[0]-@XMM[1]}, [$out]!
-
-       vld1.64         {@XMM[8]}, [r0,:128]            @ next round tweak
-       b               .Lxts_dec_done
-.align 4
-.Lxts_dec_1:
-       mov             r0, sp
-       veor            @XMM[0], @XMM[8]
-       mov             r1, sp
-       vst1.8          {@XMM[0]}, [sp,:128]
-       mov             r2, $key
-       mov             r4, $fp                         @ preserve fp
-       mov             r5, $magic                      @ preserve magic
-
-       bl              AES_decrypt
-
-       vld1.8          {@XMM[0]}, [sp,:128]
-       veor            @XMM[0], @XMM[0], @XMM[8]
-       vst1.8          {@XMM[0]}, [$out]!
-       mov             $fp, r4
-       mov             $magic, r5
-
-       vmov            @XMM[8], @XMM[9]                @ next round tweak
-
-.Lxts_dec_done:
-#ifndef        XTS_CHAIN_TWEAK
-       adds            $len, #0x10
-       beq             .Lxts_dec_ret
-
-       @ calculate one round of extra tweak for the stolen ciphertext
-       vldmia          $magic, {$twmask}
-       vshr.s64        @XMM[6], @XMM[8], #63
-       vand            @XMM[6], @XMM[6], $twmask
-       vadd.u64        @XMM[9], @XMM[8], @XMM[8]
-       vswp            `&Dhi("@XMM[6]")`,`&Dlo("@XMM[6]")`
-       veor            @XMM[9], @XMM[9], @XMM[6]
-
-       @ perform the final decryption with the last tweak value
-       vld1.8          {@XMM[0]}, [$inp]!
-       mov             r0, sp
-       veor            @XMM[0], @XMM[0], @XMM[9]
-       mov             r1, sp
-       vst1.8          {@XMM[0]}, [sp,:128]
-       mov             r2, $key
-       mov             r4, $fp                 @ preserve fp
-
-       bl              AES_decrypt
-
-       vld1.8          {@XMM[0]}, [sp,:128]
-       veor            @XMM[0], @XMM[0], @XMM[9]
-       vst1.8          {@XMM[0]}, [$out]
-
-       mov             r6, $out
-.Lxts_dec_steal:
-       ldrb            r1, [$out]
-       ldrb            r0, [$inp], #1
-       strb            r1, [$out, #0x10]
-       strb            r0, [$out], #1
-
-       subs            $len, #1
-       bhi             .Lxts_dec_steal
-
-       vld1.8          {@XMM[0]}, [r6]
-       mov             r0, sp
-       veor            @XMM[0], @XMM[8]
-       mov             r1, sp
-       vst1.8          {@XMM[0]}, [sp,:128]
-       mov             r2, $key
-
-       bl              AES_decrypt
-
-       vld1.8          {@XMM[0]}, [sp,:128]
-       veor            @XMM[0], @XMM[0], @XMM[8]
-       vst1.8          {@XMM[0]}, [r6]
-       mov             $fp, r4
-#endif
-
-.Lxts_dec_ret:
-       bic             r0, $fp, #0xf
-       vmov.i32        q0, #0
-       vmov.i32        q1, #0
-#ifdef XTS_CHAIN_TWEAK
-       ldr             r1, [$fp, #0x20+VFP_ABI_FRAME]  @ chain tweak
-#endif
-.Lxts_dec_bzero:                               @ wipe key schedule [if any]
-       vstmia          sp!, {q0-q1}
-       cmp             sp, r0
-       bne             .Lxts_dec_bzero
-
-       mov             sp, $fp
-#ifdef XTS_CHAIN_TWEAK
-       vst1.8          {@XMM[8]}, [r1]
-#endif
-       VFP_ABI_POP
-       ldmia           sp!, {r4-r10, pc}       @ return
-
-.size  bsaes_xts_decrypt,.-bsaes_xts_decrypt
-___
-}
-$code.=<<___;
-#endif
-___
-
-$code =~ s/\`([^\`]*)\`/eval($1)/gem;
-
-open SELF,$0;
-while(<SELF>) {
-       next if (/^#!/);
-        last if (!s/^#/@/ and !/^$/);
-        print;
-}
-close SELF;
-
-print $code;
-
-close STDOUT;