]> git.ipfire.org Git - thirdparty/freeswitch.git/blob - libs/libzrtp/third_party/bgaes/aescrypt.c
[mod_http_cache] Fix leaking curl handle in http_get()
[thirdparty/freeswitch.git] / libs / libzrtp / third_party / bgaes / aescrypt.c
1 /*
2 ---------------------------------------------------------------------------
3 Copyright (c) 1998-2006, 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 ---------------------------------------------------------------------------
30 Issue 09/09/2006
31 */
32
33 #include "aesopt.h"
34 #include "aestab.h"
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
56 #if ( FUNCS_IN_C & ENCRYPTION_IN_C )
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 ) && !defined( _WIN64 )
64 #pragma optimize( "s", on )
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
102 AES_RETURN zrtp_bg_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;
105 #if defined( dec_fmvars )
106 dec_fmvars; /* declare variables for fwd_mcol() if needed */
107 #endif
108
109 #if defined( AES_ERR_CHK )
110 if( cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16 )
111 return EXIT_FAILURE;
112 #endif
113
114 kp = cx->ks;
115 state_in(b0, in, kp);
116
117 #if (ENC_UNROLL == FULL)
118
119 switch(cx->inf.b[0])
120 {
121 case 14 * 16:
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;
125 case 12 * 16:
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;
129 case 10 * 16:
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)
145 { uint_32t rnd;
146 for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd)
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
156 { uint_32t rnd;
157 for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd)
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);
170
171 #if defined( AES_ERR_CHK )
172 return EXIT_SUCCESS;
173 #endif
174 }
175
176 #endif
177
178 #if ( FUNCS_IN_C & DECRYPTION_IN_C)
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 ) && !defined( _WIN64 )
186 #pragma optimize( "t", on )
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
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_RETURN zrtp_bg_aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
240 { uint_32t locals(b0, b1);
241 #if defined( dec_imvars )
242 dec_imvars; /* declare variables for inv_mcol() if needed */
243 #endif
244 const uint_32t *kp;
245
246 #if defined( AES_ERR_CHK )
247 if( cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16 )
248 return EXIT_FAILURE;
249 #endif
250
251 kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);
252 state_in(b0, in, kp);
253
254 #if (DEC_UNROLL == FULL)
255
256 kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));
257 switch(cx->inf.b[0])
258 {
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));
276 }
277
278 #else
279
280 #if (DEC_UNROLL == PARTIAL)
281 { uint_32t rnd;
282 for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd)
283 {
284 kp = rnd_key(1);
285 round(inv_rnd, b1, b0, kp);
286 kp = rnd_key(1);
287 round(inv_rnd, b0, b1, kp);
288 }
289 kp = rnd_key(1);
290 round(inv_rnd, b1, b0, kp);
291 #else
292 { uint_32t rnd;
293 for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd)
294 {
295 kp = rnd_key(1);
296 round(inv_rnd, b1, b0, kp);
297 l_copy(b0, b1);
298 }
299 #endif
300 kp = rnd_key(1);
301 round(inv_lrnd, b0, b1, kp);
302 }
303 #endif
304
305 state_out(out, b0);
306
307 #if defined( AES_ERR_CHK )
308 return EXIT_SUCCESS;
309 #endif
310 }
311
312 #endif
313
314 #if defined(__cplusplus)
315 }
316 #endif