154034eb2SDan OpenSolaris Anderson/* 254034eb2SDan OpenSolaris Anderson * ==================================================================== 354034eb2SDan OpenSolaris Anderson * Written by Intel Corporation for the OpenSSL project to add support 454034eb2SDan OpenSolaris Anderson * for Intel AES-NI instructions. Rights for redistribution and usage 554034eb2SDan OpenSolaris Anderson * in source and binary forms are granted according to the OpenSSL 654034eb2SDan OpenSolaris Anderson * license. 754034eb2SDan OpenSolaris Anderson * 854034eb2SDan OpenSolaris Anderson * Author: Huang Ying <ying.huang at intel dot com> 954034eb2SDan OpenSolaris Anderson * Vinodh Gopal <vinodh.gopal at intel dot com> 1054034eb2SDan OpenSolaris Anderson * Kahraman Akdemir 1154034eb2SDan OpenSolaris Anderson * 1254034eb2SDan OpenSolaris Anderson * Intel AES-NI is a new set of Single Instruction Multiple Data (SIMD) 1354034eb2SDan OpenSolaris Anderson * instructions that are going to be introduced in the next generation 1454034eb2SDan OpenSolaris Anderson * of Intel processor, as of 2009. These instructions enable fast and 1554034eb2SDan OpenSolaris Anderson * secure data encryption and decryption, using the Advanced Encryption 1654034eb2SDan OpenSolaris Anderson * Standard (AES), defined by FIPS Publication number 197. The 1754034eb2SDan OpenSolaris Anderson * architecture introduces six instructions that offer full hardware 1854034eb2SDan OpenSolaris Anderson * support for AES. Four of them support high performance data 1954034eb2SDan OpenSolaris Anderson * encryption and decryption, and the other two instructions support 2054034eb2SDan OpenSolaris Anderson * the AES key expansion procedure. 2154034eb2SDan OpenSolaris Anderson * ==================================================================== 2254034eb2SDan OpenSolaris Anderson */ 2354034eb2SDan OpenSolaris Anderson 2454034eb2SDan OpenSolaris Anderson/* 2554034eb2SDan OpenSolaris Anderson * ==================================================================== 2654034eb2SDan OpenSolaris Anderson * Copyright (c) 1998-2008 The OpenSSL Project. All rights reserved. 2754034eb2SDan OpenSolaris Anderson * 2854034eb2SDan OpenSolaris Anderson * Redistribution and use in source and binary forms, with or without 2954034eb2SDan OpenSolaris Anderson * modification, are permitted provided that the following conditions 3054034eb2SDan OpenSolaris Anderson * are met: 3154034eb2SDan OpenSolaris Anderson * 3254034eb2SDan OpenSolaris Anderson * 1. Redistributions of source code must retain the above copyright 3354034eb2SDan OpenSolaris Anderson * notice, this list of conditions and the following disclaimer. 3454034eb2SDan OpenSolaris Anderson * 3554034eb2SDan OpenSolaris Anderson * 2. Redistributions in binary form must reproduce the above copyright 3654034eb2SDan OpenSolaris Anderson * notice, this list of conditions and the following disclaimer in 3754034eb2SDan OpenSolaris Anderson * the documentation and/or other materials provided with the 3854034eb2SDan OpenSolaris Anderson * distribution. 3954034eb2SDan OpenSolaris Anderson * 4054034eb2SDan OpenSolaris Anderson * 3. All advertising materials mentioning features or use of this 418de5c4f4SDan OpenSolaris Anderson * software must display the following acknowledgment: 4254034eb2SDan OpenSolaris Anderson * "This product includes software developed by the OpenSSL Project 4354034eb2SDan OpenSolaris Anderson * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 4454034eb2SDan OpenSolaris Anderson * 4554034eb2SDan OpenSolaris Anderson * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 4654034eb2SDan OpenSolaris Anderson * endorse or promote products derived from this software without 4754034eb2SDan OpenSolaris Anderson * prior written permission. For written permission, please contact 4854034eb2SDan OpenSolaris Anderson * openssl-core@openssl.org. 4954034eb2SDan OpenSolaris Anderson * 5054034eb2SDan OpenSolaris Anderson * 5. Products derived from this software may not be called "OpenSSL" 5154034eb2SDan OpenSolaris Anderson * nor may "OpenSSL" appear in their names without prior written 5254034eb2SDan OpenSolaris Anderson * permission of the OpenSSL Project. 5354034eb2SDan OpenSolaris Anderson * 5454034eb2SDan OpenSolaris Anderson * 6. Redistributions of any form whatsoever must retain the following 5554034eb2SDan OpenSolaris Anderson * acknowledgment: 5654034eb2SDan OpenSolaris Anderson * "This product includes software developed by the OpenSSL Project 5754034eb2SDan OpenSolaris Anderson * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 5854034eb2SDan OpenSolaris Anderson * 5954034eb2SDan OpenSolaris Anderson * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 6054034eb2SDan OpenSolaris Anderson * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 6154034eb2SDan OpenSolaris Anderson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 6254034eb2SDan OpenSolaris Anderson * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 6354034eb2SDan OpenSolaris Anderson * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 6454034eb2SDan OpenSolaris Anderson * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 6554034eb2SDan OpenSolaris Anderson * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 6654034eb2SDan OpenSolaris Anderson * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 6754034eb2SDan OpenSolaris Anderson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 6854034eb2SDan OpenSolaris Anderson * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 6954034eb2SDan OpenSolaris Anderson * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 7054034eb2SDan OpenSolaris Anderson * OF THE POSSIBILITY OF SUCH DAMAGE. 7154034eb2SDan OpenSolaris Anderson * ==================================================================== 7254034eb2SDan OpenSolaris Anderson */ 7354034eb2SDan OpenSolaris Anderson 7454034eb2SDan OpenSolaris Anderson/* 7554034eb2SDan OpenSolaris Anderson * ==================================================================== 7654034eb2SDan OpenSolaris Anderson * OpenSolaris OS modifications 7754034eb2SDan OpenSolaris Anderson * 7854034eb2SDan OpenSolaris Anderson * This source originates as files aes-intel.S and eng_aesni_asm.pl, in 7954034eb2SDan OpenSolaris Anderson * patches sent sent Dec. 9, 2008 and Dec. 24, 2008, respectively, by 8054034eb2SDan OpenSolaris Anderson * Huang Ying of Intel to the openssl-dev mailing list under the subject 8154034eb2SDan OpenSolaris Anderson * of "Add support to Intel AES-NI instruction set for x86_64 platform". 8254034eb2SDan OpenSolaris Anderson * 8354034eb2SDan OpenSolaris Anderson * This OpenSolaris version has these major changes from the original source: 8454034eb2SDan OpenSolaris Anderson * 8554034eb2SDan OpenSolaris Anderson * 1. Added OpenSolaris ENTRY_NP/SET_SIZE macros from 86*694c35faSJosef 'Jeff' Sipek * /usr/include/sys/asm_linkage.h, lint(1B) guards, and dummy C function 87*694c35faSJosef 'Jeff' Sipek * definitions for lint. 8854034eb2SDan OpenSolaris Anderson * 8954034eb2SDan OpenSolaris Anderson * 2. Formatted code, added comments, and added #includes and #defines. 9054034eb2SDan OpenSolaris Anderson * 918de5c4f4SDan OpenSolaris Anderson * 3. If bit CR0.TS is set, clear and set the TS bit, after and before 9254034eb2SDan OpenSolaris Anderson * calling kpreempt_disable() and kpreempt_enable(). 9354034eb2SDan OpenSolaris Anderson * If the TS bit is not set, Save and restore %xmm registers at the beginning 9454034eb2SDan OpenSolaris Anderson * and end of function calls (%xmm* registers are not saved and restored by 9554034eb2SDan OpenSolaris Anderson * during kernel thread preemption). 9654034eb2SDan OpenSolaris Anderson * 978de5c4f4SDan OpenSolaris Anderson * 4. Renamed functions, reordered parameters, and changed return value 9854034eb2SDan OpenSolaris Anderson * to match OpenSolaris: 9954034eb2SDan OpenSolaris Anderson * 10054034eb2SDan OpenSolaris Anderson * OpenSSL interface: 10154034eb2SDan OpenSolaris Anderson * int intel_AES_set_encrypt_key(const unsigned char *userKey, 10254034eb2SDan OpenSolaris Anderson * const int bits, AES_KEY *key); 10354034eb2SDan OpenSolaris Anderson * int intel_AES_set_decrypt_key(const unsigned char *userKey, 10454034eb2SDan OpenSolaris Anderson * const int bits, AES_KEY *key); 10554034eb2SDan OpenSolaris Anderson * Return values for above are non-zero on error, 0 on success. 10654034eb2SDan OpenSolaris Anderson * 10754034eb2SDan OpenSolaris Anderson * void intel_AES_encrypt(const unsigned char *in, unsigned char *out, 10854034eb2SDan OpenSolaris Anderson * const AES_KEY *key); 10954034eb2SDan OpenSolaris Anderson * void intel_AES_decrypt(const unsigned char *in, unsigned char *out, 11054034eb2SDan OpenSolaris Anderson * const AES_KEY *key); 11154034eb2SDan OpenSolaris Anderson * typedef struct aes_key_st { 11254034eb2SDan OpenSolaris Anderson * unsigned int rd_key[4 *(AES_MAXNR + 1)]; 11354034eb2SDan OpenSolaris Anderson * int rounds; 11454034eb2SDan OpenSolaris Anderson * unsigned int pad[3]; 11554034eb2SDan OpenSolaris Anderson * } AES_KEY; 11654034eb2SDan OpenSolaris Anderson * Note: AES_LONG is undefined (that is, Intel uses 32-bit key schedules 11754034eb2SDan OpenSolaris Anderson * (ks32) instead of 64-bit (ks64). 11854034eb2SDan OpenSolaris Anderson * Number of rounds (aka round count) is at offset 240 of AES_KEY. 11954034eb2SDan OpenSolaris Anderson * 12054034eb2SDan OpenSolaris Anderson * OpenSolaris OS interface (#ifdefs removed for readability): 12154034eb2SDan OpenSolaris Anderson * int rijndael_key_setup_dec_intel(uint32_t rk[], 12254034eb2SDan OpenSolaris Anderson * const uint32_t cipherKey[], uint64_t keyBits); 12354034eb2SDan OpenSolaris Anderson * int rijndael_key_setup_enc_intel(uint32_t rk[], 12454034eb2SDan OpenSolaris Anderson * const uint32_t cipherKey[], uint64_t keyBits); 12554034eb2SDan OpenSolaris Anderson * Return values for above are 0 on error, number of rounds on success. 12654034eb2SDan OpenSolaris Anderson * 12754034eb2SDan OpenSolaris Anderson * void aes_encrypt_intel(const aes_ks_t *ks, int Nr, 12854034eb2SDan OpenSolaris Anderson * const uint32_t pt[4], uint32_t ct[4]); 12954034eb2SDan OpenSolaris Anderson * void aes_decrypt_intel(const aes_ks_t *ks, int Nr, 13054034eb2SDan OpenSolaris Anderson * const uint32_t pt[4], uint32_t ct[4]); 13154034eb2SDan OpenSolaris Anderson * typedef union {uint64_t ks64[(MAX_AES_NR + 1) * 4]; 13254034eb2SDan OpenSolaris Anderson * uint32_t ks32[(MAX_AES_NR + 1) * 4]; } aes_ks_t; 13354034eb2SDan OpenSolaris Anderson * 13454034eb2SDan OpenSolaris Anderson * typedef union { 13554034eb2SDan OpenSolaris Anderson * uint32_t ks32[((MAX_AES_NR) + 1) * (MAX_AES_NB)]; 13654034eb2SDan OpenSolaris Anderson * } aes_ks_t; 13754034eb2SDan OpenSolaris Anderson * typedef struct aes_key { 13854034eb2SDan OpenSolaris Anderson * aes_ks_t encr_ks, decr_ks; 13954034eb2SDan OpenSolaris Anderson * long double align128; 14054034eb2SDan OpenSolaris Anderson * int flags, nr, type; 14154034eb2SDan OpenSolaris Anderson * } aes_key_t; 14254034eb2SDan OpenSolaris Anderson * 14354034eb2SDan OpenSolaris Anderson * Note: ks is the AES key schedule, Nr is number of rounds, pt is plain text, 14454034eb2SDan OpenSolaris Anderson * ct is crypto text, and MAX_AES_NR is 14. 14554034eb2SDan OpenSolaris Anderson * For the x86 64-bit architecture, OpenSolaris OS uses ks32 instead of ks64. 1468de5c4f4SDan OpenSolaris Anderson * 14754034eb2SDan OpenSolaris Anderson * Note2: aes_ks_t must be aligned on a 0 mod 128 byte boundary. 1488de5c4f4SDan OpenSolaris Anderson * 14954034eb2SDan OpenSolaris Anderson * ==================================================================== 15054034eb2SDan OpenSolaris Anderson */ 15154034eb2SDan OpenSolaris Anderson 15254034eb2SDan OpenSolaris Anderson#if defined(lint) || defined(__lint) 15354034eb2SDan OpenSolaris Anderson 15454034eb2SDan OpenSolaris Anderson#include <sys/types.h> 15554034eb2SDan OpenSolaris Anderson 15654034eb2SDan OpenSolaris Anderson/* ARGSUSED */ 15754034eb2SDan OpenSolaris Andersonvoid 15854034eb2SDan OpenSolaris Andersonaes_encrypt_intel(const uint32_t rk[], int Nr, const uint32_t pt[4], 15954034eb2SDan OpenSolaris Anderson uint32_t ct[4]) { 16054034eb2SDan OpenSolaris Anderson} 16154034eb2SDan OpenSolaris Anderson/* ARGSUSED */ 16254034eb2SDan OpenSolaris Andersonvoid 16354034eb2SDan OpenSolaris Andersonaes_decrypt_intel(const uint32_t rk[], int Nr, const uint32_t ct[4], 16454034eb2SDan OpenSolaris Anderson uint32_t pt[4]) { 16554034eb2SDan OpenSolaris Anderson} 16654034eb2SDan OpenSolaris Anderson/* ARGSUSED */ 16754034eb2SDan OpenSolaris Andersonint 16854034eb2SDan OpenSolaris Andersonrijndael_key_setup_enc_intel(uint32_t rk[], const uint32_t cipherKey[], 16954034eb2SDan OpenSolaris Anderson uint64_t keyBits) { 17054034eb2SDan OpenSolaris Anderson return (0); 17154034eb2SDan OpenSolaris Anderson} 17254034eb2SDan OpenSolaris Anderson/* ARGSUSED */ 17354034eb2SDan OpenSolaris Andersonint 17454034eb2SDan OpenSolaris Andersonrijndael_key_setup_dec_intel(uint32_t rk[], const uint32_t cipherKey[], 17554034eb2SDan OpenSolaris Anderson uint64_t keyBits) { 17654034eb2SDan OpenSolaris Anderson return (0); 17754034eb2SDan OpenSolaris Anderson} 17854034eb2SDan OpenSolaris Anderson 17954034eb2SDan OpenSolaris Anderson 18054034eb2SDan OpenSolaris Anderson#else /* lint */ 18154034eb2SDan OpenSolaris Anderson 18254034eb2SDan OpenSolaris Anderson#include <sys/asm_linkage.h> 18354034eb2SDan OpenSolaris Anderson#include <sys/controlregs.h> 18454034eb2SDan OpenSolaris Anderson#ifdef _KERNEL 18554034eb2SDan OpenSolaris Anderson#include <sys/machprivregs.h> 18654034eb2SDan OpenSolaris Anderson#endif 18754034eb2SDan OpenSolaris Anderson 18854034eb2SDan OpenSolaris Anderson#ifdef _KERNEL 18954034eb2SDan OpenSolaris Anderson /* 19054034eb2SDan OpenSolaris Anderson * Note: the CLTS macro clobbers P2 (%rsi) under i86xpv. That is, 19154034eb2SDan OpenSolaris Anderson * it calls HYPERVISOR_fpu_taskswitch() which modifies %rsi when it 19254034eb2SDan OpenSolaris Anderson * uses it to pass P2 to syscall. 19354034eb2SDan OpenSolaris Anderson * This also occurs with the STTS macro, but we don't care if 19454034eb2SDan OpenSolaris Anderson * P2 (%rsi) is modified just before function exit. 19554034eb2SDan OpenSolaris Anderson * The CLTS and STTS macros push and pop P1 (%rdi) already. 19654034eb2SDan OpenSolaris Anderson */ 19754034eb2SDan OpenSolaris Anderson#ifdef __xpv 19854034eb2SDan OpenSolaris Anderson#define PROTECTED_CLTS \ 19954034eb2SDan OpenSolaris Anderson push %rsi; \ 20054034eb2SDan OpenSolaris Anderson CLTS; \ 20154034eb2SDan OpenSolaris Anderson pop %rsi 20254034eb2SDan OpenSolaris Anderson#else 20354034eb2SDan OpenSolaris Anderson#define PROTECTED_CLTS \ 20454034eb2SDan OpenSolaris Anderson CLTS 20554034eb2SDan OpenSolaris Anderson#endif /* __xpv */ 20654034eb2SDan OpenSolaris Anderson 20754034eb2SDan OpenSolaris Anderson#define CLEAR_TS_OR_PUSH_XMM0_XMM1(tmpreg) \ 20854034eb2SDan OpenSolaris Anderson push %rbp; \ 20954034eb2SDan OpenSolaris Anderson mov %rsp, %rbp; \ 21054034eb2SDan OpenSolaris Anderson movq %cr0, tmpreg; \ 21154034eb2SDan OpenSolaris Anderson testq $CR0_TS, tmpreg; \ 21254034eb2SDan OpenSolaris Anderson jnz 1f; \ 21354034eb2SDan OpenSolaris Anderson and $-XMM_ALIGN, %rsp; \ 21454034eb2SDan OpenSolaris Anderson sub $[XMM_SIZE * 2], %rsp; \ 21554034eb2SDan OpenSolaris Anderson movaps %xmm0, 16(%rsp); \ 21654034eb2SDan OpenSolaris Anderson movaps %xmm1, (%rsp); \ 21754034eb2SDan OpenSolaris Anderson jmp 2f; \ 21854034eb2SDan OpenSolaris Anderson1: \ 21954034eb2SDan OpenSolaris Anderson PROTECTED_CLTS; \ 22054034eb2SDan OpenSolaris Anderson2: 22154034eb2SDan OpenSolaris Anderson 22254034eb2SDan OpenSolaris Anderson /* 22354034eb2SDan OpenSolaris Anderson * If CR0_TS was not set above, pop %xmm0 and %xmm1 off stack, 22454034eb2SDan OpenSolaris Anderson * otherwise set CR0_TS. 22554034eb2SDan OpenSolaris Anderson */ 22654034eb2SDan OpenSolaris Anderson#define SET_TS_OR_POP_XMM0_XMM1(tmpreg) \ 22754034eb2SDan OpenSolaris Anderson testq $CR0_TS, tmpreg; \ 22854034eb2SDan OpenSolaris Anderson jnz 1f; \ 22954034eb2SDan OpenSolaris Anderson movaps (%rsp), %xmm1; \ 23054034eb2SDan OpenSolaris Anderson movaps 16(%rsp), %xmm0; \ 23154034eb2SDan OpenSolaris Anderson jmp 2f; \ 23254034eb2SDan OpenSolaris Anderson1: \ 23354034eb2SDan OpenSolaris Anderson STTS(tmpreg); \ 23454034eb2SDan OpenSolaris Anderson2: \ 23554034eb2SDan OpenSolaris Anderson mov %rbp, %rsp; \ 23654034eb2SDan OpenSolaris Anderson pop %rbp 23754034eb2SDan OpenSolaris Anderson 23854034eb2SDan OpenSolaris Anderson /* 23954034eb2SDan OpenSolaris Anderson * If CR0_TS is not set, align stack (with push %rbp) and push 24054034eb2SDan OpenSolaris Anderson * %xmm0 - %xmm6 on stack, otherwise clear CR0_TS 24154034eb2SDan OpenSolaris Anderson */ 24254034eb2SDan OpenSolaris Anderson#define CLEAR_TS_OR_PUSH_XMM0_TO_XMM6(tmpreg) \ 24354034eb2SDan OpenSolaris Anderson push %rbp; \ 24454034eb2SDan OpenSolaris Anderson mov %rsp, %rbp; \ 24554034eb2SDan OpenSolaris Anderson movq %cr0, tmpreg; \ 24654034eb2SDan OpenSolaris Anderson testq $CR0_TS, tmpreg; \ 24754034eb2SDan OpenSolaris Anderson jnz 1f; \ 24854034eb2SDan OpenSolaris Anderson and $-XMM_ALIGN, %rsp; \ 24954034eb2SDan OpenSolaris Anderson sub $[XMM_SIZE * 7], %rsp; \ 25054034eb2SDan OpenSolaris Anderson movaps %xmm0, 96(%rsp); \ 25154034eb2SDan OpenSolaris Anderson movaps %xmm1, 80(%rsp); \ 25254034eb2SDan OpenSolaris Anderson movaps %xmm2, 64(%rsp); \ 25354034eb2SDan OpenSolaris Anderson movaps %xmm3, 48(%rsp); \ 25454034eb2SDan OpenSolaris Anderson movaps %xmm4, 32(%rsp); \ 25554034eb2SDan OpenSolaris Anderson movaps %xmm5, 16(%rsp); \ 25654034eb2SDan OpenSolaris Anderson movaps %xmm6, (%rsp); \ 25754034eb2SDan OpenSolaris Anderson jmp 2f; \ 25854034eb2SDan OpenSolaris Anderson1: \ 25954034eb2SDan OpenSolaris Anderson PROTECTED_CLTS; \ 26054034eb2SDan OpenSolaris Anderson2: 26154034eb2SDan OpenSolaris Anderson 26254034eb2SDan OpenSolaris Anderson 26354034eb2SDan OpenSolaris Anderson /* 26454034eb2SDan OpenSolaris Anderson * If CR0_TS was not set above, pop %xmm0 - %xmm6 off stack, 26554034eb2SDan OpenSolaris Anderson * otherwise set CR0_TS. 26654034eb2SDan OpenSolaris Anderson */ 26754034eb2SDan OpenSolaris Anderson#define SET_TS_OR_POP_XMM0_TO_XMM6(tmpreg) \ 26854034eb2SDan OpenSolaris Anderson testq $CR0_TS, tmpreg; \ 26954034eb2SDan OpenSolaris Anderson jnz 1f; \ 27054034eb2SDan OpenSolaris Anderson movaps (%rsp), %xmm6; \ 27154034eb2SDan OpenSolaris Anderson movaps 16(%rsp), %xmm5; \ 27254034eb2SDan OpenSolaris Anderson movaps 32(%rsp), %xmm4; \ 27354034eb2SDan OpenSolaris Anderson movaps 48(%rsp), %xmm3; \ 27454034eb2SDan OpenSolaris Anderson movaps 64(%rsp), %xmm2; \ 27554034eb2SDan OpenSolaris Anderson movaps 80(%rsp), %xmm1; \ 27654034eb2SDan OpenSolaris Anderson movaps 96(%rsp), %xmm0; \ 27754034eb2SDan OpenSolaris Anderson jmp 2f; \ 27854034eb2SDan OpenSolaris Anderson1: \ 27954034eb2SDan OpenSolaris Anderson STTS(tmpreg); \ 28054034eb2SDan OpenSolaris Anderson2: \ 28154034eb2SDan OpenSolaris Anderson mov %rbp, %rsp; \ 28254034eb2SDan OpenSolaris Anderson pop %rbp 28354034eb2SDan OpenSolaris Anderson 28454034eb2SDan OpenSolaris Anderson 28554034eb2SDan OpenSolaris Anderson#else 28654034eb2SDan OpenSolaris Anderson#define PROTECTED_CLTS 28754034eb2SDan OpenSolaris Anderson#define CLEAR_TS_OR_PUSH_XMM0_XMM1(tmpreg) 28854034eb2SDan OpenSolaris Anderson#define SET_TS_OR_POP_XMM0_XMM1(tmpreg) 28954034eb2SDan OpenSolaris Anderson#define CLEAR_TS_OR_PUSH_XMM0_TO_XMM6(tmpreg) 29054034eb2SDan OpenSolaris Anderson#define SET_TS_OR_POP_XMM0_TO_XMM6(tmpreg) 29154034eb2SDan OpenSolaris Anderson#endif /* _KERNEL */ 29254034eb2SDan OpenSolaris Anderson 29354034eb2SDan OpenSolaris Anderson 29454034eb2SDan OpenSolaris Anderson/* 29554034eb2SDan OpenSolaris Anderson * _key_expansion_128(), * _key_expansion_192a(), _key_expansion_192b(), 29654034eb2SDan OpenSolaris Anderson * _key_expansion_256a(), _key_expansion_256b() 29754034eb2SDan OpenSolaris Anderson * 29854034eb2SDan OpenSolaris Anderson * Helper functions called by rijndael_key_setup_inc_intel(). 29954034eb2SDan OpenSolaris Anderson * Also used indirectly by rijndael_key_setup_dec_intel(). 30054034eb2SDan OpenSolaris Anderson * 30154034eb2SDan OpenSolaris Anderson * Input: 30254034eb2SDan OpenSolaris Anderson * %xmm0 User-provided cipher key 30354034eb2SDan OpenSolaris Anderson * %xmm1 Round constant 30454034eb2SDan OpenSolaris Anderson * Output: 30554034eb2SDan OpenSolaris Anderson * (%rcx) AES key 30654034eb2SDan OpenSolaris Anderson */ 30754034eb2SDan OpenSolaris Anderson 30854034eb2SDan OpenSolaris Anderson.align 16 30954034eb2SDan OpenSolaris Anderson_key_expansion_128: 31054034eb2SDan OpenSolaris Anderson_key_expansion_256a: 31154034eb2SDan OpenSolaris Anderson pshufd $0b11111111, %xmm1, %xmm1 31254034eb2SDan OpenSolaris Anderson shufps $0b00010000, %xmm0, %xmm4 31354034eb2SDan OpenSolaris Anderson pxor %xmm4, %xmm0 31454034eb2SDan OpenSolaris Anderson shufps $0b10001100, %xmm0, %xmm4 31554034eb2SDan OpenSolaris Anderson pxor %xmm4, %xmm0 31654034eb2SDan OpenSolaris Anderson pxor %xmm1, %xmm0 31754034eb2SDan OpenSolaris Anderson movaps %xmm0, (%rcx) 31854034eb2SDan OpenSolaris Anderson add $0x10, %rcx 31954034eb2SDan OpenSolaris Anderson ret 32054034eb2SDan OpenSolaris Anderson SET_SIZE(_key_expansion_128) 32154034eb2SDan OpenSolaris Anderson SET_SIZE(_key_expansion_256a) 32254034eb2SDan OpenSolaris Anderson 32354034eb2SDan OpenSolaris Anderson.align 16 32454034eb2SDan OpenSolaris Anderson_key_expansion_192a: 32554034eb2SDan OpenSolaris Anderson pshufd $0b01010101, %xmm1, %xmm1 32654034eb2SDan OpenSolaris Anderson shufps $0b00010000, %xmm0, %xmm4 32754034eb2SDan OpenSolaris Anderson pxor %xmm4, %xmm0 32854034eb2SDan OpenSolaris Anderson shufps $0b10001100, %xmm0, %xmm4 32954034eb2SDan OpenSolaris Anderson pxor %xmm4, %xmm0 33054034eb2SDan OpenSolaris Anderson pxor %xmm1, %xmm0 33154034eb2SDan OpenSolaris Anderson 33254034eb2SDan OpenSolaris Anderson movaps %xmm2, %xmm5 33354034eb2SDan OpenSolaris Anderson movaps %xmm2, %xmm6 33454034eb2SDan OpenSolaris Anderson pslldq $4, %xmm5 33554034eb2SDan OpenSolaris Anderson pshufd $0b11111111, %xmm0, %xmm3 33654034eb2SDan OpenSolaris Anderson pxor %xmm3, %xmm2 33754034eb2SDan OpenSolaris Anderson pxor %xmm5, %xmm2 33854034eb2SDan OpenSolaris Anderson 33954034eb2SDan OpenSolaris Anderson movaps %xmm0, %xmm1 34054034eb2SDan OpenSolaris Anderson shufps $0b01000100, %xmm0, %xmm6 34154034eb2SDan OpenSolaris Anderson movaps %xmm6, (%rcx) 34254034eb2SDan OpenSolaris Anderson shufps $0b01001110, %xmm2, %xmm1 34354034eb2SDan OpenSolaris Anderson movaps %xmm1, 0x10(%rcx) 34454034eb2SDan OpenSolaris Anderson add $0x20, %rcx 34554034eb2SDan OpenSolaris Anderson ret 34654034eb2SDan OpenSolaris Anderson SET_SIZE(_key_expansion_192a) 34754034eb2SDan OpenSolaris Anderson 34854034eb2SDan OpenSolaris Anderson.align 16 34954034eb2SDan OpenSolaris Anderson_key_expansion_192b: 35054034eb2SDan OpenSolaris Anderson pshufd $0b01010101, %xmm1, %xmm1 35154034eb2SDan OpenSolaris Anderson shufps $0b00010000, %xmm0, %xmm4 35254034eb2SDan OpenSolaris Anderson pxor %xmm4, %xmm0 35354034eb2SDan OpenSolaris Anderson shufps $0b10001100, %xmm0, %xmm4 35454034eb2SDan OpenSolaris Anderson pxor %xmm4, %xmm0 35554034eb2SDan OpenSolaris Anderson pxor %xmm1, %xmm0 35654034eb2SDan OpenSolaris Anderson 35754034eb2SDan OpenSolaris Anderson movaps %xmm2, %xmm5 35854034eb2SDan OpenSolaris Anderson pslldq $4, %xmm5 35954034eb2SDan OpenSolaris Anderson pshufd $0b11111111, %xmm0, %xmm3 36054034eb2SDan OpenSolaris Anderson pxor %xmm3, %xmm2 36154034eb2SDan OpenSolaris Anderson pxor %xmm5, %xmm2 36254034eb2SDan OpenSolaris Anderson 36354034eb2SDan OpenSolaris Anderson movaps %xmm0, (%rcx) 36454034eb2SDan OpenSolaris Anderson add $0x10, %rcx 36554034eb2SDan OpenSolaris Anderson ret 36654034eb2SDan OpenSolaris Anderson SET_SIZE(_key_expansion_192b) 36754034eb2SDan OpenSolaris Anderson 36854034eb2SDan OpenSolaris Anderson.align 16 36954034eb2SDan OpenSolaris Anderson_key_expansion_256b: 37054034eb2SDan OpenSolaris Anderson pshufd $0b10101010, %xmm1, %xmm1 37154034eb2SDan OpenSolaris Anderson shufps $0b00010000, %xmm2, %xmm4 37254034eb2SDan OpenSolaris Anderson pxor %xmm4, %xmm2 37354034eb2SDan OpenSolaris Anderson shufps $0b10001100, %xmm2, %xmm4 37454034eb2SDan OpenSolaris Anderson pxor %xmm4, %xmm2 37554034eb2SDan OpenSolaris Anderson pxor %xmm1, %xmm2 37654034eb2SDan OpenSolaris Anderson movaps %xmm2, (%rcx) 37754034eb2SDan OpenSolaris Anderson add $0x10, %rcx 37854034eb2SDan OpenSolaris Anderson ret 37954034eb2SDan OpenSolaris Anderson SET_SIZE(_key_expansion_256b) 38054034eb2SDan OpenSolaris Anderson 38154034eb2SDan OpenSolaris Anderson 38254034eb2SDan OpenSolaris Anderson/* 38354034eb2SDan OpenSolaris Anderson * rijndael_key_setup_enc_intel() 38454034eb2SDan OpenSolaris Anderson * Expand the cipher key into the encryption key schedule. 38554034eb2SDan OpenSolaris Anderson * 38654034eb2SDan OpenSolaris Anderson * For kernel code, caller is responsible for ensuring kpreempt_disable() 38754034eb2SDan OpenSolaris Anderson * has been called. This is because %xmm registers are not saved/restored. 38854034eb2SDan OpenSolaris Anderson * Clear and set the CR0.TS bit on entry and exit, respectively, if TS is set 38954034eb2SDan OpenSolaris Anderson * on entry. Otherwise, if TS is not set, save and restore %xmm registers 39054034eb2SDan OpenSolaris Anderson * on the stack. 39154034eb2SDan OpenSolaris Anderson * 39254034eb2SDan OpenSolaris Anderson * OpenSolaris interface: 39354034eb2SDan OpenSolaris Anderson * int rijndael_key_setup_enc_intel(uint32_t rk[], const uint32_t cipherKey[], 39454034eb2SDan OpenSolaris Anderson * uint64_t keyBits); 39554034eb2SDan OpenSolaris Anderson * Return value is 0 on error, number of rounds on success. 39654034eb2SDan OpenSolaris Anderson * 39754034eb2SDan OpenSolaris Anderson * Original Intel OpenSSL interface: 39854034eb2SDan OpenSolaris Anderson * int intel_AES_set_encrypt_key(const unsigned char *userKey, 39954034eb2SDan OpenSolaris Anderson * const int bits, AES_KEY *key); 40054034eb2SDan OpenSolaris Anderson * Return value is non-zero on error, 0 on success. 40154034eb2SDan OpenSolaris Anderson */ 40254034eb2SDan OpenSolaris Anderson 40354034eb2SDan OpenSolaris Anderson#ifdef OPENSSL_INTERFACE 40454034eb2SDan OpenSolaris Anderson#define rijndael_key_setup_enc_intel intel_AES_set_encrypt_key 40554034eb2SDan OpenSolaris Anderson#define rijndael_key_setup_dec_intel intel_AES_set_decrypt_key 40654034eb2SDan OpenSolaris Anderson 40754034eb2SDan OpenSolaris Anderson#define USERCIPHERKEY rdi /* P1, 64 bits */ 40854034eb2SDan OpenSolaris Anderson#define KEYSIZE32 esi /* P2, 32 bits */ 40954034eb2SDan OpenSolaris Anderson#define KEYSIZE64 rsi /* P2, 64 bits */ 41054034eb2SDan OpenSolaris Anderson#define AESKEY rdx /* P3, 64 bits */ 41154034eb2SDan OpenSolaris Anderson 41254034eb2SDan OpenSolaris Anderson#else /* OpenSolaris Interface */ 41354034eb2SDan OpenSolaris Anderson#define AESKEY rdi /* P1, 64 bits */ 41454034eb2SDan OpenSolaris Anderson#define USERCIPHERKEY rsi /* P2, 64 bits */ 41554034eb2SDan OpenSolaris Anderson#define KEYSIZE32 edx /* P3, 32 bits */ 41654034eb2SDan OpenSolaris Anderson#define KEYSIZE64 rdx /* P3, 64 bits */ 41754034eb2SDan OpenSolaris Anderson#endif /* OPENSSL_INTERFACE */ 41854034eb2SDan OpenSolaris Anderson 41954034eb2SDan OpenSolaris Anderson#define ROUNDS32 KEYSIZE32 /* temp */ 42054034eb2SDan OpenSolaris Anderson#define ROUNDS64 KEYSIZE64 /* temp */ 42154034eb2SDan OpenSolaris Anderson#define ENDAESKEY USERCIPHERKEY /* temp */ 42254034eb2SDan OpenSolaris Anderson 42354034eb2SDan OpenSolaris Anderson 42454034eb2SDan OpenSolaris AndersonENTRY_NP(rijndael_key_setup_enc_intel) 42554034eb2SDan OpenSolaris Anderson CLEAR_TS_OR_PUSH_XMM0_TO_XMM6(%r10) 42654034eb2SDan OpenSolaris Anderson 42754034eb2SDan OpenSolaris Anderson / NULL pointer sanity check 42854034eb2SDan OpenSolaris Anderson test %USERCIPHERKEY, %USERCIPHERKEY 42954034eb2SDan OpenSolaris Anderson jz .Lenc_key_invalid_param 43054034eb2SDan OpenSolaris Anderson test %AESKEY, %AESKEY 43154034eb2SDan OpenSolaris Anderson jz .Lenc_key_invalid_param 43254034eb2SDan OpenSolaris Anderson 43354034eb2SDan OpenSolaris Anderson movups (%USERCIPHERKEY), %xmm0 / user key (first 16 bytes) 43454034eb2SDan OpenSolaris Anderson movaps %xmm0, (%AESKEY) 43554034eb2SDan OpenSolaris Anderson lea 0x10(%AESKEY), %rcx / key addr 43654034eb2SDan OpenSolaris Anderson pxor %xmm4, %xmm4 / xmm4 is assumed 0 in _key_expansion_x 43754034eb2SDan OpenSolaris Anderson 43854034eb2SDan OpenSolaris Anderson cmp $256, %KEYSIZE32 43954034eb2SDan OpenSolaris Anderson jnz .Lenc_key192 44054034eb2SDan OpenSolaris Anderson 4418de5c4f4SDan OpenSolaris Anderson / AES 256: 14 rounds in encryption key schedule 44254034eb2SDan OpenSolaris Anderson#ifdef OPENSSL_INTERFACE 44354034eb2SDan OpenSolaris Anderson mov $14, %ROUNDS32 44454034eb2SDan OpenSolaris Anderson movl %ROUNDS32, 240(%AESKEY) / key.rounds = 14 44554034eb2SDan OpenSolaris Anderson#endif /* OPENSSL_INTERFACE */ 44654034eb2SDan OpenSolaris Anderson 44754034eb2SDan OpenSolaris Anderson movups 0x10(%USERCIPHERKEY), %xmm2 / other user key (2nd 16 bytes) 44854034eb2SDan OpenSolaris Anderson movaps %xmm2, (%rcx) 44954034eb2SDan OpenSolaris Anderson add $0x10, %rcx 45054034eb2SDan OpenSolaris Anderson 4518de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x1, %xmm2, %xmm1 / expand the key 45254034eb2SDan OpenSolaris Anderson call _key_expansion_256a 4538de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x1, %xmm0, %xmm1 45454034eb2SDan OpenSolaris Anderson call _key_expansion_256b 4558de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x2, %xmm2, %xmm1 / expand the key 45654034eb2SDan OpenSolaris Anderson call _key_expansion_256a 4578de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x2, %xmm0, %xmm1 45854034eb2SDan OpenSolaris Anderson call _key_expansion_256b 4598de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x4, %xmm2, %xmm1 / expand the key 46054034eb2SDan OpenSolaris Anderson call _key_expansion_256a 4618de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x4, %xmm0, %xmm1 46254034eb2SDan OpenSolaris Anderson call _key_expansion_256b 4638de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x8, %xmm2, %xmm1 / expand the key 46454034eb2SDan OpenSolaris Anderson call _key_expansion_256a 4658de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x8, %xmm0, %xmm1 46654034eb2SDan OpenSolaris Anderson call _key_expansion_256b 4678de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x10, %xmm2, %xmm1 / expand the key 46854034eb2SDan OpenSolaris Anderson call _key_expansion_256a 4698de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x10, %xmm0, %xmm1 47054034eb2SDan OpenSolaris Anderson call _key_expansion_256b 4718de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x20, %xmm2, %xmm1 / expand the key 47254034eb2SDan OpenSolaris Anderson call _key_expansion_256a 4738de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x20, %xmm0, %xmm1 47454034eb2SDan OpenSolaris Anderson call _key_expansion_256b 4758de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x40, %xmm2, %xmm1 / expand the key 47654034eb2SDan OpenSolaris Anderson call _key_expansion_256a 47754034eb2SDan OpenSolaris Anderson 47854034eb2SDan OpenSolaris Anderson SET_TS_OR_POP_XMM0_TO_XMM6(%r10) 47954034eb2SDan OpenSolaris Anderson#ifdef OPENSSL_INTERFACE 48054034eb2SDan OpenSolaris Anderson xor %rax, %rax / return 0 (OK) 48154034eb2SDan OpenSolaris Anderson#else /* Open Solaris Interface */ 48254034eb2SDan OpenSolaris Anderson mov $14, %rax / return # rounds = 14 48354034eb2SDan OpenSolaris Anderson#endif 48454034eb2SDan OpenSolaris Anderson ret 48554034eb2SDan OpenSolaris Anderson 48654034eb2SDan OpenSolaris Anderson.align 4 48754034eb2SDan OpenSolaris Anderson.Lenc_key192: 48854034eb2SDan OpenSolaris Anderson cmp $192, %KEYSIZE32 48954034eb2SDan OpenSolaris Anderson jnz .Lenc_key128 49054034eb2SDan OpenSolaris Anderson 4918de5c4f4SDan OpenSolaris Anderson / AES 192: 12 rounds in encryption key schedule 49254034eb2SDan OpenSolaris Anderson#ifdef OPENSSL_INTERFACE 49354034eb2SDan OpenSolaris Anderson mov $12, %ROUNDS32 49454034eb2SDan OpenSolaris Anderson movl %ROUNDS32, 240(%AESKEY) / key.rounds = 12 49554034eb2SDan OpenSolaris Anderson#endif /* OPENSSL_INTERFACE */ 49654034eb2SDan OpenSolaris Anderson 49754034eb2SDan OpenSolaris Anderson movq 0x10(%USERCIPHERKEY), %xmm2 / other user key 4988de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x1, %xmm2, %xmm1 / expand the key 49954034eb2SDan OpenSolaris Anderson call _key_expansion_192a 5008de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x2, %xmm2, %xmm1 / expand the key 50154034eb2SDan OpenSolaris Anderson call _key_expansion_192b 5028de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x4, %xmm2, %xmm1 / expand the key 50354034eb2SDan OpenSolaris Anderson call _key_expansion_192a 5048de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x8, %xmm2, %xmm1 / expand the key 50554034eb2SDan OpenSolaris Anderson call _key_expansion_192b 5068de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x10, %xmm2, %xmm1 / expand the key 50754034eb2SDan OpenSolaris Anderson call _key_expansion_192a 5088de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x20, %xmm2, %xmm1 / expand the key 50954034eb2SDan OpenSolaris Anderson call _key_expansion_192b 5108de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x40, %xmm2, %xmm1 / expand the key 51154034eb2SDan OpenSolaris Anderson call _key_expansion_192a 5128de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x80, %xmm2, %xmm1 / expand the key 51354034eb2SDan OpenSolaris Anderson call _key_expansion_192b 51454034eb2SDan OpenSolaris Anderson 51554034eb2SDan OpenSolaris Anderson SET_TS_OR_POP_XMM0_TO_XMM6(%r10) 51654034eb2SDan OpenSolaris Anderson#ifdef OPENSSL_INTERFACE 51754034eb2SDan OpenSolaris Anderson xor %rax, %rax / return 0 (OK) 51854034eb2SDan OpenSolaris Anderson#else /* OpenSolaris Interface */ 51954034eb2SDan OpenSolaris Anderson mov $12, %rax / return # rounds = 12 52054034eb2SDan OpenSolaris Anderson#endif 52154034eb2SDan OpenSolaris Anderson ret 52254034eb2SDan OpenSolaris Anderson 52354034eb2SDan OpenSolaris Anderson.align 4 52454034eb2SDan OpenSolaris Anderson.Lenc_key128: 52554034eb2SDan OpenSolaris Anderson cmp $128, %KEYSIZE32 52654034eb2SDan OpenSolaris Anderson jnz .Lenc_key_invalid_key_bits 5278de5c4f4SDan OpenSolaris Anderson 5288de5c4f4SDan OpenSolaris Anderson / AES 128: 10 rounds in encryption key schedule 52954034eb2SDan OpenSolaris Anderson#ifdef OPENSSL_INTERFACE 53054034eb2SDan OpenSolaris Anderson mov $10, %ROUNDS32 53154034eb2SDan OpenSolaris Anderson movl %ROUNDS32, 240(%AESKEY) / key.rounds = 10 53254034eb2SDan OpenSolaris Anderson#endif /* OPENSSL_INTERFACE */ 53354034eb2SDan OpenSolaris Anderson 5348de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x1, %xmm0, %xmm1 / expand the key 53554034eb2SDan OpenSolaris Anderson call _key_expansion_128 5368de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x2, %xmm0, %xmm1 / expand the key 53754034eb2SDan OpenSolaris Anderson call _key_expansion_128 5388de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x4, %xmm0, %xmm1 / expand the key 53954034eb2SDan OpenSolaris Anderson call _key_expansion_128 5408de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x8, %xmm0, %xmm1 / expand the key 54154034eb2SDan OpenSolaris Anderson call _key_expansion_128 5428de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x10, %xmm0, %xmm1 / expand the key 54354034eb2SDan OpenSolaris Anderson call _key_expansion_128 5448de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x20, %xmm0, %xmm1 / expand the key 54554034eb2SDan OpenSolaris Anderson call _key_expansion_128 5468de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x40, %xmm0, %xmm1 / expand the key 54754034eb2SDan OpenSolaris Anderson call _key_expansion_128 5488de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x80, %xmm0, %xmm1 / expand the key 54954034eb2SDan OpenSolaris Anderson call _key_expansion_128 5508de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x1b, %xmm0, %xmm1 / expand the key 55154034eb2SDan OpenSolaris Anderson call _key_expansion_128 5528de5c4f4SDan OpenSolaris Anderson aeskeygenassist $0x36, %xmm0, %xmm1 / expand the key 55354034eb2SDan OpenSolaris Anderson call _key_expansion_128 55454034eb2SDan OpenSolaris Anderson 55554034eb2SDan OpenSolaris Anderson SET_TS_OR_POP_XMM0_TO_XMM6(%r10) 55654034eb2SDan OpenSolaris Anderson#ifdef OPENSSL_INTERFACE 55754034eb2SDan OpenSolaris Anderson xor %rax, %rax / return 0 (OK) 55854034eb2SDan OpenSolaris Anderson#else /* OpenSolaris Interface */ 55954034eb2SDan OpenSolaris Anderson mov $10, %rax / return # rounds = 10 56054034eb2SDan OpenSolaris Anderson#endif 56154034eb2SDan OpenSolaris Anderson ret 56254034eb2SDan OpenSolaris Anderson 56354034eb2SDan OpenSolaris Anderson.Lenc_key_invalid_param: 56454034eb2SDan OpenSolaris Anderson#ifdef OPENSSL_INTERFACE 56554034eb2SDan OpenSolaris Anderson SET_TS_OR_POP_XMM0_TO_XMM6(%r10) 56654034eb2SDan OpenSolaris Anderson mov $-1, %rax / user key or AES key pointer is NULL 56754034eb2SDan OpenSolaris Anderson ret 56854034eb2SDan OpenSolaris Anderson#else 56954034eb2SDan OpenSolaris Anderson /* FALLTHROUGH */ 57054034eb2SDan OpenSolaris Anderson#endif /* OPENSSL_INTERFACE */ 57154034eb2SDan OpenSolaris Anderson 57254034eb2SDan OpenSolaris Anderson.Lenc_key_invalid_key_bits: 57354034eb2SDan OpenSolaris Anderson SET_TS_OR_POP_XMM0_TO_XMM6(%r10) 57454034eb2SDan OpenSolaris Anderson#ifdef OPENSSL_INTERFACE 57554034eb2SDan OpenSolaris Anderson mov $-2, %rax / keysize is invalid 57654034eb2SDan OpenSolaris Anderson#else /* Open Solaris Interface */ 57754034eb2SDan OpenSolaris Anderson xor %rax, %rax / a key pointer is NULL or invalid keysize 57854034eb2SDan OpenSolaris Anderson#endif /* OPENSSL_INTERFACE */ 57954034eb2SDan OpenSolaris Anderson 58054034eb2SDan OpenSolaris Anderson ret 58154034eb2SDan OpenSolaris Anderson SET_SIZE(rijndael_key_setup_enc_intel) 58254034eb2SDan OpenSolaris Anderson 58354034eb2SDan OpenSolaris Anderson 58454034eb2SDan OpenSolaris Anderson/* 58554034eb2SDan OpenSolaris Anderson * rijndael_key_setup_dec_intel() 58654034eb2SDan OpenSolaris Anderson * Expand the cipher key into the decryption key schedule. 58754034eb2SDan OpenSolaris Anderson * 58854034eb2SDan OpenSolaris Anderson * For kernel code, caller is responsible for ensuring kpreempt_disable() 58954034eb2SDan OpenSolaris Anderson * has been called. This is because %xmm registers are not saved/restored. 59054034eb2SDan OpenSolaris Anderson * Clear and set the CR0.TS bit on entry and exit, respectively, if TS is set 59154034eb2SDan OpenSolaris Anderson * on entry. Otherwise, if TS is not set, save and restore %xmm registers 59254034eb2SDan OpenSolaris Anderson * on the stack. 59354034eb2SDan OpenSolaris Anderson * 59454034eb2SDan OpenSolaris Anderson * OpenSolaris interface: 59554034eb2SDan OpenSolaris Anderson * int rijndael_key_setup_dec_intel(uint32_t rk[], const uint32_t cipherKey[], 59654034eb2SDan OpenSolaris Anderson * uint64_t keyBits); 59754034eb2SDan OpenSolaris Anderson * Return value is 0 on error, number of rounds on success. 59854034eb2SDan OpenSolaris Anderson * P1->P2, P2->P3, P3->P1 59954034eb2SDan OpenSolaris Anderson * 60054034eb2SDan OpenSolaris Anderson * Original Intel OpenSSL interface: 60154034eb2SDan OpenSolaris Anderson * int intel_AES_set_decrypt_key(const unsigned char *userKey, 60254034eb2SDan OpenSolaris Anderson * const int bits, AES_KEY *key); 60354034eb2SDan OpenSolaris Anderson * Return value is non-zero on error, 0 on success. 60454034eb2SDan OpenSolaris Anderson */ 60554034eb2SDan OpenSolaris AndersonENTRY_NP(rijndael_key_setup_dec_intel) 6068de5c4f4SDan OpenSolaris Anderson / Generate round keys used for encryption 60754034eb2SDan OpenSolaris Anderson call rijndael_key_setup_enc_intel 60854034eb2SDan OpenSolaris Anderson test %rax, %rax 60954034eb2SDan OpenSolaris Anderson#ifdef OPENSSL_INTERFACE 61054034eb2SDan OpenSolaris Anderson jnz .Ldec_key_exit / Failed if returned non-0 61154034eb2SDan OpenSolaris Anderson#else /* OpenSolaris Interface */ 61254034eb2SDan OpenSolaris Anderson jz .Ldec_key_exit / Failed if returned 0 61354034eb2SDan OpenSolaris Anderson#endif /* OPENSSL_INTERFACE */ 61454034eb2SDan OpenSolaris Anderson 61554034eb2SDan OpenSolaris Anderson CLEAR_TS_OR_PUSH_XMM0_XMM1(%r10) 61654034eb2SDan OpenSolaris Anderson 6178de5c4f4SDan OpenSolaris Anderson /* 6188de5c4f4SDan OpenSolaris Anderson * Convert round keys used for encryption 6198de5c4f4SDan OpenSolaris Anderson * to a form usable for decryption 6208de5c4f4SDan OpenSolaris Anderson */ 62154034eb2SDan OpenSolaris Anderson#ifndef OPENSSL_INTERFACE /* OpenSolaris Interface */ 62254034eb2SDan OpenSolaris Anderson mov %rax, %ROUNDS64 / set # rounds (10, 12, or 14) 62354034eb2SDan OpenSolaris Anderson / (already set for OpenSSL) 62454034eb2SDan OpenSolaris Anderson#endif 62554034eb2SDan OpenSolaris Anderson 62654034eb2SDan OpenSolaris Anderson lea 0x10(%AESKEY), %rcx / key addr 62754034eb2SDan OpenSolaris Anderson shl $4, %ROUNDS32 62854034eb2SDan OpenSolaris Anderson add %AESKEY, %ROUNDS64 62954034eb2SDan OpenSolaris Anderson mov %ROUNDS64, %ENDAESKEY 63054034eb2SDan OpenSolaris Anderson 63154034eb2SDan OpenSolaris Anderson.align 4 63254034eb2SDan OpenSolaris Anderson.Ldec_key_reorder_loop: 63354034eb2SDan OpenSolaris Anderson movaps (%AESKEY), %xmm0 63454034eb2SDan OpenSolaris Anderson movaps (%ROUNDS64), %xmm1 63554034eb2SDan OpenSolaris Anderson movaps %xmm0, (%ROUNDS64) 63654034eb2SDan OpenSolaris Anderson movaps %xmm1, (%AESKEY) 63754034eb2SDan OpenSolaris Anderson lea 0x10(%AESKEY), %AESKEY 63854034eb2SDan OpenSolaris Anderson lea -0x10(%ROUNDS64), %ROUNDS64 63954034eb2SDan OpenSolaris Anderson cmp %AESKEY, %ROUNDS64 64054034eb2SDan OpenSolaris Anderson ja .Ldec_key_reorder_loop 64154034eb2SDan OpenSolaris Anderson 64254034eb2SDan OpenSolaris Anderson.align 4 64354034eb2SDan OpenSolaris Anderson.Ldec_key_inv_loop: 64454034eb2SDan OpenSolaris Anderson movaps (%rcx), %xmm0 6458de5c4f4SDan OpenSolaris Anderson / Convert an encryption round key to a form usable for decryption 6468de5c4f4SDan OpenSolaris Anderson / with the "AES Inverse Mix Columns" instruction 6478de5c4f4SDan OpenSolaris Anderson aesimc %xmm0, %xmm1 64854034eb2SDan OpenSolaris Anderson movaps %xmm1, (%rcx) 64954034eb2SDan OpenSolaris Anderson lea 0x10(%rcx), %rcx 65054034eb2SDan OpenSolaris Anderson cmp %ENDAESKEY, %rcx 65154034eb2SDan OpenSolaris Anderson jnz .Ldec_key_inv_loop 65254034eb2SDan OpenSolaris Anderson 65354034eb2SDan OpenSolaris Anderson SET_TS_OR_POP_XMM0_XMM1(%r10) 65454034eb2SDan OpenSolaris Anderson 65554034eb2SDan OpenSolaris Anderson.Ldec_key_exit: 65654034eb2SDan OpenSolaris Anderson / OpenSolaris: rax = # rounds (10, 12, or 14) or 0 for error 65754034eb2SDan OpenSolaris Anderson / OpenSSL: rax = 0 for OK, or non-zero for error 65854034eb2SDan OpenSolaris Anderson ret 65954034eb2SDan OpenSolaris Anderson SET_SIZE(rijndael_key_setup_dec_intel) 66054034eb2SDan OpenSolaris Anderson 66154034eb2SDan OpenSolaris Anderson 66254034eb2SDan OpenSolaris Anderson/* 66354034eb2SDan OpenSolaris Anderson * aes_encrypt_intel() 66454034eb2SDan OpenSolaris Anderson * Encrypt a single block (in and out can overlap). 66554034eb2SDan OpenSolaris Anderson * 66654034eb2SDan OpenSolaris Anderson * For kernel code, caller is responsible for ensuring kpreempt_disable() 66754034eb2SDan OpenSolaris Anderson * has been called. This is because %xmm registers are not saved/restored. 66854034eb2SDan OpenSolaris Anderson * Clear and set the CR0.TS bit on entry and exit, respectively, if TS is set 66954034eb2SDan OpenSolaris Anderson * on entry. Otherwise, if TS is not set, save and restore %xmm registers 67054034eb2SDan OpenSolaris Anderson * on the stack. 67154034eb2SDan OpenSolaris Anderson * 67254034eb2SDan OpenSolaris Anderson * Temporary register usage: 67354034eb2SDan OpenSolaris Anderson * %xmm0 State 67454034eb2SDan OpenSolaris Anderson * %xmm1 Key 67554034eb2SDan OpenSolaris Anderson * 67654034eb2SDan OpenSolaris Anderson * Original OpenSolaris Interface: 67754034eb2SDan OpenSolaris Anderson * void aes_encrypt_intel(const aes_ks_t *ks, int Nr, 67854034eb2SDan OpenSolaris Anderson * const uint32_t pt[4], uint32_t ct[4]) 67954034eb2SDan OpenSolaris Anderson * 68054034eb2SDan OpenSolaris Anderson * Original Intel OpenSSL Interface: 68154034eb2SDan OpenSolaris Anderson * void intel_AES_encrypt(const unsigned char *in, unsigned char *out, 68254034eb2SDan OpenSolaris Anderson * const AES_KEY *key) 68354034eb2SDan OpenSolaris Anderson */ 68454034eb2SDan OpenSolaris Anderson 68554034eb2SDan OpenSolaris Anderson#ifdef OPENSSL_INTERFACE 68654034eb2SDan OpenSolaris Anderson#define aes_encrypt_intel intel_AES_encrypt 68754034eb2SDan OpenSolaris Anderson#define aes_decrypt_intel intel_AES_decrypt 68854034eb2SDan OpenSolaris Anderson 68954034eb2SDan OpenSolaris Anderson#define INP rdi /* P1, 64 bits */ 69054034eb2SDan OpenSolaris Anderson#define OUTP rsi /* P2, 64 bits */ 69154034eb2SDan OpenSolaris Anderson#define KEYP rdx /* P3, 64 bits */ 69254034eb2SDan OpenSolaris Anderson 69354034eb2SDan OpenSolaris Anderson/* No NROUNDS parameter--offset 240 from KEYP saved in %ecx: */ 69454034eb2SDan OpenSolaris Anderson#define NROUNDS32 ecx /* temporary, 32 bits */ 69554034eb2SDan OpenSolaris Anderson#define NROUNDS cl /* temporary, 8 bits */ 69654034eb2SDan OpenSolaris Anderson 69754034eb2SDan OpenSolaris Anderson#else /* OpenSolaris Interface */ 69854034eb2SDan OpenSolaris Anderson#define KEYP rdi /* P1, 64 bits */ 69954034eb2SDan OpenSolaris Anderson#define NROUNDS esi /* P2, 32 bits */ 70054034eb2SDan OpenSolaris Anderson#define INP rdx /* P3, 64 bits */ 70154034eb2SDan OpenSolaris Anderson#define OUTP rcx /* P4, 64 bits */ 70254034eb2SDan OpenSolaris Anderson#endif /* OPENSSL_INTERFACE */ 70354034eb2SDan OpenSolaris Anderson 70454034eb2SDan OpenSolaris Anderson#define STATE xmm0 /* temporary, 128 bits */ 70554034eb2SDan OpenSolaris Anderson#define KEY xmm1 /* temporary, 128 bits */ 70654034eb2SDan OpenSolaris Anderson 70754034eb2SDan OpenSolaris AndersonENTRY_NP(aes_encrypt_intel) 70854034eb2SDan OpenSolaris Anderson CLEAR_TS_OR_PUSH_XMM0_XMM1(%r10) 70954034eb2SDan OpenSolaris Anderson 71054034eb2SDan OpenSolaris Anderson movups (%INP), %STATE / input 71154034eb2SDan OpenSolaris Anderson movaps (%KEYP), %KEY / key 71254034eb2SDan OpenSolaris Anderson#ifdef OPENSSL_INTERFACE 71354034eb2SDan OpenSolaris Anderson mov 240(%KEYP), %NROUNDS32 / round count 71454034eb2SDan OpenSolaris Anderson#else /* OpenSolaris Interface */ 71554034eb2SDan OpenSolaris Anderson /* Round count is already present as P2 in %rsi/%esi */ 71654034eb2SDan OpenSolaris Anderson#endif /* OPENSSL_INTERFACE */ 71754034eb2SDan OpenSolaris Anderson 71854034eb2SDan OpenSolaris Anderson pxor %KEY, %STATE / round 0 71954034eb2SDan OpenSolaris Anderson lea 0x30(%KEYP), %KEYP 72054034eb2SDan OpenSolaris Anderson cmp $12, %NROUNDS 72154034eb2SDan OpenSolaris Anderson jb .Lenc128 72254034eb2SDan OpenSolaris Anderson lea 0x20(%KEYP), %KEYP 72354034eb2SDan OpenSolaris Anderson je .Lenc192 72454034eb2SDan OpenSolaris Anderson 72554034eb2SDan OpenSolaris Anderson / AES 256 72654034eb2SDan OpenSolaris Anderson lea 0x20(%KEYP), %KEYP 72754034eb2SDan OpenSolaris Anderson movaps -0x60(%KEYP), %KEY 7288de5c4f4SDan OpenSolaris Anderson aesenc %KEY, %STATE 72954034eb2SDan OpenSolaris Anderson movaps -0x50(%KEYP), %KEY 7308de5c4f4SDan OpenSolaris Anderson aesenc %KEY, %STATE 73154034eb2SDan OpenSolaris Anderson 73254034eb2SDan OpenSolaris Anderson.align 4 73354034eb2SDan OpenSolaris Anderson.Lenc192: 73454034eb2SDan OpenSolaris Anderson / AES 192 and 256 73554034eb2SDan OpenSolaris Anderson movaps -0x40(%KEYP), %KEY 7368de5c4f4SDan OpenSolaris Anderson aesenc %KEY, %STATE 73754034eb2SDan OpenSolaris Anderson movaps -0x30(%KEYP), %KEY 7388de5c4f4SDan OpenSolaris Anderson aesenc %KEY, %STATE 73954034eb2SDan OpenSolaris Anderson 74054034eb2SDan OpenSolaris Anderson.align 4 74154034eb2SDan OpenSolaris Anderson.Lenc128: 74254034eb2SDan OpenSolaris Anderson / AES 128, 192, and 256 74354034eb2SDan OpenSolaris Anderson movaps -0x20(%KEYP), %KEY 7448de5c4f4SDan OpenSolaris Anderson aesenc %KEY, %STATE 74554034eb2SDan OpenSolaris Anderson movaps -0x10(%KEYP), %KEY 7468de5c4f4SDan OpenSolaris Anderson aesenc %KEY, %STATE 74754034eb2SDan OpenSolaris Anderson movaps (%KEYP), %KEY 7488de5c4f4SDan OpenSolaris Anderson aesenc %KEY, %STATE 74954034eb2SDan OpenSolaris Anderson movaps 0x10(%KEYP), %KEY 7508de5c4f4SDan OpenSolaris Anderson aesenc %KEY, %STATE 75154034eb2SDan OpenSolaris Anderson movaps 0x20(%KEYP), %KEY 7528de5c4f4SDan OpenSolaris Anderson aesenc %KEY, %STATE 75354034eb2SDan OpenSolaris Anderson movaps 0x30(%KEYP), %KEY 7548de5c4f4SDan OpenSolaris Anderson aesenc %KEY, %STATE 75554034eb2SDan OpenSolaris Anderson movaps 0x40(%KEYP), %KEY 7568de5c4f4SDan OpenSolaris Anderson aesenc %KEY, %STATE 75754034eb2SDan OpenSolaris Anderson movaps 0x50(%KEYP), %KEY 7588de5c4f4SDan OpenSolaris Anderson aesenc %KEY, %STATE 75954034eb2SDan OpenSolaris Anderson movaps 0x60(%KEYP), %KEY 7608de5c4f4SDan OpenSolaris Anderson aesenc %KEY, %STATE 76154034eb2SDan OpenSolaris Anderson movaps 0x70(%KEYP), %KEY 7628de5c4f4SDan OpenSolaris Anderson aesenclast %KEY, %STATE / last round 76354034eb2SDan OpenSolaris Anderson movups %STATE, (%OUTP) / output 76454034eb2SDan OpenSolaris Anderson 76554034eb2SDan OpenSolaris Anderson SET_TS_OR_POP_XMM0_XMM1(%r10) 76654034eb2SDan OpenSolaris Anderson ret 76754034eb2SDan OpenSolaris Anderson SET_SIZE(aes_encrypt_intel) 76854034eb2SDan OpenSolaris Anderson 76954034eb2SDan OpenSolaris Anderson 77054034eb2SDan OpenSolaris Anderson/* 77154034eb2SDan OpenSolaris Anderson * aes_decrypt_intel() 77254034eb2SDan OpenSolaris Anderson * Decrypt a single block (in and out can overlap). 77354034eb2SDan OpenSolaris Anderson * 77454034eb2SDan OpenSolaris Anderson * For kernel code, caller is responsible for ensuring kpreempt_disable() 77554034eb2SDan OpenSolaris Anderson * has been called. This is because %xmm registers are not saved/restored. 77654034eb2SDan OpenSolaris Anderson * Clear and set the CR0.TS bit on entry and exit, respectively, if TS is set 77754034eb2SDan OpenSolaris Anderson * on entry. Otherwise, if TS is not set, save and restore %xmm registers 77854034eb2SDan OpenSolaris Anderson * on the stack. 77954034eb2SDan OpenSolaris Anderson * 78054034eb2SDan OpenSolaris Anderson * Temporary register usage: 78154034eb2SDan OpenSolaris Anderson * %xmm0 State 78254034eb2SDan OpenSolaris Anderson * %xmm1 Key 78354034eb2SDan OpenSolaris Anderson * 78454034eb2SDan OpenSolaris Anderson * Original OpenSolaris Interface: 78554034eb2SDan OpenSolaris Anderson * void aes_decrypt_intel(const aes_ks_t *ks, int Nr, 78654034eb2SDan OpenSolaris Anderson * const uint32_t pt[4], uint32_t ct[4])/ 78754034eb2SDan OpenSolaris Anderson * 78854034eb2SDan OpenSolaris Anderson * Original Intel OpenSSL Interface: 78954034eb2SDan OpenSolaris Anderson * void intel_AES_decrypt(const unsigned char *in, unsigned char *out, 79054034eb2SDan OpenSolaris Anderson * const AES_KEY *key); 79154034eb2SDan OpenSolaris Anderson */ 79254034eb2SDan OpenSolaris AndersonENTRY_NP(aes_decrypt_intel) 79354034eb2SDan OpenSolaris Anderson CLEAR_TS_OR_PUSH_XMM0_XMM1(%r10) 79454034eb2SDan OpenSolaris Anderson 79554034eb2SDan OpenSolaris Anderson movups (%INP), %STATE / input 79654034eb2SDan OpenSolaris Anderson movaps (%KEYP), %KEY / key 79754034eb2SDan OpenSolaris Anderson#ifdef OPENSSL_INTERFACE 79854034eb2SDan OpenSolaris Anderson mov 240(%KEYP), %NROUNDS32 / round count 79954034eb2SDan OpenSolaris Anderson#else /* OpenSolaris Interface */ 80054034eb2SDan OpenSolaris Anderson /* Round count is already present as P2 in %rsi/%esi */ 80154034eb2SDan OpenSolaris Anderson#endif /* OPENSSL_INTERFACE */ 80254034eb2SDan OpenSolaris Anderson 80354034eb2SDan OpenSolaris Anderson pxor %KEY, %STATE / round 0 80454034eb2SDan OpenSolaris Anderson lea 0x30(%KEYP), %KEYP 80554034eb2SDan OpenSolaris Anderson cmp $12, %NROUNDS 80654034eb2SDan OpenSolaris Anderson jb .Ldec128 80754034eb2SDan OpenSolaris Anderson lea 0x20(%KEYP), %KEYP 80854034eb2SDan OpenSolaris Anderson je .Ldec192 80954034eb2SDan OpenSolaris Anderson 81054034eb2SDan OpenSolaris Anderson / AES 256 81154034eb2SDan OpenSolaris Anderson lea 0x20(%KEYP), %KEYP 81254034eb2SDan OpenSolaris Anderson movaps -0x60(%KEYP), %KEY 8138de5c4f4SDan OpenSolaris Anderson aesdec %KEY, %STATE 81454034eb2SDan OpenSolaris Anderson movaps -0x50(%KEYP), %KEY 8158de5c4f4SDan OpenSolaris Anderson aesdec %KEY, %STATE 81654034eb2SDan OpenSolaris Anderson 81754034eb2SDan OpenSolaris Anderson.align 4 81854034eb2SDan OpenSolaris Anderson.Ldec192: 81954034eb2SDan OpenSolaris Anderson / AES 192 and 256 82054034eb2SDan OpenSolaris Anderson movaps -0x40(%KEYP), %KEY 8218de5c4f4SDan OpenSolaris Anderson aesdec %KEY, %STATE 82254034eb2SDan OpenSolaris Anderson movaps -0x30(%KEYP), %KEY 8238de5c4f4SDan OpenSolaris Anderson aesdec %KEY, %STATE 82454034eb2SDan OpenSolaris Anderson 82554034eb2SDan OpenSolaris Anderson.align 4 82654034eb2SDan OpenSolaris Anderson.Ldec128: 82754034eb2SDan OpenSolaris Anderson / AES 128, 192, and 256 82854034eb2SDan OpenSolaris Anderson movaps -0x20(%KEYP), %KEY 8298de5c4f4SDan OpenSolaris Anderson aesdec %KEY, %STATE 83054034eb2SDan OpenSolaris Anderson movaps -0x10(%KEYP), %KEY 8318de5c4f4SDan OpenSolaris Anderson aesdec %KEY, %STATE 83254034eb2SDan OpenSolaris Anderson movaps (%KEYP), %KEY 8338de5c4f4SDan OpenSolaris Anderson aesdec %KEY, %STATE 83454034eb2SDan OpenSolaris Anderson movaps 0x10(%KEYP), %KEY 8358de5c4f4SDan OpenSolaris Anderson aesdec %KEY, %STATE 83654034eb2SDan OpenSolaris Anderson movaps 0x20(%KEYP), %KEY 8378de5c4f4SDan OpenSolaris Anderson aesdec %KEY, %STATE 83854034eb2SDan OpenSolaris Anderson movaps 0x30(%KEYP), %KEY 8398de5c4f4SDan OpenSolaris Anderson aesdec %KEY, %STATE 84054034eb2SDan OpenSolaris Anderson movaps 0x40(%KEYP), %KEY 8418de5c4f4SDan OpenSolaris Anderson aesdec %KEY, %STATE 84254034eb2SDan OpenSolaris Anderson movaps 0x50(%KEYP), %KEY 8438de5c4f4SDan OpenSolaris Anderson aesdec %KEY, %STATE 84454034eb2SDan OpenSolaris Anderson movaps 0x60(%KEYP), %KEY 8458de5c4f4SDan OpenSolaris Anderson aesdec %KEY, %STATE 84654034eb2SDan OpenSolaris Anderson movaps 0x70(%KEYP), %KEY 8478de5c4f4SDan OpenSolaris Anderson aesdeclast %KEY, %STATE / last round 84854034eb2SDan OpenSolaris Anderson movups %STATE, (%OUTP) / output 84954034eb2SDan OpenSolaris Anderson 85054034eb2SDan OpenSolaris Anderson SET_TS_OR_POP_XMM0_XMM1(%r10) 85154034eb2SDan OpenSolaris Anderson ret 85254034eb2SDan OpenSolaris Anderson SET_SIZE(aes_decrypt_intel) 85354034eb2SDan OpenSolaris Anderson 85454034eb2SDan OpenSolaris Anderson#endif /* lint || __lint */ 855