📄 aes.c
字号:
{ unsigned char p1 = x, p2 = 0x1b, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0; if(x < 2) return x; for(;;) { if(!n1) return v1; while(n2 >= n1) { n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2); } if(!n2) return v2; while(n1 >= n2) { n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1); } }}// define the finite field multiplies required for Rijndael#define FFmul02(x) ((((x) & 0x7f) << 1) ^ ((x) & 0x80 ? 0x1b : 0))#define FFmul03(x) ((x) ^ FFmul02(x))#define FFmul09(x) ((x) ^ FFmul02(FFmul02(FFmul02(x))))#define FFmul0b(x) ((x) ^ FFmul02((x) ^ FFmul02(FFmul02(x))))#define FFmul0d(x) ((x) ^ FFmul02(FFmul02((x) ^ FFmul02(x))))#define FFmul0e(x) FFmul02((x) ^ FFmul02((x) ^ FFmul02(x)))#else#define FFinv(x) ((x) ? pow[255 - log[x]]: 0)#define FFmul02(x) (x ? pow[log[x] + 0x19] : 0)#define FFmul03(x) (x ? pow[log[x] + 0x01] : 0)#define FFmul09(x) (x ? pow[log[x] + 0xc7] : 0)#define FFmul0b(x) (x ? pow[log[x] + 0x68] : 0)#define FFmul0d(x) (x ? pow[log[x] + 0xee] : 0)#define FFmul0e(x) (x ? pow[log[x] + 0xdf] : 0)#endif// 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)))#define inv_affine(x) \ (w = (u_int32_t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(unsigned char)(w^(w>>8)))static void gen_tabs(void){ u_int32_t i, w;#if defined(FF_TABLES) 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 i = 0; w = 1; do { pow[i] = (unsigned char)w; pow[i + 255] = (unsigned char)w; log[w] = (unsigned char)i++; w ^= (w << 1) ^ (w & ff_hi ? ff_poly : 0); } while (w != 1);#endif for(i = 0, w = 1; i < AES_RC_LENGTH; ++i) { rcon_tab[i] = bytes2word(w, 0, 0, 0); w = (w << 1) ^ (w & ff_hi ? ff_poly : 0); } for(i = 0; i < 256; ++i) { unsigned char b; s_box[i] = b = fwd_affine(FFinv((unsigned char)i)); w = bytes2word(b, 0, 0, 0);#if defined(ONE_LR_TABLE) fl_tab[i] = w;#elif defined(FOUR_LR_TABLES) fl_tab[0][i] = w; fl_tab[1][i] = upr(w,1); fl_tab[2][i] = upr(w,2); fl_tab[3][i] = upr(w,3);#endif w = bytes2word(FFmul02(b), b, b, FFmul03(b));#if defined(ONE_TABLE) ft_tab[i] = w;#elif defined(FOUR_TABLES) ft_tab[0][i] = w; ft_tab[1][i] = upr(w,1); ft_tab[2][i] = upr(w,2); ft_tab[3][i] = upr(w,3);#endif inv_s_box[i] = b = FFinv(inv_affine((unsigned char)i)); w = bytes2word(b, 0, 0, 0);#if defined(ONE_LR_TABLE) il_tab[i] = w;#elif defined(FOUR_LR_TABLES) il_tab[0][i] = w; il_tab[1][i] = upr(w,1); il_tab[2][i] = upr(w,2); il_tab[3][i] = upr(w,3);#endif w = bytes2word(FFmul0e(b), FFmul09(b), FFmul0d(b), FFmul0b(b));#if defined(ONE_TABLE) it_tab[i] = w;#elif defined(FOUR_TABLES) it_tab[0][i] = w; it_tab[1][i] = upr(w,1); it_tab[2][i] = upr(w,2); it_tab[3][i] = upr(w,3);#endif#if defined(ONE_IM_TABLE) im_tab[b] = w;#elif defined(FOUR_IM_TABLES) im_tab[0][b] = w; im_tab[1][b] = upr(w,1); im_tab[2][b] = upr(w,2); im_tab[3][b] = upr(w,3);#endif }}#endif#define no_table(x,box,vf,rf,c) bytes2word( \ box[bval(vf(x,0,c),rf(0,c))], \ box[bval(vf(x,1,c),rf(1,c))], \ box[bval(vf(x,2,c),rf(2,c))], \ box[bval(vf(x,3,c),rf(3,c))])#define one_table(x,op,tab,vf,rf,c) \ ( tab[bval(vf(x,0,c),rf(0,c))] \ ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \ ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \ ^ op(tab[bval(vf(x,3,c),rf(3,c))],3))#define four_tables(x,tab,vf,rf,c) \ ( tab[0][bval(vf(x,0,c),rf(0,c))] \ ^ tab[1][bval(vf(x,1,c),rf(1,c))] \ ^ tab[2][bval(vf(x,2,c),rf(2,c))] \ ^ tab[3][bval(vf(x,3,c),rf(3,c))])#define vf1(x,r,c) (x)#define rf1(r,c) (r)#define rf2(r,c) ((r-c)&3)#if defined(FOUR_LR_TABLES)#define ls_box(x,c) four_tables(x,fl_tab,vf1,rf2,c)#elif defined(ONE_LR_TABLE)#define ls_box(x,c) one_table(x,upr,fl_tab,vf1,rf2,c)#else#define ls_box(x,c) no_table(x,s_box,vf1,rf2,c)#endif#if defined(FOUR_IM_TABLES)#define inv_mcol(x) four_tables(x,im_tab,vf1,rf1,0)#elif defined(ONE_IM_TABLE)#define inv_mcol(x) one_table(x,upr,im_tab,vf1,rf1,0)#else#define inv_mcol(x) \ (f9 = (x),f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \ 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(aes_context *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// to Nk values of 4, 6 and 8 respectively.#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(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); \ cp(d,s); cp(d,s); \}#define mix(d,s) \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); \}#endifvoid aes_set_key(aes_context *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); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -