]>
git.saurik.com Git - apple/xnu.git/blob - bsd/crypto/aes/aescrypt.c
141cd3fbfb09eb9ece2f0e58cb83dac297fcc40e
2 ---------------------------------------------------------------------------
3 Copyright (c) 2003, Dr 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 ---------------------------------------------------------------------------
32 This file contains the code for implementing encryption and decryption
33 for AES (Rijndael) for block and key sizes of 16, 24 and 32 bytes. It
34 can optionally be replaced by code written in assembler using NASM. For
35 further details see the file aesopt.h
41 #if defined(__cplusplus)
46 #define ki(y,x,k,c) (s(y,c) = s(x, c) ^ (k)[c])
47 #define xo(y,x,c) (s(y,c) ^= s(x, c))
48 #define si(y,x,c) (s(y,c) = word_in(x, c))
49 #define so(y,x,c) word_out(y, c, s(x,c))
52 #define locals(y,x) x[4],y[4]
54 #define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
57 #define dtables(tab) const aes_32t *tab##0, *tab##1, *tab##2, *tab##3
58 #define itables(tab) tab##0 = tab[0]; tab##1 = tab[1]; tab##2 = tab[2]; tab##3 = tab[3]
60 #define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
61 s(y,2) = s(x,2); s(y,3) = s(x,3);
63 #define key_in(y,x,k) ki(y,x,k,0); ki(y,x,k,1); ki(y,x,k,2); ki(y,x,k,3)
64 #define cbc(y,x) xo(y,x,0); xo(y,x,1); xo(y,x,2); xo(y,x,3)
65 #define state_in(y,x) si(y,x,0); si(y,x,1); si(y,x,2); si(y,x,3)
66 #define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
67 #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)
69 #if defined(ENCRYPTION) && !defined(AES_ASM)
71 /* Visual C++ .Net v7.1 provides the fastest encryption code when using
72 Pentium optimiation with small code but this is poor for decryption
73 so we need to control this with the following VC++ pragmas
77 #pragma optimize( "s", on )
80 /* Given the column (c) of the output state variable, the following
81 macros give the input state variables which are needed in its
82 computation for each row (r) of the state. All the alternative
83 macros give the same end values but expand into different ways
84 of calculating these values. In particular the complex macro
85 used for dynamically variable block sizes is designed to expand
86 to a compile time constant whenever possible but will expand to
87 conditional clauses on some branches (I am grateful to Frank
88 Yellin for this construction)
91 #define fwd_var(x,r,c)\
92 ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
93 : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
94 : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
95 : ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
99 # if defined(ENC_ROUND_CACHE_TABLES)
100 #define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_cached_tables(x,t_fn,fwd_var,rf1,c))
102 #define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_fn,fwd_var,rf1,c))
104 #elif defined(FT1_SET)
106 #define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_fn,fwd_var,rf1,c))
108 #define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ fwd_mcol(no_table(x,t_sbox,fwd_var,rf1,c)))
112 # if defined(LAST_ENC_ROUND_CACHE_TABLES)
113 #define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_cached_tables(x,t_fl,fwd_var,rf1,c))
115 #define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_fl,fwd_var,rf1,c))
117 #elif defined(FL1_SET)
118 #define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_fl,fwd_var,rf1,c))
120 #define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_sbox,fwd_var,rf1,c))
123 aes_rval
aes_encrypt_cbc(const unsigned char *in
, const unsigned char *in_iv
, unsigned int num_blk
,
124 unsigned char *out
, const aes_encrypt_ctx cx
[1])
125 { aes_32t
locals(b0
, b1
);
126 const aes_32t
*kp
= cx
->ks
;
127 #if defined(ENC_ROUND_CACHE_TABLES)
130 #if defined(LAST_ENC_ROUND_CACHE_TABLES)
134 #if defined( dec_fmvars )
135 dec_fmvars
; /* declare variables for fwd_mcol() if needed */
138 #if defined( AES_ERR_CHK )
139 if( cx
->rn
!= 10 && cx
->rn
!= 12 && cx
->rn
!= 14 )
146 for (;num_blk
; in
+= AES_BLOCK_SIZE
, out
+= AES_BLOCK_SIZE
, --num_blk
)
149 // Read the plaintext into b1
151 // Do the CBC with b0 which is either the iv or the ciphertext of the previous block.
154 // Xor b1 with the key schedule to get things started.
157 // Since xor is associative we mess with the ordering here to get the loads started early
158 key_in(b1
, b0
, kp
); // Xor b0(IV) with the key schedule and assign to b1
159 state_in(b0
, in
); // Load block into b0
160 cbc(b0
, b1
); // Xor b0 with b1 and store in b0
163 #if defined(ENC_ROUND_CACHE_TABLES)
167 #if (ENC_UNROLL == FULL)
172 round(fwd_rnd
, b1
, b0
, kp
+ 1 * N_COLS
);
173 round(fwd_rnd
, b0
, b1
, kp
+ 2 * N_COLS
);
176 round(fwd_rnd
, b1
, b0
, kp
+ 1 * N_COLS
);
177 round(fwd_rnd
, b0
, b1
, kp
+ 2 * N_COLS
);
181 round(fwd_rnd
, b1
, b0
, kp
+ 1 * N_COLS
);
182 round(fwd_rnd
, b0
, b1
, kp
+ 2 * N_COLS
);
183 round(fwd_rnd
, b1
, b0
, kp
+ 3 * N_COLS
);
184 round(fwd_rnd
, b0
, b1
, kp
+ 4 * N_COLS
);
185 round(fwd_rnd
, b1
, b0
, kp
+ 5 * N_COLS
);
186 round(fwd_rnd
, b0
, b1
, kp
+ 6 * N_COLS
);
187 round(fwd_rnd
, b1
, b0
, kp
+ 7 * N_COLS
);
188 round(fwd_rnd
, b0
, b1
, kp
+ 8 * N_COLS
);
189 round(fwd_rnd
, b1
, b0
, kp
+ 9 * N_COLS
);
190 #if defined(LAST_ENC_ROUND_CACHE_TABLES)
193 round(fwd_lrnd
, b0
, b1
, kp
+10 * N_COLS
);
199 #if (ENC_UNROLL == PARTIAL)
200 for(rnd
= 0; rnd
< (cx
->rn
>> 1) - 1; ++rnd
)
203 round(fwd_rnd
, b1
, b0
, kp
);
205 round(fwd_rnd
, b0
, b1
, kp
);
208 round(fwd_rnd
, b1
, b0
, kp
);
210 for(rnd
= 0; rnd
< cx
->rn
- 1; ++rnd
)
213 round(fwd_rnd
, b1
, b0
, kp
);
217 #if defined(LAST_ENC_ROUND_CACHE_TABLES)
221 round(fwd_lrnd
, b0
, b1
, kp
);
228 #if defined( AES_ERR_CHK )
235 #if defined(DECRYPTION) && !defined(AES_ASM)
237 /* Visual C++ .Net v7.1 provides the fastest encryption code when using
238 Pentium optimiation with small code but this is poor for decryption
239 so we need to control this with the following VC++ pragmas
242 #if defined(_MSC_VER)
243 #pragma optimize( "t", on )
246 /* Given the column (c) of the output state variable, the following
247 macros give the input state variables which are needed in its
248 computation for each row (r) of the state. All the alternative
249 macros give the same end values but expand into different ways
250 of calculating these values. In particular the complex macro
251 used for dynamically variable block sizes is designed to expand
252 to a compile time constant whenever possible but will expand to
253 conditional clauses on some branches (I am grateful to Frank
254 Yellin for this construction)
257 #define inv_var(x,r,c)\
258 ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
259 : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
260 : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
261 : ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))
265 # if defined(DEC_ROUND_CACHE_TABLES)
266 #define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_cached_tables(x,t_in,inv_var,rf1,c))
268 #define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_in,inv_var,rf1,c))
270 #elif defined(IT1_SET)
272 #define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_in,inv_var,rf1,c))
274 #define inv_rnd(y,x,k,c) (s(y,c) = inv_mcol((k)[c] ^ no_table(x,t_ibox,inv_var,rf1,c)))
278 # if defined(LAST_DEC_ROUND_CACHE_TABLES)
279 #define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_cached_tables(x,t_il,inv_var,rf1,c))
281 #define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_il,inv_var,rf1,c))
283 #elif defined(IL1_SET)
284 #define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_il,inv_var,rf1,c))
286 #define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_ibox,inv_var,rf1,c))
289 aes_rval
aes_decrypt_cbc(const unsigned char *in
, const unsigned char *in_iv
, unsigned int num_blk
,
290 unsigned char *out
, const aes_decrypt_ctx cx
[1])
291 { aes_32t
locals(b0
, b1
);
292 const aes_32t
*kp
= cx
->ks
+ cx
->rn
* N_COLS
;
293 #if defined(DEC_ROUND_CACHE_TABLES)
296 #if defined(LAST_DEC_ROUND_CACHE_TABLES)
300 #if defined( dec_imvars )
301 dec_imvars
; /* declare variables for inv_mcol() if needed */
304 #if defined( AES_ERR_CHK )
305 if( cx
->rn
!= 10 && cx
->rn
!= 12 && cx
->rn
!= 14 )
309 #if defined(DEC_ROUND_CACHE_TABLES)
313 in
+= AES_BLOCK_SIZE
* (num_blk
- 1);
314 out
+= AES_BLOCK_SIZE
* (num_blk
- 1);
315 // Load the last block's ciphertext into b1
318 for (;num_blk
; out
-= AES_BLOCK_SIZE
, --num_blk
)
320 // Do the xor part of state_in, where b1 is the previous block's ciphertext.
323 #if (DEC_UNROLL == FULL)
328 round(inv_rnd
, b1
, b0
, kp
- 1 * N_COLS
);
329 round(inv_rnd
, b0
, b1
, kp
- 2 * N_COLS
);
332 round(inv_rnd
, b1
, b0
, kp
- 1 * N_COLS
);
333 round(inv_rnd
, b0
, b1
, kp
- 2 * N_COLS
);
337 round(inv_rnd
, b1
, b0
, kp
- 1 * N_COLS
);
338 round(inv_rnd
, b0
, b1
, kp
- 2 * N_COLS
);
339 round(inv_rnd
, b1
, b0
, kp
- 3 * N_COLS
);
340 round(inv_rnd
, b0
, b1
, kp
- 4 * N_COLS
);
341 round(inv_rnd
, b1
, b0
, kp
- 5 * N_COLS
);
342 round(inv_rnd
, b0
, b1
, kp
- 6 * N_COLS
);
343 round(inv_rnd
, b1
, b0
, kp
- 7 * N_COLS
);
344 round(inv_rnd
, b0
, b1
, kp
- 8 * N_COLS
);
345 round(inv_rnd
, b1
, b0
, kp
- 9 * N_COLS
);
346 #if defined(LAST_DEC_ROUND_CACHE_TABLES)
349 round(inv_lrnd
, b0
, b1
, kp
- 10 * N_COLS
);
355 #if (DEC_UNROLL == PARTIAL)
356 for(rnd
= 0; rnd
< (cx
->rn
>> 1) - 1; ++rnd
)
359 round(inv_rnd
, b1
, b0
, kp
);
361 round(inv_rnd
, b0
, b1
, kp
);
364 round(inv_rnd
, b1
, b0
, kp
);
366 for(rnd
= 0; rnd
< cx
->rn
- 1; ++rnd
)
369 round(inv_rnd
, b1
, b0
, kp
);
373 #if defined(LAST_DEC_ROUND_CACHE_TABLES)
377 round(inv_lrnd
, b0
, b1
, kp
);
383 // We are doing the first block so we need the IV rather than the previous
384 // block for CBC (there is no previous block)
389 in
-= AES_BLOCK_SIZE
;
393 // Do the CBC with b1 which is either the IV or the ciphertext of the previous block.
398 #if defined( AES_ERR_CHK )
405 #if defined(__cplusplus)