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