1#! /usr/bin/env perl 2# Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved. 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# https://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16 17# ==================================================================== 18# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL 19# project. 20# 21# Specific modes and adaptation for Linux kernel by Ard Biesheuvel 22# of Linaro. 23# ==================================================================== 24 25# Bit-sliced AES for ARM NEON 26# 27# February 2012. 28# 29# This implementation is direct adaptation of bsaes-x86_64 module for 30# ARM NEON. Except that this module is endian-neutral [in sense that 31# it can be compiled for either endianness] by courtesy of vld1.8's 32# neutrality. Initial version doesn't implement interface to OpenSSL, 33# only low-level primitives and unsupported entry points, just enough 34# to collect performance results, which for Cortex-A8 core are: 35# 36# encrypt 19.5 cycles per byte processed with 128-bit key 37# decrypt 22.1 cycles per byte processed with 128-bit key 38# key conv. 440 cycles per 128-bit key/0.18 of 8x block 39# 40# Snapdragon S4 encrypts byte in 17.6 cycles and decrypts in 19.7, 41# which is [much] worse than anticipated (for further details see 42# http://www.openssl.org/~appro/Snapdragon-S4.html). 43# 44# Cortex-A15 manages in 14.2/16.1 cycles [when integer-only code 45# manages in 20.0 cycles]. 46# 47# When comparing to x86_64 results keep in mind that NEON unit is 48# [mostly] single-issue and thus can't [fully] benefit from 49# instruction-level parallelism. And when comparing to aes-armv4 50# results keep in mind key schedule conversion overhead (see 51# bsaes-x86_64.pl for further details)... 52# 53# <appro@openssl.org> 54 55# April-August 2013 56# Add CBC, CTR and XTS subroutines and adapt for kernel use; courtesy of Ard. 57 58$flavour = shift; 59if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; } 60else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} } 61 62if ($flavour && $flavour ne "void") { 63 $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; 64 ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or 65 ( $xlate="${dir}../../../perlasm/arm-xlate.pl" and -f $xlate) or 66 die "can't locate arm-xlate.pl"; 67 68 open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; 69 *STDOUT=*OUT; 70} else { 71 open OUT,">$output"; 72 *STDOUT=*OUT; 73} 74 75my ($inp,$out,$len,$key)=("r0","r1","r2","r3"); 76my @XMM=map("q$_",(0..15)); 77 78{ 79my ($key,$rounds,$const)=("r4","r5","r6"); 80 81sub Dlo() { shift=~m|q([1]?[0-9])|?"d".($1*2):""; } 82sub Dhi() { shift=~m|q([1]?[0-9])|?"d".($1*2+1):""; } 83 84sub Sbox { 85# input in lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb 86# output in lsb > [b0, b1, b4, b6, b3, b7, b2, b5] < msb 87my @b=@_[0..7]; 88my @t=@_[8..11]; 89my @s=@_[12..15]; 90 &InBasisChange (@b); 91 &Inv_GF256 (@b[6,5,0,3,7,1,4,2],@t,@s); 92 &OutBasisChange (@b[7,1,4,2,6,5,0,3]); 93} 94 95sub InBasisChange { 96# input in lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb 97# output in lsb > [b6, b5, b0, b3, b7, b1, b4, b2] < msb 98my @b=@_[0..7]; 99$code.=<<___; 100 veor @b[2], @b[2], @b[1] 101 veor @b[5], @b[5], @b[6] 102 veor @b[3], @b[3], @b[0] 103 veor @b[6], @b[6], @b[2] 104 veor @b[5], @b[5], @b[0] 105 106 veor @b[6], @b[6], @b[3] 107 veor @b[3], @b[3], @b[7] 108 veor @b[7], @b[7], @b[5] 109 veor @b[3], @b[3], @b[4] 110 veor @b[4], @b[4], @b[5] 111 112 veor @b[2], @b[2], @b[7] 113 veor @b[3], @b[3], @b[1] 114 veor @b[1], @b[1], @b[5] 115___ 116} 117 118sub OutBasisChange { 119# input in lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb 120# output in lsb > [b6, b1, b2, b4, b7, b0, b3, b5] < msb 121my @b=@_[0..7]; 122$code.=<<___; 123 veor @b[0], @b[0], @b[6] 124 veor @b[1], @b[1], @b[4] 125 veor @b[4], @b[4], @b[6] 126 veor @b[2], @b[2], @b[0] 127 veor @b[6], @b[6], @b[1] 128 129 veor @b[1], @b[1], @b[5] 130 veor @b[5], @b[5], @b[3] 131 veor @b[3], @b[3], @b[7] 132 veor @b[7], @b[7], @b[5] 133 veor @b[2], @b[2], @b[5] 134 135 veor @b[4], @b[4], @b[7] 136___ 137} 138 139sub InvSbox { 140# input in lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb 141# output in lsb > [b0, b1, b6, b4, b2, b7, b3, b5] < msb 142my @b=@_[0..7]; 143my @t=@_[8..11]; 144my @s=@_[12..15]; 145 &InvInBasisChange (@b); 146 &Inv_GF256 (@b[5,1,2,6,3,7,0,4],@t,@s); 147 &InvOutBasisChange (@b[3,7,0,4,5,1,2,6]); 148} 149 150sub InvInBasisChange { # OutBasisChange in reverse (with twist) 151my @b=@_[5,1,2,6,3,7,0,4]; 152$code.=<<___ 153 veor @b[1], @b[1], @b[7] 154 veor @b[4], @b[4], @b[7] 155 156 veor @b[7], @b[7], @b[5] 157 veor @b[1], @b[1], @b[3] 158 veor @b[2], @b[2], @b[5] 159 veor @b[3], @b[3], @b[7] 160 161 veor @b[6], @b[6], @b[1] 162 veor @b[2], @b[2], @b[0] 163 veor @b[5], @b[5], @b[3] 164 veor @b[4], @b[4], @b[6] 165 veor @b[0], @b[0], @b[6] 166 veor @b[1], @b[1], @b[4] 167___ 168} 169 170sub InvOutBasisChange { # InBasisChange in reverse 171my @b=@_[2,5,7,3,6,1,0,4]; 172$code.=<<___; 173 veor @b[1], @b[1], @b[5] 174 veor @b[2], @b[2], @b[7] 175 176 veor @b[3], @b[3], @b[1] 177 veor @b[4], @b[4], @b[5] 178 veor @b[7], @b[7], @b[5] 179 veor @b[3], @b[3], @b[4] 180 veor @b[5], @b[5], @b[0] 181 veor @b[3], @b[3], @b[7] 182 veor @b[6], @b[6], @b[2] 183 veor @b[2], @b[2], @b[1] 184 veor @b[6], @b[6], @b[3] 185 186 veor @b[3], @b[3], @b[0] 187 veor @b[5], @b[5], @b[6] 188___ 189} 190 191sub Mul_GF4 { 192#;************************************************************* 193#;* Mul_GF4: Input x0-x1,y0-y1 Output x0-x1 Temp t0 (8) * 194#;************************************************************* 195my ($x0,$x1,$y0,$y1,$t0,$t1)=@_; 196$code.=<<___; 197 veor $t0, $y0, $y1 198 vand $t0, $t0, $x0 199 veor $x0, $x0, $x1 200 vand $t1, $x1, $y0 201 vand $x0, $x0, $y1 202 veor $x1, $t1, $t0 203 veor $x0, $x0, $t1 204___ 205} 206 207sub Mul_GF4_N { # not used, see next subroutine 208# multiply and scale by N 209my ($x0,$x1,$y0,$y1,$t0)=@_; 210$code.=<<___; 211 veor $t0, $y0, $y1 212 vand $t0, $t0, $x0 213 veor $x0, $x0, $x1 214 vand $x1, $x1, $y0 215 vand $x0, $x0, $y1 216 veor $x1, $x1, $x0 217 veor $x0, $x0, $t0 218___ 219} 220 221sub Mul_GF4_N_GF4 { 222# interleaved Mul_GF4_N and Mul_GF4 223my ($x0,$x1,$y0,$y1,$t0, 224 $x2,$x3,$y2,$y3,$t1)=@_; 225$code.=<<___; 226 veor $t0, $y0, $y1 227 veor $t1, $y2, $y3 228 vand $t0, $t0, $x0 229 vand $t1, $t1, $x2 230 veor $x0, $x0, $x1 231 veor $x2, $x2, $x3 232 vand $x1, $x1, $y0 233 vand $x3, $x3, $y2 234 vand $x0, $x0, $y1 235 vand $x2, $x2, $y3 236 veor $x1, $x1, $x0 237 veor $x2, $x2, $x3 238 veor $x0, $x0, $t0 239 veor $x3, $x3, $t1 240___ 241} 242sub Mul_GF16_2 { 243my @x=@_[0..7]; 244my @y=@_[8..11]; 245my @t=@_[12..15]; 246$code.=<<___; 247 veor @t[0], @x[0], @x[2] 248 veor @t[1], @x[1], @x[3] 249___ 250 &Mul_GF4 (@x[0], @x[1], @y[0], @y[1], @t[2..3]); 251$code.=<<___; 252 veor @y[0], @y[0], @y[2] 253 veor @y[1], @y[1], @y[3] 254___ 255 Mul_GF4_N_GF4 (@t[0], @t[1], @y[0], @y[1], @t[3], 256 @x[2], @x[3], @y[2], @y[3], @t[2]); 257$code.=<<___; 258 veor @x[0], @x[0], @t[0] 259 veor @x[2], @x[2], @t[0] 260 veor @x[1], @x[1], @t[1] 261 veor @x[3], @x[3], @t[1] 262 263 veor @t[0], @x[4], @x[6] 264 veor @t[1], @x[5], @x[7] 265___ 266 &Mul_GF4_N_GF4 (@t[0], @t[1], @y[0], @y[1], @t[3], 267 @x[6], @x[7], @y[2], @y[3], @t[2]); 268$code.=<<___; 269 veor @y[0], @y[0], @y[2] 270 veor @y[1], @y[1], @y[3] 271___ 272 &Mul_GF4 (@x[4], @x[5], @y[0], @y[1], @t[2..3]); 273$code.=<<___; 274 veor @x[4], @x[4], @t[0] 275 veor @x[6], @x[6], @t[0] 276 veor @x[5], @x[5], @t[1] 277 veor @x[7], @x[7], @t[1] 278___ 279} 280sub Inv_GF256 { 281#;******************************************************************** 282#;* Inv_GF256: Input x0-x7 Output x0-x7 Temp t0-t3,s0-s3 (144) * 283#;******************************************************************** 284my @x=@_[0..7]; 285my @t=@_[8..11]; 286my @s=@_[12..15]; 287# direct optimizations from hardware 288$code.=<<___; 289 veor @t[3], @x[4], @x[6] 290 veor @t[2], @x[5], @x[7] 291 veor @t[1], @x[1], @x[3] 292 veor @s[1], @x[7], @x[6] 293 vmov @t[0], @t[2] 294 veor @s[0], @x[0], @x[2] 295 296 vorr @t[2], @t[2], @t[1] 297 veor @s[3], @t[3], @t[0] 298 vand @s[2], @t[3], @s[0] 299 vorr @t[3], @t[3], @s[0] 300 veor @s[0], @s[0], @t[1] 301 vand @t[0], @t[0], @t[1] 302 veor @t[1], @x[3], @x[2] 303 vand @s[3], @s[3], @s[0] 304 vand @s[1], @s[1], @t[1] 305 veor @t[1], @x[4], @x[5] 306 veor @s[0], @x[1], @x[0] 307 veor @t[3], @t[3], @s[1] 308 veor @t[2], @t[2], @s[1] 309 vand @s[1], @t[1], @s[0] 310 vorr @t[1], @t[1], @s[0] 311 veor @t[3], @t[3], @s[3] 312 veor @t[0], @t[0], @s[1] 313 veor @t[2], @t[2], @s[2] 314 veor @t[1], @t[1], @s[3] 315 veor @t[0], @t[0], @s[2] 316 vand @s[0], @x[7], @x[3] 317 veor @t[1], @t[1], @s[2] 318 vand @s[1], @x[6], @x[2] 319 vand @s[2], @x[5], @x[1] 320 vorr @s[3], @x[4], @x[0] 321 veor @t[3], @t[3], @s[0] 322 veor @t[1], @t[1], @s[2] 323 veor @t[0], @t[0], @s[3] 324 veor @t[2], @t[2], @s[1] 325 326 @ Inv_GF16 \t0, \t1, \t2, \t3, \s0, \s1, \s2, \s3 327 328 @ new smaller inversion 329 330 vand @s[2], @t[3], @t[1] 331 vmov @s[0], @t[0] 332 333 veor @s[1], @t[2], @s[2] 334 veor @s[3], @t[0], @s[2] 335 veor @s[2], @t[0], @s[2] @ @s[2]=@s[3] 336 337 vbsl @s[1], @t[1], @t[0] 338 vbsl @s[3], @t[3], @t[2] 339 veor @t[3], @t[3], @t[2] 340 341 vbsl @s[0], @s[1], @s[2] 342 vbsl @t[0], @s[2], @s[1] 343 344 vand @s[2], @s[0], @s[3] 345 veor @t[1], @t[1], @t[0] 346 347 veor @s[2], @s[2], @t[3] 348___ 349# output in s3, s2, s1, t1 350 351# Mul_GF16_2 \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \t2, \t3, \t0, \t1, \s0, \s1, \s2, \s3 352 353# Mul_GF16_2 \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \s3, \s2, \s1, \t1, \s0, \t0, \t2, \t3 354 &Mul_GF16_2(@x,@s[3,2,1],@t[1],@s[0],@t[0,2,3]); 355 356### output msb > [x3,x2,x1,x0,x7,x6,x5,x4] < lsb 357} 358 359# AES linear components 360 361sub ShiftRows { 362my @x=@_[0..7]; 363my @t=@_[8..11]; 364my $mask=pop; 365$code.=<<___; 366 vldmia $key!, {@t[0]-@t[3]} 367 veor @t[0], @t[0], @x[0] 368 veor @t[1], @t[1], @x[1] 369 vtbl.8 `&Dlo(@x[0])`, {@t[0]}, `&Dlo($mask)` 370 vtbl.8 `&Dhi(@x[0])`, {@t[0]}, `&Dhi($mask)` 371 vldmia $key!, {@t[0]} 372 veor @t[2], @t[2], @x[2] 373 vtbl.8 `&Dlo(@x[1])`, {@t[1]}, `&Dlo($mask)` 374 vtbl.8 `&Dhi(@x[1])`, {@t[1]}, `&Dhi($mask)` 375 vldmia $key!, {@t[1]} 376 veor @t[3], @t[3], @x[3] 377 vtbl.8 `&Dlo(@x[2])`, {@t[2]}, `&Dlo($mask)` 378 vtbl.8 `&Dhi(@x[2])`, {@t[2]}, `&Dhi($mask)` 379 vldmia $key!, {@t[2]} 380 vtbl.8 `&Dlo(@x[3])`, {@t[3]}, `&Dlo($mask)` 381 vtbl.8 `&Dhi(@x[3])`, {@t[3]}, `&Dhi($mask)` 382 vldmia $key!, {@t[3]} 383 veor @t[0], @t[0], @x[4] 384 veor @t[1], @t[1], @x[5] 385 vtbl.8 `&Dlo(@x[4])`, {@t[0]}, `&Dlo($mask)` 386 vtbl.8 `&Dhi(@x[4])`, {@t[0]}, `&Dhi($mask)` 387 veor @t[2], @t[2], @x[6] 388 vtbl.8 `&Dlo(@x[5])`, {@t[1]}, `&Dlo($mask)` 389 vtbl.8 `&Dhi(@x[5])`, {@t[1]}, `&Dhi($mask)` 390 veor @t[3], @t[3], @x[7] 391 vtbl.8 `&Dlo(@x[6])`, {@t[2]}, `&Dlo($mask)` 392 vtbl.8 `&Dhi(@x[6])`, {@t[2]}, `&Dhi($mask)` 393 vtbl.8 `&Dlo(@x[7])`, {@t[3]}, `&Dlo($mask)` 394 vtbl.8 `&Dhi(@x[7])`, {@t[3]}, `&Dhi($mask)` 395___ 396} 397 398sub MixColumns { 399# modified to emit output in order suitable for feeding back to aesenc[last] 400my @x=@_[0..7]; 401my @t=@_[8..15]; 402my $inv=@_[16]; # optional 403$code.=<<___; 404 vext.8 @t[0], @x[0], @x[0], #12 @ x0 <<< 32 405 vext.8 @t[1], @x[1], @x[1], #12 406 veor @x[0], @x[0], @t[0] @ x0 ^ (x0 <<< 32) 407 vext.8 @t[2], @x[2], @x[2], #12 408 veor @x[1], @x[1], @t[1] 409 vext.8 @t[3], @x[3], @x[3], #12 410 veor @x[2], @x[2], @t[2] 411 vext.8 @t[4], @x[4], @x[4], #12 412 veor @x[3], @x[3], @t[3] 413 vext.8 @t[5], @x[5], @x[5], #12 414 veor @x[4], @x[4], @t[4] 415 vext.8 @t[6], @x[6], @x[6], #12 416 veor @x[5], @x[5], @t[5] 417 vext.8 @t[7], @x[7], @x[7], #12 418 veor @x[6], @x[6], @t[6] 419 420 veor @t[1], @t[1], @x[0] 421 veor @x[7], @x[7], @t[7] 422 vext.8 @x[0], @x[0], @x[0], #8 @ (x0 ^ (x0 <<< 32)) <<< 64) 423 veor @t[2], @t[2], @x[1] 424 veor @t[0], @t[0], @x[7] 425 veor @t[1], @t[1], @x[7] 426 vext.8 @x[1], @x[1], @x[1], #8 427 veor @t[5], @t[5], @x[4] 428 veor @x[0], @x[0], @t[0] 429 veor @t[6], @t[6], @x[5] 430 veor @x[1], @x[1], @t[1] 431 vext.8 @t[0], @x[4], @x[4], #8 432 veor @t[4], @t[4], @x[3] 433 vext.8 @t[1], @x[5], @x[5], #8 434 veor @t[7], @t[7], @x[6] 435 vext.8 @x[4], @x[3], @x[3], #8 436 veor @t[3], @t[3], @x[2] 437 vext.8 @x[5], @x[7], @x[7], #8 438 veor @t[4], @t[4], @x[7] 439 vext.8 @x[3], @x[6], @x[6], #8 440 veor @t[3], @t[3], @x[7] 441 vext.8 @x[6], @x[2], @x[2], #8 442 veor @x[7], @t[1], @t[5] 443___ 444$code.=<<___ if (!$inv); 445 veor @x[2], @t[0], @t[4] 446 veor @x[4], @x[4], @t[3] 447 veor @x[5], @x[5], @t[7] 448 veor @x[3], @x[3], @t[6] 449 @ vmov @x[2], @t[0] 450 veor @x[6], @x[6], @t[2] 451 @ vmov @x[7], @t[1] 452___ 453$code.=<<___ if ($inv); 454 veor @t[3], @t[3], @x[4] 455 veor @x[5], @x[5], @t[7] 456 veor @x[2], @x[3], @t[6] 457 veor @x[3], @t[0], @t[4] 458 veor @x[4], @x[6], @t[2] 459 vmov @x[6], @t[3] 460 @ vmov @x[7], @t[1] 461___ 462} 463 464sub InvMixColumns_orig { 465my @x=@_[0..7]; 466my @t=@_[8..15]; 467 468$code.=<<___; 469 @ multiplication by 0x0e 470 vext.8 @t[7], @x[7], @x[7], #12 471 vmov @t[2], @x[2] 472 veor @x[2], @x[2], @x[5] @ 2 5 473 veor @x[7], @x[7], @x[5] @ 7 5 474 vext.8 @t[0], @x[0], @x[0], #12 475 vmov @t[5], @x[5] 476 veor @x[5], @x[5], @x[0] @ 5 0 [1] 477 veor @x[0], @x[0], @x[1] @ 0 1 478 vext.8 @t[1], @x[1], @x[1], #12 479 veor @x[1], @x[1], @x[2] @ 1 25 480 veor @x[0], @x[0], @x[6] @ 01 6 [2] 481 vext.8 @t[3], @x[3], @x[3], #12 482 veor @x[1], @x[1], @x[3] @ 125 3 [4] 483 veor @x[2], @x[2], @x[0] @ 25 016 [3] 484 veor @x[3], @x[3], @x[7] @ 3 75 485 veor @x[7], @x[7], @x[6] @ 75 6 [0] 486 vext.8 @t[6], @x[6], @x[6], #12 487 vmov @t[4], @x[4] 488 veor @x[6], @x[6], @x[4] @ 6 4 489 veor @x[4], @x[4], @x[3] @ 4 375 [6] 490 veor @x[3], @x[3], @x[7] @ 375 756=36 491 veor @x[6], @x[6], @t[5] @ 64 5 [7] 492 veor @x[3], @x[3], @t[2] @ 36 2 493 vext.8 @t[5], @t[5], @t[5], #12 494 veor @x[3], @x[3], @t[4] @ 362 4 [5] 495___ 496 my @y = @x[7,5,0,2,1,3,4,6]; 497$code.=<<___; 498 @ multiplication by 0x0b 499 veor @y[1], @y[1], @y[0] 500 veor @y[0], @y[0], @t[0] 501 vext.8 @t[2], @t[2], @t[2], #12 502 veor @y[1], @y[1], @t[1] 503 veor @y[0], @y[0], @t[5] 504 vext.8 @t[4], @t[4], @t[4], #12 505 veor @y[1], @y[1], @t[6] 506 veor @y[0], @y[0], @t[7] 507 veor @t[7], @t[7], @t[6] @ clobber t[7] 508 509 veor @y[3], @y[3], @t[0] 510 veor @y[1], @y[1], @y[0] 511 vext.8 @t[0], @t[0], @t[0], #12 512 veor @y[2], @y[2], @t[1] 513 veor @y[4], @y[4], @t[1] 514 vext.8 @t[1], @t[1], @t[1], #12 515 veor @y[2], @y[2], @t[2] 516 veor @y[3], @y[3], @t[2] 517 veor @y[5], @y[5], @t[2] 518 veor @y[2], @y[2], @t[7] 519 vext.8 @t[2], @t[2], @t[2], #12 520 veor @y[3], @y[3], @t[3] 521 veor @y[6], @y[6], @t[3] 522 veor @y[4], @y[4], @t[3] 523 veor @y[7], @y[7], @t[4] 524 vext.8 @t[3], @t[3], @t[3], #12 525 veor @y[5], @y[5], @t[4] 526 veor @y[7], @y[7], @t[7] 527 veor @t[7], @t[7], @t[5] @ clobber t[7] even more 528 veor @y[3], @y[3], @t[5] 529 veor @y[4], @y[4], @t[4] 530 531 veor @y[5], @y[5], @t[7] 532 vext.8 @t[4], @t[4], @t[4], #12 533 veor @y[6], @y[6], @t[7] 534 veor @y[4], @y[4], @t[7] 535 536 veor @t[7], @t[7], @t[5] 537 vext.8 @t[5], @t[5], @t[5], #12 538 539 @ multiplication by 0x0d 540 veor @y[4], @y[4], @y[7] 541 veor @t[7], @t[7], @t[6] @ restore t[7] 542 veor @y[7], @y[7], @t[4] 543 vext.8 @t[6], @t[6], @t[6], #12 544 veor @y[2], @y[2], @t[0] 545 veor @y[7], @y[7], @t[5] 546 vext.8 @t[7], @t[7], @t[7], #12 547 veor @y[2], @y[2], @t[2] 548 549 veor @y[3], @y[3], @y[1] 550 veor @y[1], @y[1], @t[1] 551 veor @y[0], @y[0], @t[0] 552 veor @y[3], @y[3], @t[0] 553 veor @y[1], @y[1], @t[5] 554 veor @y[0], @y[0], @t[5] 555 vext.8 @t[0], @t[0], @t[0], #12 556 veor @y[1], @y[1], @t[7] 557 veor @y[0], @y[0], @t[6] 558 veor @y[3], @y[3], @y[1] 559 veor @y[4], @y[4], @t[1] 560 vext.8 @t[1], @t[1], @t[1], #12 561 562 veor @y[7], @y[7], @t[7] 563 veor @y[4], @y[4], @t[2] 564 veor @y[5], @y[5], @t[2] 565 veor @y[2], @y[2], @t[6] 566 veor @t[6], @t[6], @t[3] @ clobber t[6] 567 vext.8 @t[2], @t[2], @t[2], #12 568 veor @y[4], @y[4], @y[7] 569 veor @y[3], @y[3], @t[6] 570 571 veor @y[6], @y[6], @t[6] 572 veor @y[5], @y[5], @t[5] 573 vext.8 @t[5], @t[5], @t[5], #12 574 veor @y[6], @y[6], @t[4] 575 vext.8 @t[4], @t[4], @t[4], #12 576 veor @y[5], @y[5], @t[6] 577 veor @y[6], @y[6], @t[7] 578 vext.8 @t[7], @t[7], @t[7], #12 579 veor @t[6], @t[6], @t[3] @ restore t[6] 580 vext.8 @t[3], @t[3], @t[3], #12 581 582 @ multiplication by 0x09 583 veor @y[4], @y[4], @y[1] 584 veor @t[1], @t[1], @y[1] @ t[1]=y[1] 585 veor @t[0], @t[0], @t[5] @ clobber t[0] 586 vext.8 @t[6], @t[6], @t[6], #12 587 veor @t[1], @t[1], @t[5] 588 veor @y[3], @y[3], @t[0] 589 veor @t[0], @t[0], @y[0] @ t[0]=y[0] 590 veor @t[1], @t[1], @t[6] 591 veor @t[6], @t[6], @t[7] @ clobber t[6] 592 veor @y[4], @y[4], @t[1] 593 veor @y[7], @y[7], @t[4] 594 veor @y[6], @y[6], @t[3] 595 veor @y[5], @y[5], @t[2] 596 veor @t[4], @t[4], @y[4] @ t[4]=y[4] 597 veor @t[3], @t[3], @y[3] @ t[3]=y[3] 598 veor @t[5], @t[5], @y[5] @ t[5]=y[5] 599 veor @t[2], @t[2], @y[2] @ t[2]=y[2] 600 veor @t[3], @t[3], @t[7] 601 veor @XMM[5], @t[5], @t[6] 602 veor @XMM[6], @t[6], @y[6] @ t[6]=y[6] 603 veor @XMM[2], @t[2], @t[6] 604 veor @XMM[7], @t[7], @y[7] @ t[7]=y[7] 605 606 vmov @XMM[0], @t[0] 607 vmov @XMM[1], @t[1] 608 @ vmov @XMM[2], @t[2] 609 vmov @XMM[3], @t[3] 610 vmov @XMM[4], @t[4] 611 @ vmov @XMM[5], @t[5] 612 @ vmov @XMM[6], @t[6] 613 @ vmov @XMM[7], @t[7] 614___ 615} 616 617sub InvMixColumns { 618my @x=@_[0..7]; 619my @t=@_[8..15]; 620 621# Thanks to Jussi Kivilinna for providing pointer to 622# 623# | 0e 0b 0d 09 | | 02 03 01 01 | | 05 00 04 00 | 624# | 09 0e 0b 0d | = | 01 02 03 01 | x | 00 05 00 04 | 625# | 0d 09 0e 0b | | 01 01 02 03 | | 04 00 05 00 | 626# | 0b 0d 09 0e | | 03 01 01 02 | | 00 04 00 05 | 627 628$code.=<<___; 629 @ multiplication by 0x05-0x00-0x04-0x00 630 vext.8 @t[0], @x[0], @x[0], #8 631 vext.8 @t[6], @x[6], @x[6], #8 632 vext.8 @t[7], @x[7], @x[7], #8 633 veor @t[0], @t[0], @x[0] 634 vext.8 @t[1], @x[1], @x[1], #8 635 veor @t[6], @t[6], @x[6] 636 vext.8 @t[2], @x[2], @x[2], #8 637 veor @t[7], @t[7], @x[7] 638 vext.8 @t[3], @x[3], @x[3], #8 639 veor @t[1], @t[1], @x[1] 640 vext.8 @t[4], @x[4], @x[4], #8 641 veor @t[2], @t[2], @x[2] 642 vext.8 @t[5], @x[5], @x[5], #8 643 veor @t[3], @t[3], @x[3] 644 veor @t[4], @t[4], @x[4] 645 veor @t[5], @t[5], @x[5] 646 647 veor @x[0], @x[0], @t[6] 648 veor @x[1], @x[1], @t[6] 649 veor @x[2], @x[2], @t[0] 650 veor @x[4], @x[4], @t[2] 651 veor @x[3], @x[3], @t[1] 652 veor @x[1], @x[1], @t[7] 653 veor @x[2], @x[2], @t[7] 654 veor @x[4], @x[4], @t[6] 655 veor @x[5], @x[5], @t[3] 656 veor @x[3], @x[3], @t[6] 657 veor @x[6], @x[6], @t[4] 658 veor @x[4], @x[4], @t[7] 659 veor @x[5], @x[5], @t[7] 660 veor @x[7], @x[7], @t[5] 661___ 662 &MixColumns (@x,@t,1); # flipped 2<->3 and 4<->6 663} 664 665sub swapmove { 666my ($a,$b,$n,$mask,$t)=@_; 667$code.=<<___; 668 vshr.u64 $t, $b, #$n 669 veor $t, $t, $a 670 vand $t, $t, $mask 671 veor $a, $a, $t 672 vshl.u64 $t, $t, #$n 673 veor $b, $b, $t 674___ 675} 676sub swapmove2x { 677my ($a0,$b0,$a1,$b1,$n,$mask,$t0,$t1)=@_; 678$code.=<<___; 679 vshr.u64 $t0, $b0, #$n 680 vshr.u64 $t1, $b1, #$n 681 veor $t0, $t0, $a0 682 veor $t1, $t1, $a1 683 vand $t0, $t0, $mask 684 vand $t1, $t1, $mask 685 veor $a0, $a0, $t0 686 vshl.u64 $t0, $t0, #$n 687 veor $a1, $a1, $t1 688 vshl.u64 $t1, $t1, #$n 689 veor $b0, $b0, $t0 690 veor $b1, $b1, $t1 691___ 692} 693 694sub bitslice { 695my @x=reverse(@_[0..7]); 696my ($t0,$t1,$t2,$t3)=@_[8..11]; 697$code.=<<___; 698 vmov.i8 $t0,#0x55 @ compose .LBS0 699 vmov.i8 $t1,#0x33 @ compose .LBS1 700___ 701 &swapmove2x(@x[0,1,2,3],1,$t0,$t2,$t3); 702 &swapmove2x(@x[4,5,6,7],1,$t0,$t2,$t3); 703$code.=<<___; 704 vmov.i8 $t0,#0x0f @ compose .LBS2 705___ 706 &swapmove2x(@x[0,2,1,3],2,$t1,$t2,$t3); 707 &swapmove2x(@x[4,6,5,7],2,$t1,$t2,$t3); 708 709 &swapmove2x(@x[0,4,1,5],4,$t0,$t2,$t3); 710 &swapmove2x(@x[2,6,3,7],4,$t0,$t2,$t3); 711} 712 713$code.=<<___; 714#ifndef __KERNEL__ 715# define VFP_ABI_PUSH vstmdb sp!,{d8-d15} 716# define VFP_ABI_POP vldmia sp!,{d8-d15} 717# define VFP_ABI_FRAME 0x40 718#else 719# define VFP_ABI_PUSH 720# define VFP_ABI_POP 721# define VFP_ABI_FRAME 0 722# define BSAES_ASM_EXTENDED_KEY 723# define XTS_CHAIN_TWEAK 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#if defined(__thumb2__) || defined(__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#if defined(__thumb2__) || defined(__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#if defined(__thumb2__) || defined(__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.global bsaes_cbc_encrypt 1121.type bsaes_cbc_encrypt,%function 1122.align 5 1123bsaes_cbc_encrypt: 1124 @ In OpenSSL, this function had a fallback to aes_nohw_cbc_encrypt for 1125 @ short inputs. We patch this out, using bsaes for all input sizes. 1126 1127 @ it is up to the caller to make sure we are called with enc == 0 1128 1129 mov ip, sp 1130 stmdb sp!, {r4-r10, lr} 1131 VFP_ABI_PUSH 1132 ldr $ivp, [ip] @ IV is 1st arg on the stack 1133 mov $len, $len, lsr#4 @ len in 16 byte blocks 1134 sub sp, #0x10 @ scratch space to carry over the IV 1135 mov $fp, sp @ save sp 1136 1137 ldr $rounds, [$key, #240] @ get # of rounds 1138#ifndef BSAES_ASM_EXTENDED_KEY 1139 @ allocate the key schedule on the stack 1140 sub r12, sp, $rounds, lsl#7 @ 128 bytes per inner round key 1141 add r12, #`128-32` @ sifze of bit-slices key schedule 1142 1143 @ populate the key schedule 1144 mov r4, $key @ pass key 1145 mov r5, $rounds @ pass # of rounds 1146 mov sp, r12 @ sp is $keysched 1147 bl _bsaes_key_convert 1148 vldmia $keysched, {@XMM[6]} 1149 vstmia r12, {@XMM[15]} @ save last round key 1150 veor @XMM[7], @XMM[7], @XMM[6] @ fix up round 0 key 1151 vstmia $keysched, {@XMM[7]} 1152#else 1153 ldr r12, [$key, #244] 1154 eors r12, #1 1155 beq 0f 1156 1157 @ populate the key schedule 1158 str r12, [$key, #244] 1159 mov r4, $key @ pass key 1160 mov r5, $rounds @ pass # of rounds 1161 add r12, $key, #248 @ pass key schedule 1162 bl _bsaes_key_convert 1163 add r4, $key, #248 1164 vldmia r4, {@XMM[6]} 1165 vstmia r12, {@XMM[15]} @ save last round key 1166 veor @XMM[7], @XMM[7], @XMM[6] @ fix up round 0 key 1167 vstmia r4, {@XMM[7]} 1168 1169.align 2 11700: 1171#endif 1172 1173 vld1.8 {@XMM[15]}, [$ivp] @ load IV 1174 b .Lcbc_dec_loop 1175 1176.align 4 1177.Lcbc_dec_loop: 1178 subs $len, $len, #0x8 1179 bmi .Lcbc_dec_loop_finish 1180 1181 vld1.8 {@XMM[0]-@XMM[1]}, [$inp]! @ load input 1182 vld1.8 {@XMM[2]-@XMM[3]}, [$inp]! 1183#ifndef BSAES_ASM_EXTENDED_KEY 1184 mov r4, $keysched @ pass the key 1185#else 1186 add r4, $key, #248 1187#endif 1188 vld1.8 {@XMM[4]-@XMM[5]}, [$inp]! 1189 mov r5, $rounds 1190 vld1.8 {@XMM[6]-@XMM[7]}, [$inp] 1191 sub $inp, $inp, #0x60 1192 vstmia $fp, {@XMM[15]} @ put aside IV 1193 1194 bl _bsaes_decrypt8 1195 1196 vldmia $fp, {@XMM[14]} @ reload IV 1197 vld1.8 {@XMM[8]-@XMM[9]}, [$inp]! @ reload input 1198 veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV 1199 vld1.8 {@XMM[10]-@XMM[11]}, [$inp]! 1200 veor @XMM[1], @XMM[1], @XMM[8] 1201 veor @XMM[6], @XMM[6], @XMM[9] 1202 vld1.8 {@XMM[12]-@XMM[13]}, [$inp]! 1203 veor @XMM[4], @XMM[4], @XMM[10] 1204 veor @XMM[2], @XMM[2], @XMM[11] 1205 vld1.8 {@XMM[14]-@XMM[15]}, [$inp]! 1206 veor @XMM[7], @XMM[7], @XMM[12] 1207 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output 1208 veor @XMM[3], @XMM[3], @XMM[13] 1209 vst1.8 {@XMM[6]}, [$out]! 1210 veor @XMM[5], @XMM[5], @XMM[14] 1211 vst1.8 {@XMM[4]}, [$out]! 1212 vst1.8 {@XMM[2]}, [$out]! 1213 vst1.8 {@XMM[7]}, [$out]! 1214 vst1.8 {@XMM[3]}, [$out]! 1215 vst1.8 {@XMM[5]}, [$out]! 1216 1217 b .Lcbc_dec_loop 1218 1219.Lcbc_dec_loop_finish: 1220 adds $len, $len, #8 1221 beq .Lcbc_dec_done 1222 1223 @ Set up most parameters for the _bsaes_decrypt8 call. 1224#ifndef BSAES_ASM_EXTENDED_KEY 1225 mov r4, $keysched @ pass the key 1226#else 1227 add r4, $key, #248 1228#endif 1229 mov r5, $rounds 1230 vstmia $fp, {@XMM[15]} @ put aside IV 1231 1232 vld1.8 {@XMM[0]}, [$inp]! @ load input 1233 cmp $len, #2 1234 blo .Lcbc_dec_one 1235 vld1.8 {@XMM[1]}, [$inp]! 1236 beq .Lcbc_dec_two 1237 vld1.8 {@XMM[2]}, [$inp]! 1238 cmp $len, #4 1239 blo .Lcbc_dec_three 1240 vld1.8 {@XMM[3]}, [$inp]! 1241 beq .Lcbc_dec_four 1242 vld1.8 {@XMM[4]}, [$inp]! 1243 cmp $len, #6 1244 blo .Lcbc_dec_five 1245 vld1.8 {@XMM[5]}, [$inp]! 1246 beq .Lcbc_dec_six 1247 vld1.8 {@XMM[6]}, [$inp]! 1248 sub $inp, $inp, #0x70 1249 1250 bl _bsaes_decrypt8 1251 1252 vldmia $fp, {@XMM[14]} @ reload IV 1253 vld1.8 {@XMM[8]-@XMM[9]}, [$inp]! @ reload input 1254 veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV 1255 vld1.8 {@XMM[10]-@XMM[11]}, [$inp]! 1256 veor @XMM[1], @XMM[1], @XMM[8] 1257 veor @XMM[6], @XMM[6], @XMM[9] 1258 vld1.8 {@XMM[12]-@XMM[13]}, [$inp]! 1259 veor @XMM[4], @XMM[4], @XMM[10] 1260 veor @XMM[2], @XMM[2], @XMM[11] 1261 vld1.8 {@XMM[15]}, [$inp]! 1262 veor @XMM[7], @XMM[7], @XMM[12] 1263 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output 1264 veor @XMM[3], @XMM[3], @XMM[13] 1265 vst1.8 {@XMM[6]}, [$out]! 1266 vst1.8 {@XMM[4]}, [$out]! 1267 vst1.8 {@XMM[2]}, [$out]! 1268 vst1.8 {@XMM[7]}, [$out]! 1269 vst1.8 {@XMM[3]}, [$out]! 1270 b .Lcbc_dec_done 1271.align 4 1272.Lcbc_dec_six: 1273 sub $inp, $inp, #0x60 1274 bl _bsaes_decrypt8 1275 vldmia $fp,{@XMM[14]} @ reload IV 1276 vld1.8 {@XMM[8]-@XMM[9]}, [$inp]! @ reload input 1277 veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV 1278 vld1.8 {@XMM[10]-@XMM[11]}, [$inp]! 1279 veor @XMM[1], @XMM[1], @XMM[8] 1280 veor @XMM[6], @XMM[6], @XMM[9] 1281 vld1.8 {@XMM[12]}, [$inp]! 1282 veor @XMM[4], @XMM[4], @XMM[10] 1283 veor @XMM[2], @XMM[2], @XMM[11] 1284 vld1.8 {@XMM[15]}, [$inp]! 1285 veor @XMM[7], @XMM[7], @XMM[12] 1286 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output 1287 vst1.8 {@XMM[6]}, [$out]! 1288 vst1.8 {@XMM[4]}, [$out]! 1289 vst1.8 {@XMM[2]}, [$out]! 1290 vst1.8 {@XMM[7]}, [$out]! 1291 b .Lcbc_dec_done 1292.align 4 1293.Lcbc_dec_five: 1294 sub $inp, $inp, #0x50 1295 bl _bsaes_decrypt8 1296 vldmia $fp, {@XMM[14]} @ reload IV 1297 vld1.8 {@XMM[8]-@XMM[9]}, [$inp]! @ reload input 1298 veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV 1299 vld1.8 {@XMM[10]-@XMM[11]}, [$inp]! 1300 veor @XMM[1], @XMM[1], @XMM[8] 1301 veor @XMM[6], @XMM[6], @XMM[9] 1302 vld1.8 {@XMM[15]}, [$inp]! 1303 veor @XMM[4], @XMM[4], @XMM[10] 1304 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output 1305 veor @XMM[2], @XMM[2], @XMM[11] 1306 vst1.8 {@XMM[6]}, [$out]! 1307 vst1.8 {@XMM[4]}, [$out]! 1308 vst1.8 {@XMM[2]}, [$out]! 1309 b .Lcbc_dec_done 1310.align 4 1311.Lcbc_dec_four: 1312 sub $inp, $inp, #0x40 1313 bl _bsaes_decrypt8 1314 vldmia $fp, {@XMM[14]} @ reload IV 1315 vld1.8 {@XMM[8]-@XMM[9]}, [$inp]! @ reload input 1316 veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV 1317 vld1.8 {@XMM[10]}, [$inp]! 1318 veor @XMM[1], @XMM[1], @XMM[8] 1319 veor @XMM[6], @XMM[6], @XMM[9] 1320 vld1.8 {@XMM[15]}, [$inp]! 1321 veor @XMM[4], @XMM[4], @XMM[10] 1322 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output 1323 vst1.8 {@XMM[6]}, [$out]! 1324 vst1.8 {@XMM[4]}, [$out]! 1325 b .Lcbc_dec_done 1326.align 4 1327.Lcbc_dec_three: 1328 sub $inp, $inp, #0x30 1329 bl _bsaes_decrypt8 1330 vldmia $fp, {@XMM[14]} @ reload IV 1331 vld1.8 {@XMM[8]-@XMM[9]}, [$inp]! @ reload input 1332 veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV 1333 vld1.8 {@XMM[15]}, [$inp]! 1334 veor @XMM[1], @XMM[1], @XMM[8] 1335 veor @XMM[6], @XMM[6], @XMM[9] 1336 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output 1337 vst1.8 {@XMM[6]}, [$out]! 1338 b .Lcbc_dec_done 1339.align 4 1340.Lcbc_dec_two: 1341 sub $inp, $inp, #0x20 1342 bl _bsaes_decrypt8 1343 vldmia $fp, {@XMM[14]} @ reload IV 1344 vld1.8 {@XMM[8]}, [$inp]! @ reload input 1345 veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV 1346 vld1.8 {@XMM[15]}, [$inp]! @ reload input 1347 veor @XMM[1], @XMM[1], @XMM[8] 1348 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output 1349 b .Lcbc_dec_done 1350.align 4 1351.Lcbc_dec_one: 1352 sub $inp, $inp, #0x10 1353 bl _bsaes_decrypt8 1354 vldmia $fp, {@XMM[14]} @ reload IV 1355 vld1.8 {@XMM[15]}, [$inp]! @ reload input 1356 veor @XMM[0], @XMM[0], @XMM[14] @ ^= IV 1357 vst1.8 {@XMM[0]}, [$out]! @ write output 1358 1359.Lcbc_dec_done: 1360#ifndef BSAES_ASM_EXTENDED_KEY 1361 vmov.i32 q0, #0 1362 vmov.i32 q1, #0 1363.Lcbc_dec_bzero: @ wipe key schedule [if any] 1364 vstmia $keysched!, {q0-q1} 1365 cmp $keysched, $fp 1366 bne .Lcbc_dec_bzero 1367#endif 1368 1369 mov sp, $fp 1370 add sp, #0x10 @ add sp,$fp,#0x10 is no good for thumb 1371 vst1.8 {@XMM[15]}, [$ivp] @ return IV 1372 VFP_ABI_POP 1373 ldmia sp!, {r4-r10, pc} 1374.size bsaes_cbc_encrypt,.-bsaes_cbc_encrypt 1375___ 1376} 1377{ 1378my ($inp,$out,$len,$key, $ctr,$fp,$rounds)=(map("r$_",(0..3,8..10))); 1379my $const = "r6"; # shared with _bsaes_encrypt8_alt 1380my $keysched = "sp"; 1381 1382$code.=<<___; 1383.global bsaes_ctr32_encrypt_blocks 1384.type bsaes_ctr32_encrypt_blocks,%function 1385.align 5 1386bsaes_ctr32_encrypt_blocks: 1387 @ In OpenSSL, short inputs fall back to aes_nohw_* here. We patch this 1388 @ out to retain a constant-time implementation. 1389 mov ip, sp 1390 stmdb sp!, {r4-r10, lr} 1391 VFP_ABI_PUSH 1392 ldr $ctr, [ip] @ ctr is 1st arg on the stack 1393 sub sp, sp, #0x10 @ scratch space to carry over the ctr 1394 mov $fp, sp @ save sp 1395 1396 ldr $rounds, [$key, #240] @ get # of rounds 1397#ifndef BSAES_ASM_EXTENDED_KEY 1398 @ allocate the key schedule on the stack 1399 sub r12, sp, $rounds, lsl#7 @ 128 bytes per inner round key 1400 add r12, #`128-32` @ size of bit-sliced key schedule 1401 1402 @ populate the key schedule 1403 mov r4, $key @ pass key 1404 mov r5, $rounds @ pass # of rounds 1405 mov sp, r12 @ sp is $keysched 1406 bl _bsaes_key_convert 1407 veor @XMM[7],@XMM[7],@XMM[15] @ fix up last round key 1408 vstmia r12, {@XMM[7]} @ save last round key 1409 1410 vld1.8 {@XMM[0]}, [$ctr] @ load counter 1411#ifdef __APPLE__ 1412 mov $ctr, #:lower16:(.LREVM0SR-.LM0) 1413 add $ctr, $const, $ctr 1414#else 1415 add $ctr, $const, #.LREVM0SR-.LM0 @ borrow $ctr 1416#endif 1417 vldmia $keysched, {@XMM[4]} @ load round0 key 1418#else 1419 ldr r12, [$key, #244] 1420 eors r12, #1 1421 beq 0f 1422 1423 @ populate the key schedule 1424 str r12, [$key, #244] 1425 mov r4, $key @ pass key 1426 mov r5, $rounds @ pass # of rounds 1427 add r12, $key, #248 @ pass key schedule 1428 bl _bsaes_key_convert 1429 veor @XMM[7],@XMM[7],@XMM[15] @ fix up last round key 1430 vstmia r12, {@XMM[7]} @ save last round key 1431 1432.align 2 14330: add r12, $key, #248 1434 vld1.8 {@XMM[0]}, [$ctr] @ load counter 1435 adrl $ctr, .LREVM0SR @ borrow $ctr 1436 vldmia r12, {@XMM[4]} @ load round0 key 1437 sub sp, #0x10 @ place for adjusted round0 key 1438#endif 1439 1440 vmov.i32 @XMM[8],#1 @ compose 1<<96 1441 veor @XMM[9],@XMM[9],@XMM[9] 1442 vrev32.8 @XMM[0],@XMM[0] 1443 vext.8 @XMM[8],@XMM[9],@XMM[8],#4 1444 vrev32.8 @XMM[4],@XMM[4] 1445 vadd.u32 @XMM[9],@XMM[8],@XMM[8] @ compose 2<<96 1446 vstmia $keysched, {@XMM[4]} @ save adjusted round0 key 1447 b .Lctr_enc_loop 1448 1449.align 4 1450.Lctr_enc_loop: 1451 vadd.u32 @XMM[10], @XMM[8], @XMM[9] @ compose 3<<96 1452 vadd.u32 @XMM[1], @XMM[0], @XMM[8] @ +1 1453 vadd.u32 @XMM[2], @XMM[0], @XMM[9] @ +2 1454 vadd.u32 @XMM[3], @XMM[0], @XMM[10] @ +3 1455 vadd.u32 @XMM[4], @XMM[1], @XMM[10] 1456 vadd.u32 @XMM[5], @XMM[2], @XMM[10] 1457 vadd.u32 @XMM[6], @XMM[3], @XMM[10] 1458 vadd.u32 @XMM[7], @XMM[4], @XMM[10] 1459 vadd.u32 @XMM[10], @XMM[5], @XMM[10] @ next counter 1460 1461 @ Borrow prologue from _bsaes_encrypt8 to use the opportunity 1462 @ to flip byte order in 32-bit counter 1463 1464 vldmia $keysched, {@XMM[9]} @ load round0 key 1465#ifndef BSAES_ASM_EXTENDED_KEY 1466 add r4, $keysched, #0x10 @ pass next round key 1467#else 1468 add r4, $key, #`248+16` 1469#endif 1470 vldmia $ctr, {@XMM[8]} @ .LREVM0SR 1471 mov r5, $rounds @ pass rounds 1472 vstmia $fp, {@XMM[10]} @ save next counter 1473#ifdef __APPLE__ 1474 mov $const, #:lower16:(.LREVM0SR-.LSR) 1475 sub $const, $ctr, $const 1476#else 1477 sub $const, $ctr, #.LREVM0SR-.LSR @ pass constants 1478#endif 1479 1480 bl _bsaes_encrypt8_alt 1481 1482 subs $len, $len, #8 1483 blo .Lctr_enc_loop_done 1484 1485 vld1.8 {@XMM[8]-@XMM[9]}, [$inp]! @ load input 1486 vld1.8 {@XMM[10]-@XMM[11]}, [$inp]! 1487 veor @XMM[0], @XMM[8] 1488 veor @XMM[1], @XMM[9] 1489 vld1.8 {@XMM[12]-@XMM[13]}, [$inp]! 1490 veor @XMM[4], @XMM[10] 1491 veor @XMM[6], @XMM[11] 1492 vld1.8 {@XMM[14]-@XMM[15]}, [$inp]! 1493 veor @XMM[3], @XMM[12] 1494 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! @ write output 1495 veor @XMM[7], @XMM[13] 1496 veor @XMM[2], @XMM[14] 1497 vst1.8 {@XMM[4]}, [$out]! 1498 veor @XMM[5], @XMM[15] 1499 vst1.8 {@XMM[6]}, [$out]! 1500 vmov.i32 @XMM[8], #1 @ compose 1<<96 1501 vst1.8 {@XMM[3]}, [$out]! 1502 veor @XMM[9], @XMM[9], @XMM[9] 1503 vst1.8 {@XMM[7]}, [$out]! 1504 vext.8 @XMM[8], @XMM[9], @XMM[8], #4 1505 vst1.8 {@XMM[2]}, [$out]! 1506 vadd.u32 @XMM[9],@XMM[8],@XMM[8] @ compose 2<<96 1507 vst1.8 {@XMM[5]}, [$out]! 1508 vldmia $fp, {@XMM[0]} @ load counter 1509 1510 bne .Lctr_enc_loop 1511 b .Lctr_enc_done 1512 1513.align 4 1514.Lctr_enc_loop_done: 1515 add $len, $len, #8 1516 vld1.8 {@XMM[8]}, [$inp]! @ load input 1517 veor @XMM[0], @XMM[8] 1518 vst1.8 {@XMM[0]}, [$out]! @ write output 1519 cmp $len, #2 1520 blo .Lctr_enc_done 1521 vld1.8 {@XMM[9]}, [$inp]! 1522 veor @XMM[1], @XMM[9] 1523 vst1.8 {@XMM[1]}, [$out]! 1524 beq .Lctr_enc_done 1525 vld1.8 {@XMM[10]}, [$inp]! 1526 veor @XMM[4], @XMM[10] 1527 vst1.8 {@XMM[4]}, [$out]! 1528 cmp $len, #4 1529 blo .Lctr_enc_done 1530 vld1.8 {@XMM[11]}, [$inp]! 1531 veor @XMM[6], @XMM[11] 1532 vst1.8 {@XMM[6]}, [$out]! 1533 beq .Lctr_enc_done 1534 vld1.8 {@XMM[12]}, [$inp]! 1535 veor @XMM[3], @XMM[12] 1536 vst1.8 {@XMM[3]}, [$out]! 1537 cmp $len, #6 1538 blo .Lctr_enc_done 1539 vld1.8 {@XMM[13]}, [$inp]! 1540 veor @XMM[7], @XMM[13] 1541 vst1.8 {@XMM[7]}, [$out]! 1542 beq .Lctr_enc_done 1543 vld1.8 {@XMM[14]}, [$inp] 1544 veor @XMM[2], @XMM[14] 1545 vst1.8 {@XMM[2]}, [$out]! 1546 1547.Lctr_enc_done: 1548 vmov.i32 q0, #0 1549 vmov.i32 q1, #0 1550#ifndef BSAES_ASM_EXTENDED_KEY 1551.Lctr_enc_bzero: @ wipe key schedule [if any] 1552 vstmia $keysched!, {q0-q1} 1553 cmp $keysched, $fp 1554 bne .Lctr_enc_bzero 1555#else 1556 vstmia $keysched, {q0-q1} 1557#endif 1558 1559 mov sp, $fp 1560 add sp, #0x10 @ add sp,$fp,#0x10 is no good for thumb 1561 VFP_ABI_POP 1562 ldmia sp!, {r4-r10, pc} @ return 1563 1564 @ OpenSSL contains aes_nohw_* fallback code here. We patch this 1565 @ out to retain a constant-time implementation. 1566.size bsaes_ctr32_encrypt_blocks,.-bsaes_ctr32_encrypt_blocks 1567___ 1568} 1569# In BorinSSL, we patch XTS support out. 1570if (0) { 1571###################################################################### 1572# void bsaes_xts_[en|de]crypt(const char *inp,char *out,size_t len, 1573# const AES_KEY *key1, const AES_KEY *key2, 1574# const unsigned char iv[16]); 1575# 1576my ($inp,$out,$len,$key,$rounds,$magic,$fp)=(map("r$_",(7..10,1..3))); 1577my $const="r6"; # returned by _bsaes_key_convert 1578my $twmask=@XMM[5]; 1579my @T=@XMM[6..7]; 1580 1581$code.=<<___; 1582.globl bsaes_xts_encrypt 1583.type bsaes_xts_encrypt,%function 1584.align 4 1585bsaes_xts_encrypt: 1586 mov ip, sp 1587 stmdb sp!, {r4-r10, lr} @ 0x20 1588 VFP_ABI_PUSH 1589 mov r6, sp @ future $fp 1590 1591 mov $inp, r0 1592 mov $out, r1 1593 mov $len, r2 1594 mov $key, r3 1595 1596 sub r0, sp, #0x10 @ 0x10 1597 bic r0, #0xf @ align at 16 bytes 1598 mov sp, r0 1599 1600#ifdef XTS_CHAIN_TWEAK 1601 ldr r0, [ip] @ pointer to input tweak 1602#else 1603 @ generate initial tweak 1604 ldr r0, [ip, #4] @ iv[] 1605 mov r1, sp 1606 ldr r2, [ip, #0] @ key2 1607 bl aes_nohw_encrypt 1608 mov r0,sp @ pointer to initial tweak 1609#endif 1610 1611 ldr $rounds, [$key, #240] @ get # of rounds 1612 mov $fp, r6 1613#ifndef BSAES_ASM_EXTENDED_KEY 1614 @ allocate the key schedule on the stack 1615 sub r12, sp, $rounds, lsl#7 @ 128 bytes per inner round key 1616 @ add r12, #`128-32` @ size of bit-sliced key schedule 1617 sub r12, #`32+16` @ place for tweak[9] 1618 1619 @ populate the key schedule 1620 mov r4, $key @ pass key 1621 mov r5, $rounds @ pass # of rounds 1622 mov sp, r12 1623 add r12, #0x90 @ pass key schedule 1624 bl _bsaes_key_convert 1625 veor @XMM[7], @XMM[7], @XMM[15] @ fix up last round key 1626 vstmia r12, {@XMM[7]} @ save last round key 1627#else 1628 ldr r12, [$key, #244] 1629 eors r12, #1 1630 beq 0f 1631 1632 str r12, [$key, #244] 1633 mov r4, $key @ pass key 1634 mov r5, $rounds @ pass # of rounds 1635 add r12, $key, #248 @ pass key schedule 1636 bl _bsaes_key_convert 1637 veor @XMM[7], @XMM[7], @XMM[15] @ fix up last round key 1638 vstmia r12, {@XMM[7]} 1639 1640.align 2 16410: sub sp, #0x90 @ place for tweak[9] 1642#endif 1643 1644 vld1.8 {@XMM[8]}, [r0] @ initial tweak 1645 adr $magic, .Lxts_magic 1646 1647 subs $len, #0x80 1648 blo .Lxts_enc_short 1649 b .Lxts_enc_loop 1650 1651.align 4 1652.Lxts_enc_loop: 1653 vldmia $magic, {$twmask} @ load XTS magic 1654 vshr.s64 @T[0], @XMM[8], #63 1655 mov r0, sp 1656 vand @T[0], @T[0], $twmask 1657___ 1658for($i=9;$i<16;$i++) { 1659$code.=<<___; 1660 vadd.u64 @XMM[$i], @XMM[$i-1], @XMM[$i-1] 1661 vst1.64 {@XMM[$i-1]}, [r0,:128]! 1662 vswp `&Dhi("@T[0]")`,`&Dlo("@T[0]")` 1663 vshr.s64 @T[1], @XMM[$i], #63 1664 veor @XMM[$i], @XMM[$i], @T[0] 1665 vand @T[1], @T[1], $twmask 1666___ 1667 @T=reverse(@T); 1668 1669$code.=<<___ if ($i>=10); 1670 vld1.8 {@XMM[$i-10]}, [$inp]! 1671___ 1672$code.=<<___ if ($i>=11); 1673 veor @XMM[$i-11], @XMM[$i-11], @XMM[$i-3] 1674___ 1675} 1676$code.=<<___; 1677 vadd.u64 @XMM[8], @XMM[15], @XMM[15] 1678 vst1.64 {@XMM[15]}, [r0,:128]! 1679 vswp `&Dhi("@T[0]")`,`&Dlo("@T[0]")` 1680 veor @XMM[8], @XMM[8], @T[0] 1681 vst1.64 {@XMM[8]}, [r0,:128] @ next round tweak 1682 1683 vld1.8 {@XMM[6]-@XMM[7]}, [$inp]! 1684 veor @XMM[5], @XMM[5], @XMM[13] 1685#ifndef BSAES_ASM_EXTENDED_KEY 1686 add r4, sp, #0x90 @ pass key schedule 1687#else 1688 add r4, $key, #248 @ pass key schedule 1689#endif 1690 veor @XMM[6], @XMM[6], @XMM[14] 1691 mov r5, $rounds @ pass rounds 1692 veor @XMM[7], @XMM[7], @XMM[15] 1693 mov r0, sp 1694 1695 bl _bsaes_encrypt8 1696 1697 vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]! 1698 vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]! 1699 veor @XMM[0], @XMM[0], @XMM[ 8] 1700 vld1.64 {@XMM[12]-@XMM[13]}, [r0,:128]! 1701 veor @XMM[1], @XMM[1], @XMM[ 9] 1702 veor @XMM[8], @XMM[4], @XMM[10] 1703 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! 1704 veor @XMM[9], @XMM[6], @XMM[11] 1705 vld1.64 {@XMM[14]-@XMM[15]}, [r0,:128]! 1706 veor @XMM[10], @XMM[3], @XMM[12] 1707 vst1.8 {@XMM[8]-@XMM[9]}, [$out]! 1708 veor @XMM[11], @XMM[7], @XMM[13] 1709 veor @XMM[12], @XMM[2], @XMM[14] 1710 vst1.8 {@XMM[10]-@XMM[11]}, [$out]! 1711 veor @XMM[13], @XMM[5], @XMM[15] 1712 vst1.8 {@XMM[12]-@XMM[13]}, [$out]! 1713 1714 vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak 1715 1716 subs $len, #0x80 1717 bpl .Lxts_enc_loop 1718 1719.Lxts_enc_short: 1720 adds $len, #0x70 1721 bmi .Lxts_enc_done 1722 1723 vldmia $magic, {$twmask} @ load XTS magic 1724 vshr.s64 @T[0], @XMM[8], #63 1725 mov r0, sp 1726 vand @T[0], @T[0], $twmask 1727___ 1728for($i=9;$i<16;$i++) { 1729$code.=<<___; 1730 vadd.u64 @XMM[$i], @XMM[$i-1], @XMM[$i-1] 1731 vst1.64 {@XMM[$i-1]}, [r0,:128]! 1732 vswp `&Dhi("@T[0]")`,`&Dlo("@T[0]")` 1733 vshr.s64 @T[1], @XMM[$i], #63 1734 veor @XMM[$i], @XMM[$i], @T[0] 1735 vand @T[1], @T[1], $twmask 1736___ 1737 @T=reverse(@T); 1738 1739$code.=<<___ if ($i>=10); 1740 vld1.8 {@XMM[$i-10]}, [$inp]! 1741 subs $len, #0x10 1742 bmi .Lxts_enc_`$i-9` 1743___ 1744$code.=<<___ if ($i>=11); 1745 veor @XMM[$i-11], @XMM[$i-11], @XMM[$i-3] 1746___ 1747} 1748$code.=<<___; 1749 sub $len, #0x10 1750 vst1.64 {@XMM[15]}, [r0,:128] @ next round tweak 1751 1752 vld1.8 {@XMM[6]}, [$inp]! 1753 veor @XMM[5], @XMM[5], @XMM[13] 1754#ifndef BSAES_ASM_EXTENDED_KEY 1755 add r4, sp, #0x90 @ pass key schedule 1756#else 1757 add r4, $key, #248 @ pass key schedule 1758#endif 1759 veor @XMM[6], @XMM[6], @XMM[14] 1760 mov r5, $rounds @ pass rounds 1761 mov r0, sp 1762 1763 bl _bsaes_encrypt8 1764 1765 vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]! 1766 vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]! 1767 veor @XMM[0], @XMM[0], @XMM[ 8] 1768 vld1.64 {@XMM[12]-@XMM[13]}, [r0,:128]! 1769 veor @XMM[1], @XMM[1], @XMM[ 9] 1770 veor @XMM[8], @XMM[4], @XMM[10] 1771 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! 1772 veor @XMM[9], @XMM[6], @XMM[11] 1773 vld1.64 {@XMM[14]}, [r0,:128]! 1774 veor @XMM[10], @XMM[3], @XMM[12] 1775 vst1.8 {@XMM[8]-@XMM[9]}, [$out]! 1776 veor @XMM[11], @XMM[7], @XMM[13] 1777 veor @XMM[12], @XMM[2], @XMM[14] 1778 vst1.8 {@XMM[10]-@XMM[11]}, [$out]! 1779 vst1.8 {@XMM[12]}, [$out]! 1780 1781 vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak 1782 b .Lxts_enc_done 1783.align 4 1784.Lxts_enc_6: 1785 veor @XMM[4], @XMM[4], @XMM[12] 1786#ifndef BSAES_ASM_EXTENDED_KEY 1787 add r4, sp, #0x90 @ pass key schedule 1788#else 1789 add r4, $key, #248 @ pass key schedule 1790#endif 1791 veor @XMM[5], @XMM[5], @XMM[13] 1792 mov r5, $rounds @ pass rounds 1793 mov r0, sp 1794 1795 bl _bsaes_encrypt8 1796 1797 vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]! 1798 vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]! 1799 veor @XMM[0], @XMM[0], @XMM[ 8] 1800 vld1.64 {@XMM[12]-@XMM[13]}, [r0,:128]! 1801 veor @XMM[1], @XMM[1], @XMM[ 9] 1802 veor @XMM[8], @XMM[4], @XMM[10] 1803 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! 1804 veor @XMM[9], @XMM[6], @XMM[11] 1805 veor @XMM[10], @XMM[3], @XMM[12] 1806 vst1.8 {@XMM[8]-@XMM[9]}, [$out]! 1807 veor @XMM[11], @XMM[7], @XMM[13] 1808 vst1.8 {@XMM[10]-@XMM[11]}, [$out]! 1809 1810 vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak 1811 b .Lxts_enc_done 1812 1813@ put this in range for both ARM and Thumb mode adr instructions 1814.align 5 1815.Lxts_magic: 1816 .quad 1, 0x87 1817 1818.align 5 1819.Lxts_enc_5: 1820 veor @XMM[3], @XMM[3], @XMM[11] 1821#ifndef BSAES_ASM_EXTENDED_KEY 1822 add r4, sp, #0x90 @ pass key schedule 1823#else 1824 add r4, $key, #248 @ pass key schedule 1825#endif 1826 veor @XMM[4], @XMM[4], @XMM[12] 1827 mov r5, $rounds @ pass rounds 1828 mov r0, sp 1829 1830 bl _bsaes_encrypt8 1831 1832 vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]! 1833 vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]! 1834 veor @XMM[0], @XMM[0], @XMM[ 8] 1835 vld1.64 {@XMM[12]}, [r0,:128]! 1836 veor @XMM[1], @XMM[1], @XMM[ 9] 1837 veor @XMM[8], @XMM[4], @XMM[10] 1838 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! 1839 veor @XMM[9], @XMM[6], @XMM[11] 1840 veor @XMM[10], @XMM[3], @XMM[12] 1841 vst1.8 {@XMM[8]-@XMM[9]}, [$out]! 1842 vst1.8 {@XMM[10]}, [$out]! 1843 1844 vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak 1845 b .Lxts_enc_done 1846.align 4 1847.Lxts_enc_4: 1848 veor @XMM[2], @XMM[2], @XMM[10] 1849#ifndef BSAES_ASM_EXTENDED_KEY 1850 add r4, sp, #0x90 @ pass key schedule 1851#else 1852 add r4, $key, #248 @ pass key schedule 1853#endif 1854 veor @XMM[3], @XMM[3], @XMM[11] 1855 mov r5, $rounds @ pass rounds 1856 mov r0, sp 1857 1858 bl _bsaes_encrypt8 1859 1860 vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]! 1861 vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]! 1862 veor @XMM[0], @XMM[0], @XMM[ 8] 1863 veor @XMM[1], @XMM[1], @XMM[ 9] 1864 veor @XMM[8], @XMM[4], @XMM[10] 1865 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! 1866 veor @XMM[9], @XMM[6], @XMM[11] 1867 vst1.8 {@XMM[8]-@XMM[9]}, [$out]! 1868 1869 vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak 1870 b .Lxts_enc_done 1871.align 4 1872.Lxts_enc_3: 1873 veor @XMM[1], @XMM[1], @XMM[9] 1874#ifndef BSAES_ASM_EXTENDED_KEY 1875 add r4, sp, #0x90 @ pass key schedule 1876#else 1877 add r4, $key, #248 @ pass key schedule 1878#endif 1879 veor @XMM[2], @XMM[2], @XMM[10] 1880 mov r5, $rounds @ pass rounds 1881 mov r0, sp 1882 1883 bl _bsaes_encrypt8 1884 1885 vld1.64 {@XMM[8]-@XMM[9]}, [r0,:128]! 1886 vld1.64 {@XMM[10]}, [r0,:128]! 1887 veor @XMM[0], @XMM[0], @XMM[ 8] 1888 veor @XMM[1], @XMM[1], @XMM[ 9] 1889 veor @XMM[8], @XMM[4], @XMM[10] 1890 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! 1891 vst1.8 {@XMM[8]}, [$out]! 1892 1893 vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak 1894 b .Lxts_enc_done 1895.align 4 1896.Lxts_enc_2: 1897 veor @XMM[0], @XMM[0], @XMM[8] 1898#ifndef BSAES_ASM_EXTENDED_KEY 1899 add r4, sp, #0x90 @ pass key schedule 1900#else 1901 add r4, $key, #248 @ pass key schedule 1902#endif 1903 veor @XMM[1], @XMM[1], @XMM[9] 1904 mov r5, $rounds @ pass rounds 1905 mov r0, sp 1906 1907 bl _bsaes_encrypt8 1908 1909 vld1.64 {@XMM[8]-@XMM[9]}, [r0,:128]! 1910 veor @XMM[0], @XMM[0], @XMM[ 8] 1911 veor @XMM[1], @XMM[1], @XMM[ 9] 1912 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! 1913 1914 vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak 1915 b .Lxts_enc_done 1916.align 4 1917.Lxts_enc_1: 1918 mov r0, sp 1919 veor @XMM[0], @XMM[0], @XMM[8] 1920 mov r1, sp 1921 vst1.8 {@XMM[0]}, [sp,:128] 1922 mov r2, $key 1923 mov r4, $fp @ preserve fp 1924 1925 bl aes_nohw_encrypt 1926 1927 vld1.8 {@XMM[0]}, [sp,:128] 1928 veor @XMM[0], @XMM[0], @XMM[8] 1929 vst1.8 {@XMM[0]}, [$out]! 1930 mov $fp, r4 1931 1932 vmov @XMM[8], @XMM[9] @ next round tweak 1933 1934.Lxts_enc_done: 1935#ifndef XTS_CHAIN_TWEAK 1936 adds $len, #0x10 1937 beq .Lxts_enc_ret 1938 sub r6, $out, #0x10 1939 1940.Lxts_enc_steal: 1941 ldrb r0, [$inp], #1 1942 ldrb r1, [$out, #-0x10] 1943 strb r0, [$out, #-0x10] 1944 strb r1, [$out], #1 1945 1946 subs $len, #1 1947 bhi .Lxts_enc_steal 1948 1949 vld1.8 {@XMM[0]}, [r6] 1950 mov r0, sp 1951 veor @XMM[0], @XMM[0], @XMM[8] 1952 mov r1, sp 1953 vst1.8 {@XMM[0]}, [sp,:128] 1954 mov r2, $key 1955 mov r4, $fp @ preserve fp 1956 1957 bl aes_nohw_encrypt 1958 1959 vld1.8 {@XMM[0]}, [sp,:128] 1960 veor @XMM[0], @XMM[0], @XMM[8] 1961 vst1.8 {@XMM[0]}, [r6] 1962 mov $fp, r4 1963#endif 1964 1965.Lxts_enc_ret: 1966 bic r0, $fp, #0xf 1967 vmov.i32 q0, #0 1968 vmov.i32 q1, #0 1969#ifdef XTS_CHAIN_TWEAK 1970 ldr r1, [$fp, #0x20+VFP_ABI_FRAME] @ chain tweak 1971#endif 1972.Lxts_enc_bzero: @ wipe key schedule [if any] 1973 vstmia sp!, {q0-q1} 1974 cmp sp, r0 1975 bne .Lxts_enc_bzero 1976 1977 mov sp, $fp 1978#ifdef XTS_CHAIN_TWEAK 1979 vst1.8 {@XMM[8]}, [r1] 1980#endif 1981 VFP_ABI_POP 1982 ldmia sp!, {r4-r10, pc} @ return 1983 1984.size bsaes_xts_encrypt,.-bsaes_xts_encrypt 1985 1986.globl bsaes_xts_decrypt 1987.type bsaes_xts_decrypt,%function 1988.align 4 1989bsaes_xts_decrypt: 1990 mov ip, sp 1991 stmdb sp!, {r4-r10, lr} @ 0x20 1992 VFP_ABI_PUSH 1993 mov r6, sp @ future $fp 1994 1995 mov $inp, r0 1996 mov $out, r1 1997 mov $len, r2 1998 mov $key, r3 1999 2000 sub r0, sp, #0x10 @ 0x10 2001 bic r0, #0xf @ align at 16 bytes 2002 mov sp, r0 2003 2004#ifdef XTS_CHAIN_TWEAK 2005 ldr r0, [ip] @ pointer to input tweak 2006#else 2007 @ generate initial tweak 2008 ldr r0, [ip, #4] @ iv[] 2009 mov r1, sp 2010 ldr r2, [ip, #0] @ key2 2011 bl aes_nohw_encrypt 2012 mov r0, sp @ pointer to initial tweak 2013#endif 2014 2015 ldr $rounds, [$key, #240] @ get # of rounds 2016 mov $fp, r6 2017#ifndef BSAES_ASM_EXTENDED_KEY 2018 @ allocate the key schedule on the stack 2019 sub r12, sp, $rounds, lsl#7 @ 128 bytes per inner round key 2020 @ add r12, #`128-32` @ size of bit-sliced key schedule 2021 sub r12, #`32+16` @ place for tweak[9] 2022 2023 @ populate the key schedule 2024 mov r4, $key @ pass key 2025 mov r5, $rounds @ pass # of rounds 2026 mov sp, r12 2027 add r12, #0x90 @ pass key schedule 2028 bl _bsaes_key_convert 2029 add r4, sp, #0x90 2030 vldmia r4, {@XMM[6]} 2031 vstmia r12, {@XMM[15]} @ save last round key 2032 veor @XMM[7], @XMM[7], @XMM[6] @ fix up round 0 key 2033 vstmia r4, {@XMM[7]} 2034#else 2035 ldr r12, [$key, #244] 2036 eors r12, #1 2037 beq 0f 2038 2039 str r12, [$key, #244] 2040 mov r4, $key @ pass key 2041 mov r5, $rounds @ pass # of rounds 2042 add r12, $key, #248 @ pass key schedule 2043 bl _bsaes_key_convert 2044 add r4, $key, #248 2045 vldmia r4, {@XMM[6]} 2046 vstmia r12, {@XMM[15]} @ save last round key 2047 veor @XMM[7], @XMM[7], @XMM[6] @ fix up round 0 key 2048 vstmia r4, {@XMM[7]} 2049 2050.align 2 20510: sub sp, #0x90 @ place for tweak[9] 2052#endif 2053 vld1.8 {@XMM[8]}, [r0] @ initial tweak 2054 adr $magic, .Lxts_magic 2055 2056#ifndef XTS_CHAIN_TWEAK 2057 tst $len, #0xf @ if not multiple of 16 2058 it ne @ Thumb2 thing, sanity check in ARM 2059 subne $len, #0x10 @ subtract another 16 bytes 2060#endif 2061 subs $len, #0x80 2062 2063 blo .Lxts_dec_short 2064 b .Lxts_dec_loop 2065 2066.align 4 2067.Lxts_dec_loop: 2068 vldmia $magic, {$twmask} @ load XTS magic 2069 vshr.s64 @T[0], @XMM[8], #63 2070 mov r0, sp 2071 vand @T[0], @T[0], $twmask 2072___ 2073for($i=9;$i<16;$i++) { 2074$code.=<<___; 2075 vadd.u64 @XMM[$i], @XMM[$i-1], @XMM[$i-1] 2076 vst1.64 {@XMM[$i-1]}, [r0,:128]! 2077 vswp `&Dhi("@T[0]")`,`&Dlo("@T[0]")` 2078 vshr.s64 @T[1], @XMM[$i], #63 2079 veor @XMM[$i], @XMM[$i], @T[0] 2080 vand @T[1], @T[1], $twmask 2081___ 2082 @T=reverse(@T); 2083 2084$code.=<<___ if ($i>=10); 2085 vld1.8 {@XMM[$i-10]}, [$inp]! 2086___ 2087$code.=<<___ if ($i>=11); 2088 veor @XMM[$i-11], @XMM[$i-11], @XMM[$i-3] 2089___ 2090} 2091$code.=<<___; 2092 vadd.u64 @XMM[8], @XMM[15], @XMM[15] 2093 vst1.64 {@XMM[15]}, [r0,:128]! 2094 vswp `&Dhi("@T[0]")`,`&Dlo("@T[0]")` 2095 veor @XMM[8], @XMM[8], @T[0] 2096 vst1.64 {@XMM[8]}, [r0,:128] @ next round tweak 2097 2098 vld1.8 {@XMM[6]-@XMM[7]}, [$inp]! 2099 veor @XMM[5], @XMM[5], @XMM[13] 2100#ifndef BSAES_ASM_EXTENDED_KEY 2101 add r4, sp, #0x90 @ pass key schedule 2102#else 2103 add r4, $key, #248 @ pass key schedule 2104#endif 2105 veor @XMM[6], @XMM[6], @XMM[14] 2106 mov r5, $rounds @ pass rounds 2107 veor @XMM[7], @XMM[7], @XMM[15] 2108 mov r0, sp 2109 2110 bl _bsaes_decrypt8 2111 2112 vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]! 2113 vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]! 2114 veor @XMM[0], @XMM[0], @XMM[ 8] 2115 vld1.64 {@XMM[12]-@XMM[13]}, [r0,:128]! 2116 veor @XMM[1], @XMM[1], @XMM[ 9] 2117 veor @XMM[8], @XMM[6], @XMM[10] 2118 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! 2119 veor @XMM[9], @XMM[4], @XMM[11] 2120 vld1.64 {@XMM[14]-@XMM[15]}, [r0,:128]! 2121 veor @XMM[10], @XMM[2], @XMM[12] 2122 vst1.8 {@XMM[8]-@XMM[9]}, [$out]! 2123 veor @XMM[11], @XMM[7], @XMM[13] 2124 veor @XMM[12], @XMM[3], @XMM[14] 2125 vst1.8 {@XMM[10]-@XMM[11]}, [$out]! 2126 veor @XMM[13], @XMM[5], @XMM[15] 2127 vst1.8 {@XMM[12]-@XMM[13]}, [$out]! 2128 2129 vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak 2130 2131 subs $len, #0x80 2132 bpl .Lxts_dec_loop 2133 2134.Lxts_dec_short: 2135 adds $len, #0x70 2136 bmi .Lxts_dec_done 2137 2138 vldmia $magic, {$twmask} @ load XTS magic 2139 vshr.s64 @T[0], @XMM[8], #63 2140 mov r0, sp 2141 vand @T[0], @T[0], $twmask 2142___ 2143for($i=9;$i<16;$i++) { 2144$code.=<<___; 2145 vadd.u64 @XMM[$i], @XMM[$i-1], @XMM[$i-1] 2146 vst1.64 {@XMM[$i-1]}, [r0,:128]! 2147 vswp `&Dhi("@T[0]")`,`&Dlo("@T[0]")` 2148 vshr.s64 @T[1], @XMM[$i], #63 2149 veor @XMM[$i], @XMM[$i], @T[0] 2150 vand @T[1], @T[1], $twmask 2151___ 2152 @T=reverse(@T); 2153 2154$code.=<<___ if ($i>=10); 2155 vld1.8 {@XMM[$i-10]}, [$inp]! 2156 subs $len, #0x10 2157 bmi .Lxts_dec_`$i-9` 2158___ 2159$code.=<<___ if ($i>=11); 2160 veor @XMM[$i-11], @XMM[$i-11], @XMM[$i-3] 2161___ 2162} 2163$code.=<<___; 2164 sub $len, #0x10 2165 vst1.64 {@XMM[15]}, [r0,:128] @ next round tweak 2166 2167 vld1.8 {@XMM[6]}, [$inp]! 2168 veor @XMM[5], @XMM[5], @XMM[13] 2169#ifndef BSAES_ASM_EXTENDED_KEY 2170 add r4, sp, #0x90 @ pass key schedule 2171#else 2172 add r4, $key, #248 @ pass key schedule 2173#endif 2174 veor @XMM[6], @XMM[6], @XMM[14] 2175 mov r5, $rounds @ pass rounds 2176 mov r0, sp 2177 2178 bl _bsaes_decrypt8 2179 2180 vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]! 2181 vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]! 2182 veor @XMM[0], @XMM[0], @XMM[ 8] 2183 vld1.64 {@XMM[12]-@XMM[13]}, [r0,:128]! 2184 veor @XMM[1], @XMM[1], @XMM[ 9] 2185 veor @XMM[8], @XMM[6], @XMM[10] 2186 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! 2187 veor @XMM[9], @XMM[4], @XMM[11] 2188 vld1.64 {@XMM[14]}, [r0,:128]! 2189 veor @XMM[10], @XMM[2], @XMM[12] 2190 vst1.8 {@XMM[8]-@XMM[9]}, [$out]! 2191 veor @XMM[11], @XMM[7], @XMM[13] 2192 veor @XMM[12], @XMM[3], @XMM[14] 2193 vst1.8 {@XMM[10]-@XMM[11]}, [$out]! 2194 vst1.8 {@XMM[12]}, [$out]! 2195 2196 vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak 2197 b .Lxts_dec_done 2198.align 4 2199.Lxts_dec_6: 2200 vst1.64 {@XMM[14]}, [r0,:128] @ next round tweak 2201 2202 veor @XMM[4], @XMM[4], @XMM[12] 2203#ifndef BSAES_ASM_EXTENDED_KEY 2204 add r4, sp, #0x90 @ pass key schedule 2205#else 2206 add r4, $key, #248 @ pass key schedule 2207#endif 2208 veor @XMM[5], @XMM[5], @XMM[13] 2209 mov r5, $rounds @ pass rounds 2210 mov r0, sp 2211 2212 bl _bsaes_decrypt8 2213 2214 vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]! 2215 vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]! 2216 veor @XMM[0], @XMM[0], @XMM[ 8] 2217 vld1.64 {@XMM[12]-@XMM[13]}, [r0,:128]! 2218 veor @XMM[1], @XMM[1], @XMM[ 9] 2219 veor @XMM[8], @XMM[6], @XMM[10] 2220 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! 2221 veor @XMM[9], @XMM[4], @XMM[11] 2222 veor @XMM[10], @XMM[2], @XMM[12] 2223 vst1.8 {@XMM[8]-@XMM[9]}, [$out]! 2224 veor @XMM[11], @XMM[7], @XMM[13] 2225 vst1.8 {@XMM[10]-@XMM[11]}, [$out]! 2226 2227 vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak 2228 b .Lxts_dec_done 2229.align 4 2230.Lxts_dec_5: 2231 veor @XMM[3], @XMM[3], @XMM[11] 2232#ifndef BSAES_ASM_EXTENDED_KEY 2233 add r4, sp, #0x90 @ pass key schedule 2234#else 2235 add r4, $key, #248 @ pass key schedule 2236#endif 2237 veor @XMM[4], @XMM[4], @XMM[12] 2238 mov r5, $rounds @ pass rounds 2239 mov r0, sp 2240 2241 bl _bsaes_decrypt8 2242 2243 vld1.64 {@XMM[ 8]-@XMM[ 9]}, [r0,:128]! 2244 vld1.64 {@XMM[10]-@XMM[11]}, [r0,:128]! 2245 veor @XMM[0], @XMM[0], @XMM[ 8] 2246 vld1.64 {@XMM[12]}, [r0,:128]! 2247 veor @XMM[1], @XMM[1], @XMM[ 9] 2248 veor @XMM[8], @XMM[6], @XMM[10] 2249 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! 2250 veor @XMM[9], @XMM[4], @XMM[11] 2251 veor @XMM[10], @XMM[2], @XMM[12] 2252 vst1.8 {@XMM[8]-@XMM[9]}, [$out]! 2253 vst1.8 {@XMM[10]}, [$out]! 2254 2255 vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak 2256 b .Lxts_dec_done 2257.align 4 2258.Lxts_dec_4: 2259 veor @XMM[2], @XMM[2], @XMM[10] 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[3], @XMM[3], @XMM[11] 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 veor @XMM[1], @XMM[1], @XMM[ 9] 2275 veor @XMM[8], @XMM[6], @XMM[10] 2276 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! 2277 veor @XMM[9], @XMM[4], @XMM[11] 2278 vst1.8 {@XMM[8]-@XMM[9]}, [$out]! 2279 2280 vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak 2281 b .Lxts_dec_done 2282.align 4 2283.Lxts_dec_3: 2284 veor @XMM[1], @XMM[1], @XMM[9] 2285#ifndef BSAES_ASM_EXTENDED_KEY 2286 add r4, sp, #0x90 @ pass key schedule 2287#else 2288 add r4, $key, #248 @ pass key schedule 2289#endif 2290 veor @XMM[2], @XMM[2], @XMM[10] 2291 mov r5, $rounds @ pass rounds 2292 mov r0, sp 2293 2294 bl _bsaes_decrypt8 2295 2296 vld1.64 {@XMM[8]-@XMM[9]}, [r0,:128]! 2297 vld1.64 {@XMM[10]}, [r0,:128]! 2298 veor @XMM[0], @XMM[0], @XMM[ 8] 2299 veor @XMM[1], @XMM[1], @XMM[ 9] 2300 veor @XMM[8], @XMM[6], @XMM[10] 2301 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! 2302 vst1.8 {@XMM[8]}, [$out]! 2303 2304 vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak 2305 b .Lxts_dec_done 2306.align 4 2307.Lxts_dec_2: 2308 veor @XMM[0], @XMM[0], @XMM[8] 2309#ifndef BSAES_ASM_EXTENDED_KEY 2310 add r4, sp, #0x90 @ pass key schedule 2311#else 2312 add r4, $key, #248 @ pass key schedule 2313#endif 2314 veor @XMM[1], @XMM[1], @XMM[9] 2315 mov r5, $rounds @ pass rounds 2316 mov r0, sp 2317 2318 bl _bsaes_decrypt8 2319 2320 vld1.64 {@XMM[8]-@XMM[9]}, [r0,:128]! 2321 veor @XMM[0], @XMM[0], @XMM[ 8] 2322 veor @XMM[1], @XMM[1], @XMM[ 9] 2323 vst1.8 {@XMM[0]-@XMM[1]}, [$out]! 2324 2325 vld1.64 {@XMM[8]}, [r0,:128] @ next round tweak 2326 b .Lxts_dec_done 2327.align 4 2328.Lxts_dec_1: 2329 mov r0, sp 2330 veor @XMM[0], @XMM[0], @XMM[8] 2331 mov r1, sp 2332 vst1.8 {@XMM[0]}, [sp,:128] 2333 mov r5, $magic @ preserve magic 2334 mov r2, $key 2335 mov r4, $fp @ preserve fp 2336 2337 bl aes_nohw_decrypt 2338 2339 vld1.8 {@XMM[0]}, [sp,:128] 2340 veor @XMM[0], @XMM[0], @XMM[8] 2341 vst1.8 {@XMM[0]}, [$out]! 2342 mov $fp, r4 2343 mov $magic, r5 2344 2345 vmov @XMM[8], @XMM[9] @ next round tweak 2346 2347.Lxts_dec_done: 2348#ifndef XTS_CHAIN_TWEAK 2349 adds $len, #0x10 2350 beq .Lxts_dec_ret 2351 2352 @ calculate one round of extra tweak for the stolen ciphertext 2353 vldmia $magic, {$twmask} 2354 vshr.s64 @XMM[6], @XMM[8], #63 2355 vand @XMM[6], @XMM[6], $twmask 2356 vadd.u64 @XMM[9], @XMM[8], @XMM[8] 2357 vswp `&Dhi("@XMM[6]")`,`&Dlo("@XMM[6]")` 2358 veor @XMM[9], @XMM[9], @XMM[6] 2359 2360 @ perform the final decryption with the last tweak value 2361 vld1.8 {@XMM[0]}, [$inp]! 2362 mov r0, sp 2363 veor @XMM[0], @XMM[0], @XMM[9] 2364 mov r1, sp 2365 vst1.8 {@XMM[0]}, [sp,:128] 2366 mov r2, $key 2367 mov r4, $fp @ preserve fp 2368 2369 bl aes_nohw_decrypt 2370 2371 vld1.8 {@XMM[0]}, [sp,:128] 2372 veor @XMM[0], @XMM[0], @XMM[9] 2373 vst1.8 {@XMM[0]}, [$out] 2374 2375 mov r6, $out 2376.Lxts_dec_steal: 2377 ldrb r1, [$out] 2378 ldrb r0, [$inp], #1 2379 strb r1, [$out, #0x10] 2380 strb r0, [$out], #1 2381 2382 subs $len, #1 2383 bhi .Lxts_dec_steal 2384 2385 vld1.8 {@XMM[0]}, [r6] 2386 mov r0, sp 2387 veor @XMM[0], @XMM[8] 2388 mov r1, sp 2389 vst1.8 {@XMM[0]}, [sp,:128] 2390 mov r2, $key 2391 2392 bl aes_nohw_decrypt 2393 2394 vld1.8 {@XMM[0]}, [sp,:128] 2395 veor @XMM[0], @XMM[0], @XMM[8] 2396 vst1.8 {@XMM[0]}, [r6] 2397 mov $fp, r4 2398#endif 2399 2400.Lxts_dec_ret: 2401 bic r0, $fp, #0xf 2402 vmov.i32 q0, #0 2403 vmov.i32 q1, #0 2404#ifdef XTS_CHAIN_TWEAK 2405 ldr r1, [$fp, #0x20+VFP_ABI_FRAME] @ chain tweak 2406#endif 2407.Lxts_dec_bzero: @ wipe key schedule [if any] 2408 vstmia sp!, {q0-q1} 2409 cmp sp, r0 2410 bne .Lxts_dec_bzero 2411 2412 mov sp, $fp 2413#ifdef XTS_CHAIN_TWEAK 2414 vst1.8 {@XMM[8]}, [r1] 2415#endif 2416 VFP_ABI_POP 2417 ldmia sp!, {r4-r10, pc} @ return 2418 2419.size bsaes_xts_decrypt,.-bsaes_xts_decrypt 2420___ 2421} 2422$code.=<<___; 2423#endif 2424___ 2425 2426$code =~ s/\`([^\`]*)\`/eval($1)/gem; 2427 2428open SELF,$0; 2429while(<SELF>) { 2430 next if (/^#!/); 2431 last if (!s/^#/@/ and !/^$/); 2432 print; 2433} 2434close SELF; 2435 2436print $code; 2437 2438close STDOUT or die "error closing STDOUT: $!"; 2439