1#! /usr/bin/env perl 2# SPDX-License-Identifier: GPL-2.0 3 4# This code is taken from CRYPTOGAMs[1] and is included here using the option 5# in the license to distribute the code under the GPL. Therefore this program 6# is free software; you can redistribute it and/or modify it under the terms of 7# the GNU General Public License version 2 as published by the Free Software 8# Foundation. 9# 10# [1] https://www.openssl.org/~appro/cryptogams/ 11 12# Copyright (c) 2006-2017, CRYPTOGAMS by <appro@openssl.org> 13# All rights reserved. 14# 15# Redistribution and use in source and binary forms, with or without 16# modification, are permitted provided that the following conditions 17# are met: 18# 19# * Redistributions of source code must retain copyright notices, 20# this list of conditions and the following disclaimer. 21# 22# * Redistributions in binary form must reproduce the above 23# copyright notice, this list of conditions and the following 24# disclaimer in the documentation and/or other materials 25# provided with the distribution. 26# 27# * Neither the name of the CRYPTOGAMS nor the names of its 28# copyright holder and contributors may be used to endorse or 29# promote products derived from this software without specific 30# prior written permission. 31# 32# ALTERNATIVELY, provided that this notice is retained in full, this 33# product may be distributed under the terms of the GNU General Public 34# License (GPL), in which case the provisions of the GPL apply INSTEAD OF 35# those given above. 36# 37# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS 38# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 39# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 40# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 41# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 42# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 43# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 44# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 45# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 46# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 47# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 48 49# ==================================================================== 50# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL 51# project. The module is, however, dual licensed under OpenSSL and 52# CRYPTOGAMS licenses depending on where you obtain it. For further 53# details see https://www.openssl.org/~appro/cryptogams/. 54# ==================================================================== 55# 56# This module implements support for AES instructions as per PowerISA 57# specification version 2.07, first implemented by POWER8 processor. 58# The module is endian-agnostic in sense that it supports both big- 59# and little-endian cases. Data alignment in parallelizable modes is 60# handled with VSX loads and stores, which implies MSR.VSX flag being 61# set. It should also be noted that ISA specification doesn't prohibit 62# alignment exceptions for these instructions on page boundaries. 63# Initially alignment was handled in pure AltiVec/VMX way [when data 64# is aligned programmatically, which in turn guarantees exception- 65# free execution], but it turned to hamper performance when vcipher 66# instructions are interleaved. It's reckoned that eventual 67# misalignment penalties at page boundaries are in average lower 68# than additional overhead in pure AltiVec approach. 69# 70# May 2016 71# 72# Add XTS subroutine, 9x on little- and 12x improvement on big-endian 73# systems were measured. 74# 75###################################################################### 76# Current large-block performance in cycles per byte processed with 77# 128-bit key (less is better). 78# 79# CBC en-/decrypt CTR XTS 80# POWER8[le] 3.96/0.72 0.74 1.1 81# POWER8[be] 3.75/0.65 0.66 1.0 82 83$flavour = shift; 84 85if ($flavour =~ /64/) { 86 $SIZE_T =8; 87 $LRSAVE =2*$SIZE_T; 88 $STU ="stdu"; 89 $POP ="ld"; 90 $PUSH ="std"; 91 $UCMP ="cmpld"; 92 $SHL ="sldi"; 93} elsif ($flavour =~ /32/) { 94 $SIZE_T =4; 95 $LRSAVE =$SIZE_T; 96 $STU ="stwu"; 97 $POP ="lwz"; 98 $PUSH ="stw"; 99 $UCMP ="cmplw"; 100 $SHL ="slwi"; 101} else { die "nonsense $flavour"; } 102 103$LITTLE_ENDIAN = ($flavour=~/le$/) ? $SIZE_T : 0; 104 105$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; 106( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or 107( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or 108die "can't locate ppc-xlate.pl"; 109 110open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; 111 112$FRAME=8*$SIZE_T; 113$prefix="aes_p8"; 114 115$sp="r1"; 116$vrsave="r12"; 117 118######################################################################### 119{{{ # Key setup procedures # 120my ($inp,$bits,$out,$ptr,$cnt,$rounds)=map("r$_",(3..8)); 121my ($zero,$in0,$in1,$key,$rcon,$mask,$tmp)=map("v$_",(0..6)); 122my ($stage,$outperm,$outmask,$outhead,$outtail)=map("v$_",(7..11)); 123 124$code.=<<___; 125.machine "any" 126 127.text 128 129.align 7 130rcon: 131.long 0x01000000, 0x01000000, 0x01000000, 0x01000000 ?rev 132.long 0x1b000000, 0x1b000000, 0x1b000000, 0x1b000000 ?rev 133.long 0x0d0e0f0c, 0x0d0e0f0c, 0x0d0e0f0c, 0x0d0e0f0c ?rev 134.long 0,0,0,0 ?asis 135Lconsts: 136 mflr r0 137 bcl 20,31,\$+4 138 mflr $ptr #vvvvv "distance between . and rcon 139 addi $ptr,$ptr,-0x48 140 mtlr r0 141 blr 142 .long 0 143 .byte 0,12,0x14,0,0,0,0,0 144.asciz "AES for PowerISA 2.07, CRYPTOGAMS by <appro\@openssl.org>" 145 146.globl .${prefix}_set_encrypt_key 147Lset_encrypt_key: 148 mflr r11 149 $PUSH r11,$LRSAVE($sp) 150 151 li $ptr,-1 152 ${UCMP}i $inp,0 153 beq- Lenc_key_abort # if ($inp==0) return -1; 154 ${UCMP}i $out,0 155 beq- Lenc_key_abort # if ($out==0) return -1; 156 li $ptr,-2 157 cmpwi $bits,128 158 blt- Lenc_key_abort 159 cmpwi $bits,256 160 bgt- Lenc_key_abort 161 andi. r0,$bits,0x3f 162 bne- Lenc_key_abort 163 164 lis r0,0xfff0 165 mfspr $vrsave,256 166 mtspr 256,r0 167 168 bl Lconsts 169 mtlr r11 170 171 neg r9,$inp 172 lvx $in0,0,$inp 173 addi $inp,$inp,15 # 15 is not typo 174 lvsr $key,0,r9 # borrow $key 175 li r8,0x20 176 cmpwi $bits,192 177 lvx $in1,0,$inp 178 le?vspltisb $mask,0x0f # borrow $mask 179 lvx $rcon,0,$ptr 180 le?vxor $key,$key,$mask # adjust for byte swap 181 lvx $mask,r8,$ptr 182 addi $ptr,$ptr,0x10 183 vperm $in0,$in0,$in1,$key # align [and byte swap in LE] 184 li $cnt,8 185 vxor $zero,$zero,$zero 186 mtctr $cnt 187 188 ?lvsr $outperm,0,$out 189 vspltisb $outmask,-1 190 lvx $outhead,0,$out 191 ?vperm $outmask,$zero,$outmask,$outperm 192 193 blt Loop128 194 addi $inp,$inp,8 195 beq L192 196 addi $inp,$inp,8 197 b L256 198 199.align 4 200Loop128: 201 vperm $key,$in0,$in0,$mask # rotate-n-splat 202 vsldoi $tmp,$zero,$in0,12 # >>32 203 vperm $outtail,$in0,$in0,$outperm # rotate 204 vsel $stage,$outhead,$outtail,$outmask 205 vmr $outhead,$outtail 206 vcipherlast $key,$key,$rcon 207 stvx $stage,0,$out 208 addi $out,$out,16 209 210 vxor $in0,$in0,$tmp 211 vsldoi $tmp,$zero,$tmp,12 # >>32 212 vxor $in0,$in0,$tmp 213 vsldoi $tmp,$zero,$tmp,12 # >>32 214 vxor $in0,$in0,$tmp 215 vadduwm $rcon,$rcon,$rcon 216 vxor $in0,$in0,$key 217 bdnz Loop128 218 219 lvx $rcon,0,$ptr # last two round keys 220 221 vperm $key,$in0,$in0,$mask # rotate-n-splat 222 vsldoi $tmp,$zero,$in0,12 # >>32 223 vperm $outtail,$in0,$in0,$outperm # rotate 224 vsel $stage,$outhead,$outtail,$outmask 225 vmr $outhead,$outtail 226 vcipherlast $key,$key,$rcon 227 stvx $stage,0,$out 228 addi $out,$out,16 229 230 vxor $in0,$in0,$tmp 231 vsldoi $tmp,$zero,$tmp,12 # >>32 232 vxor $in0,$in0,$tmp 233 vsldoi $tmp,$zero,$tmp,12 # >>32 234 vxor $in0,$in0,$tmp 235 vadduwm $rcon,$rcon,$rcon 236 vxor $in0,$in0,$key 237 238 vperm $key,$in0,$in0,$mask # rotate-n-splat 239 vsldoi $tmp,$zero,$in0,12 # >>32 240 vperm $outtail,$in0,$in0,$outperm # rotate 241 vsel $stage,$outhead,$outtail,$outmask 242 vmr $outhead,$outtail 243 vcipherlast $key,$key,$rcon 244 stvx $stage,0,$out 245 addi $out,$out,16 246 247 vxor $in0,$in0,$tmp 248 vsldoi $tmp,$zero,$tmp,12 # >>32 249 vxor $in0,$in0,$tmp 250 vsldoi $tmp,$zero,$tmp,12 # >>32 251 vxor $in0,$in0,$tmp 252 vxor $in0,$in0,$key 253 vperm $outtail,$in0,$in0,$outperm # rotate 254 vsel $stage,$outhead,$outtail,$outmask 255 vmr $outhead,$outtail 256 stvx $stage,0,$out 257 258 addi $inp,$out,15 # 15 is not typo 259 addi $out,$out,0x50 260 261 li $rounds,10 262 b Ldone 263 264.align 4 265L192: 266 lvx $tmp,0,$inp 267 li $cnt,4 268 vperm $outtail,$in0,$in0,$outperm # rotate 269 vsel $stage,$outhead,$outtail,$outmask 270 vmr $outhead,$outtail 271 stvx $stage,0,$out 272 addi $out,$out,16 273 vperm $in1,$in1,$tmp,$key # align [and byte swap in LE] 274 vspltisb $key,8 # borrow $key 275 mtctr $cnt 276 vsububm $mask,$mask,$key # adjust the mask 277 278Loop192: 279 vperm $key,$in1,$in1,$mask # roate-n-splat 280 vsldoi $tmp,$zero,$in0,12 # >>32 281 vcipherlast $key,$key,$rcon 282 283 vxor $in0,$in0,$tmp 284 vsldoi $tmp,$zero,$tmp,12 # >>32 285 vxor $in0,$in0,$tmp 286 vsldoi $tmp,$zero,$tmp,12 # >>32 287 vxor $in0,$in0,$tmp 288 289 vsldoi $stage,$zero,$in1,8 290 vspltw $tmp,$in0,3 291 vxor $tmp,$tmp,$in1 292 vsldoi $in1,$zero,$in1,12 # >>32 293 vadduwm $rcon,$rcon,$rcon 294 vxor $in1,$in1,$tmp 295 vxor $in0,$in0,$key 296 vxor $in1,$in1,$key 297 vsldoi $stage,$stage,$in0,8 298 299 vperm $key,$in1,$in1,$mask # rotate-n-splat 300 vsldoi $tmp,$zero,$in0,12 # >>32 301 vperm $outtail,$stage,$stage,$outperm # rotate 302 vsel $stage,$outhead,$outtail,$outmask 303 vmr $outhead,$outtail 304 vcipherlast $key,$key,$rcon 305 stvx $stage,0,$out 306 addi $out,$out,16 307 308 vsldoi $stage,$in0,$in1,8 309 vxor $in0,$in0,$tmp 310 vsldoi $tmp,$zero,$tmp,12 # >>32 311 vperm $outtail,$stage,$stage,$outperm # rotate 312 vsel $stage,$outhead,$outtail,$outmask 313 vmr $outhead,$outtail 314 vxor $in0,$in0,$tmp 315 vsldoi $tmp,$zero,$tmp,12 # >>32 316 vxor $in0,$in0,$tmp 317 stvx $stage,0,$out 318 addi $out,$out,16 319 320 vspltw $tmp,$in0,3 321 vxor $tmp,$tmp,$in1 322 vsldoi $in1,$zero,$in1,12 # >>32 323 vadduwm $rcon,$rcon,$rcon 324 vxor $in1,$in1,$tmp 325 vxor $in0,$in0,$key 326 vxor $in1,$in1,$key 327 vperm $outtail,$in0,$in0,$outperm # rotate 328 vsel $stage,$outhead,$outtail,$outmask 329 vmr $outhead,$outtail 330 stvx $stage,0,$out 331 addi $inp,$out,15 # 15 is not typo 332 addi $out,$out,16 333 bdnz Loop192 334 335 li $rounds,12 336 addi $out,$out,0x20 337 b Ldone 338 339.align 4 340L256: 341 lvx $tmp,0,$inp 342 li $cnt,7 343 li $rounds,14 344 vperm $outtail,$in0,$in0,$outperm # rotate 345 vsel $stage,$outhead,$outtail,$outmask 346 vmr $outhead,$outtail 347 stvx $stage,0,$out 348 addi $out,$out,16 349 vperm $in1,$in1,$tmp,$key # align [and byte swap in LE] 350 mtctr $cnt 351 352Loop256: 353 vperm $key,$in1,$in1,$mask # rotate-n-splat 354 vsldoi $tmp,$zero,$in0,12 # >>32 355 vperm $outtail,$in1,$in1,$outperm # rotate 356 vsel $stage,$outhead,$outtail,$outmask 357 vmr $outhead,$outtail 358 vcipherlast $key,$key,$rcon 359 stvx $stage,0,$out 360 addi $out,$out,16 361 362 vxor $in0,$in0,$tmp 363 vsldoi $tmp,$zero,$tmp,12 # >>32 364 vxor $in0,$in0,$tmp 365 vsldoi $tmp,$zero,$tmp,12 # >>32 366 vxor $in0,$in0,$tmp 367 vadduwm $rcon,$rcon,$rcon 368 vxor $in0,$in0,$key 369 vperm $outtail,$in0,$in0,$outperm # rotate 370 vsel $stage,$outhead,$outtail,$outmask 371 vmr $outhead,$outtail 372 stvx $stage,0,$out 373 addi $inp,$out,15 # 15 is not typo 374 addi $out,$out,16 375 bdz Ldone 376 377 vspltw $key,$in0,3 # just splat 378 vsldoi $tmp,$zero,$in1,12 # >>32 379 vsbox $key,$key 380 381 vxor $in1,$in1,$tmp 382 vsldoi $tmp,$zero,$tmp,12 # >>32 383 vxor $in1,$in1,$tmp 384 vsldoi $tmp,$zero,$tmp,12 # >>32 385 vxor $in1,$in1,$tmp 386 387 vxor $in1,$in1,$key 388 b Loop256 389 390.align 4 391Ldone: 392 lvx $in1,0,$inp # redundant in aligned case 393 vsel $in1,$outhead,$in1,$outmask 394 stvx $in1,0,$inp 395 li $ptr,0 396 mtspr 256,$vrsave 397 stw $rounds,0($out) 398 399Lenc_key_abort: 400 mr r3,$ptr 401 blr 402 .long 0 403 .byte 0,12,0x14,1,0,0,3,0 404 .long 0 405.size .${prefix}_set_encrypt_key,.-.${prefix}_set_encrypt_key 406 407.globl .${prefix}_set_decrypt_key 408 $STU $sp,-$FRAME($sp) 409 mflr r10 410 $PUSH r10,$FRAME+$LRSAVE($sp) 411 bl Lset_encrypt_key 412 mtlr r10 413 414 cmpwi r3,0 415 bne- Ldec_key_abort 416 417 slwi $cnt,$rounds,4 418 subi $inp,$out,240 # first round key 419 srwi $rounds,$rounds,1 420 add $out,$inp,$cnt # last round key 421 mtctr $rounds 422 423Ldeckey: 424 lwz r0, 0($inp) 425 lwz r6, 4($inp) 426 lwz r7, 8($inp) 427 lwz r8, 12($inp) 428 addi $inp,$inp,16 429 lwz r9, 0($out) 430 lwz r10,4($out) 431 lwz r11,8($out) 432 lwz r12,12($out) 433 stw r0, 0($out) 434 stw r6, 4($out) 435 stw r7, 8($out) 436 stw r8, 12($out) 437 subi $out,$out,16 438 stw r9, -16($inp) 439 stw r10,-12($inp) 440 stw r11,-8($inp) 441 stw r12,-4($inp) 442 bdnz Ldeckey 443 444 xor r3,r3,r3 # return value 445Ldec_key_abort: 446 addi $sp,$sp,$FRAME 447 blr 448 .long 0 449 .byte 0,12,4,1,0x80,0,3,0 450 .long 0 451.size .${prefix}_set_decrypt_key,.-.${prefix}_set_decrypt_key 452___ 453}}} 454######################################################################### 455{{{ # Single block en- and decrypt procedures # 456sub gen_block () { 457my $dir = shift; 458my $n = $dir eq "de" ? "n" : ""; 459my ($inp,$out,$key,$rounds,$idx)=map("r$_",(3..7)); 460 461$code.=<<___; 462.globl .${prefix}_${dir}crypt 463 lwz $rounds,240($key) 464 lis r0,0xfc00 465 mfspr $vrsave,256 466 li $idx,15 # 15 is not typo 467 mtspr 256,r0 468 469 lvx v0,0,$inp 470 neg r11,$out 471 lvx v1,$idx,$inp 472 lvsl v2,0,$inp # inpperm 473 le?vspltisb v4,0x0f 474 ?lvsl v3,0,r11 # outperm 475 le?vxor v2,v2,v4 476 li $idx,16 477 vperm v0,v0,v1,v2 # align [and byte swap in LE] 478 lvx v1,0,$key 479 ?lvsl v5,0,$key # keyperm 480 srwi $rounds,$rounds,1 481 lvx v2,$idx,$key 482 addi $idx,$idx,16 483 subi $rounds,$rounds,1 484 ?vperm v1,v1,v2,v5 # align round key 485 486 vxor v0,v0,v1 487 lvx v1,$idx,$key 488 addi $idx,$idx,16 489 mtctr $rounds 490 491Loop_${dir}c: 492 ?vperm v2,v2,v1,v5 493 v${n}cipher v0,v0,v2 494 lvx v2,$idx,$key 495 addi $idx,$idx,16 496 ?vperm v1,v1,v2,v5 497 v${n}cipher v0,v0,v1 498 lvx v1,$idx,$key 499 addi $idx,$idx,16 500 bdnz Loop_${dir}c 501 502 ?vperm v2,v2,v1,v5 503 v${n}cipher v0,v0,v2 504 lvx v2,$idx,$key 505 ?vperm v1,v1,v2,v5 506 v${n}cipherlast v0,v0,v1 507 508 vspltisb v2,-1 509 vxor v1,v1,v1 510 li $idx,15 # 15 is not typo 511 ?vperm v2,v1,v2,v3 # outmask 512 le?vxor v3,v3,v4 513 lvx v1,0,$out # outhead 514 vperm v0,v0,v0,v3 # rotate [and byte swap in LE] 515 vsel v1,v1,v0,v2 516 lvx v4,$idx,$out 517 stvx v1,0,$out 518 vsel v0,v0,v4,v2 519 stvx v0,$idx,$out 520 521 mtspr 256,$vrsave 522 blr 523 .long 0 524 .byte 0,12,0x14,0,0,0,3,0 525 .long 0 526.size .${prefix}_${dir}crypt,.-.${prefix}_${dir}crypt 527___ 528} 529&gen_block("en"); 530&gen_block("de"); 531}}} 532######################################################################### 533{{{ # CBC en- and decrypt procedures # 534my ($inp,$out,$len,$key,$ivp,$enc,$rounds,$idx)=map("r$_",(3..10)); 535my ($rndkey0,$rndkey1,$inout,$tmp)= map("v$_",(0..3)); 536my ($ivec,$inptail,$inpperm,$outhead,$outperm,$outmask,$keyperm)= 537 map("v$_",(4..10)); 538$code.=<<___; 539.globl .${prefix}_cbc_encrypt 540 ${UCMP}i $len,16 541 bltlr- 542 543 cmpwi $enc,0 # test direction 544 lis r0,0xffe0 545 mfspr $vrsave,256 546 mtspr 256,r0 547 548 li $idx,15 549 vxor $rndkey0,$rndkey0,$rndkey0 550 le?vspltisb $tmp,0x0f 551 552 lvx $ivec,0,$ivp # load [unaligned] iv 553 lvsl $inpperm,0,$ivp 554 lvx $inptail,$idx,$ivp 555 le?vxor $inpperm,$inpperm,$tmp 556 vperm $ivec,$ivec,$inptail,$inpperm 557 558 neg r11,$inp 559 ?lvsl $keyperm,0,$key # prepare for unaligned key 560 lwz $rounds,240($key) 561 562 lvsr $inpperm,0,r11 # prepare for unaligned load 563 lvx $inptail,0,$inp 564 addi $inp,$inp,15 # 15 is not typo 565 le?vxor $inpperm,$inpperm,$tmp 566 567 ?lvsr $outperm,0,$out # prepare for unaligned store 568 vspltisb $outmask,-1 569 lvx $outhead,0,$out 570 ?vperm $outmask,$rndkey0,$outmask,$outperm 571 le?vxor $outperm,$outperm,$tmp 572 573 srwi $rounds,$rounds,1 574 li $idx,16 575 subi $rounds,$rounds,1 576 beq Lcbc_dec 577 578Lcbc_enc: 579 vmr $inout,$inptail 580 lvx $inptail,0,$inp 581 addi $inp,$inp,16 582 mtctr $rounds 583 subi $len,$len,16 # len-=16 584 585 lvx $rndkey0,0,$key 586 vperm $inout,$inout,$inptail,$inpperm 587 lvx $rndkey1,$idx,$key 588 addi $idx,$idx,16 589 ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm 590 vxor $inout,$inout,$rndkey0 591 lvx $rndkey0,$idx,$key 592 addi $idx,$idx,16 593 vxor $inout,$inout,$ivec 594 595Loop_cbc_enc: 596 ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm 597 vcipher $inout,$inout,$rndkey1 598 lvx $rndkey1,$idx,$key 599 addi $idx,$idx,16 600 ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm 601 vcipher $inout,$inout,$rndkey0 602 lvx $rndkey0,$idx,$key 603 addi $idx,$idx,16 604 bdnz Loop_cbc_enc 605 606 ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm 607 vcipher $inout,$inout,$rndkey1 608 lvx $rndkey1,$idx,$key 609 li $idx,16 610 ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm 611 vcipherlast $ivec,$inout,$rndkey0 612 ${UCMP}i $len,16 613 614 vperm $tmp,$ivec,$ivec,$outperm 615 vsel $inout,$outhead,$tmp,$outmask 616 vmr $outhead,$tmp 617 stvx $inout,0,$out 618 addi $out,$out,16 619 bge Lcbc_enc 620 621 b Lcbc_done 622 623.align 4 624Lcbc_dec: 625 ${UCMP}i $len,128 626 bge _aesp8_cbc_decrypt8x 627 vmr $tmp,$inptail 628 lvx $inptail,0,$inp 629 addi $inp,$inp,16 630 mtctr $rounds 631 subi $len,$len,16 # len-=16 632 633 lvx $rndkey0,0,$key 634 vperm $tmp,$tmp,$inptail,$inpperm 635 lvx $rndkey1,$idx,$key 636 addi $idx,$idx,16 637 ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm 638 vxor $inout,$tmp,$rndkey0 639 lvx $rndkey0,$idx,$key 640 addi $idx,$idx,16 641 642Loop_cbc_dec: 643 ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm 644 vncipher $inout,$inout,$rndkey1 645 lvx $rndkey1,$idx,$key 646 addi $idx,$idx,16 647 ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm 648 vncipher $inout,$inout,$rndkey0 649 lvx $rndkey0,$idx,$key 650 addi $idx,$idx,16 651 bdnz Loop_cbc_dec 652 653 ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm 654 vncipher $inout,$inout,$rndkey1 655 lvx $rndkey1,$idx,$key 656 li $idx,16 657 ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm 658 vncipherlast $inout,$inout,$rndkey0 659 ${UCMP}i $len,16 660 661 vxor $inout,$inout,$ivec 662 vmr $ivec,$tmp 663 vperm $tmp,$inout,$inout,$outperm 664 vsel $inout,$outhead,$tmp,$outmask 665 vmr $outhead,$tmp 666 stvx $inout,0,$out 667 addi $out,$out,16 668 bge Lcbc_dec 669 670Lcbc_done: 671 addi $out,$out,-1 672 lvx $inout,0,$out # redundant in aligned case 673 vsel $inout,$outhead,$inout,$outmask 674 stvx $inout,0,$out 675 676 neg $enc,$ivp # write [unaligned] iv 677 li $idx,15 # 15 is not typo 678 vxor $rndkey0,$rndkey0,$rndkey0 679 vspltisb $outmask,-1 680 le?vspltisb $tmp,0x0f 681 ?lvsl $outperm,0,$enc 682 ?vperm $outmask,$rndkey0,$outmask,$outperm 683 le?vxor $outperm,$outperm,$tmp 684 lvx $outhead,0,$ivp 685 vperm $ivec,$ivec,$ivec,$outperm 686 vsel $inout,$outhead,$ivec,$outmask 687 lvx $inptail,$idx,$ivp 688 stvx $inout,0,$ivp 689 vsel $inout,$ivec,$inptail,$outmask 690 stvx $inout,$idx,$ivp 691 692 mtspr 256,$vrsave 693 blr 694 .long 0 695 .byte 0,12,0x14,0,0,0,6,0 696 .long 0 697___ 698######################################################################### 699{{ # Optimized CBC decrypt procedure # 700my $key_="r11"; 701my ($x00,$x10,$x20,$x30,$x40,$x50,$x60,$x70)=map("r$_",(0,8,26..31)); 702my ($in0, $in1, $in2, $in3, $in4, $in5, $in6, $in7 )=map("v$_",(0..3,10..13)); 703my ($out0,$out1,$out2,$out3,$out4,$out5,$out6,$out7)=map("v$_",(14..21)); 704my $rndkey0="v23"; # v24-v25 rotating buffer for first found keys 705 # v26-v31 last 6 round keys 706my ($tmp,$keyperm)=($in3,$in4); # aliases with "caller", redundant assignment 707 708$code.=<<___; 709.align 5 710_aesp8_cbc_decrypt8x: 711 $STU $sp,-`($FRAME+21*16+6*$SIZE_T)`($sp) 712 li r10,`$FRAME+8*16+15` 713 li r11,`$FRAME+8*16+31` 714 stvx v20,r10,$sp # ABI says so 715 addi r10,r10,32 716 stvx v21,r11,$sp 717 addi r11,r11,32 718 stvx v22,r10,$sp 719 addi r10,r10,32 720 stvx v23,r11,$sp 721 addi r11,r11,32 722 stvx v24,r10,$sp 723 addi r10,r10,32 724 stvx v25,r11,$sp 725 addi r11,r11,32 726 stvx v26,r10,$sp 727 addi r10,r10,32 728 stvx v27,r11,$sp 729 addi r11,r11,32 730 stvx v28,r10,$sp 731 addi r10,r10,32 732 stvx v29,r11,$sp 733 addi r11,r11,32 734 stvx v30,r10,$sp 735 stvx v31,r11,$sp 736 li r0,-1 737 stw $vrsave,`$FRAME+21*16-4`($sp) # save vrsave 738 li $x10,0x10 739 $PUSH r26,`$FRAME+21*16+0*$SIZE_T`($sp) 740 li $x20,0x20 741 $PUSH r27,`$FRAME+21*16+1*$SIZE_T`($sp) 742 li $x30,0x30 743 $PUSH r28,`$FRAME+21*16+2*$SIZE_T`($sp) 744 li $x40,0x40 745 $PUSH r29,`$FRAME+21*16+3*$SIZE_T`($sp) 746 li $x50,0x50 747 $PUSH r30,`$FRAME+21*16+4*$SIZE_T`($sp) 748 li $x60,0x60 749 $PUSH r31,`$FRAME+21*16+5*$SIZE_T`($sp) 750 li $x70,0x70 751 mtspr 256,r0 752 753 subi $rounds,$rounds,3 # -4 in total 754 subi $len,$len,128 # bias 755 756 lvx $rndkey0,$x00,$key # load key schedule 757 lvx v30,$x10,$key 758 addi $key,$key,0x20 759 lvx v31,$x00,$key 760 ?vperm $rndkey0,$rndkey0,v30,$keyperm 761 addi $key_,$sp,$FRAME+15 762 mtctr $rounds 763 764Load_cbc_dec_key: 765 ?vperm v24,v30,v31,$keyperm 766 lvx v30,$x10,$key 767 addi $key,$key,0x20 768 stvx v24,$x00,$key_ # off-load round[1] 769 ?vperm v25,v31,v30,$keyperm 770 lvx v31,$x00,$key 771 stvx v25,$x10,$key_ # off-load round[2] 772 addi $key_,$key_,0x20 773 bdnz Load_cbc_dec_key 774 775 lvx v26,$x10,$key 776 ?vperm v24,v30,v31,$keyperm 777 lvx v27,$x20,$key 778 stvx v24,$x00,$key_ # off-load round[3] 779 ?vperm v25,v31,v26,$keyperm 780 lvx v28,$x30,$key 781 stvx v25,$x10,$key_ # off-load round[4] 782 addi $key_,$sp,$FRAME+15 # rewind $key_ 783 ?vperm v26,v26,v27,$keyperm 784 lvx v29,$x40,$key 785 ?vperm v27,v27,v28,$keyperm 786 lvx v30,$x50,$key 787 ?vperm v28,v28,v29,$keyperm 788 lvx v31,$x60,$key 789 ?vperm v29,v29,v30,$keyperm 790 lvx $out0,$x70,$key # borrow $out0 791 ?vperm v30,v30,v31,$keyperm 792 lvx v24,$x00,$key_ # pre-load round[1] 793 ?vperm v31,v31,$out0,$keyperm 794 lvx v25,$x10,$key_ # pre-load round[2] 795 796 #lvx $inptail,0,$inp # "caller" already did this 797 #addi $inp,$inp,15 # 15 is not typo 798 subi $inp,$inp,15 # undo "caller" 799 800 le?li $idx,8 801 lvx_u $in0,$x00,$inp # load first 8 "words" 802 le?lvsl $inpperm,0,$idx 803 le?vspltisb $tmp,0x0f 804 lvx_u $in1,$x10,$inp 805 le?vxor $inpperm,$inpperm,$tmp # transform for lvx_u/stvx_u 806 lvx_u $in2,$x20,$inp 807 le?vperm $in0,$in0,$in0,$inpperm 808 lvx_u $in3,$x30,$inp 809 le?vperm $in1,$in1,$in1,$inpperm 810 lvx_u $in4,$x40,$inp 811 le?vperm $in2,$in2,$in2,$inpperm 812 vxor $out0,$in0,$rndkey0 813 lvx_u $in5,$x50,$inp 814 le?vperm $in3,$in3,$in3,$inpperm 815 vxor $out1,$in1,$rndkey0 816 lvx_u $in6,$x60,$inp 817 le?vperm $in4,$in4,$in4,$inpperm 818 vxor $out2,$in2,$rndkey0 819 lvx_u $in7,$x70,$inp 820 addi $inp,$inp,0x80 821 le?vperm $in5,$in5,$in5,$inpperm 822 vxor $out3,$in3,$rndkey0 823 le?vperm $in6,$in6,$in6,$inpperm 824 vxor $out4,$in4,$rndkey0 825 le?vperm $in7,$in7,$in7,$inpperm 826 vxor $out5,$in5,$rndkey0 827 vxor $out6,$in6,$rndkey0 828 vxor $out7,$in7,$rndkey0 829 830 mtctr $rounds 831 b Loop_cbc_dec8x 832.align 5 833Loop_cbc_dec8x: 834 vncipher $out0,$out0,v24 835 vncipher $out1,$out1,v24 836 vncipher $out2,$out2,v24 837 vncipher $out3,$out3,v24 838 vncipher $out4,$out4,v24 839 vncipher $out5,$out5,v24 840 vncipher $out6,$out6,v24 841 vncipher $out7,$out7,v24 842 lvx v24,$x20,$key_ # round[3] 843 addi $key_,$key_,0x20 844 845 vncipher $out0,$out0,v25 846 vncipher $out1,$out1,v25 847 vncipher $out2,$out2,v25 848 vncipher $out3,$out3,v25 849 vncipher $out4,$out4,v25 850 vncipher $out5,$out5,v25 851 vncipher $out6,$out6,v25 852 vncipher $out7,$out7,v25 853 lvx v25,$x10,$key_ # round[4] 854 bdnz Loop_cbc_dec8x 855 856 subic $len,$len,128 # $len-=128 857 vncipher $out0,$out0,v24 858 vncipher $out1,$out1,v24 859 vncipher $out2,$out2,v24 860 vncipher $out3,$out3,v24 861 vncipher $out4,$out4,v24 862 vncipher $out5,$out5,v24 863 vncipher $out6,$out6,v24 864 vncipher $out7,$out7,v24 865 866 subfe. r0,r0,r0 # borrow?-1:0 867 vncipher $out0,$out0,v25 868 vncipher $out1,$out1,v25 869 vncipher $out2,$out2,v25 870 vncipher $out3,$out3,v25 871 vncipher $out4,$out4,v25 872 vncipher $out5,$out5,v25 873 vncipher $out6,$out6,v25 874 vncipher $out7,$out7,v25 875 876 and r0,r0,$len 877 vncipher $out0,$out0,v26 878 vncipher $out1,$out1,v26 879 vncipher $out2,$out2,v26 880 vncipher $out3,$out3,v26 881 vncipher $out4,$out4,v26 882 vncipher $out5,$out5,v26 883 vncipher $out6,$out6,v26 884 vncipher $out7,$out7,v26 885 886 add $inp,$inp,r0 # $inp is adjusted in such 887 # way that at exit from the 888 # loop inX-in7 are loaded 889 # with last "words" 890 vncipher $out0,$out0,v27 891 vncipher $out1,$out1,v27 892 vncipher $out2,$out2,v27 893 vncipher $out3,$out3,v27 894 vncipher $out4,$out4,v27 895 vncipher $out5,$out5,v27 896 vncipher $out6,$out6,v27 897 vncipher $out7,$out7,v27 898 899 addi $key_,$sp,$FRAME+15 # rewind $key_ 900 vncipher $out0,$out0,v28 901 vncipher $out1,$out1,v28 902 vncipher $out2,$out2,v28 903 vncipher $out3,$out3,v28 904 vncipher $out4,$out4,v28 905 vncipher $out5,$out5,v28 906 vncipher $out6,$out6,v28 907 vncipher $out7,$out7,v28 908 lvx v24,$x00,$key_ # re-pre-load round[1] 909 910 vncipher $out0,$out0,v29 911 vncipher $out1,$out1,v29 912 vncipher $out2,$out2,v29 913 vncipher $out3,$out3,v29 914 vncipher $out4,$out4,v29 915 vncipher $out5,$out5,v29 916 vncipher $out6,$out6,v29 917 vncipher $out7,$out7,v29 918 lvx v25,$x10,$key_ # re-pre-load round[2] 919 920 vncipher $out0,$out0,v30 921 vxor $ivec,$ivec,v31 # xor with last round key 922 vncipher $out1,$out1,v30 923 vxor $in0,$in0,v31 924 vncipher $out2,$out2,v30 925 vxor $in1,$in1,v31 926 vncipher $out3,$out3,v30 927 vxor $in2,$in2,v31 928 vncipher $out4,$out4,v30 929 vxor $in3,$in3,v31 930 vncipher $out5,$out5,v30 931 vxor $in4,$in4,v31 932 vncipher $out6,$out6,v30 933 vxor $in5,$in5,v31 934 vncipher $out7,$out7,v30 935 vxor $in6,$in6,v31 936 937 vncipherlast $out0,$out0,$ivec 938 vncipherlast $out1,$out1,$in0 939 lvx_u $in0,$x00,$inp # load next input block 940 vncipherlast $out2,$out2,$in1 941 lvx_u $in1,$x10,$inp 942 vncipherlast $out3,$out3,$in2 943 le?vperm $in0,$in0,$in0,$inpperm 944 lvx_u $in2,$x20,$inp 945 vncipherlast $out4,$out4,$in3 946 le?vperm $in1,$in1,$in1,$inpperm 947 lvx_u $in3,$x30,$inp 948 vncipherlast $out5,$out5,$in4 949 le?vperm $in2,$in2,$in2,$inpperm 950 lvx_u $in4,$x40,$inp 951 vncipherlast $out6,$out6,$in5 952 le?vperm $in3,$in3,$in3,$inpperm 953 lvx_u $in5,$x50,$inp 954 vncipherlast $out7,$out7,$in6 955 le?vperm $in4,$in4,$in4,$inpperm 956 lvx_u $in6,$x60,$inp 957 vmr $ivec,$in7 958 le?vperm $in5,$in5,$in5,$inpperm 959 lvx_u $in7,$x70,$inp 960 addi $inp,$inp,0x80 961 962 le?vperm $out0,$out0,$out0,$inpperm 963 le?vperm $out1,$out1,$out1,$inpperm 964 stvx_u $out0,$x00,$out 965 le?vperm $in6,$in6,$in6,$inpperm 966 vxor $out0,$in0,$rndkey0 967 le?vperm $out2,$out2,$out2,$inpperm 968 stvx_u $out1,$x10,$out 969 le?vperm $in7,$in7,$in7,$inpperm 970 vxor $out1,$in1,$rndkey0 971 le?vperm $out3,$out3,$out3,$inpperm 972 stvx_u $out2,$x20,$out 973 vxor $out2,$in2,$rndkey0 974 le?vperm $out4,$out4,$out4,$inpperm 975 stvx_u $out3,$x30,$out 976 vxor $out3,$in3,$rndkey0 977 le?vperm $out5,$out5,$out5,$inpperm 978 stvx_u $out4,$x40,$out 979 vxor $out4,$in4,$rndkey0 980 le?vperm $out6,$out6,$out6,$inpperm 981 stvx_u $out5,$x50,$out 982 vxor $out5,$in5,$rndkey0 983 le?vperm $out7,$out7,$out7,$inpperm 984 stvx_u $out6,$x60,$out 985 vxor $out6,$in6,$rndkey0 986 stvx_u $out7,$x70,$out 987 addi $out,$out,0x80 988 vxor $out7,$in7,$rndkey0 989 990 mtctr $rounds 991 beq Loop_cbc_dec8x # did $len-=128 borrow? 992 993 addic. $len,$len,128 994 beq Lcbc_dec8x_done 995 nop 996 nop 997 998Loop_cbc_dec8x_tail: # up to 7 "words" tail... 999 vncipher $out1,$out1,v24 1000 vncipher $out2,$out2,v24 1001 vncipher $out3,$out3,v24 1002 vncipher $out4,$out4,v24 1003 vncipher $out5,$out5,v24 1004 vncipher $out6,$out6,v24 1005 vncipher $out7,$out7,v24 1006 lvx v24,$x20,$key_ # round[3] 1007 addi $key_,$key_,0x20 1008 1009 vncipher $out1,$out1,v25 1010 vncipher $out2,$out2,v25 1011 vncipher $out3,$out3,v25 1012 vncipher $out4,$out4,v25 1013 vncipher $out5,$out5,v25 1014 vncipher $out6,$out6,v25 1015 vncipher $out7,$out7,v25 1016 lvx v25,$x10,$key_ # round[4] 1017 bdnz Loop_cbc_dec8x_tail 1018 1019 vncipher $out1,$out1,v24 1020 vncipher $out2,$out2,v24 1021 vncipher $out3,$out3,v24 1022 vncipher $out4,$out4,v24 1023 vncipher $out5,$out5,v24 1024 vncipher $out6,$out6,v24 1025 vncipher $out7,$out7,v24 1026 1027 vncipher $out1,$out1,v25 1028 vncipher $out2,$out2,v25 1029 vncipher $out3,$out3,v25 1030 vncipher $out4,$out4,v25 1031 vncipher $out5,$out5,v25 1032 vncipher $out6,$out6,v25 1033 vncipher $out7,$out7,v25 1034 1035 vncipher $out1,$out1,v26 1036 vncipher $out2,$out2,v26 1037 vncipher $out3,$out3,v26 1038 vncipher $out4,$out4,v26 1039 vncipher $out5,$out5,v26 1040 vncipher $out6,$out6,v26 1041 vncipher $out7,$out7,v26 1042 1043 vncipher $out1,$out1,v27 1044 vncipher $out2,$out2,v27 1045 vncipher $out3,$out3,v27 1046 vncipher $out4,$out4,v27 1047 vncipher $out5,$out5,v27 1048 vncipher $out6,$out6,v27 1049 vncipher $out7,$out7,v27 1050 1051 vncipher $out1,$out1,v28 1052 vncipher $out2,$out2,v28 1053 vncipher $out3,$out3,v28 1054 vncipher $out4,$out4,v28 1055 vncipher $out5,$out5,v28 1056 vncipher $out6,$out6,v28 1057 vncipher $out7,$out7,v28 1058 1059 vncipher $out1,$out1,v29 1060 vncipher $out2,$out2,v29 1061 vncipher $out3,$out3,v29 1062 vncipher $out4,$out4,v29 1063 vncipher $out5,$out5,v29 1064 vncipher $out6,$out6,v29 1065 vncipher $out7,$out7,v29 1066 1067 vncipher $out1,$out1,v30 1068 vxor $ivec,$ivec,v31 # last round key 1069 vncipher $out2,$out2,v30 1070 vxor $in1,$in1,v31 1071 vncipher $out3,$out3,v30 1072 vxor $in2,$in2,v31 1073 vncipher $out4,$out4,v30 1074 vxor $in3,$in3,v31 1075 vncipher $out5,$out5,v30 1076 vxor $in4,$in4,v31 1077 vncipher $out6,$out6,v30 1078 vxor $in5,$in5,v31 1079 vncipher $out7,$out7,v30 1080 vxor $in6,$in6,v31 1081 1082 cmplwi $len,32 # switch($len) 1083 blt Lcbc_dec8x_one 1084 nop 1085 beq Lcbc_dec8x_two 1086 cmplwi $len,64 1087 blt Lcbc_dec8x_three 1088 nop 1089 beq Lcbc_dec8x_four 1090 cmplwi $len,96 1091 blt Lcbc_dec8x_five 1092 nop 1093 beq Lcbc_dec8x_six 1094 1095Lcbc_dec8x_seven: 1096 vncipherlast $out1,$out1,$ivec 1097 vncipherlast $out2,$out2,$in1 1098 vncipherlast $out3,$out3,$in2 1099 vncipherlast $out4,$out4,$in3 1100 vncipherlast $out5,$out5,$in4 1101 vncipherlast $out6,$out6,$in5 1102 vncipherlast $out7,$out7,$in6 1103 vmr $ivec,$in7 1104 1105 le?vperm $out1,$out1,$out1,$inpperm 1106 le?vperm $out2,$out2,$out2,$inpperm 1107 stvx_u $out1,$x00,$out 1108 le?vperm $out3,$out3,$out3,$inpperm 1109 stvx_u $out2,$x10,$out 1110 le?vperm $out4,$out4,$out4,$inpperm 1111 stvx_u $out3,$x20,$out 1112 le?vperm $out5,$out5,$out5,$inpperm 1113 stvx_u $out4,$x30,$out 1114 le?vperm $out6,$out6,$out6,$inpperm 1115 stvx_u $out5,$x40,$out 1116 le?vperm $out7,$out7,$out7,$inpperm 1117 stvx_u $out6,$x50,$out 1118 stvx_u $out7,$x60,$out 1119 addi $out,$out,0x70 1120 b Lcbc_dec8x_done 1121 1122.align 5 1123Lcbc_dec8x_six: 1124 vncipherlast $out2,$out2,$ivec 1125 vncipherlast $out3,$out3,$in2 1126 vncipherlast $out4,$out4,$in3 1127 vncipherlast $out5,$out5,$in4 1128 vncipherlast $out6,$out6,$in5 1129 vncipherlast $out7,$out7,$in6 1130 vmr $ivec,$in7 1131 1132 le?vperm $out2,$out2,$out2,$inpperm 1133 le?vperm $out3,$out3,$out3,$inpperm 1134 stvx_u $out2,$x00,$out 1135 le?vperm $out4,$out4,$out4,$inpperm 1136 stvx_u $out3,$x10,$out 1137 le?vperm $out5,$out5,$out5,$inpperm 1138 stvx_u $out4,$x20,$out 1139 le?vperm $out6,$out6,$out6,$inpperm 1140 stvx_u $out5,$x30,$out 1141 le?vperm $out7,$out7,$out7,$inpperm 1142 stvx_u $out6,$x40,$out 1143 stvx_u $out7,$x50,$out 1144 addi $out,$out,0x60 1145 b Lcbc_dec8x_done 1146 1147.align 5 1148Lcbc_dec8x_five: 1149 vncipherlast $out3,$out3,$ivec 1150 vncipherlast $out4,$out4,$in3 1151 vncipherlast $out5,$out5,$in4 1152 vncipherlast $out6,$out6,$in5 1153 vncipherlast $out7,$out7,$in6 1154 vmr $ivec,$in7 1155 1156 le?vperm $out3,$out3,$out3,$inpperm 1157 le?vperm $out4,$out4,$out4,$inpperm 1158 stvx_u $out3,$x00,$out 1159 le?vperm $out5,$out5,$out5,$inpperm 1160 stvx_u $out4,$x10,$out 1161 le?vperm $out6,$out6,$out6,$inpperm 1162 stvx_u $out5,$x20,$out 1163 le?vperm $out7,$out7,$out7,$inpperm 1164 stvx_u $out6,$x30,$out 1165 stvx_u $out7,$x40,$out 1166 addi $out,$out,0x50 1167 b Lcbc_dec8x_done 1168 1169.align 5 1170Lcbc_dec8x_four: 1171 vncipherlast $out4,$out4,$ivec 1172 vncipherlast $out5,$out5,$in4 1173 vncipherlast $out6,$out6,$in5 1174 vncipherlast $out7,$out7,$in6 1175 vmr $ivec,$in7 1176 1177 le?vperm $out4,$out4,$out4,$inpperm 1178 le?vperm $out5,$out5,$out5,$inpperm 1179 stvx_u $out4,$x00,$out 1180 le?vperm $out6,$out6,$out6,$inpperm 1181 stvx_u $out5,$x10,$out 1182 le?vperm $out7,$out7,$out7,$inpperm 1183 stvx_u $out6,$x20,$out 1184 stvx_u $out7,$x30,$out 1185 addi $out,$out,0x40 1186 b Lcbc_dec8x_done 1187 1188.align 5 1189Lcbc_dec8x_three: 1190 vncipherlast $out5,$out5,$ivec 1191 vncipherlast $out6,$out6,$in5 1192 vncipherlast $out7,$out7,$in6 1193 vmr $ivec,$in7 1194 1195 le?vperm $out5,$out5,$out5,$inpperm 1196 le?vperm $out6,$out6,$out6,$inpperm 1197 stvx_u $out5,$x00,$out 1198 le?vperm $out7,$out7,$out7,$inpperm 1199 stvx_u $out6,$x10,$out 1200 stvx_u $out7,$x20,$out 1201 addi $out,$out,0x30 1202 b Lcbc_dec8x_done 1203 1204.align 5 1205Lcbc_dec8x_two: 1206 vncipherlast $out6,$out6,$ivec 1207 vncipherlast $out7,$out7,$in6 1208 vmr $ivec,$in7 1209 1210 le?vperm $out6,$out6,$out6,$inpperm 1211 le?vperm $out7,$out7,$out7,$inpperm 1212 stvx_u $out6,$x00,$out 1213 stvx_u $out7,$x10,$out 1214 addi $out,$out,0x20 1215 b Lcbc_dec8x_done 1216 1217.align 5 1218Lcbc_dec8x_one: 1219 vncipherlast $out7,$out7,$ivec 1220 vmr $ivec,$in7 1221 1222 le?vperm $out7,$out7,$out7,$inpperm 1223 stvx_u $out7,0,$out 1224 addi $out,$out,0x10 1225 1226Lcbc_dec8x_done: 1227 le?vperm $ivec,$ivec,$ivec,$inpperm 1228 stvx_u $ivec,0,$ivp # write [unaligned] iv 1229 1230 li r10,`$FRAME+15` 1231 li r11,`$FRAME+31` 1232 stvx $inpperm,r10,$sp # wipe copies of round keys 1233 addi r10,r10,32 1234 stvx $inpperm,r11,$sp 1235 addi r11,r11,32 1236 stvx $inpperm,r10,$sp 1237 addi r10,r10,32 1238 stvx $inpperm,r11,$sp 1239 addi r11,r11,32 1240 stvx $inpperm,r10,$sp 1241 addi r10,r10,32 1242 stvx $inpperm,r11,$sp 1243 addi r11,r11,32 1244 stvx $inpperm,r10,$sp 1245 addi r10,r10,32 1246 stvx $inpperm,r11,$sp 1247 addi r11,r11,32 1248 1249 mtspr 256,$vrsave 1250 lvx v20,r10,$sp # ABI says so 1251 addi r10,r10,32 1252 lvx v21,r11,$sp 1253 addi r11,r11,32 1254 lvx v22,r10,$sp 1255 addi r10,r10,32 1256 lvx v23,r11,$sp 1257 addi r11,r11,32 1258 lvx v24,r10,$sp 1259 addi r10,r10,32 1260 lvx v25,r11,$sp 1261 addi r11,r11,32 1262 lvx v26,r10,$sp 1263 addi r10,r10,32 1264 lvx v27,r11,$sp 1265 addi r11,r11,32 1266 lvx v28,r10,$sp 1267 addi r10,r10,32 1268 lvx v29,r11,$sp 1269 addi r11,r11,32 1270 lvx v30,r10,$sp 1271 lvx v31,r11,$sp 1272 $POP r26,`$FRAME+21*16+0*$SIZE_T`($sp) 1273 $POP r27,`$FRAME+21*16+1*$SIZE_T`($sp) 1274 $POP r28,`$FRAME+21*16+2*$SIZE_T`($sp) 1275 $POP r29,`$FRAME+21*16+3*$SIZE_T`($sp) 1276 $POP r30,`$FRAME+21*16+4*$SIZE_T`($sp) 1277 $POP r31,`$FRAME+21*16+5*$SIZE_T`($sp) 1278 addi $sp,$sp,`$FRAME+21*16+6*$SIZE_T` 1279 blr 1280 .long 0 1281 .byte 0,12,0x14,0,0x80,6,6,0 1282 .long 0 1283.size .${prefix}_cbc_encrypt,.-.${prefix}_cbc_encrypt 1284___ 1285}} }}} 1286 1287######################################################################### 1288{{{ # CTR procedure[s] # 1289 1290####################### WARNING: Here be dragons! ####################### 1291# 1292# This code is written as 'ctr32', based on a 32-bit counter used 1293# upstream. The kernel does *not* use a 32-bit counter. The kernel uses 1294# a 128-bit counter. 1295# 1296# This leads to subtle changes from the upstream code: the counter 1297# is incremented with vaddu_q_m rather than vaddu_w_m. This occurs in 1298# both the bulk (8 blocks at a time) path, and in the individual block 1299# path. Be aware of this when doing updates. 1300# 1301# See: 1302# 1d4aa0b4c181 ("crypto: vmx - Fixing AES-CTR counter bug") 1303# 009b30ac7444 ("crypto: vmx - CTR: always increment IV as quadword") 1304# https://github.com/openssl/openssl/pull/8942 1305# 1306######################################################################### 1307my ($inp,$out,$len,$key,$ivp,$x10,$rounds,$idx)=map("r$_",(3..10)); 1308my ($rndkey0,$rndkey1,$inout,$tmp)= map("v$_",(0..3)); 1309my ($ivec,$inptail,$inpperm,$outhead,$outperm,$outmask,$keyperm,$one)= 1310 map("v$_",(4..11)); 1311my $dat=$tmp; 1312 1313$code.=<<___; 1314.globl .${prefix}_ctr32_encrypt_blocks 1315 ${UCMP}i $len,1 1316 bltlr- 1317 1318 lis r0,0xfff0 1319 mfspr $vrsave,256 1320 mtspr 256,r0 1321 1322 li $idx,15 1323 vxor $rndkey0,$rndkey0,$rndkey0 1324 le?vspltisb $tmp,0x0f 1325 1326 lvx $ivec,0,$ivp # load [unaligned] iv 1327 lvsl $inpperm,0,$ivp 1328 lvx $inptail,$idx,$ivp 1329 vspltisb $one,1 1330 le?vxor $inpperm,$inpperm,$tmp 1331 vperm $ivec,$ivec,$inptail,$inpperm 1332 vsldoi $one,$rndkey0,$one,1 1333 1334 neg r11,$inp 1335 ?lvsl $keyperm,0,$key # prepare for unaligned key 1336 lwz $rounds,240($key) 1337 1338 lvsr $inpperm,0,r11 # prepare for unaligned load 1339 lvx $inptail,0,$inp 1340 addi $inp,$inp,15 # 15 is not typo 1341 le?vxor $inpperm,$inpperm,$tmp 1342 1343 srwi $rounds,$rounds,1 1344 li $idx,16 1345 subi $rounds,$rounds,1 1346 1347 ${UCMP}i $len,8 1348 bge _aesp8_ctr32_encrypt8x 1349 1350 ?lvsr $outperm,0,$out # prepare for unaligned store 1351 vspltisb $outmask,-1 1352 lvx $outhead,0,$out 1353 ?vperm $outmask,$rndkey0,$outmask,$outperm 1354 le?vxor $outperm,$outperm,$tmp 1355 1356 lvx $rndkey0,0,$key 1357 mtctr $rounds 1358 lvx $rndkey1,$idx,$key 1359 addi $idx,$idx,16 1360 ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm 1361 vxor $inout,$ivec,$rndkey0 1362 lvx $rndkey0,$idx,$key 1363 addi $idx,$idx,16 1364 b Loop_ctr32_enc 1365 1366.align 5 1367Loop_ctr32_enc: 1368 ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm 1369 vcipher $inout,$inout,$rndkey1 1370 lvx $rndkey1,$idx,$key 1371 addi $idx,$idx,16 1372 ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm 1373 vcipher $inout,$inout,$rndkey0 1374 lvx $rndkey0,$idx,$key 1375 addi $idx,$idx,16 1376 bdnz Loop_ctr32_enc 1377 1378 vadduqm $ivec,$ivec,$one # Kernel change for 128-bit 1379 vmr $dat,$inptail 1380 lvx $inptail,0,$inp 1381 addi $inp,$inp,16 1382 subic. $len,$len,1 # blocks-- 1383 1384 ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm 1385 vcipher $inout,$inout,$rndkey1 1386 lvx $rndkey1,$idx,$key 1387 vperm $dat,$dat,$inptail,$inpperm 1388 li $idx,16 1389 ?vperm $rndkey1,$rndkey0,$rndkey1,$keyperm 1390 lvx $rndkey0,0,$key 1391 vxor $dat,$dat,$rndkey1 # last round key 1392 vcipherlast $inout,$inout,$dat 1393 1394 lvx $rndkey1,$idx,$key 1395 addi $idx,$idx,16 1396 vperm $inout,$inout,$inout,$outperm 1397 vsel $dat,$outhead,$inout,$outmask 1398 mtctr $rounds 1399 ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm 1400 vmr $outhead,$inout 1401 vxor $inout,$ivec,$rndkey0 1402 lvx $rndkey0,$idx,$key 1403 addi $idx,$idx,16 1404 stvx $dat,0,$out 1405 addi $out,$out,16 1406 bne Loop_ctr32_enc 1407 1408 addi $out,$out,-1 1409 lvx $inout,0,$out # redundant in aligned case 1410 vsel $inout,$outhead,$inout,$outmask 1411 stvx $inout,0,$out 1412 1413 mtspr 256,$vrsave 1414 blr 1415 .long 0 1416 .byte 0,12,0x14,0,0,0,6,0 1417 .long 0 1418___ 1419######################################################################### 1420{{ # Optimized CTR procedure # 1421my $key_="r11"; 1422my ($x00,$x10,$x20,$x30,$x40,$x50,$x60,$x70)=map("r$_",(0,8,26..31)); 1423my ($in0, $in1, $in2, $in3, $in4, $in5, $in6, $in7 )=map("v$_",(0..3,10,12..14)); 1424my ($out0,$out1,$out2,$out3,$out4,$out5,$out6,$out7)=map("v$_",(15..22)); 1425my $rndkey0="v23"; # v24-v25 rotating buffer for first found keys 1426 # v26-v31 last 6 round keys 1427my ($tmp,$keyperm)=($in3,$in4); # aliases with "caller", redundant assignment 1428my ($two,$three,$four)=($outhead,$outperm,$outmask); 1429 1430$code.=<<___; 1431.align 5 1432_aesp8_ctr32_encrypt8x: 1433 $STU $sp,-`($FRAME+21*16+6*$SIZE_T)`($sp) 1434 li r10,`$FRAME+8*16+15` 1435 li r11,`$FRAME+8*16+31` 1436 stvx v20,r10,$sp # ABI says so 1437 addi r10,r10,32 1438 stvx v21,r11,$sp 1439 addi r11,r11,32 1440 stvx v22,r10,$sp 1441 addi r10,r10,32 1442 stvx v23,r11,$sp 1443 addi r11,r11,32 1444 stvx v24,r10,$sp 1445 addi r10,r10,32 1446 stvx v25,r11,$sp 1447 addi r11,r11,32 1448 stvx v26,r10,$sp 1449 addi r10,r10,32 1450 stvx v27,r11,$sp 1451 addi r11,r11,32 1452 stvx v28,r10,$sp 1453 addi r10,r10,32 1454 stvx v29,r11,$sp 1455 addi r11,r11,32 1456 stvx v30,r10,$sp 1457 stvx v31,r11,$sp 1458 li r0,-1 1459 stw $vrsave,`$FRAME+21*16-4`($sp) # save vrsave 1460 li $x10,0x10 1461 $PUSH r26,`$FRAME+21*16+0*$SIZE_T`($sp) 1462 li $x20,0x20 1463 $PUSH r27,`$FRAME+21*16+1*$SIZE_T`($sp) 1464 li $x30,0x30 1465 $PUSH r28,`$FRAME+21*16+2*$SIZE_T`($sp) 1466 li $x40,0x40 1467 $PUSH r29,`$FRAME+21*16+3*$SIZE_T`($sp) 1468 li $x50,0x50 1469 $PUSH r30,`$FRAME+21*16+4*$SIZE_T`($sp) 1470 li $x60,0x60 1471 $PUSH r31,`$FRAME+21*16+5*$SIZE_T`($sp) 1472 li $x70,0x70 1473 mtspr 256,r0 1474 1475 subi $rounds,$rounds,3 # -4 in total 1476 1477 lvx $rndkey0,$x00,$key # load key schedule 1478 lvx v30,$x10,$key 1479 addi $key,$key,0x20 1480 lvx v31,$x00,$key 1481 ?vperm $rndkey0,$rndkey0,v30,$keyperm 1482 addi $key_,$sp,$FRAME+15 1483 mtctr $rounds 1484 1485Load_ctr32_enc_key: 1486 ?vperm v24,v30,v31,$keyperm 1487 lvx v30,$x10,$key 1488 addi $key,$key,0x20 1489 stvx v24,$x00,$key_ # off-load round[1] 1490 ?vperm v25,v31,v30,$keyperm 1491 lvx v31,$x00,$key 1492 stvx v25,$x10,$key_ # off-load round[2] 1493 addi $key_,$key_,0x20 1494 bdnz Load_ctr32_enc_key 1495 1496 lvx v26,$x10,$key 1497 ?vperm v24,v30,v31,$keyperm 1498 lvx v27,$x20,$key 1499 stvx v24,$x00,$key_ # off-load round[3] 1500 ?vperm v25,v31,v26,$keyperm 1501 lvx v28,$x30,$key 1502 stvx v25,$x10,$key_ # off-load round[4] 1503 addi $key_,$sp,$FRAME+15 # rewind $key_ 1504 ?vperm v26,v26,v27,$keyperm 1505 lvx v29,$x40,$key 1506 ?vperm v27,v27,v28,$keyperm 1507 lvx v30,$x50,$key 1508 ?vperm v28,v28,v29,$keyperm 1509 lvx v31,$x60,$key 1510 ?vperm v29,v29,v30,$keyperm 1511 lvx $out0,$x70,$key # borrow $out0 1512 ?vperm v30,v30,v31,$keyperm 1513 lvx v24,$x00,$key_ # pre-load round[1] 1514 ?vperm v31,v31,$out0,$keyperm 1515 lvx v25,$x10,$key_ # pre-load round[2] 1516 1517 vadduqm $two,$one,$one 1518 subi $inp,$inp,15 # undo "caller" 1519 $SHL $len,$len,4 1520 1521 vadduqm $out1,$ivec,$one # counter values ... 1522 vadduqm $out2,$ivec,$two # (do all ctr adds as 128-bit) 1523 vxor $out0,$ivec,$rndkey0 # ... xored with rndkey[0] 1524 le?li $idx,8 1525 vadduqm $out3,$out1,$two 1526 vxor $out1,$out1,$rndkey0 1527 le?lvsl $inpperm,0,$idx 1528 vadduqm $out4,$out2,$two 1529 vxor $out2,$out2,$rndkey0 1530 le?vspltisb $tmp,0x0f 1531 vadduqm $out5,$out3,$two 1532 vxor $out3,$out3,$rndkey0 1533 le?vxor $inpperm,$inpperm,$tmp # transform for lvx_u/stvx_u 1534 vadduqm $out6,$out4,$two 1535 vxor $out4,$out4,$rndkey0 1536 vadduqm $out7,$out5,$two 1537 vxor $out5,$out5,$rndkey0 1538 vadduqm $ivec,$out6,$two # next counter value 1539 vxor $out6,$out6,$rndkey0 1540 vxor $out7,$out7,$rndkey0 1541 1542 mtctr $rounds 1543 b Loop_ctr32_enc8x 1544.align 5 1545Loop_ctr32_enc8x: 1546 vcipher $out0,$out0,v24 1547 vcipher $out1,$out1,v24 1548 vcipher $out2,$out2,v24 1549 vcipher $out3,$out3,v24 1550 vcipher $out4,$out4,v24 1551 vcipher $out5,$out5,v24 1552 vcipher $out6,$out6,v24 1553 vcipher $out7,$out7,v24 1554Loop_ctr32_enc8x_middle: 1555 lvx v24,$x20,$key_ # round[3] 1556 addi $key_,$key_,0x20 1557 1558 vcipher $out0,$out0,v25 1559 vcipher $out1,$out1,v25 1560 vcipher $out2,$out2,v25 1561 vcipher $out3,$out3,v25 1562 vcipher $out4,$out4,v25 1563 vcipher $out5,$out5,v25 1564 vcipher $out6,$out6,v25 1565 vcipher $out7,$out7,v25 1566 lvx v25,$x10,$key_ # round[4] 1567 bdnz Loop_ctr32_enc8x 1568 1569 subic r11,$len,256 # $len-256, borrow $key_ 1570 vcipher $out0,$out0,v24 1571 vcipher $out1,$out1,v24 1572 vcipher $out2,$out2,v24 1573 vcipher $out3,$out3,v24 1574 vcipher $out4,$out4,v24 1575 vcipher $out5,$out5,v24 1576 vcipher $out6,$out6,v24 1577 vcipher $out7,$out7,v24 1578 1579 subfe r0,r0,r0 # borrow?-1:0 1580 vcipher $out0,$out0,v25 1581 vcipher $out1,$out1,v25 1582 vcipher $out2,$out2,v25 1583 vcipher $out3,$out3,v25 1584 vcipher $out4,$out4,v25 1585 vcipher $out5,$out5,v25 1586 vcipher $out6,$out6,v25 1587 vcipher $out7,$out7,v25 1588 1589 and r0,r0,r11 1590 addi $key_,$sp,$FRAME+15 # rewind $key_ 1591 vcipher $out0,$out0,v26 1592 vcipher $out1,$out1,v26 1593 vcipher $out2,$out2,v26 1594 vcipher $out3,$out3,v26 1595 vcipher $out4,$out4,v26 1596 vcipher $out5,$out5,v26 1597 vcipher $out6,$out6,v26 1598 vcipher $out7,$out7,v26 1599 lvx v24,$x00,$key_ # re-pre-load round[1] 1600 1601 subic $len,$len,129 # $len-=129 1602 vcipher $out0,$out0,v27 1603 addi $len,$len,1 # $len-=128 really 1604 vcipher $out1,$out1,v27 1605 vcipher $out2,$out2,v27 1606 vcipher $out3,$out3,v27 1607 vcipher $out4,$out4,v27 1608 vcipher $out5,$out5,v27 1609 vcipher $out6,$out6,v27 1610 vcipher $out7,$out7,v27 1611 lvx v25,$x10,$key_ # re-pre-load round[2] 1612 1613 vcipher $out0,$out0,v28 1614 lvx_u $in0,$x00,$inp # load input 1615 vcipher $out1,$out1,v28 1616 lvx_u $in1,$x10,$inp 1617 vcipher $out2,$out2,v28 1618 lvx_u $in2,$x20,$inp 1619 vcipher $out3,$out3,v28 1620 lvx_u $in3,$x30,$inp 1621 vcipher $out4,$out4,v28 1622 lvx_u $in4,$x40,$inp 1623 vcipher $out5,$out5,v28 1624 lvx_u $in5,$x50,$inp 1625 vcipher $out6,$out6,v28 1626 lvx_u $in6,$x60,$inp 1627 vcipher $out7,$out7,v28 1628 lvx_u $in7,$x70,$inp 1629 addi $inp,$inp,0x80 1630 1631 vcipher $out0,$out0,v29 1632 le?vperm $in0,$in0,$in0,$inpperm 1633 vcipher $out1,$out1,v29 1634 le?vperm $in1,$in1,$in1,$inpperm 1635 vcipher $out2,$out2,v29 1636 le?vperm $in2,$in2,$in2,$inpperm 1637 vcipher $out3,$out3,v29 1638 le?vperm $in3,$in3,$in3,$inpperm 1639 vcipher $out4,$out4,v29 1640 le?vperm $in4,$in4,$in4,$inpperm 1641 vcipher $out5,$out5,v29 1642 le?vperm $in5,$in5,$in5,$inpperm 1643 vcipher $out6,$out6,v29 1644 le?vperm $in6,$in6,$in6,$inpperm 1645 vcipher $out7,$out7,v29 1646 le?vperm $in7,$in7,$in7,$inpperm 1647 1648 add $inp,$inp,r0 # $inp is adjusted in such 1649 # way that at exit from the 1650 # loop inX-in7 are loaded 1651 # with last "words" 1652 subfe. r0,r0,r0 # borrow?-1:0 1653 vcipher $out0,$out0,v30 1654 vxor $in0,$in0,v31 # xor with last round key 1655 vcipher $out1,$out1,v30 1656 vxor $in1,$in1,v31 1657 vcipher $out2,$out2,v30 1658 vxor $in2,$in2,v31 1659 vcipher $out3,$out3,v30 1660 vxor $in3,$in3,v31 1661 vcipher $out4,$out4,v30 1662 vxor $in4,$in4,v31 1663 vcipher $out5,$out5,v30 1664 vxor $in5,$in5,v31 1665 vcipher $out6,$out6,v30 1666 vxor $in6,$in6,v31 1667 vcipher $out7,$out7,v30 1668 vxor $in7,$in7,v31 1669 1670 bne Lctr32_enc8x_break # did $len-129 borrow? 1671 1672 vcipherlast $in0,$out0,$in0 1673 vcipherlast $in1,$out1,$in1 1674 vadduqm $out1,$ivec,$one # counter values ... 1675 vcipherlast $in2,$out2,$in2 1676 vadduqm $out2,$ivec,$two 1677 vxor $out0,$ivec,$rndkey0 # ... xored with rndkey[0] 1678 vcipherlast $in3,$out3,$in3 1679 vadduqm $out3,$out1,$two 1680 vxor $out1,$out1,$rndkey0 1681 vcipherlast $in4,$out4,$in4 1682 vadduqm $out4,$out2,$two 1683 vxor $out2,$out2,$rndkey0 1684 vcipherlast $in5,$out5,$in5 1685 vadduqm $out5,$out3,$two 1686 vxor $out3,$out3,$rndkey0 1687 vcipherlast $in6,$out6,$in6 1688 vadduqm $out6,$out4,$two 1689 vxor $out4,$out4,$rndkey0 1690 vcipherlast $in7,$out7,$in7 1691 vadduqm $out7,$out5,$two 1692 vxor $out5,$out5,$rndkey0 1693 le?vperm $in0,$in0,$in0,$inpperm 1694 vadduqm $ivec,$out6,$two # next counter value 1695 vxor $out6,$out6,$rndkey0 1696 le?vperm $in1,$in1,$in1,$inpperm 1697 vxor $out7,$out7,$rndkey0 1698 mtctr $rounds 1699 1700 vcipher $out0,$out0,v24 1701 stvx_u $in0,$x00,$out 1702 le?vperm $in2,$in2,$in2,$inpperm 1703 vcipher $out1,$out1,v24 1704 stvx_u $in1,$x10,$out 1705 le?vperm $in3,$in3,$in3,$inpperm 1706 vcipher $out2,$out2,v24 1707 stvx_u $in2,$x20,$out 1708 le?vperm $in4,$in4,$in4,$inpperm 1709 vcipher $out3,$out3,v24 1710 stvx_u $in3,$x30,$out 1711 le?vperm $in5,$in5,$in5,$inpperm 1712 vcipher $out4,$out4,v24 1713 stvx_u $in4,$x40,$out 1714 le?vperm $in6,$in6,$in6,$inpperm 1715 vcipher $out5,$out5,v24 1716 stvx_u $in5,$x50,$out 1717 le?vperm $in7,$in7,$in7,$inpperm 1718 vcipher $out6,$out6,v24 1719 stvx_u $in6,$x60,$out 1720 vcipher $out7,$out7,v24 1721 stvx_u $in7,$x70,$out 1722 addi $out,$out,0x80 1723 1724 b Loop_ctr32_enc8x_middle 1725 1726.align 5 1727Lctr32_enc8x_break: 1728 cmpwi $len,-0x60 1729 blt Lctr32_enc8x_one 1730 nop 1731 beq Lctr32_enc8x_two 1732 cmpwi $len,-0x40 1733 blt Lctr32_enc8x_three 1734 nop 1735 beq Lctr32_enc8x_four 1736 cmpwi $len,-0x20 1737 blt Lctr32_enc8x_five 1738 nop 1739 beq Lctr32_enc8x_six 1740 cmpwi $len,0x00 1741 blt Lctr32_enc8x_seven 1742 1743Lctr32_enc8x_eight: 1744 vcipherlast $out0,$out0,$in0 1745 vcipherlast $out1,$out1,$in1 1746 vcipherlast $out2,$out2,$in2 1747 vcipherlast $out3,$out3,$in3 1748 vcipherlast $out4,$out4,$in4 1749 vcipherlast $out5,$out5,$in5 1750 vcipherlast $out6,$out6,$in6 1751 vcipherlast $out7,$out7,$in7 1752 1753 le?vperm $out0,$out0,$out0,$inpperm 1754 le?vperm $out1,$out1,$out1,$inpperm 1755 stvx_u $out0,$x00,$out 1756 le?vperm $out2,$out2,$out2,$inpperm 1757 stvx_u $out1,$x10,$out 1758 le?vperm $out3,$out3,$out3,$inpperm 1759 stvx_u $out2,$x20,$out 1760 le?vperm $out4,$out4,$out4,$inpperm 1761 stvx_u $out3,$x30,$out 1762 le?vperm $out5,$out5,$out5,$inpperm 1763 stvx_u $out4,$x40,$out 1764 le?vperm $out6,$out6,$out6,$inpperm 1765 stvx_u $out5,$x50,$out 1766 le?vperm $out7,$out7,$out7,$inpperm 1767 stvx_u $out6,$x60,$out 1768 stvx_u $out7,$x70,$out 1769 addi $out,$out,0x80 1770 b Lctr32_enc8x_done 1771 1772.align 5 1773Lctr32_enc8x_seven: 1774 vcipherlast $out0,$out0,$in1 1775 vcipherlast $out1,$out1,$in2 1776 vcipherlast $out2,$out2,$in3 1777 vcipherlast $out3,$out3,$in4 1778 vcipherlast $out4,$out4,$in5 1779 vcipherlast $out5,$out5,$in6 1780 vcipherlast $out6,$out6,$in7 1781 1782 le?vperm $out0,$out0,$out0,$inpperm 1783 le?vperm $out1,$out1,$out1,$inpperm 1784 stvx_u $out0,$x00,$out 1785 le?vperm $out2,$out2,$out2,$inpperm 1786 stvx_u $out1,$x10,$out 1787 le?vperm $out3,$out3,$out3,$inpperm 1788 stvx_u $out2,$x20,$out 1789 le?vperm $out4,$out4,$out4,$inpperm 1790 stvx_u $out3,$x30,$out 1791 le?vperm $out5,$out5,$out5,$inpperm 1792 stvx_u $out4,$x40,$out 1793 le?vperm $out6,$out6,$out6,$inpperm 1794 stvx_u $out5,$x50,$out 1795 stvx_u $out6,$x60,$out 1796 addi $out,$out,0x70 1797 b Lctr32_enc8x_done 1798 1799.align 5 1800Lctr32_enc8x_six: 1801 vcipherlast $out0,$out0,$in2 1802 vcipherlast $out1,$out1,$in3 1803 vcipherlast $out2,$out2,$in4 1804 vcipherlast $out3,$out3,$in5 1805 vcipherlast $out4,$out4,$in6 1806 vcipherlast $out5,$out5,$in7 1807 1808 le?vperm $out0,$out0,$out0,$inpperm 1809 le?vperm $out1,$out1,$out1,$inpperm 1810 stvx_u $out0,$x00,$out 1811 le?vperm $out2,$out2,$out2,$inpperm 1812 stvx_u $out1,$x10,$out 1813 le?vperm $out3,$out3,$out3,$inpperm 1814 stvx_u $out2,$x20,$out 1815 le?vperm $out4,$out4,$out4,$inpperm 1816 stvx_u $out3,$x30,$out 1817 le?vperm $out5,$out5,$out5,$inpperm 1818 stvx_u $out4,$x40,$out 1819 stvx_u $out5,$x50,$out 1820 addi $out,$out,0x60 1821 b Lctr32_enc8x_done 1822 1823.align 5 1824Lctr32_enc8x_five: 1825 vcipherlast $out0,$out0,$in3 1826 vcipherlast $out1,$out1,$in4 1827 vcipherlast $out2,$out2,$in5 1828 vcipherlast $out3,$out3,$in6 1829 vcipherlast $out4,$out4,$in7 1830 1831 le?vperm $out0,$out0,$out0,$inpperm 1832 le?vperm $out1,$out1,$out1,$inpperm 1833 stvx_u $out0,$x00,$out 1834 le?vperm $out2,$out2,$out2,$inpperm 1835 stvx_u $out1,$x10,$out 1836 le?vperm $out3,$out3,$out3,$inpperm 1837 stvx_u $out2,$x20,$out 1838 le?vperm $out4,$out4,$out4,$inpperm 1839 stvx_u $out3,$x30,$out 1840 stvx_u $out4,$x40,$out 1841 addi $out,$out,0x50 1842 b Lctr32_enc8x_done 1843 1844.align 5 1845Lctr32_enc8x_four: 1846 vcipherlast $out0,$out0,$in4 1847 vcipherlast $out1,$out1,$in5 1848 vcipherlast $out2,$out2,$in6 1849 vcipherlast $out3,$out3,$in7 1850 1851 le?vperm $out0,$out0,$out0,$inpperm 1852 le?vperm $out1,$out1,$out1,$inpperm 1853 stvx_u $out0,$x00,$out 1854 le?vperm $out2,$out2,$out2,$inpperm 1855 stvx_u $out1,$x10,$out 1856 le?vperm $out3,$out3,$out3,$inpperm 1857 stvx_u $out2,$x20,$out 1858 stvx_u $out3,$x30,$out 1859 addi $out,$out,0x40 1860 b Lctr32_enc8x_done 1861 1862.align 5 1863Lctr32_enc8x_three: 1864 vcipherlast $out0,$out0,$in5 1865 vcipherlast $out1,$out1,$in6 1866 vcipherlast $out2,$out2,$in7 1867 1868 le?vperm $out0,$out0,$out0,$inpperm 1869 le?vperm $out1,$out1,$out1,$inpperm 1870 stvx_u $out0,$x00,$out 1871 le?vperm $out2,$out2,$out2,$inpperm 1872 stvx_u $out1,$x10,$out 1873 stvx_u $out2,$x20,$out 1874 addi $out,$out,0x30 1875 b Lctr32_enc8x_done 1876 1877.align 5 1878Lctr32_enc8x_two: 1879 vcipherlast $out0,$out0,$in6 1880 vcipherlast $out1,$out1,$in7 1881 1882 le?vperm $out0,$out0,$out0,$inpperm 1883 le?vperm $out1,$out1,$out1,$inpperm 1884 stvx_u $out0,$x00,$out 1885 stvx_u $out1,$x10,$out 1886 addi $out,$out,0x20 1887 b Lctr32_enc8x_done 1888 1889.align 5 1890Lctr32_enc8x_one: 1891 vcipherlast $out0,$out0,$in7 1892 1893 le?vperm $out0,$out0,$out0,$inpperm 1894 stvx_u $out0,0,$out 1895 addi $out,$out,0x10 1896 1897Lctr32_enc8x_done: 1898 li r10,`$FRAME+15` 1899 li r11,`$FRAME+31` 1900 stvx $inpperm,r10,$sp # wipe copies of round keys 1901 addi r10,r10,32 1902 stvx $inpperm,r11,$sp 1903 addi r11,r11,32 1904 stvx $inpperm,r10,$sp 1905 addi r10,r10,32 1906 stvx $inpperm,r11,$sp 1907 addi r11,r11,32 1908 stvx $inpperm,r10,$sp 1909 addi r10,r10,32 1910 stvx $inpperm,r11,$sp 1911 addi r11,r11,32 1912 stvx $inpperm,r10,$sp 1913 addi r10,r10,32 1914 stvx $inpperm,r11,$sp 1915 addi r11,r11,32 1916 1917 mtspr 256,$vrsave 1918 lvx v20,r10,$sp # ABI says so 1919 addi r10,r10,32 1920 lvx v21,r11,$sp 1921 addi r11,r11,32 1922 lvx v22,r10,$sp 1923 addi r10,r10,32 1924 lvx v23,r11,$sp 1925 addi r11,r11,32 1926 lvx v24,r10,$sp 1927 addi r10,r10,32 1928 lvx v25,r11,$sp 1929 addi r11,r11,32 1930 lvx v26,r10,$sp 1931 addi r10,r10,32 1932 lvx v27,r11,$sp 1933 addi r11,r11,32 1934 lvx v28,r10,$sp 1935 addi r10,r10,32 1936 lvx v29,r11,$sp 1937 addi r11,r11,32 1938 lvx v30,r10,$sp 1939 lvx v31,r11,$sp 1940 $POP r26,`$FRAME+21*16+0*$SIZE_T`($sp) 1941 $POP r27,`$FRAME+21*16+1*$SIZE_T`($sp) 1942 $POP r28,`$FRAME+21*16+2*$SIZE_T`($sp) 1943 $POP r29,`$FRAME+21*16+3*$SIZE_T`($sp) 1944 $POP r30,`$FRAME+21*16+4*$SIZE_T`($sp) 1945 $POP r31,`$FRAME+21*16+5*$SIZE_T`($sp) 1946 addi $sp,$sp,`$FRAME+21*16+6*$SIZE_T` 1947 blr 1948 .long 0 1949 .byte 0,12,0x14,0,0x80,6,6,0 1950 .long 0 1951.size .${prefix}_ctr32_encrypt_blocks,.-.${prefix}_ctr32_encrypt_blocks 1952___ 1953}} }}} 1954 1955######################################################################### 1956{{{ # XTS procedures # 1957# int aes_p8_xts_[en|de]crypt(const char *inp, char *out, size_t len, # 1958# const AES_KEY *key1, const AES_KEY *key2, # 1959# [const] unsigned char iv[16]); # 1960# If $key2 is NULL, then a "tweak chaining" mode is engaged, in which # 1961# input tweak value is assumed to be encrypted already, and last tweak # 1962# value, one suitable for consecutive call on same chunk of data, is # 1963# written back to original buffer. In addition, in "tweak chaining" # 1964# mode only complete input blocks are processed. # 1965 1966my ($inp,$out,$len,$key1,$key2,$ivp,$rounds,$idx) = map("r$_",(3..10)); 1967my ($rndkey0,$rndkey1,$inout) = map("v$_",(0..2)); 1968my ($output,$inptail,$inpperm,$leperm,$keyperm) = map("v$_",(3..7)); 1969my ($tweak,$seven,$eighty7,$tmp,$tweak1) = map("v$_",(8..12)); 1970my $taillen = $key2; 1971 1972 ($inp,$idx) = ($idx,$inp); # reassign 1973 1974$code.=<<___; 1975.globl .${prefix}_xts_encrypt 1976 mr $inp,r3 # reassign 1977 li r3,-1 1978 ${UCMP}i $len,16 1979 bltlr- 1980 1981 lis r0,0xfff0 1982 mfspr r12,256 # save vrsave 1983 li r11,0 1984 mtspr 256,r0 1985 1986 vspltisb $seven,0x07 # 0x070707..07 1987 le?lvsl $leperm,r11,r11 1988 le?vspltisb $tmp,0x0f 1989 le?vxor $leperm,$leperm,$seven 1990 1991 li $idx,15 1992 lvx $tweak,0,$ivp # load [unaligned] iv 1993 lvsl $inpperm,0,$ivp 1994 lvx $inptail,$idx,$ivp 1995 le?vxor $inpperm,$inpperm,$tmp 1996 vperm $tweak,$tweak,$inptail,$inpperm 1997 1998 neg r11,$inp 1999 lvsr $inpperm,0,r11 # prepare for unaligned load 2000 lvx $inout,0,$inp 2001 addi $inp,$inp,15 # 15 is not typo 2002 le?vxor $inpperm,$inpperm,$tmp 2003 2004 ${UCMP}i $key2,0 # key2==NULL? 2005 beq Lxts_enc_no_key2 2006 2007 ?lvsl $keyperm,0,$key2 # prepare for unaligned key 2008 lwz $rounds,240($key2) 2009 srwi $rounds,$rounds,1 2010 subi $rounds,$rounds,1 2011 li $idx,16 2012 2013 lvx $rndkey0,0,$key2 2014 lvx $rndkey1,$idx,$key2 2015 addi $idx,$idx,16 2016 ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm 2017 vxor $tweak,$tweak,$rndkey0 2018 lvx $rndkey0,$idx,$key2 2019 addi $idx,$idx,16 2020 mtctr $rounds 2021 2022Ltweak_xts_enc: 2023 ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm 2024 vcipher $tweak,$tweak,$rndkey1 2025 lvx $rndkey1,$idx,$key2 2026 addi $idx,$idx,16 2027 ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm 2028 vcipher $tweak,$tweak,$rndkey0 2029 lvx $rndkey0,$idx,$key2 2030 addi $idx,$idx,16 2031 bdnz Ltweak_xts_enc 2032 2033 ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm 2034 vcipher $tweak,$tweak,$rndkey1 2035 lvx $rndkey1,$idx,$key2 2036 ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm 2037 vcipherlast $tweak,$tweak,$rndkey0 2038 2039 li $ivp,0 # don't chain the tweak 2040 b Lxts_enc 2041 2042Lxts_enc_no_key2: 2043 li $idx,-16 2044 and $len,$len,$idx # in "tweak chaining" 2045 # mode only complete 2046 # blocks are processed 2047Lxts_enc: 2048 lvx $inptail,0,$inp 2049 addi $inp,$inp,16 2050 2051 ?lvsl $keyperm,0,$key1 # prepare for unaligned key 2052 lwz $rounds,240($key1) 2053 srwi $rounds,$rounds,1 2054 subi $rounds,$rounds,1 2055 li $idx,16 2056 2057 vslb $eighty7,$seven,$seven # 0x808080..80 2058 vor $eighty7,$eighty7,$seven # 0x878787..87 2059 vspltisb $tmp,1 # 0x010101..01 2060 vsldoi $eighty7,$eighty7,$tmp,15 # 0x870101..01 2061 2062 ${UCMP}i $len,96 2063 bge _aesp8_xts_encrypt6x 2064 2065 andi. $taillen,$len,15 2066 subic r0,$len,32 2067 subi $taillen,$taillen,16 2068 subfe r0,r0,r0 2069 and r0,r0,$taillen 2070 add $inp,$inp,r0 2071 2072 lvx $rndkey0,0,$key1 2073 lvx $rndkey1,$idx,$key1 2074 addi $idx,$idx,16 2075 vperm $inout,$inout,$inptail,$inpperm 2076 ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm 2077 vxor $inout,$inout,$tweak 2078 vxor $inout,$inout,$rndkey0 2079 lvx $rndkey0,$idx,$key1 2080 addi $idx,$idx,16 2081 mtctr $rounds 2082 b Loop_xts_enc 2083 2084.align 5 2085Loop_xts_enc: 2086 ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm 2087 vcipher $inout,$inout,$rndkey1 2088 lvx $rndkey1,$idx,$key1 2089 addi $idx,$idx,16 2090 ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm 2091 vcipher $inout,$inout,$rndkey0 2092 lvx $rndkey0,$idx,$key1 2093 addi $idx,$idx,16 2094 bdnz Loop_xts_enc 2095 2096 ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm 2097 vcipher $inout,$inout,$rndkey1 2098 lvx $rndkey1,$idx,$key1 2099 li $idx,16 2100 ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm 2101 vxor $rndkey0,$rndkey0,$tweak 2102 vcipherlast $output,$inout,$rndkey0 2103 2104 le?vperm $tmp,$output,$output,$leperm 2105 be?nop 2106 le?stvx_u $tmp,0,$out 2107 be?stvx_u $output,0,$out 2108 addi $out,$out,16 2109 2110 subic. $len,$len,16 2111 beq Lxts_enc_done 2112 2113 vmr $inout,$inptail 2114 lvx $inptail,0,$inp 2115 addi $inp,$inp,16 2116 lvx $rndkey0,0,$key1 2117 lvx $rndkey1,$idx,$key1 2118 addi $idx,$idx,16 2119 2120 subic r0,$len,32 2121 subfe r0,r0,r0 2122 and r0,r0,$taillen 2123 add $inp,$inp,r0 2124 2125 vsrab $tmp,$tweak,$seven # next tweak value 2126 vaddubm $tweak,$tweak,$tweak 2127 vsldoi $tmp,$tmp,$tmp,15 2128 vand $tmp,$tmp,$eighty7 2129 vxor $tweak,$tweak,$tmp 2130 2131 vperm $inout,$inout,$inptail,$inpperm 2132 ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm 2133 vxor $inout,$inout,$tweak 2134 vxor $output,$output,$rndkey0 # just in case $len<16 2135 vxor $inout,$inout,$rndkey0 2136 lvx $rndkey0,$idx,$key1 2137 addi $idx,$idx,16 2138 2139 mtctr $rounds 2140 ${UCMP}i $len,16 2141 bge Loop_xts_enc 2142 2143 vxor $output,$output,$tweak 2144 lvsr $inpperm,0,$len # $inpperm is no longer needed 2145 vxor $inptail,$inptail,$inptail # $inptail is no longer needed 2146 vspltisb $tmp,-1 2147 vperm $inptail,$inptail,$tmp,$inpperm 2148 vsel $inout,$inout,$output,$inptail 2149 2150 subi r11,$out,17 2151 subi $out,$out,16 2152 mtctr $len 2153 li $len,16 2154Loop_xts_enc_steal: 2155 lbzu r0,1(r11) 2156 stb r0,16(r11) 2157 bdnz Loop_xts_enc_steal 2158 2159 mtctr $rounds 2160 b Loop_xts_enc # one more time... 2161 2162Lxts_enc_done: 2163 ${UCMP}i $ivp,0 2164 beq Lxts_enc_ret 2165 2166 vsrab $tmp,$tweak,$seven # next tweak value 2167 vaddubm $tweak,$tweak,$tweak 2168 vsldoi $tmp,$tmp,$tmp,15 2169 vand $tmp,$tmp,$eighty7 2170 vxor $tweak,$tweak,$tmp 2171 2172 le?vperm $tweak,$tweak,$tweak,$leperm 2173 stvx_u $tweak,0,$ivp 2174 2175Lxts_enc_ret: 2176 mtspr 256,r12 # restore vrsave 2177 li r3,0 2178 blr 2179 .long 0 2180 .byte 0,12,0x04,0,0x80,6,6,0 2181 .long 0 2182.size .${prefix}_xts_encrypt,.-.${prefix}_xts_encrypt 2183 2184.globl .${prefix}_xts_decrypt 2185 mr $inp,r3 # reassign 2186 li r3,-1 2187 ${UCMP}i $len,16 2188 bltlr- 2189 2190 lis r0,0xfff8 2191 mfspr r12,256 # save vrsave 2192 li r11,0 2193 mtspr 256,r0 2194 2195 andi. r0,$len,15 2196 neg r0,r0 2197 andi. r0,r0,16 2198 sub $len,$len,r0 2199 2200 vspltisb $seven,0x07 # 0x070707..07 2201 le?lvsl $leperm,r11,r11 2202 le?vspltisb $tmp,0x0f 2203 le?vxor $leperm,$leperm,$seven 2204 2205 li $idx,15 2206 lvx $tweak,0,$ivp # load [unaligned] iv 2207 lvsl $inpperm,0,$ivp 2208 lvx $inptail,$idx,$ivp 2209 le?vxor $inpperm,$inpperm,$tmp 2210 vperm $tweak,$tweak,$inptail,$inpperm 2211 2212 neg r11,$inp 2213 lvsr $inpperm,0,r11 # prepare for unaligned load 2214 lvx $inout,0,$inp 2215 addi $inp,$inp,15 # 15 is not typo 2216 le?vxor $inpperm,$inpperm,$tmp 2217 2218 ${UCMP}i $key2,0 # key2==NULL? 2219 beq Lxts_dec_no_key2 2220 2221 ?lvsl $keyperm,0,$key2 # prepare for unaligned key 2222 lwz $rounds,240($key2) 2223 srwi $rounds,$rounds,1 2224 subi $rounds,$rounds,1 2225 li $idx,16 2226 2227 lvx $rndkey0,0,$key2 2228 lvx $rndkey1,$idx,$key2 2229 addi $idx,$idx,16 2230 ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm 2231 vxor $tweak,$tweak,$rndkey0 2232 lvx $rndkey0,$idx,$key2 2233 addi $idx,$idx,16 2234 mtctr $rounds 2235 2236Ltweak_xts_dec: 2237 ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm 2238 vcipher $tweak,$tweak,$rndkey1 2239 lvx $rndkey1,$idx,$key2 2240 addi $idx,$idx,16 2241 ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm 2242 vcipher $tweak,$tweak,$rndkey0 2243 lvx $rndkey0,$idx,$key2 2244 addi $idx,$idx,16 2245 bdnz Ltweak_xts_dec 2246 2247 ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm 2248 vcipher $tweak,$tweak,$rndkey1 2249 lvx $rndkey1,$idx,$key2 2250 ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm 2251 vcipherlast $tweak,$tweak,$rndkey0 2252 2253 li $ivp,0 # don't chain the tweak 2254 b Lxts_dec 2255 2256Lxts_dec_no_key2: 2257 neg $idx,$len 2258 andi. $idx,$idx,15 2259 add $len,$len,$idx # in "tweak chaining" 2260 # mode only complete 2261 # blocks are processed 2262Lxts_dec: 2263 lvx $inptail,0,$inp 2264 addi $inp,$inp,16 2265 2266 ?lvsl $keyperm,0,$key1 # prepare for unaligned key 2267 lwz $rounds,240($key1) 2268 srwi $rounds,$rounds,1 2269 subi $rounds,$rounds,1 2270 li $idx,16 2271 2272 vslb $eighty7,$seven,$seven # 0x808080..80 2273 vor $eighty7,$eighty7,$seven # 0x878787..87 2274 vspltisb $tmp,1 # 0x010101..01 2275 vsldoi $eighty7,$eighty7,$tmp,15 # 0x870101..01 2276 2277 ${UCMP}i $len,96 2278 bge _aesp8_xts_decrypt6x 2279 2280 lvx $rndkey0,0,$key1 2281 lvx $rndkey1,$idx,$key1 2282 addi $idx,$idx,16 2283 vperm $inout,$inout,$inptail,$inpperm 2284 ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm 2285 vxor $inout,$inout,$tweak 2286 vxor $inout,$inout,$rndkey0 2287 lvx $rndkey0,$idx,$key1 2288 addi $idx,$idx,16 2289 mtctr $rounds 2290 2291 ${UCMP}i $len,16 2292 blt Ltail_xts_dec 2293 be?b Loop_xts_dec 2294 2295.align 5 2296Loop_xts_dec: 2297 ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm 2298 vncipher $inout,$inout,$rndkey1 2299 lvx $rndkey1,$idx,$key1 2300 addi $idx,$idx,16 2301 ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm 2302 vncipher $inout,$inout,$rndkey0 2303 lvx $rndkey0,$idx,$key1 2304 addi $idx,$idx,16 2305 bdnz Loop_xts_dec 2306 2307 ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm 2308 vncipher $inout,$inout,$rndkey1 2309 lvx $rndkey1,$idx,$key1 2310 li $idx,16 2311 ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm 2312 vxor $rndkey0,$rndkey0,$tweak 2313 vncipherlast $output,$inout,$rndkey0 2314 2315 le?vperm $tmp,$output,$output,$leperm 2316 be?nop 2317 le?stvx_u $tmp,0,$out 2318 be?stvx_u $output,0,$out 2319 addi $out,$out,16 2320 2321 subic. $len,$len,16 2322 beq Lxts_dec_done 2323 2324 vmr $inout,$inptail 2325 lvx $inptail,0,$inp 2326 addi $inp,$inp,16 2327 lvx $rndkey0,0,$key1 2328 lvx $rndkey1,$idx,$key1 2329 addi $idx,$idx,16 2330 2331 vsrab $tmp,$tweak,$seven # next tweak value 2332 vaddubm $tweak,$tweak,$tweak 2333 vsldoi $tmp,$tmp,$tmp,15 2334 vand $tmp,$tmp,$eighty7 2335 vxor $tweak,$tweak,$tmp 2336 2337 vperm $inout,$inout,$inptail,$inpperm 2338 ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm 2339 vxor $inout,$inout,$tweak 2340 vxor $inout,$inout,$rndkey0 2341 lvx $rndkey0,$idx,$key1 2342 addi $idx,$idx,16 2343 2344 mtctr $rounds 2345 ${UCMP}i $len,16 2346 bge Loop_xts_dec 2347 2348Ltail_xts_dec: 2349 vsrab $tmp,$tweak,$seven # next tweak value 2350 vaddubm $tweak1,$tweak,$tweak 2351 vsldoi $tmp,$tmp,$tmp,15 2352 vand $tmp,$tmp,$eighty7 2353 vxor $tweak1,$tweak1,$tmp 2354 2355 subi $inp,$inp,16 2356 add $inp,$inp,$len 2357 2358 vxor $inout,$inout,$tweak # :-( 2359 vxor $inout,$inout,$tweak1 # :-) 2360 2361Loop_xts_dec_short: 2362 ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm 2363 vncipher $inout,$inout,$rndkey1 2364 lvx $rndkey1,$idx,$key1 2365 addi $idx,$idx,16 2366 ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm 2367 vncipher $inout,$inout,$rndkey0 2368 lvx $rndkey0,$idx,$key1 2369 addi $idx,$idx,16 2370 bdnz Loop_xts_dec_short 2371 2372 ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm 2373 vncipher $inout,$inout,$rndkey1 2374 lvx $rndkey1,$idx,$key1 2375 li $idx,16 2376 ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm 2377 vxor $rndkey0,$rndkey0,$tweak1 2378 vncipherlast $output,$inout,$rndkey0 2379 2380 le?vperm $tmp,$output,$output,$leperm 2381 be?nop 2382 le?stvx_u $tmp,0,$out 2383 be?stvx_u $output,0,$out 2384 2385 vmr $inout,$inptail 2386 lvx $inptail,0,$inp 2387 #addi $inp,$inp,16 2388 lvx $rndkey0,0,$key1 2389 lvx $rndkey1,$idx,$key1 2390 addi $idx,$idx,16 2391 vperm $inout,$inout,$inptail,$inpperm 2392 ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm 2393 2394 lvsr $inpperm,0,$len # $inpperm is no longer needed 2395 vxor $inptail,$inptail,$inptail # $inptail is no longer needed 2396 vspltisb $tmp,-1 2397 vperm $inptail,$inptail,$tmp,$inpperm 2398 vsel $inout,$inout,$output,$inptail 2399 2400 vxor $rndkey0,$rndkey0,$tweak 2401 vxor $inout,$inout,$rndkey0 2402 lvx $rndkey0,$idx,$key1 2403 addi $idx,$idx,16 2404 2405 subi r11,$out,1 2406 mtctr $len 2407 li $len,16 2408Loop_xts_dec_steal: 2409 lbzu r0,1(r11) 2410 stb r0,16(r11) 2411 bdnz Loop_xts_dec_steal 2412 2413 mtctr $rounds 2414 b Loop_xts_dec # one more time... 2415 2416Lxts_dec_done: 2417 ${UCMP}i $ivp,0 2418 beq Lxts_dec_ret 2419 2420 vsrab $tmp,$tweak,$seven # next tweak value 2421 vaddubm $tweak,$tweak,$tweak 2422 vsldoi $tmp,$tmp,$tmp,15 2423 vand $tmp,$tmp,$eighty7 2424 vxor $tweak,$tweak,$tmp 2425 2426 le?vperm $tweak,$tweak,$tweak,$leperm 2427 stvx_u $tweak,0,$ivp 2428 2429Lxts_dec_ret: 2430 mtspr 256,r12 # restore vrsave 2431 li r3,0 2432 blr 2433 .long 0 2434 .byte 0,12,0x04,0,0x80,6,6,0 2435 .long 0 2436.size .${prefix}_xts_decrypt,.-.${prefix}_xts_decrypt 2437___ 2438######################################################################### 2439{{ # Optimized XTS procedures # 2440my $key_=$key2; 2441my ($x00,$x10,$x20,$x30,$x40,$x50,$x60,$x70)=map("r$_",(0,3,26..31)); 2442 $x00=0 if ($flavour =~ /osx/); 2443my ($in0, $in1, $in2, $in3, $in4, $in5 )=map("v$_",(0..5)); 2444my ($out0, $out1, $out2, $out3, $out4, $out5)=map("v$_",(7,12..16)); 2445my ($twk0, $twk1, $twk2, $twk3, $twk4, $twk5)=map("v$_",(17..22)); 2446my $rndkey0="v23"; # v24-v25 rotating buffer for first found keys 2447 # v26-v31 last 6 round keys 2448my ($keyperm)=($out0); # aliases with "caller", redundant assignment 2449my $taillen=$x70; 2450 2451$code.=<<___; 2452.align 5 2453_aesp8_xts_encrypt6x: 2454 $STU $sp,-`($FRAME+21*16+6*$SIZE_T)`($sp) 2455 mflr r11 2456 li r7,`$FRAME+8*16+15` 2457 li r3,`$FRAME+8*16+31` 2458 $PUSH r11,`$FRAME+21*16+6*$SIZE_T+$LRSAVE`($sp) 2459 stvx v20,r7,$sp # ABI says so 2460 addi r7,r7,32 2461 stvx v21,r3,$sp 2462 addi r3,r3,32 2463 stvx v22,r7,$sp 2464 addi r7,r7,32 2465 stvx v23,r3,$sp 2466 addi r3,r3,32 2467 stvx v24,r7,$sp 2468 addi r7,r7,32 2469 stvx v25,r3,$sp 2470 addi r3,r3,32 2471 stvx v26,r7,$sp 2472 addi r7,r7,32 2473 stvx v27,r3,$sp 2474 addi r3,r3,32 2475 stvx v28,r7,$sp 2476 addi r7,r7,32 2477 stvx v29,r3,$sp 2478 addi r3,r3,32 2479 stvx v30,r7,$sp 2480 stvx v31,r3,$sp 2481 li r0,-1 2482 stw $vrsave,`$FRAME+21*16-4`($sp) # save vrsave 2483 li $x10,0x10 2484 $PUSH r26,`$FRAME+21*16+0*$SIZE_T`($sp) 2485 li $x20,0x20 2486 $PUSH r27,`$FRAME+21*16+1*$SIZE_T`($sp) 2487 li $x30,0x30 2488 $PUSH r28,`$FRAME+21*16+2*$SIZE_T`($sp) 2489 li $x40,0x40 2490 $PUSH r29,`$FRAME+21*16+3*$SIZE_T`($sp) 2491 li $x50,0x50 2492 $PUSH r30,`$FRAME+21*16+4*$SIZE_T`($sp) 2493 li $x60,0x60 2494 $PUSH r31,`$FRAME+21*16+5*$SIZE_T`($sp) 2495 li $x70,0x70 2496 mtspr 256,r0 2497 2498 subi $rounds,$rounds,3 # -4 in total 2499 2500 lvx $rndkey0,$x00,$key1 # load key schedule 2501 lvx v30,$x10,$key1 2502 addi $key1,$key1,0x20 2503 lvx v31,$x00,$key1 2504 ?vperm $rndkey0,$rndkey0,v30,$keyperm 2505 addi $key_,$sp,$FRAME+15 2506 mtctr $rounds 2507 2508Load_xts_enc_key: 2509 ?vperm v24,v30,v31,$keyperm 2510 lvx v30,$x10,$key1 2511 addi $key1,$key1,0x20 2512 stvx v24,$x00,$key_ # off-load round[1] 2513 ?vperm v25,v31,v30,$keyperm 2514 lvx v31,$x00,$key1 2515 stvx v25,$x10,$key_ # off-load round[2] 2516 addi $key_,$key_,0x20 2517 bdnz Load_xts_enc_key 2518 2519 lvx v26,$x10,$key1 2520 ?vperm v24,v30,v31,$keyperm 2521 lvx v27,$x20,$key1 2522 stvx v24,$x00,$key_ # off-load round[3] 2523 ?vperm v25,v31,v26,$keyperm 2524 lvx v28,$x30,$key1 2525 stvx v25,$x10,$key_ # off-load round[4] 2526 addi $key_,$sp,$FRAME+15 # rewind $key_ 2527 ?vperm v26,v26,v27,$keyperm 2528 lvx v29,$x40,$key1 2529 ?vperm v27,v27,v28,$keyperm 2530 lvx v30,$x50,$key1 2531 ?vperm v28,v28,v29,$keyperm 2532 lvx v31,$x60,$key1 2533 ?vperm v29,v29,v30,$keyperm 2534 lvx $twk5,$x70,$key1 # borrow $twk5 2535 ?vperm v30,v30,v31,$keyperm 2536 lvx v24,$x00,$key_ # pre-load round[1] 2537 ?vperm v31,v31,$twk5,$keyperm 2538 lvx v25,$x10,$key_ # pre-load round[2] 2539 2540 vperm $in0,$inout,$inptail,$inpperm 2541 subi $inp,$inp,31 # undo "caller" 2542 vxor $twk0,$tweak,$rndkey0 2543 vsrab $tmp,$tweak,$seven # next tweak value 2544 vaddubm $tweak,$tweak,$tweak 2545 vsldoi $tmp,$tmp,$tmp,15 2546 vand $tmp,$tmp,$eighty7 2547 vxor $out0,$in0,$twk0 2548 vxor $tweak,$tweak,$tmp 2549 2550 lvx_u $in1,$x10,$inp 2551 vxor $twk1,$tweak,$rndkey0 2552 vsrab $tmp,$tweak,$seven # next tweak value 2553 vaddubm $tweak,$tweak,$tweak 2554 vsldoi $tmp,$tmp,$tmp,15 2555 le?vperm $in1,$in1,$in1,$leperm 2556 vand $tmp,$tmp,$eighty7 2557 vxor $out1,$in1,$twk1 2558 vxor $tweak,$tweak,$tmp 2559 2560 lvx_u $in2,$x20,$inp 2561 andi. $taillen,$len,15 2562 vxor $twk2,$tweak,$rndkey0 2563 vsrab $tmp,$tweak,$seven # next tweak value 2564 vaddubm $tweak,$tweak,$tweak 2565 vsldoi $tmp,$tmp,$tmp,15 2566 le?vperm $in2,$in2,$in2,$leperm 2567 vand $tmp,$tmp,$eighty7 2568 vxor $out2,$in2,$twk2 2569 vxor $tweak,$tweak,$tmp 2570 2571 lvx_u $in3,$x30,$inp 2572 sub $len,$len,$taillen 2573 vxor $twk3,$tweak,$rndkey0 2574 vsrab $tmp,$tweak,$seven # next tweak value 2575 vaddubm $tweak,$tweak,$tweak 2576 vsldoi $tmp,$tmp,$tmp,15 2577 le?vperm $in3,$in3,$in3,$leperm 2578 vand $tmp,$tmp,$eighty7 2579 vxor $out3,$in3,$twk3 2580 vxor $tweak,$tweak,$tmp 2581 2582 lvx_u $in4,$x40,$inp 2583 subi $len,$len,0x60 2584 vxor $twk4,$tweak,$rndkey0 2585 vsrab $tmp,$tweak,$seven # next tweak value 2586 vaddubm $tweak,$tweak,$tweak 2587 vsldoi $tmp,$tmp,$tmp,15 2588 le?vperm $in4,$in4,$in4,$leperm 2589 vand $tmp,$tmp,$eighty7 2590 vxor $out4,$in4,$twk4 2591 vxor $tweak,$tweak,$tmp 2592 2593 lvx_u $in5,$x50,$inp 2594 addi $inp,$inp,0x60 2595 vxor $twk5,$tweak,$rndkey0 2596 vsrab $tmp,$tweak,$seven # next tweak value 2597 vaddubm $tweak,$tweak,$tweak 2598 vsldoi $tmp,$tmp,$tmp,15 2599 le?vperm $in5,$in5,$in5,$leperm 2600 vand $tmp,$tmp,$eighty7 2601 vxor $out5,$in5,$twk5 2602 vxor $tweak,$tweak,$tmp 2603 2604 vxor v31,v31,$rndkey0 2605 mtctr $rounds 2606 b Loop_xts_enc6x 2607 2608.align 5 2609Loop_xts_enc6x: 2610 vcipher $out0,$out0,v24 2611 vcipher $out1,$out1,v24 2612 vcipher $out2,$out2,v24 2613 vcipher $out3,$out3,v24 2614 vcipher $out4,$out4,v24 2615 vcipher $out5,$out5,v24 2616 lvx v24,$x20,$key_ # round[3] 2617 addi $key_,$key_,0x20 2618 2619 vcipher $out0,$out0,v25 2620 vcipher $out1,$out1,v25 2621 vcipher $out2,$out2,v25 2622 vcipher $out3,$out3,v25 2623 vcipher $out4,$out4,v25 2624 vcipher $out5,$out5,v25 2625 lvx v25,$x10,$key_ # round[4] 2626 bdnz Loop_xts_enc6x 2627 2628 subic $len,$len,96 # $len-=96 2629 vxor $in0,$twk0,v31 # xor with last round key 2630 vcipher $out0,$out0,v24 2631 vcipher $out1,$out1,v24 2632 vsrab $tmp,$tweak,$seven # next tweak value 2633 vxor $twk0,$tweak,$rndkey0 2634 vaddubm $tweak,$tweak,$tweak 2635 vcipher $out2,$out2,v24 2636 vcipher $out3,$out3,v24 2637 vsldoi $tmp,$tmp,$tmp,15 2638 vcipher $out4,$out4,v24 2639 vcipher $out5,$out5,v24 2640 2641 subfe. r0,r0,r0 # borrow?-1:0 2642 vand $tmp,$tmp,$eighty7 2643 vcipher $out0,$out0,v25 2644 vcipher $out1,$out1,v25 2645 vxor $tweak,$tweak,$tmp 2646 vcipher $out2,$out2,v25 2647 vcipher $out3,$out3,v25 2648 vxor $in1,$twk1,v31 2649 vsrab $tmp,$tweak,$seven # next tweak value 2650 vxor $twk1,$tweak,$rndkey0 2651 vcipher $out4,$out4,v25 2652 vcipher $out5,$out5,v25 2653 2654 and r0,r0,$len 2655 vaddubm $tweak,$tweak,$tweak 2656 vsldoi $tmp,$tmp,$tmp,15 2657 vcipher $out0,$out0,v26 2658 vcipher $out1,$out1,v26 2659 vand $tmp,$tmp,$eighty7 2660 vcipher $out2,$out2,v26 2661 vcipher $out3,$out3,v26 2662 vxor $tweak,$tweak,$tmp 2663 vcipher $out4,$out4,v26 2664 vcipher $out5,$out5,v26 2665 2666 add $inp,$inp,r0 # $inp is adjusted in such 2667 # way that at exit from the 2668 # loop inX-in5 are loaded 2669 # with last "words" 2670 vxor $in2,$twk2,v31 2671 vsrab $tmp,$tweak,$seven # next tweak value 2672 vxor $twk2,$tweak,$rndkey0 2673 vaddubm $tweak,$tweak,$tweak 2674 vcipher $out0,$out0,v27 2675 vcipher $out1,$out1,v27 2676 vsldoi $tmp,$tmp,$tmp,15 2677 vcipher $out2,$out2,v27 2678 vcipher $out3,$out3,v27 2679 vand $tmp,$tmp,$eighty7 2680 vcipher $out4,$out4,v27 2681 vcipher $out5,$out5,v27 2682 2683 addi $key_,$sp,$FRAME+15 # rewind $key_ 2684 vxor $tweak,$tweak,$tmp 2685 vcipher $out0,$out0,v28 2686 vcipher $out1,$out1,v28 2687 vxor $in3,$twk3,v31 2688 vsrab $tmp,$tweak,$seven # next tweak value 2689 vxor $twk3,$tweak,$rndkey0 2690 vcipher $out2,$out2,v28 2691 vcipher $out3,$out3,v28 2692 vaddubm $tweak,$tweak,$tweak 2693 vsldoi $tmp,$tmp,$tmp,15 2694 vcipher $out4,$out4,v28 2695 vcipher $out5,$out5,v28 2696 lvx v24,$x00,$key_ # re-pre-load round[1] 2697 vand $tmp,$tmp,$eighty7 2698 2699 vcipher $out0,$out0,v29 2700 vcipher $out1,$out1,v29 2701 vxor $tweak,$tweak,$tmp 2702 vcipher $out2,$out2,v29 2703 vcipher $out3,$out3,v29 2704 vxor $in4,$twk4,v31 2705 vsrab $tmp,$tweak,$seven # next tweak value 2706 vxor $twk4,$tweak,$rndkey0 2707 vcipher $out4,$out4,v29 2708 vcipher $out5,$out5,v29 2709 lvx v25,$x10,$key_ # re-pre-load round[2] 2710 vaddubm $tweak,$tweak,$tweak 2711 vsldoi $tmp,$tmp,$tmp,15 2712 2713 vcipher $out0,$out0,v30 2714 vcipher $out1,$out1,v30 2715 vand $tmp,$tmp,$eighty7 2716 vcipher $out2,$out2,v30 2717 vcipher $out3,$out3,v30 2718 vxor $tweak,$tweak,$tmp 2719 vcipher $out4,$out4,v30 2720 vcipher $out5,$out5,v30 2721 vxor $in5,$twk5,v31 2722 vsrab $tmp,$tweak,$seven # next tweak value 2723 vxor $twk5,$tweak,$rndkey0 2724 2725 vcipherlast $out0,$out0,$in0 2726 lvx_u $in0,$x00,$inp # load next input block 2727 vaddubm $tweak,$tweak,$tweak 2728 vsldoi $tmp,$tmp,$tmp,15 2729 vcipherlast $out1,$out1,$in1 2730 lvx_u $in1,$x10,$inp 2731 vcipherlast $out2,$out2,$in2 2732 le?vperm $in0,$in0,$in0,$leperm 2733 lvx_u $in2,$x20,$inp 2734 vand $tmp,$tmp,$eighty7 2735 vcipherlast $out3,$out3,$in3 2736 le?vperm $in1,$in1,$in1,$leperm 2737 lvx_u $in3,$x30,$inp 2738 vcipherlast $out4,$out4,$in4 2739 le?vperm $in2,$in2,$in2,$leperm 2740 lvx_u $in4,$x40,$inp 2741 vxor $tweak,$tweak,$tmp 2742 vcipherlast $tmp,$out5,$in5 # last block might be needed 2743 # in stealing mode 2744 le?vperm $in3,$in3,$in3,$leperm 2745 lvx_u $in5,$x50,$inp 2746 addi $inp,$inp,0x60 2747 le?vperm $in4,$in4,$in4,$leperm 2748 le?vperm $in5,$in5,$in5,$leperm 2749 2750 le?vperm $out0,$out0,$out0,$leperm 2751 le?vperm $out1,$out1,$out1,$leperm 2752 stvx_u $out0,$x00,$out # store output 2753 vxor $out0,$in0,$twk0 2754 le?vperm $out2,$out2,$out2,$leperm 2755 stvx_u $out1,$x10,$out 2756 vxor $out1,$in1,$twk1 2757 le?vperm $out3,$out3,$out3,$leperm 2758 stvx_u $out2,$x20,$out 2759 vxor $out2,$in2,$twk2 2760 le?vperm $out4,$out4,$out4,$leperm 2761 stvx_u $out3,$x30,$out 2762 vxor $out3,$in3,$twk3 2763 le?vperm $out5,$tmp,$tmp,$leperm 2764 stvx_u $out4,$x40,$out 2765 vxor $out4,$in4,$twk4 2766 le?stvx_u $out5,$x50,$out 2767 be?stvx_u $tmp, $x50,$out 2768 vxor $out5,$in5,$twk5 2769 addi $out,$out,0x60 2770 2771 mtctr $rounds 2772 beq Loop_xts_enc6x # did $len-=96 borrow? 2773 2774 addic. $len,$len,0x60 2775 beq Lxts_enc6x_zero 2776 cmpwi $len,0x20 2777 blt Lxts_enc6x_one 2778 nop 2779 beq Lxts_enc6x_two 2780 cmpwi $len,0x40 2781 blt Lxts_enc6x_three 2782 nop 2783 beq Lxts_enc6x_four 2784 2785Lxts_enc6x_five: 2786 vxor $out0,$in1,$twk0 2787 vxor $out1,$in2,$twk1 2788 vxor $out2,$in3,$twk2 2789 vxor $out3,$in4,$twk3 2790 vxor $out4,$in5,$twk4 2791 2792 bl _aesp8_xts_enc5x 2793 2794 le?vperm $out0,$out0,$out0,$leperm 2795 vmr $twk0,$twk5 # unused tweak 2796 le?vperm $out1,$out1,$out1,$leperm 2797 stvx_u $out0,$x00,$out # store output 2798 le?vperm $out2,$out2,$out2,$leperm 2799 stvx_u $out1,$x10,$out 2800 le?vperm $out3,$out3,$out3,$leperm 2801 stvx_u $out2,$x20,$out 2802 vxor $tmp,$out4,$twk5 # last block prep for stealing 2803 le?vperm $out4,$out4,$out4,$leperm 2804 stvx_u $out3,$x30,$out 2805 stvx_u $out4,$x40,$out 2806 addi $out,$out,0x50 2807 bne Lxts_enc6x_steal 2808 b Lxts_enc6x_done 2809 2810.align 4 2811Lxts_enc6x_four: 2812 vxor $out0,$in2,$twk0 2813 vxor $out1,$in3,$twk1 2814 vxor $out2,$in4,$twk2 2815 vxor $out3,$in5,$twk3 2816 vxor $out4,$out4,$out4 2817 2818 bl _aesp8_xts_enc5x 2819 2820 le?vperm $out0,$out0,$out0,$leperm 2821 vmr $twk0,$twk4 # unused tweak 2822 le?vperm $out1,$out1,$out1,$leperm 2823 stvx_u $out0,$x00,$out # store output 2824 le?vperm $out2,$out2,$out2,$leperm 2825 stvx_u $out1,$x10,$out 2826 vxor $tmp,$out3,$twk4 # last block prep for stealing 2827 le?vperm $out3,$out3,$out3,$leperm 2828 stvx_u $out2,$x20,$out 2829 stvx_u $out3,$x30,$out 2830 addi $out,$out,0x40 2831 bne Lxts_enc6x_steal 2832 b Lxts_enc6x_done 2833 2834.align 4 2835Lxts_enc6x_three: 2836 vxor $out0,$in3,$twk0 2837 vxor $out1,$in4,$twk1 2838 vxor $out2,$in5,$twk2 2839 vxor $out3,$out3,$out3 2840 vxor $out4,$out4,$out4 2841 2842 bl _aesp8_xts_enc5x 2843 2844 le?vperm $out0,$out0,$out0,$leperm 2845 vmr $twk0,$twk3 # unused tweak 2846 le?vperm $out1,$out1,$out1,$leperm 2847 stvx_u $out0,$x00,$out # store output 2848 vxor $tmp,$out2,$twk3 # last block prep for stealing 2849 le?vperm $out2,$out2,$out2,$leperm 2850 stvx_u $out1,$x10,$out 2851 stvx_u $out2,$x20,$out 2852 addi $out,$out,0x30 2853 bne Lxts_enc6x_steal 2854 b Lxts_enc6x_done 2855 2856.align 4 2857Lxts_enc6x_two: 2858 vxor $out0,$in4,$twk0 2859 vxor $out1,$in5,$twk1 2860 vxor $out2,$out2,$out2 2861 vxor $out3,$out3,$out3 2862 vxor $out4,$out4,$out4 2863 2864 bl _aesp8_xts_enc5x 2865 2866 le?vperm $out0,$out0,$out0,$leperm 2867 vmr $twk0,$twk2 # unused tweak 2868 vxor $tmp,$out1,$twk2 # last block prep for stealing 2869 le?vperm $out1,$out1,$out1,$leperm 2870 stvx_u $out0,$x00,$out # store output 2871 stvx_u $out1,$x10,$out 2872 addi $out,$out,0x20 2873 bne Lxts_enc6x_steal 2874 b Lxts_enc6x_done 2875 2876.align 4 2877Lxts_enc6x_one: 2878 vxor $out0,$in5,$twk0 2879 nop 2880Loop_xts_enc1x: 2881 vcipher $out0,$out0,v24 2882 lvx v24,$x20,$key_ # round[3] 2883 addi $key_,$key_,0x20 2884 2885 vcipher $out0,$out0,v25 2886 lvx v25,$x10,$key_ # round[4] 2887 bdnz Loop_xts_enc1x 2888 2889 add $inp,$inp,$taillen 2890 cmpwi $taillen,0 2891 vcipher $out0,$out0,v24 2892 2893 subi $inp,$inp,16 2894 vcipher $out0,$out0,v25 2895 2896 lvsr $inpperm,0,$taillen 2897 vcipher $out0,$out0,v26 2898 2899 lvx_u $in0,0,$inp 2900 vcipher $out0,$out0,v27 2901 2902 addi $key_,$sp,$FRAME+15 # rewind $key_ 2903 vcipher $out0,$out0,v28 2904 lvx v24,$x00,$key_ # re-pre-load round[1] 2905 2906 vcipher $out0,$out0,v29 2907 lvx v25,$x10,$key_ # re-pre-load round[2] 2908 vxor $twk0,$twk0,v31 2909 2910 le?vperm $in0,$in0,$in0,$leperm 2911 vcipher $out0,$out0,v30 2912 2913 vperm $in0,$in0,$in0,$inpperm 2914 vcipherlast $out0,$out0,$twk0 2915 2916 vmr $twk0,$twk1 # unused tweak 2917 vxor $tmp,$out0,$twk1 # last block prep for stealing 2918 le?vperm $out0,$out0,$out0,$leperm 2919 stvx_u $out0,$x00,$out # store output 2920 addi $out,$out,0x10 2921 bne Lxts_enc6x_steal 2922 b Lxts_enc6x_done 2923 2924.align 4 2925Lxts_enc6x_zero: 2926 cmpwi $taillen,0 2927 beq Lxts_enc6x_done 2928 2929 add $inp,$inp,$taillen 2930 subi $inp,$inp,16 2931 lvx_u $in0,0,$inp 2932 lvsr $inpperm,0,$taillen # $in5 is no more 2933 le?vperm $in0,$in0,$in0,$leperm 2934 vperm $in0,$in0,$in0,$inpperm 2935 vxor $tmp,$tmp,$twk0 2936Lxts_enc6x_steal: 2937 vxor $in0,$in0,$twk0 2938 vxor $out0,$out0,$out0 2939 vspltisb $out1,-1 2940 vperm $out0,$out0,$out1,$inpperm 2941 vsel $out0,$in0,$tmp,$out0 # $tmp is last block, remember? 2942 2943 subi r30,$out,17 2944 subi $out,$out,16 2945 mtctr $taillen 2946Loop_xts_enc6x_steal: 2947 lbzu r0,1(r30) 2948 stb r0,16(r30) 2949 bdnz Loop_xts_enc6x_steal 2950 2951 li $taillen,0 2952 mtctr $rounds 2953 b Loop_xts_enc1x # one more time... 2954 2955.align 4 2956Lxts_enc6x_done: 2957 ${UCMP}i $ivp,0 2958 beq Lxts_enc6x_ret 2959 2960 vxor $tweak,$twk0,$rndkey0 2961 le?vperm $tweak,$tweak,$tweak,$leperm 2962 stvx_u $tweak,0,$ivp 2963 2964Lxts_enc6x_ret: 2965 mtlr r11 2966 li r10,`$FRAME+15` 2967 li r11,`$FRAME+31` 2968 stvx $seven,r10,$sp # wipe copies of round keys 2969 addi r10,r10,32 2970 stvx $seven,r11,$sp 2971 addi r11,r11,32 2972 stvx $seven,r10,$sp 2973 addi r10,r10,32 2974 stvx $seven,r11,$sp 2975 addi r11,r11,32 2976 stvx $seven,r10,$sp 2977 addi r10,r10,32 2978 stvx $seven,r11,$sp 2979 addi r11,r11,32 2980 stvx $seven,r10,$sp 2981 addi r10,r10,32 2982 stvx $seven,r11,$sp 2983 addi r11,r11,32 2984 2985 mtspr 256,$vrsave 2986 lvx v20,r10,$sp # ABI says so 2987 addi r10,r10,32 2988 lvx v21,r11,$sp 2989 addi r11,r11,32 2990 lvx v22,r10,$sp 2991 addi r10,r10,32 2992 lvx v23,r11,$sp 2993 addi r11,r11,32 2994 lvx v24,r10,$sp 2995 addi r10,r10,32 2996 lvx v25,r11,$sp 2997 addi r11,r11,32 2998 lvx v26,r10,$sp 2999 addi r10,r10,32 3000 lvx v27,r11,$sp 3001 addi r11,r11,32 3002 lvx v28,r10,$sp 3003 addi r10,r10,32 3004 lvx v29,r11,$sp 3005 addi r11,r11,32 3006 lvx v30,r10,$sp 3007 lvx v31,r11,$sp 3008 $POP r26,`$FRAME+21*16+0*$SIZE_T`($sp) 3009 $POP r27,`$FRAME+21*16+1*$SIZE_T`($sp) 3010 $POP r28,`$FRAME+21*16+2*$SIZE_T`($sp) 3011 $POP r29,`$FRAME+21*16+3*$SIZE_T`($sp) 3012 $POP r30,`$FRAME+21*16+4*$SIZE_T`($sp) 3013 $POP r31,`$FRAME+21*16+5*$SIZE_T`($sp) 3014 addi $sp,$sp,`$FRAME+21*16+6*$SIZE_T` 3015 blr 3016 .long 0 3017 .byte 0,12,0x04,1,0x80,6,6,0 3018 .long 0 3019 3020.align 5 3021_aesp8_xts_enc5x: 3022 vcipher $out0,$out0,v24 3023 vcipher $out1,$out1,v24 3024 vcipher $out2,$out2,v24 3025 vcipher $out3,$out3,v24 3026 vcipher $out4,$out4,v24 3027 lvx v24,$x20,$key_ # round[3] 3028 addi $key_,$key_,0x20 3029 3030 vcipher $out0,$out0,v25 3031 vcipher $out1,$out1,v25 3032 vcipher $out2,$out2,v25 3033 vcipher $out3,$out3,v25 3034 vcipher $out4,$out4,v25 3035 lvx v25,$x10,$key_ # round[4] 3036 bdnz _aesp8_xts_enc5x 3037 3038 add $inp,$inp,$taillen 3039 cmpwi $taillen,0 3040 vcipher $out0,$out0,v24 3041 vcipher $out1,$out1,v24 3042 vcipher $out2,$out2,v24 3043 vcipher $out3,$out3,v24 3044 vcipher $out4,$out4,v24 3045 3046 subi $inp,$inp,16 3047 vcipher $out0,$out0,v25 3048 vcipher $out1,$out1,v25 3049 vcipher $out2,$out2,v25 3050 vcipher $out3,$out3,v25 3051 vcipher $out4,$out4,v25 3052 vxor $twk0,$twk0,v31 3053 3054 vcipher $out0,$out0,v26 3055 lvsr $inpperm,r0,$taillen # $in5 is no more 3056 vcipher $out1,$out1,v26 3057 vcipher $out2,$out2,v26 3058 vcipher $out3,$out3,v26 3059 vcipher $out4,$out4,v26 3060 vxor $in1,$twk1,v31 3061 3062 vcipher $out0,$out0,v27 3063 lvx_u $in0,0,$inp 3064 vcipher $out1,$out1,v27 3065 vcipher $out2,$out2,v27 3066 vcipher $out3,$out3,v27 3067 vcipher $out4,$out4,v27 3068 vxor $in2,$twk2,v31 3069 3070 addi $key_,$sp,$FRAME+15 # rewind $key_ 3071 vcipher $out0,$out0,v28 3072 vcipher $out1,$out1,v28 3073 vcipher $out2,$out2,v28 3074 vcipher $out3,$out3,v28 3075 vcipher $out4,$out4,v28 3076 lvx v24,$x00,$key_ # re-pre-load round[1] 3077 vxor $in3,$twk3,v31 3078 3079 vcipher $out0,$out0,v29 3080 le?vperm $in0,$in0,$in0,$leperm 3081 vcipher $out1,$out1,v29 3082 vcipher $out2,$out2,v29 3083 vcipher $out3,$out3,v29 3084 vcipher $out4,$out4,v29 3085 lvx v25,$x10,$key_ # re-pre-load round[2] 3086 vxor $in4,$twk4,v31 3087 3088 vcipher $out0,$out0,v30 3089 vperm $in0,$in0,$in0,$inpperm 3090 vcipher $out1,$out1,v30 3091 vcipher $out2,$out2,v30 3092 vcipher $out3,$out3,v30 3093 vcipher $out4,$out4,v30 3094 3095 vcipherlast $out0,$out0,$twk0 3096 vcipherlast $out1,$out1,$in1 3097 vcipherlast $out2,$out2,$in2 3098 vcipherlast $out3,$out3,$in3 3099 vcipherlast $out4,$out4,$in4 3100 blr 3101 .long 0 3102 .byte 0,12,0x14,0,0,0,0,0 3103 3104.align 5 3105_aesp8_xts_decrypt6x: 3106 $STU $sp,-`($FRAME+21*16+6*$SIZE_T)`($sp) 3107 mflr r11 3108 li r7,`$FRAME+8*16+15` 3109 li r3,`$FRAME+8*16+31` 3110 $PUSH r11,`$FRAME+21*16+6*$SIZE_T+$LRSAVE`($sp) 3111 stvx v20,r7,$sp # ABI says so 3112 addi r7,r7,32 3113 stvx v21,r3,$sp 3114 addi r3,r3,32 3115 stvx v22,r7,$sp 3116 addi r7,r7,32 3117 stvx v23,r3,$sp 3118 addi r3,r3,32 3119 stvx v24,r7,$sp 3120 addi r7,r7,32 3121 stvx v25,r3,$sp 3122 addi r3,r3,32 3123 stvx v26,r7,$sp 3124 addi r7,r7,32 3125 stvx v27,r3,$sp 3126 addi r3,r3,32 3127 stvx v28,r7,$sp 3128 addi r7,r7,32 3129 stvx v29,r3,$sp 3130 addi r3,r3,32 3131 stvx v30,r7,$sp 3132 stvx v31,r3,$sp 3133 li r0,-1 3134 stw $vrsave,`$FRAME+21*16-4`($sp) # save vrsave 3135 li $x10,0x10 3136 $PUSH r26,`$FRAME+21*16+0*$SIZE_T`($sp) 3137 li $x20,0x20 3138 $PUSH r27,`$FRAME+21*16+1*$SIZE_T`($sp) 3139 li $x30,0x30 3140 $PUSH r28,`$FRAME+21*16+2*$SIZE_T`($sp) 3141 li $x40,0x40 3142 $PUSH r29,`$FRAME+21*16+3*$SIZE_T`($sp) 3143 li $x50,0x50 3144 $PUSH r30,`$FRAME+21*16+4*$SIZE_T`($sp) 3145 li $x60,0x60 3146 $PUSH r31,`$FRAME+21*16+5*$SIZE_T`($sp) 3147 li $x70,0x70 3148 mtspr 256,r0 3149 3150 subi $rounds,$rounds,3 # -4 in total 3151 3152 lvx $rndkey0,$x00,$key1 # load key schedule 3153 lvx v30,$x10,$key1 3154 addi $key1,$key1,0x20 3155 lvx v31,$x00,$key1 3156 ?vperm $rndkey0,$rndkey0,v30,$keyperm 3157 addi $key_,$sp,$FRAME+15 3158 mtctr $rounds 3159 3160Load_xts_dec_key: 3161 ?vperm v24,v30,v31,$keyperm 3162 lvx v30,$x10,$key1 3163 addi $key1,$key1,0x20 3164 stvx v24,$x00,$key_ # off-load round[1] 3165 ?vperm v25,v31,v30,$keyperm 3166 lvx v31,$x00,$key1 3167 stvx v25,$x10,$key_ # off-load round[2] 3168 addi $key_,$key_,0x20 3169 bdnz Load_xts_dec_key 3170 3171 lvx v26,$x10,$key1 3172 ?vperm v24,v30,v31,$keyperm 3173 lvx v27,$x20,$key1 3174 stvx v24,$x00,$key_ # off-load round[3] 3175 ?vperm v25,v31,v26,$keyperm 3176 lvx v28,$x30,$key1 3177 stvx v25,$x10,$key_ # off-load round[4] 3178 addi $key_,$sp,$FRAME+15 # rewind $key_ 3179 ?vperm v26,v26,v27,$keyperm 3180 lvx v29,$x40,$key1 3181 ?vperm v27,v27,v28,$keyperm 3182 lvx v30,$x50,$key1 3183 ?vperm v28,v28,v29,$keyperm 3184 lvx v31,$x60,$key1 3185 ?vperm v29,v29,v30,$keyperm 3186 lvx $twk5,$x70,$key1 # borrow $twk5 3187 ?vperm v30,v30,v31,$keyperm 3188 lvx v24,$x00,$key_ # pre-load round[1] 3189 ?vperm v31,v31,$twk5,$keyperm 3190 lvx v25,$x10,$key_ # pre-load round[2] 3191 3192 vperm $in0,$inout,$inptail,$inpperm 3193 subi $inp,$inp,31 # undo "caller" 3194 vxor $twk0,$tweak,$rndkey0 3195 vsrab $tmp,$tweak,$seven # next tweak value 3196 vaddubm $tweak,$tweak,$tweak 3197 vsldoi $tmp,$tmp,$tmp,15 3198 vand $tmp,$tmp,$eighty7 3199 vxor $out0,$in0,$twk0 3200 vxor $tweak,$tweak,$tmp 3201 3202 lvx_u $in1,$x10,$inp 3203 vxor $twk1,$tweak,$rndkey0 3204 vsrab $tmp,$tweak,$seven # next tweak value 3205 vaddubm $tweak,$tweak,$tweak 3206 vsldoi $tmp,$tmp,$tmp,15 3207 le?vperm $in1,$in1,$in1,$leperm 3208 vand $tmp,$tmp,$eighty7 3209 vxor $out1,$in1,$twk1 3210 vxor $tweak,$tweak,$tmp 3211 3212 lvx_u $in2,$x20,$inp 3213 andi. $taillen,$len,15 3214 vxor $twk2,$tweak,$rndkey0 3215 vsrab $tmp,$tweak,$seven # next tweak value 3216 vaddubm $tweak,$tweak,$tweak 3217 vsldoi $tmp,$tmp,$tmp,15 3218 le?vperm $in2,$in2,$in2,$leperm 3219 vand $tmp,$tmp,$eighty7 3220 vxor $out2,$in2,$twk2 3221 vxor $tweak,$tweak,$tmp 3222 3223 lvx_u $in3,$x30,$inp 3224 sub $len,$len,$taillen 3225 vxor $twk3,$tweak,$rndkey0 3226 vsrab $tmp,$tweak,$seven # next tweak value 3227 vaddubm $tweak,$tweak,$tweak 3228 vsldoi $tmp,$tmp,$tmp,15 3229 le?vperm $in3,$in3,$in3,$leperm 3230 vand $tmp,$tmp,$eighty7 3231 vxor $out3,$in3,$twk3 3232 vxor $tweak,$tweak,$tmp 3233 3234 lvx_u $in4,$x40,$inp 3235 subi $len,$len,0x60 3236 vxor $twk4,$tweak,$rndkey0 3237 vsrab $tmp,$tweak,$seven # next tweak value 3238 vaddubm $tweak,$tweak,$tweak 3239 vsldoi $tmp,$tmp,$tmp,15 3240 le?vperm $in4,$in4,$in4,$leperm 3241 vand $tmp,$tmp,$eighty7 3242 vxor $out4,$in4,$twk4 3243 vxor $tweak,$tweak,$tmp 3244 3245 lvx_u $in5,$x50,$inp 3246 addi $inp,$inp,0x60 3247 vxor $twk5,$tweak,$rndkey0 3248 vsrab $tmp,$tweak,$seven # next tweak value 3249 vaddubm $tweak,$tweak,$tweak 3250 vsldoi $tmp,$tmp,$tmp,15 3251 le?vperm $in5,$in5,$in5,$leperm 3252 vand $tmp,$tmp,$eighty7 3253 vxor $out5,$in5,$twk5 3254 vxor $tweak,$tweak,$tmp 3255 3256 vxor v31,v31,$rndkey0 3257 mtctr $rounds 3258 b Loop_xts_dec6x 3259 3260.align 5 3261Loop_xts_dec6x: 3262 vncipher $out0,$out0,v24 3263 vncipher $out1,$out1,v24 3264 vncipher $out2,$out2,v24 3265 vncipher $out3,$out3,v24 3266 vncipher $out4,$out4,v24 3267 vncipher $out5,$out5,v24 3268 lvx v24,$x20,$key_ # round[3] 3269 addi $key_,$key_,0x20 3270 3271 vncipher $out0,$out0,v25 3272 vncipher $out1,$out1,v25 3273 vncipher $out2,$out2,v25 3274 vncipher $out3,$out3,v25 3275 vncipher $out4,$out4,v25 3276 vncipher $out5,$out5,v25 3277 lvx v25,$x10,$key_ # round[4] 3278 bdnz Loop_xts_dec6x 3279 3280 subic $len,$len,96 # $len-=96 3281 vxor $in0,$twk0,v31 # xor with last round key 3282 vncipher $out0,$out0,v24 3283 vncipher $out1,$out1,v24 3284 vsrab $tmp,$tweak,$seven # next tweak value 3285 vxor $twk0,$tweak,$rndkey0 3286 vaddubm $tweak,$tweak,$tweak 3287 vncipher $out2,$out2,v24 3288 vncipher $out3,$out3,v24 3289 vsldoi $tmp,$tmp,$tmp,15 3290 vncipher $out4,$out4,v24 3291 vncipher $out5,$out5,v24 3292 3293 subfe. r0,r0,r0 # borrow?-1:0 3294 vand $tmp,$tmp,$eighty7 3295 vncipher $out0,$out0,v25 3296 vncipher $out1,$out1,v25 3297 vxor $tweak,$tweak,$tmp 3298 vncipher $out2,$out2,v25 3299 vncipher $out3,$out3,v25 3300 vxor $in1,$twk1,v31 3301 vsrab $tmp,$tweak,$seven # next tweak value 3302 vxor $twk1,$tweak,$rndkey0 3303 vncipher $out4,$out4,v25 3304 vncipher $out5,$out5,v25 3305 3306 and r0,r0,$len 3307 vaddubm $tweak,$tweak,$tweak 3308 vsldoi $tmp,$tmp,$tmp,15 3309 vncipher $out0,$out0,v26 3310 vncipher $out1,$out1,v26 3311 vand $tmp,$tmp,$eighty7 3312 vncipher $out2,$out2,v26 3313 vncipher $out3,$out3,v26 3314 vxor $tweak,$tweak,$tmp 3315 vncipher $out4,$out4,v26 3316 vncipher $out5,$out5,v26 3317 3318 add $inp,$inp,r0 # $inp is adjusted in such 3319 # way that at exit from the 3320 # loop inX-in5 are loaded 3321 # with last "words" 3322 vxor $in2,$twk2,v31 3323 vsrab $tmp,$tweak,$seven # next tweak value 3324 vxor $twk2,$tweak,$rndkey0 3325 vaddubm $tweak,$tweak,$tweak 3326 vncipher $out0,$out0,v27 3327 vncipher $out1,$out1,v27 3328 vsldoi $tmp,$tmp,$tmp,15 3329 vncipher $out2,$out2,v27 3330 vncipher $out3,$out3,v27 3331 vand $tmp,$tmp,$eighty7 3332 vncipher $out4,$out4,v27 3333 vncipher $out5,$out5,v27 3334 3335 addi $key_,$sp,$FRAME+15 # rewind $key_ 3336 vxor $tweak,$tweak,$tmp 3337 vncipher $out0,$out0,v28 3338 vncipher $out1,$out1,v28 3339 vxor $in3,$twk3,v31 3340 vsrab $tmp,$tweak,$seven # next tweak value 3341 vxor $twk3,$tweak,$rndkey0 3342 vncipher $out2,$out2,v28 3343 vncipher $out3,$out3,v28 3344 vaddubm $tweak,$tweak,$tweak 3345 vsldoi $tmp,$tmp,$tmp,15 3346 vncipher $out4,$out4,v28 3347 vncipher $out5,$out5,v28 3348 lvx v24,$x00,$key_ # re-pre-load round[1] 3349 vand $tmp,$tmp,$eighty7 3350 3351 vncipher $out0,$out0,v29 3352 vncipher $out1,$out1,v29 3353 vxor $tweak,$tweak,$tmp 3354 vncipher $out2,$out2,v29 3355 vncipher $out3,$out3,v29 3356 vxor $in4,$twk4,v31 3357 vsrab $tmp,$tweak,$seven # next tweak value 3358 vxor $twk4,$tweak,$rndkey0 3359 vncipher $out4,$out4,v29 3360 vncipher $out5,$out5,v29 3361 lvx v25,$x10,$key_ # re-pre-load round[2] 3362 vaddubm $tweak,$tweak,$tweak 3363 vsldoi $tmp,$tmp,$tmp,15 3364 3365 vncipher $out0,$out0,v30 3366 vncipher $out1,$out1,v30 3367 vand $tmp,$tmp,$eighty7 3368 vncipher $out2,$out2,v30 3369 vncipher $out3,$out3,v30 3370 vxor $tweak,$tweak,$tmp 3371 vncipher $out4,$out4,v30 3372 vncipher $out5,$out5,v30 3373 vxor $in5,$twk5,v31 3374 vsrab $tmp,$tweak,$seven # next tweak value 3375 vxor $twk5,$tweak,$rndkey0 3376 3377 vncipherlast $out0,$out0,$in0 3378 lvx_u $in0,$x00,$inp # load next input block 3379 vaddubm $tweak,$tweak,$tweak 3380 vsldoi $tmp,$tmp,$tmp,15 3381 vncipherlast $out1,$out1,$in1 3382 lvx_u $in1,$x10,$inp 3383 vncipherlast $out2,$out2,$in2 3384 le?vperm $in0,$in0,$in0,$leperm 3385 lvx_u $in2,$x20,$inp 3386 vand $tmp,$tmp,$eighty7 3387 vncipherlast $out3,$out3,$in3 3388 le?vperm $in1,$in1,$in1,$leperm 3389 lvx_u $in3,$x30,$inp 3390 vncipherlast $out4,$out4,$in4 3391 le?vperm $in2,$in2,$in2,$leperm 3392 lvx_u $in4,$x40,$inp 3393 vxor $tweak,$tweak,$tmp 3394 vncipherlast $out5,$out5,$in5 3395 le?vperm $in3,$in3,$in3,$leperm 3396 lvx_u $in5,$x50,$inp 3397 addi $inp,$inp,0x60 3398 le?vperm $in4,$in4,$in4,$leperm 3399 le?vperm $in5,$in5,$in5,$leperm 3400 3401 le?vperm $out0,$out0,$out0,$leperm 3402 le?vperm $out1,$out1,$out1,$leperm 3403 stvx_u $out0,$x00,$out # store output 3404 vxor $out0,$in0,$twk0 3405 le?vperm $out2,$out2,$out2,$leperm 3406 stvx_u $out1,$x10,$out 3407 vxor $out1,$in1,$twk1 3408 le?vperm $out3,$out3,$out3,$leperm 3409 stvx_u $out2,$x20,$out 3410 vxor $out2,$in2,$twk2 3411 le?vperm $out4,$out4,$out4,$leperm 3412 stvx_u $out3,$x30,$out 3413 vxor $out3,$in3,$twk3 3414 le?vperm $out5,$out5,$out5,$leperm 3415 stvx_u $out4,$x40,$out 3416 vxor $out4,$in4,$twk4 3417 stvx_u $out5,$x50,$out 3418 vxor $out5,$in5,$twk5 3419 addi $out,$out,0x60 3420 3421 mtctr $rounds 3422 beq Loop_xts_dec6x # did $len-=96 borrow? 3423 3424 addic. $len,$len,0x60 3425 beq Lxts_dec6x_zero 3426 cmpwi $len,0x20 3427 blt Lxts_dec6x_one 3428 nop 3429 beq Lxts_dec6x_two 3430 cmpwi $len,0x40 3431 blt Lxts_dec6x_three 3432 nop 3433 beq Lxts_dec6x_four 3434 3435Lxts_dec6x_five: 3436 vxor $out0,$in1,$twk0 3437 vxor $out1,$in2,$twk1 3438 vxor $out2,$in3,$twk2 3439 vxor $out3,$in4,$twk3 3440 vxor $out4,$in5,$twk4 3441 3442 bl _aesp8_xts_dec5x 3443 3444 le?vperm $out0,$out0,$out0,$leperm 3445 vmr $twk0,$twk5 # unused tweak 3446 vxor $twk1,$tweak,$rndkey0 3447 le?vperm $out1,$out1,$out1,$leperm 3448 stvx_u $out0,$x00,$out # store output 3449 vxor $out0,$in0,$twk1 3450 le?vperm $out2,$out2,$out2,$leperm 3451 stvx_u $out1,$x10,$out 3452 le?vperm $out3,$out3,$out3,$leperm 3453 stvx_u $out2,$x20,$out 3454 le?vperm $out4,$out4,$out4,$leperm 3455 stvx_u $out3,$x30,$out 3456 stvx_u $out4,$x40,$out 3457 addi $out,$out,0x50 3458 bne Lxts_dec6x_steal 3459 b Lxts_dec6x_done 3460 3461.align 4 3462Lxts_dec6x_four: 3463 vxor $out0,$in2,$twk0 3464 vxor $out1,$in3,$twk1 3465 vxor $out2,$in4,$twk2 3466 vxor $out3,$in5,$twk3 3467 vxor $out4,$out4,$out4 3468 3469 bl _aesp8_xts_dec5x 3470 3471 le?vperm $out0,$out0,$out0,$leperm 3472 vmr $twk0,$twk4 # unused tweak 3473 vmr $twk1,$twk5 3474 le?vperm $out1,$out1,$out1,$leperm 3475 stvx_u $out0,$x00,$out # store output 3476 vxor $out0,$in0,$twk5 3477 le?vperm $out2,$out2,$out2,$leperm 3478 stvx_u $out1,$x10,$out 3479 le?vperm $out3,$out3,$out3,$leperm 3480 stvx_u $out2,$x20,$out 3481 stvx_u $out3,$x30,$out 3482 addi $out,$out,0x40 3483 bne Lxts_dec6x_steal 3484 b Lxts_dec6x_done 3485 3486.align 4 3487Lxts_dec6x_three: 3488 vxor $out0,$in3,$twk0 3489 vxor $out1,$in4,$twk1 3490 vxor $out2,$in5,$twk2 3491 vxor $out3,$out3,$out3 3492 vxor $out4,$out4,$out4 3493 3494 bl _aesp8_xts_dec5x 3495 3496 le?vperm $out0,$out0,$out0,$leperm 3497 vmr $twk0,$twk3 # unused tweak 3498 vmr $twk1,$twk4 3499 le?vperm $out1,$out1,$out1,$leperm 3500 stvx_u $out0,$x00,$out # store output 3501 vxor $out0,$in0,$twk4 3502 le?vperm $out2,$out2,$out2,$leperm 3503 stvx_u $out1,$x10,$out 3504 stvx_u $out2,$x20,$out 3505 addi $out,$out,0x30 3506 bne Lxts_dec6x_steal 3507 b Lxts_dec6x_done 3508 3509.align 4 3510Lxts_dec6x_two: 3511 vxor $out0,$in4,$twk0 3512 vxor $out1,$in5,$twk1 3513 vxor $out2,$out2,$out2 3514 vxor $out3,$out3,$out3 3515 vxor $out4,$out4,$out4 3516 3517 bl _aesp8_xts_dec5x 3518 3519 le?vperm $out0,$out0,$out0,$leperm 3520 vmr $twk0,$twk2 # unused tweak 3521 vmr $twk1,$twk3 3522 le?vperm $out1,$out1,$out1,$leperm 3523 stvx_u $out0,$x00,$out # store output 3524 vxor $out0,$in0,$twk3 3525 stvx_u $out1,$x10,$out 3526 addi $out,$out,0x20 3527 bne Lxts_dec6x_steal 3528 b Lxts_dec6x_done 3529 3530.align 4 3531Lxts_dec6x_one: 3532 vxor $out0,$in5,$twk0 3533 nop 3534Loop_xts_dec1x: 3535 vncipher $out0,$out0,v24 3536 lvx v24,$x20,$key_ # round[3] 3537 addi $key_,$key_,0x20 3538 3539 vncipher $out0,$out0,v25 3540 lvx v25,$x10,$key_ # round[4] 3541 bdnz Loop_xts_dec1x 3542 3543 subi r0,$taillen,1 3544 vncipher $out0,$out0,v24 3545 3546 andi. r0,r0,16 3547 cmpwi $taillen,0 3548 vncipher $out0,$out0,v25 3549 3550 sub $inp,$inp,r0 3551 vncipher $out0,$out0,v26 3552 3553 lvx_u $in0,0,$inp 3554 vncipher $out0,$out0,v27 3555 3556 addi $key_,$sp,$FRAME+15 # rewind $key_ 3557 vncipher $out0,$out0,v28 3558 lvx v24,$x00,$key_ # re-pre-load round[1] 3559 3560 vncipher $out0,$out0,v29 3561 lvx v25,$x10,$key_ # re-pre-load round[2] 3562 vxor $twk0,$twk0,v31 3563 3564 le?vperm $in0,$in0,$in0,$leperm 3565 vncipher $out0,$out0,v30 3566 3567 mtctr $rounds 3568 vncipherlast $out0,$out0,$twk0 3569 3570 vmr $twk0,$twk1 # unused tweak 3571 vmr $twk1,$twk2 3572 le?vperm $out0,$out0,$out0,$leperm 3573 stvx_u $out0,$x00,$out # store output 3574 addi $out,$out,0x10 3575 vxor $out0,$in0,$twk2 3576 bne Lxts_dec6x_steal 3577 b Lxts_dec6x_done 3578 3579.align 4 3580Lxts_dec6x_zero: 3581 cmpwi $taillen,0 3582 beq Lxts_dec6x_done 3583 3584 lvx_u $in0,0,$inp 3585 le?vperm $in0,$in0,$in0,$leperm 3586 vxor $out0,$in0,$twk1 3587Lxts_dec6x_steal: 3588 vncipher $out0,$out0,v24 3589 lvx v24,$x20,$key_ # round[3] 3590 addi $key_,$key_,0x20 3591 3592 vncipher $out0,$out0,v25 3593 lvx v25,$x10,$key_ # round[4] 3594 bdnz Lxts_dec6x_steal 3595 3596 add $inp,$inp,$taillen 3597 vncipher $out0,$out0,v24 3598 3599 cmpwi $taillen,0 3600 vncipher $out0,$out0,v25 3601 3602 lvx_u $in0,0,$inp 3603 vncipher $out0,$out0,v26 3604 3605 lvsr $inpperm,0,$taillen # $in5 is no more 3606 vncipher $out0,$out0,v27 3607 3608 addi $key_,$sp,$FRAME+15 # rewind $key_ 3609 vncipher $out0,$out0,v28 3610 lvx v24,$x00,$key_ # re-pre-load round[1] 3611 3612 vncipher $out0,$out0,v29 3613 lvx v25,$x10,$key_ # re-pre-load round[2] 3614 vxor $twk1,$twk1,v31 3615 3616 le?vperm $in0,$in0,$in0,$leperm 3617 vncipher $out0,$out0,v30 3618 3619 vperm $in0,$in0,$in0,$inpperm 3620 vncipherlast $tmp,$out0,$twk1 3621 3622 le?vperm $out0,$tmp,$tmp,$leperm 3623 le?stvx_u $out0,0,$out 3624 be?stvx_u $tmp,0,$out 3625 3626 vxor $out0,$out0,$out0 3627 vspltisb $out1,-1 3628 vperm $out0,$out0,$out1,$inpperm 3629 vsel $out0,$in0,$tmp,$out0 3630 vxor $out0,$out0,$twk0 3631 3632 subi r30,$out,1 3633 mtctr $taillen 3634Loop_xts_dec6x_steal: 3635 lbzu r0,1(r30) 3636 stb r0,16(r30) 3637 bdnz Loop_xts_dec6x_steal 3638 3639 li $taillen,0 3640 mtctr $rounds 3641 b Loop_xts_dec1x # one more time... 3642 3643.align 4 3644Lxts_dec6x_done: 3645 ${UCMP}i $ivp,0 3646 beq Lxts_dec6x_ret 3647 3648 vxor $tweak,$twk0,$rndkey0 3649 le?vperm $tweak,$tweak,$tweak,$leperm 3650 stvx_u $tweak,0,$ivp 3651 3652Lxts_dec6x_ret: 3653 mtlr r11 3654 li r10,`$FRAME+15` 3655 li r11,`$FRAME+31` 3656 stvx $seven,r10,$sp # wipe copies of round keys 3657 addi r10,r10,32 3658 stvx $seven,r11,$sp 3659 addi r11,r11,32 3660 stvx $seven,r10,$sp 3661 addi r10,r10,32 3662 stvx $seven,r11,$sp 3663 addi r11,r11,32 3664 stvx $seven,r10,$sp 3665 addi r10,r10,32 3666 stvx $seven,r11,$sp 3667 addi r11,r11,32 3668 stvx $seven,r10,$sp 3669 addi r10,r10,32 3670 stvx $seven,r11,$sp 3671 addi r11,r11,32 3672 3673 mtspr 256,$vrsave 3674 lvx v20,r10,$sp # ABI says so 3675 addi r10,r10,32 3676 lvx v21,r11,$sp 3677 addi r11,r11,32 3678 lvx v22,r10,$sp 3679 addi r10,r10,32 3680 lvx v23,r11,$sp 3681 addi r11,r11,32 3682 lvx v24,r10,$sp 3683 addi r10,r10,32 3684 lvx v25,r11,$sp 3685 addi r11,r11,32 3686 lvx v26,r10,$sp 3687 addi r10,r10,32 3688 lvx v27,r11,$sp 3689 addi r11,r11,32 3690 lvx v28,r10,$sp 3691 addi r10,r10,32 3692 lvx v29,r11,$sp 3693 addi r11,r11,32 3694 lvx v30,r10,$sp 3695 lvx v31,r11,$sp 3696 $POP r26,`$FRAME+21*16+0*$SIZE_T`($sp) 3697 $POP r27,`$FRAME+21*16+1*$SIZE_T`($sp) 3698 $POP r28,`$FRAME+21*16+2*$SIZE_T`($sp) 3699 $POP r29,`$FRAME+21*16+3*$SIZE_T`($sp) 3700 $POP r30,`$FRAME+21*16+4*$SIZE_T`($sp) 3701 $POP r31,`$FRAME+21*16+5*$SIZE_T`($sp) 3702 addi $sp,$sp,`$FRAME+21*16+6*$SIZE_T` 3703 blr 3704 .long 0 3705 .byte 0,12,0x04,1,0x80,6,6,0 3706 .long 0 3707 3708.align 5 3709_aesp8_xts_dec5x: 3710 vncipher $out0,$out0,v24 3711 vncipher $out1,$out1,v24 3712 vncipher $out2,$out2,v24 3713 vncipher $out3,$out3,v24 3714 vncipher $out4,$out4,v24 3715 lvx v24,$x20,$key_ # round[3] 3716 addi $key_,$key_,0x20 3717 3718 vncipher $out0,$out0,v25 3719 vncipher $out1,$out1,v25 3720 vncipher $out2,$out2,v25 3721 vncipher $out3,$out3,v25 3722 vncipher $out4,$out4,v25 3723 lvx v25,$x10,$key_ # round[4] 3724 bdnz _aesp8_xts_dec5x 3725 3726 subi r0,$taillen,1 3727 vncipher $out0,$out0,v24 3728 vncipher $out1,$out1,v24 3729 vncipher $out2,$out2,v24 3730 vncipher $out3,$out3,v24 3731 vncipher $out4,$out4,v24 3732 3733 andi. r0,r0,16 3734 cmpwi $taillen,0 3735 vncipher $out0,$out0,v25 3736 vncipher $out1,$out1,v25 3737 vncipher $out2,$out2,v25 3738 vncipher $out3,$out3,v25 3739 vncipher $out4,$out4,v25 3740 vxor $twk0,$twk0,v31 3741 3742 sub $inp,$inp,r0 3743 vncipher $out0,$out0,v26 3744 vncipher $out1,$out1,v26 3745 vncipher $out2,$out2,v26 3746 vncipher $out3,$out3,v26 3747 vncipher $out4,$out4,v26 3748 vxor $in1,$twk1,v31 3749 3750 vncipher $out0,$out0,v27 3751 lvx_u $in0,0,$inp 3752 vncipher $out1,$out1,v27 3753 vncipher $out2,$out2,v27 3754 vncipher $out3,$out3,v27 3755 vncipher $out4,$out4,v27 3756 vxor $in2,$twk2,v31 3757 3758 addi $key_,$sp,$FRAME+15 # rewind $key_ 3759 vncipher $out0,$out0,v28 3760 vncipher $out1,$out1,v28 3761 vncipher $out2,$out2,v28 3762 vncipher $out3,$out3,v28 3763 vncipher $out4,$out4,v28 3764 lvx v24,$x00,$key_ # re-pre-load round[1] 3765 vxor $in3,$twk3,v31 3766 3767 vncipher $out0,$out0,v29 3768 le?vperm $in0,$in0,$in0,$leperm 3769 vncipher $out1,$out1,v29 3770 vncipher $out2,$out2,v29 3771 vncipher $out3,$out3,v29 3772 vncipher $out4,$out4,v29 3773 lvx v25,$x10,$key_ # re-pre-load round[2] 3774 vxor $in4,$twk4,v31 3775 3776 vncipher $out0,$out0,v30 3777 vncipher $out1,$out1,v30 3778 vncipher $out2,$out2,v30 3779 vncipher $out3,$out3,v30 3780 vncipher $out4,$out4,v30 3781 3782 vncipherlast $out0,$out0,$twk0 3783 vncipherlast $out1,$out1,$in1 3784 vncipherlast $out2,$out2,$in2 3785 vncipherlast $out3,$out3,$in3 3786 vncipherlast $out4,$out4,$in4 3787 mtctr $rounds 3788 blr 3789 .long 0 3790 .byte 0,12,0x14,0,0,0,0,0 3791___ 3792}} }}} 3793 3794my $consts=1; 3795foreach(split("\n",$code)) { 3796 s/\`([^\`]*)\`/eval($1)/geo; 3797 3798 # constants table endian-specific conversion 3799 if ($consts && m/\.(long|byte)\s+(.+)\s+(\?[a-z]*)$/o) { 3800 my $conv=$3; 3801 my @bytes=(); 3802 3803 # convert to endian-agnostic format 3804 if ($1 eq "long") { 3805 foreach (split(/,\s*/,$2)) { 3806 my $l = /^0/?oct:int; 3807 push @bytes,($l>>24)&0xff,($l>>16)&0xff,($l>>8)&0xff,$l&0xff; 3808 } 3809 } else { 3810 @bytes = map(/^0/?oct:int,split(/,\s*/,$2)); 3811 } 3812 3813 # little-endian conversion 3814 if ($flavour =~ /le$/o) { 3815 SWITCH: for($conv) { 3816 /\?inv/ && do { @bytes=map($_^0xf,@bytes); last; }; 3817 /\?rev/ && do { @bytes=reverse(@bytes); last; }; 3818 } 3819 } 3820 3821 #emit 3822 print ".byte\t",join(',',map (sprintf("0x%02x",$_),@bytes)),"\n"; 3823 next; 3824 } 3825 $consts=0 if (m/Lconsts:/o); # end of table 3826 3827 # instructions prefixed with '?' are endian-specific and need 3828 # to be adjusted accordingly... 3829 if ($flavour =~ /le$/o) { # little-endian 3830 s/le\?//o or 3831 s/be\?/#be#/o or 3832 s/\?lvsr/lvsl/o or 3833 s/\?lvsl/lvsr/o or 3834 s/\?(vperm\s+v[0-9]+,\s*)(v[0-9]+,\s*)(v[0-9]+,\s*)(v[0-9]+)/$1$3$2$4/o or 3835 s/\?(vsldoi\s+v[0-9]+,\s*)(v[0-9]+,)\s*(v[0-9]+,\s*)([0-9]+)/$1$3$2 16-$4/o or 3836 s/\?(vspltw\s+v[0-9]+,\s*)(v[0-9]+,)\s*([0-9])/$1$2 3-$3/o; 3837 } else { # big-endian 3838 s/le\?/#le#/o or 3839 s/be\?//o or 3840 s/\?([a-z]+)/$1/o; 3841 } 3842 3843 print $_,"\n"; 3844} 3845 3846close STDOUT; 3847