/*
 *  VIA PadLock support functions
 *
 *  Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
 *
 *  This file is part of mbed TLS (http://www.polarssl.org)
 *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
 *
 *  All rights reserved.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
/*
 *  This implementation is based on the VIA PadLock Programming Guide:
 *
 *  http://www.via.com.tw/en/downloads/whitepapers/initiatives/padlock/
 *  programming_guide.pdf
 */

#if !defined(POLARSSL_CONFIG_FILE)
#include "polarssl/config.h"
#else
#include POLARSSL_CONFIG_FILE
#endif

#if defined(POLARSSL_PADLOCK_C)

#include "polarssl/padlock.h"

#if defined(POLARSSL_HAVE_X86)

/*
 * PadLock detection routine
 */
int padlock_supports( int feature )
{
    static int flags = -1;
    int ebx = 0, edx = 0;

    if( flags == -1 )
    {
        asm( "movl  %%ebx, %0           \n\t"
             "movl  $0xC0000000, %%eax  \n\t"
             "cpuid                     \n\t"
             "cmpl  $0xC0000001, %%eax  \n\t"
             "movl  $0, %%edx           \n\t"
             "jb    unsupported         \n\t"
             "movl  $0xC0000001, %%eax  \n\t"
             "cpuid                     \n\t"
             "unsupported:              \n\t"
             "movl  %%edx, %1           \n\t"
             "movl  %2, %%ebx           \n\t"
             : "=m" (ebx), "=m" (edx)
             :  "m" (ebx)
             : "eax", "ecx", "edx" );

        flags = edx;
    }

    return( flags & feature );
}

/*
 * PadLock AES-ECB block en(de)cryption
 */
int padlock_xcryptecb( aes_context *ctx,
                       int mode,
                       const unsigned char input[16],
                       unsigned char output[16] )
{
    int ebx = 0;
    uint32_t *rk;
    uint32_t *blk;
    uint32_t *ctrl;
    unsigned char buf[256];

    rk  = ctx->rk;
    blk = PADLOCK_ALIGN16( buf );
    memcpy( blk, input, 16 );

     ctrl = blk + 4;
    *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode^1 ) - 10 ) << 9 );

    asm( "pushfl                        \n\t"
         "popfl                         \n\t"
         "movl    %%ebx, %0             \n\t"
         "movl    $1, %%ecx             \n\t"
         "movl    %2, %%edx             \n\t"
         "movl    %3, %%ebx             \n\t"
         "movl    %4, %%esi             \n\t"
         "movl    %4, %%edi             \n\t"
         ".byte  0xf3,0x0f,0xa7,0xc8    \n\t"
         "movl    %1, %%ebx             \n\t"
         : "=m" (ebx)
         :  "m" (ebx), "m" (ctrl), "m" (rk), "m" (blk)
         : "ecx", "edx", "esi", "edi" );

    memcpy( output, blk, 16 );

    return( 0 );
}

/*
 * PadLock AES-CBC buffer en(de)cryption
 */
int padlock_xcryptcbc( aes_context *ctx,
                       int mode,
                       size_t length,
                       unsigned char iv[16],
                       const unsigned char *input,
                       unsigned char *output )
{
    int ebx = 0;
    size_t count;
    uint32_t *rk;
    uint32_t *iw;
    uint32_t *ctrl;
    unsigned char buf[256];

    if( ( (long) input  & 15 ) != 0 ||
        ( (long) output & 15 ) != 0 )
        return( POLARSSL_ERR_PADLOCK_DATA_MISALIGNED );

    rk = ctx->rk;
    iw = PADLOCK_ALIGN16( buf );
    memcpy( iw, iv, 16 );

     ctrl = iw + 4;
    *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode ^ 1 ) - 10 ) << 9 );

    count = ( length + 15 ) >> 4;

    asm( "pushfl                        \n\t"
         "popfl                         \n\t"
         "movl    %%ebx, %0             \n\t"
         "movl    %2, %%ecx             \n\t"
         "movl    %3, %%edx             \n\t"
         "movl    %4, %%ebx             \n\t"
         "movl    %5, %%esi             \n\t"
         "movl    %6, %%edi             \n\t"
         "movl    %7, %%eax             \n\t"
         ".byte  0xf3,0x0f,0xa7,0xd0    \n\t"
         "movl    %1, %%ebx             \n\t"
         : "=m" (ebx)
         :  "m" (ebx), "m" (count), "m" (ctrl),
            "m"  (rk), "m" (input), "m" (output), "m" (iw)
         : "eax", "ecx", "edx", "esi", "edi" );

    memcpy( iv, iw, 16 );

    return( 0 );
}

#endif /* POLARSSL_HAVE_X86 */

#endif /* POLARSSL_PADLOCK_C */
