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 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 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 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 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 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 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 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 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