xref: /titanic_51/usr/src/common/crypto/aes/amd64/aes_intel.s (revision 694c35faa87b858ecdadfe4fc592615f4eefbb07)
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