3 # ====================================================================
4 # Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
5 # project. The module is, however, dual licensed under OpenSSL and
6 # CRYPTOGAMS licenses depending on where you obtain it. For further
7 # details see http://www.openssl.org/~appro/cryptogams/.
9 # Specific modes and adaptation for Linux kernel by Ard Biesheuvel
10 # <ard.biesheuvel@linaro.org>. Permission to use under GPL terms is
12 # ====================================================================
14 # Bit-sliced AES for ARM NEON
18 # This implementation is direct adaptation of bsaes-x86_64 module for
19 # ARM NEON. Except that this module is endian-neutral [in sense that
20 # it can be compiled for either endianness] by courtesy of vld1.8's
21 # neutrality. Initial version doesn't implement interface to OpenSSL,
22 # only low-level primitives and unsupported entry points, just enough
23 # to collect performance results, which for Cortex-A8 core are:
25 # encrypt 19.5 cycles per byte processed with 128-bit key
26 # decrypt 24.0 cycles per byte processed with 128-bit key
27 # key conv. 440 cycles per 128-bit key/0.18 of 8x block
29 # Snapdragon S4 encrypts byte in 17.6 cycles and decrypts in 22.6,
30 # which is [much] worse than anticipated (for further details see
31 # http://www.openssl.org/~appro/Snapdragon-S4.html).
33 # Cortex-A15 manages in 14.2/19.6 cycles [when integer-only code
34 # manages in 20.0 cycles].
36 # When comparing to x86_64 results keep in mind that NEON unit is
37 # [mostly] single-issue and thus can't [fully] benefit from
38 # instruction-level parallelism. And when comparing to aes-armv4
39 # results keep in mind key schedule conversion overhead (see
40 # bsaes-x86_64.pl for further details)...
46 # Add CBC, CTR and XTS subroutines, adapt for kernel use.
48 # <ard.biesheuvel@linaro.org>
50 while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
51 open STDOUT,">$output";
53 my ($inp,$out,$len,$key)=("r0","r1","r2","r3");
54 my @XMM=map("q$_",(0..15));
57 my ($key,$rounds,$const)=("r4","r5","r6");
59 sub Dlo() { shift=~m|q([1]?[0-9])|?"d".($1*2):""; }
60 sub Dhi() { shift=~m|q([1]?[0-9])|?"d".($1*2+1):""; }
63 # input in lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
64 # output in lsb > [b0, b1, b4, b6, b3, b7, b2, b5] < msb
69 &Inv_GF256 (@b[6,5,0,3,7,1,4,2],@t,@s);
70 &OutBasisChange (@b[7,1,4,2,6,5,0,3]);
74 # input in lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
75 # output in lsb > [b6, b5, b0, b3, b7, b1, b4, b2] < msb
78 veor @b[2], @b[2], @b[1]
79 veor @b[5], @b[5], @b[6]
80 veor @b[3], @b[3], @b[0]
81 veor @b[6], @b[6], @b[2]
82 veor @b[5], @b[5], @b[0]
84 veor @b[6], @b[6], @b[3]
85 veor @b[3], @b[3], @b[7]
86 veor @b[7], @b[7], @b[5]
87 veor @b[3], @b[3], @b[4]
88 veor @b[4], @b[4], @b[5]
90 veor @b[2], @b[2], @b[7]
91 veor @b[3], @b[3], @b[1]
92 veor @b[1], @b[1], @b[5]
97 # input in lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
98 # output in lsb > [b6, b1, b2, b4, b7, b0, b3, b5] < msb
101 veor @b[0], @b[0], @b[6]
102 veor @b[1], @b[1], @b[4]
103 veor @b[4], @b[4], @b[6]
104 veor @b[2], @b[2], @b[0]
105 veor @b[6], @b[6], @b[1]
107 veor @b[1], @b[1], @b[5]
108 veor @b[5], @b[5], @b[3]
109 veor @b[3], @b[3], @b[7]
110 veor @b[7], @b[7], @b[5]
111 veor @b[2], @b[2], @b[5]
113 veor @b[4], @b[4], @b[7]
118 # input in lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
119 # output in lsb > [b0, b1, b6, b4, b2, b7, b3, b5] < msb
123 &InvInBasisChange (@b);
124 &Inv_GF256 (@b[5,1,2,6,3,7,0,4],@t,@s);
125 &InvOutBasisChange (@b[3,7,0,4,5,1,2,6]);
128 sub InvInBasisChange { # OutBasisChange in reverse (with twist)
129 my @b=@_[5,1,2,6,3,7,0,4];
131 veor @b[1], @b[1], @b[7]
132 veor @b[4], @b[4], @b[7]
134 veor @b[7], @b[7], @b[5]
135 veor @b[1], @b[1], @b[3]
136 veor @b[2], @b[2], @b[5]
137 veor @b[3], @b[3], @b[7]
139 veor @b[6], @b[6], @b[1]
140 veor @b[2], @b[2], @b[0]
141 veor @b[5], @b[5], @b[3]
142 veor @b[4], @b[4], @b[6]
143 veor @b[0], @b[0], @b[6]
144 veor @b[1], @b[1], @b[4]
148 sub InvOutBasisChange { # InBasisChange in reverse
149 my @b=@_[2,5,7,3,6,1,0,4];
151 veor @b[1], @b[1], @b[5]
152 veor @b[2], @b[2], @b[7]
154 veor @b[3], @b[3], @b[1]
155 veor @b[4], @b[4], @b[5]
156 veor @b[7], @b[7], @b[5]
157 veor @b[3], @b[3], @b[4]
158 veor @b[5], @b[5], @b[0]
159 veor @b[3], @b[3], @b[7]
160 veor @b[6], @b[6], @b[2]
161 veor @b[2], @b[2], @b[1]
162 veor @b[6], @b[6], @b[3]
164 veor @b[3], @b[3], @b[0]
165 veor @b[5], @b[5], @b[6]
170 #;*************************************************************
171 #;* Mul_GF4: Input x0-x1,y0-y1 Output x0-x1 Temp t0 (8) *
172 #;*************************************************************
173 my ($x0,$x1,$y0,$y1,$t0,$t1)=@_;
185 sub Mul_GF4_N { # not used, see next subroutine
186 # multiply and scale by N
187 my ($x0,$x1,$y0,$y1,$t0)=@_;
200 # interleaved Mul_GF4_N and Mul_GF4
201 my ($x0,$x1,$y0,$y1,$t0,
202 $x2,$x3,$y2,$y3,$t1)=@_;
225 veor @t[0], @x[0], @x[2]
226 veor @t[1], @x[1], @x[3]
228 &Mul_GF4 (@x[0], @x[1], @y[0], @y[1], @t[2..3]);
230 veor @y[0], @y[0], @y[2]
231 veor @y[1], @y[1], @y[3]
233 Mul_GF4_N_GF4 (@t[0], @t[1], @y[0], @y[1], @t[3],
234 @x[2], @x[3], @y[2], @y[3], @t[2]);
236 veor @x[0], @x[0], @t[0]
237 veor @x[2], @x[2], @t[0]
238 veor @x[1], @x[1], @t[1]
239 veor @x[3], @x[3], @t[1]
241 veor @t[0], @x[4], @x[6]
242 veor @t[1], @x[5], @x[7]
244 &Mul_GF4_N_GF4 (@t[0], @t[1], @y[0], @y[1], @t[3],
245 @x[6], @x[7], @y[2], @y[3], @t[2]);
247 veor @y[0], @y[0], @y[2]
248 veor @y[1], @y[1], @y[3]
250 &Mul_GF4 (@x[4], @x[5], @y[0], @y[1], @t[2..3]);
252 veor @x[4], @x[4], @t[0]
253 veor @x[6], @x[6], @t[0]
254 veor @x[5], @x[5], @t[1]
255 veor @x[7], @x[7], @t[1]
259 #;********************************************************************
260 #;* Inv_GF256: Input x0-x7 Output x0-x7 Temp t0-t3,s0-s3 (144) *
261 #;********************************************************************
265 # direct optimizations from hardware
267 veor @t[3], @x[4], @x[6]
268 veor @t[2], @x[5], @x[7]
269 veor @t[1], @x[1], @x[3]
270 veor @s[1], @x[7], @x[6]
272 veor @s[0], @x[0], @x[2]
274 vorr @t[2], @t[2], @t[1]
275 veor @s[3], @t[3], @t[0]
276 vand @s[2], @t[3], @s[0]
277 vorr @t[3], @t[3], @s[0]
278 veor @s[0], @s[0], @t[1]
279 vand @t[0], @t[0], @t[1]
280 veor @t[1], @x[3], @x[2]
281 vand @s[3], @s[3], @s[0]
282 vand @s[1], @s[1], @t[1]
283 veor @t[1], @x[4], @x[5]
284 veor @s[0], @x[1], @x[0]
285 veor @t[3], @t[3], @s[1]
286 veor @t[2], @t[2], @s[1]
287 vand @s[1], @t[1], @s[0]
288 vorr @t[1], @t[1], @s[0]
289 veor @t[3], @t[3], @s[3]
290 veor @t[0], @t[0], @s[1]
291 veor @t[2], @t[2], @s[2]
292 veor @t[1], @t[1], @s[3]
293 veor @t[0], @t[0], @s[2]
294 vand @s[0], @x[7], @x[3]
295 veor @t[1], @t[1], @s[2]
296 vand @s[1], @x[6], @x[2]
297 vand @s[2], @x[5], @x[1]
298 vorr @s[3], @x[4], @x[0]
299 veor @t[3], @t[3], @s[0]
300 veor @t[1], @t[1], @s[2]
301 veor @t[0], @t[0], @s[3]
302 veor @t[2], @t[2], @s[1]
304 @ Inv_GF16 \t0, \t1, \t2, \t3, \s0, \s1, \s2, \s3
306 @ new smaller inversion
308 vand @s[2], @t[3], @t[1]
311 veor @s[1], @t[2], @s[2]
312 veor @s[3], @t[0], @s[2]
313 veor @s[2], @t[0], @s[2] @ @s[2]=@s[3]
315 vbsl @s[1], @t[1], @t[0]
316 vbsl @s[3], @t[3], @t[2]
317 veor @t[3], @t[3], @t[2]
319 vbsl @s[0], @s[1], @s[2]
320 vbsl @t[0], @s[2], @s[1]
322 vand @s[2], @s[0], @s[3]
323 veor @t[1], @t[1], @t[0]
325 veor @s[2], @s[2], @t[3]
327 # output in s3, s2, s1, t1
329 # Mul_GF16_2 \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \t2, \t3, \t0, \t1, \s0, \s1, \s2, \s3
331 # Mul_GF16_2 \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \s3, \s2, \s1, \t1, \s0, \t0, \t2, \t3
332 &Mul_GF16_2(@x,@s[3,2,1],@t[1],@s[0],@t[0,2,3]);
334 ### output msb > [x3,x2,x1,x0,x7,x6,x5,x4] < lsb
337 # AES linear components
344 vldmia $key!, {@t[0]-@t[3]}
345 veor @t[0], @t[0], @x[0]
346 veor @t[1], @t[1], @x[1]
347 vtbl.8 `&Dlo(@x[0])`, {@t[0]}, `&Dlo($mask)`
348 vtbl.8 `&Dhi(@x[0])`, {@t[0]}, `&Dhi($mask)`
349 vldmia $key!, {@t[0]}
350 veor @t[2], @t[2], @x[2]
351 vtbl.8 `&Dlo(@x[1])`, {@t[1]}, `&Dlo($mask)`
352 vtbl.8 `&Dhi(@x[1])`, {@t[1]}, `&Dhi($mask)`
353 vldmia $key!, {@t[1]}
354 veor @t[3], @t[3], @x[3]
355 vtbl.8 `&Dlo(@x[2])`, {@t[2]}, `&Dlo($mask)`
356 vtbl.8 `&Dhi(@x[2])`, {@t[2]}, `&Dhi($mask)`
357 vldmia $key!, {@t[2]}
358 vtbl.8 `&Dlo(@x[3])`, {@t[3]}, `&Dlo($mask)`
359 vtbl.8 `&Dhi(@x[3])`, {@t[3]}, `&Dhi($mask)`
360 vldmia $key!, {@t[3]}
361 veor @t[0], @t[0], @x[4]
362 veor @t[1], @t[1], @x[5]
363 vtbl.8 `&Dlo(@x[4])`, {@t[0]}, `&Dlo($mask)`
364 vtbl.8 `&Dhi(@x[4])`, {@t[0]}, `&Dhi($mask)`
365 veor @t[2], @t[2], @x[6]
366 vtbl.8 `&Dlo(@x[5])`, {@t[1]}, `&Dlo($mask)`
367 vtbl.8 `&Dhi(@x[5])`, {@t[1]}, `&Dhi($mask)`
368 veor @t[3], @t[3], @x[7]
369 vtbl.8 `&Dlo(@x[6])`, {@t[2]}, `&Dlo($mask)`
370 vtbl.8 `&Dhi(@x[6])`, {@t[2]}, `&Dhi($mask)`
371 vtbl.8 `&Dlo(@x[7])`, {@t[3]}, `&Dlo($mask)`
372 vtbl.8 `&Dhi(@x[7])`, {@t[3]}, `&Dhi($mask)`
377 # modified to emit output in order suitable for feeding back to aesenc[last]
381 vext.8 @t[0], @x[0], @x[0], #12 @ x0 <<< 32
382 vext.8 @t[1], @x[1], @x[1], #12
383 veor @x[0], @x[0], @t[0] @ x0 ^ (x0 <<< 32)
384 vext.8 @t[2], @x[2], @x[2], #12
385 veor @x[1], @x[1], @t[1]
386 vext.8 @t[3], @x[3], @x[3], #12
387 veor @x[2], @x[2], @t[2]
388 vext.8 @t[4], @x[4], @x[4], #12
389 veor @x[3], @x[3], @t[3]
390 vext.8 @t[5], @x[5], @x[5], #12
391 veor @x[4], @x[4], @t[4]
392 vext.8 @t[6], @x[6], @x[6], #12
393 veor @x[5], @x[5], @t[5]
394 vext.8 @t[7], @x[7], @x[7], #12
395 veor @x[6], @x[6], @t[6]
397 veor @t[1], @t[1], @x[0]
398 veor @x[7], @x[7], @t[7]
399 vext.8 @x[0], @x[0], @x[0], #8 @ (x0 ^ (x0 <<< 32)) <<< 64)
400 veor @t[2], @t[2], @x[1]
401 veor @t[0], @t[0], @x[7]
402 veor @t[1], @t[1], @x[7]
403 vext.8 @x[1], @x[1], @x[1], #8
404 veor @t[5], @t[5], @x[4]
405 veor @x[0], @x[0], @t[0]
406 veor @t[6], @t[6], @x[5]
407 veor @x[1], @x[1], @t[1]
408 vext.8 @t[0], @x[4], @x[4], #8
409 veor @t[4], @t[4], @x[3]
410 vext.8 @t[1], @x[5], @x[5], #8
411 veor @t[7], @t[7], @x[6]
412 vext.8 @x[4], @x[3], @x[3], #8
413 veor @t[3], @t[3], @x[2]
414 vext.8 @x[5], @x[7], @x[7], #8
415 veor @t[4], @t[4], @x[7]
416 vext.8 @x[3], @x[6], @x[6], #8
417 veor @t[3], @t[3], @x[7]
418 vext.8 @x[6], @x[2], @x[2], #8
419 veor @x[7], @t[1], @t[5]
420 veor @x[2], @t[0], @t[4]
422 veor @x[4], @x[4], @t[3]
423 veor @x[5], @x[5], @t[7]
424 veor @x[3], @x[3], @t[6]
426 veor @x[6], @x[6], @t[2]
436 @ multiplication by 0x0e
437 vext.8 @t[7], @x[7], @x[7], #12
439 veor @x[2], @x[2], @x[5] @ 2 5
440 veor @x[7], @x[7], @x[5] @ 7 5
441 vext.8 @t[0], @x[0], @x[0], #12
443 veor @x[5], @x[5], @x[0] @ 5 0 [1]
444 veor @x[0], @x[0], @x[1] @ 0 1
445 vext.8 @t[1], @x[1], @x[1], #12
446 veor @x[1], @x[1], @x[2] @ 1 25
447 veor @x[0], @x[0], @x[6] @ 01 6 [2]
448 vext.8 @t[3], @x[3], @x[3], #12
449 veor @x[1], @x[1], @x[3] @ 125 3 [4]
450 veor @x[2], @x[2], @x[0] @ 25 016 [3]
451 veor @x[3], @x[3], @x[7] @ 3 75
452 veor @x[7], @x[7], @x[6] @ 75 6 [0]
453 vext.8 @t[6], @x[6], @x[6], #12
455 veor @x[6], @x[6], @x[4] @ 6 4
456 veor @x[4], @x[4], @x[3] @ 4 375 [6]
457 veor @x[3], @x[3], @x[7] @ 375 756=36
458 veor @x[6], @x[6], @t[5] @ 64 5 [7]
459 veor @x[3], @x[3], @t[2] @ 36 2
460 vext.8 @t[5], @t[5], @t[5], #12
461 veor @x[3], @x[3], @t[4] @ 362 4 [5]
463 my @y = @x[7,5,0,2,1,3,4,6];
465 @ multiplication by 0x0b
466 veor @y[1], @y[1], @y[0]
467 veor @y[0], @y[0], @t[0]
468 vext.8 @t[2], @t[2], @t[2], #12
469 veor @y[1], @y[1], @t[1]
470 veor @y[0], @y[0], @t[5]
471 vext.8 @t[4], @t[4], @t[4], #12
472 veor @y[1], @y[1], @t[6]
473 veor @y[0], @y[0], @t[7]
474 veor @t[7], @t[7], @t[6] @ clobber t[7]
476 veor @y[3], @y[3], @t[0]
477 veor @y[1], @y[1], @y[0]
478 vext.8 @t[0], @t[0], @t[0], #12
479 veor @y[2], @y[2], @t[1]
480 veor @y[4], @y[4], @t[1]
481 vext.8 @t[1], @t[1], @t[1], #12
482 veor @y[2], @y[2], @t[2]
483 veor @y[3], @y[3], @t[2]
484 veor @y[5], @y[5], @t[2]
485 veor @y[2], @y[2], @t[7]
486 vext.8 @t[2], @t[2], @t[2], #12
487 veor @y[3], @y[3], @t[3]
488 veor @y[6], @y[6], @t[3]
489 veor @y[4], @y[4], @t[3]
490 veor @y[7], @y[7], @t[4]
491 vext.8 @t[3], @t[3], @t[3], #12
492 veor @y[5], @y[5], @t[4]
493 veor @y[7], @y[7], @t[7]
494 veor @t[7], @t[7], @t[5] @ clobber t[7] even more
495 veor @y[3], @y[3], @t[5]
496 veor @y[4], @y[4], @t[4]
498 veor @y[5], @y[5], @t[7]
499 vext.8 @t[4], @t[4], @t[4], #12
500 veor @y[6], @y[6], @t[7]
501 veor @y[4], @y[4], @t[7]
503 veor @t[7], @t[7], @t[5]
504 vext.8 @t[5], @t[5], @t[5], #12
506 @ multiplication by 0x0d
507 veor @y[4], @y[4], @y[7]
508 veor @t[7], @t[7], @t[6] @ restore t[7]
509 veor @y[7], @y[7], @t[4]
510 vext.8 @t[6], @t[6], @t[6], #12
511 veor @y[2], @y[2], @t[0]
512 veor @y[7], @y[7], @t[5]
513 vext.8 @t[7], @t[7], @t[7], #12
514 veor @y[2], @y[2], @t[2]
516 veor @y[3], @y[3], @y[1]
517 veor @y[1], @y[1], @t[1]
518 veor @y[0], @y[0], @t[0]
519 veor @y[3], @y[3], @t[0]
520 veor @y[1], @y[1], @t[5]
521 veor @y[0], @y[0], @t[5]
522 vext.8 @t[0], @t[0], @t[0], #12
523 veor @y[1], @y[1], @t[7]
524 veor @y[0], @y[0], @t[6]
525 veor @y[3], @y[3], @y[1]
526 veor @y[4], @y[4], @t[1]
527 vext.8 @t[1], @t[1], @t[1], #12
529 veor @y[7], @y[7], @t[7]
530 veor @y[4], @y[4], @t[2]
531 veor @y[5], @y[5], @t[2]
532 veor @y[2], @y[2], @t[6]
533 veor @t[6], @t[6], @t[3] @ clobber t[6]
534 vext.8 @t[2], @t[2], @t[2], #12
535 veor @y[4], @y[4], @y[7]
536 veor @y[3], @y[3], @t[6]
538 veor @y[6], @y[6], @t[6]
539 veor @y[5], @y[5], @t[5]
540 vext.8 @t[5], @t[5], @t[5], #12
541 veor @y[6], @y[6], @t[4]
542 vext.8 @t[4], @t[4], @t[4], #12
543 veor @y[5], @y[5], @t[6]
544 veor @y[6], @y[6], @t[7]
545 vext.8 @t[7], @t[7], @t[7], #12
546 veor @t[6], @t[6], @t[3] @ restore t[6]
547 vext.8 @t[3], @t[3], @t[3], #12
549 @ multiplication by 0x09
550 veor @y[4], @y[4], @y[1]
551 veor @t[1], @t[1], @y[1] @ t[1]=y[1]
552 veor @t[0], @t[0], @t[5] @ clobber t[0]
553 vext.8 @t[6], @t[6], @t[6], #12
554 veor @t[1], @t[1], @t[5]
555 veor @y[3], @y[3], @t[0]
556 veor @t[0], @t[0], @y[0] @ t[0]=y[0]
557 veor @t[1], @t[1], @t[6]
558 veor @t[6], @t[6], @t[7] @ clobber t[6]
559 veor @y[4], @y[4], @t[1]
560 veor @y[7], @y[7], @t[4]
561 veor @y[6], @y[6], @t[3]
562 veor @y[5], @y[5], @t[2]
563 veor @t[4], @t[4], @y[4] @ t[4]=y[4]
564 veor @t[3], @t[3], @y[3] @ t[3]=y[3]
565 veor @t[5], @t[5], @y[5] @ t[5]=y[5]
566 veor @t[2], @t[2], @y[2] @ t[2]=y[2]
567 veor @t[3], @t[3], @t[7]
568 veor @XMM[5], @t[5], @t[6]
569 veor @XMM[6], @t[6], @y[6] @ t[6]=y[6]
570 veor @XMM[2], @t[2], @t[6]
571 veor @XMM[7], @t[7], @y[7] @ t[7]=y[7]
575 @ vmov @XMM[2], @t[2]
578 @ vmov @XMM[5], @t[5]
579 @ vmov @XMM[6], @t[6]
580 @ vmov @XMM[7], @t[7]
585 my ($a,$b,$n,$mask,$t)=@_;
596 my ($a0,$b0,$a1,$b1,$n,$mask,$t0,$t1)=@_;
598 vshr.u64 $t0, $b0, #$n
599 vshr.u64 $t1, $b1, #$n
605 vshl.u64 $t0, $t0, #$n
607 vshl.u64 $t1, $t1, #$n
614 my @x=reverse(@_[0..7]);
615 my ($t0,$t1,$t2,$t3)=@_[8..11];
617 vmov.i8 $t0,#0x55 @ compose .LBS0
618 vmov.i8 $t1,#0x33 @ compose .LBS1
620 &swapmove2x(@x[0,1,2,3],1,$t0,$t2,$t3);
621 &swapmove2x(@x[4,5,6,7],1,$t0,$t2,$t3);
623 vmov.i8 $t0,#0x0f @ compose .LBS2
625 &swapmove2x(@x[0,2,1,3],2,$t1,$t2,$t3);
626 &swapmove2x(@x[4,6,5,7],2,$t1,$t2,$t3);
628 &swapmove2x(@x[0,4,1,5],4,$t0,$t2,$t3);
629 &swapmove2x(@x[2,6,3,7],4,$t0,$t2,$t3);
634 # include "arm_arch.h"
636 # define VFP_ABI_PUSH vstmdb sp!,{d8-d15}
637 # define VFP_ABI_POP vldmia sp!,{d8-d15}
638 # define VFP_ABI_FRAME 0x40
640 # define VFP_ABI_PUSH
642 # define VFP_ABI_FRAME 0
643 # define BSAES_ASM_EXTENDED_KEY
644 # define XTS_CHAIN_TWEAK
645 # define __ARM_ARCH__ __LINUX_ARM_ARCH__
654 .syntax unified @ ARMv7-capable assembler is expected to handle this
657 .type _bsaes_decrypt8,%function
660 adr $const,_bsaes_decrypt8
661 vldmia $key!, {@XMM[9]} @ round 0 key
662 add $const,$const,#.LM0ISR-_bsaes_decrypt8
664 vldmia $const!, {@XMM[8]} @ .LM0ISR
665 veor @XMM[10], @XMM[0], @XMM[9] @ xor with round0 key
666 veor @XMM[11], @XMM[1], @XMM[9]
667 vtbl.8 `&Dlo(@XMM[0])`, {@XMM[10]}, `&Dlo(@XMM[8])`
668 vtbl.8 `&Dhi(@XMM[0])`, {@XMM[10]}, `&Dhi(@XMM[8])`
669 veor @XMM[12], @XMM[2], @XMM[9]
670 vtbl.8 `&Dlo(@XMM[1])`, {@XMM[11]}, `&Dlo(@XMM[8])`
671 vtbl.8 `&Dhi(@XMM[1])`, {@XMM[11]}, `&Dhi(@XMM[8])`
672 veor @XMM[13], @XMM[3], @XMM[9]
673 vtbl.8 `&Dlo(@XMM[2])`, {@XMM[12]}, `&Dlo(@XMM[8])`
674 vtbl.8 `&Dhi(@XMM[2])`, {@XMM[12]}, `&Dhi(@XMM[8])`
675 veor @XMM[14], @XMM[4], @XMM[9]
676 vtbl.8 `&Dlo(@XMM[3])`, {@XMM[13]}, `&Dlo(@XMM[8])`
677 vtbl.8 `&Dhi(@XMM[3])`, {@XMM[13]}, `&Dhi(@XMM[8])`
678 veor @XMM[15], @XMM[5], @XMM[9]
679 vtbl.8 `&Dlo(@XMM[4])`, {@XMM[14]}, `&Dlo(@XMM[8])`
680 vtbl.8 `&Dhi(@XMM[4])`, {@XMM[14]}, `&Dhi(@XMM[8])`
681 veor @XMM[10], @XMM[6], @XMM[9]
682 vtbl.8 `&Dlo(@XMM[5])`, {@XMM[15]}, `&Dlo(@XMM[8])`
683 vtbl.8 `&Dhi(@XMM[5])`, {@XMM[15]}, `&Dhi(@XMM[8])`
684 veor @XMM[11], @XMM[7], @XMM[9]
685 vtbl.8 `&Dlo(@XMM[6])`, {@XMM[10]}, `&Dlo(@XMM[8])`
686 vtbl.8 `&Dhi(@XMM[6])`, {@XMM[10]}, `&Dhi(@XMM[8])`
687 vtbl.8 `&Dlo(@XMM[7])`, {@XMM[11]}, `&Dlo(@XMM[8])`
688 vtbl.8 `&Dhi(@XMM[7])`, {@XMM[11]}, `&Dhi(@XMM[8])`
690 &bitslice (@XMM[0..7, 8..11]);
692 sub $rounds,$rounds,#1
697 &ShiftRows (@XMM[0..7, 8..12]);
698 $code.=".Ldec_sbox:\n";
699 &InvSbox (@XMM[0..7, 8..15]);
701 subs $rounds,$rounds,#1
704 &InvMixColumns (@XMM[0,1,6,4,2,7,3,5, 8..15]);
706 vldmia $const, {@XMM[12]} @ .LISR
707 ite eq @ Thumb2 thing, sanity check in ARM
708 addeq $const,$const,#0x10
710 vldmia $const, {@XMM[12]} @ .LISRM0
715 &bitslice (@XMM[0,1,6,4,2,7,3,5, 8..11]);
717 vldmia $key, {@XMM[8]} @ last round key
718 veor @XMM[6], @XMM[6], @XMM[8]
719 veor @XMM[4], @XMM[4], @XMM[8]
720 veor @XMM[2], @XMM[2], @XMM[8]
721 veor @XMM[7], @XMM[7], @XMM[8]
722 veor @XMM[3], @XMM[3], @XMM[8]
723 veor @XMM[5], @XMM[5], @XMM[8]
724 veor @XMM[0], @XMM[0], @XMM[8]
725 veor @XMM[1], @XMM[1], @XMM[8]
727 .size _bsaes_decrypt8,.-_bsaes_decrypt8
729 .type _bsaes_const,%object
732 .LM0ISR: @ InvShiftRows constants
733 .quad 0x0a0e0206070b0f03, 0x0004080c0d010509
735 .quad 0x0504070602010003, 0x0f0e0d0c080b0a09
737 .quad 0x01040b0e0205080f, 0x0306090c00070a0d
738 .LM0SR: @ ShiftRows constants
739 .quad 0x0a0e02060f03070b, 0x0004080c05090d01
741 .quad 0x0504070600030201, 0x0f0e0d0c0a09080b
743 .quad 0x0304090e00050a0f, 0x01060b0c0207080d
745 .quad 0x02060a0e03070b0f, 0x0004080c0105090d
747 .quad 0x090d01050c000408, 0x03070b0f060a0e02
748 .asciz "Bit-sliced AES for NEON, CRYPTOGAMS by <appro\@openssl.org>"
750 .size _bsaes_const,.-_bsaes_const
752 .type _bsaes_encrypt8,%function
755 adr $const,_bsaes_encrypt8
756 vldmia $key!, {@XMM[9]} @ round 0 key
757 sub $const,$const,#_bsaes_encrypt8-.LM0SR
759 vldmia $const!, {@XMM[8]} @ .LM0SR
761 veor @XMM[10], @XMM[0], @XMM[9] @ xor with round0 key
762 veor @XMM[11], @XMM[1], @XMM[9]
763 vtbl.8 `&Dlo(@XMM[0])`, {@XMM[10]}, `&Dlo(@XMM[8])`
764 vtbl.8 `&Dhi(@XMM[0])`, {@XMM[10]}, `&Dhi(@XMM[8])`
765 veor @XMM[12], @XMM[2], @XMM[9]
766 vtbl.8 `&Dlo(@XMM[1])`, {@XMM[11]}, `&Dlo(@XMM[8])`
767 vtbl.8 `&Dhi(@XMM[1])`, {@XMM[11]}, `&Dhi(@XMM[8])`
768 veor @XMM[13], @XMM[3], @XMM[9]
769 vtbl.8 `&Dlo(@XMM[2])`, {@XMM[12]}, `&Dlo(@XMM[8])`
770 vtbl.8 `&Dhi(@XMM[2])`, {@XMM[12]}, `&Dhi(@XMM[8])`
771 veor @XMM[14], @XMM[4], @XMM[9]
772 vtbl.8 `&Dlo(@XMM[3])`, {@XMM[13]}, `&Dlo(@XMM[8])`
773 vtbl.8 `&Dhi(@XMM[3])`, {@XMM[13]}, `&Dhi(@XMM[8])`
774 veor @XMM[15], @XMM[5], @XMM[9]
775 vtbl.8 `&Dlo(@XMM[4])`, {@XMM[14]}, `&Dlo(@XMM[8])`
776 vtbl.8 `&Dhi(@XMM[4])`, {@XMM[14]}, `&Dhi(@XMM[8])`
777 veor @XMM[10], @XMM[6], @XMM[9]
778 vtbl.8 `&Dlo(@XMM[5])`, {@XMM[15]}, `&Dlo(@XMM[8])`
779 vtbl.8 `&Dhi(@XMM[5])`, {@XMM[15]}, `&Dhi(@XMM[8])`
780 veor @XMM[11], @XMM[7], @XMM[9]
781 vtbl.8 `&Dlo(@XMM[6])`, {@XMM[10]}, `&Dlo(@XMM[8])`
782 vtbl.8 `&Dhi(@XMM[6])`, {@XMM[10]}, `&Dhi(@XMM[8])`
783 vtbl.8 `&Dlo(@XMM[7])`, {@XMM[11]}, `&Dlo(@XMM[8])`
784 vtbl.8 `&Dhi(@XMM[7])`, {@XMM[11]}, `&Dhi(@XMM[8])`
785 _bsaes_encrypt8_bitslice:
787 &bitslice (@XMM[0..7, 8..11]);
789 sub $rounds,$rounds,#1
794 &ShiftRows (@XMM[0..7, 8..12]);
795 $code.=".Lenc_sbox:\n";
796 &Sbox (@XMM[0..7, 8..15]);
798 subs $rounds,$rounds,#1
801 &MixColumns (@XMM[0,1,4,6,3,7,2,5, 8..15]);
803 vldmia $const, {@XMM[12]} @ .LSR
804 ite eq @ Thumb2 thing, samity check in ARM
805 addeq $const,$const,#0x10
807 vldmia $const, {@XMM[12]} @ .LSRM0
812 # output in lsb > [t0, t1, t4, t6, t3, t7, t2, t5] < msb
813 &bitslice (@XMM[0,1,4,6,3,7,2,5, 8..11]);
815 vldmia $key, {@XMM[8]} @ last round key
816 veor @XMM[4], @XMM[4], @XMM[8]
817 veor @XMM[6], @XMM[6], @XMM[8]
818 veor @XMM[3], @XMM[3], @XMM[8]
819 veor @XMM[7], @XMM[7], @XMM[8]
820 veor @XMM[2], @XMM[2], @XMM[8]
821 veor @XMM[5], @XMM[5], @XMM[8]
822 veor @XMM[0], @XMM[0], @XMM[8]
823 veor @XMM[1], @XMM[1], @XMM[8]
825 .size _bsaes_encrypt8,.-_bsaes_encrypt8
829 my ($out,$inp,$rounds,$const)=("r12","r4","r5","r6");
832 my @x=reverse(@_[0..7]);
833 my ($bs0,$bs1,$bs2,$t2,$t3)=@_[8..12];
835 &swapmove (@x[0,1],1,$bs0,$t2,$t3);
837 @ &swapmove(@x[2,3],1,$t0,$t2,$t3);
841 #&swapmove2x(@x[4,5,6,7],1,$t0,$t2,$t3);
843 &swapmove2x (@x[0,2,1,3],2,$bs1,$t2,$t3);
845 @ &swapmove2x(@x[4,6,5,7],2,$t1,$t2,$t3);
851 &swapmove2x (@x[0,4,1,5],4,$bs2,$t2,$t3);
852 &swapmove2x (@x[2,6,3,7],4,$bs2,$t2,$t3);
856 .type _bsaes_key_convert,%function
859 adr $const,_bsaes_key_convert
860 vld1.8 {@XMM[7]}, [$inp]! @ load round 0 key
861 sub $const,$const,#_bsaes_key_convert-.LM0
862 vld1.8 {@XMM[15]}, [$inp]! @ load round 1 key
864 vmov.i8 @XMM[8], #0x01 @ bit masks
865 vmov.i8 @XMM[9], #0x02
866 vmov.i8 @XMM[10], #0x04
867 vmov.i8 @XMM[11], #0x08
868 vmov.i8 @XMM[12], #0x10
869 vmov.i8 @XMM[13], #0x20
870 vldmia $const, {@XMM[14]} @ .LM0
873 vrev32.8 @XMM[7], @XMM[7]
874 vrev32.8 @XMM[15], @XMM[15]
876 sub $rounds,$rounds,#1
877 vstmia $out!, {@XMM[7]} @ save round 0 key
882 vtbl.8 `&Dlo(@XMM[7])`,{@XMM[15]},`&Dlo(@XMM[14])`
883 vtbl.8 `&Dhi(@XMM[7])`,{@XMM[15]},`&Dhi(@XMM[14])`
884 vmov.i8 @XMM[6], #0x40
885 vmov.i8 @XMM[15], #0x80
887 vtst.8 @XMM[0], @XMM[7], @XMM[8]
888 vtst.8 @XMM[1], @XMM[7], @XMM[9]
889 vtst.8 @XMM[2], @XMM[7], @XMM[10]
890 vtst.8 @XMM[3], @XMM[7], @XMM[11]
891 vtst.8 @XMM[4], @XMM[7], @XMM[12]
892 vtst.8 @XMM[5], @XMM[7], @XMM[13]
893 vtst.8 @XMM[6], @XMM[7], @XMM[6]
894 vtst.8 @XMM[7], @XMM[7], @XMM[15]
895 vld1.8 {@XMM[15]}, [$inp]! @ load next round key
896 vmvn @XMM[0], @XMM[0] @ "pnot"
897 vmvn @XMM[1], @XMM[1]
898 vmvn @XMM[5], @XMM[5]
899 vmvn @XMM[6], @XMM[6]
901 vrev32.8 @XMM[15], @XMM[15]
903 subs $rounds,$rounds,#1
904 vstmia $out!,{@XMM[0]-@XMM[7]} @ write bit-sliced round key
907 vmov.i8 @XMM[7],#0x63 @ compose .L63
908 @ don't save last round key
910 .size _bsaes_key_convert,.-_bsaes_key_convert
914 if (0) { # following four functions are unsupported interface
915 # used for benchmarking...
917 .globl bsaes_enc_key_convert
918 .type bsaes_enc_key_convert,%function
920 bsaes_enc_key_convert:
922 vstmdb sp!,{d8-d15} @ ABI specification says so
924 ldr r5,[$inp,#240] @ pass rounds
925 mov r4,$inp @ pass key
926 mov r12,$out @ pass key schedule
927 bl _bsaes_key_convert
928 veor @XMM[7],@XMM[7],@XMM[15] @ fix up last round key
929 vstmia r12, {@XMM[7]} @ save last round key
933 .size bsaes_enc_key_convert,.-bsaes_enc_key_convert
935 .globl bsaes_encrypt_128
936 .type bsaes_encrypt_128,%function
940 vstmdb sp!,{d8-d15} @ ABI specification says so
942 vld1.8 {@XMM[0]-@XMM[1]}, [$inp]! @ load input
943 vld1.8 {@XMM[2]-@XMM[3]}, [$inp]!
944 mov r4,$key @ pass the key
945 vld1.8 {@XMM[4]-@XMM[5]}, [$inp]!
946 mov r5,#10 @ pass rounds
947 vld1.8 {@XMM[6]-@XMM[7]}, [$inp]!
951 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output
952 vst1.8 {@XMM[4]}, [$out]!
953 vst1.8 {@XMM[6]}, [$out]!
954 vst1.8 {@XMM[3]}, [$out]!
955 vst1.8 {@XMM[7]}, [$out]!
956 vst1.8 {@XMM[2]}, [$out]!
958 vst1.8 {@XMM[5]}, [$out]!
963 .size bsaes_encrypt_128,.-bsaes_encrypt_128
965 .globl bsaes_dec_key_convert
966 .type bsaes_dec_key_convert,%function
968 bsaes_dec_key_convert:
970 vstmdb sp!,{d8-d15} @ ABI specification says so
972 ldr r5,[$inp,#240] @ pass rounds
973 mov r4,$inp @ pass key
974 mov r12,$out @ pass key schedule
975 bl _bsaes_key_convert
976 vldmia $out, {@XMM[6]}
977 vstmia r12, {@XMM[15]} @ save last round key
978 veor @XMM[7], @XMM[7], @XMM[6] @ fix up round 0 key
979 vstmia $out, {@XMM[7]}
983 .size bsaes_dec_key_convert,.-bsaes_dec_key_convert
985 .globl bsaes_decrypt_128
986 .type bsaes_decrypt_128,%function
990 vstmdb sp!,{d8-d15} @ ABI specification says so
992 vld1.8 {@XMM[0]-@XMM[1]}, [$inp]! @ load input
993 vld1.8 {@XMM[2]-@XMM[3]}, [$inp]!
994 mov r4,$key @ pass the key
995 vld1.8 {@XMM[4]-@XMM[5]}, [$inp]!
996 mov r5,#10 @ pass rounds
997 vld1.8 {@XMM[6]-@XMM[7]}, [$inp]!
1001 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output
1002 vst1.8 {@XMM[6]}, [$out]!
1003 vst1.8 {@XMM[4]}, [$out]!
1004 vst1.8 {@XMM[2]}, [$out]!
1005 vst1.8 {@XMM[7]}, [$out]!
1006 vst1.8 {@XMM[3]}, [$out]!
1007 subs $len,$len,#0x80
1008 vst1.8 {@XMM[5]}, [$out]!
1012 ldmia sp!,{r4-r6,pc}
1013 .size bsaes_decrypt_128,.-bsaes_decrypt_128
1017 my ($inp,$out,$len,$key, $ivp,$fp,$rounds)=map("r$_",(0..3,8..10));
1018 my ($keysched)=("sp");
1021 .extern AES_cbc_encrypt
1024 .global bsaes_cbc_encrypt
1025 .type bsaes_cbc_encrypt,%function
1039 @ it is up to the caller to make sure we are called with enc == 0
1042 stmdb sp!, {r4-r10, lr}
1044 ldr $ivp, [ip] @ IV is 1st arg on the stack
1045 mov $len, $len, lsr#4 @ len in 16 byte blocks
1046 sub sp, #0x10 @ scratch space to carry over the IV
1047 mov $fp, sp @ save sp
1049 ldr $rounds, [$key, #240] @ get # of rounds
1050 #ifndef BSAES_ASM_EXTENDED_KEY
1051 @ allocate the key schedule on the stack
1052 sub r12, sp, $rounds, lsl#7 @ 128 bytes per inner round key
1053 add r12, #`128-32` @ sifze of bit-slices key schedule
1055 @ populate the key schedule
1056 mov r4, $key @ pass key
1057 mov r5, $rounds @ pass # of rounds
1058 mov sp, r12 @ sp is $keysched
1059 bl _bsaes_key_convert
1060 vldmia $keysched, {@XMM[6]}
1061 vstmia r12, {@XMM[15]} @ save last round key
1062 veor @XMM[7], @XMM[7], @XMM[6] @ fix up round 0 key
1063 vstmia $keysched, {@XMM[7]}
1065 ldr r12, [$key, #244]
1069 @ populate the key schedule
1070 str r12, [$key, #244]
1071 mov r4, $key @ pass key
1072 mov r5, $rounds @ pass # of rounds
1073 add r12, $key, #248 @ pass key schedule
1074 bl _bsaes_key_convert
1076 vldmia r4, {@XMM[6]}
1077 vstmia r12, {@XMM[15]} @ save last round key
1078 veor @XMM[7], @XMM[7], @XMM[6] @ fix up round 0 key
1079 vstmia r4, {@XMM[7]}
1085 vld1.8 {@XMM[15]}, [$ivp] @ load IV
1090 subs $len, $len, #0x8
1091 bmi .Lcbc_dec_loop_finish
1093 vld1.8 {@XMM[0]-@XMM[1]}, [$inp]! @ load input
1094 vld1.8 {@XMM[2]-@XMM[3]}, [$inp]!
1095 #ifndef BSAES_ASM_EXTENDED_KEY
1096 mov r4, $keysched @ pass the key
1100 vld1.8 {@XMM[4]-@XMM[5]}, [$inp]!
1102 vld1.8 {@XMM[6]-@XMM[7]}, [$inp]
1103 sub $inp, $inp, #0x60
1104 vstmia $fp, {@XMM[15]} @ put aside IV
1108 vldmia $fp, {@XMM[14]} @ reload IV
1109 vld1.8 {@XMM[8]-@XMM[9]}, [$inp]! @ reload input
1110 veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV
1111 vld1.8 {@XMM[10]-@XMM[11]}, [$inp]!
1112 veor @XMM[1], @XMM[1], @XMM[8]
1113 veor @XMM[6], @XMM[6], @XMM[9]
1114 vld1.8 {@XMM[12]-@XMM[13]}, [$inp]!
1115 veor @XMM[4], @XMM[4], @XMM[10]
1116 veor @XMM[2], @XMM[2], @XMM[11]
1117 vld1.8 {@XMM[14]-@XMM[15]}, [$inp]!
1118 veor @XMM[7], @XMM[7], @XMM[12]
1119 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output
1120 veor @XMM[3], @XMM[3], @XMM[13]
1121 vst1.8 {@XMM[6]}, [$out]!
1122 veor @XMM[5], @XMM[5], @XMM[14]
1123 vst1.8 {@XMM[4]}, [$out]!
1124 vst1.8 {@XMM[2]}, [$out]!
1125 vst1.8 {@XMM[7]}, [$out]!
1126 vst1.8 {@XMM[3]}, [$out]!
1127 vst1.8 {@XMM[5]}, [$out]!
1131 .Lcbc_dec_loop_finish:
1135 vld1.8 {@XMM[0]}, [$inp]! @ load input
1138 vld1.8 {@XMM[1]}, [$inp]!
1139 #ifndef BSAES_ASM_EXTENDED_KEY
1140 mov r4, $keysched @ pass the key
1145 vstmia $fp, {@XMM[15]} @ put aside IV
1147 vld1.8 {@XMM[2]}, [$inp]!
1150 vld1.8 {@XMM[3]}, [$inp]!
1152 vld1.8 {@XMM[4]}, [$inp]!
1155 vld1.8 {@XMM[5]}, [$inp]!
1157 vld1.8 {@XMM[6]}, [$inp]!
1158 sub $inp, $inp, #0x70
1162 vldmia $fp, {@XMM[14]} @ reload IV
1163 vld1.8 {@XMM[8]-@XMM[9]}, [$inp]! @ reload input
1164 veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV
1165 vld1.8 {@XMM[10]-@XMM[11]}, [$inp]!
1166 veor @XMM[1], @XMM[1], @XMM[8]
1167 veor @XMM[6], @XMM[6], @XMM[9]
1168 vld1.8 {@XMM[12]-@XMM[13]}, [$inp]!
1169 veor @XMM[4], @XMM[4], @XMM[10]
1170 veor @XMM[2], @XMM[2], @XMM[11]
1171 vld1.8 {@XMM[15]}, [$inp]!
1172 veor @XMM[7], @XMM[7], @XMM[12]
1173 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output
1174 veor @XMM[3], @XMM[3], @XMM[13]
1175 vst1.8 {@XMM[6]}, [$out]!
1176 vst1.8 {@XMM[4]}, [$out]!
1177 vst1.8 {@XMM[2]}, [$out]!
1178 vst1.8 {@XMM[7]}, [$out]!
1179 vst1.8 {@XMM[3]}, [$out]!
1183 sub $inp, $inp, #0x60
1185 vldmia $fp,{@XMM[14]} @ reload IV
1186 vld1.8 {@XMM[8]-@XMM[9]}, [$inp]! @ reload input
1187 veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV
1188 vld1.8 {@XMM[10]-@XMM[11]}, [$inp]!
1189 veor @XMM[1], @XMM[1], @XMM[8]
1190 veor @XMM[6], @XMM[6], @XMM[9]
1191 vld1.8 {@XMM[12]}, [$inp]!
1192 veor @XMM[4], @XMM[4], @XMM[10]
1193 veor @XMM[2], @XMM[2], @XMM[11]
1194 vld1.8 {@XMM[15]}, [$inp]!
1195 veor @XMM[7], @XMM[7], @XMM[12]
1196 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output
1197 vst1.8 {@XMM[6]}, [$out]!
1198 vst1.8 {@XMM[4]}, [$out]!
1199 vst1.8 {@XMM[2]}, [$out]!
1200 vst1.8 {@XMM[7]}, [$out]!
1204 sub $inp, $inp, #0x50
1206 vldmia $fp, {@XMM[14]} @ reload IV
1207 vld1.8 {@XMM[8]-@XMM[9]}, [$inp]! @ reload input
1208 veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV
1209 vld1.8 {@XMM[10]-@XMM[11]}, [$inp]!
1210 veor @XMM[1], @XMM[1], @XMM[8]
1211 veor @XMM[6], @XMM[6], @XMM[9]
1212 vld1.8 {@XMM[15]}, [$inp]!
1213 veor @XMM[4], @XMM[4], @XMM[10]
1214 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output
1215 veor @XMM[2], @XMM[2], @XMM[11]
1216 vst1.8 {@XMM[6]}, [$out]!
1217 vst1.8 {@XMM[4]}, [$out]!
1218 vst1.8 {@XMM[2]}, [$out]!
1222 sub $inp, $inp, #0x40
1224 vldmia $fp, {@XMM[14]} @ reload IV
1225 vld1.8 {@XMM[8]-@XMM[9]}, [$inp]! @ reload input
1226 veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV
1227 vld1.8 {@XMM[10]}, [$inp]!
1228 veor @XMM[1], @XMM[1], @XMM[8]
1229 veor @XMM[6], @XMM[6], @XMM[9]
1230 vld1.8 {@XMM[15]}, [$inp]!
1231 veor @XMM[4], @XMM[4], @XMM[10]
1232 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output
1233 vst1.8 {@XMM[6]}, [$out]!
1234 vst1.8 {@XMM[4]}, [$out]!
1238 sub $inp, $inp, #0x30
1240 vldmia $fp, {@XMM[14]} @ reload IV
1241 vld1.8 {@XMM[8]-@XMM[9]}, [$inp]! @ reload input
1242 veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV
1243 vld1.8 {@XMM[15]}, [$inp]!
1244 veor @XMM[1], @XMM[1], @XMM[8]
1245 veor @XMM[6], @XMM[6], @XMM[9]
1246 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output
1247 vst1.8 {@XMM[6]}, [$out]!
1251 sub $inp, $inp, #0x20
1253 vldmia $fp, {@XMM[14]} @ reload IV
1254 vld1.8 {@XMM[8]}, [$inp]! @ reload input
1255 veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV
1256 vld1.8 {@XMM[15]}, [$inp]! @ reload input
1257 veor @XMM[1], @XMM[1], @XMM[8]
1258 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output
1262 sub $inp, $inp, #0x10
1263 mov $rounds, $out @ save original out pointer
1264 mov $out, $fp @ use the iv scratch space as out buffer
1266 vmov @XMM[4],@XMM[15] @ just in case ensure that IV
1267 vmov @XMM[5],@XMM[0] @ and input are preserved
1269 vld1.8 {@XMM[0]}, [$fp,:64] @ load result
1270 veor @XMM[0], @XMM[0], @XMM[4] @ ^= IV
1271 vmov @XMM[15], @XMM[5] @ @XMM[5] holds input
1272 vst1.8 {@XMM[0]}, [$rounds] @ write output
1275 #ifndef BSAES_ASM_EXTENDED_KEY
1278 .Lcbc_dec_bzero: @ wipe key schedule [if any]
1279 vstmia $keysched!, {q0-q1}
1285 add sp, #0x10 @ add sp,$fp,#0x10 is no good for thumb
1286 vst1.8 {@XMM[15]}, [$ivp] @ return IV
1288 ldmia sp!, {r4-r10, pc}
1289 .size bsaes_cbc_encrypt,.-bsaes_cbc_encrypt
1293 my ($inp,$out,$len,$key, $ctr,$fp,$rounds)=(map("r$_",(0..3,8..10)));
1294 my $const = "r6"; # shared with _bsaes_encrypt8_alt
1295 my $keysched = "sp";
1299 .global bsaes_ctr32_encrypt_blocks
1300 .type bsaes_ctr32_encrypt_blocks,%function
1302 bsaes_ctr32_encrypt_blocks:
1303 cmp $len, #8 @ use plain AES for
1304 blo .Lctr_enc_short @ small sizes
1307 stmdb sp!, {r4-r10, lr}
1309 ldr $ctr, [ip] @ ctr is 1st arg on the stack
1310 sub sp, sp, #0x10 @ scratch space to carry over the ctr
1311 mov $fp, sp @ save sp
1313 ldr $rounds, [$key, #240] @ get # of rounds
1314 #ifndef BSAES_ASM_EXTENDED_KEY
1315 @ allocate the key schedule on the stack
1316 sub r12, sp, $rounds, lsl#7 @ 128 bytes per inner round key
1317 add r12, #`128-32` @ size of bit-sliced key schedule
1319 @ populate the key schedule
1320 mov r4, $key @ pass key
1321 mov r5, $rounds @ pass # of rounds
1322 mov sp, r12 @ sp is $keysched
1323 bl _bsaes_key_convert
1324 veor @XMM[7],@XMM[7],@XMM[15] @ fix up last round key
1325 vstmia r12, {@XMM[7]} @ save last round key
1327 vld1.8 {@XMM[0]}, [$ctr] @ load counter
1328 add $ctr, $const, #.LREVM0SR-.LM0 @ borrow $ctr
1329 vldmia $keysched, {@XMM[4]} @ load round0 key
1331 ldr r12, [$key, #244]
1335 @ populate the key schedule
1336 str r12, [$key, #244]
1337 mov r4, $key @ pass key
1338 mov r5, $rounds @ pass # of rounds
1339 add r12, $key, #248 @ pass key schedule
1340 bl _bsaes_key_convert
1341 veor @XMM[7],@XMM[7],@XMM[15] @ fix up last round key
1342 vstmia r12, {@XMM[7]} @ save last round key
1345 0: add r12, $key, #248
1346 vld1.8 {@XMM[0]}, [$ctr] @ load counter
1347 adrl $ctr, .LREVM0SR @ borrow $ctr
1348 vldmia r12, {@XMM[4]} @ load round0 key
1349 sub sp, #0x10 @ place for adjusted round0 key
1352 vmov.i32 @XMM[8],#1 @ compose 1<<96
1353 veor @XMM[9],@XMM[9],@XMM[9]
1354 vrev32.8 @XMM[0],@XMM[0]
1355 vext.8 @XMM[8],@XMM[9],@XMM[8],#4
1356 vrev32.8 @XMM[4],@XMM[4]
1357 vadd.u32 @XMM[9],@XMM[8],@XMM[8] @ compose 2<<96
1358 vstmia $keysched, {@XMM[4]} @ save adjusted round0 key
1363 vadd.u32 @XMM[10], @XMM[8], @XMM[9] @ compose 3<<96
1364 vadd.u32 @XMM[1], @XMM[0], @XMM[8] @ +1
1365 vadd.u32 @XMM[2], @XMM[0], @XMM[9] @ +2
1366 vadd.u32 @XMM[3], @XMM[0], @XMM[10] @ +3
1367 vadd.u32 @XMM[4], @XMM[1], @XMM[10]
1368 vadd.u32 @XMM[5], @XMM[2], @XMM[10]
1369 vadd.u32 @XMM[6], @XMM[3], @XMM[10]
1370 vadd.u32 @XMM[7], @XMM[4], @XMM[10]
1371 vadd.u32 @XMM[10], @XMM[5], @XMM[10] @ next counter
1373 @ Borrow prologue from _bsaes_encrypt8 to use the opportunity
1374 @ to flip byte order in 32-bit counter
1376 vldmia $keysched, {@XMM[9]} @ load round0 key
1377 #ifndef BSAES_ASM_EXTENDED_KEY
1378 add r4, $keysched, #0x10 @ pass next round key
1380 add r4, $key, #`248+16`
1382 vldmia $ctr, {@XMM[8]} @ .LREVM0SR
1383 mov r5, $rounds @ pass rounds
1384 vstmia $fp, {@XMM[10]} @ save next counter
1385 sub $const, $ctr, #.LREVM0SR-.LSR @ pass constants
1387 bl _bsaes_encrypt8_alt
1390 blo .Lctr_enc_loop_done
1392 vld1.8 {@XMM[8]-@XMM[9]}, [$inp]! @ load input
1393 vld1.8 {@XMM[10]-@XMM[11]}, [$inp]!
1394 veor @XMM[0], @XMM[8]
1395 veor @XMM[1], @XMM[9]
1396 vld1.8 {@XMM[12]-@XMM[13]}, [$inp]!
1397 veor @XMM[4], @XMM[10]
1398 veor @XMM[6], @XMM[11]
1399 vld1.8 {@XMM[14]-@XMM[15]}, [$inp]!
1400 veor @XMM[3], @XMM[12]
1401 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output
1402 veor @XMM[7], @XMM[13]
1403 veor @XMM[2], @XMM[14]
1404 vst1.8 {@XMM[4]}, [$out]!
1405 veor @XMM[5], @XMM[15]
1406 vst1.8 {@XMM[6]}, [$out]!
1407 vmov.i32 @XMM[8], #1 @ compose 1<<96
1408 vst1.8 {@XMM[3]}, [$out]!
1409 veor @XMM[9], @XMM[9], @XMM[9]
1410 vst1.8 {@XMM[7]}, [$out]!
1411 vext.8 @XMM[8], @XMM[9], @XMM[8], #4
1412 vst1.8 {@XMM[2]}, [$out]!
1413 vadd.u32 @XMM[9],@XMM[8],@XMM[8] @ compose 2<<96
1414 vst1.8 {@XMM[5]}, [$out]!
1415 vldmia $fp, {@XMM[0]} @ load counter
1421 .Lctr_enc_loop_done:
1423 vld1.8 {@XMM[8]}, [$inp]! @ load input
1424 veor @XMM[0], @XMM[8]
1425 vst1.8 {@XMM[0]}, [$out]! @ write output
1428 vld1.8 {@XMM[9]}, [$inp]!
1429 veor @XMM[1], @XMM[9]
1430 vst1.8 {@XMM[1]}, [$out]!
1432 vld1.8 {@XMM[10]}, [$inp]!
1433 veor @XMM[4], @XMM[10]
1434 vst1.8 {@XMM[4]}, [$out]!
1437 vld1.8 {@XMM[11]}, [$inp]!
1438 veor @XMM[6], @XMM[11]
1439 vst1.8 {@XMM[6]}, [$out]!
1441 vld1.8 {@XMM[12]}, [$inp]!
1442 veor @XMM[3], @XMM[12]
1443 vst1.8 {@XMM[3]}, [$out]!
1446 vld1.8 {@XMM[13]}, [$inp]!
1447 veor @XMM[7], @XMM[13]
1448 vst1.8 {@XMM[7]}, [$out]!
1450 vld1.8 {@XMM[14]}, [$inp]
1451 veor @XMM[2], @XMM[14]
1452 vst1.8 {@XMM[2]}, [$out]!
1457 #ifndef BSAES_ASM_EXTENDED_KEY
1458 .Lctr_enc_bzero: @ wipe key schedule [if any]
1459 vstmia $keysched!, {q0-q1}
1463 vstmia $keysched, {q0-q1}
1467 add sp, #0x10 @ add sp,$fp,#0x10 is no good for thumb
1469 ldmia sp!, {r4-r10, pc} @ return
1473 ldr ip, [sp] @ ctr pointer is passed on stack
1474 stmdb sp!, {r4-r8, lr}
1476 mov r4, $inp @ copy arguments
1480 ldr r8, [ip, #12] @ load counter LSW
1481 vld1.8 {@XMM[1]}, [ip] @ load whole counter value
1486 vst1.8 {@XMM[1]}, [sp,:64] @ copy counter value
1489 .Lctr_enc_short_loop:
1490 add r0, sp, #0x10 @ input counter value
1491 mov r1, sp @ output on the stack
1496 vld1.8 {@XMM[0]}, [r4]! @ load input
1497 vld1.8 {@XMM[1]}, [sp,:64] @ load encrypted counter
1501 str r0, [sp, #0x1c] @ next counter value
1503 str r8, [sp, #0x1c] @ next counter value
1505 veor @XMM[0],@XMM[0],@XMM[1]
1506 vst1.8 {@XMM[0]}, [r5]! @ store output
1508 bne .Lctr_enc_short_loop
1514 ldmia sp!, {r4-r8, pc}
1515 .size bsaes_ctr32_encrypt_blocks,.-bsaes_ctr32_encrypt_blocks
1519 ######################################################################
1520 # void bsaes_xts_[en|de]crypt(const char *inp,char *out,size_t len,
1521 # const AES_KEY *key1, const AES_KEY *key2,
1522 # const unsigned char iv[16]);
1524 my ($inp,$out,$len,$key,$rounds,$magic,$fp)=(map("r$_",(7..10,1..3)));
1525 my $const="r6"; # returned by _bsaes_key_convert
1530 .globl bsaes_xts_encrypt
1531 .type bsaes_xts_encrypt,%function
1535 stmdb sp!, {r4-r10, lr} @ 0x20
1537 mov r6, sp @ future $fp
1544 sub r0, sp, #0x10 @ 0x10
1545 bic r0, #0xf @ align at 16 bytes
1548 #ifdef XTS_CHAIN_TWEAK
1549 ldr r0, [ip] @ pointer to input tweak
1551 @ generate initial tweak
1552 ldr r0, [ip, #4] @ iv[]
1554 ldr r2, [ip, #0] @ key2
1556 mov r0,sp @ pointer to initial tweak
1559 ldr $rounds, [$key, #240] @ get # of rounds
1561 #ifndef BSAES_ASM_EXTENDED_KEY
1562 @ allocate the key schedule on the stack
1563 sub r12, sp, $rounds, lsl#7 @ 128 bytes per inner round key
1564 @ add r12, #`128-32` @ size of bit-sliced key schedule
1565 sub r12, #`32+16` @ place for tweak[9]
1567 @ populate the key schedule
1568 mov r4, $key @ pass key
1569 mov r5, $rounds @ pass # of rounds
1571 add r12, #0x90 @ pass key schedule
1572 bl _bsaes_key_convert
1573 veor @XMM[7], @XMM[7], @XMM[15] @ fix up last round key
1574 vstmia r12, {@XMM[7]} @ save last round key
1576 ldr r12, [$key, #244]
1580 str r12, [$key, #244]
1581 mov r4, $key @ pass key
1582 mov r5, $rounds @ pass # of rounds
1583 add r12, $key, #248 @ pass key schedule
1584 bl _bsaes_key_convert
1585 veor @XMM[7], @XMM[7], @XMM[15] @ fix up last round key
1586 vstmia r12, {@XMM[7]}
1589 0: sub sp, #0x90 @ place for tweak[9]
1592 vld1.8 {@XMM[8]}, [r0] @ initial tweak
1593 adr $magic, .Lxts_magic
1601 vldmia $magic, {$twmask} @ load XTS magic
1602 vshr.s64 @T[0], @XMM[8], #63
1604 vand @T[0], @T[0], $twmask
1606 for($i=9;$i<16;$i++) {
1608 vadd.u64 @XMM[$i], @XMM[$i-1], @XMM[$i-1]
1609 vst1.64 {@XMM[$i-1]}, [r0,:128]!
1610 vswp `&Dhi("@T[0]")`,`&Dlo("@T[0]")`
1611 vshr.s64 @T[1], @XMM[$i], #63
1612 veor @XMM[$i], @XMM[$i], @T[0]
1613 vand @T[1], @T[1], $twmask
1617 $code.=<<___ if ($i>=10);
1618 vld1.8 {@XMM[$i-10]}, [$inp]!
1620 $code.=<<___ if ($i>=11);
1621 veor @XMM[$i-11], @XMM[$i-11], @XMM[$i-3]
1625 vadd.u64 @XMM[8], @XMM[15], @XMM[15]
1626 vst1.64 {@XMM[15]}, [r0,:128]!
1627 vswp `&Dhi("@T[0]")`,`&Dlo("@T[0]")`
1628 veor @XMM[8], @XMM[8], @T[0]
1629 vst1.64 {@XMM[8]}, [r0,:128] @ next round tweak
1631 vld1.8 {@XMM[6]-@XMM[7]}, [$inp]!
1632 veor @XMM[5], @XMM[5], @XMM[13]
1633 #ifndef BSAES_ASM_EXTENDED_KEY
1634 add r4, sp, #0x90 @ pass key schedule
1636 add r4, $key, #248 @ pass key schedule
1638 veor @XMM[6], @XMM[6], @XMM[14]
1639 mov r5, $rounds @ pass rounds
1640 veor @XMM[7], @XMM[7], @XMM[15]
1645 vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
1646 vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]!
1647 veor @XMM[0], @XMM[0], @XMM[ 8]
1648 vld1.64 {@XMM[12]-@XMM[13]}, [r0,:128]!
1649 veor @XMM[1], @XMM[1], @XMM[ 9]
1650 veor @XMM[8], @XMM[4], @XMM[10]
1651 vst1.8 {@XMM[0]-@XMM[1]}, [$out]!
1652 veor @XMM[9], @XMM[6], @XMM[11]
1653 vld1.64 {@XMM[14]-@XMM[15]}, [r0,:128]!
1654 veor @XMM[10], @XMM[3], @XMM[12]
1655 vst1.8 {@XMM[8]-@XMM[9]}, [$out]!
1656 veor @XMM[11], @XMM[7], @XMM[13]
1657 veor @XMM[12], @XMM[2], @XMM[14]
1658 vst1.8 {@XMM[10]-@XMM[11]}, [$out]!
1659 veor @XMM[13], @XMM[5], @XMM[15]
1660 vst1.8 {@XMM[12]-@XMM[13]}, [$out]!
1662 vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak
1671 vldmia $magic, {$twmask} @ load XTS magic
1672 vshr.s64 @T[0], @XMM[8], #63
1674 vand @T[0], @T[0], $twmask
1676 for($i=9;$i<16;$i++) {
1678 vadd.u64 @XMM[$i], @XMM[$i-1], @XMM[$i-1]
1679 vst1.64 {@XMM[$i-1]}, [r0,:128]!
1680 vswp `&Dhi("@T[0]")`,`&Dlo("@T[0]")`
1681 vshr.s64 @T[1], @XMM[$i], #63
1682 veor @XMM[$i], @XMM[$i], @T[0]
1683 vand @T[1], @T[1], $twmask
1687 $code.=<<___ if ($i>=10);
1688 vld1.8 {@XMM[$i-10]}, [$inp]!
1690 bmi .Lxts_enc_`$i-9`
1692 $code.=<<___ if ($i>=11);
1693 veor @XMM[$i-11], @XMM[$i-11], @XMM[$i-3]
1698 vst1.64 {@XMM[15]}, [r0,:128] @ next round tweak
1700 vld1.8 {@XMM[6]}, [$inp]!
1701 veor @XMM[5], @XMM[5], @XMM[13]
1702 #ifndef BSAES_ASM_EXTENDED_KEY
1703 add r4, sp, #0x90 @ pass key schedule
1705 add r4, $key, #248 @ pass key schedule
1707 veor @XMM[6], @XMM[6], @XMM[14]
1708 mov r5, $rounds @ pass rounds
1713 vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
1714 vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]!
1715 veor @XMM[0], @XMM[0], @XMM[ 8]
1716 vld1.64 {@XMM[12]-@XMM[13]}, [r0,:128]!
1717 veor @XMM[1], @XMM[1], @XMM[ 9]
1718 veor @XMM[8], @XMM[4], @XMM[10]
1719 vst1.8 {@XMM[0]-@XMM[1]}, [$out]!
1720 veor @XMM[9], @XMM[6], @XMM[11]
1721 vld1.64 {@XMM[14]}, [r0,:128]!
1722 veor @XMM[10], @XMM[3], @XMM[12]
1723 vst1.8 {@XMM[8]-@XMM[9]}, [$out]!
1724 veor @XMM[11], @XMM[7], @XMM[13]
1725 veor @XMM[12], @XMM[2], @XMM[14]
1726 vst1.8 {@XMM[10]-@XMM[11]}, [$out]!
1727 vst1.8 {@XMM[12]}, [$out]!
1729 vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak
1733 vst1.64 {@XMM[14]}, [r0,:128] @ next round tweak
1735 veor @XMM[4], @XMM[4], @XMM[12]
1736 #ifndef BSAES_ASM_EXTENDED_KEY
1737 add r4, sp, #0x90 @ pass key schedule
1739 add r4, $key, #248 @ pass key schedule
1741 veor @XMM[5], @XMM[5], @XMM[13]
1742 mov r5, $rounds @ pass rounds
1747 vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
1748 vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]!
1749 veor @XMM[0], @XMM[0], @XMM[ 8]
1750 vld1.64 {@XMM[12]-@XMM[13]}, [r0,:128]!
1751 veor @XMM[1], @XMM[1], @XMM[ 9]
1752 veor @XMM[8], @XMM[4], @XMM[10]
1753 vst1.8 {@XMM[0]-@XMM[1]}, [$out]!
1754 veor @XMM[9], @XMM[6], @XMM[11]
1755 veor @XMM[10], @XMM[3], @XMM[12]
1756 vst1.8 {@XMM[8]-@XMM[9]}, [$out]!
1757 veor @XMM[11], @XMM[7], @XMM[13]
1758 vst1.8 {@XMM[10]-@XMM[11]}, [$out]!
1760 vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak
1763 @ put this in range for both ARM and Thumb mode adr instructions
1770 vst1.64 {@XMM[13]}, [r0,:128] @ next round tweak
1772 veor @XMM[3], @XMM[3], @XMM[11]
1773 #ifndef BSAES_ASM_EXTENDED_KEY
1774 add r4, sp, #0x90 @ pass key schedule
1776 add r4, $key, #248 @ pass key schedule
1778 veor @XMM[4], @XMM[4], @XMM[12]
1779 mov r5, $rounds @ pass rounds
1784 vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
1785 vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]!
1786 veor @XMM[0], @XMM[0], @XMM[ 8]
1787 vld1.64 {@XMM[12]}, [r0,:128]!
1788 veor @XMM[1], @XMM[1], @XMM[ 9]
1789 veor @XMM[8], @XMM[4], @XMM[10]
1790 vst1.8 {@XMM[0]-@XMM[1]}, [$out]!
1791 veor @XMM[9], @XMM[6], @XMM[11]
1792 veor @XMM[10], @XMM[3], @XMM[12]
1793 vst1.8 {@XMM[8]-@XMM[9]}, [$out]!
1794 vst1.8 {@XMM[10]}, [$out]!
1796 vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak
1800 vst1.64 {@XMM[12]}, [r0,:128] @ next round tweak
1802 veor @XMM[2], @XMM[2], @XMM[10]
1803 #ifndef BSAES_ASM_EXTENDED_KEY
1804 add r4, sp, #0x90 @ pass key schedule
1806 add r4, $key, #248 @ pass key schedule
1808 veor @XMM[3], @XMM[3], @XMM[11]
1809 mov r5, $rounds @ pass rounds
1814 vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
1815 vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]!
1816 veor @XMM[0], @XMM[0], @XMM[ 8]
1817 veor @XMM[1], @XMM[1], @XMM[ 9]
1818 veor @XMM[8], @XMM[4], @XMM[10]
1819 vst1.8 {@XMM[0]-@XMM[1]}, [$out]!
1820 veor @XMM[9], @XMM[6], @XMM[11]
1821 vst1.8 {@XMM[8]-@XMM[9]}, [$out]!
1823 vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak
1827 vst1.64 {@XMM[11]}, [r0,:128] @ next round tweak
1829 veor @XMM[1], @XMM[1], @XMM[9]
1830 #ifndef BSAES_ASM_EXTENDED_KEY
1831 add r4, sp, #0x90 @ pass key schedule
1833 add r4, $key, #248 @ pass key schedule
1835 veor @XMM[2], @XMM[2], @XMM[10]
1836 mov r5, $rounds @ pass rounds
1841 vld1.64 {@XMM[8]-@XMM[9]}, [r0,:128]!
1842 vld1.64 {@XMM[10]}, [r0,:128]!
1843 veor @XMM[0], @XMM[0], @XMM[ 8]
1844 veor @XMM[1], @XMM[1], @XMM[ 9]
1845 veor @XMM[8], @XMM[4], @XMM[10]
1846 vst1.8 {@XMM[0]-@XMM[1]}, [$out]!
1847 vst1.8 {@XMM[8]}, [$out]!
1849 vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak
1853 vst1.64 {@XMM[10]}, [r0,:128] @ next round tweak
1855 veor @XMM[0], @XMM[0], @XMM[8]
1856 #ifndef BSAES_ASM_EXTENDED_KEY
1857 add r4, sp, #0x90 @ pass key schedule
1859 add r4, $key, #248 @ pass key schedule
1861 veor @XMM[1], @XMM[1], @XMM[9]
1862 mov r5, $rounds @ pass rounds
1867 vld1.64 {@XMM[8]-@XMM[9]}, [r0,:128]!
1868 veor @XMM[0], @XMM[0], @XMM[ 8]
1869 veor @XMM[1], @XMM[1], @XMM[ 9]
1870 vst1.8 {@XMM[0]-@XMM[1]}, [$out]!
1872 vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak
1877 veor @XMM[0], @XMM[8]
1879 vst1.8 {@XMM[0]}, [sp,:128]
1881 mov r4, $fp @ preserve fp
1885 vld1.8 {@XMM[0]}, [sp,:128]
1886 veor @XMM[0], @XMM[0], @XMM[8]
1887 vst1.8 {@XMM[0]}, [$out]!
1890 vmov @XMM[8], @XMM[9] @ next round tweak
1893 #ifndef XTS_CHAIN_TWEAK
1900 ldrb r1, [$out, #-0x10]
1901 strb r0, [$out, #-0x10]
1907 vld1.8 {@XMM[0]}, [r6]
1909 veor @XMM[0], @XMM[0], @XMM[8]
1911 vst1.8 {@XMM[0]}, [sp,:128]
1913 mov r4, $fp @ preserve fp
1917 vld1.8 {@XMM[0]}, [sp,:128]
1918 veor @XMM[0], @XMM[0], @XMM[8]
1919 vst1.8 {@XMM[0]}, [r6]
1927 #ifdef XTS_CHAIN_TWEAK
1928 ldr r1, [$fp, #0x20+VFP_ABI_FRAME] @ chain tweak
1930 .Lxts_enc_bzero: @ wipe key schedule [if any]
1936 #ifdef XTS_CHAIN_TWEAK
1937 vst1.8 {@XMM[8]}, [r1]
1940 ldmia sp!, {r4-r10, pc} @ return
1942 .size bsaes_xts_encrypt,.-bsaes_xts_encrypt
1944 .globl bsaes_xts_decrypt
1945 .type bsaes_xts_decrypt,%function
1949 stmdb sp!, {r4-r10, lr} @ 0x20
1951 mov r6, sp @ future $fp
1958 sub r0, sp, #0x10 @ 0x10
1959 bic r0, #0xf @ align at 16 bytes
1962 #ifdef XTS_CHAIN_TWEAK
1963 ldr r0, [ip] @ pointer to input tweak
1965 @ generate initial tweak
1966 ldr r0, [ip, #4] @ iv[]
1968 ldr r2, [ip, #0] @ key2
1970 mov r0, sp @ pointer to initial tweak
1973 ldr $rounds, [$key, #240] @ get # of rounds
1975 #ifndef BSAES_ASM_EXTENDED_KEY
1976 @ allocate the key schedule on the stack
1977 sub r12, sp, $rounds, lsl#7 @ 128 bytes per inner round key
1978 @ add r12, #`128-32` @ size of bit-sliced key schedule
1979 sub r12, #`32+16` @ place for tweak[9]
1981 @ populate the key schedule
1982 mov r4, $key @ pass key
1983 mov r5, $rounds @ pass # of rounds
1985 add r12, #0x90 @ pass key schedule
1986 bl _bsaes_key_convert
1988 vldmia r4, {@XMM[6]}
1989 vstmia r12, {@XMM[15]} @ save last round key
1990 veor @XMM[7], @XMM[7], @XMM[6] @ fix up round 0 key
1991 vstmia r4, {@XMM[7]}
1993 ldr r12, [$key, #244]
1997 str r12, [$key, #244]
1998 mov r4, $key @ pass key
1999 mov r5, $rounds @ pass # of rounds
2000 add r12, $key, #248 @ pass key schedule
2001 bl _bsaes_key_convert
2003 vldmia r4, {@XMM[6]}
2004 vstmia r12, {@XMM[15]} @ save last round key
2005 veor @XMM[7], @XMM[7], @XMM[6] @ fix up round 0 key
2006 vstmia r4, {@XMM[7]}
2009 0: sub sp, #0x90 @ place for tweak[9]
2011 vld1.8 {@XMM[8]}, [r0] @ initial tweak
2012 adr $magic, .Lxts_magic
2014 tst $len, #0xf @ if not multiple of 16
2015 it ne @ Thumb2 thing, sanity check in ARM
2016 subne $len, #0x10 @ subtract another 16 bytes
2024 vldmia $magic, {$twmask} @ load XTS magic
2025 vshr.s64 @T[0], @XMM[8], #63
2027 vand @T[0], @T[0], $twmask
2029 for($i=9;$i<16;$i++) {
2031 vadd.u64 @XMM[$i], @XMM[$i-1], @XMM[$i-1]
2032 vst1.64 {@XMM[$i-1]}, [r0,:128]!
2033 vswp `&Dhi("@T[0]")`,`&Dlo("@T[0]")`
2034 vshr.s64 @T[1], @XMM[$i], #63
2035 veor @XMM[$i], @XMM[$i], @T[0]
2036 vand @T[1], @T[1], $twmask
2040 $code.=<<___ if ($i>=10);
2041 vld1.8 {@XMM[$i-10]}, [$inp]!
2043 $code.=<<___ if ($i>=11);
2044 veor @XMM[$i-11], @XMM[$i-11], @XMM[$i-3]
2048 vadd.u64 @XMM[8], @XMM[15], @XMM[15]
2049 vst1.64 {@XMM[15]}, [r0,:128]!
2050 vswp `&Dhi("@T[0]")`,`&Dlo("@T[0]")`
2051 veor @XMM[8], @XMM[8], @T[0]
2052 vst1.64 {@XMM[8]}, [r0,:128] @ next round tweak
2054 vld1.8 {@XMM[6]-@XMM[7]}, [$inp]!
2055 veor @XMM[5], @XMM[5], @XMM[13]
2056 #ifndef BSAES_ASM_EXTENDED_KEY
2057 add r4, sp, #0x90 @ pass key schedule
2059 add r4, $key, #248 @ pass key schedule
2061 veor @XMM[6], @XMM[6], @XMM[14]
2062 mov r5, $rounds @ pass rounds
2063 veor @XMM[7], @XMM[7], @XMM[15]
2068 vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
2069 vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]!
2070 veor @XMM[0], @XMM[0], @XMM[ 8]
2071 vld1.64 {@XMM[12]-@XMM[13]}, [r0,:128]!
2072 veor @XMM[1], @XMM[1], @XMM[ 9]
2073 veor @XMM[8], @XMM[6], @XMM[10]
2074 vst1.8 {@XMM[0]-@XMM[1]}, [$out]!
2075 veor @XMM[9], @XMM[4], @XMM[11]
2076 vld1.64 {@XMM[14]-@XMM[15]}, [r0,:128]!
2077 veor @XMM[10], @XMM[2], @XMM[12]
2078 vst1.8 {@XMM[8]-@XMM[9]}, [$out]!
2079 veor @XMM[11], @XMM[7], @XMM[13]
2080 veor @XMM[12], @XMM[3], @XMM[14]
2081 vst1.8 {@XMM[10]-@XMM[11]}, [$out]!
2082 veor @XMM[13], @XMM[5], @XMM[15]
2083 vst1.8 {@XMM[12]-@XMM[13]}, [$out]!
2085 vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak
2094 vldmia $magic, {$twmask} @ load XTS magic
2095 vshr.s64 @T[0], @XMM[8], #63
2097 vand @T[0], @T[0], $twmask
2099 for($i=9;$i<16;$i++) {
2101 vadd.u64 @XMM[$i], @XMM[$i-1], @XMM[$i-1]
2102 vst1.64 {@XMM[$i-1]}, [r0,:128]!
2103 vswp `&Dhi("@T[0]")`,`&Dlo("@T[0]")`
2104 vshr.s64 @T[1], @XMM[$i], #63
2105 veor @XMM[$i], @XMM[$i], @T[0]
2106 vand @T[1], @T[1], $twmask
2110 $code.=<<___ if ($i>=10);
2111 vld1.8 {@XMM[$i-10]}, [$inp]!
2113 bmi .Lxts_dec_`$i-9`
2115 $code.=<<___ if ($i>=11);
2116 veor @XMM[$i-11], @XMM[$i-11], @XMM[$i-3]
2121 vst1.64 {@XMM[15]}, [r0,:128] @ next round tweak
2123 vld1.8 {@XMM[6]}, [$inp]!
2124 veor @XMM[5], @XMM[5], @XMM[13]
2125 #ifndef BSAES_ASM_EXTENDED_KEY
2126 add r4, sp, #0x90 @ pass key schedule
2128 add r4, $key, #248 @ pass key schedule
2130 veor @XMM[6], @XMM[6], @XMM[14]
2131 mov r5, $rounds @ pass rounds
2136 vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
2137 vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]!
2138 veor @XMM[0], @XMM[0], @XMM[ 8]
2139 vld1.64 {@XMM[12]-@XMM[13]}, [r0,:128]!
2140 veor @XMM[1], @XMM[1], @XMM[ 9]
2141 veor @XMM[8], @XMM[6], @XMM[10]
2142 vst1.8 {@XMM[0]-@XMM[1]}, [$out]!
2143 veor @XMM[9], @XMM[4], @XMM[11]
2144 vld1.64 {@XMM[14]}, [r0,:128]!
2145 veor @XMM[10], @XMM[2], @XMM[12]
2146 vst1.8 {@XMM[8]-@XMM[9]}, [$out]!
2147 veor @XMM[11], @XMM[7], @XMM[13]
2148 veor @XMM[12], @XMM[3], @XMM[14]
2149 vst1.8 {@XMM[10]-@XMM[11]}, [$out]!
2150 vst1.8 {@XMM[12]}, [$out]!
2152 vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak
2156 vst1.64 {@XMM[14]}, [r0,:128] @ next round tweak
2158 veor @XMM[4], @XMM[4], @XMM[12]
2159 #ifndef BSAES_ASM_EXTENDED_KEY
2160 add r4, sp, #0x90 @ pass key schedule
2162 add r4, $key, #248 @ pass key schedule
2164 veor @XMM[5], @XMM[5], @XMM[13]
2165 mov r5, $rounds @ pass rounds
2170 vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
2171 vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]!
2172 veor @XMM[0], @XMM[0], @XMM[ 8]
2173 vld1.64 {@XMM[12]-@XMM[13]}, [r0,:128]!
2174 veor @XMM[1], @XMM[1], @XMM[ 9]
2175 veor @XMM[8], @XMM[6], @XMM[10]
2176 vst1.8 {@XMM[0]-@XMM[1]}, [$out]!
2177 veor @XMM[9], @XMM[4], @XMM[11]
2178 veor @XMM[10], @XMM[2], @XMM[12]
2179 vst1.8 {@XMM[8]-@XMM[9]}, [$out]!
2180 veor @XMM[11], @XMM[7], @XMM[13]
2181 vst1.8 {@XMM[10]-@XMM[11]}, [$out]!
2183 vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak
2187 vst1.64 {@XMM[13]}, [r0,:128] @ next round tweak
2189 veor @XMM[3], @XMM[3], @XMM[11]
2190 #ifndef BSAES_ASM_EXTENDED_KEY
2191 add r4, sp, #0x90 @ pass key schedule
2193 add r4, $key, #248 @ pass key schedule
2195 veor @XMM[4], @XMM[4], @XMM[12]
2196 mov r5, $rounds @ pass rounds
2201 vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
2202 vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]!
2203 veor @XMM[0], @XMM[0], @XMM[ 8]
2204 vld1.64 {@XMM[12]}, [r0,:128]!
2205 veor @XMM[1], @XMM[1], @XMM[ 9]
2206 veor @XMM[8], @XMM[6], @XMM[10]
2207 vst1.8 {@XMM[0]-@XMM[1]}, [$out]!
2208 veor @XMM[9], @XMM[4], @XMM[11]
2209 veor @XMM[10], @XMM[2], @XMM[12]
2210 vst1.8 {@XMM[8]-@XMM[9]}, [$out]!
2211 vst1.8 {@XMM[10]}, [$out]!
2213 vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak
2217 vst1.64 {@XMM[12]}, [r0,:128] @ next round tweak
2219 veor @XMM[2], @XMM[2], @XMM[10]
2220 #ifndef BSAES_ASM_EXTENDED_KEY
2221 add r4, sp, #0x90 @ pass key schedule
2223 add r4, $key, #248 @ pass key schedule
2225 veor @XMM[3], @XMM[3], @XMM[11]
2226 mov r5, $rounds @ pass rounds
2231 vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
2232 vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]!
2233 veor @XMM[0], @XMM[0], @XMM[ 8]
2234 veor @XMM[1], @XMM[1], @XMM[ 9]
2235 veor @XMM[8], @XMM[6], @XMM[10]
2236 vst1.8 {@XMM[0]-@XMM[1]}, [$out]!
2237 veor @XMM[9], @XMM[4], @XMM[11]
2238 vst1.8 {@XMM[8]-@XMM[9]}, [$out]!
2240 vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak
2244 vst1.64 {@XMM[11]}, [r0,:128] @ next round tweak
2246 veor @XMM[1], @XMM[1], @XMM[9]
2247 #ifndef BSAES_ASM_EXTENDED_KEY
2248 add r4, sp, #0x90 @ pass key schedule
2250 add r4, $key, #248 @ pass key schedule
2252 veor @XMM[2], @XMM[2], @XMM[10]
2253 mov r5, $rounds @ pass rounds
2258 vld1.64 {@XMM[8]-@XMM[9]}, [r0,:128]!
2259 vld1.64 {@XMM[10]}, [r0,:128]!
2260 veor @XMM[0], @XMM[0], @XMM[ 8]
2261 veor @XMM[1], @XMM[1], @XMM[ 9]
2262 veor @XMM[8], @XMM[6], @XMM[10]
2263 vst1.8 {@XMM[0]-@XMM[1]}, [$out]!
2264 vst1.8 {@XMM[8]}, [$out]!
2266 vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak
2270 vst1.64 {@XMM[10]}, [r0,:128] @ next round tweak
2272 veor @XMM[0], @XMM[0], @XMM[8]
2273 #ifndef BSAES_ASM_EXTENDED_KEY
2274 add r4, sp, #0x90 @ pass key schedule
2276 add r4, $key, #248 @ pass key schedule
2278 veor @XMM[1], @XMM[1], @XMM[9]
2279 mov r5, $rounds @ pass rounds
2284 vld1.64 {@XMM[8]-@XMM[9]}, [r0,:128]!
2285 veor @XMM[0], @XMM[0], @XMM[ 8]
2286 veor @XMM[1], @XMM[1], @XMM[ 9]
2287 vst1.8 {@XMM[0]-@XMM[1]}, [$out]!
2289 vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak
2294 veor @XMM[0], @XMM[8]
2296 vst1.8 {@XMM[0]}, [sp,:128]
2298 mov r4, $fp @ preserve fp
2299 mov r5, $magic @ preserve magic
2303 vld1.8 {@XMM[0]}, [sp,:128]
2304 veor @XMM[0], @XMM[0], @XMM[8]
2305 vst1.8 {@XMM[0]}, [$out]!
2309 vmov @XMM[8], @XMM[9] @ next round tweak
2312 #ifndef XTS_CHAIN_TWEAK
2316 @ calculate one round of extra tweak for the stolen ciphertext
2317 vldmia $magic, {$twmask}
2318 vshr.s64 @XMM[6], @XMM[8], #63
2319 vand @XMM[6], @XMM[6], $twmask
2320 vadd.u64 @XMM[9], @XMM[8], @XMM[8]
2321 vswp `&Dhi("@XMM[6]")`,`&Dlo("@XMM[6]")`
2322 veor @XMM[9], @XMM[9], @XMM[6]
2324 @ perform the final decryption with the last tweak value
2325 vld1.8 {@XMM[0]}, [$inp]!
2327 veor @XMM[0], @XMM[0], @XMM[9]
2329 vst1.8 {@XMM[0]}, [sp,:128]
2331 mov r4, $fp @ preserve fp
2335 vld1.8 {@XMM[0]}, [sp,:128]
2336 veor @XMM[0], @XMM[0], @XMM[9]
2337 vst1.8 {@XMM[0]}, [$out]
2343 strb r1, [$out, #0x10]
2349 vld1.8 {@XMM[0]}, [r6]
2351 veor @XMM[0], @XMM[8]
2353 vst1.8 {@XMM[0]}, [sp,:128]
2358 vld1.8 {@XMM[0]}, [sp,:128]
2359 veor @XMM[0], @XMM[0], @XMM[8]
2360 vst1.8 {@XMM[0]}, [r6]
2368 #ifdef XTS_CHAIN_TWEAK
2369 ldr r1, [$fp, #0x20+VFP_ABI_FRAME] @ chain tweak
2371 .Lxts_dec_bzero: @ wipe key schedule [if any]
2377 #ifdef XTS_CHAIN_TWEAK
2378 vst1.8 {@XMM[8]}, [r1]
2381 ldmia sp!, {r4-r10, pc} @ return
2383 .size bsaes_xts_decrypt,.-bsaes_xts_decrypt
2390 $code =~ s/\`([^\`]*)\`/eval($1)/gem;
2395 last if (!s/^#/@/ and !/^$/);