1817466cbSJens Wiklander /* 2817466cbSJens Wiklander * VIA PadLock support functions 3817466cbSJens Wiklander * 4*7901324dSJerome Forissier * Copyright The Mbed TLS Contributors 5*7901324dSJerome Forissier * SPDX-License-Identifier: Apache-2.0 6817466cbSJens Wiklander * 7817466cbSJens Wiklander * Licensed under the Apache License, Version 2.0 (the "License"); you may 8817466cbSJens Wiklander * not use this file except in compliance with the License. 9817466cbSJens Wiklander * You may obtain a copy of the License at 10817466cbSJens Wiklander * 11817466cbSJens Wiklander * http://www.apache.org/licenses/LICENSE-2.0 12817466cbSJens Wiklander * 13817466cbSJens Wiklander * Unless required by applicable law or agreed to in writing, software 14817466cbSJens Wiklander * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15817466cbSJens Wiklander * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16817466cbSJens Wiklander * See the License for the specific language governing permissions and 17817466cbSJens Wiklander * limitations under the License. 18817466cbSJens Wiklander */ 19817466cbSJens Wiklander /* 20817466cbSJens Wiklander * This implementation is based on the VIA PadLock Programming Guide: 21817466cbSJens Wiklander * 22817466cbSJens Wiklander * http://www.via.com.tw/en/downloads/whitepapers/initiatives/padlock/ 23817466cbSJens Wiklander * programming_guide.pdf 24817466cbSJens Wiklander */ 25817466cbSJens Wiklander 26*7901324dSJerome Forissier #include "common.h" 27817466cbSJens Wiklander 28817466cbSJens Wiklander #if defined(MBEDTLS_PADLOCK_C) 29817466cbSJens Wiklander 30817466cbSJens Wiklander #include "mbedtls/padlock.h" 31817466cbSJens Wiklander 32817466cbSJens Wiklander #include <string.h> 33817466cbSJens Wiklander 34817466cbSJens Wiklander #ifndef asm 35817466cbSJens Wiklander #define asm __asm 36817466cbSJens Wiklander #endif 37817466cbSJens Wiklander 38817466cbSJens Wiklander #if defined(MBEDTLS_HAVE_X86) 39817466cbSJens Wiklander 40817466cbSJens Wiklander /* 41817466cbSJens Wiklander * PadLock detection routine 42817466cbSJens Wiklander */ 43817466cbSJens Wiklander int mbedtls_padlock_has_support( int feature ) 44817466cbSJens Wiklander { 45817466cbSJens Wiklander static int flags = -1; 46817466cbSJens Wiklander int ebx = 0, edx = 0; 47817466cbSJens Wiklander 48817466cbSJens Wiklander if( flags == -1 ) 49817466cbSJens Wiklander { 50817466cbSJens Wiklander asm( "movl %%ebx, %0 \n\t" 51817466cbSJens Wiklander "movl $0xC0000000, %%eax \n\t" 52817466cbSJens Wiklander "cpuid \n\t" 53817466cbSJens Wiklander "cmpl $0xC0000001, %%eax \n\t" 54817466cbSJens Wiklander "movl $0, %%edx \n\t" 55*7901324dSJerome Forissier "jb 1f \n\t" 56817466cbSJens Wiklander "movl $0xC0000001, %%eax \n\t" 57817466cbSJens Wiklander "cpuid \n\t" 58*7901324dSJerome Forissier "1: \n\t" 59817466cbSJens Wiklander "movl %%edx, %1 \n\t" 60817466cbSJens Wiklander "movl %2, %%ebx \n\t" 61817466cbSJens Wiklander : "=m" (ebx), "=m" (edx) 62817466cbSJens Wiklander : "m" (ebx) 63817466cbSJens Wiklander : "eax", "ecx", "edx" ); 64817466cbSJens Wiklander 65817466cbSJens Wiklander flags = edx; 66817466cbSJens Wiklander } 67817466cbSJens Wiklander 68817466cbSJens Wiklander return( flags & feature ); 69817466cbSJens Wiklander } 70817466cbSJens Wiklander 71817466cbSJens Wiklander /* 72817466cbSJens Wiklander * PadLock AES-ECB block en(de)cryption 73817466cbSJens Wiklander */ 74817466cbSJens Wiklander int mbedtls_padlock_xcryptecb( mbedtls_aes_context *ctx, 75817466cbSJens Wiklander int mode, 76817466cbSJens Wiklander const unsigned char input[16], 77817466cbSJens Wiklander unsigned char output[16] ) 78817466cbSJens Wiklander { 79817466cbSJens Wiklander int ebx = 0; 80817466cbSJens Wiklander uint32_t *rk; 81817466cbSJens Wiklander uint32_t *blk; 82817466cbSJens Wiklander uint32_t *ctrl; 83817466cbSJens Wiklander unsigned char buf[256]; 84817466cbSJens Wiklander 85817466cbSJens Wiklander rk = ctx->rk; 86817466cbSJens Wiklander blk = MBEDTLS_PADLOCK_ALIGN16( buf ); 87817466cbSJens Wiklander memcpy( blk, input, 16 ); 88817466cbSJens Wiklander 89817466cbSJens Wiklander ctrl = blk + 4; 90817466cbSJens Wiklander *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode^1 ) - 10 ) << 9 ); 91817466cbSJens Wiklander 92817466cbSJens Wiklander asm( "pushfl \n\t" 93817466cbSJens Wiklander "popfl \n\t" 94817466cbSJens Wiklander "movl %%ebx, %0 \n\t" 95817466cbSJens Wiklander "movl $1, %%ecx \n\t" 96817466cbSJens Wiklander "movl %2, %%edx \n\t" 97817466cbSJens Wiklander "movl %3, %%ebx \n\t" 98817466cbSJens Wiklander "movl %4, %%esi \n\t" 99817466cbSJens Wiklander "movl %4, %%edi \n\t" 100817466cbSJens Wiklander ".byte 0xf3,0x0f,0xa7,0xc8 \n\t" 101817466cbSJens Wiklander "movl %1, %%ebx \n\t" 102817466cbSJens Wiklander : "=m" (ebx) 103817466cbSJens Wiklander : "m" (ebx), "m" (ctrl), "m" (rk), "m" (blk) 104817466cbSJens Wiklander : "memory", "ecx", "edx", "esi", "edi" ); 105817466cbSJens Wiklander 106817466cbSJens Wiklander memcpy( output, blk, 16 ); 107817466cbSJens Wiklander 108817466cbSJens Wiklander return( 0 ); 109817466cbSJens Wiklander } 110817466cbSJens Wiklander 111817466cbSJens Wiklander /* 112817466cbSJens Wiklander * PadLock AES-CBC buffer en(de)cryption 113817466cbSJens Wiklander */ 114817466cbSJens Wiklander int mbedtls_padlock_xcryptcbc( mbedtls_aes_context *ctx, 115817466cbSJens Wiklander int mode, 116817466cbSJens Wiklander size_t length, 117817466cbSJens Wiklander unsigned char iv[16], 118817466cbSJens Wiklander const unsigned char *input, 119817466cbSJens Wiklander unsigned char *output ) 120817466cbSJens Wiklander { 121817466cbSJens Wiklander int ebx = 0; 122817466cbSJens Wiklander size_t count; 123817466cbSJens Wiklander uint32_t *rk; 124817466cbSJens Wiklander uint32_t *iw; 125817466cbSJens Wiklander uint32_t *ctrl; 126817466cbSJens Wiklander unsigned char buf[256]; 127817466cbSJens Wiklander 128817466cbSJens Wiklander if( ( (long) input & 15 ) != 0 || 129817466cbSJens Wiklander ( (long) output & 15 ) != 0 ) 130817466cbSJens Wiklander return( MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED ); 131817466cbSJens Wiklander 132817466cbSJens Wiklander rk = ctx->rk; 133817466cbSJens Wiklander iw = MBEDTLS_PADLOCK_ALIGN16( buf ); 134817466cbSJens Wiklander memcpy( iw, iv, 16 ); 135817466cbSJens Wiklander 136817466cbSJens Wiklander ctrl = iw + 4; 137817466cbSJens Wiklander *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode ^ 1 ) - 10 ) << 9 ); 138817466cbSJens Wiklander 139817466cbSJens Wiklander count = ( length + 15 ) >> 4; 140817466cbSJens Wiklander 141817466cbSJens Wiklander asm( "pushfl \n\t" 142817466cbSJens Wiklander "popfl \n\t" 143817466cbSJens Wiklander "movl %%ebx, %0 \n\t" 144817466cbSJens Wiklander "movl %2, %%ecx \n\t" 145817466cbSJens Wiklander "movl %3, %%edx \n\t" 146817466cbSJens Wiklander "movl %4, %%ebx \n\t" 147817466cbSJens Wiklander "movl %5, %%esi \n\t" 148817466cbSJens Wiklander "movl %6, %%edi \n\t" 149817466cbSJens Wiklander "movl %7, %%eax \n\t" 150817466cbSJens Wiklander ".byte 0xf3,0x0f,0xa7,0xd0 \n\t" 151817466cbSJens Wiklander "movl %1, %%ebx \n\t" 152817466cbSJens Wiklander : "=m" (ebx) 153817466cbSJens Wiklander : "m" (ebx), "m" (count), "m" (ctrl), 154817466cbSJens Wiklander "m" (rk), "m" (input), "m" (output), "m" (iw) 155817466cbSJens Wiklander : "memory", "eax", "ecx", "edx", "esi", "edi" ); 156817466cbSJens Wiklander 157817466cbSJens Wiklander memcpy( iv, iw, 16 ); 158817466cbSJens Wiklander 159817466cbSJens Wiklander return( 0 ); 160817466cbSJens Wiklander } 161817466cbSJens Wiklander 162817466cbSJens Wiklander #endif /* MBEDTLS_HAVE_X86 */ 163817466cbSJens Wiklander 164817466cbSJens Wiklander #endif /* MBEDTLS_PADLOCK_C */ 165