diff options
Diffstat (limited to 'src/lib/crypto/builtin/aes/aeskey.c')
-rw-r--r-- | src/lib/crypto/builtin/aes/aeskey.c | 753 |
1 files changed, 478 insertions, 275 deletions
diff --git a/src/lib/crypto/builtin/aes/aeskey.c b/src/lib/crypto/builtin/aes/aeskey.c index 8402b50..11ed11a 100644 --- a/src/lib/crypto/builtin/aes/aeskey.c +++ b/src/lib/crypto/builtin/aes/aeskey.c @@ -1,69 +1,53 @@ /* - * Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK. - * All rights reserved. - * - * LICENSE TERMS - * - * The free distribution and use of this software in both source and binary - * form is allowed (with or without changes) provided that: - * - * 1. distributions of this source code include the above copyright - * notice, this list of conditions and the following disclaimer; - * - * 2. distributions in binary form include the above copyright - * notice, this list of conditions and the following disclaimer - * in the documentation and/or other associated materials; - * - * 3. the copyright holder's name is not used to endorse products - * built using this software without specific written permission. - * - * DISCLAIMER - * - * This software is provided 'as is' with no explcit or implied warranties - * in respect of any properties, including, but not limited to, correctness - * and fitness for purpose. - */ +--------------------------------------------------------------------------- +Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. -/* - * Issue Date: 21/01/2002 - * - * This file contains the code for implementing the key schedule for AES - * (Rijndael) for block and key sizes of 16, 24, and 32 bytes. - */ +The redistribution and use of this software (with or without changes) +is allowed without the payment of fees or royalties provided that: -#include "aesopt.h" + source code distributions include the above copyright notice, this + list of conditions and the following disclaimer; -#if defined(BLOCK_SIZE) && (BLOCK_SIZE & 7) -#error An illegal block size has been specified. -#endif + binary distributions include the above copyright notice, this list + of conditions and the following disclaimer in their documentation. -/* Subroutine to set the block size (if variable) in bytes, legal - values being 16, 24 and 32. +This software is provided 'as is' with no explicit or implied warranties +in respect of its operation, including, but not limited to, correctness +and fitness for purpose. +--------------------------------------------------------------------------- +Issue Date: 20/12/2007 */ -#if !defined(BLOCK_SIZE) && defined(SET_BLOCK_LENGTH) +#include "aesopt.h" +#include "aestab.h" -aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1]) -{ -#if !defined(FIXED_TABLES) - if(!tab_init) gen_tabs(); +#if defined( USE_INTEL_AES_IF_PRESENT ) +# include "aes_ni.h" +#else +/* map names here to provide the external API ('name' -> 'aes_name') */ +# define aes_xi(x) aes_ ## x #endif - if((blen & 7) || blen < 16 || blen > 32) - { - cx->n_blk = 0; return aes_bad; - } - - cx->n_blk = blen; - return aes_good; -} +#ifdef USE_VIA_ACE_IF_PRESENT +# include "aes_via_ace.h" +#endif +#if defined(__cplusplus) +extern "C" +{ #endif +/* Use the low bit in the context's inf.b[2] as a flag to + indicate whether a context was initialized for encryption + or decryption. +*/ +#define MARK_AS_ENCRYPTION_CTX(cx) (cx)->inf.b[2] |= (uint8_t)0x01 +#define MARK_AS_DECRYPTION_CTX(cx) (cx)->inf.b[2] &= (uint8_t)0xfe + /* Initialise the key schedule from the user supplied key. The key - length is now specified in bytes - 16, 24 or 32 as appropriate. - This corresponds to bit lengths of 128, 192 and 256 bits, and - to Nk values of 4, 6 and 8 respectively. + length can be specified in bytes, with legal values of 16, 24 + and 32, or in bits, with legal values of 128, 192 and 256. These + values correspond with Nk values of 4, 6 and 8 respectively. The following macros implement a single cycle in the key schedule generation process. The number of cycles needed @@ -78,293 +62,512 @@ aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1]) cx->n_col = 8 29 23 19 17 14 */ -#if defined(ENCRYPTION_KEY_SCHEDULE) +#if defined( REDUCE_CODE_SIZE ) +# define ls_box ls_sub + uint32_t ls_sub(const uint32_t t, const uint32_t n); +# define inv_mcol im_sub + uint32_t im_sub(const uint32_t x); +# ifdef ENC_KS_UNROLL +# undef ENC_KS_UNROLL +# endif +# ifdef DEC_KS_UNROLL +# undef DEC_KS_UNROLL +# endif +#endif + +#if (FUNCS_IN_C & ENC_KEYING_IN_C) + +#if defined(AES_128) || defined( AES_VAR ) #define ke4(k,i) \ -{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \ - k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \ +{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \ + k[4*(i)+5] = ss[1] ^= ss[0]; \ + k[4*(i)+6] = ss[2] ^= ss[1]; \ + k[4*(i)+7] = ss[3] ^= ss[2]; \ } -#define kel4(k,i) \ -{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \ - k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \ + +AES_RETURN aes_xi(encrypt_key128)(const unsigned char *key, aes_encrypt_ctx cx[1]) +{ uint32_t ss[4]; + + cx->ks[0] = ss[0] = word_in(key, 0); + cx->ks[1] = ss[1] = word_in(key, 1); + cx->ks[2] = ss[2] = word_in(key, 2); + cx->ks[3] = ss[3] = word_in(key, 3); + +#ifdef ENC_KS_UNROLL + ke4(cx->ks, 0); ke4(cx->ks, 1); + ke4(cx->ks, 2); ke4(cx->ks, 3); + ke4(cx->ks, 4); ke4(cx->ks, 5); + ke4(cx->ks, 6); ke4(cx->ks, 7); + ke4(cx->ks, 8); +#else + { uint32_t i; + for(i = 0; i < 9; ++i) + ke4(cx->ks, i); + } +#endif + ke4(cx->ks, 9); + cx->inf.l = 0; + cx->inf.b[0] = 10 * AES_BLOCK_SIZE; + +#ifdef USE_VIA_ACE_IF_PRESENT + if(VIA_ACE_AVAILABLE) + cx->inf.b[1] = 0xff; +#endif + MARK_AS_ENCRYPTION_CTX(cx); + return EXIT_SUCCESS; +} + +#endif + +#if defined(AES_192) || defined( AES_VAR ) + +#define kef6(k,i) \ +{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \ + k[6*(i)+ 7] = ss[1] ^= ss[0]; \ + k[6*(i)+ 8] = ss[2] ^= ss[1]; \ + k[6*(i)+ 9] = ss[3] ^= ss[2]; \ } #define ke6(k,i) \ -{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \ - k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \ - k[6*(i)+10] = ss[4] ^= ss[3]; k[6*(i)+11] = ss[5] ^= ss[4]; \ +{ kef6(k,i); \ + k[6*(i)+10] = ss[4] ^= ss[3]; \ + k[6*(i)+11] = ss[5] ^= ss[4]; \ } -#define kel6(k,i) \ -{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \ - k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \ + +AES_RETURN aes_xi(encrypt_key192)(const unsigned char *key, aes_encrypt_ctx cx[1]) +{ uint32_t ss[6]; + + cx->ks[0] = ss[0] = word_in(key, 0); + cx->ks[1] = ss[1] = word_in(key, 1); + cx->ks[2] = ss[2] = word_in(key, 2); + cx->ks[3] = ss[3] = word_in(key, 3); + cx->ks[4] = ss[4] = word_in(key, 4); + cx->ks[5] = ss[5] = word_in(key, 5); + +#ifdef ENC_KS_UNROLL + ke6(cx->ks, 0); ke6(cx->ks, 1); + ke6(cx->ks, 2); ke6(cx->ks, 3); + ke6(cx->ks, 4); ke6(cx->ks, 5); + ke6(cx->ks, 6); +#else + { uint32_t i; + for(i = 0; i < 7; ++i) + ke6(cx->ks, i); + } +#endif + kef6(cx->ks, 7); + cx->inf.l = 0; + cx->inf.b[0] = 12 * AES_BLOCK_SIZE; + +#ifdef USE_VIA_ACE_IF_PRESENT + if(VIA_ACE_AVAILABLE) + cx->inf.b[1] = 0xff; +#endif + MARK_AS_ENCRYPTION_CTX(cx); + return EXIT_SUCCESS; } -#define ke8(k,i) \ -{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \ - k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \ - k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); k[8*(i)+13] = ss[5] ^= ss[4]; \ - k[8*(i)+14] = ss[6] ^= ss[5]; k[8*(i)+15] = ss[7] ^= ss[6]; \ +#endif + +#if defined(AES_256) || defined( AES_VAR ) + +#define kef8(k,i) \ +{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \ + k[8*(i)+ 9] = ss[1] ^= ss[0]; \ + k[8*(i)+10] = ss[2] ^= ss[1]; \ + k[8*(i)+11] = ss[3] ^= ss[2]; \ } -#define kel8(k,i) \ -{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \ - k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \ + +#define ke8(k,i) \ +{ kef8(k,i); \ + k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \ + k[8*(i)+13] = ss[5] ^= ss[4]; \ + k[8*(i)+14] = ss[6] ^= ss[5]; \ + k[8*(i)+15] = ss[7] ^= ss[6]; \ } -aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]) +AES_RETURN aes_xi(encrypt_key256)(const unsigned char *key, aes_encrypt_ctx cx[1]) { uint32_t ss[8]; -#if !defined(FIXED_TABLES) - if(!tab_init) gen_tabs(); -#endif - -#if !defined(BLOCK_SIZE) - if(!cx->n_blk) cx->n_blk = 16; -#else - cx->n_blk = BLOCK_SIZE; -#endif - - cx->n_blk = (cx->n_blk & ~3U) | 1; - - cx->k_sch[0] = ss[0] = word_in(in_key ); - cx->k_sch[1] = ss[1] = word_in(in_key + 4); - cx->k_sch[2] = ss[2] = word_in(in_key + 8); - cx->k_sch[3] = ss[3] = word_in(in_key + 12); - -#if (BLOCK_SIZE == 16) && (ENC_UNROLL != NONE) - - switch(klen) - { - case 16: ke4(cx->k_sch, 0); ke4(cx->k_sch, 1); - ke4(cx->k_sch, 2); ke4(cx->k_sch, 3); - ke4(cx->k_sch, 4); ke4(cx->k_sch, 5); - ke4(cx->k_sch, 6); ke4(cx->k_sch, 7); - ke4(cx->k_sch, 8); kel4(cx->k_sch, 9); - cx->n_rnd = 10; break; - case 24: cx->k_sch[4] = ss[4] = word_in(in_key + 16); - cx->k_sch[5] = ss[5] = word_in(in_key + 20); - ke6(cx->k_sch, 0); ke6(cx->k_sch, 1); - ke6(cx->k_sch, 2); ke6(cx->k_sch, 3); - ke6(cx->k_sch, 4); ke6(cx->k_sch, 5); - ke6(cx->k_sch, 6); kel6(cx->k_sch, 7); - cx->n_rnd = 12; break; - case 32: cx->k_sch[4] = ss[4] = word_in(in_key + 16); - cx->k_sch[5] = ss[5] = word_in(in_key + 20); - cx->k_sch[6] = ss[6] = word_in(in_key + 24); - cx->k_sch[7] = ss[7] = word_in(in_key + 28); - ke8(cx->k_sch, 0); ke8(cx->k_sch, 1); - ke8(cx->k_sch, 2); ke8(cx->k_sch, 3); - ke8(cx->k_sch, 4); ke8(cx->k_sch, 5); - kel8(cx->k_sch, 6); - cx->n_rnd = 14; break; - default: cx->n_rnd = 0; return aes_bad; - } + cx->ks[0] = ss[0] = word_in(key, 0); + cx->ks[1] = ss[1] = word_in(key, 1); + cx->ks[2] = ss[2] = word_in(key, 2); + cx->ks[3] = ss[3] = word_in(key, 3); + cx->ks[4] = ss[4] = word_in(key, 4); + cx->ks[5] = ss[5] = word_in(key, 5); + cx->ks[6] = ss[6] = word_in(key, 6); + cx->ks[7] = ss[7] = word_in(key, 7); + +#ifdef ENC_KS_UNROLL + ke8(cx->ks, 0); ke8(cx->ks, 1); + ke8(cx->ks, 2); ke8(cx->ks, 3); + ke8(cx->ks, 4); ke8(cx->ks, 5); #else - { uint32_t i, l; - cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6; - l = (nc * cx->n_rnd + nc - 1) / (klen >> 2); - - switch(klen) - { - case 16: for(i = 0; i < l; ++i) - ke4(cx->k_sch, i); - break; - case 24: cx->k_sch[4] = ss[4] = word_in(in_key + 16); - cx->k_sch[5] = ss[5] = word_in(in_key + 20); - for(i = 0; i < l; ++i) - ke6(cx->k_sch, i); - break; - case 32: cx->k_sch[4] = ss[4] = word_in(in_key + 16); - cx->k_sch[5] = ss[5] = word_in(in_key + 20); - cx->k_sch[6] = ss[6] = word_in(in_key + 24); - cx->k_sch[7] = ss[7] = word_in(in_key + 28); - for(i = 0; i < l; ++i) - ke8(cx->k_sch, i); - break; - default: cx->n_rnd = 0; return aes_bad; - } + { uint32_t i; + for(i = 0; i < 6; ++i) + ke8(cx->ks, i); } #endif + kef8(cx->ks, 6); + cx->inf.l = 0; + cx->inf.b[0] = 14 * AES_BLOCK_SIZE; - return aes_good; +#ifdef USE_VIA_ACE_IF_PRESENT + if(VIA_ACE_AVAILABLE) + cx->inf.b[1] = 0xff; +#endif + MARK_AS_ENCRYPTION_CTX(cx); + return EXIT_SUCCESS; } #endif -#if defined(DECRYPTION_KEY_SCHEDULE) +#endif -#if (DEC_ROUND != NO_TABLES) -#define d_vars dec_imvars -#define ff(x) inv_mcol(x) +#if (FUNCS_IN_C & DEC_KEYING_IN_C) + +/* this is used to store the decryption round keys */ +/* in forward or reverse order */ + +#ifdef AES_REV_DKS +#define v(n,i) ((n) - (i) + 2 * ((i) & 3)) #else +#define v(n,i) (i) +#endif + +#if DEC_ROUND == NO_TABLES #define ff(x) (x) -#define d_vars +#else +#define ff(x) inv_mcol(x) +#if defined( dec_imvars ) +#define d_vars dec_imvars #endif +#endif + +#if defined(AES_128) || defined( AES_VAR ) + +#define k4e(k,i) \ +{ k[v(40,(4*(i))+4)] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \ + k[v(40,(4*(i))+5)] = ss[1] ^= ss[0]; \ + k[v(40,(4*(i))+6)] = ss[2] ^= ss[1]; \ + k[v(40,(4*(i))+7)] = ss[3] ^= ss[2]; \ +} #if 1 + #define kdf4(k,i) \ -{ ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; ss[1] = ss[1] ^ ss[3]; ss[2] = ss[2] ^ ss[3]; ss[3] = ss[3]; \ - ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; \ - ss[4] ^= k[4*(i)]; k[4*(i)+4] = ff(ss[4]); ss[4] ^= k[4*(i)+1]; k[4*(i)+5] = ff(ss[4]); \ - ss[4] ^= k[4*(i)+2]; k[4*(i)+6] = ff(ss[4]); ss[4] ^= k[4*(i)+3]; k[4*(i)+7] = ff(ss[4]); \ +{ ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \ + ss[1] = ss[1] ^ ss[3]; \ + ss[2] = ss[2] ^ ss[3]; \ + ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \ + ss[i % 4] ^= ss[4]; \ + ss[4] ^= k[v(40,(4*(i)))]; k[v(40,(4*(i))+4)] = ff(ss[4]); \ + ss[4] ^= k[v(40,(4*(i))+1)]; k[v(40,(4*(i))+5)] = ff(ss[4]); \ + ss[4] ^= k[v(40,(4*(i))+2)]; k[v(40,(4*(i))+6)] = ff(ss[4]); \ + ss[4] ^= k[v(40,(4*(i))+3)]; k[v(40,(4*(i))+7)] = ff(ss[4]); \ } + #define kd4(k,i) \ -{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \ - k[4*(i)+4] = ss[4] ^= k[4*(i)]; k[4*(i)+5] = ss[4] ^= k[4*(i)+1]; \ - k[4*(i)+6] = ss[4] ^= k[4*(i)+2]; k[4*(i)+7] = ss[4] ^= k[4*(i)+3]; \ +{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \ + ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \ + k[v(40,(4*(i))+4)] = ss[4] ^= k[v(40,(4*(i)))]; \ + k[v(40,(4*(i))+5)] = ss[4] ^= k[v(40,(4*(i))+1)]; \ + k[v(40,(4*(i))+6)] = ss[4] ^= k[v(40,(4*(i))+2)]; \ + k[v(40,(4*(i))+7)] = ss[4] ^= k[v(40,(4*(i))+3)]; \ } + #define kdl4(k,i) \ -{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; \ - k[4*(i)+4] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; k[4*(i)+5] = ss[1] ^ ss[3]; \ - k[4*(i)+6] = ss[0]; k[4*(i)+7] = ss[1]; \ +{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \ + k[v(40,(4*(i))+4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \ + k[v(40,(4*(i))+5)] = ss[1] ^ ss[3]; \ + k[v(40,(4*(i))+6)] = ss[0]; \ + k[v(40,(4*(i))+7)] = ss[1]; \ } + #else + #define kdf4(k,i) \ -{ ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+ 4] = ff(ss[0]); ss[1] ^= ss[0]; k[4*(i)+ 5] = ff(ss[1]); \ - ss[2] ^= ss[1]; k[4*(i)+ 6] = ff(ss[2]); ss[3] ^= ss[2]; k[4*(i)+ 7] = ff(ss[3]); \ +{ ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ff(ss[0]); \ + ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ff(ss[1]); \ + ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ff(ss[2]); \ + ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ff(ss[3]); \ } + #define kd4(k,i) \ -{ ss[4] = ls_box(ss[3],3) ^ rcon_tab[i]; \ - ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[4*(i)+ 4] = ss[4] ^= k[4*(i)]; \ - ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[4] ^= k[4*(i)+ 1]; \ - ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[4] ^= k[4*(i)+ 2]; \ - ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[4] ^= k[4*(i)+ 3]; \ +{ ss[4] = ls_box(ss[3],3) ^ t_use(r,c)[i]; \ + ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[v(40,(4*(i))+ 4)] = ss[4] ^= k[v(40,(4*(i)))]; \ + ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[4] ^= k[v(40,(4*(i))+ 1)]; \ + ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[4] ^= k[v(40,(4*(i))+ 2)]; \ + ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[4] ^= k[v(40,(4*(i))+ 3)]; \ } + #define kdl4(k,i) \ -{ ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+ 4] = ss[0]; ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[1]; \ - ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[2]; ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[3]; \ +{ ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ss[0]; \ + ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[1]; \ + ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[2]; \ + ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[3]; \ } + +#endif + +AES_RETURN aes_xi(decrypt_key128)(const unsigned char *key, aes_decrypt_ctx cx[1]) +{ uint32_t ss[5]; +#if defined( d_vars ) + d_vars; +#endif + + cx->ks[v(40,(0))] = ss[0] = word_in(key, 0); + cx->ks[v(40,(1))] = ss[1] = word_in(key, 1); + cx->ks[v(40,(2))] = ss[2] = word_in(key, 2); + cx->ks[v(40,(3))] = ss[3] = word_in(key, 3); + +#ifdef DEC_KS_UNROLL + kdf4(cx->ks, 0); kd4(cx->ks, 1); + kd4(cx->ks, 2); kd4(cx->ks, 3); + kd4(cx->ks, 4); kd4(cx->ks, 5); + kd4(cx->ks, 6); kd4(cx->ks, 7); + kd4(cx->ks, 8); kdl4(cx->ks, 9); +#else + { uint32_t i; + for(i = 0; i < 10; ++i) + k4e(cx->ks, i); +#if !(DEC_ROUND == NO_TABLES) + for(i = N_COLS; i < 10 * N_COLS; ++i) + cx->ks[i] = inv_mcol(cx->ks[i]); +#endif + } #endif + cx->inf.l = 0; + cx->inf.b[0] = 10 * AES_BLOCK_SIZE; + +#ifdef USE_VIA_ACE_IF_PRESENT + if(VIA_ACE_AVAILABLE) + cx->inf.b[1] = 0xff; +#endif + MARK_AS_DECRYPTION_CTX(cx); + return EXIT_SUCCESS; +} + +#endif + +#if defined(AES_192) || defined( AES_VAR ) + +#define k6ef(k,i) \ +{ k[v(48,(6*(i))+ 6)] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \ + k[v(48,(6*(i))+ 7)] = ss[1] ^= ss[0]; \ + k[v(48,(6*(i))+ 8)] = ss[2] ^= ss[1]; \ + k[v(48,(6*(i))+ 9)] = ss[3] ^= ss[2]; \ +} + +#define k6e(k,i) \ +{ k6ef(k,i); \ + k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \ + k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \ +} #define kdf6(k,i) \ -{ ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 6] = ff(ss[0]); ss[1] ^= ss[0]; k[6*(i)+ 7] = ff(ss[1]); \ - ss[2] ^= ss[1]; k[6*(i)+ 8] = ff(ss[2]); ss[3] ^= ss[2]; k[6*(i)+ 9] = ff(ss[3]); \ - ss[4] ^= ss[3]; k[6*(i)+10] = ff(ss[4]); ss[5] ^= ss[4]; k[6*(i)+11] = ff(ss[5]); \ +{ ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ff(ss[0]); \ + ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ff(ss[1]); \ + ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ff(ss[2]); \ + ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ff(ss[3]); \ + ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ff(ss[4]); \ + ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ff(ss[5]); \ } + #define kd6(k,i) \ -{ ss[6] = ls_box(ss[5],3) ^ rcon_tab[i]; \ - ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[6*(i)+ 6] = ss[6] ^= k[6*(i)]; \ - ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[6] ^= k[6*(i)+ 1]; \ - ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[6] ^= k[6*(i)+ 2]; \ - ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[6] ^= k[6*(i)+ 3]; \ - ss[4] ^= ss[3]; k[6*(i)+10] = ss[6] ^= k[6*(i)+ 4]; \ - ss[5] ^= ss[4]; k[6*(i)+11] = ss[6] ^= k[6*(i)+ 5]; \ +{ ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \ + ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[v(48,(6*(i))+ 6)] = ss[6] ^= k[v(48,(6*(i)))]; \ + ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[6] ^= k[v(48,(6*(i))+ 1)]; \ + ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[6] ^= k[v(48,(6*(i))+ 2)]; \ + ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[6] ^= k[v(48,(6*(i))+ 3)]; \ + ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ss[6] ^= k[v(48,(6*(i))+ 4)]; \ + ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ss[6] ^= k[v(48,(6*(i))+ 5)]; \ } + #define kdl6(k,i) \ -{ ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 6] = ss[0]; ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[1]; \ - ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[2]; ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[3]; \ +{ ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ss[0]; \ + ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[1]; \ + ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[2]; \ + ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \ +} + +AES_RETURN aes_xi(decrypt_key192)(const unsigned char *key, aes_decrypt_ctx cx[1]) +{ uint32_t ss[7]; +#if defined( d_vars ) + d_vars; +#endif + + cx->ks[v(48,(0))] = ss[0] = word_in(key, 0); + cx->ks[v(48,(1))] = ss[1] = word_in(key, 1); + cx->ks[v(48,(2))] = ss[2] = word_in(key, 2); + cx->ks[v(48,(3))] = ss[3] = word_in(key, 3); + +#ifdef DEC_KS_UNROLL + ss[4] = word_in(key, 4); + ss[5] = word_in(key, 5); + cx->ks[v(48, (4))] = ff(ss[4]); + cx->ks[v(48, (5))] = ff(ss[5]); + kdf6(cx->ks, 0); kd6(cx->ks, 1); + kd6(cx->ks, 2); kd6(cx->ks, 3); + kd6(cx->ks, 4); kd6(cx->ks, 5); + kd6(cx->ks, 6); kdl6(cx->ks, 7); +#else + cx->ks[v(48,(4))] = ss[4] = word_in(key, 4); + cx->ks[v(48,(5))] = ss[5] = word_in(key, 5); + { uint32_t i; + + for(i = 0; i < 7; ++i) + k6e(cx->ks, i); + k6ef(cx->ks, 7); +#if !(DEC_ROUND == NO_TABLES) + for(i = N_COLS; i < 12 * N_COLS; ++i) + cx->ks[i] = inv_mcol(cx->ks[i]); +#endif + } +#endif + cx->inf.l = 0; + cx->inf.b[0] = 12 * AES_BLOCK_SIZE; + +#ifdef USE_VIA_ACE_IF_PRESENT + if(VIA_ACE_AVAILABLE) + cx->inf.b[1] = 0xff; +#endif + MARK_AS_DECRYPTION_CTX(cx); + return EXIT_SUCCESS; +} + +#endif + +#if defined(AES_256) || defined( AES_VAR ) + +#define k8ef(k,i) \ +{ k[v(56,(8*(i))+ 8)] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \ + k[v(56,(8*(i))+ 9)] = ss[1] ^= ss[0]; \ + k[v(56,(8*(i))+10)] = ss[2] ^= ss[1]; \ + k[v(56,(8*(i))+11)] = ss[3] ^= ss[2]; \ +} + +#define k8e(k,i) \ +{ k8ef(k,i); \ + k[v(56,(8*(i))+12)] = ss[4] ^= ls_box(ss[3],0); \ + k[v(56,(8*(i))+13)] = ss[5] ^= ss[4]; \ + k[v(56,(8*(i))+14)] = ss[6] ^= ss[5]; \ + k[v(56,(8*(i))+15)] = ss[7] ^= ss[6]; \ } #define kdf8(k,i) \ -{ ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 8] = ff(ss[0]); ss[1] ^= ss[0]; k[8*(i)+ 9] = ff(ss[1]); \ - ss[2] ^= ss[1]; k[8*(i)+10] = ff(ss[2]); ss[3] ^= ss[2]; k[8*(i)+11] = ff(ss[3]); \ - ss[4] ^= ls_box(ss[3],0); k[8*(i)+12] = ff(ss[4]); ss[5] ^= ss[4]; k[8*(i)+13] = ff(ss[5]); \ - ss[6] ^= ss[5]; k[8*(i)+14] = ff(ss[6]); ss[7] ^= ss[6]; k[8*(i)+15] = ff(ss[7]); \ +{ ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ff(ss[0]); \ + ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ff(ss[1]); \ + ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ff(ss[2]); \ + ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ff(ss[3]); \ + ss[4] ^= ls_box(ss[3],0); k[v(56,(8*(i))+12)] = ff(ss[4]); \ + ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ff(ss[5]); \ + ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ff(ss[6]); \ + ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ff(ss[7]); \ } + #define kd8(k,i) \ -{ uint32_t g = ls_box(ss[7],3) ^ rcon_tab[i]; \ - ss[0] ^= g; g = ff(g); k[8*(i)+ 8] = g ^= k[8*(i)]; \ - ss[1] ^= ss[0]; k[8*(i)+ 9] = g ^= k[8*(i)+ 1]; \ - ss[2] ^= ss[1]; k[8*(i)+10] = g ^= k[8*(i)+ 2]; \ - ss[3] ^= ss[2]; k[8*(i)+11] = g ^= k[8*(i)+ 3]; \ - g = ls_box(ss[3],0); \ - ss[4] ^= g; g = ff(g); k[8*(i)+12] = g ^= k[8*(i)+ 4]; \ - ss[5] ^= ss[4]; k[8*(i)+13] = g ^= k[8*(i)+ 5]; \ - ss[6] ^= ss[5]; k[8*(i)+14] = g ^= k[8*(i)+ 6]; \ - ss[7] ^= ss[6]; k[8*(i)+15] = g ^= k[8*(i)+ 7]; \ +{ ss[8] = ls_box(ss[7],3) ^ t_use(r,c)[i]; \ + ss[0] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+ 8)] = ss[8] ^= k[v(56,(8*(i)))]; \ + ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[8] ^= k[v(56,(8*(i))+ 1)]; \ + ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[8] ^= k[v(56,(8*(i))+ 2)]; \ + ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[8] ^= k[v(56,(8*(i))+ 3)]; \ + ss[8] = ls_box(ss[3],0); \ + ss[4] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+12)] = ss[8] ^= k[v(56,(8*(i))+ 4)]; \ + ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ss[8] ^= k[v(56,(8*(i))+ 5)]; \ + ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ss[8] ^= k[v(56,(8*(i))+ 6)]; \ + ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ss[8] ^= k[v(56,(8*(i))+ 7)]; \ } + #define kdl8(k,i) \ -{ ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 8] = ss[0]; ss[1] ^= ss[0]; k[8*(i)+ 9] = ss[1]; \ - ss[2] ^= ss[1]; k[8*(i)+10] = ss[2]; ss[3] ^= ss[2]; k[8*(i)+11] = ss[3]; \ +{ ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ss[0]; \ + ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[1]; \ + ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[2]; \ + ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[3]; \ } -aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]) -{ uint32_t ss[8]; - d_vars - -#if !defined(FIXED_TABLES) - if(!tab_init) gen_tabs(); +AES_RETURN aes_xi(decrypt_key256)(const unsigned char *key, aes_decrypt_ctx cx[1]) +{ uint32_t ss[9]; +#if defined( d_vars ) + d_vars; #endif -#if !defined(BLOCK_SIZE) - if(!cx->n_blk) cx->n_blk = 16; -#else - cx->n_blk = BLOCK_SIZE; -#endif - - cx->n_blk = (cx->n_blk & ~3U) | 2; - - cx->k_sch[0] = ss[0] = word_in(in_key ); - cx->k_sch[1] = ss[1] = word_in(in_key + 4); - cx->k_sch[2] = ss[2] = word_in(in_key + 8); - cx->k_sch[3] = ss[3] = word_in(in_key + 12); - -#if (BLOCK_SIZE == 16) && (DEC_UNROLL != NONE) - - switch(klen) - { - case 16: kdf4(cx->k_sch, 0); kd4(cx->k_sch, 1); - kd4(cx->k_sch, 2); kd4(cx->k_sch, 3); - kd4(cx->k_sch, 4); kd4(cx->k_sch, 5); - kd4(cx->k_sch, 6); kd4(cx->k_sch, 7); - kd4(cx->k_sch, 8); kdl4(cx->k_sch, 9); - cx->n_rnd = 10; break; - case 24: ss[4] = word_in(in_key + 16); - cx->k_sch[4] = ff(ss[4]); - ss[5] = word_in(in_key + 20); - cx->k_sch[5] = ff(ss[5]); - kdf6(cx->k_sch, 0); kd6(cx->k_sch, 1); - kd6(cx->k_sch, 2); kd6(cx->k_sch, 3); - kd6(cx->k_sch, 4); kd6(cx->k_sch, 5); - kd6(cx->k_sch, 6); kdl6(cx->k_sch, 7); - cx->n_rnd = 12; break; - case 32: ss[4] = word_in(in_key + 16); - cx->k_sch[4] = ff(ss[4]); - ss[5] = word_in(in_key + 20); - cx->k_sch[5] = ff(ss[5]); - ss[6] = word_in(in_key + 24); - cx->k_sch[6] = ff(ss[6]); - ss[7] = word_in(in_key + 28); - cx->k_sch[7] = ff(ss[7]); - kdf8(cx->k_sch, 0); kd8(cx->k_sch, 1); - kd8(cx->k_sch, 2); kd8(cx->k_sch, 3); - kd8(cx->k_sch, 4); kd8(cx->k_sch, 5); - kdl8(cx->k_sch, 6); - cx->n_rnd = 14; break; - default: cx->n_rnd = 0; return aes_bad; - } + cx->ks[v(56,(0))] = ss[0] = word_in(key, 0); + cx->ks[v(56,(1))] = ss[1] = word_in(key, 1); + cx->ks[v(56,(2))] = ss[2] = word_in(key, 2); + cx->ks[v(56,(3))] = ss[3] = word_in(key, 3); + +#ifdef DEC_KS_UNROLL + ss[4] = word_in(key, 4); + ss[5] = word_in(key, 5); + ss[6] = word_in(key, 6); + ss[7] = word_in(key, 7); + cx->ks[v(56,(4))] = ff(ss[4]); + cx->ks[v(56,(5))] = ff(ss[5]); + cx->ks[v(56,(6))] = ff(ss[6]); + cx->ks[v(56,(7))] = ff(ss[7]); + kdf8(cx->ks, 0); kd8(cx->ks, 1); + kd8(cx->ks, 2); kd8(cx->ks, 3); + kd8(cx->ks, 4); kd8(cx->ks, 5); + kdl8(cx->ks, 6); #else - { uint32_t i, l; - cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6; - l = (nc * cx->n_rnd + nc - 1) / (klen >> 2); - - switch(klen) - { - case 16: - for(i = 0; i < l; ++i) - ke4(cx->k_sch, i); - break; - case 24: cx->k_sch[4] = ss[4] = word_in(in_key + 16); - cx->k_sch[5] = ss[5] = word_in(in_key + 20); - for(i = 0; i < l; ++i) - ke6(cx->k_sch, i); - break; - case 32: cx->k_sch[4] = ss[4] = word_in(in_key + 16); - cx->k_sch[5] = ss[5] = word_in(in_key + 20); - cx->k_sch[6] = ss[6] = word_in(in_key + 24); - cx->k_sch[7] = ss[7] = word_in(in_key + 28); - for(i = 0; i < l; ++i) - ke8(cx->k_sch, i); - break; - default: cx->n_rnd = 0; return aes_bad; - } -#if (DEC_ROUND != NO_TABLES) - for(i = nc; i < nc * cx->n_rnd; ++i) - cx->k_sch[i] = inv_mcol(cx->k_sch[i]); + cx->ks[v(56,(4))] = ss[4] = word_in(key, 4); + cx->ks[v(56,(5))] = ss[5] = word_in(key, 5); + cx->ks[v(56,(6))] = ss[6] = word_in(key, 6); + cx->ks[v(56,(7))] = ss[7] = word_in(key, 7); + { uint32_t i; + + for(i = 0; i < 6; ++i) + k8e(cx->ks, i); + k8ef(cx->ks, 6); +#if !(DEC_ROUND == NO_TABLES) + for(i = N_COLS; i < 14 * N_COLS; ++i) + cx->ks[i] = inv_mcol(cx->ks[i]); #endif } #endif + cx->inf.l = 0; + cx->inf.b[0] = 14 * AES_BLOCK_SIZE; - return aes_good; +#ifdef USE_VIA_ACE_IF_PRESENT + if(VIA_ACE_AVAILABLE) + cx->inf.b[1] = 0xff; +#endif + MARK_AS_DECRYPTION_CTX(cx); + return EXIT_SUCCESS; } #endif + +#endif + +#if defined( AES_VAR ) + +AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1]) +{ + switch(key_len) + { + case 16: case 128: return aes_encrypt_key128(key, cx); + case 24: case 192: return aes_encrypt_key192(key, cx); + case 32: case 256: return aes_encrypt_key256(key, cx); + default: return EXIT_FAILURE; + } +} + +AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]) +{ + switch(key_len) + { + case 16: case 128: return aes_decrypt_key128(key, cx); + case 24: case 192: return aes_decrypt_key192(key, cx); + case 32: case 256: return aes_decrypt_key256(key, cx); + default: return EXIT_FAILURE; + } +} + +#endif + +#if defined(__cplusplus) +} +#endif |