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