-: 0:Source:aescrypt.c -: 0:Graph:/var/tsitkova/Sources/v10/trunk/src/lib/crypto/builtin/aes/aescrypt.so.gcno -: 0:Data:/var/tsitkova/Sources/v10/trunk/src/lib/crypto/builtin/aes/aescrypt.so.gcda -: 0:Runs:1630 -: 0:Programs:1 -: 1:/* -: 2: * Copyright (c) 2001, Dr Brian Gladman , Worcester, UK. -: 3: * All rights reserved. -: 4: * -: 5: * LICENSE TERMS -: 6: * -: 7: * The free distribution and use of this software in both source and binary -: 8: * form is allowed (with or without changes) provided that: -: 9: * -: 10: * 1. distributions of this source code include the above copyright -: 11: * notice, this list of conditions and the following disclaimer; -: 12: * -: 13: * 2. distributions in binary form include the above copyright -: 14: * notice, this list of conditions and the following disclaimer -: 15: * in the documentation and/or other associated materials; -: 16: * -: 17: * 3. the copyright holder's name is not used to endorse products -: 18: * built using this software without specific written permission. -: 19: * -: 20: * DISCLAIMER -: 21: * -: 22: * This software is provided 'as is' with no explcit or implied warranties -: 23: * in respect of any properties, including, but not limited to, correctness -: 24: * and fitness for purpose. -: 25: */ -: 26: -: 27:/* -: 28: * Issue Date: 21/01/2002 -: 29: * -: 30: * This file contains the code for implementing encryption and decryption -: 31: * for AES (Rijndael) for block and key sizes of 16, 24 and 32 bytes. It -: 32: * can optionally be replaced by code written in assembler using NASM. -: 33:*/ -: 34: -: 35:#include "aesopt.h" -: 36: -: 37:#if defined(BLOCK_SIZE) && (BLOCK_SIZE & 7) -: 38:#error An illegal block size has been specified. -: 39:#endif -: 40: -: 41:#define unused 77 /* Sunset Strip */ -: 42: -: 43:#define si(y,x,k,c) s(y,c) = word_in(x + 4 * c) ^ k[c] -: 44:#define so(y,x,c) word_out(y + 4 * c, s(x,c)) -: 45: -: 46:#if BLOCK_SIZE == 16 -: 47: -: 48:#if defined(ARRAYS) -: 49:#define locals(y,x) x[4],y[4] -: 50:#else -: 51:#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3 -: 52: /* -: 53: the following defines prevent the compiler requiring the declaration -: 54: of generated but unused variables in the fwd_var and inv_var macros -: 55: */ -: 56:#define b04 unused -: 57:#define b05 unused -: 58:#define b06 unused -: 59:#define b07 unused -: 60:#define b14 unused -: 61:#define b15 unused -: 62:#define b16 unused -: 63:#define b17 unused -: 64:#endif -: 65:#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \ -: 66: s(y,2) = s(x,2); s(y,3) = s(x,3); -: 67:#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3) -: 68:#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3) -: 69:#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3) -: 70: -: 71:#elif BLOCK_SIZE == 24 -: 72: -: 73:#if defined(ARRAYS) -: 74:#define locals(y,x) x[6],y[6] -: 75:#else -: 76:#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5, \ -: 77: y##0,y##1,y##2,y##3,y##4,y##5 -: 78:#define b06 unused -: 79:#define b07 unused -: 80:#define b16 unused -: 81:#define b17 unused -: 82:#endif -: 83:#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \ -: 84: s(y,2) = s(x,2); s(y,3) = s(x,3); \ -: 85: s(y,4) = s(x,4); s(y,5) = s(x,5); -: 86:#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \ -: 87: si(y,x,k,3); si(y,x,k,4); si(y,x,k,5) -: 88:#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); \ -: 89: so(y,x,3); so(y,x,4); so(y,x,5) -: 90:#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \ -: 91: rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5) -: 92:#else -: 93: -: 94:#if defined(ARRAYS) -: 95:#define locals(y,x) x[8],y[8] -: 96:#else -: 97:#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \ -: 98: y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7 -: 99:#endif -: 100:#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \ -: 101: s(y,2) = s(x,2); s(y,3) = s(x,3); \ -: 102: s(y,4) = s(x,4); s(y,5) = s(x,5); \ -: 103: s(y,6) = s(x,6); s(y,7) = s(x,7); -: 104: -: 105:#if BLOCK_SIZE == 32 -: 106: -: 107:#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3); \ -: 108: si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7) -: 109:#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \ -: 110: so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7) -: 111:#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3); \ -: 112: rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7) -: 113:#else -: 114: -: 115:#define state_in(y,x,k) \ -: 116:switch(nc) \ -: 117:{ case 8: si(y,x,k,7); si(y,x,k,6); \ -: 118: case 6: si(y,x,k,5); si(y,x,k,4); \ -: 119: case 4: si(y,x,k,3); si(y,x,k,2); \ -: 120: si(y,x,k,1); si(y,x,k,0); \ -: 121:} -: 122: -: 123:#define state_out(y,x) \ -: 124:switch(nc) \ -: 125:{ case 8: so(y,x,7); so(y,x,6); \ -: 126: case 6: so(y,x,5); so(y,x,4); \ -: 127: case 4: so(y,x,3); so(y,x,2); \ -: 128: so(y,x,1); so(y,x,0); \ -: 129:} -: 130: -: 131:#if defined(FAST_VARIABLE) -: 132: -: 133:#define round(rm,y,x,k) \ -: 134:switch(nc) \ -: 135:{ case 8: rm(y,x,k,7); rm(y,x,k,6); \ -: 136: rm(y,x,k,5); rm(y,x,k,4); \ -: 137: rm(y,x,k,3); rm(y,x,k,2); \ -: 138: rm(y,x,k,1); rm(y,x,k,0); \ -: 139: break; \ -: 140: case 6: rm(y,x,k,5); rm(y,x,k,4); \ -: 141: rm(y,x,k,3); rm(y,x,k,2); \ -: 142: rm(y,x,k,1); rm(y,x,k,0); \ -: 143: break; \ -: 144: case 4: rm(y,x,k,3); rm(y,x,k,2); \ -: 145: rm(y,x,k,1); rm(y,x,k,0); \ -: 146: break; \ -: 147:} -: 148:#else -: 149: -: 150:#define round(rm,y,x,k) \ -: 151:switch(nc) \ -: 152:{ case 8: rm(y,x,k,7); rm(y,x,k,6); \ -: 153: case 6: rm(y,x,k,5); rm(y,x,k,4); \ -: 154: case 4: rm(y,x,k,3); rm(y,x,k,2); \ -: 155: rm(y,x,k,1); rm(y,x,k,0); \ -: 156:} -: 157: -: 158:#endif -: 159: -: 160:#endif -: 161:#endif -: 162: -: 163:#if defined(ENCRYPTION) -: 164: -: 165:/* I am grateful to Frank Yellin for the following construction -: 166: (and that for decryption) which, given the column (c) of the -: 167: output state variable, gives the input state variables which -: 168: are needed in its computation for each row (r) of the state. -: 169: -: 170: For the fixed block size options, compilers should be able to -: 171: reduce this complex expression (and the equivalent one for -: 172: decryption) to a static variable reference at compile time. -: 173: But for variable block size code, there will be some limbs on -: 174: which conditional clauses will be returned. -: 175:*/ -: 176: -: 177:/* y = output word, x = input word, r = row, c = column for r = 0, -: 178: 1, 2 and 3 = column accessed for row r. -: 179:*/ -: 180: -: 181:#define fwd_var(x,r,c) \ -: 182: ( r==0 ? \ -: 183: ( c==0 ? s(x,0) \ -: 184: : c==1 ? s(x,1) \ -: 185: : c==2 ? s(x,2) \ -: 186: : c==3 ? s(x,3) \ -: 187: : c==4 ? s(x,4) \ -: 188: : c==5 ? s(x,5) \ -: 189: : c==6 ? s(x,6) \ -: 190: : s(x,7)) \ -: 191: : r==1 ? \ -: 192: ( c==0 ? s(x,1) \ -: 193: : c==1 ? s(x,2) \ -: 194: : c==2 ? s(x,3) \ -: 195: : c==3 ? nc==4 ? s(x,0) : s(x,4) \ -: 196: : c==4 ? s(x,5) \ -: 197: : c==5 ? nc==8 ? s(x,6) : s(x,0) \ -: 198: : c==6 ? s(x,7) \ -: 199: : s(x,0)) \ -: 200: : r==2 ? \ -: 201: ( c==0 ? nc==8 ? s(x,3) : s(x,2) \ -: 202: : c==1 ? nc==8 ? s(x,4) : s(x,3) \ -: 203: : c==2 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \ -: 204: : c==3 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \ -: 205: : c==4 ? nc==8 ? s(x,7) : s(x,0) \ -: 206: : c==5 ? nc==8 ? s(x,0) : s(x,1) \ -: 207: : c==6 ? s(x,1) \ -: 208: : s(x,2)) \ -: 209: : \ -: 210: ( c==0 ? nc==8 ? s(x,4) : s(x,3) \ -: 211: : c==1 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \ -: 212: : c==2 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \ -: 213: : c==3 ? nc==4 ? s(x,2) : nc==8 ? s(x,7) : s(x,0) \ -: 214: : c==4 ? nc==8 ? s(x,0) : s(x,1) \ -: 215: : c==5 ? nc==8 ? s(x,1) : s(x,2) \ -: 216: : c==6 ? s(x,2) \ -: 217: : s(x,3))) -: 218: -: 219:#if defined(FT4_SET) -: 220:#undef dec_fmvars -: 221:#define dec_fmvars -: 222:#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c) -: 223:#elif defined(FT1_SET) -: 224:#undef dec_fmvars -: 225:#define dec_fmvars -: 226:#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,ft_tab,fwd_var,rf1,c) -: 227:#else -: 228:#define fwd_rnd(y,x,k,c) s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) ^ (k)[c] -: 229:#endif -: 230: -: 231:#if defined(FL4_SET) -: 232:#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c) -: 233:#elif defined(FL1_SET) -: 234:#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,fl_tab,fwd_var,rf1,c) -: 235:#else -: 236:#define fwd_lrnd(y,x,k,c) s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c] -: 237:#endif -: 238: 864736: 239:aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]) -: 240:{ uint32_t locals(b0, b1); 864736: 241: const uint32_t *kp = cx->k_sch; -: 242: dec_fmvars /* declare variables for fwd_mcol() if needed */ -: 243: 864736: 244: if(!(cx->n_blk & 1)) return aes_bad; -: 245: 864736: 246: state_in(b0, in_blk, kp); -: 247: -: 248:#if (ENC_UNROLL == FULL) -: 249: 864736: 250: kp += (cx->n_rnd - 9) * nc; -: 251: 864736: 252: switch(cx->n_rnd) -: 253: { 859840: 254: case 14: round(fwd_rnd, b1, b0, kp - 4 * nc); 859840: 255: round(fwd_rnd, b0, b1, kp - 3 * nc); 859840: 256: case 12: round(fwd_rnd, b1, b0, kp - 2 * nc); 859840: 257: round(fwd_rnd, b0, b1, kp - nc); 864736: 258: case 10: round(fwd_rnd, b1, b0, kp ); 864736: 259: round(fwd_rnd, b0, b1, kp + nc); 864736: 260: round(fwd_rnd, b1, b0, kp + 2 * nc); 864736: 261: round(fwd_rnd, b0, b1, kp + 3 * nc); 864736: 262: round(fwd_rnd, b1, b0, kp + 4 * nc); 864736: 263: round(fwd_rnd, b0, b1, kp + 5 * nc); 864736: 264: round(fwd_rnd, b1, b0, kp + 6 * nc); 864736: 265: round(fwd_rnd, b0, b1, kp + 7 * nc); 864736: 266: round(fwd_rnd, b1, b0, kp + 8 * nc); 864736: 267: round(fwd_lrnd, b0, b1, kp + 9 * nc); -: 268: } -: 269:#else -: 270: -: 271:#if (ENC_UNROLL == PARTIAL) -: 272: { uint32_t rnd; -: 273: for(rnd = 0; rnd < (cx->n_rnd >> 1) - 1; ++rnd) -: 274: { -: 275: kp += nc; -: 276: round(fwd_rnd, b1, b0, kp); -: 277: kp += nc; -: 278: round(fwd_rnd, b0, b1, kp); -: 279: } -: 280: kp += nc; -: 281: round(fwd_rnd, b1, b0, kp); -: 282:#else -: 283: { uint32_t rnd, *p0 = b0, *p1 = b1, *pt; -: 284: for(rnd = 0; rnd < cx->n_rnd - 1; ++rnd) -: 285: { -: 286: kp += nc; -: 287: round(fwd_rnd, p1, p0, kp); -: 288: pt = p0, p0 = p1, p1 = pt; -: 289: } -: 290:#endif -: 291: kp += nc; -: 292: round(fwd_lrnd, b0, b1, kp); -: 293: } -: 294:#endif -: 295: 864736: 296: state_out(out_blk, b0); 864736: 297: return aes_good; -: 298:} -: 299: -: 300:#endif -: 301: -: 302:#if defined(DECRYPTION) -: 303: -: 304:#define inv_var(x,r,c) \ -: 305: ( r==0 ? \ -: 306: ( c==0 ? s(x,0) \ -: 307: : c==1 ? s(x,1) \ -: 308: : c==2 ? s(x,2) \ -: 309: : c==3 ? s(x,3) \ -: 310: : c==4 ? s(x,4) \ -: 311: : c==5 ? s(x,5) \ -: 312: : c==6 ? s(x,6) \ -: 313: : s(x,7)) \ -: 314: : r==1 ? \ -: 315: ( c==0 ? nc==4 ? s(x,3) : nc==8 ? s(x,7) : s(x,5) \ -: 316: : c==1 ? s(x,0) \ -: 317: : c==2 ? s(x,1) \ -: 318: : c==3 ? s(x,2) \ -: 319: : c==4 ? s(x,3) \ -: 320: : c==5 ? s(x,4) \ -: 321: : c==6 ? s(x,5) \ -: 322: : s(x,6)) \ -: 323: : r==2 ? \ -: 324: ( c==0 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \ -: 325: : c==1 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \ -: 326: : c==2 ? nc==8 ? s(x,7) : s(x,0) \ -: 327: : c==3 ? nc==8 ? s(x,0) : s(x,1) \ -: 328: : c==4 ? nc==8 ? s(x,1) : s(x,2) \ -: 329: : c==5 ? nc==8 ? s(x,2) : s(x,3) \ -: 330: : c==6 ? s(x,3) \ -: 331: : s(x,4)) \ -: 332: : \ -: 333: ( c==0 ? nc==4 ? s(x,1) : nc==8 ? s(x,4) : s(x,3) \ -: 334: : c==1 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \ -: 335: : c==2 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \ -: 336: : c==3 ? nc==8 ? s(x,7) : s(x,0) \ -: 337: : c==4 ? nc==8 ? s(x,0) : s(x,1) \ -: 338: : c==5 ? nc==8 ? s(x,1) : s(x,2) \ -: 339: : c==6 ? s(x,2) \ -: 340: : s(x,3))) -: 341: -: 342:#if defined(IT4_SET) -: 343:#undef dec_imvars -: 344:#define dec_imvars -: 345:#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,it_tab,inv_var,rf1,c) -: 346:#elif defined(IT1_SET) -: 347:#undef dec_imvars -: 348:#define dec_imvars -: 349:#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,it_tab,inv_var,rf1,c) -: 350:#else -: 351:#define inv_rnd(y,x,k,c) s(y,c) = inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c]) -: 352:#endif -: 353: -: 354:#if defined(IL4_SET) -: 355:#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,il_tab,inv_var,rf1,c) -: 356:#elif defined(IL1_SET) -: 357:#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,il_tab,inv_var,rf1,c) -: 358:#else -: 359:#define inv_lrnd(y,x,k,c) s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c] -: 360:#endif -: 361: 14696: 362:aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]) -: 363:{ uint32_t locals(b0, b1); 14696: 364: const uint32_t *kp = cx->k_sch + nc * cx->n_rnd; -: 365: dec_imvars /* declare variables for inv_mcol() if needed */ -: 366: 14696: 367: if(!(cx->n_blk & 2)) return aes_bad; -: 368: 14696: 369: state_in(b0, in_blk, kp); -: 370: -: 371:#if (DEC_UNROLL == FULL) -: 372: 14696: 373: kp = cx->k_sch + 9 * nc; 14696: 374: switch(cx->n_rnd) -: 375: { 12680: 376: case 14: round(inv_rnd, b1, b0, kp + 4 * nc); 12680: 377: round(inv_rnd, b0, b1, kp + 3 * nc); 12680: 378: case 12: round(inv_rnd, b1, b0, kp + 2 * nc); 12680: 379: round(inv_rnd, b0, b1, kp + nc ); 14696: 380: case 10: round(inv_rnd, b1, b0, kp ); 14696: 381: round(inv_rnd, b0, b1, kp - nc); 14696: 382: round(inv_rnd, b1, b0, kp - 2 * nc); 14696: 383: round(inv_rnd, b0, b1, kp - 3 * nc); 14696: 384: round(inv_rnd, b1, b0, kp - 4 * nc); 14696: 385: round(inv_rnd, b0, b1, kp - 5 * nc); 14696: 386: round(inv_rnd, b1, b0, kp - 6 * nc); 14696: 387: round(inv_rnd, b0, b1, kp - 7 * nc); 14696: 388: round(inv_rnd, b1, b0, kp - 8 * nc); 14696: 389: round(inv_lrnd, b0, b1, kp - 9 * nc); -: 390: } -: 391:#else -: 392: -: 393:#if (DEC_UNROLL == PARTIAL) -: 394: { uint32_t rnd; -: 395: for(rnd = 0; rnd < (cx->n_rnd >> 1) - 1; ++rnd) -: 396: { -: 397: kp -= nc; -: 398: round(inv_rnd, b1, b0, kp); -: 399: kp -= nc; -: 400: round(inv_rnd, b0, b1, kp); -: 401: } -: 402: kp -= nc; -: 403: round(inv_rnd, b1, b0, kp); -: 404:#else -: 405: { uint32_t rnd, *p0 = b0, *p1 = b1, *pt; -: 406: for(rnd = 0; rnd < cx->n_rnd - 1; ++rnd) -: 407: { -: 408: kp -= nc; -: 409: round(inv_rnd, p1, p0, kp); -: 410: pt = p0, p0 = p1, p1 = pt; -: 411: } -: 412:#endif -: 413: kp -= nc; -: 414: round(inv_lrnd, b0, b1, kp); -: 415: } -: 416:#endif -: 417: 14696: 418: state_out(out_blk, b0); 14696: 419: return aes_good; -: 420:} -: 421: -: 422:#endif