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