|
|
1.1 root 1: /*
2: ---------------------------------------------------------------------------
1.1.1.6 ! root 3: Copyright (c) 1998-2007, Brian Gladman, Worcester, UK. All rights reserved.
1.1 root 4:
5: LICENSE TERMS
6:
1.1.1.6 ! root 7: The free distribution and use of this software is allowed (with or without
! 8: changes) provided that:
1.1 root 9:
1.1.1.6 ! root 10: 1. source code distributions include the above copyright notice, this
! 11: list of conditions and the following disclaimer;
1.1 root 12:
1.1.1.6 ! root 13: 2. binary distributions include the above copyright notice, this list
! 14: of conditions and the following disclaimer in their documentation;
! 15:
! 16: 3. the name of the copyright holder is not used to endorse products
! 17: built using this software without specific written permission.
1.1 root 18:
19: DISCLAIMER
20:
21: This software is provided 'as is' with no explicit or implied warranties
22: in respect of its properties, including, but not limited to, correctness
23: and/or fitness for purpose.
24: ---------------------------------------------------------------------------
1.1.1.6 ! root 25: Issue Date: 20/12/2007
1.1 root 26: */
27:
1.1.1.3 root 28: #include "Aesopt.h"
29: #include "Aestab.h"
1.1 root 30:
31: #if defined(__cplusplus)
32: extern "C"
33: {
34: #endif
35:
36: #define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])
37: #define so(y,x,c) word_out(y, c, s(x,c))
38:
39: #if defined(ARRAYS)
40: #define locals(y,x) x[4],y[4]
41: #else
42: #define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
43: #endif
44:
45: #define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
46: s(y,2) = s(x,2); s(y,3) = s(x,3);
47: #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)
48: #define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
49: #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)
50:
1.1.1.5 root 51: #if ( FUNCS_IN_C & ENCRYPTION_IN_C )
1.1 root 52:
53: /* Visual C++ .Net v7.1 provides the fastest encryption code when using
54: Pentium optimiation with small code but this is poor for decryption
55: so we need to control this with the following VC++ pragmas
56: */
57:
1.1.1.5 root 58: #if defined( _MSC_VER ) && !defined( _WIN64 )
1.1.1.4 root 59: #pragma optimize( "s", on )
1.1 root 60: #endif
61:
62: /* Given the column (c) of the output state variable, the following
63: macros give the input state variables which are needed in its
64: computation for each row (r) of the state. All the alternative
65: macros give the same end values but expand into different ways
66: of calculating these values. In particular the complex macro
67: used for dynamically variable block sizes is designed to expand
68: to a compile time constant whenever possible but will expand to
69: conditional clauses on some branches (I am grateful to Frank
70: Yellin for this construction)
71: */
72:
73: #define fwd_var(x,r,c)\
74: ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
75: : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
76: : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
77: : ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
78:
79: #if defined(FT4_SET)
80: #undef dec_fmvars
81: #define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
82: #elif defined(FT1_SET)
83: #undef dec_fmvars
84: #define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(f,n),fwd_var,rf1,c))
85: #else
86: #define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ fwd_mcol(no_table(x,t_use(s,box),fwd_var,rf1,c)))
87: #endif
88:
89: #if defined(FL4_SET)
90: #define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))
91: #elif defined(FL1_SET)
92: #define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(f,l),fwd_var,rf1,c))
93: #else
94: #define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(s,box),fwd_var,rf1,c))
95: #endif
96:
1.1.1.5 root 97: AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])
1.1.1.4 root 98: { uint_32t locals(b0, b1);
99: const uint_32t *kp;
1.1 root 100: #if defined( dec_fmvars )
101: dec_fmvars; /* declare variables for fwd_mcol() if needed */
102: #endif
103:
104: #if defined( AES_ERR_CHK )
1.1.1.4 root 105: if( cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16 )
106: return EXIT_FAILURE;
1.1 root 107: #endif
108:
1.1.1.4 root 109: kp = cx->ks;
1.1 root 110: state_in(b0, in, kp);
111:
112: #if (ENC_UNROLL == FULL)
113:
1.1.1.4 root 114: switch(cx->inf.b[0])
1.1 root 115: {
1.1.1.4 root 116: case 14 * 16:
1.1 root 117: round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
118: round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
119: kp += 2 * N_COLS;
1.1.1.4 root 120: case 12 * 16:
1.1 root 121: round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
122: round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
123: kp += 2 * N_COLS;
1.1.1.4 root 124: case 10 * 16:
1.1 root 125: round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
126: round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
127: round(fwd_rnd, b1, b0, kp + 3 * N_COLS);
128: round(fwd_rnd, b0, b1, kp + 4 * N_COLS);
129: round(fwd_rnd, b1, b0, kp + 5 * N_COLS);
130: round(fwd_rnd, b0, b1, kp + 6 * N_COLS);
131: round(fwd_rnd, b1, b0, kp + 7 * N_COLS);
132: round(fwd_rnd, b0, b1, kp + 8 * N_COLS);
133: round(fwd_rnd, b1, b0, kp + 9 * N_COLS);
134: round(fwd_lrnd, b0, b1, kp +10 * N_COLS);
135: }
136:
137: #else
138:
139: #if (ENC_UNROLL == PARTIAL)
1.1.1.4 root 140: { uint_32t rnd;
141: for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd)
1.1 root 142: {
143: kp += N_COLS;
144: round(fwd_rnd, b1, b0, kp);
145: kp += N_COLS;
146: round(fwd_rnd, b0, b1, kp);
147: }
148: kp += N_COLS;
149: round(fwd_rnd, b1, b0, kp);
150: #else
1.1.1.4 root 151: { uint_32t rnd;
152: for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd)
1.1 root 153: {
154: kp += N_COLS;
155: round(fwd_rnd, b1, b0, kp);
156: l_copy(b0, b1);
157: }
158: #endif
159: kp += N_COLS;
160: round(fwd_lrnd, b0, b1, kp);
161: }
162: #endif
163:
164: state_out(out, b0);
1.1.1.4 root 165:
1.1 root 166: #if defined( AES_ERR_CHK )
1.1.1.4 root 167: return EXIT_SUCCESS;
1.1 root 168: #endif
169: }
170:
171: #endif
172:
1.1.1.4 root 173: #if ( FUNCS_IN_C & DECRYPTION_IN_C)
1.1 root 174:
175: /* Visual C++ .Net v7.1 provides the fastest encryption code when using
176: Pentium optimiation with small code but this is poor for decryption
177: so we need to control this with the following VC++ pragmas
178: */
179:
1.1.1.5 root 180: #if defined( _MSC_VER ) && !defined( _WIN64 )
1.1.1.4 root 181: #pragma optimize( "t", on )
1.1 root 182: #endif
183:
184: /* Given the column (c) of the output state variable, the following
185: macros give the input state variables which are needed in its
186: computation for each row (r) of the state. All the alternative
187: macros give the same end values but expand into different ways
188: of calculating these values. In particular the complex macro
189: used for dynamically variable block sizes is designed to expand
190: to a compile time constant whenever possible but will expand to
191: conditional clauses on some branches (I am grateful to Frank
192: Yellin for this construction)
193: */
194:
195: #define inv_var(x,r,c)\
196: ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
197: : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
198: : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
199: : ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))
200:
201: #if defined(IT4_SET)
202: #undef dec_imvars
203: #define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))
204: #elif defined(IT1_SET)
205: #undef dec_imvars
206: #define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(i,n),inv_var,rf1,c))
207: #else
208: #define inv_rnd(y,x,k,c) (s(y,c) = inv_mcol((k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c)))
209: #endif
210:
211: #if defined(IL4_SET)
212: #define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))
213: #elif defined(IL1_SET)
214: #define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(i,l),inv_var,rf1,c))
215: #else
216: #define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c))
217: #endif
218:
1.1.1.4 root 219: /* This code can work with the decryption key schedule in the */
220: /* order that is used for encrytpion (where the 1st decryption */
221: /* round key is at the high end ot the schedule) or with a key */
222: /* schedule that has been reversed to put the 1st decryption */
223: /* round key at the low end of the schedule in memory (when */
224: /* AES_REV_DKS is defined) */
225:
226: #ifdef AES_REV_DKS
227: #define key_ofs 0
228: #define rnd_key(n) (kp + n * N_COLS)
229: #else
230: #define key_ofs 1
231: #define rnd_key(n) (kp - n * N_COLS)
232: #endif
233:
1.1.1.5 root 234: AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
1.1.1.4 root 235: { uint_32t locals(b0, b1);
1.1 root 236: #if defined( dec_imvars )
237: dec_imvars; /* declare variables for inv_mcol() if needed */
238: #endif
1.1.1.4 root 239: const uint_32t *kp;
1.1 root 240:
241: #if defined( AES_ERR_CHK )
1.1.1.4 root 242: if( cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16 )
243: return EXIT_FAILURE;
1.1 root 244: #endif
245:
1.1.1.4 root 246: kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);
1.1 root 247: state_in(b0, in, kp);
248:
249: #if (DEC_UNROLL == FULL)
250:
1.1.1.4 root 251: kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));
252: switch(cx->inf.b[0])
1.1 root 253: {
1.1.1.4 root 254: case 14 * 16:
255: round(inv_rnd, b1, b0, rnd_key(-13));
256: round(inv_rnd, b0, b1, rnd_key(-12));
257: case 12 * 16:
258: round(inv_rnd, b1, b0, rnd_key(-11));
259: round(inv_rnd, b0, b1, rnd_key(-10));
260: case 10 * 16:
261: round(inv_rnd, b1, b0, rnd_key(-9));
262: round(inv_rnd, b0, b1, rnd_key(-8));
263: round(inv_rnd, b1, b0, rnd_key(-7));
264: round(inv_rnd, b0, b1, rnd_key(-6));
265: round(inv_rnd, b1, b0, rnd_key(-5));
266: round(inv_rnd, b0, b1, rnd_key(-4));
267: round(inv_rnd, b1, b0, rnd_key(-3));
268: round(inv_rnd, b0, b1, rnd_key(-2));
269: round(inv_rnd, b1, b0, rnd_key(-1));
270: round(inv_lrnd, b0, b1, rnd_key( 0));
1.1 root 271: }
272:
273: #else
274:
275: #if (DEC_UNROLL == PARTIAL)
1.1.1.4 root 276: { uint_32t rnd;
277: for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd)
1.1 root 278: {
1.1.1.4 root 279: kp = rnd_key(1);
1.1 root 280: round(inv_rnd, b1, b0, kp);
1.1.1.4 root 281: kp = rnd_key(1);
1.1 root 282: round(inv_rnd, b0, b1, kp);
283: }
1.1.1.4 root 284: kp = rnd_key(1);
1.1 root 285: round(inv_rnd, b1, b0, kp);
286: #else
1.1.1.4 root 287: { uint_32t rnd;
288: for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd)
1.1 root 289: {
1.1.1.4 root 290: kp = rnd_key(1);
1.1 root 291: round(inv_rnd, b1, b0, kp);
292: l_copy(b0, b1);
293: }
294: #endif
1.1.1.4 root 295: kp = rnd_key(1);
1.1 root 296: round(inv_lrnd, b0, b1, kp);
1.1.1.4 root 297: }
1.1 root 298: #endif
299:
300: state_out(out, b0);
1.1.1.4 root 301:
1.1 root 302: #if defined( AES_ERR_CHK )
1.1.1.4 root 303: return EXIT_SUCCESS;
1.1 root 304: #endif
305: }
306:
307: #endif
308:
309: #if defined(__cplusplus)
310: }
311: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.