]>
git.ipfire.org Git - thirdparty/freeswitch.git/blob - libs/libzrtp/third_party/bgaes/aescrypt.c
2 ---------------------------------------------------------------------------
3 Copyright (c) 1998-2006, Brian Gladman, Worcester, UK. All rights reserved.
7 The free distribution and use of this software in both source and binary
8 form is allowed (with or without changes) provided that:
10 1. distributions of this source code include the above copyright
11 notice, this list of conditions and the following disclaimer;
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;
17 3. the copyright holder's name is not used to endorse products
18 built using this software without specific written permission.
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.
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 ---------------------------------------------------------------------------
36 #if defined(__cplusplus)
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))
45 #define locals(y,x) x[4],y[4]
47 #define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
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)
56 #if ( FUNCS_IN_C & ENCRYPTION_IN_C )
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
63 #if defined( _MSC_VER ) && !defined( _WIN64 )
64 #pragma optimize( "s", on )
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)
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)))
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)
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))
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)))
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))
99 #define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(s,box),fwd_var,rf1,c))
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
);
105 #if defined( dec_fmvars )
106 dec_fmvars
; /* declare variables for fwd_mcol() if needed */
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 )
115 state_in(b0
, in
, kp
);
117 #if (ENC_UNROLL == FULL)
122 round(fwd_rnd
, b1
, b0
, kp
+ 1 * N_COLS
);
123 round(fwd_rnd
, b0
, b1
, kp
+ 2 * N_COLS
);
126 round(fwd_rnd
, b1
, b0
, kp
+ 1 * N_COLS
);
127 round(fwd_rnd
, b0
, b1
, kp
+ 2 * N_COLS
);
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
);
144 #if (ENC_UNROLL == PARTIAL)
146 for(rnd
= 0; rnd
< (cx
->inf
.b
[0] >> 5) - 1; ++rnd
)
149 round(fwd_rnd
, b1
, b0
, kp
);
151 round(fwd_rnd
, b0
, b1
, kp
);
154 round(fwd_rnd
, b1
, b0
, kp
);
157 for(rnd
= 0; rnd
< (cx
->inf
.b
[0] >> 4) - 1; ++rnd
)
160 round(fwd_rnd
, b1
, b0
, kp
);
165 round(fwd_lrnd
, b0
, b1
, kp
);
171 #if defined( AES_ERR_CHK )
178 #if ( FUNCS_IN_C & DECRYPTION_IN_C)
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
185 #if defined( _MSC_VER ) && !defined( _WIN64 )
186 #pragma optimize( "t", on )
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)
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)))
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)
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))
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)))
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))
221 #define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c))
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) */
233 #define rnd_key(n) (kp + n * N_COLS)
236 #define rnd_key(n) (kp - n * N_COLS)
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 */
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 )
251 kp
= cx
->ks
+ (key_ofs
? (cx
->inf
.b
[0] >> 2) : 0);
252 state_in(b0
, in
, kp
);
254 #if (DEC_UNROLL == FULL)
256 kp
= cx
->ks
+ (key_ofs
? 0 : (cx
->inf
.b
[0] >> 2));
260 round(inv_rnd
, b1
, b0
, rnd_key(-13));
261 round(inv_rnd
, b0
, b1
, rnd_key(-12));
263 round(inv_rnd
, b1
, b0
, rnd_key(-11));
264 round(inv_rnd
, b0
, b1
, rnd_key(-10));
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));
280 #if (DEC_UNROLL == PARTIAL)
282 for(rnd
= 0; rnd
< (cx
->inf
.b
[0] >> 5) - 1; ++rnd
)
285 round(inv_rnd
, b1
, b0
, kp
);
287 round(inv_rnd
, b0
, b1
, kp
);
290 round(inv_rnd
, b1
, b0
, kp
);
293 for(rnd
= 0; rnd
< (cx
->inf
.b
[0] >> 4) - 1; ++rnd
)
296 round(inv_rnd
, b1
, b0
, kp
);
301 round(inv_lrnd
, b0
, b1
, kp
);
307 #if defined( AES_ERR_CHK )
314 #if defined(__cplusplus)