00001 /* 00002 * VIA PadLock support functions 00003 * 00004 * Copyright (C) 2006-2007 Christophe Devine 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License along 00017 * with this program; if not, write to the Free Software Foundation, Inc., 00018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00019 */ 00020 /* 00021 * This implementation is based on the VIA PadLock Programming Guide: 00022 * 00023 * http://www.via.com.tw/en/downloads/whitepapers/initiatives/padlock/ 00024 * programming_guide.pdf 00025 */ 00026 00027 #include "xyssl/config.h" 00028 00029 #if defined(XYSSL_PADLOCK_C) 00030 00031 #include "xyssl/aes.h" 00032 #include "xyssl/padlock.h" 00033 00034 #if defined(XYSSL_HAVE_X86) 00035 00036 #include <string.h> 00037 00038 /* 00039 * PadLock detection routine 00040 */ 00041 int padlock_supports( int feature ) 00042 { 00043 static int flags = -1; 00044 int ebx, edx; 00045 00046 if( flags == -1 ) 00047 { 00048 asm( "movl %%ebx, %0 \n" \ 00049 "movl 0ドルxC0000000, %%eax \n" \ 00050 "cpuid \n" \ 00051 "cmpl 0ドルxC0000001, %%eax \n" \ 00052 "movl 0,ドル %%edx \n" \ 00053 "jb unsupported \n" \ 00054 "movl 0ドルxC0000001, %%eax \n" \ 00055 "cpuid \n" \ 00056 "unsupported: \n" \ 00057 "movl %%edx, %1 \n" \ 00058 "movl %2, %%ebx \n" 00059 : "=m" (ebx), "=m" (edx) 00060 : "m" (ebx) 00061 : "eax", "ecx", "edx" ); 00062 00063 flags = edx; 00064 } 00065 00066 return( flags & feature ); 00067 } 00068 00069 /* 00070 * PadLock AES-ECB block en(de)cryption 00071 */ 00072 int padlock_xcryptecb( aes_context *ctx, 00073 int mode, 00074 unsigned char input[16], 00075 unsigned char output[16] ) 00076 { 00077 int ebx; 00078 unsigned long *rk; 00079 unsigned long *blk; 00080 unsigned long *ctrl; 00081 unsigned char buf[256]; 00082 00083 rk = ctx->rk; 00084 blk = PADLOCK_ALIGN16( buf ); 00085 memcpy( blk, input, 16 ); 00086 00087 ctrl = blk + 4; 00088 *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode^1 ) - 10 ) << 9 ); 00089 00090 asm( "pushfl; popfl \n" \ 00091 "movl %%ebx, %0 \n" \ 00092 "movl 1,ドル %%ecx \n" \ 00093 "movl %2, %%edx \n" \ 00094 "movl %3, %%ebx \n" \ 00095 "movl %4, %%esi \n" \ 00096 "movl %4, %%edi \n" \ 00097 ".byte 0xf3,0x0f,0xa7,0xc8\n" \ 00098 "movl %1, %%ebx \n" 00099 : "=m" (ebx) 00100 : "m" (ebx), "m" (ctrl), "m" (rk), "m" (blk) 00101 : "ecx", "edx", "esi", "edi" ); 00102 00103 memcpy( output, blk, 16 ); 00104 00105 return( 0 ); 00106 } 00107 00108 /* 00109 * PadLock AES-CBC buffer en(de)cryption 00110 */ 00111 int padlock_xcryptcbc( aes_context *ctx, 00112 int mode, 00113 int length, 00114 unsigned char iv[16], 00115 unsigned char *input, 00116 unsigned char *output ) 00117 { 00118 int ebx, count; 00119 unsigned long *rk; 00120 unsigned long *iw; 00121 unsigned long *ctrl; 00122 unsigned char buf[256]; 00123 00124 if( ( (long) input & 15 ) != 0 || 00125 ( (long) output & 15 ) != 0 ) 00126 return( 1 ); 00127 00128 rk = ctx->rk; 00129 iw = PADLOCK_ALIGN16( buf ); 00130 memcpy( iw, iv, 16 ); 00131 00132 ctrl = iw + 4; 00133 *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + (mode^1) - 10 ) << 9 ); 00134 00135 count = (length + 15) >> 4; 00136 00137 asm( "pushfl; popfl \n" \ 00138 "movl %%ebx, %0 \n" \ 00139 "movl %2, %%ecx \n" \ 00140 "movl %3, %%edx \n" \ 00141 "movl %4, %%ebx \n" \ 00142 "movl %5, %%esi \n" \ 00143 "movl %6, %%edi \n" \ 00144 "movl %7, %%eax \n" \ 00145 ".byte 0xf3,0x0f,0xa7,0xd0\n" \ 00146 "movl %1, %%ebx \n" 00147 : "=m" (ebx) 00148 : "m" (ebx), "m" (count), "m" (ctrl), 00149 "m" (rk), "m" (input), "m" (output), "m" (iw) 00150 : "eax", "ecx", "edx", "esi", "edi" ); 00151 00152 memcpy( iv, iw, 16 ); 00153 00154 return( 0 ); 00155 } 00156 00157 #endif 00158 00159 #endif