#include "aesopt.h"
#if !defined(BLOCK_SIZE) && defined(SET_BLOCK_LENGTH)
aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1])
{
#if !defined(FIXED_TABLES)
if(!tab_init) gen_tabs();
#endif
if((blen & 3) || blen < 16 || blen > 32)
{
cx->n_blk = 0; return aes_bad;
}
cx->n_blk = blen;
return aes_good;
}
#endif
#define mx(t,f) (*t++ = inv_mcol(*f),f++)
#define cp(t,f) *t++ = *f++
#if 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 BLOCK_SIZE == 20
#define cpy(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)
#elif 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 BLOCK_SIZE == 28
#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)
#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)
#elif 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(nc) \
{ case 8: cp(d,s); \
case 7: cp(d,s); \
case 6: cp(d,s); \
case 5: cp(d,s); \
case 4: cp(d,s); cp(d,s); \
cp(d,s); cp(d,s); \
}
#define mix(d,s) \
switch(nc) \
{ case 8: mx(d,s); \
case 7: mx(d,s); \
case 6: mx(d,s); \
case 5: mx(d,s); \
case 4: mx(d,s); mx(d,s); \
mx(d,s); mx(d,s); \
}
#endif
#define ks4(i) \
{ p ^= ls_box(s,3) ^ rcon_tab[i]; q ^= p; r ^= q; s ^= r; \
cx->k_sch[4*(i)+4] = p; \
cx->k_sch[4*(i)+5] = q; \
cx->k_sch[4*(i)+6] = r; \
cx->k_sch[4*(i)+7] = s; \
}
#define ks5(i) \
{ p ^= ls_box(t,3) ^ rcon_tab[i]; q ^= p; \
r ^= q; s ^= r; t ^= s; \
cx->k_sch[5*(i)+ 5] = p; \
cx->k_sch[5*(i)+ 6] = q; \
cx->k_sch[5*(i)+ 7] = r; \
cx->k_sch[5*(i)+ 8] = s; \
cx->k_sch[5*(i)+ 9] = t; \
}
#define ks6(i) \
{ p ^= ls_box(u,3) ^ rcon_tab[i]; q ^= p; \
r ^= q; s ^= r; t ^= s; u ^= t; \
cx->k_sch[6*(i)+ 6] = p; \
cx->k_sch[6*(i)+ 7] = q; \
cx->k_sch[6*(i)+ 8] = r; \
cx->k_sch[6*(i)+ 9] = s; \
cx->k_sch[6*(i)+10] = t; \
cx->k_sch[6*(i)+11] = u; \
}
#define ks7(i) \
{ p ^= ls_box(v,3) ^ rcon_tab[i]; q ^= p; r ^= q; s ^= r; \
t ^= ls_box(s,0); u ^= t; v ^= u; \
cx->k_sch[7*(i)+ 7] = p; \
cx->k_sch[7*(i)+ 8] = q; \
cx->k_sch[7*(i)+ 9] = r; \
cx->k_sch[7*(i)+10] = s; \
cx->k_sch[7*(i)+11] = t; \
cx->k_sch[7*(i)+12] = u; \
cx->k_sch[7*(i)+13] = v; \
}
#define ks8(i) \
{ p ^= ls_box(w,3) ^ rcon_tab[i]; q ^= p; r ^= q; s ^= r; \
t ^= ls_box(s,0); u ^= t; v ^= u; w ^= v; \
cx->k_sch[8*(i)+ 8] = p; \
cx->k_sch[8*(i)+ 9] = q; \
cx->k_sch[8*(i)+10] = r; \
cx->k_sch[8*(i)+11] = s; \
cx->k_sch[8*(i)+12] = t; \
cx->k_sch[8*(i)+13] = u; \
cx->k_sch[8*(i)+14] = v; \
cx->k_sch[8*(i)+15] = w; \
}
#if defined(ENCRYPTION_KEY_SCHEDULE)
aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1])
{ uint32_t i,p,q,r,s,t,u,v,w;
#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 & ~3) | 1;
cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
cx->k_sch[0] = p = word_in(in_key );
cx->k_sch[1] = q = word_in(in_key + 4);
cx->k_sch[2] = r = word_in(in_key + 8);
cx->k_sch[3] = s = word_in(in_key + 12);
#if BLOCK_SIZE == 16 && defined(UNROLL)
switch(klen >> 2)
{
case 4: ks4(0); ks4(1); ks4(2); ks4(3);
ks4(4); ks4(5); ks4(6); ks4(7);
ks4(8); ks4(9);
cx->n_rnd = 10; break;
case 5: cx->k_sch[4] = t = word_in(in_key + 16);
ks5(0); ks5(1); ks5(2); ks5(3);
ks5(4); ks5(5); ks5(6); ks5(7);
ks5(8);
cx->n_rnd = 11; break;
case 6: cx->k_sch[4] = t = word_in(in_key + 16);
cx->k_sch[5] = u = word_in(in_key + 20);
ks6(0); ks6(1); ks6(2); ks6(3);
ks6(4); ks6(5); ks6(6); ks6(7);
cx->n_rnd = 12; break;
case 7: cx->k_sch[4] = t = word_in(in_key + 16);
cx->k_sch[5] = u = word_in(in_key + 20);
cx->k_sch[6] = v = word_in(in_key + 24);
ks7(0); ks7(1); ks7(2); ks7(3);
ks7(4); ks7(5); ks7(6);
cx->n_rnd = 13; break;
case 8: cx->k_sch[4] = t = word_in(in_key + 16);
cx->k_sch[5] = u = word_in(in_key + 20);
cx->k_sch[6] = v = word_in(in_key + 24);
cx->k_sch[7] = w = word_in(in_key + 28);
ks8(0); ks8(1); ks8(2); ks8(3);
ks8(4); ks8(5); ks8(6);
cx->n_rnd = 14; break;
default:cx->n_rnd = 0; return aes_bad;
}
#else
cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
{
uint32_t l = (nc * (cx->n_rnd + 1) - 1) / (klen >> 2);
switch(klen >> 2)
{
case 4: for(i = 0; i < l; ++i)
ks4(i);
break;
case 5: cx->k_sch[4] = t = word_in(in_key + 16);
for(i = 0; i < l; ++i)
ks5(i);
break;
case 6: cx->k_sch[4] = t = word_in(in_key + 16);
cx->k_sch[5] = u = word_in(in_key + 20);
for(i = 0; i < l; ++i)
ks6(i);
break;
case 7: cx->k_sch[4] = t = word_in(in_key + 16);
cx->k_sch[5] = u = word_in(in_key + 20);
cx->k_sch[6] = v = word_in(in_key + 24);
for(i = 0; i < l; ++i)
ks7(i);
break;
case 8: cx->k_sch[4] = t = word_in(in_key + 16);
cx->k_sch[5] = u = word_in(in_key + 20);
cx->k_sch[6] = v = word_in(in_key + 24);
cx->k_sch[7] = w = word_in(in_key + 28);
for(i = 0; i < l; ++i)
ks8(i);
break;
}
}
#endif
return aes_good;
}
#endif
#if defined(DECRYPTION_KEY_SCHEDULE)
aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1])
{ uint32_t i,p,q,r,s,t,u,v,w;
dec_imvars
#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 & ~3) | 2;
cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
cx->k_sch[0] = p = word_in(in_key );
cx->k_sch[1] = q = word_in(in_key + 4);
cx->k_sch[2] = r = word_in(in_key + 8);
cx->k_sch[3] = s = word_in(in_key + 12);
#if BLOCK_SIZE == 16 && defined(UNROLL)
switch(klen >> 2)
{
case 4: ks4(0); ks4(1); ks4(2); ks4(3);
ks4(4); ks4(5); ks4(6); ks4(7);
ks4(8); ks4(9);
cx->n_rnd = 10; break;
case 5: cx->k_sch[4] = t = word_in(in_key + 16);
ks5(0); ks5(1); ks5(2); ks5(3);
ks5(4); ks5(5); ks5(6); ks5(7);
ks5(8);
cx->n_rnd = 11; break;
case 6: cx->k_sch[4] = t = word_in(in_key + 16);
cx->k_sch[5] = u = word_in(in_key + 20);
ks6(0); ks6(1); ks6(2); ks6(3);
ks6(4); ks6(5); ks6(6); ks6(7);
cx->n_rnd = 12; break;
case 7: cx->k_sch[4] = t = word_in(in_key + 16);
cx->k_sch[5] = u = word_in(in_key + 20);
cx->k_sch[6] = v = word_in(in_key + 24);
ks7(0); ks7(1); ks7(2); ks7(3);
ks7(4); ks7(5); ks7(6);
cx->n_rnd = 13; break;
case 8: cx->k_sch[4] = t = word_in(in_key + 16);
cx->k_sch[5] = u = word_in(in_key + 20);
cx->k_sch[6] = v = word_in(in_key + 24);
cx->k_sch[7] = w = word_in(in_key + 28);
ks8(0); ks8(1); ks8(2); ks8(3);
ks8(4); ks8(5); ks8(6);
cx->n_rnd = 14; break;
default:cx->n_rnd = 0; return aes_bad;
}
#else
cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
{
uint32_t l = (nc * (cx->n_rnd + 1) - 1) / (klen >> 2);
switch(klen >> 2)
{
case 4: for(i = 0; i < l; ++i)
ks4(i);
break;
case 5: cx->k_sch[4] = t = word_in(in_key + 16);
for(i = 0; i < l; ++i)
ks5(i);
break;
case 6: cx->k_sch[4] = t = word_in(in_key + 16);
cx->k_sch[5] = u = word_in(in_key + 20);
for(i = 0; i < l; ++i)
ks6(i);
break;
case 7: cx->k_sch[4] = t = word_in(in_key + 16);
cx->k_sch[5] = u = word_in(in_key + 20);
cx->k_sch[6] = v = word_in(in_key + 24);
for(i = 0; i < l; ++i)
ks7(i);
break;
case 8: cx->k_sch[4] = t = word_in(in_key + 16);
cx->k_sch[5] = u = word_in(in_key + 20);
cx->k_sch[6] = v = word_in(in_key + 24);
cx->k_sch[7] = w = word_in(in_key + 28);
for(i = 0; i < l; ++i)
ks8(i);
break;
}
}
#endif
#if (DEC_ROUND != NO_TABLES)
for(i = nc; i < nc * cx->n_rnd; ++i)
cx->k_sch[i] = inv_mcol(cx->k_sch[i]);
#endif
return aes_good;
}
#endif