1*817466cbSJens Wiklander /* 2*817466cbSJens Wiklander * VIA PadLock support functions 3*817466cbSJens Wiklander * 4*817466cbSJens Wiklander * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 5*817466cbSJens Wiklander * SPDX-License-Identifier: Apache-2.0 6*817466cbSJens Wiklander * 7*817466cbSJens Wiklander * Licensed under the Apache License, Version 2.0 (the "License"); you may 8*817466cbSJens Wiklander * not use this file except in compliance with the License. 9*817466cbSJens Wiklander * You may obtain a copy of the License at 10*817466cbSJens Wiklander * 11*817466cbSJens Wiklander * http://www.apache.org/licenses/LICENSE-2.0 12*817466cbSJens Wiklander * 13*817466cbSJens Wiklander * Unless required by applicable law or agreed to in writing, software 14*817466cbSJens Wiklander * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15*817466cbSJens Wiklander * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16*817466cbSJens Wiklander * See the License for the specific language governing permissions and 17*817466cbSJens Wiklander * limitations under the License. 18*817466cbSJens Wiklander * 19*817466cbSJens Wiklander * This file is part of mbed TLS (https://tls.mbed.org) 20*817466cbSJens Wiklander */ 21*817466cbSJens Wiklander /* 22*817466cbSJens Wiklander * This implementation is based on the VIA PadLock Programming Guide: 23*817466cbSJens Wiklander * 24*817466cbSJens Wiklander * http://www.via.com.tw/en/downloads/whitepapers/initiatives/padlock/ 25*817466cbSJens Wiklander * programming_guide.pdf 26*817466cbSJens Wiklander */ 27*817466cbSJens Wiklander 28*817466cbSJens Wiklander #if !defined(MBEDTLS_CONFIG_FILE) 29*817466cbSJens Wiklander #include "mbedtls/config.h" 30*817466cbSJens Wiklander #else 31*817466cbSJens Wiklander #include MBEDTLS_CONFIG_FILE 32*817466cbSJens Wiklander #endif 33*817466cbSJens Wiklander 34*817466cbSJens Wiklander #if defined(MBEDTLS_PADLOCK_C) 35*817466cbSJens Wiklander 36*817466cbSJens Wiklander #include "mbedtls/padlock.h" 37*817466cbSJens Wiklander 38*817466cbSJens Wiklander #include <string.h> 39*817466cbSJens Wiklander 40*817466cbSJens Wiklander #ifndef asm 41*817466cbSJens Wiklander #define asm __asm 42*817466cbSJens Wiklander #endif 43*817466cbSJens Wiklander 44*817466cbSJens Wiklander #if defined(MBEDTLS_HAVE_X86) 45*817466cbSJens Wiklander 46*817466cbSJens Wiklander /* 47*817466cbSJens Wiklander * PadLock detection routine 48*817466cbSJens Wiklander */ 49*817466cbSJens Wiklander int mbedtls_padlock_has_support( int feature ) 50*817466cbSJens Wiklander { 51*817466cbSJens Wiklander static int flags = -1; 52*817466cbSJens Wiklander int ebx = 0, edx = 0; 53*817466cbSJens Wiklander 54*817466cbSJens Wiklander if( flags == -1 ) 55*817466cbSJens Wiklander { 56*817466cbSJens Wiklander asm( "movl %%ebx, %0 \n\t" 57*817466cbSJens Wiklander "movl $0xC0000000, %%eax \n\t" 58*817466cbSJens Wiklander "cpuid \n\t" 59*817466cbSJens Wiklander "cmpl $0xC0000001, %%eax \n\t" 60*817466cbSJens Wiklander "movl $0, %%edx \n\t" 61*817466cbSJens Wiklander "jb unsupported \n\t" 62*817466cbSJens Wiklander "movl $0xC0000001, %%eax \n\t" 63*817466cbSJens Wiklander "cpuid \n\t" 64*817466cbSJens Wiklander "unsupported: \n\t" 65*817466cbSJens Wiklander "movl %%edx, %1 \n\t" 66*817466cbSJens Wiklander "movl %2, %%ebx \n\t" 67*817466cbSJens Wiklander : "=m" (ebx), "=m" (edx) 68*817466cbSJens Wiklander : "m" (ebx) 69*817466cbSJens Wiklander : "eax", "ecx", "edx" ); 70*817466cbSJens Wiklander 71*817466cbSJens Wiklander flags = edx; 72*817466cbSJens Wiklander } 73*817466cbSJens Wiklander 74*817466cbSJens Wiklander return( flags & feature ); 75*817466cbSJens Wiklander } 76*817466cbSJens Wiklander 77*817466cbSJens Wiklander /* 78*817466cbSJens Wiklander * PadLock AES-ECB block en(de)cryption 79*817466cbSJens Wiklander */ 80*817466cbSJens Wiklander int mbedtls_padlock_xcryptecb( mbedtls_aes_context *ctx, 81*817466cbSJens Wiklander int mode, 82*817466cbSJens Wiklander const unsigned char input[16], 83*817466cbSJens Wiklander unsigned char output[16] ) 84*817466cbSJens Wiklander { 85*817466cbSJens Wiklander int ebx = 0; 86*817466cbSJens Wiklander uint32_t *rk; 87*817466cbSJens Wiklander uint32_t *blk; 88*817466cbSJens Wiklander uint32_t *ctrl; 89*817466cbSJens Wiklander unsigned char buf[256]; 90*817466cbSJens Wiklander 91*817466cbSJens Wiklander rk = ctx->rk; 92*817466cbSJens Wiklander blk = MBEDTLS_PADLOCK_ALIGN16( buf ); 93*817466cbSJens Wiklander memcpy( blk, input, 16 ); 94*817466cbSJens Wiklander 95*817466cbSJens Wiklander ctrl = blk + 4; 96*817466cbSJens Wiklander *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode^1 ) - 10 ) << 9 ); 97*817466cbSJens Wiklander 98*817466cbSJens Wiklander asm( "pushfl \n\t" 99*817466cbSJens Wiklander "popfl \n\t" 100*817466cbSJens Wiklander "movl %%ebx, %0 \n\t" 101*817466cbSJens Wiklander "movl $1, %%ecx \n\t" 102*817466cbSJens Wiklander "movl %2, %%edx \n\t" 103*817466cbSJens Wiklander "movl %3, %%ebx \n\t" 104*817466cbSJens Wiklander "movl %4, %%esi \n\t" 105*817466cbSJens Wiklander "movl %4, %%edi \n\t" 106*817466cbSJens Wiklander ".byte 0xf3,0x0f,0xa7,0xc8 \n\t" 107*817466cbSJens Wiklander "movl %1, %%ebx \n\t" 108*817466cbSJens Wiklander : "=m" (ebx) 109*817466cbSJens Wiklander : "m" (ebx), "m" (ctrl), "m" (rk), "m" (blk) 110*817466cbSJens Wiklander : "memory", "ecx", "edx", "esi", "edi" ); 111*817466cbSJens Wiklander 112*817466cbSJens Wiklander memcpy( output, blk, 16 ); 113*817466cbSJens Wiklander 114*817466cbSJens Wiklander return( 0 ); 115*817466cbSJens Wiklander } 116*817466cbSJens Wiklander 117*817466cbSJens Wiklander /* 118*817466cbSJens Wiklander * PadLock AES-CBC buffer en(de)cryption 119*817466cbSJens Wiklander */ 120*817466cbSJens Wiklander int mbedtls_padlock_xcryptcbc( mbedtls_aes_context *ctx, 121*817466cbSJens Wiklander int mode, 122*817466cbSJens Wiklander size_t length, 123*817466cbSJens Wiklander unsigned char iv[16], 124*817466cbSJens Wiklander const unsigned char *input, 125*817466cbSJens Wiklander unsigned char *output ) 126*817466cbSJens Wiklander { 127*817466cbSJens Wiklander int ebx = 0; 128*817466cbSJens Wiklander size_t count; 129*817466cbSJens Wiklander uint32_t *rk; 130*817466cbSJens Wiklander uint32_t *iw; 131*817466cbSJens Wiklander uint32_t *ctrl; 132*817466cbSJens Wiklander unsigned char buf[256]; 133*817466cbSJens Wiklander 134*817466cbSJens Wiklander if( ( (long) input & 15 ) != 0 || 135*817466cbSJens Wiklander ( (long) output & 15 ) != 0 ) 136*817466cbSJens Wiklander return( MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED ); 137*817466cbSJens Wiklander 138*817466cbSJens Wiklander rk = ctx->rk; 139*817466cbSJens Wiklander iw = MBEDTLS_PADLOCK_ALIGN16( buf ); 140*817466cbSJens Wiklander memcpy( iw, iv, 16 ); 141*817466cbSJens Wiklander 142*817466cbSJens Wiklander ctrl = iw + 4; 143*817466cbSJens Wiklander *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode ^ 1 ) - 10 ) << 9 ); 144*817466cbSJens Wiklander 145*817466cbSJens Wiklander count = ( length + 15 ) >> 4; 146*817466cbSJens Wiklander 147*817466cbSJens Wiklander asm( "pushfl \n\t" 148*817466cbSJens Wiklander "popfl \n\t" 149*817466cbSJens Wiklander "movl %%ebx, %0 \n\t" 150*817466cbSJens Wiklander "movl %2, %%ecx \n\t" 151*817466cbSJens Wiklander "movl %3, %%edx \n\t" 152*817466cbSJens Wiklander "movl %4, %%ebx \n\t" 153*817466cbSJens Wiklander "movl %5, %%esi \n\t" 154*817466cbSJens Wiklander "movl %6, %%edi \n\t" 155*817466cbSJens Wiklander "movl %7, %%eax \n\t" 156*817466cbSJens Wiklander ".byte 0xf3,0x0f,0xa7,0xd0 \n\t" 157*817466cbSJens Wiklander "movl %1, %%ebx \n\t" 158*817466cbSJens Wiklander : "=m" (ebx) 159*817466cbSJens Wiklander : "m" (ebx), "m" (count), "m" (ctrl), 160*817466cbSJens Wiklander "m" (rk), "m" (input), "m" (output), "m" (iw) 161*817466cbSJens Wiklander : "memory", "eax", "ecx", "edx", "esi", "edi" ); 162*817466cbSJens Wiklander 163*817466cbSJens Wiklander memcpy( iv, iw, 16 ); 164*817466cbSJens Wiklander 165*817466cbSJens Wiklander return( 0 ); 166*817466cbSJens Wiklander } 167*817466cbSJens Wiklander 168*817466cbSJens Wiklander #endif /* MBEDTLS_HAVE_X86 */ 169*817466cbSJens Wiklander 170*817466cbSJens Wiklander #endif /* MBEDTLS_PADLOCK_C */ 171