1817466cbSJens Wiklander /* 2817466cbSJens Wiklander * VIA PadLock support functions 3817466cbSJens Wiklander * 47901324dSJerome Forissier * Copyright The Mbed TLS Contributors 57901324dSJerome 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 267901324dSJerome Forissier #include "common.h" 27817466cbSJens Wiklander 28817466cbSJens Wiklander #if defined(MBEDTLS_PADLOCK_C) 29817466cbSJens Wiklander 30*32b31808SJens Wiklander #include "padlock.h" 31817466cbSJens Wiklander 32817466cbSJens Wiklander #include <string.h> 33817466cbSJens Wiklander 34817466cbSJens Wiklander #if defined(MBEDTLS_HAVE_X86) 35817466cbSJens Wiklander 36817466cbSJens Wiklander /* 37817466cbSJens Wiklander * PadLock detection routine 38817466cbSJens Wiklander */ 39817466cbSJens Wiklander int mbedtls_padlock_has_support(int feature) 40817466cbSJens Wiklander { 41817466cbSJens Wiklander static int flags = -1; 42817466cbSJens Wiklander int ebx = 0, edx = 0; 43817466cbSJens Wiklander 44*32b31808SJens Wiklander if (flags == -1) { 45817466cbSJens Wiklander asm ("movl %%ebx, %0 \n\t" 46817466cbSJens Wiklander "movl $0xC0000000, %%eax \n\t" 47817466cbSJens Wiklander "cpuid \n\t" 48817466cbSJens Wiklander "cmpl $0xC0000001, %%eax \n\t" 49817466cbSJens Wiklander "movl $0, %%edx \n\t" 507901324dSJerome Forissier "jb 1f \n\t" 51817466cbSJens Wiklander "movl $0xC0000001, %%eax \n\t" 52817466cbSJens Wiklander "cpuid \n\t" 537901324dSJerome Forissier "1: \n\t" 54817466cbSJens Wiklander "movl %%edx, %1 \n\t" 55817466cbSJens Wiklander "movl %2, %%ebx \n\t" 56817466cbSJens Wiklander : "=m" (ebx), "=m" (edx) 57817466cbSJens Wiklander : "m" (ebx) 58817466cbSJens Wiklander : "eax", "ecx", "edx"); 59817466cbSJens Wiklander 60817466cbSJens Wiklander flags = edx; 61817466cbSJens Wiklander } 62817466cbSJens Wiklander 63*32b31808SJens Wiklander return flags & feature; 64817466cbSJens Wiklander } 65817466cbSJens Wiklander 66817466cbSJens Wiklander /* 67817466cbSJens Wiklander * PadLock AES-ECB block en(de)cryption 68817466cbSJens Wiklander */ 69817466cbSJens Wiklander int mbedtls_padlock_xcryptecb(mbedtls_aes_context *ctx, 70817466cbSJens Wiklander int mode, 71817466cbSJens Wiklander const unsigned char input[16], 72817466cbSJens Wiklander unsigned char output[16]) 73817466cbSJens Wiklander { 74817466cbSJens Wiklander int ebx = 0; 75817466cbSJens Wiklander uint32_t *rk; 76817466cbSJens Wiklander uint32_t *blk; 77817466cbSJens Wiklander uint32_t *ctrl; 78817466cbSJens Wiklander unsigned char buf[256]; 79817466cbSJens Wiklander 80*32b31808SJens Wiklander rk = ctx->buf + ctx->rk_offset; 81*32b31808SJens Wiklander 82*32b31808SJens Wiklander if (((long) rk & 15) != 0) { 83*32b31808SJens Wiklander return MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED; 84*32b31808SJens Wiklander } 85*32b31808SJens Wiklander 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 108*32b31808SJens 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 128*32b31808SJens Wiklander rk = ctx->buf + ctx->rk_offset; 129817466cbSJens Wiklander 130*32b31808SJens Wiklander if (((long) input & 15) != 0 || 131*32b31808SJens Wiklander ((long) output & 15) != 0 || 132*32b31808SJens Wiklander ((long) rk & 15) != 0) { 133*32b31808SJens Wiklander return MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED; 134*32b31808SJens Wiklander } 135*32b31808SJens Wiklander 136817466cbSJens Wiklander iw = MBEDTLS_PADLOCK_ALIGN16(buf); 137817466cbSJens Wiklander memcpy(iw, iv, 16); 138817466cbSJens Wiklander 139817466cbSJens Wiklander ctrl = iw + 4; 140817466cbSJens Wiklander *ctrl = 0x80 | ctx->nr | ((ctx->nr + (mode ^ 1) - 10) << 9); 141817466cbSJens Wiklander 142817466cbSJens Wiklander count = (length + 15) >> 4; 143817466cbSJens Wiklander 144817466cbSJens Wiklander asm ("pushfl \n\t" 145817466cbSJens Wiklander "popfl \n\t" 146817466cbSJens Wiklander "movl %%ebx, %0 \n\t" 147817466cbSJens Wiklander "movl %2, %%ecx \n\t" 148817466cbSJens Wiklander "movl %3, %%edx \n\t" 149817466cbSJens Wiklander "movl %4, %%ebx \n\t" 150817466cbSJens Wiklander "movl %5, %%esi \n\t" 151817466cbSJens Wiklander "movl %6, %%edi \n\t" 152817466cbSJens Wiklander "movl %7, %%eax \n\t" 153817466cbSJens Wiklander ".byte 0xf3,0x0f,0xa7,0xd0 \n\t" 154817466cbSJens Wiklander "movl %1, %%ebx \n\t" 155817466cbSJens Wiklander : "=m" (ebx) 156817466cbSJens Wiklander : "m" (ebx), "m" (count), "m" (ctrl), 157817466cbSJens Wiklander "m" (rk), "m" (input), "m" (output), "m" (iw) 158817466cbSJens Wiklander : "memory", "eax", "ecx", "edx", "esi", "edi"); 159817466cbSJens Wiklander 160817466cbSJens Wiklander memcpy(iv, iw, 16); 161817466cbSJens Wiklander 162*32b31808SJens Wiklander return 0; 163817466cbSJens Wiklander } 164817466cbSJens Wiklander 165817466cbSJens Wiklander #endif /* MBEDTLS_HAVE_X86 */ 166817466cbSJens Wiklander 167817466cbSJens Wiklander #endif /* MBEDTLS_PADLOCK_C */ 168