/*
 *  VIA PadLock support functions
 *
 *  Copyright The Mbed TLS Contributors
 *  SPDX-License-Identifier: Apache-2.0
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may
 *  not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
/*
 *  This implementation is based on the VIA PadLock Programming Guide:
 *
 *  http://www.via.com.tw/en/downloads/whitepapers/initiatives/padlock/
 *  programming_guide.pdf
 */

#include "common.h"

#if defined(MBEDTLS_PADLOCK_C)

#include "padlock.h"

#include <string.h>

#if defined(MBEDTLS_HAVE_X86)

/*
 * PadLock detection routine
 */
int mbedtls_padlock_has_support(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    1f                  \n\t"
             "movl  $0xC0000001, %%eax  \n\t"
             "cpuid                     \n\t"
             "1:                        \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 mbedtls_padlock_xcryptecb(mbedtls_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->buf + ctx->rk_offset;

    if (((long) rk & 15) != 0) {
        return MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED;
    }

    blk = MBEDTLS_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)
         : "memory", "ecx", "edx", "esi", "edi");

    memcpy(output, blk, 16);

    return 0;
}

/*
 * PadLock AES-CBC buffer en(de)cryption
 */
int mbedtls_padlock_xcryptcbc(mbedtls_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];

    rk = ctx->buf + ctx->rk_offset;

    if (((long) input  & 15) != 0 ||
        ((long) output & 15) != 0 ||
        ((long) rk & 15) != 0) {
        return MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED;
    }

    iw = MBEDTLS_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)
         : "memory", "eax", "ecx", "edx", "esi", "edi");

    memcpy(iv, iw, 16);

    return 0;
}

#endif /* MBEDTLS_HAVE_X86 */

#endif /* MBEDTLS_PADLOCK_C */
