2 * AES (Rijndael) cipher - decrypt
4 * Modifications to public domain implementation:
5 * - support only 128-bit keys
7 * - use C pre-processor to make it easier to change S table access
8 * - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at
9 * cost of reduced throughput (quite small difference on Pentium 4,
10 * 10-25% when using -O1 or -O2 optimization)
12 * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
18 * Alternatively, this software may be distributed under the terms of BSD
21 * See README and COPYING for more details.
31 * Expand the cipher key into the decryption key schedule.
33 * @return the number of rounds for the given cipher key size.
35 void rijndaelKeySetupDec(u32 rk
[/*44*/], const u8 cipherKey
[])
40 /* expand the cipher key: */
41 rijndaelKeySetupEnc(rk
, cipherKey
);
42 /* invert the order of the round keys: */
43 for (i
= 0, j
= 4*Nr
; i
< j
; i
+= 4, j
-= 4) {
44 temp
= rk
[i
]; rk
[i
] = rk
[j
]; rk
[j
] = temp
;
45 temp
= rk
[i
+ 1]; rk
[i
+ 1] = rk
[j
+ 1]; rk
[j
+ 1] = temp
;
46 temp
= rk
[i
+ 2]; rk
[i
+ 2] = rk
[j
+ 2]; rk
[j
+ 2] = temp
;
47 temp
= rk
[i
+ 3]; rk
[i
+ 3] = rk
[j
+ 3]; rk
[j
+ 3] = temp
;
49 /* apply the inverse MixColumn transform to all round keys but the
50 * first and the last: */
51 for (i
= 1; i
< Nr
; i
++) {
53 for (j
= 0; j
< 4; j
++) {
54 rk
[j
] = TD0_(TE4((rk
[j
] >> 24) )) ^
55 TD1_(TE4((rk
[j
] >> 16) & 0xff)) ^
56 TD2_(TE4((rk
[j
] >> 8) & 0xff)) ^
57 TD3_(TE4((rk
[j
] ) & 0xff));
62 void * aes_decrypt_init(const u8
*key
, size_t len
)
67 rk
= os_malloc(AES_PRIV_SIZE
);
70 rijndaelKeySetupDec(rk
, key
);
74 static void rijndaelDecrypt(const u32 rk
[/*44*/], const u8 ct
[16], u8 pt
[16])
76 u32 s0
, s1
, s2
, s3
, t0
, t1
, t2
, t3
;
80 #endif /* ?FULL_UNROLL */
83 * map byte array block to cipher state
84 * and add initial round key:
86 s0
= GETU32(ct
) ^ rk
[0];
87 s1
= GETU32(ct
+ 4) ^ rk
[1];
88 s2
= GETU32(ct
+ 8) ^ rk
[2];
89 s3
= GETU32(ct
+ 12) ^ rk
[3];
91 #define ROUND(i,d,s) \
92 d##0 = TD0(s##0) ^ TD1(s##3) ^ TD2(s##2) ^ TD3(s##1) ^ rk[4 * i]; \
93 d##1 = TD0(s##1) ^ TD1(s##0) ^ TD2(s##3) ^ TD3(s##2) ^ rk[4 * i + 1]; \
94 d##2 = TD0(s##2) ^ TD1(s##1) ^ TD2(s##0) ^ TD3(s##3) ^ rk[4 * i + 2]; \
95 d##3 = TD0(s##3) ^ TD1(s##2) ^ TD2(s##1) ^ TD3(s##0) ^ rk[4 * i + 3]
111 #else /* !FULL_UNROLL */
113 /* Nr - 1 full rounds: */
123 #endif /* ?FULL_UNROLL */
128 * apply last round and
129 * map cipher state to byte array block:
131 s0
= TD41(t0
) ^ TD42(t3
) ^ TD43(t2
) ^ TD44(t1
) ^ rk
[0];
133 s1
= TD41(t1
) ^ TD42(t0
) ^ TD43(t3
) ^ TD44(t2
) ^ rk
[1];
135 s2
= TD41(t2
) ^ TD42(t1
) ^ TD43(t0
) ^ TD44(t3
) ^ rk
[2];
137 s3
= TD41(t3
) ^ TD42(t2
) ^ TD43(t1
) ^ TD44(t0
) ^ rk
[3];
141 void aes_decrypt(void *ctx
, const u8
*crypt
, u8
*plain
)
143 rijndaelDecrypt(ctx
, crypt
, plain
);
147 void aes_decrypt_deinit(void *ctx
)
149 os_memset(ctx
, 0, AES_PRIV_SIZE
);