Home | History | Annotate | Download | only in aes
      1 
      2 @ ====================================================================
      3 @ Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
      4 @ project. The module is, however, dual licensed under OpenSSL and
      5 @ CRYPTOGAMS licenses depending on where you obtain it. For further
      6 @ details see http://www.openssl.org/~appro/cryptogams/.
      7 @
      8 @ Specific modes and adaptation for Linux kernel by Ard Biesheuvel
      9 @ <ard.biesheuvel@linaro.org>. Permission to use under GPL terms is
     10 @ granted.
     11 @ ====================================================================
     12 
     13 @ Bit-sliced AES for ARM NEON
     14 @
     15 @ February 2012.
     16 @
     17 @ This implementation is direct adaptation of bsaes-x86_64 module for
     18 @ ARM NEON. Except that this module is endian-neutral [in sense that
     19 @ it can be compiled for either endianness] by courtesy of vld1.8's
     20 @ neutrality. Initial version doesn't implement interface to OpenSSL,
     21 @ only low-level primitives and unsupported entry points, just enough
     22 @ to collect performance results, which for Cortex-A8 core are:
     23 @
     24 @ encrypt	19.5 cycles per byte processed with 128-bit key
     25 @ decrypt	22.1 cycles per byte processed with 128-bit key
     26 @ key conv.	440  cycles per 128-bit key/0.18 of 8x block
     27 @
     28 @ Snapdragon S4 encrypts byte in 17.6 cycles and decrypts in 19.7,
     29 @ which is [much] worse than anticipated (for further details see
     30 @ http://www.openssl.org/~appro/Snapdragon-S4.html).
     31 @
     32 @ Cortex-A15 manages in 14.2/16.1 cycles [when integer-only code
     33 @ manages in 20.0 cycles].
     34 @
     35 @ When comparing to x86_64 results keep in mind that NEON unit is
     36 @ [mostly] single-issue and thus can't [fully] benefit from
     37 @ instruction-level parallelism. And when comparing to aes-armv4
     38 @ results keep in mind key schedule conversion overhead (see
     39 @ bsaes-x86_64.pl for further details)...
     40 @
     41 @						<appro (at) openssl.org>
     42 
     43 @ April-August 2013
     44 @
     45 @ Add CBC, CTR and XTS subroutines, adapt for kernel use.
     46 @
     47 @					<ard.biesheuvel (at) linaro.org>
     48 
     49 #if defined(__arm__)
     50 #ifndef __KERNEL__
     51 # include "arm_arch.h"
     52 
     53 # define VFP_ABI_PUSH	vstmdb	sp!,{d8-d15}
     54 # define VFP_ABI_POP	vldmia	sp!,{d8-d15}
     55 # define VFP_ABI_FRAME	0x40
     56 #else
     57 # define VFP_ABI_PUSH
     58 # define VFP_ABI_POP
     59 # define VFP_ABI_FRAME	0
     60 # define BSAES_ASM_EXTENDED_KEY
     61 # define XTS_CHAIN_TWEAK
     62 # define __ARM_ARCH__ __LINUX_ARM_ARCH__
     63 # define __ARM_MAX_ARCH__ 7
     64 #endif
     65 
     66 #ifdef __thumb__
     67 # define adrl adr
     68 #endif
     69 
     70 #if __ARM_MAX_ARCH__>=7
     71 .arch	armv7-a
     72 .fpu	neon
     73 
     74 .text
     75 .syntax	unified 	@ ARMv7-capable assembler is expected to handle this
     76 #if defined(__thumb2__) && !defined(__APPLE__)
     77 .thumb
     78 #else
     79 .code	32
     80 #endif
     81 
     82 .type	_bsaes_decrypt8,%function
     83 .align	4
     84 _bsaes_decrypt8:
     85 	adr	r6,_bsaes_decrypt8
     86 	vldmia	r4!, {q9}		@ round 0 key
     87 #ifdef	__APPLE__
     88 	adr	r6,.LM0ISR
     89 #else
     90 	add	r6,r6,#.LM0ISR-_bsaes_decrypt8
     91 #endif
     92 
     93 	vldmia	r6!, {q8}		@ .LM0ISR
     94 	veor	q10, q0, q9	@ xor with round0 key
     95 	veor	q11, q1, q9
     96 	vtbl.8	d0, {q10}, d16
     97 	vtbl.8	d1, {q10}, d17
     98 	veor	q12, q2, q9
     99 	vtbl.8	d2, {q11}, d16
    100 	vtbl.8	d3, {q11}, d17
    101 	veor	q13, q3, q9
    102 	vtbl.8	d4, {q12}, d16
    103 	vtbl.8	d5, {q12}, d17
    104 	veor	q14, q4, q9
    105 	vtbl.8	d6, {q13}, d16
    106 	vtbl.8	d7, {q13}, d17
    107 	veor	q15, q5, q9
    108 	vtbl.8	d8, {q14}, d16
    109 	vtbl.8	d9, {q14}, d17
    110 	veor	q10, q6, q9
    111 	vtbl.8	d10, {q15}, d16
    112 	vtbl.8	d11, {q15}, d17
    113 	veor	q11, q7, q9
    114 	vtbl.8	d12, {q10}, d16
    115 	vtbl.8	d13, {q10}, d17
    116 	vtbl.8	d14, {q11}, d16
    117 	vtbl.8	d15, {q11}, d17
    118 	vmov.i8	q8,#0x55			@ compose .LBS0
    119 	vmov.i8	q9,#0x33			@ compose .LBS1
    120 	vshr.u64	q10, q6, #1
    121 	vshr.u64	q11, q4, #1
    122 	veor	q10, q10, q7
    123 	veor	q11, q11, q5
    124 	vand	q10, q10, q8
    125 	vand	q11, q11, q8
    126 	veor	q7, q7, q10
    127 	vshl.u64	q10, q10, #1
    128 	veor	q5, q5, q11
    129 	vshl.u64	q11, q11, #1
    130 	veor	q6, q6, q10
    131 	veor	q4, q4, q11
    132 	vshr.u64	q10, q2, #1
    133 	vshr.u64	q11, q0, #1
    134 	veor	q10, q10, q3
    135 	veor	q11, q11, q1
    136 	vand	q10, q10, q8
    137 	vand	q11, q11, q8
    138 	veor	q3, q3, q10
    139 	vshl.u64	q10, q10, #1
    140 	veor	q1, q1, q11
    141 	vshl.u64	q11, q11, #1
    142 	veor	q2, q2, q10
    143 	veor	q0, q0, q11
    144 	vmov.i8	q8,#0x0f			@ compose .LBS2
    145 	vshr.u64	q10, q5, #2
    146 	vshr.u64	q11, q4, #2
    147 	veor	q10, q10, q7
    148 	veor	q11, q11, q6
    149 	vand	q10, q10, q9
    150 	vand	q11, q11, q9
    151 	veor	q7, q7, q10
    152 	vshl.u64	q10, q10, #2
    153 	veor	q6, q6, q11
    154 	vshl.u64	q11, q11, #2
    155 	veor	q5, q5, q10
    156 	veor	q4, q4, q11
    157 	vshr.u64	q10, q1, #2
    158 	vshr.u64	q11, q0, #2
    159 	veor	q10, q10, q3
    160 	veor	q11, q11, q2
    161 	vand	q10, q10, q9
    162 	vand	q11, q11, q9
    163 	veor	q3, q3, q10
    164 	vshl.u64	q10, q10, #2
    165 	veor	q2, q2, q11
    166 	vshl.u64	q11, q11, #2
    167 	veor	q1, q1, q10
    168 	veor	q0, q0, q11
    169 	vshr.u64	q10, q3, #4
    170 	vshr.u64	q11, q2, #4
    171 	veor	q10, q10, q7
    172 	veor	q11, q11, q6
    173 	vand	q10, q10, q8
    174 	vand	q11, q11, q8
    175 	veor	q7, q7, q10
    176 	vshl.u64	q10, q10, #4
    177 	veor	q6, q6, q11
    178 	vshl.u64	q11, q11, #4
    179 	veor	q3, q3, q10
    180 	veor	q2, q2, q11
    181 	vshr.u64	q10, q1, #4
    182 	vshr.u64	q11, q0, #4
    183 	veor	q10, q10, q5
    184 	veor	q11, q11, q4
    185 	vand	q10, q10, q8
    186 	vand	q11, q11, q8
    187 	veor	q5, q5, q10
    188 	vshl.u64	q10, q10, #4
    189 	veor	q4, q4, q11
    190 	vshl.u64	q11, q11, #4
    191 	veor	q1, q1, q10
    192 	veor	q0, q0, q11
    193 	sub	r5,r5,#1
    194 	b	.Ldec_sbox
    195 .align	4
    196 .Ldec_loop:
    197 	vldmia	r4!, {q8,q9,q10,q11}
    198 	veor	q8, q8, q0
    199 	veor	q9, q9, q1
    200 	vtbl.8	d0, {q8}, d24
    201 	vtbl.8	d1, {q8}, d25
    202 	vldmia	r4!, {q8}
    203 	veor	q10, q10, q2
    204 	vtbl.8	d2, {q9}, d24
    205 	vtbl.8	d3, {q9}, d25
    206 	vldmia	r4!, {q9}
    207 	veor	q11, q11, q3
    208 	vtbl.8	d4, {q10}, d24
    209 	vtbl.8	d5, {q10}, d25
    210 	vldmia	r4!, {q10}
    211 	vtbl.8	d6, {q11}, d24
    212 	vtbl.8	d7, {q11}, d25
    213 	vldmia	r4!, {q11}
    214 	veor	q8, q8, q4
    215 	veor	q9, q9, q5
    216 	vtbl.8	d8, {q8}, d24
    217 	vtbl.8	d9, {q8}, d25
    218 	veor	q10, q10, q6
    219 	vtbl.8	d10, {q9}, d24
    220 	vtbl.8	d11, {q9}, d25
    221 	veor	q11, q11, q7
    222 	vtbl.8	d12, {q10}, d24
    223 	vtbl.8	d13, {q10}, d25
    224 	vtbl.8	d14, {q11}, d24
    225 	vtbl.8	d15, {q11}, d25
    226 .Ldec_sbox:
    227 	veor	q1, q1, q4
    228 	veor	q3, q3, q4
    229 
    230 	veor	q4, q4, q7
    231 	veor	q1, q1, q6
    232 	veor	q2, q2, q7
    233 	veor	q6, q6, q4
    234 
    235 	veor	q0, q0, q1
    236 	veor	q2, q2, q5
    237 	veor	q7, q7, q6
    238 	veor	q3, q3, q0
    239 	veor	q5, q5, q0
    240 	veor	q1, q1, q3
    241 	veor	q11, q3, q0
    242 	veor	q10, q7, q4
    243 	veor	q9, q1, q6
    244 	veor	q13, q4, q0
    245 	vmov	q8, q10
    246 	veor	q12, q5, q2
    247 
    248 	vorr	q10, q10, q9
    249 	veor	q15, q11, q8
    250 	vand	q14, q11, q12
    251 	vorr	q11, q11, q12
    252 	veor	q12, q12, q9
    253 	vand	q8, q8, q9
    254 	veor	q9, q6, q2
    255 	vand	q15, q15, q12
    256 	vand	q13, q13, q9
    257 	veor	q9, q3, q7
    258 	veor	q12, q1, q5
    259 	veor	q11, q11, q13
    260 	veor	q10, q10, q13
    261 	vand	q13, q9, q12
    262 	vorr	q9, q9, q12
    263 	veor	q11, q11, q15
    264 	veor	q8, q8, q13
    265 	veor	q10, q10, q14
    266 	veor	q9, q9, q15
    267 	veor	q8, q8, q14
    268 	vand	q12, q4, q6
    269 	veor	q9, q9, q14
    270 	vand	q13, q0, q2
    271 	vand	q14, q7, q1
    272 	vorr	q15, q3, q5
    273 	veor	q11, q11, q12
    274 	veor	q9, q9, q14
    275 	veor	q8, q8, q15
    276 	veor	q10, q10, q13
    277 
    278 	@ Inv_GF16 	0, 	1, 	2, 	3, s0, s1, s2, s3
    279 
    280 	@ new smaller inversion
    281 
    282 	vand	q14, q11, q9
    283 	vmov	q12, q8
    284 
    285 	veor	q13, q10, q14
    286 	veor	q15, q8, q14
    287 	veor	q14, q8, q14	@ q14=q15
    288 
    289 	vbsl	q13, q9, q8
    290 	vbsl	q15, q11, q10
    291 	veor	q11, q11, q10
    292 
    293 	vbsl	q12, q13, q14
    294 	vbsl	q8, q14, q13
    295 
    296 	vand	q14, q12, q15
    297 	veor	q9, q9, q8
    298 
    299 	veor	q14, q14, q11
    300 	veor	q12, q5, q2
    301 	veor	q8, q1, q6
    302 	veor	q10, q15, q14
    303 	vand	q10, q10, q5
    304 	veor	q5, q5, q1
    305 	vand	q11, q1, q15
    306 	vand	q5, q5, q14
    307 	veor	q1, q11, q10
    308 	veor	q5, q5, q11
    309 	veor	q15, q15, q13
    310 	veor	q14, q14, q9
    311 	veor	q11, q15, q14
    312 	veor	q10, q13, q9
    313 	vand	q11, q11, q12
    314 	vand	q10, q10, q2
    315 	veor	q12, q12, q8
    316 	veor	q2, q2, q6
    317 	vand	q8, q8, q15
    318 	vand	q6, q6, q13
    319 	vand	q12, q12, q14
    320 	vand	q2, q2, q9
    321 	veor	q8, q8, q12
    322 	veor	q2, q2, q6
    323 	veor	q12, q12, q11
    324 	veor	q6, q6, q10
    325 	veor	q5, q5, q12
    326 	veor	q2, q2, q12
    327 	veor	q1, q1, q8
    328 	veor	q6, q6, q8
    329 
    330 	veor	q12, q3, q0
    331 	veor	q8, q7, q4
    332 	veor	q11, q15, q14
    333 	veor	q10, q13, q9
    334 	vand	q11, q11, q12
    335 	vand	q10, q10, q0
    336 	veor	q12, q12, q8
    337 	veor	q0, q0, q4
    338 	vand	q8, q8, q15
    339 	vand	q4, q4, q13
    340 	vand	q12, q12, q14
    341 	vand	q0, q0, q9
    342 	veor	q8, q8, q12
    343 	veor	q0, q0, q4
    344 	veor	q12, q12, q11
    345 	veor	q4, q4, q10
    346 	veor	q15, q15, q13
    347 	veor	q14, q14, q9
    348 	veor	q10, q15, q14
    349 	vand	q10, q10, q3
    350 	veor	q3, q3, q7
    351 	vand	q11, q7, q15
    352 	vand	q3, q3, q14
    353 	veor	q7, q11, q10
    354 	veor	q3, q3, q11
    355 	veor	q3, q3, q12
    356 	veor	q0, q0, q12
    357 	veor	q7, q7, q8
    358 	veor	q4, q4, q8
    359 	veor	q1, q1, q7
    360 	veor	q6, q6, q5
    361 
    362 	veor	q4, q4, q1
    363 	veor	q2, q2, q7
    364 	veor	q5, q5, q7
    365 	veor	q4, q4, q2
    366 	veor	q7, q7, q0
    367 	veor	q4, q4, q5
    368 	veor	q3, q3, q6
    369 	veor	q6, q6, q1
    370 	veor	q3, q3, q4
    371 
    372 	veor	q4, q4, q0
    373 	veor	q7, q7, q3
    374 	subs	r5,r5,#1
    375 	bcc	.Ldec_done
    376 	@ multiplication by 0x05-0x00-0x04-0x00
    377 	vext.8	q8, q0, q0, #8
    378 	vext.8	q14, q3, q3, #8
    379 	vext.8	q15, q5, q5, #8
    380 	veor	q8, q8, q0
    381 	vext.8	q9, q1, q1, #8
    382 	veor	q14, q14, q3
    383 	vext.8	q10, q6, q6, #8
    384 	veor	q15, q15, q5
    385 	vext.8	q11, q4, q4, #8
    386 	veor	q9, q9, q1
    387 	vext.8	q12, q2, q2, #8
    388 	veor	q10, q10, q6
    389 	vext.8	q13, q7, q7, #8
    390 	veor	q11, q11, q4
    391 	veor	q12, q12, q2
    392 	veor	q13, q13, q7
    393 
    394 	veor	q0, q0, q14
    395 	veor	q1, q1, q14
    396 	veor	q6, q6, q8
    397 	veor	q2, q2, q10
    398 	veor	q4, q4, q9
    399 	veor	q1, q1, q15
    400 	veor	q6, q6, q15
    401 	veor	q2, q2, q14
    402 	veor	q7, q7, q11
    403 	veor	q4, q4, q14
    404 	veor	q3, q3, q12
    405 	veor	q2, q2, q15
    406 	veor	q7, q7, q15
    407 	veor	q5, q5, q13
    408 	vext.8	q8, q0, q0, #12	@ x0 <<< 32
    409 	vext.8	q9, q1, q1, #12
    410 	veor	q0, q0, q8		@ x0 ^ (x0 <<< 32)
    411 	vext.8	q10, q6, q6, #12
    412 	veor	q1, q1, q9
    413 	vext.8	q11, q4, q4, #12
    414 	veor	q6, q6, q10
    415 	vext.8	q12, q2, q2, #12
    416 	veor	q4, q4, q11
    417 	vext.8	q13, q7, q7, #12
    418 	veor	q2, q2, q12
    419 	vext.8	q14, q3, q3, #12
    420 	veor	q7, q7, q13
    421 	vext.8	q15, q5, q5, #12
    422 	veor	q3, q3, q14
    423 
    424 	veor	q9, q9, q0
    425 	veor	q5, q5, q15
    426 	vext.8	q0, q0, q0, #8		@ (x0 ^ (x0 <<< 32)) <<< 64)
    427 	veor	q10, q10, q1
    428 	veor	q8, q8, q5
    429 	veor	q9, q9, q5
    430 	vext.8	q1, q1, q1, #8
    431 	veor	q13, q13, q2
    432 	veor	q0, q0, q8
    433 	veor	q14, q14, q7
    434 	veor	q1, q1, q9
    435 	vext.8	q8, q2, q2, #8
    436 	veor	q12, q12, q4
    437 	vext.8	q9, q7, q7, #8
    438 	veor	q15, q15, q3
    439 	vext.8	q2, q4, q4, #8
    440 	veor	q11, q11, q6
    441 	vext.8	q7, q5, q5, #8
    442 	veor	q12, q12, q5
    443 	vext.8	q4, q3, q3, #8
    444 	veor	q11, q11, q5
    445 	vext.8	q3, q6, q6, #8
    446 	veor	q5, q9, q13
    447 	veor	q11, q11, q2
    448 	veor	q7, q7, q15
    449 	veor	q6, q4, q14
    450 	veor	q4, q8, q12
    451 	veor	q2, q3, q10
    452 	vmov	q3, q11
    453 	 @ vmov	q5, q9
    454 	vldmia	r6, {q12}		@ .LISR
    455 	ite	eq				@ Thumb2 thing, sanity check in ARM
    456 	addeq	r6,r6,#0x10
    457 	bne	.Ldec_loop
    458 	vldmia	r6, {q12}		@ .LISRM0
    459 	b	.Ldec_loop
    460 .align	4
    461 .Ldec_done:
    462 	vmov.i8	q8,#0x55			@ compose .LBS0
    463 	vmov.i8	q9,#0x33			@ compose .LBS1
    464 	vshr.u64	q10, q3, #1
    465 	vshr.u64	q11, q2, #1
    466 	veor	q10, q10, q5
    467 	veor	q11, q11, q7
    468 	vand	q10, q10, q8
    469 	vand	q11, q11, q8
    470 	veor	q5, q5, q10
    471 	vshl.u64	q10, q10, #1
    472 	veor	q7, q7, q11
    473 	vshl.u64	q11, q11, #1
    474 	veor	q3, q3, q10
    475 	veor	q2, q2, q11
    476 	vshr.u64	q10, q6, #1
    477 	vshr.u64	q11, q0, #1
    478 	veor	q10, q10, q4
    479 	veor	q11, q11, q1
    480 	vand	q10, q10, q8
    481 	vand	q11, q11, q8
    482 	veor	q4, q4, q10
    483 	vshl.u64	q10, q10, #1
    484 	veor	q1, q1, q11
    485 	vshl.u64	q11, q11, #1
    486 	veor	q6, q6, q10
    487 	veor	q0, q0, q11
    488 	vmov.i8	q8,#0x0f			@ compose .LBS2
    489 	vshr.u64	q10, q7, #2
    490 	vshr.u64	q11, q2, #2
    491 	veor	q10, q10, q5
    492 	veor	q11, q11, q3
    493 	vand	q10, q10, q9
    494 	vand	q11, q11, q9
    495 	veor	q5, q5, q10
    496 	vshl.u64	q10, q10, #2
    497 	veor	q3, q3, q11
    498 	vshl.u64	q11, q11, #2
    499 	veor	q7, q7, q10
    500 	veor	q2, q2, q11
    501 	vshr.u64	q10, q1, #2
    502 	vshr.u64	q11, q0, #2
    503 	veor	q10, q10, q4
    504 	veor	q11, q11, q6
    505 	vand	q10, q10, q9
    506 	vand	q11, q11, q9
    507 	veor	q4, q4, q10
    508 	vshl.u64	q10, q10, #2
    509 	veor	q6, q6, q11
    510 	vshl.u64	q11, q11, #2
    511 	veor	q1, q1, q10
    512 	veor	q0, q0, q11
    513 	vshr.u64	q10, q4, #4
    514 	vshr.u64	q11, q6, #4
    515 	veor	q10, q10, q5
    516 	veor	q11, q11, q3
    517 	vand	q10, q10, q8
    518 	vand	q11, q11, q8
    519 	veor	q5, q5, q10
    520 	vshl.u64	q10, q10, #4
    521 	veor	q3, q3, q11
    522 	vshl.u64	q11, q11, #4
    523 	veor	q4, q4, q10
    524 	veor	q6, q6, q11
    525 	vshr.u64	q10, q1, #4
    526 	vshr.u64	q11, q0, #4
    527 	veor	q10, q10, q7
    528 	veor	q11, q11, q2
    529 	vand	q10, q10, q8
    530 	vand	q11, q11, q8
    531 	veor	q7, q7, q10
    532 	vshl.u64	q10, q10, #4
    533 	veor	q2, q2, q11
    534 	vshl.u64	q11, q11, #4
    535 	veor	q1, q1, q10
    536 	veor	q0, q0, q11
    537 	vldmia	r4, {q8}			@ last round key
    538 	veor	q6, q6, q8
    539 	veor	q4, q4, q8
    540 	veor	q2, q2, q8
    541 	veor	q7, q7, q8
    542 	veor	q3, q3, q8
    543 	veor	q5, q5, q8
    544 	veor	q0, q0, q8
    545 	veor	q1, q1, q8
    546 	bx	lr
    547 .size	_bsaes_decrypt8,.-_bsaes_decrypt8
    548 
    549 .type	_bsaes_const,%object
    550 .align	6
    551 _bsaes_const:
    552 .LM0ISR:@ InvShiftRows constants
    553 .quad	0x0a0e0206070b0f03, 0x0004080c0d010509
    554 .LISR:
    555 .quad	0x0504070602010003, 0x0f0e0d0c080b0a09
    556 .LISRM0:
    557 .quad	0x01040b0e0205080f, 0x0306090c00070a0d
    558 .LM0SR:@ ShiftRows constants
    559 .quad	0x0a0e02060f03070b, 0x0004080c05090d01
    560 .LSR:
    561 .quad	0x0504070600030201, 0x0f0e0d0c0a09080b
    562 .LSRM0:
    563 .quad	0x0304090e00050a0f, 0x01060b0c0207080d
    564 .LM0:
    565 .quad	0x02060a0e03070b0f, 0x0004080c0105090d
    566 .LREVM0SR:
    567 .quad	0x090d01050c000408, 0x03070b0f060a0e02
    568 .byte	66,105,116,45,115,108,105,99,101,100,32,65,69,83,32,102,111,114,32,78,69,79,78,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
    569 .align	2
    570 .align	6
    571 .size	_bsaes_const,.-_bsaes_const
    572 
    573 .type	_bsaes_encrypt8,%function
    574 .align	4
    575 _bsaes_encrypt8:
    576 	adr	r6,_bsaes_encrypt8
    577 	vldmia	r4!, {q9}		@ round 0 key
    578 #ifdef	__APPLE__
    579 	adr	r6,.LM0SR
    580 #else
    581 	sub	r6,r6,#_bsaes_encrypt8-.LM0SR
    582 #endif
    583 
    584 	vldmia	r6!, {q8}		@ .LM0SR
    585 _bsaes_encrypt8_alt:
    586 	veor	q10, q0, q9	@ xor with round0 key
    587 	veor	q11, q1, q9
    588 	vtbl.8	d0, {q10}, d16
    589 	vtbl.8	d1, {q10}, d17
    590 	veor	q12, q2, q9
    591 	vtbl.8	d2, {q11}, d16
    592 	vtbl.8	d3, {q11}, d17
    593 	veor	q13, q3, q9
    594 	vtbl.8	d4, {q12}, d16
    595 	vtbl.8	d5, {q12}, d17
    596 	veor	q14, q4, q9
    597 	vtbl.8	d6, {q13}, d16
    598 	vtbl.8	d7, {q13}, d17
    599 	veor	q15, q5, q9
    600 	vtbl.8	d8, {q14}, d16
    601 	vtbl.8	d9, {q14}, d17
    602 	veor	q10, q6, q9
    603 	vtbl.8	d10, {q15}, d16
    604 	vtbl.8	d11, {q15}, d17
    605 	veor	q11, q7, q9
    606 	vtbl.8	d12, {q10}, d16
    607 	vtbl.8	d13, {q10}, d17
    608 	vtbl.8	d14, {q11}, d16
    609 	vtbl.8	d15, {q11}, d17
    610 _bsaes_encrypt8_bitslice:
    611 	vmov.i8	q8,#0x55			@ compose .LBS0
    612 	vmov.i8	q9,#0x33			@ compose .LBS1
    613 	vshr.u64	q10, q6, #1
    614 	vshr.u64	q11, q4, #1
    615 	veor	q10, q10, q7
    616 	veor	q11, q11, q5
    617 	vand	q10, q10, q8
    618 	vand	q11, q11, q8
    619 	veor	q7, q7, q10
    620 	vshl.u64	q10, q10, #1
    621 	veor	q5, q5, q11
    622 	vshl.u64	q11, q11, #1
    623 	veor	q6, q6, q10
    624 	veor	q4, q4, q11
    625 	vshr.u64	q10, q2, #1
    626 	vshr.u64	q11, q0, #1
    627 	veor	q10, q10, q3
    628 	veor	q11, q11, q1
    629 	vand	q10, q10, q8
    630 	vand	q11, q11, q8
    631 	veor	q3, q3, q10
    632 	vshl.u64	q10, q10, #1
    633 	veor	q1, q1, q11
    634 	vshl.u64	q11, q11, #1
    635 	veor	q2, q2, q10
    636 	veor	q0, q0, q11
    637 	vmov.i8	q8,#0x0f			@ compose .LBS2
    638 	vshr.u64	q10, q5, #2
    639 	vshr.u64	q11, q4, #2
    640 	veor	q10, q10, q7
    641 	veor	q11, q11, q6
    642 	vand	q10, q10, q9
    643 	vand	q11, q11, q9
    644 	veor	q7, q7, q10
    645 	vshl.u64	q10, q10, #2
    646 	veor	q6, q6, q11
    647 	vshl.u64	q11, q11, #2
    648 	veor	q5, q5, q10
    649 	veor	q4, q4, q11
    650 	vshr.u64	q10, q1, #2
    651 	vshr.u64	q11, q0, #2
    652 	veor	q10, q10, q3
    653 	veor	q11, q11, q2
    654 	vand	q10, q10, q9
    655 	vand	q11, q11, q9
    656 	veor	q3, q3, q10
    657 	vshl.u64	q10, q10, #2
    658 	veor	q2, q2, q11
    659 	vshl.u64	q11, q11, #2
    660 	veor	q1, q1, q10
    661 	veor	q0, q0, q11
    662 	vshr.u64	q10, q3, #4
    663 	vshr.u64	q11, q2, #4
    664 	veor	q10, q10, q7
    665 	veor	q11, q11, q6
    666 	vand	q10, q10, q8
    667 	vand	q11, q11, q8
    668 	veor	q7, q7, q10
    669 	vshl.u64	q10, q10, #4
    670 	veor	q6, q6, q11
    671 	vshl.u64	q11, q11, #4
    672 	veor	q3, q3, q10
    673 	veor	q2, q2, q11
    674 	vshr.u64	q10, q1, #4
    675 	vshr.u64	q11, q0, #4
    676 	veor	q10, q10, q5
    677 	veor	q11, q11, q4
    678 	vand	q10, q10, q8
    679 	vand	q11, q11, q8
    680 	veor	q5, q5, q10
    681 	vshl.u64	q10, q10, #4
    682 	veor	q4, q4, q11
    683 	vshl.u64	q11, q11, #4
    684 	veor	q1, q1, q10
    685 	veor	q0, q0, q11
    686 	sub	r5,r5,#1
    687 	b	.Lenc_sbox
    688 .align	4
    689 .Lenc_loop:
    690 	vldmia	r4!, {q8,q9,q10,q11}
    691 	veor	q8, q8, q0
    692 	veor	q9, q9, q1
    693 	vtbl.8	d0, {q8}, d24
    694 	vtbl.8	d1, {q8}, d25
    695 	vldmia	r4!, {q8}
    696 	veor	q10, q10, q2
    697 	vtbl.8	d2, {q9}, d24
    698 	vtbl.8	d3, {q9}, d25
    699 	vldmia	r4!, {q9}
    700 	veor	q11, q11, q3
    701 	vtbl.8	d4, {q10}, d24
    702 	vtbl.8	d5, {q10}, d25
    703 	vldmia	r4!, {q10}
    704 	vtbl.8	d6, {q11}, d24
    705 	vtbl.8	d7, {q11}, d25
    706 	vldmia	r4!, {q11}
    707 	veor	q8, q8, q4
    708 	veor	q9, q9, q5
    709 	vtbl.8	d8, {q8}, d24
    710 	vtbl.8	d9, {q8}, d25
    711 	veor	q10, q10, q6
    712 	vtbl.8	d10, {q9}, d24
    713 	vtbl.8	d11, {q9}, d25
    714 	veor	q11, q11, q7
    715 	vtbl.8	d12, {q10}, d24
    716 	vtbl.8	d13, {q10}, d25
    717 	vtbl.8	d14, {q11}, d24
    718 	vtbl.8	d15, {q11}, d25
    719 .Lenc_sbox:
    720 	veor	q2, q2, q1
    721 	veor	q5, q5, q6
    722 	veor	q3, q3, q0
    723 	veor	q6, q6, q2
    724 	veor	q5, q5, q0
    725 
    726 	veor	q6, q6, q3
    727 	veor	q3, q3, q7
    728 	veor	q7, q7, q5
    729 	veor	q3, q3, q4
    730 	veor	q4, q4, q5
    731 
    732 	veor	q2, q2, q7
    733 	veor	q3, q3, q1
    734 	veor	q1, q1, q5
    735 	veor	q11, q7, q4
    736 	veor	q10, q1, q2
    737 	veor	q9, q5, q3
    738 	veor	q13, q2, q4
    739 	vmov	q8, q10
    740 	veor	q12, q6, q0
    741 
    742 	vorr	q10, q10, q9
    743 	veor	q15, q11, q8
    744 	vand	q14, q11, q12
    745 	vorr	q11, q11, q12
    746 	veor	q12, q12, q9
    747 	vand	q8, q8, q9
    748 	veor	q9, q3, q0
    749 	vand	q15, q15, q12
    750 	vand	q13, q13, q9
    751 	veor	q9, q7, q1
    752 	veor	q12, q5, q6
    753 	veor	q11, q11, q13
    754 	veor	q10, q10, q13
    755 	vand	q13, q9, q12
    756 	vorr	q9, q9, q12
    757 	veor	q11, q11, q15
    758 	veor	q8, q8, q13
    759 	veor	q10, q10, q14
    760 	veor	q9, q9, q15
    761 	veor	q8, q8, q14
    762 	vand	q12, q2, q3
    763 	veor	q9, q9, q14
    764 	vand	q13, q4, q0
    765 	vand	q14, q1, q5
    766 	vorr	q15, q7, q6
    767 	veor	q11, q11, q12
    768 	veor	q9, q9, q14
    769 	veor	q8, q8, q15
    770 	veor	q10, q10, q13
    771 
    772 	@ Inv_GF16 	0, 	1, 	2, 	3, s0, s1, s2, s3
    773 
    774 	@ new smaller inversion
    775 
    776 	vand	q14, q11, q9
    777 	vmov	q12, q8
    778 
    779 	veor	q13, q10, q14
    780 	veor	q15, q8, q14
    781 	veor	q14, q8, q14	@ q14=q15
    782 
    783 	vbsl	q13, q9, q8
    784 	vbsl	q15, q11, q10
    785 	veor	q11, q11, q10
    786 
    787 	vbsl	q12, q13, q14
    788 	vbsl	q8, q14, q13
    789 
    790 	vand	q14, q12, q15
    791 	veor	q9, q9, q8
    792 
    793 	veor	q14, q14, q11
    794 	veor	q12, q6, q0
    795 	veor	q8, q5, q3
    796 	veor	q10, q15, q14
    797 	vand	q10, q10, q6
    798 	veor	q6, q6, q5
    799 	vand	q11, q5, q15
    800 	vand	q6, q6, q14
    801 	veor	q5, q11, q10
    802 	veor	q6, q6, q11
    803 	veor	q15, q15, q13
    804 	veor	q14, q14, q9
    805 	veor	q11, q15, q14
    806 	veor	q10, q13, q9
    807 	vand	q11, q11, q12
    808 	vand	q10, q10, q0
    809 	veor	q12, q12, q8
    810 	veor	q0, q0, q3
    811 	vand	q8, q8, q15
    812 	vand	q3, q3, q13
    813 	vand	q12, q12, q14
    814 	vand	q0, q0, q9
    815 	veor	q8, q8, q12
    816 	veor	q0, q0, q3
    817 	veor	q12, q12, q11
    818 	veor	q3, q3, q10
    819 	veor	q6, q6, q12
    820 	veor	q0, q0, q12
    821 	veor	q5, q5, q8
    822 	veor	q3, q3, q8
    823 
    824 	veor	q12, q7, q4
    825 	veor	q8, q1, q2
    826 	veor	q11, q15, q14
    827 	veor	q10, q13, q9
    828 	vand	q11, q11, q12
    829 	vand	q10, q10, q4
    830 	veor	q12, q12, q8
    831 	veor	q4, q4, q2
    832 	vand	q8, q8, q15
    833 	vand	q2, q2, q13
    834 	vand	q12, q12, q14
    835 	vand	q4, q4, q9
    836 	veor	q8, q8, q12
    837 	veor	q4, q4, q2
    838 	veor	q12, q12, q11
    839 	veor	q2, q2, q10
    840 	veor	q15, q15, q13
    841 	veor	q14, q14, q9
    842 	veor	q10, q15, q14
    843 	vand	q10, q10, q7
    844 	veor	q7, q7, q1
    845 	vand	q11, q1, q15
    846 	vand	q7, q7, q14
    847 	veor	q1, q11, q10
    848 	veor	q7, q7, q11
    849 	veor	q7, q7, q12
    850 	veor	q4, q4, q12
    851 	veor	q1, q1, q8
    852 	veor	q2, q2, q8
    853 	veor	q7, q7, q0
    854 	veor	q1, q1, q6
    855 	veor	q6, q6, q0
    856 	veor	q4, q4, q7
    857 	veor	q0, q0, q1
    858 
    859 	veor	q1, q1, q5
    860 	veor	q5, q5, q2
    861 	veor	q2, q2, q3
    862 	veor	q3, q3, q5
    863 	veor	q4, q4, q5
    864 
    865 	veor	q6, q6, q3
    866 	subs	r5,r5,#1
    867 	bcc	.Lenc_done
    868 	vext.8	q8, q0, q0, #12	@ x0 <<< 32
    869 	vext.8	q9, q1, q1, #12
    870 	veor	q0, q0, q8		@ x0 ^ (x0 <<< 32)
    871 	vext.8	q10, q4, q4, #12
    872 	veor	q1, q1, q9
    873 	vext.8	q11, q6, q6, #12
    874 	veor	q4, q4, q10
    875 	vext.8	q12, q3, q3, #12
    876 	veor	q6, q6, q11
    877 	vext.8	q13, q7, q7, #12
    878 	veor	q3, q3, q12
    879 	vext.8	q14, q2, q2, #12
    880 	veor	q7, q7, q13
    881 	vext.8	q15, q5, q5, #12
    882 	veor	q2, q2, q14
    883 
    884 	veor	q9, q9, q0
    885 	veor	q5, q5, q15
    886 	vext.8	q0, q0, q0, #8		@ (x0 ^ (x0 <<< 32)) <<< 64)
    887 	veor	q10, q10, q1
    888 	veor	q8, q8, q5
    889 	veor	q9, q9, q5
    890 	vext.8	q1, q1, q1, #8
    891 	veor	q13, q13, q3
    892 	veor	q0, q0, q8
    893 	veor	q14, q14, q7
    894 	veor	q1, q1, q9
    895 	vext.8	q8, q3, q3, #8
    896 	veor	q12, q12, q6
    897 	vext.8	q9, q7, q7, #8
    898 	veor	q15, q15, q2
    899 	vext.8	q3, q6, q6, #8
    900 	veor	q11, q11, q4
    901 	vext.8	q7, q5, q5, #8
    902 	veor	q12, q12, q5
    903 	vext.8	q6, q2, q2, #8
    904 	veor	q11, q11, q5
    905 	vext.8	q2, q4, q4, #8
    906 	veor	q5, q9, q13
    907 	veor	q4, q8, q12
    908 	veor	q3, q3, q11
    909 	veor	q7, q7, q15
    910 	veor	q6, q6, q14
    911 	 @ vmov	q4, q8
    912 	veor	q2, q2, q10
    913 	 @ vmov	q5, q9
    914 	vldmia	r6, {q12}		@ .LSR
    915 	ite	eq				@ Thumb2 thing, samity check in ARM
    916 	addeq	r6,r6,#0x10
    917 	bne	.Lenc_loop
    918 	vldmia	r6, {q12}		@ .LSRM0
    919 	b	.Lenc_loop
    920 .align	4
    921 .Lenc_done:
    922 	vmov.i8	q8,#0x55			@ compose .LBS0
    923 	vmov.i8	q9,#0x33			@ compose .LBS1
    924 	vshr.u64	q10, q2, #1
    925 	vshr.u64	q11, q3, #1
    926 	veor	q10, q10, q5
    927 	veor	q11, q11, q7
    928 	vand	q10, q10, q8
    929 	vand	q11, q11, q8
    930 	veor	q5, q5, q10
    931 	vshl.u64	q10, q10, #1
    932 	veor	q7, q7, q11
    933 	vshl.u64	q11, q11, #1
    934 	veor	q2, q2, q10
    935 	veor	q3, q3, q11
    936 	vshr.u64	q10, q4, #1
    937 	vshr.u64	q11, q0, #1
    938 	veor	q10, q10, q6
    939 	veor	q11, q11, q1
    940 	vand	q10, q10, q8
    941 	vand	q11, q11, q8
    942 	veor	q6, q6, q10
    943 	vshl.u64	q10, q10, #1
    944 	veor	q1, q1, q11
    945 	vshl.u64	q11, q11, #1
    946 	veor	q4, q4, q10
    947 	veor	q0, q0, q11
    948 	vmov.i8	q8,#0x0f			@ compose .LBS2
    949 	vshr.u64	q10, q7, #2
    950 	vshr.u64	q11, q3, #2
    951 	veor	q10, q10, q5
    952 	veor	q11, q11, q2
    953 	vand	q10, q10, q9
    954 	vand	q11, q11, q9
    955 	veor	q5, q5, q10
    956 	vshl.u64	q10, q10, #2
    957 	veor	q2, q2, q11
    958 	vshl.u64	q11, q11, #2
    959 	veor	q7, q7, q10
    960 	veor	q3, q3, q11
    961 	vshr.u64	q10, q1, #2
    962 	vshr.u64	q11, q0, #2
    963 	veor	q10, q10, q6
    964 	veor	q11, q11, q4
    965 	vand	q10, q10, q9
    966 	vand	q11, q11, q9
    967 	veor	q6, q6, q10
    968 	vshl.u64	q10, q10, #2
    969 	veor	q4, q4, q11
    970 	vshl.u64	q11, q11, #2
    971 	veor	q1, q1, q10
    972 	veor	q0, q0, q11
    973 	vshr.u64	q10, q6, #4
    974 	vshr.u64	q11, q4, #4
    975 	veor	q10, q10, q5
    976 	veor	q11, q11, q2
    977 	vand	q10, q10, q8
    978 	vand	q11, q11, q8
    979 	veor	q5, q5, q10
    980 	vshl.u64	q10, q10, #4
    981 	veor	q2, q2, q11
    982 	vshl.u64	q11, q11, #4
    983 	veor	q6, q6, q10
    984 	veor	q4, q4, q11
    985 	vshr.u64	q10, q1, #4
    986 	vshr.u64	q11, q0, #4
    987 	veor	q10, q10, q7
    988 	veor	q11, q11, q3
    989 	vand	q10, q10, q8
    990 	vand	q11, q11, q8
    991 	veor	q7, q7, q10
    992 	vshl.u64	q10, q10, #4
    993 	veor	q3, q3, q11
    994 	vshl.u64	q11, q11, #4
    995 	veor	q1, q1, q10
    996 	veor	q0, q0, q11
    997 	vldmia	r4, {q8}			@ last round key
    998 	veor	q4, q4, q8
    999 	veor	q6, q6, q8
   1000 	veor	q3, q3, q8
   1001 	veor	q7, q7, q8
   1002 	veor	q2, q2, q8
   1003 	veor	q5, q5, q8
   1004 	veor	q0, q0, q8
   1005 	veor	q1, q1, q8
   1006 	bx	lr
   1007 .size	_bsaes_encrypt8,.-_bsaes_encrypt8
   1008 .type	_bsaes_key_convert,%function
   1009 .align	4
   1010 _bsaes_key_convert:
   1011 	adr	r6,_bsaes_key_convert
   1012 	vld1.8	{q7},  [r4]!		@ load round 0 key
   1013 #ifdef	__APPLE__
   1014 	adr	r6,.LM0
   1015 #else
   1016 	sub	r6,r6,#_bsaes_key_convert-.LM0
   1017 #endif
   1018 	vld1.8	{q15}, [r4]!		@ load round 1 key
   1019 
   1020 	vmov.i8	q8,  #0x01			@ bit masks
   1021 	vmov.i8	q9,  #0x02
   1022 	vmov.i8	q10, #0x04
   1023 	vmov.i8	q11, #0x08
   1024 	vmov.i8	q12, #0x10
   1025 	vmov.i8	q13, #0x20
   1026 	vldmia	r6, {q14}		@ .LM0
   1027 
   1028 #ifdef __ARMEL__
   1029 	vrev32.8	q7,  q7
   1030 	vrev32.8	q15, q15
   1031 #endif
   1032 	sub	r5,r5,#1
   1033 	vstmia	r12!, {q7}		@ save round 0 key
   1034 	b	.Lkey_loop
   1035 
   1036 .align	4
   1037 .Lkey_loop:
   1038 	vtbl.8	d14,{q15},d28
   1039 	vtbl.8	d15,{q15},d29
   1040 	vmov.i8	q6,  #0x40
   1041 	vmov.i8	q15, #0x80
   1042 
   1043 	vtst.8	q0, q7, q8
   1044 	vtst.8	q1, q7, q9
   1045 	vtst.8	q2, q7, q10
   1046 	vtst.8	q3, q7, q11
   1047 	vtst.8	q4, q7, q12
   1048 	vtst.8	q5, q7, q13
   1049 	vtst.8	q6, q7, q6
   1050 	vtst.8	q7, q7, q15
   1051 	vld1.8	{q15}, [r4]!		@ load next round key
   1052 	vmvn	q0, q0		@ "pnot"
   1053 	vmvn	q1, q1
   1054 	vmvn	q5, q5
   1055 	vmvn	q6, q6
   1056 #ifdef __ARMEL__
   1057 	vrev32.8	q15, q15
   1058 #endif
   1059 	subs	r5,r5,#1
   1060 	vstmia	r12!,{q0,q1,q2,q3,q4,q5,q6,q7}		@ write bit-sliced round key
   1061 	bne	.Lkey_loop
   1062 
   1063 	vmov.i8	q7,#0x63			@ compose .L63
   1064 	@ don't save last round key
   1065 	bx	lr
   1066 .size	_bsaes_key_convert,.-_bsaes_key_convert
   1067 
   1068 
   1069 
   1070 .globl	bsaes_cbc_encrypt
   1071 .hidden	bsaes_cbc_encrypt
   1072 .type	bsaes_cbc_encrypt,%function
   1073 .align	5
   1074 bsaes_cbc_encrypt:
   1075 #ifndef	__KERNEL__
   1076 	cmp	r2, #128
   1077 #ifndef	__thumb__
   1078 	blo	AES_cbc_encrypt
   1079 #else
   1080 	bhs	1f
   1081 	b	AES_cbc_encrypt
   1082 1:
   1083 #endif
   1084 #endif
   1085 
   1086 	@ it is up to the caller to make sure we are called with enc == 0
   1087 
   1088 	mov	ip, sp
   1089 	stmdb	sp!, {r4,r5,r6,r7,r8,r9,r10, lr}
   1090 	VFP_ABI_PUSH
   1091 	ldr	r8, [ip]			@ IV is 1st arg on the stack
   1092 	mov	r2, r2, lsr#4		@ len in 16 byte blocks
   1093 	sub	sp, #0x10			@ scratch space to carry over the IV
   1094 	mov	r9, sp				@ save sp
   1095 
   1096 	ldr	r10, [r3, #240]		@ get # of rounds
   1097 #ifndef	BSAES_ASM_EXTENDED_KEY
   1098 	@ allocate the key schedule on the stack
   1099 	sub	r12, sp, r10, lsl#7		@ 128 bytes per inner round key
   1100 	add	r12, #96			@ sifze of bit-slices key schedule
   1101 
   1102 	@ populate the key schedule
   1103 	mov	r4, r3			@ pass key
   1104 	mov	r5, r10			@ pass # of rounds
   1105 	mov	sp, r12				@ sp is sp
   1106 	bl	_bsaes_key_convert
   1107 	vldmia	sp, {q6}
   1108 	vstmia	r12,  {q15}		@ save last round key
   1109 	veor	q7, q7, q6	@ fix up round 0 key
   1110 	vstmia	sp, {q7}
   1111 #else
   1112 	ldr	r12, [r3, #244]
   1113 	eors	r12, #1
   1114 	beq	0f
   1115 
   1116 	@ populate the key schedule
   1117 	str	r12, [r3, #244]
   1118 	mov	r4, r3			@ pass key
   1119 	mov	r5, r10			@ pass # of rounds
   1120 	add	r12, r3, #248			@ pass key schedule
   1121 	bl	_bsaes_key_convert
   1122 	add	r4, r3, #248
   1123 	vldmia	r4, {q6}
   1124 	vstmia	r12, {q15}			@ save last round key
   1125 	veor	q7, q7, q6	@ fix up round 0 key
   1126 	vstmia	r4, {q7}
   1127 
   1128 .align	2
   1129 
   1130 #endif
   1131 
   1132 	vld1.8	{q15}, [r8]		@ load IV
   1133 	b	.Lcbc_dec_loop
   1134 
   1135 .align	4
   1136 .Lcbc_dec_loop:
   1137 	subs	r2, r2, #0x8
   1138 	bmi	.Lcbc_dec_loop_finish
   1139 
   1140 	vld1.8	{q0,q1}, [r0]!	@ load input
   1141 	vld1.8	{q2,q3}, [r0]!
   1142 #ifndef	BSAES_ASM_EXTENDED_KEY
   1143 	mov	r4, sp			@ pass the key
   1144 #else
   1145 	add	r4, r3, #248
   1146 #endif
   1147 	vld1.8	{q4,q5}, [r0]!
   1148 	mov	r5, r10
   1149 	vld1.8	{q6,q7}, [r0]
   1150 	sub	r0, r0, #0x60
   1151 	vstmia	r9, {q15}			@ put aside IV
   1152 
   1153 	bl	_bsaes_decrypt8
   1154 
   1155 	vldmia	r9, {q14}			@ reload IV
   1156 	vld1.8	{q8,q9}, [r0]!	@ reload input
   1157 	veor	q0, q0, q14	@ ^= IV
   1158 	vld1.8	{q10,q11}, [r0]!
   1159 	veor	q1, q1, q8
   1160 	veor	q6, q6, q9
   1161 	vld1.8	{q12,q13}, [r0]!
   1162 	veor	q4, q4, q10
   1163 	veor	q2, q2, q11
   1164 	vld1.8	{q14,q15}, [r0]!
   1165 	veor	q7, q7, q12
   1166 	vst1.8	{q0,q1}, [r1]!	@ write output
   1167 	veor	q3, q3, q13
   1168 	vst1.8	{q6}, [r1]!
   1169 	veor	q5, q5, q14
   1170 	vst1.8	{q4}, [r1]!
   1171 	vst1.8	{q2}, [r1]!
   1172 	vst1.8	{q7}, [r1]!
   1173 	vst1.8	{q3}, [r1]!
   1174 	vst1.8	{q5}, [r1]!
   1175 
   1176 	b	.Lcbc_dec_loop
   1177 
   1178 .Lcbc_dec_loop_finish:
   1179 	adds	r2, r2, #8
   1180 	beq	.Lcbc_dec_done
   1181 
   1182 	vld1.8	{q0}, [r0]!		@ load input
   1183 	cmp	r2, #2
   1184 	blo	.Lcbc_dec_one
   1185 	vld1.8	{q1}, [r0]!
   1186 #ifndef	BSAES_ASM_EXTENDED_KEY
   1187 	mov	r4, sp			@ pass the key
   1188 #else
   1189 	add	r4, r3, #248
   1190 #endif
   1191 	mov	r5, r10
   1192 	vstmia	r9, {q15}			@ put aside IV
   1193 	beq	.Lcbc_dec_two
   1194 	vld1.8	{q2}, [r0]!
   1195 	cmp	r2, #4
   1196 	blo	.Lcbc_dec_three
   1197 	vld1.8	{q3}, [r0]!
   1198 	beq	.Lcbc_dec_four
   1199 	vld1.8	{q4}, [r0]!
   1200 	cmp	r2, #6
   1201 	blo	.Lcbc_dec_five
   1202 	vld1.8	{q5}, [r0]!
   1203 	beq	.Lcbc_dec_six
   1204 	vld1.8	{q6}, [r0]!
   1205 	sub	r0, r0, #0x70
   1206 
   1207 	bl	_bsaes_decrypt8
   1208 
   1209 	vldmia	r9, {q14}			@ reload IV
   1210 	vld1.8	{q8,q9}, [r0]!	@ reload input
   1211 	veor	q0, q0, q14	@ ^= IV
   1212 	vld1.8	{q10,q11}, [r0]!
   1213 	veor	q1, q1, q8
   1214 	veor	q6, q6, q9
   1215 	vld1.8	{q12,q13}, [r0]!
   1216 	veor	q4, q4, q10
   1217 	veor	q2, q2, q11
   1218 	vld1.8	{q15}, [r0]!
   1219 	veor	q7, q7, q12
   1220 	vst1.8	{q0,q1}, [r1]!	@ write output
   1221 	veor	q3, q3, q13
   1222 	vst1.8	{q6}, [r1]!
   1223 	vst1.8	{q4}, [r1]!
   1224 	vst1.8	{q2}, [r1]!
   1225 	vst1.8	{q7}, [r1]!
   1226 	vst1.8	{q3}, [r1]!
   1227 	b	.Lcbc_dec_done
   1228 .align	4
   1229 .Lcbc_dec_six:
   1230 	sub	r0, r0, #0x60
   1231 	bl	_bsaes_decrypt8
   1232 	vldmia	r9,{q14}			@ reload IV
   1233 	vld1.8	{q8,q9}, [r0]!	@ reload input
   1234 	veor	q0, q0, q14	@ ^= IV
   1235 	vld1.8	{q10,q11}, [r0]!
   1236 	veor	q1, q1, q8
   1237 	veor	q6, q6, q9
   1238 	vld1.8	{q12}, [r0]!
   1239 	veor	q4, q4, q10
   1240 	veor	q2, q2, q11
   1241 	vld1.8	{q15}, [r0]!
   1242 	veor	q7, q7, q12
   1243 	vst1.8	{q0,q1}, [r1]!	@ write output
   1244 	vst1.8	{q6}, [r1]!
   1245 	vst1.8	{q4}, [r1]!
   1246 	vst1.8	{q2}, [r1]!
   1247 	vst1.8	{q7}, [r1]!
   1248 	b	.Lcbc_dec_done
   1249 .align	4
   1250 .Lcbc_dec_five:
   1251 	sub	r0, r0, #0x50
   1252 	bl	_bsaes_decrypt8
   1253 	vldmia	r9, {q14}			@ reload IV
   1254 	vld1.8	{q8,q9}, [r0]!	@ reload input
   1255 	veor	q0, q0, q14	@ ^= IV
   1256 	vld1.8	{q10,q11}, [r0]!
   1257 	veor	q1, q1, q8
   1258 	veor	q6, q6, q9
   1259 	vld1.8	{q15}, [r0]!
   1260 	veor	q4, q4, q10
   1261 	vst1.8	{q0,q1}, [r1]!	@ write output
   1262 	veor	q2, q2, q11
   1263 	vst1.8	{q6}, [r1]!
   1264 	vst1.8	{q4}, [r1]!
   1265 	vst1.8	{q2}, [r1]!
   1266 	b	.Lcbc_dec_done
   1267 .align	4
   1268 .Lcbc_dec_four:
   1269 	sub	r0, r0, #0x40
   1270 	bl	_bsaes_decrypt8
   1271 	vldmia	r9, {q14}			@ reload IV
   1272 	vld1.8	{q8,q9}, [r0]!	@ reload input
   1273 	veor	q0, q0, q14	@ ^= IV
   1274 	vld1.8	{q10}, [r0]!
   1275 	veor	q1, q1, q8
   1276 	veor	q6, q6, q9
   1277 	vld1.8	{q15}, [r0]!
   1278 	veor	q4, q4, q10
   1279 	vst1.8	{q0,q1}, [r1]!	@ write output
   1280 	vst1.8	{q6}, [r1]!
   1281 	vst1.8	{q4}, [r1]!
   1282 	b	.Lcbc_dec_done
   1283 .align	4
   1284 .Lcbc_dec_three:
   1285 	sub	r0, r0, #0x30
   1286 	bl	_bsaes_decrypt8
   1287 	vldmia	r9, {q14}			@ reload IV
   1288 	vld1.8	{q8,q9}, [r0]!	@ reload input
   1289 	veor	q0, q0, q14	@ ^= IV
   1290 	vld1.8	{q15}, [r0]!
   1291 	veor	q1, q1, q8
   1292 	veor	q6, q6, q9
   1293 	vst1.8	{q0,q1}, [r1]!	@ write output
   1294 	vst1.8	{q6}, [r1]!
   1295 	b	.Lcbc_dec_done
   1296 .align	4
   1297 .Lcbc_dec_two:
   1298 	sub	r0, r0, #0x20
   1299 	bl	_bsaes_decrypt8
   1300 	vldmia	r9, {q14}			@ reload IV
   1301 	vld1.8	{q8}, [r0]!		@ reload input
   1302 	veor	q0, q0, q14	@ ^= IV
   1303 	vld1.8	{q15}, [r0]!		@ reload input
   1304 	veor	q1, q1, q8
   1305 	vst1.8	{q0,q1}, [r1]!	@ write output
   1306 	b	.Lcbc_dec_done
   1307 .align	4
   1308 .Lcbc_dec_one:
   1309 	sub	r0, r0, #0x10
   1310 	mov	r10, r1			@ save original out pointer
   1311 	mov	r1, r9			@ use the iv scratch space as out buffer
   1312 	mov	r2, r3
   1313 	vmov	q4,q15		@ just in case ensure that IV
   1314 	vmov	q5,q0			@ and input are preserved
   1315 	bl	AES_decrypt
   1316 	vld1.8	{q0}, [r9,:64]		@ load result
   1317 	veor	q0, q0, q4	@ ^= IV
   1318 	vmov	q15, q5		@ q5 holds input
   1319 	vst1.8	{q0}, [r10]		@ write output
   1320 
   1321 .Lcbc_dec_done:
   1322 #ifndef	BSAES_ASM_EXTENDED_KEY
   1323 	vmov.i32	q0, #0
   1324 	vmov.i32	q1, #0
   1325 .Lcbc_dec_bzero:@ wipe key schedule [if any]
   1326 	vstmia	sp!, {q0,q1}
   1327 	cmp	sp, r9
   1328 	bne	.Lcbc_dec_bzero
   1329 #endif
   1330 
   1331 	mov	sp, r9
   1332 	add	sp, #0x10			@ add sp,r9,#0x10 is no good for thumb
   1333 	vst1.8	{q15}, [r8]		@ return IV
   1334 	VFP_ABI_POP
   1335 	ldmia	sp!, {r4,r5,r6,r7,r8,r9,r10, pc}
   1336 .size	bsaes_cbc_encrypt,.-bsaes_cbc_encrypt
   1337 
   1338 .globl	bsaes_ctr32_encrypt_blocks
   1339 .hidden	bsaes_ctr32_encrypt_blocks
   1340 .type	bsaes_ctr32_encrypt_blocks,%function
   1341 .align	5
   1342 bsaes_ctr32_encrypt_blocks:
   1343 	cmp	r2, #8			@ use plain AES for
   1344 	blo	.Lctr_enc_short			@ small sizes
   1345 
   1346 	mov	ip, sp
   1347 	stmdb	sp!, {r4,r5,r6,r7,r8,r9,r10, lr}
   1348 	VFP_ABI_PUSH
   1349 	ldr	r8, [ip]			@ ctr is 1st arg on the stack
   1350 	sub	sp, sp, #0x10			@ scratch space to carry over the ctr
   1351 	mov	r9, sp				@ save sp
   1352 
   1353 	ldr	r10, [r3, #240]		@ get # of rounds
   1354 #ifndef	BSAES_ASM_EXTENDED_KEY
   1355 	@ allocate the key schedule on the stack
   1356 	sub	r12, sp, r10, lsl#7		@ 128 bytes per inner round key
   1357 	add	r12, #96			@ size of bit-sliced key schedule
   1358 
   1359 	@ populate the key schedule
   1360 	mov	r4, r3			@ pass key
   1361 	mov	r5, r10			@ pass # of rounds
   1362 	mov	sp, r12				@ sp is sp
   1363 	bl	_bsaes_key_convert
   1364 	veor	q7,q7,q15	@ fix up last round key
   1365 	vstmia	r12, {q7}			@ save last round key
   1366 
   1367 	vld1.8	{q0}, [r8]		@ load counter
   1368 #ifdef	__APPLE__
   1369 	mov	r8, #:lower16:(.LREVM0SR-.LM0)
   1370 	add	r8, r6, r8
   1371 #else
   1372 	add	r8, r6, #.LREVM0SR-.LM0	@ borrow r8
   1373 #endif
   1374 	vldmia	sp, {q4}		@ load round0 key
   1375 #else
   1376 	ldr	r12, [r3, #244]
   1377 	eors	r12, #1
   1378 	beq	0f
   1379 
   1380 	@ populate the key schedule
   1381 	str	r12, [r3, #244]
   1382 	mov	r4, r3			@ pass key
   1383 	mov	r5, r10			@ pass # of rounds
   1384 	add	r12, r3, #248			@ pass key schedule
   1385 	bl	_bsaes_key_convert
   1386 	veor	q7,q7,q15	@ fix up last round key
   1387 	vstmia	r12, {q7}			@ save last round key
   1388 
   1389 .align	2
   1390 	add	r12, r3, #248
   1391 	vld1.8	{q0}, [r8]		@ load counter
   1392 	adrl	r8, .LREVM0SR			@ borrow r8
   1393 	vldmia	r12, {q4}			@ load round0 key
   1394 	sub	sp, #0x10			@ place for adjusted round0 key
   1395 #endif
   1396 
   1397 	vmov.i32	q8,#1		@ compose 1<<96
   1398 	veor	q9,q9,q9
   1399 	vrev32.8	q0,q0
   1400 	vext.8	q8,q9,q8,#4
   1401 	vrev32.8	q4,q4
   1402 	vadd.u32	q9,q8,q8	@ compose 2<<96
   1403 	vstmia	sp, {q4}		@ save adjusted round0 key
   1404 	b	.Lctr_enc_loop
   1405 
   1406 .align	4
   1407 .Lctr_enc_loop:
   1408 	vadd.u32	q10, q8, q9	@ compose 3<<96
   1409 	vadd.u32	q1, q0, q8	@ +1
   1410 	vadd.u32	q2, q0, q9	@ +2
   1411 	vadd.u32	q3, q0, q10	@ +3
   1412 	vadd.u32	q4, q1, q10
   1413 	vadd.u32	q5, q2, q10
   1414 	vadd.u32	q6, q3, q10
   1415 	vadd.u32	q7, q4, q10
   1416 	vadd.u32	q10, q5, q10	@ next counter
   1417 
   1418 	@ Borrow prologue from _bsaes_encrypt8 to use the opportunity
   1419 	@ to flip byte order in 32-bit counter
   1420 
   1421 	vldmia	sp, {q9}		@ load round0 key
   1422 #ifndef	BSAES_ASM_EXTENDED_KEY
   1423 	add	r4, sp, #0x10		@ pass next round key
   1424 #else
   1425 	add	r4, r3, #264
   1426 #endif
   1427 	vldmia	r8, {q8}			@ .LREVM0SR
   1428 	mov	r5, r10			@ pass rounds
   1429 	vstmia	r9, {q10}			@ save next counter
   1430 #ifdef	__APPLE__
   1431 	mov	r6, #:lower16:(.LREVM0SR-.LSR)
   1432 	sub	r6, r8, r6
   1433 #else
   1434 	sub	r6, r8, #.LREVM0SR-.LSR	@ pass constants
   1435 #endif
   1436 
   1437 	bl	_bsaes_encrypt8_alt
   1438 
   1439 	subs	r2, r2, #8
   1440 	blo	.Lctr_enc_loop_done
   1441 
   1442 	vld1.8	{q8,q9}, [r0]!	@ load input
   1443 	vld1.8	{q10,q11}, [r0]!
   1444 	veor	q0, q8
   1445 	veor	q1, q9
   1446 	vld1.8	{q12,q13}, [r0]!
   1447 	veor	q4, q10
   1448 	veor	q6, q11
   1449 	vld1.8	{q14,q15}, [r0]!
   1450 	veor	q3, q12
   1451 	vst1.8	{q0,q1}, [r1]!	@ write output
   1452 	veor	q7, q13
   1453 	veor	q2, q14
   1454 	vst1.8	{q4}, [r1]!
   1455 	veor	q5, q15
   1456 	vst1.8	{q6}, [r1]!
   1457 	vmov.i32	q8, #1			@ compose 1<<96
   1458 	vst1.8	{q3}, [r1]!
   1459 	veor	q9, q9, q9
   1460 	vst1.8	{q7}, [r1]!
   1461 	vext.8	q8, q9, q8, #4
   1462 	vst1.8	{q2}, [r1]!
   1463 	vadd.u32	q9,q8,q8		@ compose 2<<96
   1464 	vst1.8	{q5}, [r1]!
   1465 	vldmia	r9, {q0}			@ load counter
   1466 
   1467 	bne	.Lctr_enc_loop
   1468 	b	.Lctr_enc_done
   1469 
   1470 .align	4
   1471 .Lctr_enc_loop_done:
   1472 	add	r2, r2, #8
   1473 	vld1.8	{q8}, [r0]!	@ load input
   1474 	veor	q0, q8
   1475 	vst1.8	{q0}, [r1]!	@ write output
   1476 	cmp	r2, #2
   1477 	blo	.Lctr_enc_done
   1478 	vld1.8	{q9}, [r0]!
   1479 	veor	q1, q9
   1480 	vst1.8	{q1}, [r1]!
   1481 	beq	.Lctr_enc_done
   1482 	vld1.8	{q10}, [r0]!
   1483 	veor	q4, q10
   1484 	vst1.8	{q4}, [r1]!
   1485 	cmp	r2, #4
   1486 	blo	.Lctr_enc_done
   1487 	vld1.8	{q11}, [r0]!
   1488 	veor	q6, q11
   1489 	vst1.8	{q6}, [r1]!
   1490 	beq	.Lctr_enc_done
   1491 	vld1.8	{q12}, [r0]!
   1492 	veor	q3, q12
   1493 	vst1.8	{q3}, [r1]!
   1494 	cmp	r2, #6
   1495 	blo	.Lctr_enc_done
   1496 	vld1.8	{q13}, [r0]!
   1497 	veor	q7, q13
   1498 	vst1.8	{q7}, [r1]!
   1499 	beq	.Lctr_enc_done
   1500 	vld1.8	{q14}, [r0]
   1501 	veor	q2, q14
   1502 	vst1.8	{q2}, [r1]!
   1503 
   1504 .Lctr_enc_done:
   1505 	vmov.i32	q0, #0
   1506 	vmov.i32	q1, #0
   1507 #ifndef	BSAES_ASM_EXTENDED_KEY
   1508 .Lctr_enc_bzero:@ wipe key schedule [if any]
   1509 	vstmia	sp!, {q0,q1}
   1510 	cmp	sp, r9
   1511 	bne	.Lctr_enc_bzero
   1512 #else
   1513 	vstmia	sp, {q0,q1}
   1514 #endif
   1515 
   1516 	mov	sp, r9
   1517 	add	sp, #0x10		@ add sp,r9,#0x10 is no good for thumb
   1518 	VFP_ABI_POP
   1519 	ldmia	sp!, {r4,r5,r6,r7,r8,r9,r10, pc}	@ return
   1520 
   1521 .align	4
   1522 .Lctr_enc_short:
   1523 	ldr	ip, [sp]		@ ctr pointer is passed on stack
   1524 	stmdb	sp!, {r4,r5,r6,r7,r8, lr}
   1525 
   1526 	mov	r4, r0		@ copy arguments
   1527 	mov	r5, r1
   1528 	mov	r6, r2
   1529 	mov	r7, r3
   1530 	ldr	r8, [ip, #12]		@ load counter .LSW
   1531 	vld1.8	{q1}, [ip]		@ load whole counter value
   1532 #ifdef __ARMEL__
   1533 	rev	r8, r8
   1534 #endif
   1535 	sub	sp, sp, #0x10
   1536 	vst1.8	{q1}, [sp]		@ copy counter value
   1537 	sub	sp, sp, #0x10
   1538 
   1539 .Lctr_enc_short_loop:
   1540 	add	r0, sp, #0x10		@ input counter value
   1541 	mov	r1, sp			@ output on the stack
   1542 	mov	r2, r7			@ key
   1543 
   1544 	bl	AES_encrypt
   1545 
   1546 	vld1.8	{q0}, [r4]!	@ load input
   1547 	vld1.8	{q1}, [sp]		@ load encrypted counter
   1548 	add	r8, r8, #1
   1549 #ifdef __ARMEL__
   1550 	rev	r0, r8
   1551 	str	r0, [sp, #0x1c]		@ next counter value
   1552 #else
   1553 	str	r8, [sp, #0x1c]		@ next counter value
   1554 #endif
   1555 	veor	q0,q0,q1
   1556 	vst1.8	{q0}, [r5]!	@ store output
   1557 	subs	r6, r6, #1
   1558 	bne	.Lctr_enc_short_loop
   1559 
   1560 	vmov.i32	q0, #0
   1561 	vmov.i32	q1, #0
   1562 	vstmia	sp!, {q0,q1}
   1563 
   1564 	ldmia	sp!, {r4,r5,r6,r7,r8, pc}
   1565 .size	bsaes_ctr32_encrypt_blocks,.-bsaes_ctr32_encrypt_blocks
   1566 .globl	bsaes_xts_encrypt
   1567 .hidden	bsaes_xts_encrypt
   1568 .type	bsaes_xts_encrypt,%function
   1569 .align	4
   1570 bsaes_xts_encrypt:
   1571 	mov	ip, sp
   1572 	stmdb	sp!, {r4,r5,r6,r7,r8,r9,r10, lr}		@ 0x20
   1573 	VFP_ABI_PUSH
   1574 	mov	r6, sp				@ future r3
   1575 
   1576 	mov	r7, r0
   1577 	mov	r8, r1
   1578 	mov	r9, r2
   1579 	mov	r10, r3
   1580 
   1581 	sub	r0, sp, #0x10			@ 0x10
   1582 	bic	r0, #0xf			@ align at 16 bytes
   1583 	mov	sp, r0
   1584 
   1585 #ifdef	XTS_CHAIN_TWEAK
   1586 	ldr	r0, [ip]			@ pointer to input tweak
   1587 #else
   1588 	@ generate initial tweak
   1589 	ldr	r0, [ip, #4]			@ iv[]
   1590 	mov	r1, sp
   1591 	ldr	r2, [ip, #0]			@ key2
   1592 	bl	AES_encrypt
   1593 	mov	r0,sp				@ pointer to initial tweak
   1594 #endif
   1595 
   1596 	ldr	r1, [r10, #240]		@ get # of rounds
   1597 	mov	r3, r6
   1598 #ifndef	BSAES_ASM_EXTENDED_KEY
   1599 	@ allocate the key schedule on the stack
   1600 	sub	r12, sp, r1, lsl#7		@ 128 bytes per inner round key
   1601 	@ add	r12, #96			@ size of bit-sliced key schedule
   1602 	sub	r12, #48			@ place for tweak[9]
   1603 
   1604 	@ populate the key schedule
   1605 	mov	r4, r10			@ pass key
   1606 	mov	r5, r1			@ pass # of rounds
   1607 	mov	sp, r12
   1608 	add	r12, #0x90			@ pass key schedule
   1609 	bl	_bsaes_key_convert
   1610 	veor	q7, q7, q15	@ fix up last round key
   1611 	vstmia	r12, {q7}			@ save last round key
   1612 #else
   1613 	ldr	r12, [r10, #244]
   1614 	eors	r12, #1
   1615 	beq	0f
   1616 
   1617 	str	r12, [r10, #244]
   1618 	mov	r4, r10			@ pass key
   1619 	mov	r5, r1			@ pass # of rounds
   1620 	add	r12, r10, #248			@ pass key schedule
   1621 	bl	_bsaes_key_convert
   1622 	veor	q7, q7, q15	@ fix up last round key
   1623 	vstmia	r12, {q7}
   1624 
   1625 .align	2
   1626 	sub	sp, #0x90			@ place for tweak[9]
   1627 #endif
   1628 
   1629 	vld1.8	{q8}, [r0]			@ initial tweak
   1630 	adr	r2, .Lxts_magic
   1631 
   1632 	subs	r9, #0x80
   1633 	blo	.Lxts_enc_short
   1634 	b	.Lxts_enc_loop
   1635 
   1636 .align	4
   1637 .Lxts_enc_loop:
   1638 	vldmia	r2, {q5}	@ load XTS magic
   1639 	vshr.s64	q6, q8, #63
   1640 	mov	r0, sp
   1641 	vand	q6, q6, q5
   1642 	vadd.u64	q9, q8, q8
   1643 	vst1.64	{q8}, [r0,:128]!
   1644 	vswp	d13,d12
   1645 	vshr.s64	q7, q9, #63
   1646 	veor	q9, q9, q6
   1647 	vand	q7, q7, q5
   1648 	vadd.u64	q10, q9, q9
   1649 	vst1.64	{q9}, [r0,:128]!
   1650 	vswp	d15,d14
   1651 	vshr.s64	q6, q10, #63
   1652 	veor	q10, q10, q7
   1653 	vand	q6, q6, q5
   1654 	vld1.8	{q0}, [r7]!
   1655 	vadd.u64	q11, q10, q10
   1656 	vst1.64	{q10}, [r0,:128]!
   1657 	vswp	d13,d12
   1658 	vshr.s64	q7, q11, #63
   1659 	veor	q11, q11, q6
   1660 	vand	q7, q7, q5
   1661 	vld1.8	{q1}, [r7]!
   1662 	veor	q0, q0, q8
   1663 	vadd.u64	q12, q11, q11
   1664 	vst1.64	{q11}, [r0,:128]!
   1665 	vswp	d15,d14
   1666 	vshr.s64	q6, q12, #63
   1667 	veor	q12, q12, q7
   1668 	vand	q6, q6, q5
   1669 	vld1.8	{q2}, [r7]!
   1670 	veor	q1, q1, q9
   1671 	vadd.u64	q13, q12, q12
   1672 	vst1.64	{q12}, [r0,:128]!
   1673 	vswp	d13,d12
   1674 	vshr.s64	q7, q13, #63
   1675 	veor	q13, q13, q6
   1676 	vand	q7, q7, q5
   1677 	vld1.8	{q3}, [r7]!
   1678 	veor	q2, q2, q10
   1679 	vadd.u64	q14, q13, q13
   1680 	vst1.64	{q13}, [r0,:128]!
   1681 	vswp	d15,d14
   1682 	vshr.s64	q6, q14, #63
   1683 	veor	q14, q14, q7
   1684 	vand	q6, q6, q5
   1685 	vld1.8	{q4}, [r7]!
   1686 	veor	q3, q3, q11
   1687 	vadd.u64	q15, q14, q14
   1688 	vst1.64	{q14}, [r0,:128]!
   1689 	vswp	d13,d12
   1690 	vshr.s64	q7, q15, #63
   1691 	veor	q15, q15, q6
   1692 	vand	q7, q7, q5
   1693 	vld1.8	{q5}, [r7]!
   1694 	veor	q4, q4, q12
   1695 	vadd.u64	q8, q15, q15
   1696 	vst1.64	{q15}, [r0,:128]!
   1697 	vswp	d15,d14
   1698 	veor	q8, q8, q7
   1699 	vst1.64	{q8}, [r0,:128]		@ next round tweak
   1700 
   1701 	vld1.8	{q6,q7}, [r7]!
   1702 	veor	q5, q5, q13
   1703 #ifndef	BSAES_ASM_EXTENDED_KEY
   1704 	add	r4, sp, #0x90			@ pass key schedule
   1705 #else
   1706 	add	r4, r10, #248			@ pass key schedule
   1707 #endif
   1708 	veor	q6, q6, q14
   1709 	mov	r5, r1			@ pass rounds
   1710 	veor	q7, q7, q15
   1711 	mov	r0, sp
   1712 
   1713 	bl	_bsaes_encrypt8
   1714 
   1715 	vld1.64	{q8,q9}, [r0,:128]!
   1716 	vld1.64	{q10,q11}, [r0,:128]!
   1717 	veor	q0, q0, q8
   1718 	vld1.64	{q12,q13}, [r0,:128]!
   1719 	veor	q1, q1, q9
   1720 	veor	q8, q4, q10
   1721 	vst1.8	{q0,q1}, [r8]!
   1722 	veor	q9, q6, q11
   1723 	vld1.64	{q14,q15}, [r0,:128]!
   1724 	veor	q10, q3, q12
   1725 	vst1.8	{q8,q9}, [r8]!
   1726 	veor	q11, q7, q13
   1727 	veor	q12, q2, q14
   1728 	vst1.8	{q10,q11}, [r8]!
   1729 	veor	q13, q5, q15
   1730 	vst1.8	{q12,q13}, [r8]!
   1731 
   1732 	vld1.64	{q8}, [r0,:128]		@ next round tweak
   1733 
   1734 	subs	r9, #0x80
   1735 	bpl	.Lxts_enc_loop
   1736 
   1737 .Lxts_enc_short:
   1738 	adds	r9, #0x70
   1739 	bmi	.Lxts_enc_done
   1740 
   1741 	vldmia	r2, {q5}	@ load XTS magic
   1742 	vshr.s64	q7, q8, #63
   1743 	mov	r0, sp
   1744 	vand	q7, q7, q5
   1745 	vadd.u64	q9, q8, q8
   1746 	vst1.64	{q8}, [r0,:128]!
   1747 	vswp	d15,d14
   1748 	vshr.s64	q6, q9, #63
   1749 	veor	q9, q9, q7
   1750 	vand	q6, q6, q5
   1751 	vadd.u64	q10, q9, q9
   1752 	vst1.64	{q9}, [r0,:128]!
   1753 	vswp	d13,d12
   1754 	vshr.s64	q7, q10, #63
   1755 	veor	q10, q10, q6
   1756 	vand	q7, q7, q5
   1757 	vld1.8	{q0}, [r7]!
   1758 	subs	r9, #0x10
   1759 	bmi	.Lxts_enc_1
   1760 	vadd.u64	q11, q10, q10
   1761 	vst1.64	{q10}, [r0,:128]!
   1762 	vswp	d15,d14
   1763 	vshr.s64	q6, q11, #63
   1764 	veor	q11, q11, q7
   1765 	vand	q6, q6, q5
   1766 	vld1.8	{q1}, [r7]!
   1767 	subs	r9, #0x10
   1768 	bmi	.Lxts_enc_2
   1769 	veor	q0, q0, q8
   1770 	vadd.u64	q12, q11, q11
   1771 	vst1.64	{q11}, [r0,:128]!
   1772 	vswp	d13,d12
   1773 	vshr.s64	q7, q12, #63
   1774 	veor	q12, q12, q6
   1775 	vand	q7, q7, q5
   1776 	vld1.8	{q2}, [r7]!
   1777 	subs	r9, #0x10
   1778 	bmi	.Lxts_enc_3
   1779 	veor	q1, q1, q9
   1780 	vadd.u64	q13, q12, q12
   1781 	vst1.64	{q12}, [r0,:128]!
   1782 	vswp	d15,d14
   1783 	vshr.s64	q6, q13, #63
   1784 	veor	q13, q13, q7
   1785 	vand	q6, q6, q5
   1786 	vld1.8	{q3}, [r7]!
   1787 	subs	r9, #0x10
   1788 	bmi	.Lxts_enc_4
   1789 	veor	q2, q2, q10
   1790 	vadd.u64	q14, q13, q13
   1791 	vst1.64	{q13}, [r0,:128]!
   1792 	vswp	d13,d12
   1793 	vshr.s64	q7, q14, #63
   1794 	veor	q14, q14, q6
   1795 	vand	q7, q7, q5
   1796 	vld1.8	{q4}, [r7]!
   1797 	subs	r9, #0x10
   1798 	bmi	.Lxts_enc_5
   1799 	veor	q3, q3, q11
   1800 	vadd.u64	q15, q14, q14
   1801 	vst1.64	{q14}, [r0,:128]!
   1802 	vswp	d15,d14
   1803 	vshr.s64	q6, q15, #63
   1804 	veor	q15, q15, q7
   1805 	vand	q6, q6, q5
   1806 	vld1.8	{q5}, [r7]!
   1807 	subs	r9, #0x10
   1808 	bmi	.Lxts_enc_6
   1809 	veor	q4, q4, q12
   1810 	sub	r9, #0x10
   1811 	vst1.64	{q15}, [r0,:128]		@ next round tweak
   1812 
   1813 	vld1.8	{q6}, [r7]!
   1814 	veor	q5, q5, q13
   1815 #ifndef	BSAES_ASM_EXTENDED_KEY
   1816 	add	r4, sp, #0x90			@ pass key schedule
   1817 #else
   1818 	add	r4, r10, #248			@ pass key schedule
   1819 #endif
   1820 	veor	q6, q6, q14
   1821 	mov	r5, r1			@ pass rounds
   1822 	mov	r0, sp
   1823 
   1824 	bl	_bsaes_encrypt8
   1825 
   1826 	vld1.64	{q8,q9}, [r0,:128]!
   1827 	vld1.64	{q10,q11}, [r0,:128]!
   1828 	veor	q0, q0, q8
   1829 	vld1.64	{q12,q13}, [r0,:128]!
   1830 	veor	q1, q1, q9
   1831 	veor	q8, q4, q10
   1832 	vst1.8	{q0,q1}, [r8]!
   1833 	veor	q9, q6, q11
   1834 	vld1.64	{q14}, [r0,:128]!
   1835 	veor	q10, q3, q12
   1836 	vst1.8	{q8,q9}, [r8]!
   1837 	veor	q11, q7, q13
   1838 	veor	q12, q2, q14
   1839 	vst1.8	{q10,q11}, [r8]!
   1840 	vst1.8	{q12}, [r8]!
   1841 
   1842 	vld1.64	{q8}, [r0,:128]		@ next round tweak
   1843 	b	.Lxts_enc_done
   1844 .align	4
   1845 .Lxts_enc_6:
   1846 	vst1.64	{q14}, [r0,:128]		@ next round tweak
   1847 
   1848 	veor	q4, q4, q12
   1849 #ifndef	BSAES_ASM_EXTENDED_KEY
   1850 	add	r4, sp, #0x90			@ pass key schedule
   1851 #else
   1852 	add	r4, r10, #248			@ pass key schedule
   1853 #endif
   1854 	veor	q5, q5, q13
   1855 	mov	r5, r1			@ pass rounds
   1856 	mov	r0, sp
   1857 
   1858 	bl	_bsaes_encrypt8
   1859 
   1860 	vld1.64	{q8,q9}, [r0,:128]!
   1861 	vld1.64	{q10,q11}, [r0,:128]!
   1862 	veor	q0, q0, q8
   1863 	vld1.64	{q12,q13}, [r0,:128]!
   1864 	veor	q1, q1, q9
   1865 	veor	q8, q4, q10
   1866 	vst1.8	{q0,q1}, [r8]!
   1867 	veor	q9, q6, q11
   1868 	veor	q10, q3, q12
   1869 	vst1.8	{q8,q9}, [r8]!
   1870 	veor	q11, q7, q13
   1871 	vst1.8	{q10,q11}, [r8]!
   1872 
   1873 	vld1.64	{q8}, [r0,:128]		@ next round tweak
   1874 	b	.Lxts_enc_done
   1875 
   1876 @ put this in range for both ARM and Thumb mode adr instructions
   1877 .align	5
   1878 .Lxts_magic:
   1879 .quad	1, 0x87
   1880 
   1881 .align	5
   1882 .Lxts_enc_5:
   1883 	vst1.64	{q13}, [r0,:128]		@ next round tweak
   1884 
   1885 	veor	q3, q3, q11
   1886 #ifndef	BSAES_ASM_EXTENDED_KEY
   1887 	add	r4, sp, #0x90			@ pass key schedule
   1888 #else
   1889 	add	r4, r10, #248			@ pass key schedule
   1890 #endif
   1891 	veor	q4, q4, q12
   1892 	mov	r5, r1			@ pass rounds
   1893 	mov	r0, sp
   1894 
   1895 	bl	_bsaes_encrypt8
   1896 
   1897 	vld1.64	{q8,q9}, [r0,:128]!
   1898 	vld1.64	{q10,q11}, [r0,:128]!
   1899 	veor	q0, q0, q8
   1900 	vld1.64	{q12}, [r0,:128]!
   1901 	veor	q1, q1, q9
   1902 	veor	q8, q4, q10
   1903 	vst1.8	{q0,q1}, [r8]!
   1904 	veor	q9, q6, q11
   1905 	veor	q10, q3, q12
   1906 	vst1.8	{q8,q9}, [r8]!
   1907 	vst1.8	{q10}, [r8]!
   1908 
   1909 	vld1.64	{q8}, [r0,:128]		@ next round tweak
   1910 	b	.Lxts_enc_done
   1911 .align	4
   1912 .Lxts_enc_4:
   1913 	vst1.64	{q12}, [r0,:128]		@ next round tweak
   1914 
   1915 	veor	q2, q2, q10
   1916 #ifndef	BSAES_ASM_EXTENDED_KEY
   1917 	add	r4, sp, #0x90			@ pass key schedule
   1918 #else
   1919 	add	r4, r10, #248			@ pass key schedule
   1920 #endif
   1921 	veor	q3, q3, q11
   1922 	mov	r5, r1			@ pass rounds
   1923 	mov	r0, sp
   1924 
   1925 	bl	_bsaes_encrypt8
   1926 
   1927 	vld1.64	{q8,q9}, [r0,:128]!
   1928 	vld1.64	{q10,q11}, [r0,:128]!
   1929 	veor	q0, q0, q8
   1930 	veor	q1, q1, q9
   1931 	veor	q8, q4, q10
   1932 	vst1.8	{q0,q1}, [r8]!
   1933 	veor	q9, q6, q11
   1934 	vst1.8	{q8,q9}, [r8]!
   1935 
   1936 	vld1.64	{q8}, [r0,:128]		@ next round tweak
   1937 	b	.Lxts_enc_done
   1938 .align	4
   1939 .Lxts_enc_3:
   1940 	vst1.64	{q11}, [r0,:128]		@ next round tweak
   1941 
   1942 	veor	q1, q1, q9
   1943 #ifndef	BSAES_ASM_EXTENDED_KEY
   1944 	add	r4, sp, #0x90			@ pass key schedule
   1945 #else
   1946 	add	r4, r10, #248			@ pass key schedule
   1947 #endif
   1948 	veor	q2, q2, q10
   1949 	mov	r5, r1			@ pass rounds
   1950 	mov	r0, sp
   1951 
   1952 	bl	_bsaes_encrypt8
   1953 
   1954 	vld1.64	{q8,q9}, [r0,:128]!
   1955 	vld1.64	{q10}, [r0,:128]!
   1956 	veor	q0, q0, q8
   1957 	veor	q1, q1, q9
   1958 	veor	q8, q4, q10
   1959 	vst1.8	{q0,q1}, [r8]!
   1960 	vst1.8	{q8}, [r8]!
   1961 
   1962 	vld1.64	{q8}, [r0,:128]		@ next round tweak
   1963 	b	.Lxts_enc_done
   1964 .align	4
   1965 .Lxts_enc_2:
   1966 	vst1.64	{q10}, [r0,:128]		@ next round tweak
   1967 
   1968 	veor	q0, q0, q8
   1969 #ifndef	BSAES_ASM_EXTENDED_KEY
   1970 	add	r4, sp, #0x90			@ pass key schedule
   1971 #else
   1972 	add	r4, r10, #248			@ pass key schedule
   1973 #endif
   1974 	veor	q1, q1, q9
   1975 	mov	r5, r1			@ pass rounds
   1976 	mov	r0, sp
   1977 
   1978 	bl	_bsaes_encrypt8
   1979 
   1980 	vld1.64	{q8,q9}, [r0,:128]!
   1981 	veor	q0, q0, q8
   1982 	veor	q1, q1, q9
   1983 	vst1.8	{q0,q1}, [r8]!
   1984 
   1985 	vld1.64	{q8}, [r0,:128]		@ next round tweak
   1986 	b	.Lxts_enc_done
   1987 .align	4
   1988 .Lxts_enc_1:
   1989 	mov	r0, sp
   1990 	veor	q0, q8
   1991 	mov	r1, sp
   1992 	vst1.8	{q0}, [sp,:128]
   1993 	mov	r2, r10
   1994 	mov	r4, r3				@ preserve fp
   1995 
   1996 	bl	AES_encrypt
   1997 
   1998 	vld1.8	{q0}, [sp,:128]
   1999 	veor	q0, q0, q8
   2000 	vst1.8	{q0}, [r8]!
   2001 	mov	r3, r4
   2002 
   2003 	vmov	q8, q9		@ next round tweak
   2004 
   2005 .Lxts_enc_done:
   2006 #ifndef	XTS_CHAIN_TWEAK
   2007 	adds	r9, #0x10
   2008 	beq	.Lxts_enc_ret
   2009 	sub	r6, r8, #0x10
   2010 
   2011 .Lxts_enc_steal:
   2012 	ldrb	r0, [r7], #1
   2013 	ldrb	r1, [r8, #-0x10]
   2014 	strb	r0, [r8, #-0x10]
   2015 	strb	r1, [r8], #1
   2016 
   2017 	subs	r9, #1
   2018 	bhi	.Lxts_enc_steal
   2019 
   2020 	vld1.8	{q0}, [r6]
   2021 	mov	r0, sp
   2022 	veor	q0, q0, q8
   2023 	mov	r1, sp
   2024 	vst1.8	{q0}, [sp,:128]
   2025 	mov	r2, r10
   2026 	mov	r4, r3			@ preserve fp
   2027 
   2028 	bl	AES_encrypt
   2029 
   2030 	vld1.8	{q0}, [sp,:128]
   2031 	veor	q0, q0, q8
   2032 	vst1.8	{q0}, [r6]
   2033 	mov	r3, r4
   2034 #endif
   2035 
   2036 .Lxts_enc_ret:
   2037 	bic	r0, r3, #0xf
   2038 	vmov.i32	q0, #0
   2039 	vmov.i32	q1, #0
   2040 #ifdef	XTS_CHAIN_TWEAK
   2041 	ldr	r1, [r3, #0x20+VFP_ABI_FRAME]	@ chain tweak
   2042 #endif
   2043 .Lxts_enc_bzero:@ wipe key schedule [if any]
   2044 	vstmia	sp!, {q0,q1}
   2045 	cmp	sp, r0
   2046 	bne	.Lxts_enc_bzero
   2047 
   2048 	mov	sp, r3
   2049 #ifdef	XTS_CHAIN_TWEAK
   2050 	vst1.8	{q8}, [r1]
   2051 #endif
   2052 	VFP_ABI_POP
   2053 	ldmia	sp!, {r4,r5,r6,r7,r8,r9,r10, pc}	@ return
   2054 
   2055 .size	bsaes_xts_encrypt,.-bsaes_xts_encrypt
   2056 
   2057 .globl	bsaes_xts_decrypt
   2058 .hidden	bsaes_xts_decrypt
   2059 .type	bsaes_xts_decrypt,%function
   2060 .align	4
   2061 bsaes_xts_decrypt:
   2062 	mov	ip, sp
   2063 	stmdb	sp!, {r4,r5,r6,r7,r8,r9,r10, lr}		@ 0x20
   2064 	VFP_ABI_PUSH
   2065 	mov	r6, sp				@ future r3
   2066 
   2067 	mov	r7, r0
   2068 	mov	r8, r1
   2069 	mov	r9, r2
   2070 	mov	r10, r3
   2071 
   2072 	sub	r0, sp, #0x10			@ 0x10
   2073 	bic	r0, #0xf			@ align at 16 bytes
   2074 	mov	sp, r0
   2075 
   2076 #ifdef	XTS_CHAIN_TWEAK
   2077 	ldr	r0, [ip]			@ pointer to input tweak
   2078 #else
   2079 	@ generate initial tweak
   2080 	ldr	r0, [ip, #4]			@ iv[]
   2081 	mov	r1, sp
   2082 	ldr	r2, [ip, #0]			@ key2
   2083 	bl	AES_encrypt
   2084 	mov	r0, sp				@ pointer to initial tweak
   2085 #endif
   2086 
   2087 	ldr	r1, [r10, #240]		@ get # of rounds
   2088 	mov	r3, r6
   2089 #ifndef	BSAES_ASM_EXTENDED_KEY
   2090 	@ allocate the key schedule on the stack
   2091 	sub	r12, sp, r1, lsl#7		@ 128 bytes per inner round key
   2092 	@ add	r12, #96			@ size of bit-sliced key schedule
   2093 	sub	r12, #48			@ place for tweak[9]
   2094 
   2095 	@ populate the key schedule
   2096 	mov	r4, r10			@ pass key
   2097 	mov	r5, r1			@ pass # of rounds
   2098 	mov	sp, r12
   2099 	add	r12, #0x90			@ pass key schedule
   2100 	bl	_bsaes_key_convert
   2101 	add	r4, sp, #0x90
   2102 	vldmia	r4, {q6}
   2103 	vstmia	r12,  {q15}		@ save last round key
   2104 	veor	q7, q7, q6	@ fix up round 0 key
   2105 	vstmia	r4, {q7}
   2106 #else
   2107 	ldr	r12, [r10, #244]
   2108 	eors	r12, #1
   2109 	beq	0f
   2110 
   2111 	str	r12, [r10, #244]
   2112 	mov	r4, r10			@ pass key
   2113 	mov	r5, r1			@ pass # of rounds
   2114 	add	r12, r10, #248			@ pass key schedule
   2115 	bl	_bsaes_key_convert
   2116 	add	r4, r10, #248
   2117 	vldmia	r4, {q6}
   2118 	vstmia	r12,  {q15}		@ save last round key
   2119 	veor	q7, q7, q6	@ fix up round 0 key
   2120 	vstmia	r4, {q7}
   2121 
   2122 .align	2
   2123 	sub	sp, #0x90			@ place for tweak[9]
   2124 #endif
   2125 	vld1.8	{q8}, [r0]			@ initial tweak
   2126 	adr	r2, .Lxts_magic
   2127 
   2128 #ifndef	XTS_CHAIN_TWEAK
   2129 	tst	r9, #0xf			@ if not multiple of 16
   2130 	it	ne				@ Thumb2 thing, sanity check in ARM
   2131 	subne	r9, #0x10			@ subtract another 16 bytes
   2132 #endif
   2133 	subs	r9, #0x80
   2134 
   2135 	blo	.Lxts_dec_short
   2136 	b	.Lxts_dec_loop
   2137 
   2138 .align	4
   2139 .Lxts_dec_loop:
   2140 	vldmia	r2, {q5}	@ load XTS magic
   2141 	vshr.s64	q6, q8, #63
   2142 	mov	r0, sp
   2143 	vand	q6, q6, q5
   2144 	vadd.u64	q9, q8, q8
   2145 	vst1.64	{q8}, [r0,:128]!
   2146 	vswp	d13,d12
   2147 	vshr.s64	q7, q9, #63
   2148 	veor	q9, q9, q6
   2149 	vand	q7, q7, q5
   2150 	vadd.u64	q10, q9, q9
   2151 	vst1.64	{q9}, [r0,:128]!
   2152 	vswp	d15,d14
   2153 	vshr.s64	q6, q10, #63
   2154 	veor	q10, q10, q7
   2155 	vand	q6, q6, q5
   2156 	vld1.8	{q0}, [r7]!
   2157 	vadd.u64	q11, q10, q10
   2158 	vst1.64	{q10}, [r0,:128]!
   2159 	vswp	d13,d12
   2160 	vshr.s64	q7, q11, #63
   2161 	veor	q11, q11, q6
   2162 	vand	q7, q7, q5
   2163 	vld1.8	{q1}, [r7]!
   2164 	veor	q0, q0, q8
   2165 	vadd.u64	q12, q11, q11
   2166 	vst1.64	{q11}, [r0,:128]!
   2167 	vswp	d15,d14
   2168 	vshr.s64	q6, q12, #63
   2169 	veor	q12, q12, q7
   2170 	vand	q6, q6, q5
   2171 	vld1.8	{q2}, [r7]!
   2172 	veor	q1, q1, q9
   2173 	vadd.u64	q13, q12, q12
   2174 	vst1.64	{q12}, [r0,:128]!
   2175 	vswp	d13,d12
   2176 	vshr.s64	q7, q13, #63
   2177 	veor	q13, q13, q6
   2178 	vand	q7, q7, q5
   2179 	vld1.8	{q3}, [r7]!
   2180 	veor	q2, q2, q10
   2181 	vadd.u64	q14, q13, q13
   2182 	vst1.64	{q13}, [r0,:128]!
   2183 	vswp	d15,d14
   2184 	vshr.s64	q6, q14, #63
   2185 	veor	q14, q14, q7
   2186 	vand	q6, q6, q5
   2187 	vld1.8	{q4}, [r7]!
   2188 	veor	q3, q3, q11
   2189 	vadd.u64	q15, q14, q14
   2190 	vst1.64	{q14}, [r0,:128]!
   2191 	vswp	d13,d12
   2192 	vshr.s64	q7, q15, #63
   2193 	veor	q15, q15, q6
   2194 	vand	q7, q7, q5
   2195 	vld1.8	{q5}, [r7]!
   2196 	veor	q4, q4, q12
   2197 	vadd.u64	q8, q15, q15
   2198 	vst1.64	{q15}, [r0,:128]!
   2199 	vswp	d15,d14
   2200 	veor	q8, q8, q7
   2201 	vst1.64	{q8}, [r0,:128]		@ next round tweak
   2202 
   2203 	vld1.8	{q6,q7}, [r7]!
   2204 	veor	q5, q5, q13
   2205 #ifndef	BSAES_ASM_EXTENDED_KEY
   2206 	add	r4, sp, #0x90			@ pass key schedule
   2207 #else
   2208 	add	r4, r10, #248			@ pass key schedule
   2209 #endif
   2210 	veor	q6, q6, q14
   2211 	mov	r5, r1			@ pass rounds
   2212 	veor	q7, q7, q15
   2213 	mov	r0, sp
   2214 
   2215 	bl	_bsaes_decrypt8
   2216 
   2217 	vld1.64	{q8,q9}, [r0,:128]!
   2218 	vld1.64	{q10,q11}, [r0,:128]!
   2219 	veor	q0, q0, q8
   2220 	vld1.64	{q12,q13}, [r0,:128]!
   2221 	veor	q1, q1, q9
   2222 	veor	q8, q6, q10
   2223 	vst1.8	{q0,q1}, [r8]!
   2224 	veor	q9, q4, q11
   2225 	vld1.64	{q14,q15}, [r0,:128]!
   2226 	veor	q10, q2, q12
   2227 	vst1.8	{q8,q9}, [r8]!
   2228 	veor	q11, q7, q13
   2229 	veor	q12, q3, q14
   2230 	vst1.8	{q10,q11}, [r8]!
   2231 	veor	q13, q5, q15
   2232 	vst1.8	{q12,q13}, [r8]!
   2233 
   2234 	vld1.64	{q8}, [r0,:128]		@ next round tweak
   2235 
   2236 	subs	r9, #0x80
   2237 	bpl	.Lxts_dec_loop
   2238 
   2239 .Lxts_dec_short:
   2240 	adds	r9, #0x70
   2241 	bmi	.Lxts_dec_done
   2242 
   2243 	vldmia	r2, {q5}	@ load XTS magic
   2244 	vshr.s64	q7, q8, #63
   2245 	mov	r0, sp
   2246 	vand	q7, q7, q5
   2247 	vadd.u64	q9, q8, q8
   2248 	vst1.64	{q8}, [r0,:128]!
   2249 	vswp	d15,d14
   2250 	vshr.s64	q6, q9, #63
   2251 	veor	q9, q9, q7
   2252 	vand	q6, q6, q5
   2253 	vadd.u64	q10, q9, q9
   2254 	vst1.64	{q9}, [r0,:128]!
   2255 	vswp	d13,d12
   2256 	vshr.s64	q7, q10, #63
   2257 	veor	q10, q10, q6
   2258 	vand	q7, q7, q5
   2259 	vld1.8	{q0}, [r7]!
   2260 	subs	r9, #0x10
   2261 	bmi	.Lxts_dec_1
   2262 	vadd.u64	q11, q10, q10
   2263 	vst1.64	{q10}, [r0,:128]!
   2264 	vswp	d15,d14
   2265 	vshr.s64	q6, q11, #63
   2266 	veor	q11, q11, q7
   2267 	vand	q6, q6, q5
   2268 	vld1.8	{q1}, [r7]!
   2269 	subs	r9, #0x10
   2270 	bmi	.Lxts_dec_2
   2271 	veor	q0, q0, q8
   2272 	vadd.u64	q12, q11, q11
   2273 	vst1.64	{q11}, [r0,:128]!
   2274 	vswp	d13,d12
   2275 	vshr.s64	q7, q12, #63
   2276 	veor	q12, q12, q6
   2277 	vand	q7, q7, q5
   2278 	vld1.8	{q2}, [r7]!
   2279 	subs	r9, #0x10
   2280 	bmi	.Lxts_dec_3
   2281 	veor	q1, q1, q9
   2282 	vadd.u64	q13, q12, q12
   2283 	vst1.64	{q12}, [r0,:128]!
   2284 	vswp	d15,d14
   2285 	vshr.s64	q6, q13, #63
   2286 	veor	q13, q13, q7
   2287 	vand	q6, q6, q5
   2288 	vld1.8	{q3}, [r7]!
   2289 	subs	r9, #0x10
   2290 	bmi	.Lxts_dec_4
   2291 	veor	q2, q2, q10
   2292 	vadd.u64	q14, q13, q13
   2293 	vst1.64	{q13}, [r0,:128]!
   2294 	vswp	d13,d12
   2295 	vshr.s64	q7, q14, #63
   2296 	veor	q14, q14, q6
   2297 	vand	q7, q7, q5
   2298 	vld1.8	{q4}, [r7]!
   2299 	subs	r9, #0x10
   2300 	bmi	.Lxts_dec_5
   2301 	veor	q3, q3, q11
   2302 	vadd.u64	q15, q14, q14
   2303 	vst1.64	{q14}, [r0,:128]!
   2304 	vswp	d15,d14
   2305 	vshr.s64	q6, q15, #63
   2306 	veor	q15, q15, q7
   2307 	vand	q6, q6, q5
   2308 	vld1.8	{q5}, [r7]!
   2309 	subs	r9, #0x10
   2310 	bmi	.Lxts_dec_6
   2311 	veor	q4, q4, q12
   2312 	sub	r9, #0x10
   2313 	vst1.64	{q15}, [r0,:128]		@ next round tweak
   2314 
   2315 	vld1.8	{q6}, [r7]!
   2316 	veor	q5, q5, q13
   2317 #ifndef	BSAES_ASM_EXTENDED_KEY
   2318 	add	r4, sp, #0x90			@ pass key schedule
   2319 #else
   2320 	add	r4, r10, #248			@ pass key schedule
   2321 #endif
   2322 	veor	q6, q6, q14
   2323 	mov	r5, r1			@ pass rounds
   2324 	mov	r0, sp
   2325 
   2326 	bl	_bsaes_decrypt8
   2327 
   2328 	vld1.64	{q8,q9}, [r0,:128]!
   2329 	vld1.64	{q10,q11}, [r0,:128]!
   2330 	veor	q0, q0, q8
   2331 	vld1.64	{q12,q13}, [r0,:128]!
   2332 	veor	q1, q1, q9
   2333 	veor	q8, q6, q10
   2334 	vst1.8	{q0,q1}, [r8]!
   2335 	veor	q9, q4, q11
   2336 	vld1.64	{q14}, [r0,:128]!
   2337 	veor	q10, q2, q12
   2338 	vst1.8	{q8,q9}, [r8]!
   2339 	veor	q11, q7, q13
   2340 	veor	q12, q3, q14
   2341 	vst1.8	{q10,q11}, [r8]!
   2342 	vst1.8	{q12}, [r8]!
   2343 
   2344 	vld1.64	{q8}, [r0,:128]		@ next round tweak
   2345 	b	.Lxts_dec_done
   2346 .align	4
   2347 .Lxts_dec_6:
   2348 	vst1.64	{q14}, [r0,:128]		@ next round tweak
   2349 
   2350 	veor	q4, q4, q12
   2351 #ifndef	BSAES_ASM_EXTENDED_KEY
   2352 	add	r4, sp, #0x90			@ pass key schedule
   2353 #else
   2354 	add	r4, r10, #248			@ pass key schedule
   2355 #endif
   2356 	veor	q5, q5, q13
   2357 	mov	r5, r1			@ pass rounds
   2358 	mov	r0, sp
   2359 
   2360 	bl	_bsaes_decrypt8
   2361 
   2362 	vld1.64	{q8,q9}, [r0,:128]!
   2363 	vld1.64	{q10,q11}, [r0,:128]!
   2364 	veor	q0, q0, q8
   2365 	vld1.64	{q12,q13}, [r0,:128]!
   2366 	veor	q1, q1, q9
   2367 	veor	q8, q6, q10
   2368 	vst1.8	{q0,q1}, [r8]!
   2369 	veor	q9, q4, q11
   2370 	veor	q10, q2, q12
   2371 	vst1.8	{q8,q9}, [r8]!
   2372 	veor	q11, q7, q13
   2373 	vst1.8	{q10,q11}, [r8]!
   2374 
   2375 	vld1.64	{q8}, [r0,:128]		@ next round tweak
   2376 	b	.Lxts_dec_done
   2377 .align	4
   2378 .Lxts_dec_5:
   2379 	vst1.64	{q13}, [r0,:128]		@ next round tweak
   2380 
   2381 	veor	q3, q3, q11
   2382 #ifndef	BSAES_ASM_EXTENDED_KEY
   2383 	add	r4, sp, #0x90			@ pass key schedule
   2384 #else
   2385 	add	r4, r10, #248			@ pass key schedule
   2386 #endif
   2387 	veor	q4, q4, q12
   2388 	mov	r5, r1			@ pass rounds
   2389 	mov	r0, sp
   2390 
   2391 	bl	_bsaes_decrypt8
   2392 
   2393 	vld1.64	{q8,q9}, [r0,:128]!
   2394 	vld1.64	{q10,q11}, [r0,:128]!
   2395 	veor	q0, q0, q8
   2396 	vld1.64	{q12}, [r0,:128]!
   2397 	veor	q1, q1, q9
   2398 	veor	q8, q6, q10
   2399 	vst1.8	{q0,q1}, [r8]!
   2400 	veor	q9, q4, q11
   2401 	veor	q10, q2, q12
   2402 	vst1.8	{q8,q9}, [r8]!
   2403 	vst1.8	{q10}, [r8]!
   2404 
   2405 	vld1.64	{q8}, [r0,:128]		@ next round tweak
   2406 	b	.Lxts_dec_done
   2407 .align	4
   2408 .Lxts_dec_4:
   2409 	vst1.64	{q12}, [r0,:128]		@ next round tweak
   2410 
   2411 	veor	q2, q2, q10
   2412 #ifndef	BSAES_ASM_EXTENDED_KEY
   2413 	add	r4, sp, #0x90			@ pass key schedule
   2414 #else
   2415 	add	r4, r10, #248			@ pass key schedule
   2416 #endif
   2417 	veor	q3, q3, q11
   2418 	mov	r5, r1			@ pass rounds
   2419 	mov	r0, sp
   2420 
   2421 	bl	_bsaes_decrypt8
   2422 
   2423 	vld1.64	{q8,q9}, [r0,:128]!
   2424 	vld1.64	{q10,q11}, [r0,:128]!
   2425 	veor	q0, q0, q8
   2426 	veor	q1, q1, q9
   2427 	veor	q8, q6, q10
   2428 	vst1.8	{q0,q1}, [r8]!
   2429 	veor	q9, q4, q11
   2430 	vst1.8	{q8,q9}, [r8]!
   2431 
   2432 	vld1.64	{q8}, [r0,:128]		@ next round tweak
   2433 	b	.Lxts_dec_done
   2434 .align	4
   2435 .Lxts_dec_3:
   2436 	vst1.64	{q11}, [r0,:128]		@ next round tweak
   2437 
   2438 	veor	q1, q1, q9
   2439 #ifndef	BSAES_ASM_EXTENDED_KEY
   2440 	add	r4, sp, #0x90			@ pass key schedule
   2441 #else
   2442 	add	r4, r10, #248			@ pass key schedule
   2443 #endif
   2444 	veor	q2, q2, q10
   2445 	mov	r5, r1			@ pass rounds
   2446 	mov	r0, sp
   2447 
   2448 	bl	_bsaes_decrypt8
   2449 
   2450 	vld1.64	{q8,q9}, [r0,:128]!
   2451 	vld1.64	{q10}, [r0,:128]!
   2452 	veor	q0, q0, q8
   2453 	veor	q1, q1, q9
   2454 	veor	q8, q6, q10
   2455 	vst1.8	{q0,q1}, [r8]!
   2456 	vst1.8	{q8}, [r8]!
   2457 
   2458 	vld1.64	{q8}, [r0,:128]		@ next round tweak
   2459 	b	.Lxts_dec_done
   2460 .align	4
   2461 .Lxts_dec_2:
   2462 	vst1.64	{q10}, [r0,:128]		@ next round tweak
   2463 
   2464 	veor	q0, q0, q8
   2465 #ifndef	BSAES_ASM_EXTENDED_KEY
   2466 	add	r4, sp, #0x90			@ pass key schedule
   2467 #else
   2468 	add	r4, r10, #248			@ pass key schedule
   2469 #endif
   2470 	veor	q1, q1, q9
   2471 	mov	r5, r1			@ pass rounds
   2472 	mov	r0, sp
   2473 
   2474 	bl	_bsaes_decrypt8
   2475 
   2476 	vld1.64	{q8,q9}, [r0,:128]!
   2477 	veor	q0, q0, q8
   2478 	veor	q1, q1, q9
   2479 	vst1.8	{q0,q1}, [r8]!
   2480 
   2481 	vld1.64	{q8}, [r0,:128]		@ next round tweak
   2482 	b	.Lxts_dec_done
   2483 .align	4
   2484 .Lxts_dec_1:
   2485 	mov	r0, sp
   2486 	veor	q0, q8
   2487 	mov	r1, sp
   2488 	vst1.8	{q0}, [sp,:128]
   2489 	mov	r2, r10
   2490 	mov	r4, r3				@ preserve fp
   2491 	mov	r5, r2			@ preserve magic
   2492 
   2493 	bl	AES_decrypt
   2494 
   2495 	vld1.8	{q0}, [sp,:128]
   2496 	veor	q0, q0, q8
   2497 	vst1.8	{q0}, [r8]!
   2498 	mov	r3, r4
   2499 	mov	r2, r5
   2500 
   2501 	vmov	q8, q9		@ next round tweak
   2502 
   2503 .Lxts_dec_done:
   2504 #ifndef	XTS_CHAIN_TWEAK
   2505 	adds	r9, #0x10
   2506 	beq	.Lxts_dec_ret
   2507 
   2508 	@ calculate one round of extra tweak for the stolen ciphertext
   2509 	vldmia	r2, {q5}
   2510 	vshr.s64	q6, q8, #63
   2511 	vand	q6, q6, q5
   2512 	vadd.u64	q9, q8, q8
   2513 	vswp	d13,d12
   2514 	veor	q9, q9, q6
   2515 
   2516 	@ perform the final decryption with the last tweak value
   2517 	vld1.8	{q0}, [r7]!
   2518 	mov	r0, sp
   2519 	veor	q0, q0, q9
   2520 	mov	r1, sp
   2521 	vst1.8	{q0}, [sp,:128]
   2522 	mov	r2, r10
   2523 	mov	r4, r3			@ preserve fp
   2524 
   2525 	bl	AES_decrypt
   2526 
   2527 	vld1.8	{q0}, [sp,:128]
   2528 	veor	q0, q0, q9
   2529 	vst1.8	{q0}, [r8]
   2530 
   2531 	mov	r6, r8
   2532 .Lxts_dec_steal:
   2533 	ldrb	r1, [r8]
   2534 	ldrb	r0, [r7], #1
   2535 	strb	r1, [r8, #0x10]
   2536 	strb	r0, [r8], #1
   2537 
   2538 	subs	r9, #1
   2539 	bhi	.Lxts_dec_steal
   2540 
   2541 	vld1.8	{q0}, [r6]
   2542 	mov	r0, sp
   2543 	veor	q0, q8
   2544 	mov	r1, sp
   2545 	vst1.8	{q0}, [sp,:128]
   2546 	mov	r2, r10
   2547 
   2548 	bl	AES_decrypt
   2549 
   2550 	vld1.8	{q0}, [sp,:128]
   2551 	veor	q0, q0, q8
   2552 	vst1.8	{q0}, [r6]
   2553 	mov	r3, r4
   2554 #endif
   2555 
   2556 .Lxts_dec_ret:
   2557 	bic	r0, r3, #0xf
   2558 	vmov.i32	q0, #0
   2559 	vmov.i32	q1, #0
   2560 #ifdef	XTS_CHAIN_TWEAK
   2561 	ldr	r1, [r3, #0x20+VFP_ABI_FRAME]	@ chain tweak
   2562 #endif
   2563 .Lxts_dec_bzero:@ wipe key schedule [if any]
   2564 	vstmia	sp!, {q0,q1}
   2565 	cmp	sp, r0
   2566 	bne	.Lxts_dec_bzero
   2567 
   2568 	mov	sp, r3
   2569 #ifdef	XTS_CHAIN_TWEAK
   2570 	vst1.8	{q8}, [r1]
   2571 #endif
   2572 	VFP_ABI_POP
   2573 	ldmia	sp!, {r4,r5,r6,r7,r8,r9,r10, pc}	@ return
   2574 
   2575 .size	bsaes_xts_decrypt,.-bsaes_xts_decrypt
   2576 #endif
   2577 #endif
   2578