diff options
Diffstat (limited to 'Source/charon/transforms')
-rw-r--r-- | Source/charon/transforms/crypters/aes_cbc_crypter.c | 673 |
1 files changed, 322 insertions, 351 deletions
diff --git a/Source/charon/transforms/crypters/aes_cbc_crypter.c b/Source/charon/transforms/crypters/aes_cbc_crypter.c index be1c0d27e..7e4b13bde 100644 --- a/Source/charon/transforms/crypters/aes_cbc_crypter.c +++ b/Source/charon/transforms/crypters/aes_cbc_crypter.c @@ -84,60 +84,34 @@ struct private_aes_cbc_crypter_t { */ u_int32_t blocksize; - - /** - * @brief Encrypt a chunk of data with blocksize length. - * - * No memory is allocated in here so caller is responsible to allocate memory. - * - * @param this calling crypter - * @param data data to encrypt - * @param [out]encrypted pointer where the encrypted bytes will be written to - * @return - * - SUCCESS in any case - */ - status_t (*encrypt_block) (private_aes_cbc_crypter_t *this, u_int8_t *data, u_int8_t *encrypted); - - /** - * @brief Decrypt a chunk of data with blocksize length. - * - * No memory is allocated in here so caller is responsible to allocate memory. - * - * @param this calling crypter - * @param data data to decrypt - * @param [out]encrypted pointer where the decrypted bytes will be written - * @return - * - SUCCESS in any case - */ - status_t (*decrypt_block) (private_aes_cbc_crypter_t *this, u_int8_t *data, u_int8_t *decrypted); - + }; /* ugly macro stuff */ - -/* CONFIGURATION OPTIONS - * - * 1. Define UNROLL for full loop unrolling in encryption and decryption. - * 2. Define PARTIAL_UNROLL to unroll two loops in encryption and decryption. - * 3. Define FIXED_TABLES for compiled rather than dynamic tables. - * 4. Define FF_TABLES to use tables for field multiplies and inverses. - * Do not enable this without understanding stack space requirements. - * 5. Define ARRAYS to use arrays to hold the local state block. If this - * is not defined, individually declared 32-bit words are used. - * 6. Define FAST_VARIABLE if a high speed variable block implementation - * is needed (essentially three separate fixed block size code sequences) - * 7. Define either ONE_TABLE or FOUR_TABLES for a fast table driven - * version using 1 table (2 kbytes of table space) or 4 tables (8 - * kbytes of table space) for higher speed. - * 8. Define either ONE_LR_TABLE or FOUR_LR_TABLES for a further speed - * increase by using tables for the last rounds but with more table - * space (2 or 8 kbytes extra). - * 9. If neither ONE_TABLE nor FOUR_TABLES is defined, a compact but - * slower version is provided. - * 10. If fast decryption key scheduling is needed define ONE_IM_TABLE - * or FOUR_IM_TABLES for higher speed (2 or 8 kbytes extra). - */ +/*******************************/ + +// CONFIGURATION OPTIONS (see also aes.h) +// +// 1. Define UNROLL for full loop unrolling in encryption and decryption. +// 2. Define PARTIAL_UNROLL to unroll two loops in encryption and decryption. +// 3. Define FIXED_TABLES for compiled rather than dynamic tables. +// 4. Define FF_TABLES to use tables for field multiplies and inverses. +// Do not enable this without understanding stack space requirements. +// 5. Define ARRAYS to use arrays to hold the local state block. If this +// is not defined, individually declared 32-bit words are used. +// 6. Define FAST_VARIABLE if a high speed variable block implementation +// is needed (essentially three separate fixed block size code sequences) +// 7. Define either ONE_TABLE or FOUR_TABLES for a fast table driven +// version using 1 table (2 kbytes of table space) or 4 tables (8 +// kbytes of table space) for higher speed. +// 8. Define either ONE_LR_TABLE or FOUR_LR_TABLES for a further speed +// increase by using tables for the last rounds but with more table +// space (2 or 8 kbytes extra). +// 9. If neither ONE_TABLE nor FOUR_TABLES is defined, a compact but +// slower version is provided. +// 10. If fast decryption key scheduling is needed define ONE_IM_TABLE +// or FOUR_IM_TABLES for higher speed (2 or 8 kbytes extra). #define UNROLL //#define PARTIAL_UNROLL @@ -172,27 +146,19 @@ struct private_aes_cbc_crypter_t { #error both ONE_IM_TABLE and FOUR_IM_TABLES are defined #endif +#if defined(AES_BLOCK_SIZE) && AES_BLOCK_SIZE != 16 && AES_BLOCK_SIZE != 24 && AES_BLOCK_SIZE != 32 +#error an illegal block size has been specified +#endif -/** - * Rotates bytes within words by n positions, moving bytes - * to higher index positions with wrap around into low positions. - */ -#define upr(x,n) (((x) << 8 * (n)) | ((x) >> (32 - 8 * (n)))) +// upr(x,n): rotates bytes within words by n positions, moving bytes +// to higher index positions with wrap around into low positions +// ups(x,n): moves bytes by n positions to higher index positions in +// words but without wrap around +// bval(x,n): extracts a byte from a word -/** - * Moves bytes by n positions to higher index positions in - * words but without wrap around. - */ +#define upr(x,n) (((x) << 8 * (n)) | ((x) >> (32 - 8 * (n)))) #define ups(x,n) ((x) << 8 * (n)) - -/** - * Extracts a byte from a word. - */ #define bval(x,n) ((unsigned char)((x) >> 8 * (n))) - -/** - * Creates a word value from 4 byte values. - */ #define bytes2word(b0, b1, b2, b3) \ ((u_int32_t)(b3) << 24 | (u_int32_t)(b2) << 16 | (u_int32_t)(b1) << 8 | (b0)) @@ -249,40 +215,34 @@ struct private_aes_cbc_crypter_t { #endif #endif -/** - * The finite field modular polynomial and elements. - */ +// the finite field modular polynomial and elements + #define ff_poly 0x011b #define ff_hi 0x80 +// multiply four bytes in GF(2^8) by 'x' {02} in parallel -/** - * Multiply four bytes in GF(2^8) by 'x' {02} in parallel. - */ #define m1 0x80808080 #define m2 0x7f7f7f7f #define m3 0x0000001b #define FFmulX(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * m3)) -/* The following defines provide alternative definitions of FFmulX that might - * give improved performance if a fast 32-bit multiply is not available. Note - * that a temporary variable u needs to be defined where FFmulX is used. +// The following defines provide alternative definitions of FFmulX that might +// give improved performance if a fast 32-bit multiply is not available. Note +// that a temporary variable u needs to be defined where FFmulX is used. - * #define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6)) - * #define m4 0x1b1b1b1b - * #define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4) - */ +// #define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6)) +// #define m4 0x1b1b1b1b +// #define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4) + +// perform column mix operation on four bytes in parallel -/** - * Prform column mix operation on four bytes in parallel. - */ #define fwd_mcol(x) (f2 = FFmulX(x), f2 ^ upr(x ^ f2,3) ^ upr(x,2) ^ upr(x,1)) #if defined(FIXED_TABLES) -/** - * The S-Box table. - */ +// the S-Box table + static const unsigned char s_box[256] = { 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, @@ -319,9 +279,8 @@ static const unsigned char s_box[256] = 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; -/** - * The inverse S-Box table - */ +// the inverse S-Box table + static const unsigned char inv_s_box[256] = { 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, @@ -360,19 +319,17 @@ static const unsigned char inv_s_box[256] = #define w0(p) 0x000000##p -/* - * Number of elements required in this table for different - * block and key lengths is: - * - * Nk = 4 6 8 - * ---------- - * Nb = 4 | 10 8 7 - * 6 | 19 12 11 - * 8 | 29 19 14 - * - * this table can be a table of bytes if the key schedule - * code is adjusted accordingly - */ +// Number of elements required in this table for different +// block and key lengths is: +// +// Nk = 4 6 8 +// ---------- +// Nb = 4 | 10 8 7 +// 6 | 19 12 11 +// 8 | 29 19 14 +// +// this table can be a table of bytes if the key schedule +// code is adjusted accordingly static const u_int32_t rcon_tab[29] = { @@ -399,9 +356,8 @@ static const u_int32_t rcon_tab[29] = #if defined(FIXED_TABLES) && (defined(ONE_TABLE) || defined(FOUR_TABLES)) -/** - * Data for forward tables (other than last round) - */ +// data for forward tables (other than last round) + #define f_table \ r(a5,63,63,c6), r(84,7c,7c,f8), r(99,77,77,ee), r(8d,7b,7b,f6),\ r(0d,f2,f2,ff), r(bd,6b,6b,d6), r(b1,6f,6f,de), r(54,c5,c5,91),\ @@ -468,9 +424,8 @@ static const u_int32_t rcon_tab[29] = r(c3,41,41,82), r(b0,99,99,29), r(77,2d,2d,5a), r(11,0f,0f,1e),\ r(cb,b0,b0,7b), r(fc,54,54,a8), r(d6,bb,bb,6d), r(3a,16,16,2c) -/** - * Ddata for inverse tables (other than last round). - */ +// data for inverse tables (other than last round) + #define i_table \ r(50,a7,f4,51), r(53,65,41,7e), r(c3,a4,17,1a), r(96,5e,27,3a),\ r(cb,6b,ab,3b), r(f1,45,9d,1f), r(ab,58,fa,ac), r(93,03,e3,4b),\ @@ -537,7 +492,7 @@ static const u_int32_t rcon_tab[29] = r(71,01,a8,39), r(de,b3,0c,08), r(9c,e4,b4,d8), r(90,c1,56,64),\ r(61,84,cb,7b), r(70,b6,32,d5), r(74,5c,6c,48), r(42,57,b8,d0) -/* generate the required tables in the desired endian format */ +// generate the required tables in the desired endian format #undef r #define r r0 @@ -584,9 +539,8 @@ static const u_int32_t it_tab[4][256] = #if defined(FIXED_TABLES) && (defined(ONE_LR_TABLE) || defined(FOUR_LR_TABLES)) -/** - * Data for inverse tables (last round) - */ +// data for inverse tables (last round) + #define li_table \ w(52), w(09), w(6a), w(d5), w(30), w(36), w(a5), w(38),\ w(bf), w(40), w(a3), w(9e), w(81), w(f3), w(d7), w(fb),\ @@ -621,7 +575,7 @@ static const u_int32_t it_tab[4][256] = w(17), w(2b), w(04), w(7e), w(ba), w(77), w(d6), w(26),\ w(e1), w(69), w(14), w(63), w(55), w(21), w(0c), w(7d), -/* generate the required tables in the desired endian format */ +// generate the required tables in the desired endian format #undef r #define r(p,q,r,s) w0(q) @@ -760,20 +714,9 @@ static const u_int32_t im_tab[4][256] = static int tab_gen = 0; -/** - * The S box - */ -static unsigned char s_box[256]; - -/** - * The inverse S box - */ -static unsigned char inv_s_box[256]; - -/** - * Table of round constants. - */ -static u_int32_t rcon_tab[AES_RC_LENGTH]; +static unsigned char s_box[256]; // the S box +static unsigned char inv_s_box[256]; // the inverse S box +static u_int32_t rcon_tab[AES_RC_LENGTH]; // table of round constants #if defined(ONE_TABLE) static u_int32_t ft_tab[256]; @@ -797,18 +740,17 @@ static u_int32_t im_tab[256]; static u_int32_t im_tab[4][256]; #endif -/* Generate the tables for the dynamic table option */ +// Generate the tables for the dynamic table option #if !defined(FF_TABLES) -/* It will generally be sensible to use tables to compute finite - * field multiplies and inverses but where memory is scarse this - * code might sometimes be better. +// It will generally be sensible to use tables to compute finite +// field multiplies and inverses but where memory is scarse this +// code might sometimes be better. - * return 2 ^ (n - 1) where n is the bit number of the highest bit - * set in x with x in the range 1 < x < 0x00000200. This form is - * used so that locals within FFinv can be bytes rather than words - */ +// return 2 ^ (n - 1) where n is the bit number of the highest bit +// set in x with x in the range 1 < x < 0x00000200. This form is +// used so that locals within FFinv can be bytes rather than words static unsigned char hibit(const u_int32_t x) { unsigned char r = (unsigned char)((x >> 1) | (x >> 2)); @@ -818,7 +760,7 @@ static unsigned char hibit(const u_int32_t x) return (r + 1) >> 1; } -/* return the inverse of the finite field element x */ +// return the inverse of the finite field element x static unsigned char FFinv(const unsigned char x) { unsigned char p1 = x, p2 = 0x1b, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0; @@ -843,7 +785,7 @@ static unsigned char FFinv(const unsigned char x) } } -/* define the finite field multiplies required for Rijndael */ +// define the finite field multiplies required for Rijndael #define FFmul02(x) ((((x) & 0x7f) << 1) ^ ((x) & 0x80 ? 0x1b : 0)) #define FFmul03(x) ((x) ^ FFmul02(x)) @@ -865,7 +807,7 @@ static unsigned char FFinv(const unsigned char x) #endif -/* The forward and inverse affine transformations used in the S-box */ +// The forward and inverse affine transformations used in the S-box #define fwd_affine(x) \ (w = (u_int32_t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(unsigned char)(w^(w>>8))) @@ -880,11 +822,9 @@ static void gen_tabs(void) unsigned char pow[512], log[256]; - /* - * log and power tables for GF(2^8) finite field with - * 0x011b as modular polynomial - the simplest primitive - * root is 0x03, used here to generate the tables - */ + // log and power tables for GF(2^8) finite field with + // 0x011b as modular polynomial - the simplest primitive + // root is 0x03, used here to generate the tables i = 0; w = 1; do @@ -1001,6 +941,39 @@ static void gen_tabs(void) f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1)) #endif +// Subroutine to set the block size (if variable) in bytes, legal +// values being 16, 24 and 32. + +#if defined(AES_BLOCK_SIZE) +#define nc (AES_BLOCK_SIZE / 4) +#else +#define nc (cx->aes_Ncol) + +void aes_set_blk(private_aes_cbc_crypter_t *cx, int n_bytes) +{ +#if !defined(FIXED_TABLES) + if(!tab_gen) { gen_tabs(); tab_gen = 1; } +#endif + + switch(n_bytes) { + case 32: /* bytes */ + case 256: /* bits */ + nc = 8; + break; + case 24: /* bytes */ + case 192: /* bits */ + nc = 6; + break; + case 16: /* bytes */ + case 128: /* bits */ + default: + nc = 4; + break; + } +} + +#endif + // 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 @@ -1009,8 +982,23 @@ static void gen_tabs(void) #define mx(t,f) (*t++ = inv_mcol(*f),f++) #define cp(t,f) *t++ = *f++ +#if AES_BLOCK_SIZE == 16 +#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s) +#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s) +#elif AES_BLOCK_SIZE == 24 +#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \ + cp(d,s); cp(d,s) +#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \ + mx(d,s); mx(d,s) +#elif AES_BLOCK_SIZE == 32 +#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \ + cp(d,s); cp(d,s); cp(d,s); cp(d,s) +#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \ + mx(d,s); mx(d,s); mx(d,s); mx(d,s) +#else + #define cpy(d,s) \ -switch(this->aes_Ncol) \ +switch(nc) \ { case 8: cp(d,s); cp(d,s); \ case 6: cp(d,s); cp(d,s); \ case 4: cp(d,s); cp(d,s); \ @@ -1018,13 +1006,119 @@ switch(this->aes_Ncol) \ } #define mix(d,s) \ -switch(this->aes_Ncol) \ +switch(nc) \ { case 8: mx(d,s); mx(d,s); \ case 6: mx(d,s); mx(d,s); \ case 4: mx(d,s); mx(d,s); \ mx(d,s); mx(d,s); \ } +#endif + +void aes_set_key(private_aes_cbc_crypter_t *cx, const unsigned char in_key[], int n_bytes, const int f) +{ u_int32_t *kf, *kt, rci; + +#if !defined(FIXED_TABLES) + if(!tab_gen) { gen_tabs(); tab_gen = 1; } +#endif + + switch(n_bytes) { + case 32: /* bytes */ + case 256: /* bits */ + cx->aes_Nkey = 8; + break; + case 24: /* bytes */ + case 192: /* bits */ + cx->aes_Nkey = 6; + break; + case 16: /* bytes */ + case 128: /* bits */ + default: + cx->aes_Nkey = 4; + break; + } + + cx->aes_Nrnd = (cx->aes_Nkey > nc ? cx->aes_Nkey : nc) + 6; + + cx->aes_e_key[0] = const_word_in(in_key ); + cx->aes_e_key[1] = const_word_in(in_key + 4); + cx->aes_e_key[2] = const_word_in(in_key + 8); + cx->aes_e_key[3] = const_word_in(in_key + 12); + + kf = cx->aes_e_key; + kt = kf + nc * (cx->aes_Nrnd + 1) - cx->aes_Nkey; + rci = 0; + + switch(cx->aes_Nkey) + { + case 4: do + { kf[4] = kf[0] ^ ls_box(kf[3],3) ^ rcon_tab[rci++]; + kf[5] = kf[1] ^ kf[4]; + kf[6] = kf[2] ^ kf[5]; + kf[7] = kf[3] ^ kf[6]; + kf += 4; + } + while(kf < kt); + break; + + case 6: cx->aes_e_key[4] = const_word_in(in_key + 16); + cx->aes_e_key[5] = const_word_in(in_key + 20); + do + { kf[ 6] = kf[0] ^ ls_box(kf[5],3) ^ rcon_tab[rci++]; + kf[ 7] = kf[1] ^ kf[ 6]; + kf[ 8] = kf[2] ^ kf[ 7]; + kf[ 9] = kf[3] ^ kf[ 8]; + kf[10] = kf[4] ^ kf[ 9]; + kf[11] = kf[5] ^ kf[10]; + kf += 6; + } + while(kf < kt); + break; + + case 8: cx->aes_e_key[4] = const_word_in(in_key + 16); + cx->aes_e_key[5] = const_word_in(in_key + 20); + cx->aes_e_key[6] = const_word_in(in_key + 24); + cx->aes_e_key[7] = const_word_in(in_key + 28); + do + { kf[ 8] = kf[0] ^ ls_box(kf[7],3) ^ rcon_tab[rci++]; + kf[ 9] = kf[1] ^ kf[ 8]; + kf[10] = kf[2] ^ kf[ 9]; + kf[11] = kf[3] ^ kf[10]; + kf[12] = kf[4] ^ ls_box(kf[11],0); + kf[13] = kf[5] ^ kf[12]; + kf[14] = kf[6] ^ kf[13]; + kf[15] = kf[7] ^ kf[14]; + kf += 8; + } + while (kf < kt); + break; + } + + if(!f) + { u_int32_t i; + + kt = cx->aes_d_key + nc * cx->aes_Nrnd; + kf = cx->aes_e_key; + + cpy(kt, kf); kt -= 2 * nc; + + for(i = 1; i < cx->aes_Nrnd; ++i) + { +#if defined(ONE_TABLE) || defined(FOUR_TABLES) +#if !defined(ONE_IM_TABLE) && !defined(FOUR_IM_TABLES) + u_int32_t f2, f4, f8, f9; +#endif + mix(kt, kf); +#else + cpy(kt, kf); +#endif + kt -= 2 * nc; + } + + cpy(kt, kf); + } +} + // y = output word, x = input word, r = row, c = column // for r = 0, 1, 2 and 3 = column accessed for row r @@ -1040,7 +1134,7 @@ switch(this->aes_Ncol) \ // needed for each row (r) of the state // For the fixed block size options, compilers reduce these two -// expressions to fixed variable referethis->aes_Ncoles. For variable block +// expressions to fixed variable references. For variable block // size code conditional clauses will sometimes be returned #define unused 77 // Sunset Strip @@ -1059,27 +1153,27 @@ switch(this->aes_Ncol) \ ( c==0 ? s(x,1) \ : c==1 ? s(x,2) \ : c==2 ? s(x,3) \ - : c==3 ? this->aes_Ncol==4 ? s(x,0) : s(x,4) \ + : c==3 ? nc==4 ? s(x,0) : s(x,4) \ : c==4 ? s(x,5) \ - : c==5 ? this->aes_Ncol==8 ? s(x,6) : s(x,0) \ + : c==5 ? nc==8 ? s(x,6) : s(x,0) \ : c==6 ? s(x,7) \ : s(x,0)) \ : r==2 ? \ - ( c==0 ? this->aes_Ncol==8 ? s(x,3) : s(x,2) \ - : c==1 ? this->aes_Ncol==8 ? s(x,4) : s(x,3) \ - : c==2 ? this->aes_Ncol==4 ? s(x,0) : this->aes_Ncol==8 ? s(x,5) : s(x,4) \ - : c==3 ? this->aes_Ncol==4 ? s(x,1) : this->aes_Ncol==8 ? s(x,6) : s(x,5) \ - : c==4 ? this->aes_Ncol==8 ? s(x,7) : s(x,0) \ - : c==5 ? this->aes_Ncol==8 ? s(x,0) : s(x,1) \ + ( c==0 ? nc==8 ? s(x,3) : s(x,2) \ + : c==1 ? nc==8 ? s(x,4) : s(x,3) \ + : c==2 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \ + : c==3 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \ + : c==4 ? nc==8 ? s(x,7) : s(x,0) \ + : c==5 ? nc==8 ? s(x,0) : s(x,1) \ : c==6 ? s(x,1) \ : s(x,2)) \ : \ - ( c==0 ? this->aes_Ncol==8 ? s(x,4) : s(x,3) \ - : c==1 ? this->aes_Ncol==4 ? s(x,0) : this->aes_Ncol==8 ? s(x,5) : s(x,4) \ - : c==2 ? this->aes_Ncol==4 ? s(x,1) : this->aes_Ncol==8 ? s(x,6) : s(x,5) \ - : c==3 ? this->aes_Ncol==4 ? s(x,2) : this->aes_Ncol==8 ? s(x,7) : s(x,0) \ - : c==4 ? this->aes_Ncol==8 ? s(x,0) : s(x,1) \ - : c==5 ? this->aes_Ncol==8 ? s(x,1) : s(x,2) \ + ( c==0 ? nc==8 ? s(x,4) : s(x,3) \ + : c==1 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \ + : c==2 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \ + : c==3 ? nc==4 ? s(x,2) : nc==8 ? s(x,7) : s(x,0) \ + : c==4 ? nc==8 ? s(x,0) : s(x,1) \ + : c==5 ? nc==8 ? s(x,1) : s(x,2) \ : c==6 ? s(x,2) \ : s(x,3))) @@ -1094,7 +1188,7 @@ switch(this->aes_Ncol) \ : c==6 ? s(x,6) \ : s(x,7)) \ : r==1 ? \ - ( c==0 ? this->aes_Ncol==4 ? s(x,3) : this->aes_Ncol==8 ? s(x,7) : s(x,5) \ + ( c==0 ? nc==4 ? s(x,3) : nc==8 ? s(x,7) : s(x,5) \ : c==1 ? s(x,0) \ : c==2 ? s(x,1) \ : c==3 ? s(x,2) \ @@ -1103,21 +1197,21 @@ switch(this->aes_Ncol) \ : c==6 ? s(x,5) \ : s(x,6)) \ : r==2 ? \ - ( c==0 ? this->aes_Ncol==4 ? s(x,2) : this->aes_Ncol==8 ? s(x,5) : s(x,4) \ - : c==1 ? this->aes_Ncol==4 ? s(x,3) : this->aes_Ncol==8 ? s(x,6) : s(x,5) \ - : c==2 ? this->aes_Ncol==8 ? s(x,7) : s(x,0) \ - : c==3 ? this->aes_Ncol==8 ? s(x,0) : s(x,1) \ - : c==4 ? this->aes_Ncol==8 ? s(x,1) : s(x,2) \ - : c==5 ? this->aes_Ncol==8 ? s(x,2) : s(x,3) \ + ( c==0 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \ + : c==1 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \ + : c==2 ? nc==8 ? s(x,7) : s(x,0) \ + : c==3 ? nc==8 ? s(x,0) : s(x,1) \ + : c==4 ? nc==8 ? s(x,1) : s(x,2) \ + : c==5 ? nc==8 ? s(x,2) : s(x,3) \ : c==6 ? s(x,3) \ : s(x,4)) \ : \ - ( c==0 ? this->aes_Ncol==4 ? s(x,1) : this->aes_Ncol==8 ? s(x,4) : s(x,3) \ - : c==1 ? this->aes_Ncol==4 ? s(x,2) : this->aes_Ncol==8 ? s(x,5) : s(x,4) \ - : c==2 ? this->aes_Ncol==4 ? s(x,3) : this->aes_Ncol==8 ? s(x,6) : s(x,5) \ - : c==3 ? this->aes_Ncol==8 ? s(x,7) : s(x,0) \ - : c==4 ? this->aes_Ncol==8 ? s(x,0) : s(x,1) \ - : c==5 ? this->aes_Ncol==8 ? s(x,1) : s(x,2) \ + ( c==0 ? nc==4 ? s(x,1) : nc==8 ? s(x,4) : s(x,3) \ + : c==1 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \ + : c==2 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \ + : c==3 ? nc==8 ? s(x,7) : s(x,0) \ + : c==4 ? nc==8 ? s(x,0) : s(x,1) \ + : c==5 ? nc==8 ? s(x,1) : s(x,2) \ : c==6 ? s(x,2) \ : s(x,3))) @@ -1214,7 +1308,7 @@ switch(this->aes_Ncol) \ #else #define state_in(y,x,k) \ -switch(this->aes_Ncol) \ +switch(nc) \ { case 8: si(y,x,k,7); si(y,x,k,6); \ case 6: si(y,x,k,5); si(y,x,k,4); \ case 4: si(y,x,k,3); si(y,x,k,2); \ @@ -1222,7 +1316,7 @@ switch(this->aes_Ncol) \ } #define state_out(y,x) \ -switch(this->aes_Ncol) \ +switch(nc) \ { case 8: so(y,x,7); so(y,x,6); \ case 6: so(y,x,5); so(y,x,4); \ case 4: so(y,x,3); so(y,x,2); \ @@ -1232,7 +1326,7 @@ switch(this->aes_Ncol) \ #if defined(FAST_VARIABLE) #define round(rm,y,x,k) \ -switch(this->aes_Ncol) \ +switch(nc) \ { case 8: rm(y,x,k,7); rm(y,x,k,6); \ rm(y,x,k,5); rm(y,x,k,4); \ rm(y,x,k,3); rm(y,x,k,2); \ @@ -1249,7 +1343,7 @@ switch(this->aes_Ncol) \ #else #define round(rm,y,x,k) \ -switch(this->aes_Ncol) \ +switch(nc) \ { case 8: rm(y,x,k,7); rm(y,x,k,6); \ case 6: rm(y,x,k,5); rm(y,x,k,4); \ case 4: rm(y,x,k,3); rm(y,x,k,2); \ @@ -1261,159 +1355,127 @@ switch(this->aes_Ncol) \ #endif #endif - -/** - * Implementation of private_aes_cbc_crypter_t.encrypt_block. - */ -static status_t encrypt_block (private_aes_cbc_crypter_t *this, u_int8_t *data, u_int8_t *encrypted) -{ - u_int32_t locals(b0, b1); - const u_int32_t *kp = this->aes_e_key; +void aes_encrypt(const private_aes_cbc_crypter_t *cx, const unsigned char in_blk[], unsigned char out_blk[]) +{ u_int32_t locals(b0, b1); + const u_int32_t *kp = cx->aes_e_key; #if !defined(ONE_TABLE) && !defined(FOUR_TABLES) u_int32_t f2; #endif - /* - * Allocate memory for the encrypted value - */ -// encrypted->ptr = allocator_alloc(this->blocksize); -// if (encrypted->ptr == NULL) -// { -// return OUT_OF_RES; -// } -// encrypted->len = this->blocksize; - - - state_in(b0, data, kp); kp += this->aes_Ncol; + state_in(b0, in_blk, kp); kp += nc; #if defined(UNROLL) - switch(this->aes_Nrnd) + switch(cx->aes_Nrnd) { case 14: round(fwd_rnd, b1, b0, kp ); - round(fwd_rnd, b0, b1, kp + this->aes_Ncol ); kp += 2 * this->aes_Ncol; + round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc; case 12: round(fwd_rnd, b1, b0, kp ); - round(fwd_rnd, b0, b1, kp + this->aes_Ncol ); kp += 2 * this->aes_Ncol; + round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc; case 10: round(fwd_rnd, b1, b0, kp ); - round(fwd_rnd, b0, b1, kp + this->aes_Ncol); - round(fwd_rnd, b1, b0, kp + 2 * this->aes_Ncol); - round(fwd_rnd, b0, b1, kp + 3 * this->aes_Ncol); - round(fwd_rnd, b1, b0, kp + 4 * this->aes_Ncol); - round(fwd_rnd, b0, b1, kp + 5 * this->aes_Ncol); - round(fwd_rnd, b1, b0, kp + 6 * this->aes_Ncol); - round(fwd_rnd, b0, b1, kp + 7 * this->aes_Ncol); - round(fwd_rnd, b1, b0, kp + 8 * this->aes_Ncol); - round(fwd_lrnd, b0, b1, kp + 9 * this->aes_Ncol); + round(fwd_rnd, b0, b1, kp + nc); + round(fwd_rnd, b1, b0, kp + 2 * nc); + round(fwd_rnd, b0, b1, kp + 3 * nc); + round(fwd_rnd, b1, b0, kp + 4 * nc); + round(fwd_rnd, b0, b1, kp + 5 * nc); + round(fwd_rnd, b1, b0, kp + 6 * nc); + round(fwd_rnd, b0, b1, kp + 7 * nc); + round(fwd_rnd, b1, b0, kp + 8 * nc); + round(fwd_lrnd, b0, b1, kp + 9 * nc); } #elif defined(PARTIAL_UNROLL) { u_int32_t rnd; - for(rnd = 0; rnd < (this->aes_Nrnd >> 1) - 1; ++rnd) + for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd) { round(fwd_rnd, b1, b0, kp); - round(fwd_rnd, b0, b1, kp + this->aes_Ncol); kp += 2 * this->aes_Ncol; + round(fwd_rnd, b0, b1, kp + nc); kp += 2 * nc; } round(fwd_rnd, b1, b0, kp); - round(fwd_lrnd, b0, b1, kp + this->aes_Ncol); + round(fwd_lrnd, b0, b1, kp + nc); } #else { u_int32_t rnd; - for(rnd = 0; rnd < this->aes_Nrnd - 1; ++rnd) + for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd) { round(fwd_rnd, b1, b0, kp); - l_copy(b0, b1); kp += this->aes_Ncol; + l_copy(b0, b1); kp += nc; } round(fwd_lrnd, b0, b1, kp); } #endif - state_out(encrypted, b0); - - return SUCCESS; + state_out(out_blk, b0); } -/** - * Implementation of private_aes_cbc_crypter_t.decrypt_block. - */ -static status_t decrypt_block (private_aes_cbc_crypter_t *this, u_int8_t *data, u_int8_t *decrypted) -{ - u_int32_t locals(b0, b1); - const u_int32_t *kp = this->aes_d_key; +void aes_decrypt(const private_aes_cbc_crypter_t *cx, const unsigned char in_blk[], unsigned char out_blk[]) +{ u_int32_t locals(b0, b1); + const u_int32_t *kp = cx->aes_d_key; #if !defined(ONE_TABLE) && !defined(FOUR_TABLES) u_int32_t f2, f4, f8, f9; #endif - /* - * Allocate memory for the encrypted value - */ -// decrypted->ptr = allocator_alloc(this->blocksize); -// if (decrypted->ptr == NULL) -// { -// return OUT_OF_RES; -// } -// decrypted->len = this->blocksize; - - - state_in(b0, data, kp); kp += this->aes_Ncol; + state_in(b0, in_blk, kp); kp += nc; #if defined(UNROLL) - switch(this->aes_Nrnd) + switch(cx->aes_Nrnd) { case 14: round(inv_rnd, b1, b0, kp ); - round(inv_rnd, b0, b1, kp + this->aes_Ncol ); kp += 2 * this->aes_Ncol; + round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc; case 12: round(inv_rnd, b1, b0, kp ); - round(inv_rnd, b0, b1, kp + this->aes_Ncol ); kp += 2 * this->aes_Ncol; + round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc; case 10: round(inv_rnd, b1, b0, kp ); - round(inv_rnd, b0, b1, kp + this->aes_Ncol); - round(inv_rnd, b1, b0, kp + 2 * this->aes_Ncol); - round(inv_rnd, b0, b1, kp + 3 * this->aes_Ncol); - round(inv_rnd, b1, b0, kp + 4 * this->aes_Ncol); - round(inv_rnd, b0, b1, kp + 5 * this->aes_Ncol); - round(inv_rnd, b1, b0, kp + 6 * this->aes_Ncol); - round(inv_rnd, b0, b1, kp + 7 * this->aes_Ncol); - round(inv_rnd, b1, b0, kp + 8 * this->aes_Ncol); - round(inv_lrnd, b0, b1, kp + 9 * this->aes_Ncol); + round(inv_rnd, b0, b1, kp + nc); + round(inv_rnd, b1, b0, kp + 2 * nc); + round(inv_rnd, b0, b1, kp + 3 * nc); + round(inv_rnd, b1, b0, kp + 4 * nc); + round(inv_rnd, b0, b1, kp + 5 * nc); + round(inv_rnd, b1, b0, kp + 6 * nc); + round(inv_rnd, b0, b1, kp + 7 * nc); + round(inv_rnd, b1, b0, kp + 8 * nc); + round(inv_lrnd, b0, b1, kp + 9 * nc); } #elif defined(PARTIAL_UNROLL) { u_int32_t rnd; - for(rnd = 0; rnd < (this->aes_Nrnd >> 1) - 1; ++rnd) + for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd) { round(inv_rnd, b1, b0, kp); - round(inv_rnd, b0, b1, kp + this->aes_Ncol); kp += 2 * this->aes_Ncol; + round(inv_rnd, b0, b1, kp + nc); kp += 2 * nc; } round(inv_rnd, b1, b0, kp); - round(inv_lrnd, b0, b1, kp + this->aes_Ncol); + round(inv_lrnd, b0, b1, kp + nc); } #else { u_int32_t rnd; - for(rnd = 0; rnd < this->aes_Nrnd - 1; ++rnd) + for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd) { round(inv_rnd, b1, b0, kp); - l_copy(b0, b1); kp += this->aes_Ncol; + l_copy(b0, b1); kp += nc; } round(inv_lrnd, b0, b1, kp); } #endif - state_out(decrypted, b0); - - - return SUCCESS; + state_out(out_blk, b0); } + +/* *************************/ + + /** * Implementation of crypter_t.decrypt. */ @@ -1444,7 +1506,7 @@ static status_t decrypt (private_aes_cbc_crypter_t *this, chunk_t data, chunk_t in+=pos; out+=pos; while(pos>=0) { - this->decrypt_block(this,in,out); + aes_decrypt(this,in,out); if (pos==0) iv_i=(const u_int32_t*) (iv.ptr); else @@ -1499,7 +1561,7 @@ static status_t encrypt (private_aes_cbc_crypter_t *this, chunk_t data, chunk_t *((u_int32_t *)(&out[ 4])) = iv_i[1]^*((const u_int32_t *)(&in[ 4])); *((u_int32_t *)(&out[ 8])) = iv_i[2]^*((const u_int32_t *)(&in[ 8])); *((u_int32_t *)(&out[12])) = iv_i[3]^*((const u_int32_t *)(&in[12])); - this->encrypt_block(this,out,out); + aes_encrypt(this,out,out); in+=16; out+=16; pos+=16; @@ -1520,94 +1582,7 @@ static size_t get_block_size (private_aes_cbc_crypter_t *this) */ static status_t set_key (private_aes_cbc_crypter_t *this, chunk_t key) { - u_int32_t *kf, *kt, rci, f = 0; - - if (key.len != this->blocksize) - { - /* key length not as expected */ - return INVALID_ARG; - } - - this->aes_Nrnd = (this->aes_Nkey > this->aes_Ncol ? this->aes_Nkey : this->aes_Ncol) + 6; - - this->aes_e_key[0] = const_word_in(key.ptr); - this->aes_e_key[1] = const_word_in(key.ptr + 4); - this->aes_e_key[2] = const_word_in(key.ptr + 8); - this->aes_e_key[3] = const_word_in(key.ptr + 12); - - kf = this->aes_e_key; - kt = kf + this->aes_Ncol * (this->aes_Nrnd + 1) - this->aes_Nkey; - rci = 0; - - switch(this->aes_Nkey) - { - case 4: do - { kf[4] = kf[0] ^ ls_box(kf[3],3) ^ rcon_tab[rci++]; - kf[5] = kf[1] ^ kf[4]; - kf[6] = kf[2] ^ kf[5]; - kf[7] = kf[3] ^ kf[6]; - kf += 4; - } - while(kf < kt); - break; - - case 6: this->aes_e_key[4] = const_word_in(key.ptr + 16); - this->aes_e_key[5] = const_word_in(key.ptr + 20); - do - { kf[ 6] = kf[0] ^ ls_box(kf[5],3) ^ rcon_tab[rci++]; - kf[ 7] = kf[1] ^ kf[ 6]; - kf[ 8] = kf[2] ^ kf[ 7]; - kf[ 9] = kf[3] ^ kf[ 8]; - kf[10] = kf[4] ^ kf[ 9]; - kf[11] = kf[5] ^ kf[10]; - kf += 6; - } - while(kf < kt); - break; - - case 8: this->aes_e_key[4] = const_word_in(key.ptr + 16); - this->aes_e_key[5] = const_word_in(key.ptr + 20); - this->aes_e_key[6] = const_word_in(key.ptr + 24); - this->aes_e_key[7] = const_word_in(key.ptr + 28); - do - { kf[ 8] = kf[0] ^ ls_box(kf[7],3) ^ rcon_tab[rci++]; - kf[ 9] = kf[1] ^ kf[ 8]; - kf[10] = kf[2] ^ kf[ 9]; - kf[11] = kf[3] ^ kf[10]; - kf[12] = kf[4] ^ ls_box(kf[11],0); - kf[13] = kf[5] ^ kf[12]; - kf[14] = kf[6] ^ kf[13]; - kf[15] = kf[7] ^ kf[14]; - kf += 8; - } - while (kf < kt); - break; - } - - if(!f) - { u_int32_t i; - - kt = this->aes_d_key + this->aes_Ncol * this->aes_Nrnd; - kf = this->aes_e_key; - - cpy(kt, kf); kt -= 2 * this->aes_Ncol; - - for(i = 1; i < this->aes_Nrnd; ++i) - { -#if defined(ONE_TABLE) || defined(FOUR_TABLES) -#if !defined(ONE_IM_TABLE) && !defined(FOUR_IM_TABLES) - u_int32_t f2, f4, f8, f9; -#endif - mix(kt, kf); -#else - cpy(kt, kf); -#endif - kt -= 2 * this->aes_Ncol; - } - - cpy(kt, kf); - } - + aes_set_key(this, key.ptr, key.len,0); return SUCCESS; } @@ -1659,10 +1634,6 @@ aes_cbc_crypter_t *aes_cbc_crypter_create(size_t blocksize) /* public functions */ this->public.destroy = (status_t (*) (aes_cbc_crypter_t *)) destroy; - /* private functions */ - this->encrypt_block = encrypt_block; - this->decrypt_block = decrypt_block; - return &(this->public); } |