xref: /titanic_50/usr/src/common/crypto/aes/amd64/aeskey.c (revision 54034eb2d6e7d811adf4a1fe5105eac6fea6b0b5)
190bcde94Sda73024 /*
290bcde94Sda73024  * ---------------------------------------------------------------------------
390bcde94Sda73024  * Copyright (c) 1998-2007, Brian Gladman, Worcester, UK. All rights reserved.
490bcde94Sda73024  *
590bcde94Sda73024  * LICENSE TERMS
690bcde94Sda73024  *
790bcde94Sda73024  * The free distribution and use of this software is allowed (with or without
890bcde94Sda73024  * changes) provided that:
990bcde94Sda73024  *
1090bcde94Sda73024  *  1. source code distributions include the above copyright notice, this
1190bcde94Sda73024  *	 list of conditions and the following disclaimer;
1290bcde94Sda73024  *
1390bcde94Sda73024  *  2. binary distributions include the above copyright notice, this list
1490bcde94Sda73024  *	 of conditions and the following disclaimer in their documentation;
1590bcde94Sda73024  *
1690bcde94Sda73024  *  3. the name of the copyright holder is not used to endorse products
1790bcde94Sda73024  *	 built using this software without specific written permission.
1890bcde94Sda73024  *
1990bcde94Sda73024  * DISCLAIMER
2090bcde94Sda73024  *
2190bcde94Sda73024  * This software is provided 'as is' with no explicit or implied warranties
2290bcde94Sda73024  * in respect of its properties, including, but not limited to, correctness
2390bcde94Sda73024  * and/or fitness for purpose.
2490bcde94Sda73024  * ---------------------------------------------------------------------------
2590bcde94Sda73024  * Issue Date: 20/12/2007
2690bcde94Sda73024  */
2790bcde94Sda73024 
2890bcde94Sda73024 #include "aes_impl.h"
2990bcde94Sda73024 #include "aesopt.h"
3090bcde94Sda73024 #include "aestab.h"
3190bcde94Sda73024 #include "aestab2.h"
3290bcde94Sda73024 
3390bcde94Sda73024 /*
3490bcde94Sda73024  *	Initialise the key schedule from the user supplied key. The key
3590bcde94Sda73024  *	length can be specified in bytes, with legal values of 16, 24
3690bcde94Sda73024  *	and 32, or in bits, with legal values of 128, 192 and 256. These
3790bcde94Sda73024  *	values correspond with Nk values of 4, 6 and 8 respectively.
3890bcde94Sda73024  *
3990bcde94Sda73024  *	The following macros implement a single cycle in the key
4090bcde94Sda73024  *	schedule generation process. The number of cycles needed
4190bcde94Sda73024  *	for each cx->n_col and nk value is:
4290bcde94Sda73024  *
4390bcde94Sda73024  *	nk =		4  5  6  7  8
4490bcde94Sda73024  *	------------------------------
4590bcde94Sda73024  *	cx->n_col = 4	10  9  8  7  7
4690bcde94Sda73024  *	cx->n_col = 5	14 11 10  9  9
4790bcde94Sda73024  *	cx->n_col = 6	19 15 12 11 11
4890bcde94Sda73024  *	cx->n_col = 7	21 19 16 13 14
4990bcde94Sda73024  *	cx->n_col = 8	29 23 19 17 14
5090bcde94Sda73024  */
5190bcde94Sda73024 
5290bcde94Sda73024 /*
5390bcde94Sda73024  * OpenSolaris changes
5490bcde94Sda73024  * 1. Added header files aes_impl.h and aestab2.h
5590bcde94Sda73024  * 2. Changed uint_8t and uint_32t to uint8_t and uint32_t
5690bcde94Sda73024  * 3. Remove code under ifdef USE_VIA_ACE_IF_PRESENT (always undefined)
5790bcde94Sda73024  * 4. Removed always-defined ifdefs FUNCS_IN_C, ENC_KEYING_IN_C,
5890bcde94Sda73024  *	AES_128, AES_192, AES_256, AES_VAR defines
5990bcde94Sda73024  * 5. Changed aes_encrypt_key* aes_decrypt_key* functions to "static void"
6090bcde94Sda73024  * 6. Changed N_COLS to MAX_AES_NB
6190bcde94Sda73024  * 7. Replaced functions aes_encrypt_key and aes_decrypt_key with
62*54034eb2SDan OpenSolaris Anderson  *	OpenSolaris-compatible functions rijndael_key_setup_enc_amd64 and
63*54034eb2SDan OpenSolaris Anderson  *	rijndael_key_setup_dec_amd64
6490bcde94Sda73024  * 8. cstyled code and removed lint warnings
6590bcde94Sda73024  */
6690bcde94Sda73024 
6790bcde94Sda73024 #if defined(REDUCE_CODE_SIZE)
6890bcde94Sda73024 #define	ls_box ls_sub
6990bcde94Sda73024 	uint32_t	ls_sub(const uint32_t t, const uint32_t n);
7090bcde94Sda73024 #define	inv_mcol im_sub
7190bcde94Sda73024 	uint32_t	im_sub(const uint32_t x);
7290bcde94Sda73024 #ifdef ENC_KS_UNROLL
7390bcde94Sda73024 #undef ENC_KS_UNROLL
7490bcde94Sda73024 #endif
7590bcde94Sda73024 #ifdef DEC_KS_UNROLL
7690bcde94Sda73024 #undef DEC_KS_UNROLL
7790bcde94Sda73024 #endif
7890bcde94Sda73024 #endif	/* REDUCE_CODE_SIZE */
7990bcde94Sda73024 
8090bcde94Sda73024 
8190bcde94Sda73024 #define	ke4(k, i) \
8290bcde94Sda73024 {	k[4 * (i) + 4] = ss[0] ^= ls_box(ss[3], 3) ^ t_use(r, c)[i]; \
8390bcde94Sda73024 	k[4 * (i) + 5] = ss[1] ^= ss[0]; \
8490bcde94Sda73024 	k[4 * (i) + 6] = ss[2] ^= ss[1]; \
8590bcde94Sda73024 	k[4 * (i) + 7] = ss[3] ^= ss[2]; \
8690bcde94Sda73024 }
8790bcde94Sda73024 
8890bcde94Sda73024 static void
aes_encrypt_key128(const unsigned char * key,uint32_t rk[])8990bcde94Sda73024 aes_encrypt_key128(const unsigned char *key, uint32_t rk[])
9090bcde94Sda73024 {
9190bcde94Sda73024 	uint32_t	ss[4];
9290bcde94Sda73024 
9390bcde94Sda73024 	rk[0] = ss[0] = word_in(key, 0);
9490bcde94Sda73024 	rk[1] = ss[1] = word_in(key, 1);
9590bcde94Sda73024 	rk[2] = ss[2] = word_in(key, 2);
9690bcde94Sda73024 	rk[3] = ss[3] = word_in(key, 3);
9790bcde94Sda73024 
9890bcde94Sda73024 #ifdef ENC_KS_UNROLL
9990bcde94Sda73024 	ke4(rk, 0);  ke4(rk, 1);
10090bcde94Sda73024 	ke4(rk, 2);  ke4(rk, 3);
10190bcde94Sda73024 	ke4(rk, 4);  ke4(rk, 5);
10290bcde94Sda73024 	ke4(rk, 6);  ke4(rk, 7);
10390bcde94Sda73024 	ke4(rk, 8);
10490bcde94Sda73024 #else
10590bcde94Sda73024 	{
10690bcde94Sda73024 		uint32_t	i;
10790bcde94Sda73024 		for (i = 0; i < 9; ++i)
10890bcde94Sda73024 			ke4(rk, i);
10990bcde94Sda73024 	}
11090bcde94Sda73024 #endif	/* ENC_KS_UNROLL */
11190bcde94Sda73024 	ke4(rk, 9);
11290bcde94Sda73024 }
11390bcde94Sda73024 
11490bcde94Sda73024 
11590bcde94Sda73024 #define	kef6(k, i) \
11690bcde94Sda73024 {	k[6 * (i) + 6] = ss[0] ^= ls_box(ss[5], 3) ^ t_use(r, c)[i]; \
11790bcde94Sda73024 	k[6 * (i) + 7] = ss[1] ^= ss[0]; \
11890bcde94Sda73024 	k[6 * (i) + 8] = ss[2] ^= ss[1]; \
11990bcde94Sda73024 	k[6 * (i) + 9] = ss[3] ^= ss[2]; \
12090bcde94Sda73024 }
12190bcde94Sda73024 
12290bcde94Sda73024 #define	ke6(k, i) \
12390bcde94Sda73024 {	kef6(k, i); \
12490bcde94Sda73024 	k[6 * (i) + 10] = ss[4] ^= ss[3]; \
12590bcde94Sda73024 	k[6 * (i) + 11] = ss[5] ^= ss[4]; \
12690bcde94Sda73024 }
12790bcde94Sda73024 
12890bcde94Sda73024 static void
aes_encrypt_key192(const unsigned char * key,uint32_t rk[])12990bcde94Sda73024 aes_encrypt_key192(const unsigned char *key, uint32_t rk[])
13090bcde94Sda73024 {
13190bcde94Sda73024 	uint32_t	ss[6];
13290bcde94Sda73024 
13390bcde94Sda73024 	rk[0] = ss[0] = word_in(key, 0);
13490bcde94Sda73024 	rk[1] = ss[1] = word_in(key, 1);
13590bcde94Sda73024 	rk[2] = ss[2] = word_in(key, 2);
13690bcde94Sda73024 	rk[3] = ss[3] = word_in(key, 3);
13790bcde94Sda73024 	rk[4] = ss[4] = word_in(key, 4);
13890bcde94Sda73024 	rk[5] = ss[5] = word_in(key, 5);
13990bcde94Sda73024 
14090bcde94Sda73024 #ifdef ENC_KS_UNROLL
14190bcde94Sda73024 	ke6(rk, 0);  ke6(rk, 1);
14290bcde94Sda73024 	ke6(rk, 2);  ke6(rk, 3);
14390bcde94Sda73024 	ke6(rk, 4);  ke6(rk, 5);
14490bcde94Sda73024 	ke6(rk, 6);
14590bcde94Sda73024 #else
14690bcde94Sda73024 	{
14790bcde94Sda73024 		uint32_t	i;
14890bcde94Sda73024 		for (i = 0; i < 7; ++i)
14990bcde94Sda73024 			ke6(rk, i);
15090bcde94Sda73024 	}
15190bcde94Sda73024 #endif	/* ENC_KS_UNROLL */
15290bcde94Sda73024 	kef6(rk, 7);
15390bcde94Sda73024 }
15490bcde94Sda73024 
15590bcde94Sda73024 
15690bcde94Sda73024 
15790bcde94Sda73024 #define	kef8(k, i) \
15890bcde94Sda73024 {	k[8 * (i) + 8] = ss[0] ^= ls_box(ss[7], 3) ^ t_use(r, c)[i]; \
15990bcde94Sda73024 	k[8 * (i) + 9] = ss[1] ^= ss[0]; \
16090bcde94Sda73024 	k[8 * (i) + 10] = ss[2] ^= ss[1]; \
16190bcde94Sda73024 	k[8 * (i) + 11] = ss[3] ^= ss[2]; \
16290bcde94Sda73024 }
16390bcde94Sda73024 
16490bcde94Sda73024 #define	ke8(k, i) \
16590bcde94Sda73024 {   kef8(k, i); \
16690bcde94Sda73024 	k[8 * (i) + 12] = ss[4] ^= ls_box(ss[3], 0); \
16790bcde94Sda73024 	k[8 * (i) + 13] = ss[5] ^= ss[4]; \
16890bcde94Sda73024 	k[8 * (i) + 14] = ss[6] ^= ss[5]; \
16990bcde94Sda73024 	k[8 * (i) + 15] = ss[7] ^= ss[6]; \
17090bcde94Sda73024 }
17190bcde94Sda73024 
17290bcde94Sda73024 static void
aes_encrypt_key256(const unsigned char * key,uint32_t rk[])17390bcde94Sda73024 aes_encrypt_key256(const unsigned char *key, uint32_t rk[])
17490bcde94Sda73024 {
17590bcde94Sda73024 	uint32_t	ss[8];
17690bcde94Sda73024 
17790bcde94Sda73024 	rk[0] = ss[0] = word_in(key, 0);
17890bcde94Sda73024 	rk[1] = ss[1] = word_in(key, 1);
17990bcde94Sda73024 	rk[2] = ss[2] = word_in(key, 2);
18090bcde94Sda73024 	rk[3] = ss[3] = word_in(key, 3);
18190bcde94Sda73024 	rk[4] = ss[4] = word_in(key, 4);
18290bcde94Sda73024 	rk[5] = ss[5] = word_in(key, 5);
18390bcde94Sda73024 	rk[6] = ss[6] = word_in(key, 6);
18490bcde94Sda73024 	rk[7] = ss[7] = word_in(key, 7);
18590bcde94Sda73024 
18690bcde94Sda73024 #ifdef ENC_KS_UNROLL
18790bcde94Sda73024 	ke8(rk, 0); ke8(rk, 1);
18890bcde94Sda73024 	ke8(rk, 2); ke8(rk, 3);
18990bcde94Sda73024 	ke8(rk, 4); ke8(rk, 5);
19090bcde94Sda73024 #else
19190bcde94Sda73024 	{
19290bcde94Sda73024 		uint32_t	i;
19390bcde94Sda73024 		for (i = 0; i < 6; ++i)
19490bcde94Sda73024 			ke8(rk,  i);
19590bcde94Sda73024 	}
19690bcde94Sda73024 #endif	/* ENC_KS_UNROLL */
19790bcde94Sda73024 	kef8(rk, 6);
19890bcde94Sda73024 }
19990bcde94Sda73024 
20090bcde94Sda73024 
20190bcde94Sda73024 /*
20290bcde94Sda73024  * Expand the cipher key into the encryption key schedule.
20390bcde94Sda73024  *
20490bcde94Sda73024  * Return the number of rounds for the given cipher key size.
20590bcde94Sda73024  * The size of the key schedule depends on the number of rounds
20690bcde94Sda73024  * (which can be computed from the size of the key), i.e. 4 * (Nr + 1).
20790bcde94Sda73024  *
20890bcde94Sda73024  * Parameters:
20990bcde94Sda73024  * rk		AES key schedule 32-bit array to be initialized
21090bcde94Sda73024  * cipherKey	User key
21190bcde94Sda73024  * keyBits	AES key size (128, 192, or 256 bits)
21290bcde94Sda73024  */
21390bcde94Sda73024 int
rijndael_key_setup_enc_amd64(uint32_t rk[],const uint32_t cipherKey[],int keyBits)214*54034eb2SDan OpenSolaris Anderson rijndael_key_setup_enc_amd64(uint32_t rk[], const uint32_t cipherKey[],
215*54034eb2SDan OpenSolaris Anderson 	int keyBits)
21690bcde94Sda73024 {
21790bcde94Sda73024 	switch (keyBits) {
21890bcde94Sda73024 	case 128:
21990bcde94Sda73024 		aes_encrypt_key128((unsigned char *)&cipherKey[0], rk);
22090bcde94Sda73024 		return (10);
22190bcde94Sda73024 	case 192:
22290bcde94Sda73024 		aes_encrypt_key192((unsigned char *)&cipherKey[0], rk);
22390bcde94Sda73024 		return (12);
22490bcde94Sda73024 	case 256:
22590bcde94Sda73024 		aes_encrypt_key256((unsigned char *)&cipherKey[0], rk);
22690bcde94Sda73024 		return (14);
22790bcde94Sda73024 	default: /* should never get here */
22890bcde94Sda73024 		break;
22990bcde94Sda73024 	}
23090bcde94Sda73024 
23190bcde94Sda73024 	return (0);
23290bcde94Sda73024 }
23390bcde94Sda73024 
23490bcde94Sda73024 
23590bcde94Sda73024 /* this is used to store the decryption round keys  */
23690bcde94Sda73024 /* in forward or reverse order */
23790bcde94Sda73024 
23890bcde94Sda73024 #ifdef AES_REV_DKS
23990bcde94Sda73024 #define	v(n, i)  ((n) - (i) + 2 * ((i) & 3))
24090bcde94Sda73024 #else
24190bcde94Sda73024 #define	v(n, i)  (i)
24290bcde94Sda73024 #endif
24390bcde94Sda73024 
24490bcde94Sda73024 #if DEC_ROUND == NO_TABLES
24590bcde94Sda73024 #define	ff(x)   (x)
24690bcde94Sda73024 #else
24790bcde94Sda73024 #define	ff(x)   inv_mcol(x)
24890bcde94Sda73024 #if defined(dec_imvars)
24990bcde94Sda73024 #define	d_vars  dec_imvars
25090bcde94Sda73024 #endif
25190bcde94Sda73024 #endif	/* FUNCS_IN_C & DEC_KEYING_IN_C */
25290bcde94Sda73024 
25390bcde94Sda73024 
25490bcde94Sda73024 #define	k4e(k, i) \
25590bcde94Sda73024 {	k[v(40, (4 * (i)) + 4)] = ss[0] ^= ls_box(ss[3], 3) ^ t_use(r, c)[i]; \
25690bcde94Sda73024 	k[v(40, (4 * (i)) + 5)] = ss[1] ^= ss[0]; \
25790bcde94Sda73024 	k[v(40, (4 * (i)) + 6)] = ss[2] ^= ss[1]; \
25890bcde94Sda73024 	k[v(40, (4 * (i)) + 7)] = ss[3] ^= ss[2]; \
25990bcde94Sda73024 }
26090bcde94Sda73024 
26190bcde94Sda73024 #if 1
26290bcde94Sda73024 
26390bcde94Sda73024 #define	kdf4(k, i) \
26490bcde94Sda73024 {	ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \
26590bcde94Sda73024 	ss[1] = ss[1] ^ ss[3]; \
26690bcde94Sda73024 	ss[2] = ss[2] ^ ss[3]; \
26790bcde94Sda73024 	ss[4] = ls_box(ss[(i + 3) % 4], 3) ^ t_use(r, c)[i]; \
26890bcde94Sda73024 	ss[i % 4] ^= ss[4]; \
26990bcde94Sda73024 	ss[4] ^= k[v(40, (4 * (i)))];   k[v(40, (4 * (i)) + 4)] = ff(ss[4]); \
27090bcde94Sda73024 	ss[4] ^= k[v(40, (4 * (i)) + 1)]; k[v(40, (4 * (i)) + 5)] = ff(ss[4]); \
27190bcde94Sda73024 	ss[4] ^= k[v(40, (4 * (i)) + 2)]; k[v(40, (4 * (i)) + 6)] = ff(ss[4]); \
27290bcde94Sda73024 	ss[4] ^= k[v(40, (4 * (i)) + 3)]; k[v(40, (4 * (i)) + 7)] = ff(ss[4]); \
27390bcde94Sda73024 }
27490bcde94Sda73024 
27590bcde94Sda73024 #define	kd4(k, i) \
27690bcde94Sda73024 {	ss[4] = ls_box(ss[(i + 3) % 4], 3) ^ t_use(r, c)[i]; \
27790bcde94Sda73024 	ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
27890bcde94Sda73024 	k[v(40, (4 * (i)) + 4)] = ss[4] ^= k[v(40, (4 * (i)))]; \
27990bcde94Sda73024 	k[v(40, (4 * (i)) + 5)] = ss[4] ^= k[v(40, (4 * (i)) + 1)]; \
28090bcde94Sda73024 	k[v(40, (4 * (i)) + 6)] = ss[4] ^= k[v(40, (4 * (i)) + 2)]; \
28190bcde94Sda73024 	k[v(40, (4 * (i)) + 7)] = ss[4] ^= k[v(40, (4 * (i)) + 3)]; \
28290bcde94Sda73024 }
28390bcde94Sda73024 
28490bcde94Sda73024 #define	kdl4(k, i) \
28590bcde94Sda73024 {	ss[4] = ls_box(ss[(i + 3) % 4], 3) ^ t_use(r, c)[i]; \
28690bcde94Sda73024 	ss[i % 4] ^= ss[4]; \
28790bcde94Sda73024 	k[v(40, (4 * (i)) + 4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \
28890bcde94Sda73024 	k[v(40, (4 * (i)) + 5)] = ss[1] ^ ss[3]; \
28990bcde94Sda73024 	k[v(40, (4 * (i)) + 6)] = ss[0]; \
29090bcde94Sda73024 	k[v(40, (4 * (i)) + 7)] = ss[1]; \
29190bcde94Sda73024 }
29290bcde94Sda73024 
29390bcde94Sda73024 #else
29490bcde94Sda73024 
29590bcde94Sda73024 #define	kdf4(k, i) \
29690bcde94Sda73024 {	ss[0] ^= ls_box(ss[3], 3) ^ t_use(r, c)[i]; \
29790bcde94Sda73024 	k[v(40, (4 * (i)) + 4)] = ff(ss[0]); \
29890bcde94Sda73024 	ss[1] ^= ss[0]; k[v(40, (4 * (i)) + 5)] = ff(ss[1]); \
29990bcde94Sda73024 	ss[2] ^= ss[1]; k[v(40, (4 * (i)) + 6)] = ff(ss[2]); \
30090bcde94Sda73024 	ss[3] ^= ss[2]; k[v(40, (4 * (i)) + 7)] = ff(ss[3]); \
30190bcde94Sda73024 }
30290bcde94Sda73024 
30390bcde94Sda73024 #define	kd4(k, i) \
30490bcde94Sda73024 {	ss[4] = ls_box(ss[3], 3) ^ t_use(r, c)[i]; \
30590bcde94Sda73024 	ss[0] ^= ss[4]; \
30690bcde94Sda73024 	ss[4] = ff(ss[4]); \
30790bcde94Sda73024 	k[v(40, (4 * (i)) + 4)] = ss[4] ^= k[v(40, (4 * (i)))]; \
30890bcde94Sda73024 	ss[1] ^= ss[0]; \
30990bcde94Sda73024 	k[v(40, (4 * (i)) + 5)] = ss[4] ^= k[v(40, (4 * (i)) + 1)]; \
31090bcde94Sda73024 	ss[2] ^= ss[1]; \
31190bcde94Sda73024 	k[v(40, (4 * (i)) + 6)] = ss[4] ^= k[v(40, (4 * (i)) + 2)]; \
31290bcde94Sda73024 	ss[3] ^= ss[2]; \
31390bcde94Sda73024 	k[v(40, (4 * (i)) + 7)] = ss[4] ^= k[v(40, (4 * (i)) + 3)]; \
31490bcde94Sda73024 }
31590bcde94Sda73024 
31690bcde94Sda73024 #define	kdl4(k, i) \
31790bcde94Sda73024 {	ss[0] ^= ls_box(ss[3], 3) ^ t_use(r, c)[i]; \
31890bcde94Sda73024 	k[v(40, (4 * (i)) + 4)] = ss[0]; \
31990bcde94Sda73024 	ss[1] ^= ss[0]; k[v(40, (4 * (i)) + 5)] = ss[1]; \
32090bcde94Sda73024 	ss[2] ^= ss[1]; k[v(40, (4 * (i)) + 6)] = ss[2]; \
32190bcde94Sda73024 	ss[3] ^= ss[2]; k[v(40, (4 * (i)) + 7)] = ss[3]; \
32290bcde94Sda73024 }
32390bcde94Sda73024 
32490bcde94Sda73024 #endif
32590bcde94Sda73024 
32690bcde94Sda73024 static void
aes_decrypt_key128(const unsigned char * key,uint32_t rk[])32790bcde94Sda73024 aes_decrypt_key128(const unsigned char *key, uint32_t rk[])
32890bcde94Sda73024 {
32990bcde94Sda73024 	uint32_t	ss[5];
33090bcde94Sda73024 #if defined(d_vars)
33190bcde94Sda73024 	d_vars;
33290bcde94Sda73024 #endif
33390bcde94Sda73024 	rk[v(40, (0))] = ss[0] = word_in(key, 0);
33490bcde94Sda73024 	rk[v(40, (1))] = ss[1] = word_in(key, 1);
33590bcde94Sda73024 	rk[v(40, (2))] = ss[2] = word_in(key, 2);
33690bcde94Sda73024 	rk[v(40, (3))] = ss[3] = word_in(key, 3);
33790bcde94Sda73024 
33890bcde94Sda73024 #ifdef DEC_KS_UNROLL
33990bcde94Sda73024 	kdf4(rk, 0); kd4(rk, 1);
34090bcde94Sda73024 	kd4(rk, 2);  kd4(rk, 3);
34190bcde94Sda73024 	kd4(rk, 4);  kd4(rk, 5);
34290bcde94Sda73024 	kd4(rk, 6);  kd4(rk, 7);
34390bcde94Sda73024 	kd4(rk, 8);  kdl4(rk, 9);
34490bcde94Sda73024 #else
34590bcde94Sda73024 	{
34690bcde94Sda73024 		uint32_t	i;
34790bcde94Sda73024 		for (i = 0; i < 10; ++i)
34890bcde94Sda73024 			k4e(rk, i);
34990bcde94Sda73024 #if !(DEC_ROUND == NO_TABLES)
35090bcde94Sda73024 		for (i = MAX_AES_NB; i < 10 * MAX_AES_NB; ++i)
35190bcde94Sda73024 			rk[i] = inv_mcol(rk[i]);
35290bcde94Sda73024 #endif
35390bcde94Sda73024 	}
35490bcde94Sda73024 #endif	/* DEC_KS_UNROLL */
35590bcde94Sda73024 }
35690bcde94Sda73024 
35790bcde94Sda73024 
35890bcde94Sda73024 
35990bcde94Sda73024 #define	k6ef(k, i) \
36090bcde94Sda73024 {	k[v(48, (6 * (i)) + 6)] = ss[0] ^= ls_box(ss[5], 3) ^ t_use(r, c)[i]; \
36190bcde94Sda73024 	k[v(48, (6 * (i)) + 7)] = ss[1] ^= ss[0]; \
36290bcde94Sda73024 	k[v(48, (6 * (i)) + 8)] = ss[2] ^= ss[1]; \
36390bcde94Sda73024 	k[v(48, (6 * (i)) + 9)] = ss[3] ^= ss[2]; \
36490bcde94Sda73024 }
36590bcde94Sda73024 
36690bcde94Sda73024 #define	k6e(k, i) \
36790bcde94Sda73024 {	k6ef(k, i); \
36890bcde94Sda73024 	k[v(48, (6 * (i)) + 10)] = ss[4] ^= ss[3]; \
36990bcde94Sda73024 	k[v(48, (6 * (i)) + 11)] = ss[5] ^= ss[4]; \
37090bcde94Sda73024 }
37190bcde94Sda73024 
37290bcde94Sda73024 #define	kdf6(k, i) \
37390bcde94Sda73024 {	ss[0] ^= ls_box(ss[5], 3) ^ t_use(r, c)[i]; \
37490bcde94Sda73024 	k[v(48, (6 * (i)) + 6)] = ff(ss[0]); \
37590bcde94Sda73024 	ss[1] ^= ss[0]; k[v(48, (6 * (i)) + 7)] = ff(ss[1]); \
37690bcde94Sda73024 	ss[2] ^= ss[1]; k[v(48, (6 * (i)) + 8)] = ff(ss[2]); \
37790bcde94Sda73024 	ss[3] ^= ss[2]; k[v(48, (6 * (i)) + 9)] = ff(ss[3]); \
37890bcde94Sda73024 	ss[4] ^= ss[3]; k[v(48, (6 * (i)) + 10)] = ff(ss[4]); \
37990bcde94Sda73024 	ss[5] ^= ss[4]; k[v(48, (6 * (i)) + 11)] = ff(ss[5]); \
38090bcde94Sda73024 }
38190bcde94Sda73024 
38290bcde94Sda73024 #define	kd6(k, i) \
38390bcde94Sda73024 {	ss[6] = ls_box(ss[5], 3) ^ t_use(r, c)[i]; \
38490bcde94Sda73024 	ss[0] ^= ss[6]; ss[6] = ff(ss[6]); \
38590bcde94Sda73024 	k[v(48, (6 * (i)) + 6)] = ss[6] ^= k[v(48, (6 * (i)))]; \
38690bcde94Sda73024 	ss[1] ^= ss[0]; \
38790bcde94Sda73024 	k[v(48, (6 * (i)) + 7)] = ss[6] ^= k[v(48, (6 * (i)) + 1)]; \
38890bcde94Sda73024 	ss[2] ^= ss[1]; \
38990bcde94Sda73024 	k[v(48, (6 * (i)) + 8)] = ss[6] ^= k[v(48, (6 * (i)) + 2)]; \
39090bcde94Sda73024 	ss[3] ^= ss[2]; \
39190bcde94Sda73024 	k[v(48, (6 * (i)) + 9)] = ss[6] ^= k[v(48, (6 * (i)) + 3)]; \
39290bcde94Sda73024 	ss[4] ^= ss[3]; \
39390bcde94Sda73024 	k[v(48, (6 * (i)) + 10)] = ss[6] ^= k[v(48, (6 * (i)) + 4)]; \
39490bcde94Sda73024 	ss[5] ^= ss[4]; \
39590bcde94Sda73024 	k[v(48, (6 * (i)) + 11)] = ss[6] ^= k[v(48, (6 * (i)) + 5)]; \
39690bcde94Sda73024 }
39790bcde94Sda73024 
39890bcde94Sda73024 #define	kdl6(k, i) \
39990bcde94Sda73024 {	ss[0] ^= ls_box(ss[5], 3) ^ t_use(r, c)[i]; \
40090bcde94Sda73024 	k[v(48, (6 * (i)) + 6)] = ss[0]; \
40190bcde94Sda73024 	ss[1] ^= ss[0]; k[v(48, (6 * (i)) + 7)] = ss[1]; \
40290bcde94Sda73024 	ss[2] ^= ss[1]; k[v(48, (6 * (i)) + 8)] = ss[2]; \
40390bcde94Sda73024 	ss[3] ^= ss[2]; k[v(48, (6 * (i)) + 9)] = ss[3]; \
40490bcde94Sda73024 }
40590bcde94Sda73024 
40690bcde94Sda73024 static void
aes_decrypt_key192(const unsigned char * key,uint32_t rk[])40790bcde94Sda73024 aes_decrypt_key192(const unsigned char *key, uint32_t rk[])
40890bcde94Sda73024 {
40990bcde94Sda73024 	uint32_t	ss[7];
41090bcde94Sda73024 #if defined(d_vars)
41190bcde94Sda73024 	d_vars;
41290bcde94Sda73024 #endif
41390bcde94Sda73024 	rk[v(48, (0))] = ss[0] = word_in(key, 0);
41490bcde94Sda73024 	rk[v(48, (1))] = ss[1] = word_in(key, 1);
41590bcde94Sda73024 	rk[v(48, (2))] = ss[2] = word_in(key, 2);
41690bcde94Sda73024 	rk[v(48, (3))] = ss[3] = word_in(key, 3);
41790bcde94Sda73024 
41890bcde94Sda73024 #ifdef DEC_KS_UNROLL
41990bcde94Sda73024 	ss[4] = word_in(key, 4);
42090bcde94Sda73024 	rk[v(48, (4))] = ff(ss[4]);
42190bcde94Sda73024 	ss[5] = word_in(key, 5);
42290bcde94Sda73024 	rk[v(48, (5))] = ff(ss[5]);
42390bcde94Sda73024 	kdf6(rk, 0); kd6(rk, 1);
42490bcde94Sda73024 	kd6(rk, 2);  kd6(rk, 3);
42590bcde94Sda73024 	kd6(rk, 4);  kd6(rk, 5);
42690bcde94Sda73024 	kd6(rk, 6);  kdl6(rk, 7);
42790bcde94Sda73024 #else
42890bcde94Sda73024 	rk[v(48, (4))] = ss[4] = word_in(key, 4);
42990bcde94Sda73024 	rk[v(48, (5))] = ss[5] = word_in(key, 5);
43090bcde94Sda73024 	{
43190bcde94Sda73024 		uint32_t	i;
43290bcde94Sda73024 
43390bcde94Sda73024 		for (i = 0; i < 7; ++i)
43490bcde94Sda73024 			k6e(rk, i);
43590bcde94Sda73024 		k6ef(rk, 7);
43690bcde94Sda73024 #if !(DEC_ROUND == NO_TABLES)
43790bcde94Sda73024 		for (i = MAX_AES_NB; i < 12 * MAX_AES_NB; ++i)
43890bcde94Sda73024 			rk[i] = inv_mcol(rk[i]);
43990bcde94Sda73024 #endif
44090bcde94Sda73024 	}
44190bcde94Sda73024 #endif
44290bcde94Sda73024 }
44390bcde94Sda73024 
44490bcde94Sda73024 
44590bcde94Sda73024 
44690bcde94Sda73024 #define	k8ef(k, i) \
44790bcde94Sda73024 {	k[v(56, (8 * (i)) + 8)] = ss[0] ^= ls_box(ss[7], 3) ^ t_use(r, c)[i]; \
44890bcde94Sda73024 	k[v(56, (8 * (i)) + 9)] = ss[1] ^= ss[0]; \
44990bcde94Sda73024 	k[v(56, (8 * (i)) + 10)] = ss[2] ^= ss[1]; \
45090bcde94Sda73024 	k[v(56, (8 * (i)) + 11)] = ss[3] ^= ss[2]; \
45190bcde94Sda73024 }
45290bcde94Sda73024 
45390bcde94Sda73024 #define	k8e(k, i) \
45490bcde94Sda73024 {	k8ef(k, i); \
45590bcde94Sda73024 	k[v(56, (8 * (i)) + 12)] = ss[4] ^= ls_box(ss[3], 0); \
45690bcde94Sda73024 	k[v(56, (8 * (i)) + 13)] = ss[5] ^= ss[4]; \
45790bcde94Sda73024 	k[v(56, (8 * (i)) + 14)] = ss[6] ^= ss[5]; \
45890bcde94Sda73024 	k[v(56, (8 * (i)) + 15)] = ss[7] ^= ss[6]; \
45990bcde94Sda73024 }
46090bcde94Sda73024 
46190bcde94Sda73024 #define	kdf8(k, i) \
46290bcde94Sda73024 {	ss[0] ^= ls_box(ss[7], 3) ^ t_use(r, c)[i]; \
46390bcde94Sda73024 	k[v(56, (8 * (i)) + 8)] = ff(ss[0]); \
46490bcde94Sda73024 	ss[1] ^= ss[0]; k[v(56, (8 * (i)) + 9)] = ff(ss[1]); \
46590bcde94Sda73024 	ss[2] ^= ss[1]; k[v(56, (8 * (i)) + 10)] = ff(ss[2]); \
46690bcde94Sda73024 	ss[3] ^= ss[2]; k[v(56, (8 * (i)) + 11)] = ff(ss[3]); \
46790bcde94Sda73024 	ss[4] ^= ls_box(ss[3], 0); k[v(56, (8 * (i)) + 12)] = ff(ss[4]); \
46890bcde94Sda73024 	ss[5] ^= ss[4]; k[v(56, (8 * (i)) + 13)] = ff(ss[5]); \
46990bcde94Sda73024 	ss[6] ^= ss[5]; k[v(56, (8 * (i)) + 14)] = ff(ss[6]); \
47090bcde94Sda73024 	ss[7] ^= ss[6]; k[v(56, (8 * (i)) + 15)] = ff(ss[7]); \
47190bcde94Sda73024 }
47290bcde94Sda73024 
47390bcde94Sda73024 #define	kd8(k, i) \
47490bcde94Sda73024 {	ss[8] = ls_box(ss[7], 3) ^ t_use(r, c)[i]; \
47590bcde94Sda73024 	ss[0] ^= ss[8]; \
47690bcde94Sda73024 	ss[8] = ff(ss[8]); \
47790bcde94Sda73024 	k[v(56, (8 * (i)) + 8)] = ss[8] ^= k[v(56, (8 * (i)))]; \
47890bcde94Sda73024 	ss[1] ^= ss[0]; \
47990bcde94Sda73024 	k[v(56, (8 * (i)) + 9)] = ss[8] ^= k[v(56, (8 * (i)) + 1)]; \
48090bcde94Sda73024 	ss[2] ^= ss[1]; \
48190bcde94Sda73024 	k[v(56, (8 * (i)) + 10)] = ss[8] ^= k[v(56, (8 * (i)) + 2)]; \
48290bcde94Sda73024 	ss[3] ^= ss[2]; \
48390bcde94Sda73024 	k[v(56, (8 * (i)) + 11)] = ss[8] ^= k[v(56, (8 * (i)) + 3)]; \
48490bcde94Sda73024 	ss[8] = ls_box(ss[3], 0); \
48590bcde94Sda73024 	ss[4] ^= ss[8]; \
48690bcde94Sda73024 	ss[8] = ff(ss[8]); \
48790bcde94Sda73024 	k[v(56, (8 * (i)) + 12)] = ss[8] ^= k[v(56, (8 * (i)) + 4)]; \
48890bcde94Sda73024 	ss[5] ^= ss[4]; \
48990bcde94Sda73024 	k[v(56, (8 * (i)) + 13)] = ss[8] ^= k[v(56, (8 * (i)) + 5)]; \
49090bcde94Sda73024 	ss[6] ^= ss[5]; \
49190bcde94Sda73024 	k[v(56, (8 * (i)) + 14)] = ss[8] ^= k[v(56, (8 * (i)) + 6)]; \
49290bcde94Sda73024 	ss[7] ^= ss[6]; \
49390bcde94Sda73024 	k[v(56, (8 * (i)) + 15)] = ss[8] ^= k[v(56, (8 * (i)) + 7)]; \
49490bcde94Sda73024 }
49590bcde94Sda73024 
49690bcde94Sda73024 #define	kdl8(k, i) \
49790bcde94Sda73024 {	ss[0] ^= ls_box(ss[7], 3) ^ t_use(r, c)[i]; \
49890bcde94Sda73024 	k[v(56, (8 * (i)) + 8)] = ss[0]; \
49990bcde94Sda73024 	ss[1] ^= ss[0]; k[v(56, (8 * (i)) + 9)] = ss[1]; \
50090bcde94Sda73024 	ss[2] ^= ss[1]; k[v(56, (8 * (i)) + 10)] = ss[2]; \
50190bcde94Sda73024 	ss[3] ^= ss[2]; k[v(56, (8 * (i)) + 11)] = ss[3]; \
50290bcde94Sda73024 }
50390bcde94Sda73024 
50490bcde94Sda73024 static void
aes_decrypt_key256(const unsigned char * key,uint32_t rk[])50590bcde94Sda73024 aes_decrypt_key256(const unsigned char *key, uint32_t rk[])
50690bcde94Sda73024 {
50790bcde94Sda73024 	uint32_t	ss[9];
50890bcde94Sda73024 #if defined(d_vars)
50990bcde94Sda73024 	d_vars;
51090bcde94Sda73024 #endif
51190bcde94Sda73024 	rk[v(56, (0))] = ss[0] = word_in(key, 0);
51290bcde94Sda73024 	rk[v(56, (1))] = ss[1] = word_in(key, 1);
51390bcde94Sda73024 	rk[v(56, (2))] = ss[2] = word_in(key, 2);
51490bcde94Sda73024 	rk[v(56, (3))] = ss[3] = word_in(key, 3);
51590bcde94Sda73024 
51690bcde94Sda73024 #ifdef DEC_KS_UNROLL
51790bcde94Sda73024 	ss[4] = word_in(key, 4);
51890bcde94Sda73024 	rk[v(56, (4))] = ff(ss[4]);
51990bcde94Sda73024 	ss[5] = word_in(key, 5);
52090bcde94Sda73024 	rk[v(56, (5))] = ff(ss[5]);
52190bcde94Sda73024 	ss[6] = word_in(key, 6);
52290bcde94Sda73024 	rk[v(56, (6))] = ff(ss[6]);
52390bcde94Sda73024 	ss[7] = word_in(key, 7);
52490bcde94Sda73024 	rk[v(56, (7))] = ff(ss[7]);
52590bcde94Sda73024 	kdf8(rk, 0); kd8(rk, 1);
52690bcde94Sda73024 	kd8(rk, 2);  kd8(rk, 3);
52790bcde94Sda73024 	kd8(rk, 4);  kd8(rk, 5);
52890bcde94Sda73024 	kdl8(rk, 6);
52990bcde94Sda73024 #else
53090bcde94Sda73024 	rk[v(56, (4))] = ss[4] = word_in(key, 4);
53190bcde94Sda73024 	rk[v(56, (5))] = ss[5] = word_in(key, 5);
53290bcde94Sda73024 	rk[v(56, (6))] = ss[6] = word_in(key, 6);
53390bcde94Sda73024 	rk[v(56, (7))] = ss[7] = word_in(key, 7);
53490bcde94Sda73024 	{
53590bcde94Sda73024 		uint32_t	i;
53690bcde94Sda73024 
53790bcde94Sda73024 		for (i = 0; i < 6; ++i)
53890bcde94Sda73024 			k8e(rk,  i);
53990bcde94Sda73024 		k8ef(rk,  6);
54090bcde94Sda73024 #if !(DEC_ROUND == NO_TABLES)
54190bcde94Sda73024 		for (i = MAX_AES_NB; i < 14 * MAX_AES_NB; ++i)
54290bcde94Sda73024 			rk[i] = inv_mcol(rk[i]);
54390bcde94Sda73024 #endif
54490bcde94Sda73024 	}
54590bcde94Sda73024 #endif	/* DEC_KS_UNROLL */
54690bcde94Sda73024 }
54790bcde94Sda73024 
54890bcde94Sda73024 
54990bcde94Sda73024 /*
55090bcde94Sda73024  * Expand the cipher key into the decryption key schedule.
55190bcde94Sda73024  *
55290bcde94Sda73024  * Return the number of rounds for the given cipher key size.
55390bcde94Sda73024  * The size of the key schedule depends on the number of rounds
55490bcde94Sda73024  * (which can be computed from the size of the key), i.e. 4 * (Nr + 1).
55590bcde94Sda73024  *
55690bcde94Sda73024  * Parameters:
55790bcde94Sda73024  * rk		AES key schedule 32-bit array to be initialized
55890bcde94Sda73024  * cipherKey	User key
55990bcde94Sda73024  * keyBits	AES key size (128, 192, or 256 bits)
56090bcde94Sda73024  */
56190bcde94Sda73024 int
rijndael_key_setup_dec_amd64(uint32_t rk[],const uint32_t cipherKey[],int keyBits)562*54034eb2SDan OpenSolaris Anderson rijndael_key_setup_dec_amd64(uint32_t rk[], const uint32_t cipherKey[],
563*54034eb2SDan OpenSolaris Anderson 	int keyBits)
56490bcde94Sda73024 {
56590bcde94Sda73024 	switch (keyBits) {
56690bcde94Sda73024 	case 128:
56790bcde94Sda73024 		aes_decrypt_key128((unsigned char *)&cipherKey[0], rk);
56890bcde94Sda73024 		return (10);
56990bcde94Sda73024 	case 192:
57090bcde94Sda73024 		aes_decrypt_key192((unsigned char *)&cipherKey[0], rk);
57190bcde94Sda73024 		return (12);
57290bcde94Sda73024 	case 256:
57390bcde94Sda73024 		aes_decrypt_key256((unsigned char *)&cipherKey[0], rk);
57490bcde94Sda73024 		return (14);
57590bcde94Sda73024 	default: /* should never get here */
57690bcde94Sda73024 		break;
57790bcde94Sda73024 	}
57890bcde94Sda73024 
57990bcde94Sda73024 	return (0);
58090bcde94Sda73024 }
581