Add phnxdeco with debian patch set (version 0.33-3).
[delutions.git] / tc / crypto / Aescrypt.c
blob46175981a608bd3308e172addb74e5a9f96df247
1 /*
2 ---------------------------------------------------------------------------
3 Copyright (c) 1998-2007, Brian Gladman, Worcester, UK. All rights reserved.
5 LICENSE TERMS
7 The free distribution and use of this software is allowed (with or without
8 changes) provided that:
10 1. source code distributions include the above copyright notice, this
11 list of conditions and the following disclaimer;
13 2. binary distributions include the above copyright notice, this list
14 of conditions and the following disclaimer in their documentation;
16 3. the name of the copyright holder is not used to endorse products
17 built using this software without specific written permission.
19 DISCLAIMER
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 ---------------------------------------------------------------------------
25 Issue Date: 20/12/2007
28 #include "Aesopt.h"
29 #include "Aestab.h"
31 #if defined(__cplusplus)
32 extern "C"
34 #endif
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))
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
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)
51 #if ( FUNCS_IN_C & ENCRYPTION_IN_C )
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
58 #if defined( _MSC_VER ) && !defined( _WIN64 )
59 #pragma optimize( "s", on )
60 #endif
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)
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)))
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
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
97 AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])
98 { uint_32t locals(b0, b1);
99 const uint_32t *kp;
100 #if defined( dec_fmvars )
101 dec_fmvars; /* declare variables for fwd_mcol() if needed */
102 #endif
104 #if defined( AES_ERR_CHK )
105 if( cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16 )
106 return EXIT_FAILURE;
107 #endif
109 kp = cx->ks;
110 state_in(b0, in, kp);
112 #if (ENC_UNROLL == FULL)
114 switch(cx->inf.b[0])
116 case 14 * 16:
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;
120 case 12 * 16:
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;
124 case 10 * 16:
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);
137 #else
139 #if (ENC_UNROLL == PARTIAL)
140 { uint_32t rnd;
141 for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd)
143 kp += N_COLS;
144 round(fwd_rnd, b1, b0, kp);
145 kp += N_COLS;
146 round(fwd_rnd, b0, b1, kp);
148 kp += N_COLS;
149 round(fwd_rnd, b1, b0, kp);
150 #else
151 { uint_32t rnd;
152 for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd)
154 kp += N_COLS;
155 round(fwd_rnd, b1, b0, kp);
156 l_copy(b0, b1);
158 #endif
159 kp += N_COLS;
160 round(fwd_lrnd, b0, b1, kp);
162 #endif
164 state_out(out, b0);
166 #if defined( AES_ERR_CHK )
167 return EXIT_SUCCESS;
168 #endif
171 #endif
173 #if ( FUNCS_IN_C & DECRYPTION_IN_C)
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
180 #if defined( _MSC_VER ) && !defined( _WIN64 )
181 #pragma optimize( "t", on )
182 #endif
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)
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)))
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
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
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) */
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
234 AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
235 { uint_32t locals(b0, b1);
236 #if defined( dec_imvars )
237 dec_imvars; /* declare variables for inv_mcol() if needed */
238 #endif
239 const uint_32t *kp;
241 #if defined( AES_ERR_CHK )
242 if( cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16 )
243 return EXIT_FAILURE;
244 #endif
246 kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);
247 state_in(b0, in, kp);
249 #if (DEC_UNROLL == FULL)
251 kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));
252 switch(cx->inf.b[0])
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));
273 #else
275 #if (DEC_UNROLL == PARTIAL)
276 { uint_32t rnd;
277 for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd)
279 kp = rnd_key(1);
280 round(inv_rnd, b1, b0, kp);
281 kp = rnd_key(1);
282 round(inv_rnd, b0, b1, kp);
284 kp = rnd_key(1);
285 round(inv_rnd, b1, b0, kp);
286 #else
287 { uint_32t rnd;
288 for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd)
290 kp = rnd_key(1);
291 round(inv_rnd, b1, b0, kp);
292 l_copy(b0, b1);
294 #endif
295 kp = rnd_key(1);
296 round(inv_lrnd, b0, b1, kp);
298 #endif
300 state_out(out, b0);
302 #if defined( AES_ERR_CHK )
303 return EXIT_SUCCESS;
304 #endif
307 #endif
309 #if defined(__cplusplus)
311 #endif