]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added support for VIA padlock based on Andy's code (untested).
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Wed, 7 Sep 2011 17:10:57 +0000 (19:10 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Wed, 7 Sep 2011 17:36:10 +0000 (19:36 +0200)
AUTHORS
lib/accelerated/accelerated.c
lib/accelerated/intel/Makefile.am
lib/accelerated/intel/aes-gcm-x86.c
lib/accelerated/intel/aes-x86.c
lib/accelerated/intel/aes-x86.h
lib/accelerated/intel/asm/padlock-x86-64.s [new file with mode: 0644]
lib/accelerated/intel/asm/padlock-x86.s [new file with mode: 0644]
lib/accelerated/intel/padlock.c [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
index e1d6221fbb67e9ec02aeb40404a3a06a610a9e21..0c9c1cd2cb34875802e7ac2450ab587db919df1d 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -72,6 +72,9 @@ Initial DTLS implementation.
 Ruslan Ijbulatov (LRN) <lrn1986 [at] gmail.com>
 Win32 patches.
 
+Andy Polyakov <appro [at] openssl.org>
+AES-NI and Padlock assembler code (at lib/accelerated/intel/asm/)
+
 ----------------------------------------------------------------------
 Copying and distribution of this file, with or without modification,
 are permitted in any medium without royalty provided the copyright
index b64c8aa89c0d4d5d419ac96f3d85f12eed989094..ddfdf0c54a957da3d362fbfff6741e46196c8944 100644 (file)
@@ -30,6 +30,7 @@ void _gnutls_register_accel_crypto(void)
 
 #ifdef TRY_X86_OPTIMIZATIONS
   register_x86_crypto ();
+  register_padlock_crypto ();
 #endif
 
   return;
index 40fc5caaa58da56340a455c9c8414c36301d0360..59ea536fef595b3a958ff7135243a5bdf3c5dbf8 100644 (file)
@@ -34,12 +34,12 @@ EXTRA_DIST = aes-x86.h README license.txt
 
 noinst_LTLIBRARIES = libintel.la
 
-libintel_la_SOURCES = aes-x86.c
+libintel_la_SOURCES = aes-x86.c padlock.c
 
 if ASM_X86_64
 AM_CPPFLAGS += -DASM_X86_64
-libintel_la_SOURCES += asm/appro-aes-x86-64.s asm/appro-aes-gcm-x86-64.s aes-gcm-x86.c
+libintel_la_SOURCES += asm/appro-aes-x86-64.s asm/appro-aes-gcm-x86-64.s aes-gcm-x86.c asm/padlock-x86-64.s
 else
-libintel_la_SOURCES += asm/appro-aes-x86.s
+libintel_la_SOURCES += asm/appro-aes-x86.s asm/padlock-x86.s
 endif
 
index cd18dc9b641b60b2ee0a0e5e4aa7cc939a005b2f..4bcc6e163713a51377299957bed0e1deb5c67fc2 100644 (file)
@@ -98,12 +98,12 @@ aes_gcm_cipher_setkey (void *_ctx, const void *userkey, size_t keysize)
   struct aes_gcm_ctx *ctx = _ctx;
   int ret;
 
-  ret = aesni_set_encrypt_key (userkey, keysize * 8, &ctx->expanded_key);
+  ret = aesni_set_encrypt_key (userkey, keysize * 8, ALIGN16(&ctx->expanded_key));
   if (ret != 0)
     return gnutls_assert_val (GNUTLS_E_ENCRYPTION_FAILED);
 
   aesni_ecb_encrypt (ctx->gcm.H.c, ctx->gcm.H.c,
-                     GCM_BLOCK_SIZE, &ctx->expanded_key, 1);
+                     GCM_BLOCK_SIZE, ALIGN16(&ctx->expanded_key), 1);
 
   ctx->gcm.H.u[0] = bswap_64 (ctx->gcm.H.u[0]);
   ctx->gcm.H.u[1] = bswap_64 (ctx->gcm.H.u[1]);
@@ -131,7 +131,7 @@ aes_gcm_setiv (void *_ctx, const void *iv, size_t iv_size)
   ctx->gcm.Yi.c[GCM_BLOCK_SIZE - 1] = 1;
 
   aesni_ecb_encrypt (ctx->gcm.Yi.c, ctx->gcm.EK0.c,
-                     GCM_BLOCK_SIZE, &ctx->expanded_key, 1);
+                     GCM_BLOCK_SIZE, ALIGN16(&ctx->expanded_key), 1);
   ctx->gcm.Yi.c[GCM_BLOCK_SIZE - 1] = 2;
   return 0;
 }
@@ -160,7 +160,7 @@ ctr_encrypt_last (struct aes_gcm_ctx *ctx, const uint8_t * src,
   uint8_t out[GCM_BLOCK_SIZE];
 
   memcpy (tmp, &src[pos], length);
-  aesni_ctr32_encrypt_blocks (tmp, out, 1, &ctx->expanded_key, ctx->gcm.Yi.c);
+  aesni_ctr32_encrypt_blocks (tmp, out, 1, ALIGN16(&ctx->expanded_key), ctx->gcm.Yi.c);
 
   memcpy (&dst[pos], out, length);
 
@@ -179,7 +179,8 @@ aes_gcm_encrypt (void *_ctx, const void *src, size_t src_size,
   if (blocks > 0)
     {
       aesni_ctr32_encrypt_blocks (src, dst,
-                                  blocks, &ctx->expanded_key, ctx->gcm.Yi.c);
+                                  blocks, ALIGN16(&ctx->expanded_key), 
+                                  ctx->gcm.Yi.c);
 
       counter = _gnutls_read_uint32 (ctx->gcm.Yi.c + 12);
       counter += blocks;
@@ -211,7 +212,8 @@ aes_gcm_decrypt (void *_ctx, const void *src, size_t src_size,
   if (blocks > 0)
     {
       aesni_ctr32_encrypt_blocks (src, dst,
-                                  blocks, &ctx->expanded_key, ctx->gcm.Yi.c);
+                                  blocks, ALIGN16(&ctx->expanded_key), 
+                                  ctx->gcm.Yi.c);
 
       counter = _gnutls_read_uint32 (ctx->gcm.Yi.c + 12);
       counter += blocks;
index a45adaf6826444cd1874749cf1f6e672112eb8ee..446e769ee6026fc77ffd7e80f9ee1737df2fa949 100644 (file)
@@ -22,8 +22,7 @@
 
 /*
  * The following code is an implementation of the AES-128-CBC cipher
- * using intel's AES instruction set. It is based on Intel reference
- * code.
+ * using intel's AES instruction set. 
  */
 
 #include <gnutls_errors.h>
index 9764af59a67a3f41b8124f66223d5b2a806daa74..7692ab3372d97b9b6cf8fd294b8f7d9e83e67abb 100644 (file)
@@ -4,6 +4,7 @@
 #include <gnutls_int.h>
 
 void register_x86_crypto (void);
+void register_padlock_crypto(void);
 
 #define ALIGN16(x) \
         ((void *)(((unsigned long)(x)+0x0f)&~(0x0f)))
diff --git a/lib/accelerated/intel/asm/padlock-x86-64.s b/lib/accelerated/intel/asm/padlock-x86-64.s
new file mode 100644 (file)
index 0000000..d026a11
--- /dev/null
@@ -0,0 +1,718 @@
+# Copyright (c) 2011, Andy Polyakov by <appro@openssl.org>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 
+#     * Redistributions of source code must retain copyright notices,
+#      this list of conditions and the following disclaimer.
+#
+#     * Redistributions in binary form must reproduce the above
+#      copyright notice, this list of conditions and the following
+#      disclaimer in the documentation and/or other materials
+#      provided with the distribution.
+#
+#     * Neither the name of the Andy Polyakov nor the names of its
+#      copyright holder and contributors may be used to endorse or
+#      promote products derived from this software without specific
+#      prior written permission.
+#
+# ALTERNATIVELY, provided that this notice is retained in full, this
+# product may be distributed under the terms of the GNU General Public
+# License (GPL), in which case the provisions of the GPL apply INSTEAD OF
+# those given above.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+.text  
+.globl padlock_capability
+.type  padlock_capability,@function
+.align 16
+padlock_capability:
+       movq    %rbx,%r8
+       xorl    %eax,%eax
+       cpuid
+       xorl    %eax,%eax
+       cmpl    $1953391939,%ebx
+       jne     .Lnoluck
+       cmpl    $1215460705,%edx
+       jne     .Lnoluck
+       cmpl    $1936487777,%ecx
+       jne     .Lnoluck
+       movl    $3221225472,%eax
+       cpuid
+       movl    %eax,%edx
+       xorl    %eax,%eax
+       cmpl    $3221225473,%edx
+       jb      .Lnoluck
+       movl    $3221225473,%eax
+       cpuid
+       movl    %edx,%eax
+       andl    $4294967279,%eax
+       orl     $16,%eax
+.Lnoluck:
+       movq    %r8,%rbx
+       .byte   0xf3,0xc3
+.size  padlock_capability,.-padlock_capability
+
+.globl padlock_key_bswap
+.type  padlock_key_bswap,@function
+.align 16
+padlock_key_bswap:
+       movl    240(%rdi),%edx
+.Lbswap_loop:
+       movl    (%rdi),%eax
+       bswapl  %eax
+       movl    %eax,(%rdi)
+       leaq    4(%rdi),%rdi
+       subl    $1,%edx
+       jnz     .Lbswap_loop
+       .byte   0xf3,0xc3
+.size  padlock_key_bswap,.-padlock_key_bswap
+
+.globl padlock_verify_context
+.type  padlock_verify_context,@function
+.align 16
+padlock_verify_context:
+       movq    %rdi,%rdx
+       pushf
+       leaq    .Lpadlock_saved_context(%rip),%rax
+       call    _padlock_verify_ctx
+       leaq    8(%rsp),%rsp
+       .byte   0xf3,0xc3
+.size  padlock_verify_context,.-padlock_verify_context
+
+.type  _padlock_verify_ctx,@function
+.align 16
+_padlock_verify_ctx:
+       movq    8(%rsp),%r8
+       btq     $30,%r8
+       jnc     .Lverified
+       cmpq    (%rax),%rdx
+       je      .Lverified
+       pushf
+       popf
+.Lverified:
+       movq    %rdx,(%rax)
+       .byte   0xf3,0xc3
+.size  _padlock_verify_ctx,.-_padlock_verify_ctx
+
+.globl padlock_reload_key
+.type  padlock_reload_key,@function
+.align 16
+padlock_reload_key:
+       pushf
+       popf
+       .byte   0xf3,0xc3
+.size  padlock_reload_key,.-padlock_reload_key
+
+.globl padlock_aes_block
+.type  padlock_aes_block,@function
+.align 16
+padlock_aes_block:
+       movq    %rbx,%r8
+       movq    $1,%rcx
+       leaq    32(%rdx),%rbx
+       leaq    16(%rdx),%rdx
+.byte  0xf3,0x0f,0xa7,0xc8     
+       movq    %r8,%rbx
+       .byte   0xf3,0xc3
+.size  padlock_aes_block,.-padlock_aes_block
+
+.globl padlock_xstore
+.type  padlock_xstore,@function
+.align 16
+padlock_xstore:
+       movl    %esi,%edx
+.byte  0x0f,0xa7,0xc0          
+       .byte   0xf3,0xc3
+.size  padlock_xstore,.-padlock_xstore
+
+.globl padlock_sha1_oneshot
+.type  padlock_sha1_oneshot,@function
+.align 16
+padlock_sha1_oneshot:
+       xorq    %rax,%rax
+       movq    %rdx,%rcx
+.byte  0xf3,0x0f,0xa6,0xc8     
+       .byte   0xf3,0xc3
+.size  padlock_sha1_oneshot,.-padlock_sha1_oneshot
+
+.globl padlock_sha1
+.type  padlock_sha1,@function
+.align 16
+padlock_sha1:
+       movq    $-1,%rax
+       movq    %rdx,%rcx
+.byte  0xf3,0x0f,0xa6,0xc8     
+       .byte   0xf3,0xc3
+.size  padlock_sha1,.-padlock_sha1
+
+.globl padlock_sha256_oneshot
+.type  padlock_sha256_oneshot,@function
+.align 16
+padlock_sha256_oneshot:
+       xorq    %rax,%rax
+       movq    %rdx,%rcx
+.byte  0xf3,0x0f,0xa6,0xd0     
+       .byte   0xf3,0xc3
+.size  padlock_sha256_oneshot,.-padlock_sha256_oneshot
+
+.globl padlock_sha256
+.type  padlock_sha256,@function
+.align 16
+padlock_sha256:
+       movq    $-1,%rax
+       movq    %rdx,%rcx
+.byte  0xf3,0x0f,0xa6,0xd0     
+       .byte   0xf3,0xc3
+.size  padlock_sha256,.-padlock_sha256
+.globl padlock_ecb_encrypt
+.type  padlock_ecb_encrypt,@function
+.align 16
+padlock_ecb_encrypt:
+       pushq   %rbp
+       pushq   %rbx
+
+       xorl    %eax,%eax
+       testq   $15,%rdx
+       jnz     .Lecb_abort
+       testq   $15,%rcx
+       jnz     .Lecb_abort
+       leaq    .Lpadlock_saved_context(%rip),%rax
+       pushf
+       cld
+       call    _padlock_verify_ctx
+       leaq    16(%rdx),%rdx
+       xorl    %eax,%eax
+       xorl    %ebx,%ebx
+       testl   $32,(%rdx)
+       testq   $15,%rdi
+       setz    %al
+       testq   $15,%rsi
+       setz    %bl
+       testl   %ebx,%eax
+       jnz     .Lecb_aligned
+       negq    %rax
+       movq    $512,%rbx
+       notq    %rax
+       leaq    (%rsp),%rbp
+       cmpq    %rbx,%rcx
+       cmovcq  %rcx,%rbx
+       andq    %rbx,%rax
+       movq    %rcx,%rbx
+       negq    %rax
+       andq    $512-1,%rbx
+       leaq    (%rax,%rbp,1),%rsp
+       jmp     .Lecb_loop
+.align 16
+.Lecb_loop:
+       movq    %rdi,%r8
+       movq    %rsi,%r9
+       movq    %rcx,%r10
+       movq    %rbx,%rcx
+       movq    %rbx,%r11
+       testq   $15,%rdi
+       cmovnzq %rsp,%rdi
+       testq   $15,%rsi
+       jz      .Lecb_inp_aligned
+       shrq    $3,%rcx
+.byte  0xf3,0x48,0xa5          
+       subq    %rbx,%rdi
+       movq    %rbx,%rcx
+       movq    %rdi,%rsi
+.Lecb_inp_aligned:
+       leaq    -16(%rdx),%rax
+       leaq    16(%rdx),%rbx
+       shrq    $4,%rcx
+.byte  0xf3,0x0f,0xa7,200      
+       movq    %r8,%rdi
+       movq    %r11,%rbx
+       testq   $15,%rdi
+       jz      .Lecb_out_aligned
+       movq    %rbx,%rcx
+       shrq    $3,%rcx
+       leaq    (%rsp),%rsi
+.byte  0xf3,0x48,0xa5          
+       subq    %rbx,%rdi
+.Lecb_out_aligned:
+       movq    %r9,%rsi
+       movq    %r10,%rcx
+       addq    %rbx,%rdi
+       addq    %rbx,%rsi
+       subq    %rbx,%rcx
+       movq    $512,%rbx
+       jnz     .Lecb_loop
+
+       testq   $15,%rdi
+       jz      .Lecb_done
+
+       movq    %rbp,%rcx
+       movq    %rsp,%rdi
+       subq    %rsp,%rcx
+       xorq    %rax,%rax
+       shrq    $3,%rcx
+.byte  0xf3,0x48,0xab          
+.Lecb_done:
+       leaq    (%rbp),%rsp
+       jmp     .Lecb_exit
+
+.align 16
+.Lecb_aligned:
+       leaq    -16(%rdx),%rax
+       leaq    16(%rdx),%rbx
+       shrq    $4,%rcx
+.byte  0xf3,0x0f,0xa7,200      
+.Lecb_exit:
+       movl    $1,%eax
+       leaq    8(%rsp),%rsp
+.Lecb_abort:
+       popq    %rbx
+       popq    %rbp
+       .byte   0xf3,0xc3
+.size  padlock_ecb_encrypt,.-padlock_ecb_encrypt
+.globl padlock_cbc_encrypt
+.type  padlock_cbc_encrypt,@function
+.align 16
+padlock_cbc_encrypt:
+       pushq   %rbp
+       pushq   %rbx
+
+       xorl    %eax,%eax
+       testq   $15,%rdx
+       jnz     .Lcbc_abort
+       testq   $15,%rcx
+       jnz     .Lcbc_abort
+       leaq    .Lpadlock_saved_context(%rip),%rax
+       pushf
+       cld
+       call    _padlock_verify_ctx
+       leaq    16(%rdx),%rdx
+       xorl    %eax,%eax
+       xorl    %ebx,%ebx
+       testl   $32,(%rdx)
+       testq   $15,%rdi
+       setz    %al
+       testq   $15,%rsi
+       setz    %bl
+       testl   %ebx,%eax
+       jnz     .Lcbc_aligned
+       negq    %rax
+       movq    $512,%rbx
+       notq    %rax
+       leaq    (%rsp),%rbp
+       cmpq    %rbx,%rcx
+       cmovcq  %rcx,%rbx
+       andq    %rbx,%rax
+       movq    %rcx,%rbx
+       negq    %rax
+       andq    $512-1,%rbx
+       leaq    (%rax,%rbp,1),%rsp
+       jmp     .Lcbc_loop
+.align 16
+.Lcbc_loop:
+       movq    %rdi,%r8
+       movq    %rsi,%r9
+       movq    %rcx,%r10
+       movq    %rbx,%rcx
+       movq    %rbx,%r11
+       testq   $15,%rdi
+       cmovnzq %rsp,%rdi
+       testq   $15,%rsi
+       jz      .Lcbc_inp_aligned
+       shrq    $3,%rcx
+.byte  0xf3,0x48,0xa5          
+       subq    %rbx,%rdi
+       movq    %rbx,%rcx
+       movq    %rdi,%rsi
+.Lcbc_inp_aligned:
+       leaq    -16(%rdx),%rax
+       leaq    16(%rdx),%rbx
+       shrq    $4,%rcx
+.byte  0xf3,0x0f,0xa7,208      
+       movdqa  (%rax),%xmm0
+       movdqa  %xmm0,-16(%rdx)
+       movq    %r8,%rdi
+       movq    %r11,%rbx
+       testq   $15,%rdi
+       jz      .Lcbc_out_aligned
+       movq    %rbx,%rcx
+       shrq    $3,%rcx
+       leaq    (%rsp),%rsi
+.byte  0xf3,0x48,0xa5          
+       subq    %rbx,%rdi
+.Lcbc_out_aligned:
+       movq    %r9,%rsi
+       movq    %r10,%rcx
+       addq    %rbx,%rdi
+       addq    %rbx,%rsi
+       subq    %rbx,%rcx
+       movq    $512,%rbx
+       jnz     .Lcbc_loop
+
+       testq   $15,%rdi
+       jz      .Lcbc_done
+
+       movq    %rbp,%rcx
+       movq    %rsp,%rdi
+       subq    %rsp,%rcx
+       xorq    %rax,%rax
+       shrq    $3,%rcx
+.byte  0xf3,0x48,0xab          
+.Lcbc_done:
+       leaq    (%rbp),%rsp
+       jmp     .Lcbc_exit
+
+.align 16
+.Lcbc_aligned:
+       leaq    -16(%rdx),%rax
+       leaq    16(%rdx),%rbx
+       shrq    $4,%rcx
+.byte  0xf3,0x0f,0xa7,208      
+       movdqa  (%rax),%xmm0
+       movdqa  %xmm0,-16(%rdx)
+.Lcbc_exit:
+       movl    $1,%eax
+       leaq    8(%rsp),%rsp
+.Lcbc_abort:
+       popq    %rbx
+       popq    %rbp
+       .byte   0xf3,0xc3
+.size  padlock_cbc_encrypt,.-padlock_cbc_encrypt
+.globl padlock_cfb_encrypt
+.type  padlock_cfb_encrypt,@function
+.align 16
+padlock_cfb_encrypt:
+       pushq   %rbp
+       pushq   %rbx
+
+       xorl    %eax,%eax
+       testq   $15,%rdx
+       jnz     .Lcfb_abort
+       testq   $15,%rcx
+       jnz     .Lcfb_abort
+       leaq    .Lpadlock_saved_context(%rip),%rax
+       pushf
+       cld
+       call    _padlock_verify_ctx
+       leaq    16(%rdx),%rdx
+       xorl    %eax,%eax
+       xorl    %ebx,%ebx
+       testl   $32,(%rdx)
+       testq   $15,%rdi
+       setz    %al
+       testq   $15,%rsi
+       setz    %bl
+       testl   %ebx,%eax
+       jnz     .Lcfb_aligned
+       negq    %rax
+       movq    $512,%rbx
+       notq    %rax
+       leaq    (%rsp),%rbp
+       cmpq    %rbx,%rcx
+       cmovcq  %rcx,%rbx
+       andq    %rbx,%rax
+       movq    %rcx,%rbx
+       negq    %rax
+       andq    $512-1,%rbx
+       leaq    (%rax,%rbp,1),%rsp
+       jmp     .Lcfb_loop
+.align 16
+.Lcfb_loop:
+       movq    %rdi,%r8
+       movq    %rsi,%r9
+       movq    %rcx,%r10
+       movq    %rbx,%rcx
+       movq    %rbx,%r11
+       testq   $15,%rdi
+       cmovnzq %rsp,%rdi
+       testq   $15,%rsi
+       jz      .Lcfb_inp_aligned
+       shrq    $3,%rcx
+.byte  0xf3,0x48,0xa5          
+       subq    %rbx,%rdi
+       movq    %rbx,%rcx
+       movq    %rdi,%rsi
+.Lcfb_inp_aligned:
+       leaq    -16(%rdx),%rax
+       leaq    16(%rdx),%rbx
+       shrq    $4,%rcx
+.byte  0xf3,0x0f,0xa7,224      
+       movdqa  (%rax),%xmm0
+       movdqa  %xmm0,-16(%rdx)
+       movq    %r8,%rdi
+       movq    %r11,%rbx
+       testq   $15,%rdi
+       jz      .Lcfb_out_aligned
+       movq    %rbx,%rcx
+       shrq    $3,%rcx
+       leaq    (%rsp),%rsi
+.byte  0xf3,0x48,0xa5          
+       subq    %rbx,%rdi
+.Lcfb_out_aligned:
+       movq    %r9,%rsi
+       movq    %r10,%rcx
+       addq    %rbx,%rdi
+       addq    %rbx,%rsi
+       subq    %rbx,%rcx
+       movq    $512,%rbx
+       jnz     .Lcfb_loop
+
+       testq   $15,%rdi
+       jz      .Lcfb_done
+
+       movq    %rbp,%rcx
+       movq    %rsp,%rdi
+       subq    %rsp,%rcx
+       xorq    %rax,%rax
+       shrq    $3,%rcx
+.byte  0xf3,0x48,0xab          
+.Lcfb_done:
+       leaq    (%rbp),%rsp
+       jmp     .Lcfb_exit
+
+.align 16
+.Lcfb_aligned:
+       leaq    -16(%rdx),%rax
+       leaq    16(%rdx),%rbx
+       shrq    $4,%rcx
+.byte  0xf3,0x0f,0xa7,224      
+       movdqa  (%rax),%xmm0
+       movdqa  %xmm0,-16(%rdx)
+.Lcfb_exit:
+       movl    $1,%eax
+       leaq    8(%rsp),%rsp
+.Lcfb_abort:
+       popq    %rbx
+       popq    %rbp
+       .byte   0xf3,0xc3
+.size  padlock_cfb_encrypt,.-padlock_cfb_encrypt
+.globl padlock_ofb_encrypt
+.type  padlock_ofb_encrypt,@function
+.align 16
+padlock_ofb_encrypt:
+       pushq   %rbp
+       pushq   %rbx
+
+       xorl    %eax,%eax
+       testq   $15,%rdx
+       jnz     .Lofb_abort
+       testq   $15,%rcx
+       jnz     .Lofb_abort
+       leaq    .Lpadlock_saved_context(%rip),%rax
+       pushf
+       cld
+       call    _padlock_verify_ctx
+       leaq    16(%rdx),%rdx
+       xorl    %eax,%eax
+       xorl    %ebx,%ebx
+       testl   $32,(%rdx)
+       testq   $15,%rdi
+       setz    %al
+       testq   $15,%rsi
+       setz    %bl
+       testl   %ebx,%eax
+       jnz     .Lofb_aligned
+       negq    %rax
+       movq    $512,%rbx
+       notq    %rax
+       leaq    (%rsp),%rbp
+       cmpq    %rbx,%rcx
+       cmovcq  %rcx,%rbx
+       andq    %rbx,%rax
+       movq    %rcx,%rbx
+       negq    %rax
+       andq    $512-1,%rbx
+       leaq    (%rax,%rbp,1),%rsp
+       jmp     .Lofb_loop
+.align 16
+.Lofb_loop:
+       movq    %rdi,%r8
+       movq    %rsi,%r9
+       movq    %rcx,%r10
+       movq    %rbx,%rcx
+       movq    %rbx,%r11
+       testq   $15,%rdi
+       cmovnzq %rsp,%rdi
+       testq   $15,%rsi
+       jz      .Lofb_inp_aligned
+       shrq    $3,%rcx
+.byte  0xf3,0x48,0xa5          
+       subq    %rbx,%rdi
+       movq    %rbx,%rcx
+       movq    %rdi,%rsi
+.Lofb_inp_aligned:
+       leaq    -16(%rdx),%rax
+       leaq    16(%rdx),%rbx
+       shrq    $4,%rcx
+.byte  0xf3,0x0f,0xa7,232      
+       movdqa  (%rax),%xmm0
+       movdqa  %xmm0,-16(%rdx)
+       movq    %r8,%rdi
+       movq    %r11,%rbx
+       testq   $15,%rdi
+       jz      .Lofb_out_aligned
+       movq    %rbx,%rcx
+       shrq    $3,%rcx
+       leaq    (%rsp),%rsi
+.byte  0xf3,0x48,0xa5          
+       subq    %rbx,%rdi
+.Lofb_out_aligned:
+       movq    %r9,%rsi
+       movq    %r10,%rcx
+       addq    %rbx,%rdi
+       addq    %rbx,%rsi
+       subq    %rbx,%rcx
+       movq    $512,%rbx
+       jnz     .Lofb_loop
+
+       testq   $15,%rdi
+       jz      .Lofb_done
+
+       movq    %rbp,%rcx
+       movq    %rsp,%rdi
+       subq    %rsp,%rcx
+       xorq    %rax,%rax
+       shrq    $3,%rcx
+.byte  0xf3,0x48,0xab          
+.Lofb_done:
+       leaq    (%rbp),%rsp
+       jmp     .Lofb_exit
+
+.align 16
+.Lofb_aligned:
+       leaq    -16(%rdx),%rax
+       leaq    16(%rdx),%rbx
+       shrq    $4,%rcx
+.byte  0xf3,0x0f,0xa7,232      
+       movdqa  (%rax),%xmm0
+       movdqa  %xmm0,-16(%rdx)
+.Lofb_exit:
+       movl    $1,%eax
+       leaq    8(%rsp),%rsp
+.Lofb_abort:
+       popq    %rbx
+       popq    %rbp
+       .byte   0xf3,0xc3
+.size  padlock_ofb_encrypt,.-padlock_ofb_encrypt
+.globl padlock_ctr16_encrypt
+.type  padlock_ctr16_encrypt,@function
+.align 16
+padlock_ctr16_encrypt:
+       pushq   %rbp
+       pushq   %rbx
+
+       xorl    %eax,%eax
+       testq   $15,%rdx
+       jnz     .Lctr16_abort
+       testq   $15,%rcx
+       jnz     .Lctr16_abort
+       leaq    .Lpadlock_saved_context(%rip),%rax
+       pushf
+       cld
+       call    _padlock_verify_ctx
+       leaq    16(%rdx),%rdx
+       xorl    %eax,%eax
+       xorl    %ebx,%ebx
+       testl   $32,(%rdx)
+       testq   $15,%rdi
+       setz    %al
+       testq   $15,%rsi
+       setz    %bl
+       testl   %ebx,%eax
+       jnz     .Lctr16_aligned
+       negq    %rax
+       movq    $512,%rbx
+       notq    %rax
+       leaq    (%rsp),%rbp
+       cmpq    %rbx,%rcx
+       cmovcq  %rcx,%rbx
+       andq    %rbx,%rax
+       movq    %rcx,%rbx
+       negq    %rax
+       andq    $512-1,%rbx
+       leaq    (%rax,%rbp,1),%rsp
+       jmp     .Lctr16_loop
+.align 16
+.Lctr16_loop:
+       movq    %rdi,%r8
+       movq    %rsi,%r9
+       movq    %rcx,%r10
+       movq    %rbx,%rcx
+       movq    %rbx,%r11
+       testq   $15,%rdi
+       cmovnzq %rsp,%rdi
+       testq   $15,%rsi
+       jz      .Lctr16_inp_aligned
+       shrq    $3,%rcx
+.byte  0xf3,0x48,0xa5          
+       subq    %rbx,%rdi
+       movq    %rbx,%rcx
+       movq    %rdi,%rsi
+.Lctr16_inp_aligned:
+       leaq    -16(%rdx),%rax
+       leaq    16(%rdx),%rbx
+       shrq    $4,%rcx
+.byte  0xf3,0x0f,0xa7,216      
+       movq    %r8,%rdi
+       movq    %r11,%rbx
+       testq   $15,%rdi
+       jz      .Lctr16_out_aligned
+       movq    %rbx,%rcx
+       shrq    $3,%rcx
+       leaq    (%rsp),%rsi
+.byte  0xf3,0x48,0xa5          
+       subq    %rbx,%rdi
+.Lctr16_out_aligned:
+       movq    %r9,%rsi
+       movq    %r10,%rcx
+       addq    %rbx,%rdi
+       addq    %rbx,%rsi
+       subq    %rbx,%rcx
+       movq    $512,%rbx
+       jnz     .Lctr16_loop
+
+       testq   $15,%rdi
+       jz      .Lctr16_done
+
+       movq    %rbp,%rcx
+       movq    %rsp,%rdi
+       subq    %rsp,%rcx
+       xorq    %rax,%rax
+       shrq    $3,%rcx
+.byte  0xf3,0x48,0xab          
+.Lctr16_done:
+       leaq    (%rbp),%rsp
+       jmp     .Lctr16_exit
+
+.align 16
+.Lctr16_aligned:
+       leaq    -16(%rdx),%rax
+       leaq    16(%rdx),%rbx
+       shrq    $4,%rcx
+.byte  0xf3,0x0f,0xa7,216      
+.Lctr16_exit:
+       movl    $1,%eax
+       leaq    8(%rsp),%rsp
+.Lctr16_abort:
+       popq    %rbx
+       popq    %rbp
+       .byte   0xf3,0xc3
+.size  padlock_ctr16_encrypt,.-padlock_ctr16_encrypt
+.byte  86,73,65,32,80,97,100,108,111,99,107,32,120,56,54,95,54,52,32,109,111,100,117,108,101,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.align 16
+.data  
+.align 8
+.Lpadlock_saved_context:
+.quad  0
diff --git a/lib/accelerated/intel/asm/padlock-x86.s b/lib/accelerated/intel/asm/padlock-x86.s
new file mode 100644 (file)
index 0000000..17d383d
--- /dev/null
@@ -0,0 +1,817 @@
+# Copyright (c) 2011, Andy Polyakov by <appro@openssl.org>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 
+#     * Redistributions of source code must retain copyright notices,
+#      this list of conditions and the following disclaimer.
+#
+#     * Redistributions in binary form must reproduce the above
+#      copyright notice, this list of conditions and the following
+#      disclaimer in the documentation and/or other materials
+#      provided with the distribution.
+#
+#     * Neither the name of the Andy Polyakov nor the names of its
+#      copyright holder and contributors may be used to endorse or
+#      promote products derived from this software without specific
+#      prior written permission.
+#
+# ALTERNATIVELY, provided that this notice is retained in full, this
+# product may be distributed under the terms of the GNU General Public
+# License (GPL), in which case the provisions of the GPL apply INSTEAD OF
+# those given above.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+.file  "e_padlock-x86.s"
+.text
+.globl padlock_capability
+.type  padlock_capability,@function
+.align 16
+padlock_capability:
+.L_padlock_capability_begin:
+       pushl   %ebx
+       pushfl
+       popl    %eax
+       movl    %eax,%ecx
+       xorl    $2097152,%eax
+       pushl   %eax
+       popfl
+       pushfl
+       popl    %eax
+       xorl    %eax,%ecx
+       xorl    %eax,%eax
+       btl     $21,%ecx
+       jnc     .L000noluck
+       .byte   0x0f,0xa2
+       xorl    %eax,%eax
+       cmpl    $0x746e6543,%ebx
+       jne     .L000noluck
+       cmpl    $0x48727561,%edx
+       jne     .L000noluck
+       cmpl    $0x736c7561,%ecx
+       jne     .L000noluck
+       movl    $3221225472,%eax
+       .byte   0x0f,0xa2
+       movl    %eax,%edx
+       xorl    %eax,%eax
+       cmpl    $3221225473,%edx
+       jb      .L000noluck
+       movl    $1,%eax
+       .byte   0x0f,0xa2
+       orl     $15,%eax
+       xorl    %ebx,%ebx
+       andl    $4095,%eax
+       cmpl    $1791,%eax
+       sete    %bl
+       movl    $3221225473,%eax
+       pushl   %ebx
+       .byte   0x0f,0xa2
+       popl    %ebx
+       movl    %edx,%eax
+       shll    $4,%ebx
+       andl    $4294967279,%eax
+       orl     %ebx,%eax
+.L000noluck:
+       popl    %ebx
+       ret
+.size  padlock_capability,.-.L_padlock_capability_begin
+.globl padlock_key_bswap
+.type  padlock_key_bswap,@function
+.align 16
+padlock_key_bswap:
+.L_padlock_key_bswap_begin:
+       movl    4(%esp),%edx
+       movl    240(%edx),%ecx
+.L001bswap_loop:
+       movl    (%edx),%eax
+       bswap   %eax
+       movl    %eax,(%edx)
+       leal    4(%edx),%edx
+       subl    $1,%ecx
+       jnz     .L001bswap_loop
+       ret
+.size  padlock_key_bswap,.-.L_padlock_key_bswap_begin
+.globl padlock_verify_context
+.type  padlock_verify_context,@function
+.align 16
+padlock_verify_context:
+.L_padlock_verify_context_begin:
+       movl    4(%esp),%edx
+       leal    .Lpadlock_saved_context-.L002verify_pic_point,%eax
+       pushfl
+       call    _padlock_verify_ctx
+.L002verify_pic_point:
+       leal    4(%esp),%esp
+       ret
+.size  padlock_verify_context,.-.L_padlock_verify_context_begin
+.type  _padlock_verify_ctx,@function
+.align 16
+_padlock_verify_ctx:
+       addl    (%esp),%eax
+       btl     $30,4(%esp)
+       jnc     .L003verified
+       cmpl    (%eax),%edx
+       je      .L003verified
+       pushfl
+       popfl
+.L003verified:
+       movl    %edx,(%eax)
+       ret
+.size  _padlock_verify_ctx,.-_padlock_verify_ctx
+.globl padlock_reload_key
+.type  padlock_reload_key,@function
+.align 16
+padlock_reload_key:
+.L_padlock_reload_key_begin:
+       pushfl
+       popfl
+       ret
+.size  padlock_reload_key,.-.L_padlock_reload_key_begin
+.globl padlock_aes_block
+.type  padlock_aes_block,@function
+.align 16
+padlock_aes_block:
+.L_padlock_aes_block_begin:
+       pushl   %edi
+       pushl   %esi
+       pushl   %ebx
+       movl    16(%esp),%edi
+       movl    20(%esp),%esi
+       movl    24(%esp),%edx
+       movl    $1,%ecx
+       leal    32(%edx),%ebx
+       leal    16(%edx),%edx
+.byte  243,15,167,200
+       popl    %ebx
+       popl    %esi
+       popl    %edi
+       ret
+.size  padlock_aes_block,.-.L_padlock_aes_block_begin
+.globl padlock_ecb_encrypt
+.type  padlock_ecb_encrypt,@function
+.align 16
+padlock_ecb_encrypt:
+.L_padlock_ecb_encrypt_begin:
+       pushl   %ebp
+       pushl   %ebx
+       pushl   %esi
+       pushl   %edi
+       movl    20(%esp),%edi
+       movl    24(%esp),%esi
+       movl    28(%esp),%edx
+       movl    32(%esp),%ecx
+       testl   $15,%edx
+       jnz     .L004ecb_abort
+       testl   $15,%ecx
+       jnz     .L004ecb_abort
+       leal    .Lpadlock_saved_context-.L005ecb_pic_point,%eax
+       pushfl
+       cld
+       call    _padlock_verify_ctx
+.L005ecb_pic_point:
+       leal    16(%edx),%edx
+       xorl    %eax,%eax
+       xorl    %ebx,%ebx
+       testl   $32,(%edx)
+       jnz     .L006ecb_aligned
+       testl   $15,%edi
+       setz    %al
+       testl   $15,%esi
+       setz    %bl
+       testl   %ebx,%eax
+       jnz     .L006ecb_aligned
+       negl    %eax
+       movl    $512,%ebx
+       notl    %eax
+       leal    -24(%esp),%ebp
+       cmpl    %ebx,%ecx
+       cmovcl  %ecx,%ebx
+       andl    %ebx,%eax
+       movl    %ecx,%ebx
+       negl    %eax
+       andl    $511,%ebx
+       leal    (%eax,%ebp,1),%esp
+       andl    $-16,%esp
+       jmp     .L007ecb_loop
+.align 16
+.L007ecb_loop:
+       movl    %edi,(%ebp)
+       movl    %esi,4(%ebp)
+       movl    %ecx,8(%ebp)
+       movl    %ebx,%ecx
+       movl    %ebx,12(%ebp)
+       testl   $15,%edi
+       cmovnzl %esp,%edi
+       testl   $15,%esi
+       jz      .L008ecb_inp_aligned
+       shrl    $2,%ecx
+.byte  243,165
+       subl    %ebx,%edi
+       movl    %ebx,%ecx
+       movl    %edi,%esi
+.L008ecb_inp_aligned:
+       leal    -16(%edx),%eax
+       leal    16(%edx),%ebx
+       shrl    $4,%ecx
+.byte  243,15,167,200
+       movl    (%ebp),%edi
+       movl    12(%ebp),%ebx
+       testl   $15,%edi
+       jz      .L009ecb_out_aligned
+       movl    %ebx,%ecx
+       shrl    $2,%ecx
+       leal    (%esp),%esi
+.byte  243,165
+       subl    %ebx,%edi
+.L009ecb_out_aligned:
+       movl    4(%ebp),%esi
+       movl    8(%ebp),%ecx
+       addl    %ebx,%edi
+       addl    %ebx,%esi
+       subl    %ebx,%ecx
+       movl    $512,%ebx
+       jnz     .L007ecb_loop
+       testl   $15,%edi
+       jz      .L010ecb_done
+       movl    %ebp,%ecx
+       movl    %esp,%edi
+       subl    %esp,%ecx
+       xorl    %eax,%eax
+       shrl    $2,%ecx
+.byte  243,171
+.L010ecb_done:
+       leal    24(%ebp),%esp
+       jmp     .L011ecb_exit
+.align 16
+.L006ecb_aligned:
+       leal    -16(%edx),%eax
+       leal    16(%edx),%ebx
+       shrl    $4,%ecx
+.byte  243,15,167,200
+.L011ecb_exit:
+       movl    $1,%eax
+       leal    4(%esp),%esp
+.L004ecb_abort:
+       popl    %edi
+       popl    %esi
+       popl    %ebx
+       popl    %ebp
+       ret
+.size  padlock_ecb_encrypt,.-.L_padlock_ecb_encrypt_begin
+.globl padlock_cbc_encrypt
+.type  padlock_cbc_encrypt,@function
+.align 16
+padlock_cbc_encrypt:
+.L_padlock_cbc_encrypt_begin:
+       pushl   %ebp
+       pushl   %ebx
+       pushl   %esi
+       pushl   %edi
+       movl    20(%esp),%edi
+       movl    24(%esp),%esi
+       movl    28(%esp),%edx
+       movl    32(%esp),%ecx
+       testl   $15,%edx
+       jnz     .L012cbc_abort
+       testl   $15,%ecx
+       jnz     .L012cbc_abort
+       leal    .Lpadlock_saved_context-.L013cbc_pic_point,%eax
+       pushfl
+       cld
+       call    _padlock_verify_ctx
+.L013cbc_pic_point:
+       leal    16(%edx),%edx
+       xorl    %eax,%eax
+       xorl    %ebx,%ebx
+       testl   $32,(%edx)
+       jnz     .L014cbc_aligned
+       testl   $15,%edi
+       setz    %al
+       testl   $15,%esi
+       setz    %bl
+       testl   %ebx,%eax
+       jnz     .L014cbc_aligned
+       negl    %eax
+       movl    $512,%ebx
+       notl    %eax
+       leal    -24(%esp),%ebp
+       cmpl    %ebx,%ecx
+       cmovcl  %ecx,%ebx
+       andl    %ebx,%eax
+       movl    %ecx,%ebx
+       negl    %eax
+       andl    $511,%ebx
+       leal    (%eax,%ebp,1),%esp
+       andl    $-16,%esp
+       jmp     .L015cbc_loop
+.align 16
+.L015cbc_loop:
+       movl    %edi,(%ebp)
+       movl    %esi,4(%ebp)
+       movl    %ecx,8(%ebp)
+       movl    %ebx,%ecx
+       movl    %ebx,12(%ebp)
+       testl   $15,%edi
+       cmovnzl %esp,%edi
+       testl   $15,%esi
+       jz      .L016cbc_inp_aligned
+       shrl    $2,%ecx
+.byte  243,165
+       subl    %ebx,%edi
+       movl    %ebx,%ecx
+       movl    %edi,%esi
+.L016cbc_inp_aligned:
+       leal    -16(%edx),%eax
+       leal    16(%edx),%ebx
+       shrl    $4,%ecx
+.byte  243,15,167,208
+       movdqa  (%eax),%xmm0
+       movdqa  %xmm0,-16(%edx)
+       movl    (%ebp),%edi
+       movl    12(%ebp),%ebx
+       testl   $15,%edi
+       jz      .L017cbc_out_aligned
+       movl    %ebx,%ecx
+       shrl    $2,%ecx
+       leal    (%esp),%esi
+.byte  243,165
+       subl    %ebx,%edi
+.L017cbc_out_aligned:
+       movl    4(%ebp),%esi
+       movl    8(%ebp),%ecx
+       addl    %ebx,%edi
+       addl    %ebx,%esi
+       subl    %ebx,%ecx
+       movl    $512,%ebx
+       jnz     .L015cbc_loop
+       testl   $15,%edi
+       jz      .L018cbc_done
+       movl    %ebp,%ecx
+       movl    %esp,%edi
+       subl    %esp,%ecx
+       xorl    %eax,%eax
+       shrl    $2,%ecx
+.byte  243,171
+.L018cbc_done:
+       leal    24(%ebp),%esp
+       jmp     .L019cbc_exit
+.align 16
+.L014cbc_aligned:
+       leal    -16(%edx),%eax
+       leal    16(%edx),%ebx
+       shrl    $4,%ecx
+.byte  243,15,167,208
+       movdqa  (%eax),%xmm0
+       movdqa  %xmm0,-16(%edx)
+.L019cbc_exit:
+       movl    $1,%eax
+       leal    4(%esp),%esp
+.L012cbc_abort:
+       popl    %edi
+       popl    %esi
+       popl    %ebx
+       popl    %ebp
+       ret
+.size  padlock_cbc_encrypt,.-.L_padlock_cbc_encrypt_begin
+.globl padlock_cfb_encrypt
+.type  padlock_cfb_encrypt,@function
+.align 16
+padlock_cfb_encrypt:
+.L_padlock_cfb_encrypt_begin:
+       pushl   %ebp
+       pushl   %ebx
+       pushl   %esi
+       pushl   %edi
+       movl    20(%esp),%edi
+       movl    24(%esp),%esi
+       movl    28(%esp),%edx
+       movl    32(%esp),%ecx
+       testl   $15,%edx
+       jnz     .L020cfb_abort
+       testl   $15,%ecx
+       jnz     .L020cfb_abort
+       leal    .Lpadlock_saved_context-.L021cfb_pic_point,%eax
+       pushfl
+       cld
+       call    _padlock_verify_ctx
+.L021cfb_pic_point:
+       leal    16(%edx),%edx
+       xorl    %eax,%eax
+       xorl    %ebx,%ebx
+       testl   $32,(%edx)
+       jnz     .L022cfb_aligned
+       testl   $15,%edi
+       setz    %al
+       testl   $15,%esi
+       setz    %bl
+       testl   %ebx,%eax
+       jnz     .L022cfb_aligned
+       negl    %eax
+       movl    $512,%ebx
+       notl    %eax
+       leal    -24(%esp),%ebp
+       cmpl    %ebx,%ecx
+       cmovcl  %ecx,%ebx
+       andl    %ebx,%eax
+       movl    %ecx,%ebx
+       negl    %eax
+       andl    $511,%ebx
+       leal    (%eax,%ebp,1),%esp
+       andl    $-16,%esp
+       jmp     .L023cfb_loop
+.align 16
+.L023cfb_loop:
+       movl    %edi,(%ebp)
+       movl    %esi,4(%ebp)
+       movl    %ecx,8(%ebp)
+       movl    %ebx,%ecx
+       movl    %ebx,12(%ebp)
+       testl   $15,%edi
+       cmovnzl %esp,%edi
+       testl   $15,%esi
+       jz      .L024cfb_inp_aligned
+       shrl    $2,%ecx
+.byte  243,165
+       subl    %ebx,%edi
+       movl    %ebx,%ecx
+       movl    %edi,%esi
+.L024cfb_inp_aligned:
+       leal    -16(%edx),%eax
+       leal    16(%edx),%ebx
+       shrl    $4,%ecx
+.byte  243,15,167,224
+       movdqa  (%eax),%xmm0
+       movdqa  %xmm0,-16(%edx)
+       movl    (%ebp),%edi
+       movl    12(%ebp),%ebx
+       testl   $15,%edi
+       jz      .L025cfb_out_aligned
+       movl    %ebx,%ecx
+       shrl    $2,%ecx
+       leal    (%esp),%esi
+.byte  243,165
+       subl    %ebx,%edi
+.L025cfb_out_aligned:
+       movl    4(%ebp),%esi
+       movl    8(%ebp),%ecx
+       addl    %ebx,%edi
+       addl    %ebx,%esi
+       subl    %ebx,%ecx
+       movl    $512,%ebx
+       jnz     .L023cfb_loop
+       testl   $15,%edi
+       jz      .L026cfb_done
+       movl    %ebp,%ecx
+       movl    %esp,%edi
+       subl    %esp,%ecx
+       xorl    %eax,%eax
+       shrl    $2,%ecx
+.byte  243,171
+.L026cfb_done:
+       leal    24(%ebp),%esp
+       jmp     .L027cfb_exit
+.align 16
+.L022cfb_aligned:
+       leal    -16(%edx),%eax
+       leal    16(%edx),%ebx
+       shrl    $4,%ecx
+.byte  243,15,167,224
+       movdqa  (%eax),%xmm0
+       movdqa  %xmm0,-16(%edx)
+.L027cfb_exit:
+       movl    $1,%eax
+       leal    4(%esp),%esp
+.L020cfb_abort:
+       popl    %edi
+       popl    %esi
+       popl    %ebx
+       popl    %ebp
+       ret
+.size  padlock_cfb_encrypt,.-.L_padlock_cfb_encrypt_begin
+.globl padlock_ofb_encrypt
+.type  padlock_ofb_encrypt,@function
+.align 16
+padlock_ofb_encrypt:
+.L_padlock_ofb_encrypt_begin:
+       pushl   %ebp
+       pushl   %ebx
+       pushl   %esi
+       pushl   %edi
+       movl    20(%esp),%edi
+       movl    24(%esp),%esi
+       movl    28(%esp),%edx
+       movl    32(%esp),%ecx
+       testl   $15,%edx
+       jnz     .L028ofb_abort
+       testl   $15,%ecx
+       jnz     .L028ofb_abort
+       leal    .Lpadlock_saved_context-.L029ofb_pic_point,%eax
+       pushfl
+       cld
+       call    _padlock_verify_ctx
+.L029ofb_pic_point:
+       leal    16(%edx),%edx
+       xorl    %eax,%eax
+       xorl    %ebx,%ebx
+       testl   $32,(%edx)
+       jnz     .L030ofb_aligned
+       testl   $15,%edi
+       setz    %al
+       testl   $15,%esi
+       setz    %bl
+       testl   %ebx,%eax
+       jnz     .L030ofb_aligned
+       negl    %eax
+       movl    $512,%ebx
+       notl    %eax
+       leal    -24(%esp),%ebp
+       cmpl    %ebx,%ecx
+       cmovcl  %ecx,%ebx
+       andl    %ebx,%eax
+       movl    %ecx,%ebx
+       negl    %eax
+       andl    $511,%ebx
+       leal    (%eax,%ebp,1),%esp
+       andl    $-16,%esp
+       jmp     .L031ofb_loop
+.align 16
+.L031ofb_loop:
+       movl    %edi,(%ebp)
+       movl    %esi,4(%ebp)
+       movl    %ecx,8(%ebp)
+       movl    %ebx,%ecx
+       movl    %ebx,12(%ebp)
+       testl   $15,%edi
+       cmovnzl %esp,%edi
+       testl   $15,%esi
+       jz      .L032ofb_inp_aligned
+       shrl    $2,%ecx
+.byte  243,165
+       subl    %ebx,%edi
+       movl    %ebx,%ecx
+       movl    %edi,%esi
+.L032ofb_inp_aligned:
+       leal    -16(%edx),%eax
+       leal    16(%edx),%ebx
+       shrl    $4,%ecx
+.byte  243,15,167,232
+       movdqa  (%eax),%xmm0
+       movdqa  %xmm0,-16(%edx)
+       movl    (%ebp),%edi
+       movl    12(%ebp),%ebx
+       testl   $15,%edi
+       jz      .L033ofb_out_aligned
+       movl    %ebx,%ecx
+       shrl    $2,%ecx
+       leal    (%esp),%esi
+.byte  243,165
+       subl    %ebx,%edi
+.L033ofb_out_aligned:
+       movl    4(%ebp),%esi
+       movl    8(%ebp),%ecx
+       addl    %ebx,%edi
+       addl    %ebx,%esi
+       subl    %ebx,%ecx
+       movl    $512,%ebx
+       jnz     .L031ofb_loop
+       testl   $15,%edi
+       jz      .L034ofb_done
+       movl    %ebp,%ecx
+       movl    %esp,%edi
+       subl    %esp,%ecx
+       xorl    %eax,%eax
+       shrl    $2,%ecx
+.byte  243,171
+.L034ofb_done:
+       leal    24(%ebp),%esp
+       jmp     .L035ofb_exit
+.align 16
+.L030ofb_aligned:
+       leal    -16(%edx),%eax
+       leal    16(%edx),%ebx
+       shrl    $4,%ecx
+.byte  243,15,167,232
+       movdqa  (%eax),%xmm0
+       movdqa  %xmm0,-16(%edx)
+.L035ofb_exit:
+       movl    $1,%eax
+       leal    4(%esp),%esp
+.L028ofb_abort:
+       popl    %edi
+       popl    %esi
+       popl    %ebx
+       popl    %ebp
+       ret
+.size  padlock_ofb_encrypt,.-.L_padlock_ofb_encrypt_begin
+.globl padlock_ctr16_encrypt
+.type  padlock_ctr16_encrypt,@function
+.align 16
+padlock_ctr16_encrypt:
+.L_padlock_ctr16_encrypt_begin:
+       pushl   %ebp
+       pushl   %ebx
+       pushl   %esi
+       pushl   %edi
+       movl    20(%esp),%edi
+       movl    24(%esp),%esi
+       movl    28(%esp),%edx
+       movl    32(%esp),%ecx
+       testl   $15,%edx
+       jnz     .L036ctr16_abort
+       testl   $15,%ecx
+       jnz     .L036ctr16_abort
+       leal    .Lpadlock_saved_context-.L037ctr16_pic_point,%eax
+       pushfl
+       cld
+       call    _padlock_verify_ctx
+.L037ctr16_pic_point:
+       leal    16(%edx),%edx
+       xorl    %eax,%eax
+       movdqa  -16(%edx),%xmm0
+       movl    $512,%ebx
+       notl    %eax
+       leal    -24(%esp),%ebp
+       cmpl    %ebx,%ecx
+       cmovcl  %ecx,%ebx
+       andl    %ebx,%eax
+       movl    %ecx,%ebx
+       negl    %eax
+       andl    $511,%ebx
+       leal    (%eax,%ebp,1),%esp
+       andl    $-16,%esp
+       jmp     .L038ctr16_loop
+.align 16
+.L038ctr16_loop:
+       movl    %edi,(%ebp)
+       movl    %esi,4(%ebp)
+       movl    %ecx,8(%ebp)
+       movl    %ebx,%ecx
+       movl    %ebx,12(%ebp)
+       pextrw  $7,%xmm0,%ecx
+       movl    $1,%esi
+       xorl    %edi,%edi
+       xchgb   %cl,%ch
+.L039ctr16_prepare:
+       movdqa  %xmm0,(%esp,%edi,1)
+       leal    (%ecx,%esi,1),%eax
+       xchgb   %al,%ah
+       leal    16(%edi),%edi
+       pinsrw  $7,%eax,%xmm0
+       leal    1(%esi),%esi
+       cmpl    %ebx,%edi
+       jb      .L039ctr16_prepare
+       leal    (%esp),%esi
+       leal    (%esp),%edi
+       movl    %ebx,%ecx
+       leal    -16(%edx),%eax
+       leal    16(%edx),%ebx
+       shrl    $4,%ecx
+.byte  243,15,167,200
+       movl    (%ebp),%edi
+       movl    12(%ebp),%ebx
+       movl    4(%ebp),%esi
+       xorl    %ecx,%ecx
+.L040ctr16_xor:
+       movdqu  (%esi,%ecx,1),%xmm1
+       leal    16(%ecx),%ecx
+       pxor    -16(%esp,%ecx,1),%xmm1
+       movdqu  %xmm1,-16(%edi,%ecx,1)
+       cmpl    %ebx,%ecx
+       jb      .L040ctr16_xor
+       movl    8(%ebp),%ecx
+       addl    %ebx,%edi
+       addl    %ebx,%esi
+       subl    %ebx,%ecx
+       movl    $512,%ebx
+       jnz     .L038ctr16_loop
+       movdqa  %xmm0,-16(%edx)
+       pxor    %xmm0,%xmm0
+       pxor    %xmm1,%xmm1
+       movl    %ebp,%ecx
+       movl    %esp,%edi
+       subl    %esp,%ecx
+       xorl    %eax,%eax
+       shrl    $2,%ecx
+.byte  243,171
+.L041ctr16_done:
+       leal    24(%ebp),%esp
+       movl    $1,%eax
+       leal    4(%esp),%esp
+.L036ctr16_abort:
+       popl    %edi
+       popl    %esi
+       popl    %ebx
+       popl    %ebp
+       ret
+.size  padlock_ctr16_encrypt,.-.L_padlock_ctr16_encrypt_begin
+.globl padlock_xstore
+.type  padlock_xstore,@function
+.align 16
+padlock_xstore:
+.L_padlock_xstore_begin:
+       pushl   %edi
+       movl    8(%esp),%edi
+       movl    12(%esp),%edx
+.byte  15,167,192
+       popl    %edi
+       ret
+.size  padlock_xstore,.-.L_padlock_xstore_begin
+.type  _win32_segv_handler,@function
+.align 16
+_win32_segv_handler:
+       movl    $1,%eax
+       movl    4(%esp),%edx
+       movl    12(%esp),%ecx
+       cmpl    $3221225477,(%edx)
+       jne     .L042ret
+       addl    $4,184(%ecx)
+       movl    $0,%eax
+.L042ret:
+       ret
+.size  _win32_segv_handler,.-_win32_segv_handler
+.globl padlock_sha1_oneshot
+.type  padlock_sha1_oneshot,@function
+.align 16
+padlock_sha1_oneshot:
+.L_padlock_sha1_oneshot_begin:
+       pushl   %edi
+       pushl   %esi
+       xorl    %eax,%eax
+       movl    12(%esp),%edi
+       movl    16(%esp),%esi
+       movl    20(%esp),%ecx
+.byte  243,15,166,200
+       popl    %esi
+       popl    %edi
+       ret
+.size  padlock_sha1_oneshot,.-.L_padlock_sha1_oneshot_begin
+.globl padlock_sha1
+.type  padlock_sha1,@function
+.align 16
+padlock_sha1:
+.L_padlock_sha1_begin:
+       pushl   %edi
+       pushl   %esi
+       movl    $-1,%eax
+       movl    12(%esp),%edi
+       movl    16(%esp),%esi
+       movl    20(%esp),%ecx
+.byte  243,15,166,200
+       popl    %esi
+       popl    %edi
+       ret
+.size  padlock_sha1,.-.L_padlock_sha1_begin
+.globl padlock_sha256_oneshot
+.type  padlock_sha256_oneshot,@function
+.align 16
+padlock_sha256_oneshot:
+.L_padlock_sha256_oneshot_begin:
+       pushl   %edi
+       pushl   %esi
+       xorl    %eax,%eax
+       movl    12(%esp),%edi
+       movl    16(%esp),%esi
+       movl    20(%esp),%ecx
+.byte  243,15,166,208
+       popl    %esi
+       popl    %edi
+       ret
+.size  padlock_sha256_oneshot,.-.L_padlock_sha256_oneshot_begin
+.globl padlock_sha256
+.type  padlock_sha256,@function
+.align 16
+padlock_sha256:
+.L_padlock_sha256_begin:
+       pushl   %edi
+       pushl   %esi
+       movl    $-1,%eax
+       movl    12(%esp),%edi
+       movl    16(%esp),%esi
+       movl    20(%esp),%ecx
+.byte  243,15,166,208
+       popl    %esi
+       popl    %edi
+       ret
+.size  padlock_sha256,.-.L_padlock_sha256_begin
+.byte  86,73,65,32,80,97,100,108,111,99,107,32,120,56,54,32
+.byte  109,111,100,117,108,101,44,32,67,82,89,80,84,79,71,65
+.byte  77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101
+.byte  110,115,115,108,46,111,114,103,62,0
+.align 16
+.data
+.align 4
+.Lpadlock_saved_context:
+.long  0
diff --git a/lib/accelerated/intel/padlock.c b/lib/accelerated/intel/padlock.c
new file mode 100644 (file)
index 0000000..39da6da
--- /dev/null
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2011 Free Software Foundation, Inc.
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * The GnuTLS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/*
+ * The following code is an implementation of the AES-128-CBC cipher
+ * using VIA Padlock instruction set. 
+ */
+
+#include <gnutls_errors.h>
+#include <gnutls_int.h>
+#include <gnutls/crypto.h>
+#include <gnutls_errors.h>
+#include <aes-x86.h>
+#include <x86.h>
+#ifdef HAVE_LIBNETTLE
+# include <nettle/aes.h>         /* for key generation in 192 and 256 bits */
+#endif
+
+struct padlock_cipher_data {
+    unsigned char iv[16];       /* Initialization vector */
+    union {
+        unsigned int pad[4];
+        struct {
+            int rounds:4;
+            int dgst:1;         /* n/a in C3 */
+            int align:1;        /* n/a in C3 */
+            int ciphr:1;        /* n/a in C3 */
+            unsigned int keygen:1;
+            int interm:1;
+            unsigned int encdec:1;
+            int ksize:2;
+        } b;
+    } cword;                    /* Control word */
+    AES_KEY ks;                 /* Encryption key */
+};
+
+struct padlock_ctx {
+    struct padlock_cipher_data expanded_key;
+    struct padlock_cipher_data expanded_key_dec;
+};
+
+unsigned int padlock_capability();
+void padlock_key_bswap(AES_KEY * key);
+void padlock_verify_context(struct padlock_cipher_data *ctx);
+void padlock_reload_key();
+void padlock_aes_block(void *out, const void *inp,
+                       struct padlock_cipher_data *ctx);
+int padlock_ecb_encrypt(void *out, const void *inp,
+                        struct padlock_cipher_data *ctx, size_t len);
+int padlock_cbc_encrypt(void *out, const void *inp,
+                        struct padlock_cipher_data *ctx, size_t len);
+int padlock_ctr32_encrypt(void *out, const void *inp,
+                          struct padlock_cipher_data *ctx, size_t len);
+void padlock_sha1_oneshot(void *ctx, const void *inp, size_t len);
+void padlock_sha1(void *ctx, const void *inp, size_t len);
+void padlock_sha256_oneshot(void *ctx, const void *inp, size_t len);
+void padlock_sha256(void *ctx, const void *inp, size_t len);
+
+
+static int
+aes_cipher_init(gnutls_cipher_algorithm_t algorithm, void **_ctx)
+{
+    /* we use key size to distinguish */
+    if (algorithm != GNUTLS_CIPHER_AES_128_CBC
+        && algorithm != GNUTLS_CIPHER_AES_192_CBC
+        && algorithm != GNUTLS_CIPHER_AES_256_CBC)
+        return GNUTLS_E_INVALID_REQUEST;
+
+    *_ctx = gnutls_calloc(1, sizeof(struct padlock_ctx));
+    if (*_ctx == NULL) {
+        gnutls_assert();
+        return GNUTLS_E_MEMORY_ERROR;
+    }
+
+    return 0;
+}
+
+static int
+aes_cipher_setkey(void *_ctx, const void *userkey, size_t keysize)
+{
+    struct padlock_ctx *ctx = _ctx;
+    struct padlock_cipher_data *pce, *pcd;
+#ifdef HAVE_LIBNETTLE
+    struct aes_ctx nc;
+#endif
+    int ret;
+
+    memset(_ctx, 0, sizeof(struct padlock_cipher_data));
+
+    pce = ALIGN16(&ctx->expanded_key);
+    pcd = ALIGN16(&ctx->expanded_key_dec);
+
+    pce->cword.b.encdec = 0;
+    pcd->cword.b.encdec = 1;
+
+    switch (keysize) {
+    case 16:
+        pce->cword.b.ksize = pcd->cword.b.ksize = 0;
+        pce->cword.b.rounds = pcd->cword.b.rounds = 10;
+        memcpy(pce->ks.rd_key, userkey, 16);
+        memcpy(pcd->ks.rd_key, userkey, 16);
+        pce->cword.b.keygen = pcd->cword.b.keygen = 0;
+        break;
+#ifdef HAVE_LIBNETTLE
+    case 24:
+        pce->cword.b.ksize = pcd->cword.b.ksize = 1;
+        pce->cword.b.rounds = pcd->cword.b.rounds = 12;
+        goto common_24_32;
+    case 32:
+        pce->cword.b.ksize = pcd->cword.b.ksize = 2;
+        pce->cword.b.rounds = pcd->cword.b.rounds = 14;
+common_24_32:
+        /* expand key using nettle */
+        aes_set_encrypt_key(&nc, keysize, userkey);
+        memcpy(pce->ks.rd_key, nc.keys, sizeof(nc.keys));
+        pce->ks.rounds = pcd->ks.rounds = nc.nrounds;
+        aes_invert_key(&nc, &nc);
+        memcpy(pcd->ks.rd_key, nc.keys, sizeof(nc.keys));
+
+        pce->cword.b.keygen = pcd->cword.b.keygen = 1;
+        break;
+#endif
+    default:
+        return gnutls_assert_val(GNUTLS_E_ENCRYPTION_FAILED);
+    }
+    
+    padlock_reload_key ();
+
+    return 0;
+}
+
+static int aes_setiv(void *_ctx, const void *iv, size_t iv_size)
+{
+    struct padlock_ctx *ctx = _ctx;
+    struct padlock_cipher_data *pce, *pcd;
+
+    pce = ALIGN16(&ctx->expanded_key);
+    pcd = ALIGN16(&ctx->expanded_key_dec);
+
+    memcpy(pce->iv, iv, 16);
+    memcpy(pcd->iv, iv, 16);
+    return 0;
+}
+
+static int
+padlock_aes_encrypt(void *_ctx, const void *src, size_t src_size,
+            void *dst, size_t dst_size)
+{
+    struct padlock_ctx *ctx = _ctx;
+    struct padlock_cipher_data *pce;
+
+    pce = ALIGN16(&ctx->expanded_key);
+
+    padlock_cbc_encrypt(dst, src, pce, src_size);
+
+    return 0;
+}
+
+static int
+padlock_aes_decrypt(void *_ctx, const void *src, size_t src_size,
+            void *dst, size_t dst_size)
+{
+    struct padlock_ctx *ctx = _ctx;
+    struct padlock_cipher_data *pcd;
+
+    pcd = ALIGN16(&ctx->expanded_key_dec);
+
+    padlock_cbc_encrypt(dst, src, pcd, src_size);
+
+    return 0;
+}
+
+static void aes_deinit(void *_ctx)
+{
+    gnutls_free(_ctx);
+}
+
+static const gnutls_crypto_cipher_st cipher_struct = {
+    .init = aes_cipher_init,
+    .setkey = aes_cipher_setkey,
+    .setiv = aes_setiv,
+    .encrypt = padlock_aes_encrypt,
+    .decrypt = padlock_aes_decrypt,
+    .deinit = aes_deinit,
+};
+
+static int check_padlock(void)
+{
+    unsigned int edx = padlock_capability();
+
+    return ((edx & (0x3 << 6)) == (0x3 << 6));
+}
+
+static unsigned check_via(void)
+{
+    unsigned int a, b, c, d;
+    cpuid(0, a, b, c, d);
+
+    if ((memcmp(&b, "VIA ", 4) == 0 &&
+         memcmp(&d, "VIA ", 4) == 0 && memcmp(&c, "VIA ", 4) == 0)) {
+        return 1;
+    }
+
+    return 0;
+}
+
+void register_padlock_crypto(void)
+{
+    int ret;
+
+    if (check_via() == 0)
+        return;
+
+    if (check_padlock()) {
+        _gnutls_debug_log("Padlock AES accelerator was detected\n");
+        ret =
+            gnutls_crypto_single_cipher_register(GNUTLS_CIPHER_AES_128_CBC,
+                                                 80, &cipher_struct);
+        if (ret < 0) {
+            gnutls_assert();
+        }
+
+#ifdef HAVE_LIBNETTLE
+        ret =
+            gnutls_crypto_single_cipher_register(GNUTLS_CIPHER_AES_192_CBC,
+                                                 80, &cipher_struct);
+        if (ret < 0) {
+            gnutls_assert();
+        }
+
+        ret =
+            gnutls_crypto_single_cipher_register(GNUTLS_CIPHER_AES_256_CBC,
+                                                 80, &cipher_struct);
+        if (ret < 0) {
+            gnutls_assert();
+        }
+#endif
+    }
+
+    return;
+}