in src/crypto/fipsmodule/aes/asm/vpaes-x86_64.pl [138:869]
sub \$1,%rax # nr--
pxor %xmm3, %xmm0 # 0 = 2A+3B+C+D
.Lenc_entry:
# top of round
movdqa %xmm9, %xmm1 # 1 : i
movdqa %xmm11, %xmm5 # 2 : a/k
pandn %xmm0, %xmm1 # 1 = i<<4
psrld \$4, %xmm1 # 1 = i
pand %xmm9, %xmm0 # 0 = k
pshufb %xmm0, %xmm5 # 2 = a/k
movdqa %xmm10, %xmm3 # 3 : 1/i
pxor %xmm1, %xmm0 # 0 = j
pshufb %xmm1, %xmm3 # 3 = 1/i
movdqa %xmm10, %xmm4 # 4 : 1/j
pxor %xmm5, %xmm3 # 3 = iak = 1/i + a/k
pshufb %xmm0, %xmm4 # 4 = 1/j
movdqa %xmm10, %xmm2 # 2 : 1/iak
pxor %xmm5, %xmm4 # 4 = jak = 1/j + a/k
pshufb %xmm3, %xmm2 # 2 = 1/iak
movdqa %xmm10, %xmm3 # 3 : 1/jak
pxor %xmm0, %xmm2 # 2 = io
pshufb %xmm4, %xmm3 # 3 = 1/jak
movdqu (%r9), %xmm5
pxor %xmm1, %xmm3 # 3 = jo
jnz .Lenc_loop
# middle of last round
movdqa -0x60(%r10), %xmm4 # 3 : sbou .Lk_sbo
movdqa -0x50(%r10), %xmm0 # 0 : sbot .Lk_sbo+16
pshufb %xmm2, %xmm4 # 4 = sbou
pxor %xmm5, %xmm4 # 4 = sb1u + k
pshufb %xmm3, %xmm0 # 0 = sb1t
movdqa 0x40(%r11,%r10), %xmm1 # .Lk_sr[]
pxor %xmm4, %xmm0 # 0 = A
pshufb %xmm1, %xmm0
ret
.cfi_endproc
.size _vpaes_encrypt_core,.-_vpaes_encrypt_core
##
## _aes_encrypt_core_2x
##
## AES-encrypt %xmm0 and %xmm6 in parallel.
##
## Inputs:
## %xmm0 and %xmm6 = input
## %xmm9 and %xmm10 as in _vpaes_preheat
## (%rdx) = scheduled keys
##
## Output in %xmm0 and %xmm6
## Clobbers %xmm1-%xmm5, %xmm7, %xmm8, %xmm11-%xmm13, %r9, %r10, %r11, %rax
## Preserves %xmm14 and %xmm15
##
## This function stitches two parallel instances of _vpaes_encrypt_core. x86_64
## provides 16 XMM registers. _vpaes_encrypt_core computes over six registers
## (%xmm0-%xmm5) and additionally uses seven registers with preloaded constants
## from _vpaes_preheat (%xmm9-%xmm15). This does not quite fit two instances,
## so we spill some of %xmm9 through %xmm15 back to memory. We keep %xmm9 and
## %xmm10 in registers as these values are used several times in a row. The
## remainder are read once per round and are spilled to memory. This leaves two
## registers preserved for the caller.
##
## Thus, of the two _vpaes_encrypt_core instances, the first uses (%xmm0-%xmm5)
## as before. The second uses %xmm6-%xmm8,%xmm11-%xmm13. (Add 6 to %xmm2 and
## below. Add 8 to %xmm3 and up.) Instructions in the second instance are
## indented by one space.
##
##
.type _vpaes_encrypt_core_2x,\@abi-omnipotent
.align 16
_vpaes_encrypt_core_2x:
.cfi_startproc
mov %rdx, %r9
mov \$16, %r11
mov 240(%rdx),%eax
movdqa %xmm9, %xmm1
movdqa %xmm9, %xmm7
movdqa .Lk_ipt(%rip), %xmm2 # iptlo
movdqa %xmm2, %xmm8
pandn %xmm0, %xmm1
pandn %xmm6, %xmm7
movdqu (%r9), %xmm5 # round0 key
# Also use %xmm5 in the second instance.
psrld \$4, %xmm1
psrld \$4, %xmm7
pand %xmm9, %xmm0
pand %xmm9, %xmm6
pshufb %xmm0, %xmm2
pshufb %xmm6, %xmm8
movdqa .Lk_ipt+16(%rip), %xmm0 # ipthi
movdqa %xmm0, %xmm6
pshufb %xmm1, %xmm0
pshufb %xmm7, %xmm6
pxor %xmm5, %xmm2
pxor %xmm5, %xmm8
add \$16, %r9
pxor %xmm2, %xmm0
pxor %xmm8, %xmm6
lea .Lk_mc_backward(%rip),%r10
jmp .Lenc2x_entry
.align 16
.Lenc2x_loop:
# middle of middle round
movdqa .Lk_sb1(%rip), %xmm4 # 4 : sb1u
movdqa .Lk_sb1+16(%rip),%xmm0 # 0 : sb1t
movdqa %xmm4, %xmm12
movdqa %xmm0, %xmm6
pshufb %xmm2, %xmm4 # 4 = sb1u
pshufb %xmm8, %xmm12
pshufb %xmm3, %xmm0 # 0 = sb1t
pshufb %xmm11, %xmm6
pxor %xmm5, %xmm4 # 4 = sb1u + k
pxor %xmm5, %xmm12
movdqa .Lk_sb2(%rip), %xmm5 # 4 : sb2u
movdqa %xmm5, %xmm13
pxor %xmm4, %xmm0 # 0 = A
pxor %xmm12, %xmm6
movdqa -0x40(%r11,%r10), %xmm1 # .Lk_mc_forward[]
# Also use %xmm1 in the second instance.
pshufb %xmm2, %xmm5 # 4 = sb2u
pshufb %xmm8, %xmm13
movdqa (%r11,%r10), %xmm4 # .Lk_mc_backward[]
# Also use %xmm4 in the second instance.
movdqa .Lk_sb2+16(%rip), %xmm2 # 2 : sb2t
movdqa %xmm2, %xmm8
pshufb %xmm3, %xmm2 # 2 = sb2t
pshufb %xmm11, %xmm8
movdqa %xmm0, %xmm3 # 3 = A
movdqa %xmm6, %xmm11
pxor %xmm5, %xmm2 # 2 = 2A
pxor %xmm13, %xmm8
pshufb %xmm1, %xmm0 # 0 = B
pshufb %xmm1, %xmm6
add \$16, %r9 # next key
pxor %xmm2, %xmm0 # 0 = 2A+B
pxor %xmm8, %xmm6
pshufb %xmm4, %xmm3 # 3 = D
pshufb %xmm4, %xmm11
add \$16, %r11 # next mc
pxor %xmm0, %xmm3 # 3 = 2A+B+D
pxor %xmm6, %xmm11
pshufb %xmm1, %xmm0 # 0 = 2B+C
pshufb %xmm1, %xmm6
and \$0x30, %r11 # ... mod 4
sub \$1,%rax # nr--
pxor %xmm3, %xmm0 # 0 = 2A+3B+C+D
pxor %xmm11, %xmm6
.Lenc2x_entry:
# top of round
movdqa %xmm9, %xmm1 # 1 : i
movdqa %xmm9, %xmm7
movdqa .Lk_inv+16(%rip), %xmm5 # 2 : a/k
movdqa %xmm5, %xmm13
pandn %xmm0, %xmm1 # 1 = i<<4
pandn %xmm6, %xmm7
psrld \$4, %xmm1 # 1 = i
psrld \$4, %xmm7
pand %xmm9, %xmm0 # 0 = k
pand %xmm9, %xmm6
pshufb %xmm0, %xmm5 # 2 = a/k
pshufb %xmm6, %xmm13
movdqa %xmm10, %xmm3 # 3 : 1/i
movdqa %xmm10, %xmm11
pxor %xmm1, %xmm0 # 0 = j
pxor %xmm7, %xmm6
pshufb %xmm1, %xmm3 # 3 = 1/i
pshufb %xmm7, %xmm11
movdqa %xmm10, %xmm4 # 4 : 1/j
movdqa %xmm10, %xmm12
pxor %xmm5, %xmm3 # 3 = iak = 1/i + a/k
pxor %xmm13, %xmm11
pshufb %xmm0, %xmm4 # 4 = 1/j
pshufb %xmm6, %xmm12
movdqa %xmm10, %xmm2 # 2 : 1/iak
movdqa %xmm10, %xmm8
pxor %xmm5, %xmm4 # 4 = jak = 1/j + a/k
pxor %xmm13, %xmm12
pshufb %xmm3, %xmm2 # 2 = 1/iak
pshufb %xmm11, %xmm8
movdqa %xmm10, %xmm3 # 3 : 1/jak
movdqa %xmm10, %xmm11
pxor %xmm0, %xmm2 # 2 = io
pxor %xmm6, %xmm8
pshufb %xmm4, %xmm3 # 3 = 1/jak
pshufb %xmm12, %xmm11
movdqu (%r9), %xmm5
# Also use %xmm5 in the second instance.
pxor %xmm1, %xmm3 # 3 = jo
pxor %xmm7, %xmm11
jnz .Lenc2x_loop
# middle of last round
movdqa -0x60(%r10), %xmm4 # 3 : sbou .Lk_sbo
movdqa -0x50(%r10), %xmm0 # 0 : sbot .Lk_sbo+16
movdqa %xmm4, %xmm12
movdqa %xmm0, %xmm6
pshufb %xmm2, %xmm4 # 4 = sbou
pshufb %xmm8, %xmm12
pxor %xmm5, %xmm4 # 4 = sb1u + k
pxor %xmm5, %xmm12
pshufb %xmm3, %xmm0 # 0 = sb1t
pshufb %xmm11, %xmm6
movdqa 0x40(%r11,%r10), %xmm1 # .Lk_sr[]
# Also use %xmm1 in the second instance.
pxor %xmm4, %xmm0 # 0 = A
pxor %xmm12, %xmm6
pshufb %xmm1, %xmm0
pshufb %xmm1, %xmm6
ret
.cfi_endproc
.size _vpaes_encrypt_core_2x,.-_vpaes_encrypt_core_2x
##
## Decryption core
##
## Same API as encryption core.
##
.type _vpaes_decrypt_core,\@abi-omnipotent
.align 16
_vpaes_decrypt_core:
.cfi_startproc
mov %rdx, %r9 # load key
mov 240(%rdx),%eax
movdqa %xmm9, %xmm1
movdqa .Lk_dipt(%rip), %xmm2 # iptlo
pandn %xmm0, %xmm1
mov %rax, %r11
psrld \$4, %xmm1
movdqu (%r9), %xmm5 # round0 key
shl \$4, %r11
pand %xmm9, %xmm0
pshufb %xmm0, %xmm2
movdqa .Lk_dipt+16(%rip), %xmm0 # ipthi
xor \$0x30, %r11
lea .Lk_dsbd(%rip),%r10
pshufb %xmm1, %xmm0
and \$0x30, %r11
pxor %xmm5, %xmm2
movdqa .Lk_mc_forward+48(%rip), %xmm5
pxor %xmm2, %xmm0
add \$16, %r9
add %r10, %r11
jmp .Ldec_entry
.align 16
.Ldec_loop:
##
## Inverse mix columns
##
movdqa -0x20(%r10),%xmm4 # 4 : sb9u
movdqa -0x10(%r10),%xmm1 # 0 : sb9t
pshufb %xmm2, %xmm4 # 4 = sb9u
pshufb %xmm3, %xmm1 # 0 = sb9t
pxor %xmm4, %xmm0
movdqa 0x00(%r10),%xmm4 # 4 : sbdu
pxor %xmm1, %xmm0 # 0 = ch
movdqa 0x10(%r10),%xmm1 # 0 : sbdt
pshufb %xmm2, %xmm4 # 4 = sbdu
pshufb %xmm5, %xmm0 # MC ch
pshufb %xmm3, %xmm1 # 0 = sbdt
pxor %xmm4, %xmm0 # 4 = ch
movdqa 0x20(%r10),%xmm4 # 4 : sbbu
pxor %xmm1, %xmm0 # 0 = ch
movdqa 0x30(%r10),%xmm1 # 0 : sbbt
pshufb %xmm2, %xmm4 # 4 = sbbu
pshufb %xmm5, %xmm0 # MC ch
pshufb %xmm3, %xmm1 # 0 = sbbt
pxor %xmm4, %xmm0 # 4 = ch
movdqa 0x40(%r10),%xmm4 # 4 : sbeu
pxor %xmm1, %xmm0 # 0 = ch
movdqa 0x50(%r10),%xmm1 # 0 : sbet
pshufb %xmm2, %xmm4 # 4 = sbeu
pshufb %xmm5, %xmm0 # MC ch
pshufb %xmm3, %xmm1 # 0 = sbet
pxor %xmm4, %xmm0 # 4 = ch
add \$16, %r9 # next round key
palignr \$12, %xmm5, %xmm5
pxor %xmm1, %xmm0 # 0 = ch
sub \$1,%rax # nr--
.Ldec_entry:
# top of round
movdqa %xmm9, %xmm1 # 1 : i
pandn %xmm0, %xmm1 # 1 = i<<4
movdqa %xmm11, %xmm2 # 2 : a/k
psrld \$4, %xmm1 # 1 = i
pand %xmm9, %xmm0 # 0 = k
pshufb %xmm0, %xmm2 # 2 = a/k
movdqa %xmm10, %xmm3 # 3 : 1/i
pxor %xmm1, %xmm0 # 0 = j
pshufb %xmm1, %xmm3 # 3 = 1/i
movdqa %xmm10, %xmm4 # 4 : 1/j
pxor %xmm2, %xmm3 # 3 = iak = 1/i + a/k
pshufb %xmm0, %xmm4 # 4 = 1/j
pxor %xmm2, %xmm4 # 4 = jak = 1/j + a/k
movdqa %xmm10, %xmm2 # 2 : 1/iak
pshufb %xmm3, %xmm2 # 2 = 1/iak
movdqa %xmm10, %xmm3 # 3 : 1/jak
pxor %xmm0, %xmm2 # 2 = io
pshufb %xmm4, %xmm3 # 3 = 1/jak
movdqu (%r9), %xmm0
pxor %xmm1, %xmm3 # 3 = jo
jnz .Ldec_loop
# middle of last round
movdqa 0x60(%r10), %xmm4 # 3 : sbou
pshufb %xmm2, %xmm4 # 4 = sbou
pxor %xmm0, %xmm4 # 4 = sb1u + k
movdqa 0x70(%r10), %xmm0 # 0 : sbot
movdqa -0x160(%r11), %xmm2 # .Lk_sr-.Lk_dsbd=-0x160
pshufb %xmm3, %xmm0 # 0 = sb1t
pxor %xmm4, %xmm0 # 0 = A
pshufb %xmm2, %xmm0
ret
.cfi_endproc
.size _vpaes_decrypt_core,.-_vpaes_decrypt_core
########################################################
## ##
## AES key schedule ##
## ##
########################################################
.type _vpaes_schedule_core,\@abi-omnipotent
.align 16
_vpaes_schedule_core:
.cfi_startproc
# rdi = key
# rsi = size in bits
# rdx = buffer
# rcx = direction. 0=encrypt, 1=decrypt
call _vpaes_preheat # load the tables
movdqa .Lk_rcon(%rip), %xmm8 # load rcon
movdqu (%rdi), %xmm0 # load key (unaligned)
# input transform
movdqa %xmm0, %xmm3
lea .Lk_ipt(%rip), %r11
call _vpaes_schedule_transform
movdqa %xmm0, %xmm7
lea .Lk_sr(%rip),%r10
test %rcx, %rcx
jnz .Lschedule_am_decrypting
# encrypting, output zeroth round key after transform
movdqu %xmm0, (%rdx)
jmp .Lschedule_go
.Lschedule_am_decrypting:
# decrypting, output zeroth round key after shiftrows
movdqa (%r8,%r10),%xmm1
pshufb %xmm1, %xmm3
movdqu %xmm3, (%rdx)
xor \$0x30, %r8
.Lschedule_go:
cmp \$192, %esi
ja .Lschedule_256
je .Lschedule_192
# 128: fall though
##
## .schedule_128
##
## 128-bit specific part of key schedule.
##
## This schedule is really simple, because all its parts
## are accomplished by the subroutines.
##
.Lschedule_128:
mov \$10, %esi
.Loop_schedule_128:
call _vpaes_schedule_round
dec %rsi
jz .Lschedule_mangle_last
call _vpaes_schedule_mangle # write output
jmp .Loop_schedule_128
##
## .aes_schedule_192
##
## 192-bit specific part of key schedule.
##
## The main body of this schedule is the same as the 128-bit
## schedule, but with more smearing. The long, high side is
## stored in %xmm7 as before, and the short, low side is in
## the high bits of %xmm6.
##
## This schedule is somewhat nastier, however, because each
## round produces 192 bits of key material, or 1.5 round keys.
## Therefore, on each cycle we do 2 rounds and produce 3 round
## keys.
##
.align 16
.Lschedule_192:
movdqu 8(%rdi),%xmm0 # load key part 2 (very unaligned)
call _vpaes_schedule_transform # input transform
movdqa %xmm0, %xmm6 # save short part
pxor %xmm4, %xmm4 # clear 4
movhlps %xmm4, %xmm6 # clobber low side with zeros
mov \$4, %esi
.Loop_schedule_192:
call _vpaes_schedule_round
palignr \$8,%xmm6,%xmm0
call _vpaes_schedule_mangle # save key n
call _vpaes_schedule_192_smear
call _vpaes_schedule_mangle # save key n+1
call _vpaes_schedule_round
dec %rsi
jz .Lschedule_mangle_last
call _vpaes_schedule_mangle # save key n+2
call _vpaes_schedule_192_smear
jmp .Loop_schedule_192
##
## .aes_schedule_256
##
## 256-bit specific part of key schedule.
##
## The structure here is very similar to the 128-bit
## schedule, but with an additional "low side" in
## %xmm6. The low side's rounds are the same as the
## high side's, except no rcon and no rotation.
##
.align 16
.Lschedule_256:
movdqu 16(%rdi),%xmm0 # load key part 2 (unaligned)
call _vpaes_schedule_transform # input transform
mov \$7, %esi
.Loop_schedule_256:
call _vpaes_schedule_mangle # output low result
movdqa %xmm0, %xmm6 # save cur_lo in xmm6
# high round
call _vpaes_schedule_round
dec %rsi
jz .Lschedule_mangle_last
call _vpaes_schedule_mangle
# low round. swap xmm7 and xmm6
pshufd \$0xFF, %xmm0, %xmm0
movdqa %xmm7, %xmm5
movdqa %xmm6, %xmm7
call _vpaes_schedule_low_round
movdqa %xmm5, %xmm7
jmp .Loop_schedule_256
##
## .aes_schedule_mangle_last
##
## Mangler for last round of key schedule
## Mangles %xmm0
## when encrypting, outputs out(%xmm0) ^ 63
## when decrypting, outputs unskew(%xmm0)
##
## Always called right before return... jumps to cleanup and exits
##
.align 16
.Lschedule_mangle_last:
# schedule last round key from xmm0
lea .Lk_deskew(%rip),%r11 # prepare to deskew
test %rcx, %rcx
jnz .Lschedule_mangle_last_dec
# encrypting
movdqa (%r8,%r10),%xmm1
pshufb %xmm1, %xmm0 # output permute
lea .Lk_opt(%rip), %r11 # prepare to output transform
add \$32, %rdx
.Lschedule_mangle_last_dec:
add \$-16, %rdx
pxor .Lk_s63(%rip), %xmm0
call _vpaes_schedule_transform # output transform
movdqu %xmm0, (%rdx) # save last key
# cleanup
pxor %xmm0, %xmm0
pxor %xmm1, %xmm1
pxor %xmm2, %xmm2
pxor %xmm3, %xmm3
pxor %xmm4, %xmm4
pxor %xmm5, %xmm5
pxor %xmm6, %xmm6
pxor %xmm7, %xmm7
ret
.cfi_endproc
.size _vpaes_schedule_core,.-_vpaes_schedule_core
##
## .aes_schedule_192_smear
##
## Smear the short, low side in the 192-bit key schedule.
##
## Inputs:
## %xmm7: high side, b a x y
## %xmm6: low side, d c 0 0
## %xmm13: 0
##
## Outputs:
## %xmm6: b+c+d b+c 0 0
## %xmm0: b+c+d b+c b a
##
.type _vpaes_schedule_192_smear,\@abi-omnipotent
.align 16
_vpaes_schedule_192_smear:
.cfi_startproc
pshufd \$0x80, %xmm6, %xmm1 # d c 0 0 -> c 0 0 0
pshufd \$0xFE, %xmm7, %xmm0 # b a _ _ -> b b b a
pxor %xmm1, %xmm6 # -> c+d c 0 0
pxor %xmm1, %xmm1
pxor %xmm0, %xmm6 # -> b+c+d b+c b a
movdqa %xmm6, %xmm0
movhlps %xmm1, %xmm6 # clobber low side with zeros
ret
.cfi_endproc
.size _vpaes_schedule_192_smear,.-_vpaes_schedule_192_smear
##
## .aes_schedule_round
##
## Runs one main round of the key schedule on %xmm0, %xmm7
##
## Specifically, runs subbytes on the high dword of %xmm0
## then rotates it by one byte and xors into the low dword of
## %xmm7.
##
## Adds rcon from low byte of %xmm8, then rotates %xmm8 for
## next rcon.
##
## Smears the dwords of %xmm7 by xoring the low into the
## second low, result into third, result into highest.
##
## Returns results in %xmm7 = %xmm0.
## Clobbers %xmm1-%xmm4, %r11.
##
.type _vpaes_schedule_round,\@abi-omnipotent
.align 16
_vpaes_schedule_round:
.cfi_startproc
# extract rcon from xmm8
pxor %xmm1, %xmm1
palignr \$15, %xmm8, %xmm1
palignr \$15, %xmm8, %xmm8
pxor %xmm1, %xmm7
# rotate
pshufd \$0xFF, %xmm0, %xmm0
palignr \$1, %xmm0, %xmm0
# fall through...
# low round: same as high round, but no rotation and no rcon.
_vpaes_schedule_low_round:
# smear xmm7
movdqa %xmm7, %xmm1
pslldq \$4, %xmm7
pxor %xmm1, %xmm7
movdqa %xmm7, %xmm1
pslldq \$8, %xmm7
pxor %xmm1, %xmm7
pxor .Lk_s63(%rip), %xmm7
# subbytes
movdqa %xmm9, %xmm1
pandn %xmm0, %xmm1
psrld \$4, %xmm1 # 1 = i
pand %xmm9, %xmm0 # 0 = k
movdqa %xmm11, %xmm2 # 2 : a/k
pshufb %xmm0, %xmm2 # 2 = a/k
pxor %xmm1, %xmm0 # 0 = j
movdqa %xmm10, %xmm3 # 3 : 1/i
pshufb %xmm1, %xmm3 # 3 = 1/i
pxor %xmm2, %xmm3 # 3 = iak = 1/i + a/k
movdqa %xmm10, %xmm4 # 4 : 1/j
pshufb %xmm0, %xmm4 # 4 = 1/j
pxor %xmm2, %xmm4 # 4 = jak = 1/j + a/k
movdqa %xmm10, %xmm2 # 2 : 1/iak
pshufb %xmm3, %xmm2 # 2 = 1/iak
pxor %xmm0, %xmm2 # 2 = io
movdqa %xmm10, %xmm3 # 3 : 1/jak
pshufb %xmm4, %xmm3 # 3 = 1/jak
pxor %xmm1, %xmm3 # 3 = jo
movdqa %xmm13, %xmm4 # 4 : sbou
pshufb %xmm2, %xmm4 # 4 = sbou
movdqa %xmm12, %xmm0 # 0 : sbot
pshufb %xmm3, %xmm0 # 0 = sb1t
pxor %xmm4, %xmm0 # 0 = sbox output
# add in smeared stuff
pxor %xmm7, %xmm0
movdqa %xmm0, %xmm7
ret
.cfi_endproc
.size _vpaes_schedule_round,.-_vpaes_schedule_round
##
## .aes_schedule_transform
##
## Linear-transform %xmm0 according to tables at (%r11)
##
## Requires that %xmm9 = 0x0F0F... as in preheat
## Output in %xmm0
## Clobbers %xmm1, %xmm2
##
.type _vpaes_schedule_transform,\@abi-omnipotent
.align 16
_vpaes_schedule_transform:
.cfi_startproc
movdqa %xmm9, %xmm1
pandn %xmm0, %xmm1
psrld \$4, %xmm1
pand %xmm9, %xmm0
movdqa (%r11), %xmm2 # lo
pshufb %xmm0, %xmm2
movdqa 16(%r11), %xmm0 # hi
pshufb %xmm1, %xmm0
pxor %xmm2, %xmm0
ret
.cfi_endproc
.size _vpaes_schedule_transform,.-_vpaes_schedule_transform
##
## .aes_schedule_mangle
##
## Mangle xmm0 from (basis-transformed) standard version
## to our version.
##
## On encrypt,
## xor with 0x63
## multiply by circulant 0,1,1,1
## apply shiftrows transform
##
## On decrypt,
## xor with 0x63
## multiply by "inverse mixcolumns" circulant E,B,D,9
## deskew
## apply shiftrows transform
##
##
## Writes out to (%rdx), and increments or decrements it
## Keeps track of round number mod 4 in %r8
## Preserves xmm0
## Clobbers xmm1-xmm5
##
.type _vpaes_schedule_mangle,\@abi-omnipotent
.align 16
_vpaes_schedule_mangle:
.cfi_startproc
movdqa %xmm0, %xmm4 # save xmm0 for later
movdqa .Lk_mc_forward(%rip),%xmm5
test %rcx, %rcx
jnz .Lschedule_mangle_dec
# encrypting
add \$16, %rdx
pxor .Lk_s63(%rip),%xmm4
pshufb %xmm5, %xmm4
movdqa %xmm4, %xmm3
pshufb %xmm5, %xmm4
pxor %xmm4, %xmm3
pshufb %xmm5, %xmm4
pxor %xmm4, %xmm3
jmp .Lschedule_mangle_both
.align 16
.Lschedule_mangle_dec:
# inverse mix columns
lea .Lk_dksd(%rip),%r11
movdqa %xmm9, %xmm1
pandn %xmm4, %xmm1
psrld \$4, %xmm1 # 1 = hi
pand %xmm9, %xmm4 # 4 = lo
movdqa 0x00(%r11), %xmm2
pshufb %xmm4, %xmm2
movdqa 0x10(%r11), %xmm3
pshufb %xmm1, %xmm3
pxor %xmm2, %xmm3
pshufb %xmm5, %xmm3
movdqa 0x20(%r11), %xmm2
pshufb %xmm4, %xmm2
pxor %xmm3, %xmm2
movdqa 0x30(%r11), %xmm3
pshufb %xmm1, %xmm3
pxor %xmm2, %xmm3
pshufb %xmm5, %xmm3
movdqa 0x40(%r11), %xmm2
pshufb %xmm4, %xmm2
pxor %xmm3, %xmm2
movdqa 0x50(%r11), %xmm3
pshufb %xmm1, %xmm3
pxor %xmm2, %xmm3
pshufb %xmm5, %xmm3
movdqa 0x60(%r11), %xmm2
pshufb %xmm4, %xmm2
pxor %xmm3, %xmm2
movdqa 0x70(%r11), %xmm3
pshufb %xmm1, %xmm3
pxor %xmm2, %xmm3
add \$-16, %rdx
.Lschedule_mangle_both:
movdqa (%r8,%r10),%xmm1
pshufb %xmm1,%xmm3
add \$-16, %r8
and \$0x30, %r8
movdqu %xmm3, (%rdx)
ret
.cfi_endproc
.size _vpaes_schedule_mangle,.-_vpaes_schedule_mangle
#
# Interface to OpenSSL
#
.globl ${PREFIX}_set_encrypt_key