1e71b7053SJung-uk Kim#! /usr/bin/env perl 2640242a5SJung-uk Kim# Copyright 2011-2023 The OpenSSL Project Authors. All Rights Reserved. 3e71b7053SJung-uk Kim# 4*b077aed3SPierre Pronchery# Licensed under the Apache License 2.0 (the "License"). You may not use 5e71b7053SJung-uk Kim# this file except in compliance with the License. You can obtain a copy 6e71b7053SJung-uk Kim# in the file LICENSE in the source distribution or at 7e71b7053SJung-uk Kim# https://www.openssl.org/source/license.html 8e71b7053SJung-uk Kim 9e71b7053SJung-uk Kim 10e71b7053SJung-uk Kim# ==================================================================== 11e71b7053SJung-uk Kim# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL 12e71b7053SJung-uk Kim# project. The module is, however, dual licensed under OpenSSL and 13e71b7053SJung-uk Kim# CRYPTOGAMS licenses depending on where you obtain it. For further 14e71b7053SJung-uk Kim# details see http://www.openssl.org/~appro/cryptogams/. 15e71b7053SJung-uk Kim# ==================================================================== 16e71b7053SJung-uk Kim 17e71b7053SJung-uk Kim# September 2011 18e71b7053SJung-uk Kim# 19e71b7053SJung-uk Kim# Assembler helpers for Padlock engine. See even e_padlock-x86.pl for 20e71b7053SJung-uk Kim# details. 21e71b7053SJung-uk Kim 22*b077aed3SPierre Pronchery# $output is the last argument if it looks like a file (it has an extension) 23*b077aed3SPierre Pronchery# $flavour is the first argument if it doesn't look like a file 24*b077aed3SPierre Pronchery$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; 25*b077aed3SPierre Pronchery$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; 26e71b7053SJung-uk Kim 27e71b7053SJung-uk Kim$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); 28e71b7053SJung-uk Kim 29e71b7053SJung-uk Kim$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; 30e71b7053SJung-uk Kim( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or 31e71b7053SJung-uk Kim( $xlate="${dir}../../crypto/perlasm/x86_64-xlate.pl" and -f $xlate) or 32e71b7053SJung-uk Kimdie "can't locate x86_64-xlate.pl"; 33e71b7053SJung-uk Kim 34*b077aed3SPierre Proncheryopen OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" 35*b077aed3SPierre Pronchery or die "can't call $xlate: $!"; 36e71b7053SJung-uk Kim*STDOUT=*OUT; 37e71b7053SJung-uk Kim 38e71b7053SJung-uk Kim$code=".text\n"; 39e71b7053SJung-uk Kim 40e71b7053SJung-uk Kim%PADLOCK_PREFETCH=(ecb=>128, cbc=>64, ctr32=>32); # prefetch errata 41e71b7053SJung-uk Kim$PADLOCK_CHUNK=512; # Must be a power of 2 between 32 and 2^20 42e71b7053SJung-uk Kim 43e71b7053SJung-uk Kim$ctx="%rdx"; 44e71b7053SJung-uk Kim$out="%rdi"; 45e71b7053SJung-uk Kim$inp="%rsi"; 46e71b7053SJung-uk Kim$len="%rcx"; 47e71b7053SJung-uk Kim$chunk="%rbx"; 48e71b7053SJung-uk Kim 49e71b7053SJung-uk Kim($arg1,$arg2,$arg3,$arg4)=$win64?("%rcx","%rdx","%r8", "%r9") : # Win64 order 50e71b7053SJung-uk Kim ("%rdi","%rsi","%rdx","%rcx"); # Unix order 51e71b7053SJung-uk Kim 52e71b7053SJung-uk Kim$code.=<<___; 53e71b7053SJung-uk Kim.globl padlock_capability 54e71b7053SJung-uk Kim.type padlock_capability,\@abi-omnipotent 55e71b7053SJung-uk Kim.align 16 56e71b7053SJung-uk Kimpadlock_capability: 57e71b7053SJung-uk Kim mov %rbx,%r8 58e71b7053SJung-uk Kim xor %eax,%eax 59e71b7053SJung-uk Kim cpuid 60e71b7053SJung-uk Kim xor %eax,%eax 61e71b7053SJung-uk Kim cmp \$`"0x".unpack("H*",'tneC')`,%ebx 62e71b7053SJung-uk Kim jne .Lzhaoxin 63e71b7053SJung-uk Kim cmp \$`"0x".unpack("H*",'Hrua')`,%edx 64e71b7053SJung-uk Kim jne .Lnoluck 65e71b7053SJung-uk Kim cmp \$`"0x".unpack("H*",'slua')`,%ecx 66e71b7053SJung-uk Kim jne .Lnoluck 67e71b7053SJung-uk Kim jmp .LzhaoxinEnd 68e71b7053SJung-uk Kim.Lzhaoxin: 69e71b7053SJung-uk Kim cmp \$`"0x".unpack("H*",'hS ')`,%ebx 70e71b7053SJung-uk Kim jne .Lnoluck 71e71b7053SJung-uk Kim cmp \$`"0x".unpack("H*",'hgna')`,%edx 72e71b7053SJung-uk Kim jne .Lnoluck 73e71b7053SJung-uk Kim cmp \$`"0x".unpack("H*",' ia')`,%ecx 74e71b7053SJung-uk Kim jne .Lnoluck 75e71b7053SJung-uk Kim.LzhaoxinEnd: 76e71b7053SJung-uk Kim mov \$0xC0000000,%eax 77e71b7053SJung-uk Kim cpuid 78e71b7053SJung-uk Kim mov %eax,%edx 79e71b7053SJung-uk Kim xor %eax,%eax 80e71b7053SJung-uk Kim cmp \$0xC0000001,%edx 81e71b7053SJung-uk Kim jb .Lnoluck 82e71b7053SJung-uk Kim mov \$0xC0000001,%eax 83e71b7053SJung-uk Kim cpuid 84e71b7053SJung-uk Kim mov %edx,%eax 85e71b7053SJung-uk Kim and \$0xffffffef,%eax 86e71b7053SJung-uk Kim or \$0x10,%eax # set Nano bit#4 87e71b7053SJung-uk Kim.Lnoluck: 88e71b7053SJung-uk Kim mov %r8,%rbx 89e71b7053SJung-uk Kim ret 90e71b7053SJung-uk Kim.size padlock_capability,.-padlock_capability 91e71b7053SJung-uk Kim 92e71b7053SJung-uk Kim.globl padlock_key_bswap 93e71b7053SJung-uk Kim.type padlock_key_bswap,\@abi-omnipotent,0 94e71b7053SJung-uk Kim.align 16 95e71b7053SJung-uk Kimpadlock_key_bswap: 96e71b7053SJung-uk Kim mov 240($arg1),%edx 97640242a5SJung-uk Kim inc %edx 98640242a5SJung-uk Kim shl \$2,%edx 99e71b7053SJung-uk Kim.Lbswap_loop: 100e71b7053SJung-uk Kim mov ($arg1),%eax 101e71b7053SJung-uk Kim bswap %eax 102e71b7053SJung-uk Kim mov %eax,($arg1) 103e71b7053SJung-uk Kim lea 4($arg1),$arg1 104e71b7053SJung-uk Kim sub \$1,%edx 105e71b7053SJung-uk Kim jnz .Lbswap_loop 106e71b7053SJung-uk Kim ret 107e71b7053SJung-uk Kim.size padlock_key_bswap,.-padlock_key_bswap 108e71b7053SJung-uk Kim 109e71b7053SJung-uk Kim.globl padlock_verify_context 110e71b7053SJung-uk Kim.type padlock_verify_context,\@abi-omnipotent 111e71b7053SJung-uk Kim.align 16 112e71b7053SJung-uk Kimpadlock_verify_context: 113e71b7053SJung-uk Kim mov $arg1,$ctx 114e71b7053SJung-uk Kim pushf 115e71b7053SJung-uk Kim lea .Lpadlock_saved_context(%rip),%rax 116e71b7053SJung-uk Kim call _padlock_verify_ctx 117e71b7053SJung-uk Kim lea 8(%rsp),%rsp 118e71b7053SJung-uk Kim ret 119e71b7053SJung-uk Kim.size padlock_verify_context,.-padlock_verify_context 120e71b7053SJung-uk Kim 121e71b7053SJung-uk Kim.type _padlock_verify_ctx,\@abi-omnipotent 122e71b7053SJung-uk Kim.align 16 123e71b7053SJung-uk Kim_padlock_verify_ctx: 124e71b7053SJung-uk Kim mov 8(%rsp),%r8 125e71b7053SJung-uk Kim bt \$30,%r8 126e71b7053SJung-uk Kim jnc .Lverified 127e71b7053SJung-uk Kim cmp (%rax),$ctx 128e71b7053SJung-uk Kim je .Lverified 129e71b7053SJung-uk Kim pushf 130e71b7053SJung-uk Kim popf 131e71b7053SJung-uk Kim.Lverified: 132e71b7053SJung-uk Kim mov $ctx,(%rax) 133e71b7053SJung-uk Kim ret 134e71b7053SJung-uk Kim.size _padlock_verify_ctx,.-_padlock_verify_ctx 135e71b7053SJung-uk Kim 136e71b7053SJung-uk Kim.globl padlock_reload_key 137e71b7053SJung-uk Kim.type padlock_reload_key,\@abi-omnipotent 138e71b7053SJung-uk Kim.align 16 139e71b7053SJung-uk Kimpadlock_reload_key: 140e71b7053SJung-uk Kim pushf 141e71b7053SJung-uk Kim popf 142e71b7053SJung-uk Kim ret 143e71b7053SJung-uk Kim.size padlock_reload_key,.-padlock_reload_key 144e71b7053SJung-uk Kim 145e71b7053SJung-uk Kim.globl padlock_aes_block 146e71b7053SJung-uk Kim.type padlock_aes_block,\@function,3 147e71b7053SJung-uk Kim.align 16 148e71b7053SJung-uk Kimpadlock_aes_block: 149e71b7053SJung-uk Kim mov %rbx,%r8 150e71b7053SJung-uk Kim mov \$1,$len 151e71b7053SJung-uk Kim lea 32($ctx),%rbx # key 152e71b7053SJung-uk Kim lea 16($ctx),$ctx # control word 153e71b7053SJung-uk Kim .byte 0xf3,0x0f,0xa7,0xc8 # rep xcryptecb 154e71b7053SJung-uk Kim mov %r8,%rbx 155e71b7053SJung-uk Kim ret 156e71b7053SJung-uk Kim.size padlock_aes_block,.-padlock_aes_block 157e71b7053SJung-uk Kim 158e71b7053SJung-uk Kim.globl padlock_xstore 159e71b7053SJung-uk Kim.type padlock_xstore,\@function,2 160e71b7053SJung-uk Kim.align 16 161e71b7053SJung-uk Kimpadlock_xstore: 162e71b7053SJung-uk Kim mov %esi,%edx 163e71b7053SJung-uk Kim .byte 0x0f,0xa7,0xc0 # xstore 164e71b7053SJung-uk Kim ret 165e71b7053SJung-uk Kim.size padlock_xstore,.-padlock_xstore 166e71b7053SJung-uk Kim 167e71b7053SJung-uk Kim.globl padlock_sha1_oneshot 168e71b7053SJung-uk Kim.type padlock_sha1_oneshot,\@function,3 169e71b7053SJung-uk Kim.align 16 170e71b7053SJung-uk Kimpadlock_sha1_oneshot: 171e71b7053SJung-uk Kim mov %rdx,%rcx 172e71b7053SJung-uk Kim mov %rdi,%rdx # put aside %rdi 173e71b7053SJung-uk Kim movups (%rdi),%xmm0 # copy-in context 174e71b7053SJung-uk Kim sub \$128+8,%rsp 175e71b7053SJung-uk Kim mov 16(%rdi),%eax 176e71b7053SJung-uk Kim movaps %xmm0,(%rsp) 177e71b7053SJung-uk Kim mov %rsp,%rdi 178e71b7053SJung-uk Kim mov %eax,16(%rsp) 179e71b7053SJung-uk Kim xor %rax,%rax 180e71b7053SJung-uk Kim .byte 0xf3,0x0f,0xa6,0xc8 # rep xsha1 181e71b7053SJung-uk Kim movaps (%rsp),%xmm0 182e71b7053SJung-uk Kim mov 16(%rsp),%eax 183e71b7053SJung-uk Kim add \$128+8,%rsp 184e71b7053SJung-uk Kim movups %xmm0,(%rdx) # copy-out context 185e71b7053SJung-uk Kim mov %eax,16(%rdx) 186e71b7053SJung-uk Kim ret 187e71b7053SJung-uk Kim.size padlock_sha1_oneshot,.-padlock_sha1_oneshot 188e71b7053SJung-uk Kim 189e71b7053SJung-uk Kim.globl padlock_sha1_blocks 190e71b7053SJung-uk Kim.type padlock_sha1_blocks,\@function,3 191e71b7053SJung-uk Kim.align 16 192e71b7053SJung-uk Kimpadlock_sha1_blocks: 193e71b7053SJung-uk Kim mov %rdx,%rcx 194e71b7053SJung-uk Kim mov %rdi,%rdx # put aside %rdi 195e71b7053SJung-uk Kim movups (%rdi),%xmm0 # copy-in context 196e71b7053SJung-uk Kim sub \$128+8,%rsp 197e71b7053SJung-uk Kim mov 16(%rdi),%eax 198e71b7053SJung-uk Kim movaps %xmm0,(%rsp) 199e71b7053SJung-uk Kim mov %rsp,%rdi 200e71b7053SJung-uk Kim mov %eax,16(%rsp) 201e71b7053SJung-uk Kim mov \$-1,%rax 202e71b7053SJung-uk Kim .byte 0xf3,0x0f,0xa6,0xc8 # rep xsha1 203e71b7053SJung-uk Kim movaps (%rsp),%xmm0 204e71b7053SJung-uk Kim mov 16(%rsp),%eax 205e71b7053SJung-uk Kim add \$128+8,%rsp 206e71b7053SJung-uk Kim movups %xmm0,(%rdx) # copy-out context 207e71b7053SJung-uk Kim mov %eax,16(%rdx) 208e71b7053SJung-uk Kim ret 209e71b7053SJung-uk Kim.size padlock_sha1_blocks,.-padlock_sha1_blocks 210e71b7053SJung-uk Kim 211e71b7053SJung-uk Kim.globl padlock_sha256_oneshot 212e71b7053SJung-uk Kim.type padlock_sha256_oneshot,\@function,3 213e71b7053SJung-uk Kim.align 16 214e71b7053SJung-uk Kimpadlock_sha256_oneshot: 215e71b7053SJung-uk Kim mov %rdx,%rcx 216e71b7053SJung-uk Kim mov %rdi,%rdx # put aside %rdi 217e71b7053SJung-uk Kim movups (%rdi),%xmm0 # copy-in context 218e71b7053SJung-uk Kim sub \$128+8,%rsp 219e71b7053SJung-uk Kim movups 16(%rdi),%xmm1 220e71b7053SJung-uk Kim movaps %xmm0,(%rsp) 221e71b7053SJung-uk Kim mov %rsp,%rdi 222e71b7053SJung-uk Kim movaps %xmm1,16(%rsp) 223e71b7053SJung-uk Kim xor %rax,%rax 224e71b7053SJung-uk Kim .byte 0xf3,0x0f,0xa6,0xd0 # rep xsha256 225e71b7053SJung-uk Kim movaps (%rsp),%xmm0 226e71b7053SJung-uk Kim movaps 16(%rsp),%xmm1 227e71b7053SJung-uk Kim add \$128+8,%rsp 228e71b7053SJung-uk Kim movups %xmm0,(%rdx) # copy-out context 229e71b7053SJung-uk Kim movups %xmm1,16(%rdx) 230e71b7053SJung-uk Kim ret 231e71b7053SJung-uk Kim.size padlock_sha256_oneshot,.-padlock_sha256_oneshot 232e71b7053SJung-uk Kim 233e71b7053SJung-uk Kim.globl padlock_sha256_blocks 234e71b7053SJung-uk Kim.type padlock_sha256_blocks,\@function,3 235e71b7053SJung-uk Kim.align 16 236e71b7053SJung-uk Kimpadlock_sha256_blocks: 237e71b7053SJung-uk Kim mov %rdx,%rcx 238e71b7053SJung-uk Kim mov %rdi,%rdx # put aside %rdi 239e71b7053SJung-uk Kim movups (%rdi),%xmm0 # copy-in context 240e71b7053SJung-uk Kim sub \$128+8,%rsp 241e71b7053SJung-uk Kim movups 16(%rdi),%xmm1 242e71b7053SJung-uk Kim movaps %xmm0,(%rsp) 243e71b7053SJung-uk Kim mov %rsp,%rdi 244e71b7053SJung-uk Kim movaps %xmm1,16(%rsp) 245e71b7053SJung-uk Kim mov \$-1,%rax 246e71b7053SJung-uk Kim .byte 0xf3,0x0f,0xa6,0xd0 # rep xsha256 247e71b7053SJung-uk Kim movaps (%rsp),%xmm0 248e71b7053SJung-uk Kim movaps 16(%rsp),%xmm1 249e71b7053SJung-uk Kim add \$128+8,%rsp 250e71b7053SJung-uk Kim movups %xmm0,(%rdx) # copy-out context 251e71b7053SJung-uk Kim movups %xmm1,16(%rdx) 252e71b7053SJung-uk Kim ret 253e71b7053SJung-uk Kim.size padlock_sha256_blocks,.-padlock_sha256_blocks 254e71b7053SJung-uk Kim 255e71b7053SJung-uk Kim.globl padlock_sha512_blocks 256e71b7053SJung-uk Kim.type padlock_sha512_blocks,\@function,3 257e71b7053SJung-uk Kim.align 16 258e71b7053SJung-uk Kimpadlock_sha512_blocks: 259e71b7053SJung-uk Kim mov %rdx,%rcx 260e71b7053SJung-uk Kim mov %rdi,%rdx # put aside %rdi 261e71b7053SJung-uk Kim movups (%rdi),%xmm0 # copy-in context 262e71b7053SJung-uk Kim sub \$128+8,%rsp 263e71b7053SJung-uk Kim movups 16(%rdi),%xmm1 264e71b7053SJung-uk Kim movups 32(%rdi),%xmm2 265e71b7053SJung-uk Kim movups 48(%rdi),%xmm3 266e71b7053SJung-uk Kim movaps %xmm0,(%rsp) 267e71b7053SJung-uk Kim mov %rsp,%rdi 268e71b7053SJung-uk Kim movaps %xmm1,16(%rsp) 269e71b7053SJung-uk Kim movaps %xmm2,32(%rsp) 270e71b7053SJung-uk Kim movaps %xmm3,48(%rsp) 271e71b7053SJung-uk Kim .byte 0xf3,0x0f,0xa6,0xe0 # rep xha512 272e71b7053SJung-uk Kim movaps (%rsp),%xmm0 273e71b7053SJung-uk Kim movaps 16(%rsp),%xmm1 274e71b7053SJung-uk Kim movaps 32(%rsp),%xmm2 275e71b7053SJung-uk Kim movaps 48(%rsp),%xmm3 276e71b7053SJung-uk Kim add \$128+8,%rsp 277e71b7053SJung-uk Kim movups %xmm0,(%rdx) # copy-out context 278e71b7053SJung-uk Kim movups %xmm1,16(%rdx) 279e71b7053SJung-uk Kim movups %xmm2,32(%rdx) 280e71b7053SJung-uk Kim movups %xmm3,48(%rdx) 281e71b7053SJung-uk Kim ret 282e71b7053SJung-uk Kim.size padlock_sha512_blocks,.-padlock_sha512_blocks 283e71b7053SJung-uk Kim___ 284e71b7053SJung-uk Kim 285e71b7053SJung-uk Kimsub generate_mode { 286e71b7053SJung-uk Kimmy ($mode,$opcode) = @_; 287e71b7053SJung-uk Kim# int padlock_$mode_encrypt(void *out, const void *inp, 288e71b7053SJung-uk Kim# struct padlock_cipher_data *ctx, size_t len); 289e71b7053SJung-uk Kim$code.=<<___; 290e71b7053SJung-uk Kim.globl padlock_${mode}_encrypt 291e71b7053SJung-uk Kim.type padlock_${mode}_encrypt,\@function,4 292e71b7053SJung-uk Kim.align 16 293e71b7053SJung-uk Kimpadlock_${mode}_encrypt: 294e71b7053SJung-uk Kim push %rbp 295e71b7053SJung-uk Kim push %rbx 296e71b7053SJung-uk Kim 297e71b7053SJung-uk Kim xor %eax,%eax 298e71b7053SJung-uk Kim test \$15,$ctx 299e71b7053SJung-uk Kim jnz .L${mode}_abort 300e71b7053SJung-uk Kim test \$15,$len 301e71b7053SJung-uk Kim jnz .L${mode}_abort 302e71b7053SJung-uk Kim lea .Lpadlock_saved_context(%rip),%rax 303e71b7053SJung-uk Kim pushf 304e71b7053SJung-uk Kim cld 305e71b7053SJung-uk Kim call _padlock_verify_ctx 306e71b7053SJung-uk Kim lea 16($ctx),$ctx # control word 307e71b7053SJung-uk Kim xor %eax,%eax 308e71b7053SJung-uk Kim xor %ebx,%ebx 309e71b7053SJung-uk Kim testl \$`1<<5`,($ctx) # align bit in control word 310e71b7053SJung-uk Kim jnz .L${mode}_aligned 311e71b7053SJung-uk Kim test \$0x0f,$out 312e71b7053SJung-uk Kim setz %al # !out_misaligned 313e71b7053SJung-uk Kim test \$0x0f,$inp 314e71b7053SJung-uk Kim setz %bl # !inp_misaligned 315e71b7053SJung-uk Kim test %ebx,%eax 316e71b7053SJung-uk Kim jnz .L${mode}_aligned 317e71b7053SJung-uk Kim neg %rax 318e71b7053SJung-uk Kim mov \$$PADLOCK_CHUNK,$chunk 319e71b7053SJung-uk Kim not %rax # out_misaligned?-1:0 320e71b7053SJung-uk Kim lea (%rsp),%rbp 321e71b7053SJung-uk Kim cmp $chunk,$len 322e71b7053SJung-uk Kim cmovc $len,$chunk # chunk=len>PADLOCK_CHUNK?PADLOCK_CHUNK:len 323e71b7053SJung-uk Kim and $chunk,%rax # out_misaligned?chunk:0 324e71b7053SJung-uk Kim mov $len,$chunk 325e71b7053SJung-uk Kim neg %rax 326e71b7053SJung-uk Kim and \$$PADLOCK_CHUNK-1,$chunk # chunk%=PADLOCK_CHUNK 327e71b7053SJung-uk Kim lea (%rax,%rbp),%rsp 328e71b7053SJung-uk Kim mov \$$PADLOCK_CHUNK,%rax 329e71b7053SJung-uk Kim cmovz %rax,$chunk # chunk=chunk?:PADLOCK_CHUNK 330e71b7053SJung-uk Kim___ 331e71b7053SJung-uk Kim$code.=<<___ if ($mode eq "ctr32"); 332e71b7053SJung-uk Kim.L${mode}_reenter: 333e71b7053SJung-uk Kim mov -4($ctx),%eax # pull 32-bit counter 334e71b7053SJung-uk Kim bswap %eax 335e71b7053SJung-uk Kim neg %eax 336e71b7053SJung-uk Kim and \$`$PADLOCK_CHUNK/16-1`,%eax 337e71b7053SJung-uk Kim mov \$$PADLOCK_CHUNK,$chunk 338e71b7053SJung-uk Kim shl \$4,%eax 339e71b7053SJung-uk Kim cmovz $chunk,%rax 340e71b7053SJung-uk Kim cmp %rax,$len 341e71b7053SJung-uk Kim cmova %rax,$chunk # don't let counter cross PADLOCK_CHUNK 342e71b7053SJung-uk Kim cmovbe $len,$chunk 343e71b7053SJung-uk Kim___ 344e71b7053SJung-uk Kim$code.=<<___ if ($PADLOCK_PREFETCH{$mode}); 345e71b7053SJung-uk Kim cmp $chunk,$len 346e71b7053SJung-uk Kim ja .L${mode}_loop 347e71b7053SJung-uk Kim mov $inp,%rax # check if prefetch crosses page 348e71b7053SJung-uk Kim cmp %rsp,%rbp 349e71b7053SJung-uk Kim cmove $out,%rax 350e71b7053SJung-uk Kim add $len,%rax 351e71b7053SJung-uk Kim neg %rax 352e71b7053SJung-uk Kim and \$0xfff,%rax # distance to page boundary 353e71b7053SJung-uk Kim cmp \$$PADLOCK_PREFETCH{$mode},%rax 354e71b7053SJung-uk Kim mov \$-$PADLOCK_PREFETCH{$mode},%rax 355e71b7053SJung-uk Kim cmovae $chunk,%rax # mask=distance<prefetch?-prefetch:-1 356e71b7053SJung-uk Kim and %rax,$chunk 357e71b7053SJung-uk Kim jz .L${mode}_unaligned_tail 358e71b7053SJung-uk Kim___ 359e71b7053SJung-uk Kim$code.=<<___; 360e71b7053SJung-uk Kim jmp .L${mode}_loop 361e71b7053SJung-uk Kim.align 16 362e71b7053SJung-uk Kim.L${mode}_loop: 363e71b7053SJung-uk Kim cmp $len,$chunk # ctr32 artefact 364e71b7053SJung-uk Kim cmova $len,$chunk # ctr32 artefact 365e71b7053SJung-uk Kim mov $out,%r8 # save parameters 366e71b7053SJung-uk Kim mov $inp,%r9 367e71b7053SJung-uk Kim mov $len,%r10 368e71b7053SJung-uk Kim mov $chunk,$len 369e71b7053SJung-uk Kim mov $chunk,%r11 370e71b7053SJung-uk Kim test \$0x0f,$out # out_misaligned 371e71b7053SJung-uk Kim cmovnz %rsp,$out 372e71b7053SJung-uk Kim test \$0x0f,$inp # inp_misaligned 373e71b7053SJung-uk Kim jz .L${mode}_inp_aligned 374e71b7053SJung-uk Kim shr \$3,$len 375e71b7053SJung-uk Kim .byte 0xf3,0x48,0xa5 # rep movsq 376e71b7053SJung-uk Kim sub $chunk,$out 377e71b7053SJung-uk Kim mov $chunk,$len 378e71b7053SJung-uk Kim mov $out,$inp 379e71b7053SJung-uk Kim.L${mode}_inp_aligned: 380e71b7053SJung-uk Kim lea -16($ctx),%rax # ivp 381e71b7053SJung-uk Kim lea 16($ctx),%rbx # key 382e71b7053SJung-uk Kim shr \$4,$len 383e71b7053SJung-uk Kim .byte 0xf3,0x0f,0xa7,$opcode # rep xcrypt* 384e71b7053SJung-uk Kim___ 385e71b7053SJung-uk Kim$code.=<<___ if ($mode !~ /ecb|ctr/); 386e71b7053SJung-uk Kim movdqa (%rax),%xmm0 387e71b7053SJung-uk Kim movdqa %xmm0,-16($ctx) # copy [or refresh] iv 388e71b7053SJung-uk Kim___ 389e71b7053SJung-uk Kim$code.=<<___ if ($mode eq "ctr32"); 390e71b7053SJung-uk Kim mov -4($ctx),%eax # pull 32-bit counter 391e71b7053SJung-uk Kim test \$0xffff0000,%eax 392e71b7053SJung-uk Kim jnz .L${mode}_no_carry 393e71b7053SJung-uk Kim bswap %eax 394e71b7053SJung-uk Kim add \$0x10000,%eax 395e71b7053SJung-uk Kim bswap %eax 396e71b7053SJung-uk Kim mov %eax,-4($ctx) 397e71b7053SJung-uk Kim.L${mode}_no_carry: 398e71b7053SJung-uk Kim___ 399e71b7053SJung-uk Kim$code.=<<___; 400e71b7053SJung-uk Kim mov %r8,$out # restore parameters 401e71b7053SJung-uk Kim mov %r11,$chunk 402e71b7053SJung-uk Kim test \$0x0f,$out 403e71b7053SJung-uk Kim jz .L${mode}_out_aligned 404e71b7053SJung-uk Kim mov $chunk,$len 405e71b7053SJung-uk Kim lea (%rsp),$inp 406e71b7053SJung-uk Kim shr \$3,$len 407e71b7053SJung-uk Kim .byte 0xf3,0x48,0xa5 # rep movsq 408e71b7053SJung-uk Kim sub $chunk,$out 409e71b7053SJung-uk Kim.L${mode}_out_aligned: 410e71b7053SJung-uk Kim mov %r9,$inp 411e71b7053SJung-uk Kim mov %r10,$len 412e71b7053SJung-uk Kim add $chunk,$out 413e71b7053SJung-uk Kim add $chunk,$inp 414e71b7053SJung-uk Kim sub $chunk,$len 415e71b7053SJung-uk Kim mov \$$PADLOCK_CHUNK,$chunk 416e71b7053SJung-uk Kim___ 417e71b7053SJung-uk Kim if (!$PADLOCK_PREFETCH{$mode}) { 418e71b7053SJung-uk Kim$code.=<<___; 419e71b7053SJung-uk Kim jnz .L${mode}_loop 420e71b7053SJung-uk Kim___ 421e71b7053SJung-uk Kim } else { 422e71b7053SJung-uk Kim$code.=<<___; 423e71b7053SJung-uk Kim jz .L${mode}_break 424e71b7053SJung-uk Kim cmp $chunk,$len 425e71b7053SJung-uk Kim jae .L${mode}_loop 426e71b7053SJung-uk Kim___ 427e71b7053SJung-uk Kim$code.=<<___ if ($mode eq "ctr32"); 428e71b7053SJung-uk Kim mov $len,$chunk 429e71b7053SJung-uk Kim mov $inp,%rax # check if prefetch crosses page 430e71b7053SJung-uk Kim cmp %rsp,%rbp 431e71b7053SJung-uk Kim cmove $out,%rax 432e71b7053SJung-uk Kim add $len,%rax 433e71b7053SJung-uk Kim neg %rax 434e71b7053SJung-uk Kim and \$0xfff,%rax # distance to page boundary 435e71b7053SJung-uk Kim cmp \$$PADLOCK_PREFETCH{$mode},%rax 436e71b7053SJung-uk Kim mov \$-$PADLOCK_PREFETCH{$mode},%rax 437e71b7053SJung-uk Kim cmovae $chunk,%rax 438e71b7053SJung-uk Kim and %rax,$chunk 439e71b7053SJung-uk Kim jnz .L${mode}_loop 440e71b7053SJung-uk Kim___ 441e71b7053SJung-uk Kim$code.=<<___; 442e71b7053SJung-uk Kim.L${mode}_unaligned_tail: 443e71b7053SJung-uk Kim xor %eax,%eax 444e71b7053SJung-uk Kim cmp %rsp,%rbp 445e71b7053SJung-uk Kim cmove $len,%rax 446e71b7053SJung-uk Kim mov $out,%r8 # save parameters 447e71b7053SJung-uk Kim mov $len,$chunk 448e71b7053SJung-uk Kim sub %rax,%rsp # alloca 449e71b7053SJung-uk Kim shr \$3,$len 450e71b7053SJung-uk Kim lea (%rsp),$out 451e71b7053SJung-uk Kim .byte 0xf3,0x48,0xa5 # rep movsq 452e71b7053SJung-uk Kim mov %rsp,$inp 453e71b7053SJung-uk Kim mov %r8, $out # restore parameters 454e71b7053SJung-uk Kim mov $chunk,$len 455e71b7053SJung-uk Kim jmp .L${mode}_loop 456e71b7053SJung-uk Kim.align 16 457e71b7053SJung-uk Kim.L${mode}_break: 458e71b7053SJung-uk Kim___ 459e71b7053SJung-uk Kim } 460e71b7053SJung-uk Kim$code.=<<___; 461e71b7053SJung-uk Kim cmp %rbp,%rsp 462e71b7053SJung-uk Kim je .L${mode}_done 463e71b7053SJung-uk Kim 464e71b7053SJung-uk Kim pxor %xmm0,%xmm0 465e71b7053SJung-uk Kim lea (%rsp),%rax 466e71b7053SJung-uk Kim.L${mode}_bzero: 467e71b7053SJung-uk Kim movaps %xmm0,(%rax) 468e71b7053SJung-uk Kim lea 16(%rax),%rax 469e71b7053SJung-uk Kim cmp %rax,%rbp 470e71b7053SJung-uk Kim ja .L${mode}_bzero 471e71b7053SJung-uk Kim 472e71b7053SJung-uk Kim.L${mode}_done: 473e71b7053SJung-uk Kim lea (%rbp),%rsp 474e71b7053SJung-uk Kim jmp .L${mode}_exit 475e71b7053SJung-uk Kim 476e71b7053SJung-uk Kim.align 16 477e71b7053SJung-uk Kim.L${mode}_aligned: 478e71b7053SJung-uk Kim___ 479e71b7053SJung-uk Kim$code.=<<___ if ($mode eq "ctr32"); 480e71b7053SJung-uk Kim mov -4($ctx),%eax # pull 32-bit counter 481e71b7053SJung-uk Kim bswap %eax 482e71b7053SJung-uk Kim neg %eax 483e71b7053SJung-uk Kim and \$0xffff,%eax 484e71b7053SJung-uk Kim mov \$`16*0x10000`,$chunk 485e71b7053SJung-uk Kim shl \$4,%eax 486e71b7053SJung-uk Kim cmovz $chunk,%rax 487e71b7053SJung-uk Kim cmp %rax,$len 488e71b7053SJung-uk Kim cmova %rax,$chunk # don't let counter cross 2^16 489e71b7053SJung-uk Kim cmovbe $len,$chunk 490e71b7053SJung-uk Kim jbe .L${mode}_aligned_skip 491e71b7053SJung-uk Kim 492e71b7053SJung-uk Kim.L${mode}_aligned_loop: 493e71b7053SJung-uk Kim mov $len,%r10 # save parameters 494e71b7053SJung-uk Kim mov $chunk,$len 495e71b7053SJung-uk Kim mov $chunk,%r11 496e71b7053SJung-uk Kim 497e71b7053SJung-uk Kim lea -16($ctx),%rax # ivp 498e71b7053SJung-uk Kim lea 16($ctx),%rbx # key 499e71b7053SJung-uk Kim shr \$4,$len # len/=AES_BLOCK_SIZE 500e71b7053SJung-uk Kim .byte 0xf3,0x0f,0xa7,$opcode # rep xcrypt* 501e71b7053SJung-uk Kim 502e71b7053SJung-uk Kim mov -4($ctx),%eax # pull 32-bit counter 503e71b7053SJung-uk Kim bswap %eax 504e71b7053SJung-uk Kim add \$0x10000,%eax 505e71b7053SJung-uk Kim bswap %eax 506e71b7053SJung-uk Kim mov %eax,-4($ctx) 507e71b7053SJung-uk Kim 508e71b7053SJung-uk Kim mov %r10,$len # restore parameters 509e71b7053SJung-uk Kim sub %r11,$len 510e71b7053SJung-uk Kim mov \$`16*0x10000`,$chunk 511e71b7053SJung-uk Kim jz .L${mode}_exit 512e71b7053SJung-uk Kim cmp $chunk,$len 513e71b7053SJung-uk Kim jae .L${mode}_aligned_loop 514e71b7053SJung-uk Kim 515e71b7053SJung-uk Kim.L${mode}_aligned_skip: 516e71b7053SJung-uk Kim___ 517e71b7053SJung-uk Kim$code.=<<___ if ($PADLOCK_PREFETCH{$mode}); 518e71b7053SJung-uk Kim lea ($inp,$len),%rbp 519e71b7053SJung-uk Kim neg %rbp 520e71b7053SJung-uk Kim and \$0xfff,%rbp # distance to page boundary 521e71b7053SJung-uk Kim xor %eax,%eax 522e71b7053SJung-uk Kim cmp \$$PADLOCK_PREFETCH{$mode},%rbp 523e71b7053SJung-uk Kim mov \$$PADLOCK_PREFETCH{$mode}-1,%rbp 524e71b7053SJung-uk Kim cmovae %rax,%rbp 525e71b7053SJung-uk Kim and $len,%rbp # remainder 526e71b7053SJung-uk Kim sub %rbp,$len 527e71b7053SJung-uk Kim jz .L${mode}_aligned_tail 528e71b7053SJung-uk Kim___ 529e71b7053SJung-uk Kim$code.=<<___; 530e71b7053SJung-uk Kim lea -16($ctx),%rax # ivp 531e71b7053SJung-uk Kim lea 16($ctx),%rbx # key 532e71b7053SJung-uk Kim shr \$4,$len # len/=AES_BLOCK_SIZE 533e71b7053SJung-uk Kim .byte 0xf3,0x0f,0xa7,$opcode # rep xcrypt* 534e71b7053SJung-uk Kim___ 535e71b7053SJung-uk Kim$code.=<<___ if ($mode !~ /ecb|ctr/); 536e71b7053SJung-uk Kim movdqa (%rax),%xmm0 537e71b7053SJung-uk Kim movdqa %xmm0,-16($ctx) # copy [or refresh] iv 538e71b7053SJung-uk Kim___ 539e71b7053SJung-uk Kim$code.=<<___ if ($PADLOCK_PREFETCH{$mode}); 540e71b7053SJung-uk Kim test %rbp,%rbp # check remainder 541e71b7053SJung-uk Kim jz .L${mode}_exit 542e71b7053SJung-uk Kim 543e71b7053SJung-uk Kim.L${mode}_aligned_tail: 544e71b7053SJung-uk Kim mov $out,%r8 545e71b7053SJung-uk Kim mov %rbp,$chunk 546e71b7053SJung-uk Kim mov %rbp,$len 547e71b7053SJung-uk Kim lea (%rsp),%rbp 548e71b7053SJung-uk Kim sub $len,%rsp 549e71b7053SJung-uk Kim shr \$3,$len 550e71b7053SJung-uk Kim lea (%rsp),$out 551e71b7053SJung-uk Kim .byte 0xf3,0x48,0xa5 # rep movsq 552e71b7053SJung-uk Kim lea (%r8),$out 553e71b7053SJung-uk Kim lea (%rsp),$inp 554e71b7053SJung-uk Kim mov $chunk,$len 555e71b7053SJung-uk Kim jmp .L${mode}_loop 556e71b7053SJung-uk Kim___ 557e71b7053SJung-uk Kim$code.=<<___; 558e71b7053SJung-uk Kim.L${mode}_exit: 559e71b7053SJung-uk Kim mov \$1,%eax 560e71b7053SJung-uk Kim lea 8(%rsp),%rsp 561e71b7053SJung-uk Kim.L${mode}_abort: 562e71b7053SJung-uk Kim pop %rbx 563e71b7053SJung-uk Kim pop %rbp 564e71b7053SJung-uk Kim ret 565e71b7053SJung-uk Kim.size padlock_${mode}_encrypt,.-padlock_${mode}_encrypt 566e71b7053SJung-uk Kim___ 567e71b7053SJung-uk Kim} 568e71b7053SJung-uk Kim 569e71b7053SJung-uk Kim&generate_mode("ecb",0xc8); 570e71b7053SJung-uk Kim&generate_mode("cbc",0xd0); 571e71b7053SJung-uk Kim&generate_mode("cfb",0xe0); 572e71b7053SJung-uk Kim&generate_mode("ofb",0xe8); 573e71b7053SJung-uk Kim&generate_mode("ctr32",0xd8); # all 64-bit CPUs have working CTR... 574e71b7053SJung-uk Kim 575e71b7053SJung-uk Kim$code.=<<___; 576e71b7053SJung-uk Kim.asciz "VIA Padlock x86_64 module, CRYPTOGAMS by <appro\@openssl.org>" 577e71b7053SJung-uk Kim.align 16 578e71b7053SJung-uk Kim.data 579e71b7053SJung-uk Kim.align 8 580e71b7053SJung-uk Kim.Lpadlock_saved_context: 581e71b7053SJung-uk Kim .quad 0 582e71b7053SJung-uk Kim___ 583e71b7053SJung-uk Kim$code =~ s/\`([^\`]*)\`/eval($1)/gem; 584e71b7053SJung-uk Kim 585e71b7053SJung-uk Kimprint $code; 586e71b7053SJung-uk Kim 587e71b7053SJung-uk Kimclose STDOUT; 588