]>
Commit | Line | Data |
---|---|---|
381fcbc9 JB |
1 | /* |
2 | * AES (Rijndael) cipher - decrypt | |
3 | * | |
4 | * Modifications to public domain implementation: | |
381fcbc9 JB |
5 | * - cleanup |
6 | * - use C pre-processor to make it easier to change S table access | |
7 | * - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at | |
8 | * cost of reduced throughput (quite small difference on Pentium 4, | |
9 | * 10-25% when using -O1 or -O2 optimization) | |
10 | * | |
d140db6a | 11 | * Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi> |
381fcbc9 | 12 | * |
0f3d578e JM |
13 | * This software may be distributed under the terms of the BSD license. |
14 | * See README for more details. | |
381fcbc9 JB |
15 | */ |
16 | ||
17 | #include "includes.h" | |
18 | ||
19 | #include "common.h" | |
20 | #include "crypto.h" | |
21 | #include "aes_i.h" | |
22 | ||
23 | /** | |
24 | * Expand the cipher key into the decryption key schedule. | |
25 | * | |
26 | * @return the number of rounds for the given cipher key size. | |
27 | */ | |
d140db6a | 28 | static int rijndaelKeySetupDec(u32 rk[], const u8 cipherKey[], int keyBits) |
381fcbc9 | 29 | { |
d140db6a | 30 | int Nr, i, j; |
381fcbc9 JB |
31 | u32 temp; |
32 | ||
33 | /* expand the cipher key: */ | |
d140db6a JM |
34 | Nr = rijndaelKeySetupEnc(rk, cipherKey, keyBits); |
35 | if (Nr < 0) | |
36 | return Nr; | |
381fcbc9 JB |
37 | /* invert the order of the round keys: */ |
38 | for (i = 0, j = 4*Nr; i < j; i += 4, j -= 4) { | |
39 | temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; | |
40 | temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; | |
41 | temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; | |
42 | temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; | |
43 | } | |
44 | /* apply the inverse MixColumn transform to all round keys but the | |
45 | * first and the last: */ | |
46 | for (i = 1; i < Nr; i++) { | |
47 | rk += 4; | |
48 | for (j = 0; j < 4; j++) { | |
49 | rk[j] = TD0_(TE4((rk[j] >> 24) )) ^ | |
50 | TD1_(TE4((rk[j] >> 16) & 0xff)) ^ | |
51 | TD2_(TE4((rk[j] >> 8) & 0xff)) ^ | |
52 | TD3_(TE4((rk[j] ) & 0xff)); | |
53 | } | |
54 | } | |
d140db6a JM |
55 | |
56 | return Nr; | |
381fcbc9 JB |
57 | } |
58 | ||
59 | void * aes_decrypt_init(const u8 *key, size_t len) | |
60 | { | |
61 | u32 *rk; | |
d140db6a | 62 | int res; |
381fcbc9 JB |
63 | rk = os_malloc(AES_PRIV_SIZE); |
64 | if (rk == NULL) | |
65 | return NULL; | |
d140db6a JM |
66 | res = rijndaelKeySetupDec(rk, key, len * 8); |
67 | if (res < 0) { | |
68 | os_free(rk); | |
69 | return NULL; | |
70 | } | |
71 | rk[AES_PRIV_NR_POS] = res; | |
381fcbc9 JB |
72 | return rk; |
73 | } | |
74 | ||
d140db6a JM |
75 | static void rijndaelDecrypt(const u32 rk[/*44*/], int Nr, const u8 ct[16], |
76 | u8 pt[16]) | |
381fcbc9 JB |
77 | { |
78 | u32 s0, s1, s2, s3, t0, t1, t2, t3; | |
381fcbc9 JB |
79 | #ifndef FULL_UNROLL |
80 | int r; | |
81 | #endif /* ?FULL_UNROLL */ | |
82 | ||
83 | /* | |
84 | * map byte array block to cipher state | |
85 | * and add initial round key: | |
86 | */ | |
87 | s0 = GETU32(ct ) ^ rk[0]; | |
88 | s1 = GETU32(ct + 4) ^ rk[1]; | |
89 | s2 = GETU32(ct + 8) ^ rk[2]; | |
90 | s3 = GETU32(ct + 12) ^ rk[3]; | |
91 | ||
92 | #define ROUND(i,d,s) \ | |
93 | d##0 = TD0(s##0) ^ TD1(s##3) ^ TD2(s##2) ^ TD3(s##1) ^ rk[4 * i]; \ | |
94 | d##1 = TD0(s##1) ^ TD1(s##0) ^ TD2(s##3) ^ TD3(s##2) ^ rk[4 * i + 1]; \ | |
95 | d##2 = TD0(s##2) ^ TD1(s##1) ^ TD2(s##0) ^ TD3(s##3) ^ rk[4 * i + 2]; \ | |
96 | d##3 = TD0(s##3) ^ TD1(s##2) ^ TD2(s##1) ^ TD3(s##0) ^ rk[4 * i + 3] | |
97 | ||
98 | #ifdef FULL_UNROLL | |
99 | ||
100 | ROUND(1,t,s); | |
101 | ROUND(2,s,t); | |
102 | ROUND(3,t,s); | |
103 | ROUND(4,s,t); | |
104 | ROUND(5,t,s); | |
105 | ROUND(6,s,t); | |
106 | ROUND(7,t,s); | |
107 | ROUND(8,s,t); | |
108 | ROUND(9,t,s); | |
d140db6a JM |
109 | if (Nr > 10) { |
110 | ROUND(10,s,t); | |
111 | ROUND(11,t,s); | |
112 | if (Nr > 12) { | |
113 | ROUND(12,s,t); | |
114 | ROUND(13,t,s); | |
115 | } | |
116 | } | |
381fcbc9 JB |
117 | |
118 | rk += Nr << 2; | |
119 | ||
120 | #else /* !FULL_UNROLL */ | |
121 | ||
122 | /* Nr - 1 full rounds: */ | |
123 | r = Nr >> 1; | |
124 | for (;;) { | |
125 | ROUND(1,t,s); | |
126 | rk += 8; | |
127 | if (--r == 0) | |
128 | break; | |
129 | ROUND(0,s,t); | |
130 | } | |
131 | ||
132 | #endif /* ?FULL_UNROLL */ | |
133 | ||
134 | #undef ROUND | |
135 | ||
136 | /* | |
137 | * apply last round and | |
138 | * map cipher state to byte array block: | |
139 | */ | |
140 | s0 = TD41(t0) ^ TD42(t3) ^ TD43(t2) ^ TD44(t1) ^ rk[0]; | |
141 | PUTU32(pt , s0); | |
142 | s1 = TD41(t1) ^ TD42(t0) ^ TD43(t3) ^ TD44(t2) ^ rk[1]; | |
143 | PUTU32(pt + 4, s1); | |
144 | s2 = TD41(t2) ^ TD42(t1) ^ TD43(t0) ^ TD44(t3) ^ rk[2]; | |
145 | PUTU32(pt + 8, s2); | |
146 | s3 = TD41(t3) ^ TD42(t2) ^ TD43(t1) ^ TD44(t0) ^ rk[3]; | |
147 | PUTU32(pt + 12, s3); | |
148 | } | |
149 | ||
5f0e165e JM |
150 | |
151 | int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain) | |
381fcbc9 | 152 | { |
d140db6a JM |
153 | u32 *rk = ctx; |
154 | rijndaelDecrypt(ctx, rk[AES_PRIV_NR_POS], crypt, plain); | |
5f0e165e | 155 | return 0; |
381fcbc9 JB |
156 | } |
157 | ||
158 | ||
159 | void aes_decrypt_deinit(void *ctx) | |
160 | { | |
161 | os_memset(ctx, 0, AES_PRIV_SIZE); | |
162 | os_free(ctx); | |
163 | } |