diff options
author | Harvey Harrison <harvey.harrison@gmail.com> | 2008-05-02 16:47:45 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-05-14 16:29:32 -0400 |
commit | 8c046c8c64ba81dd87468ddaf2db4a5d926b988b (patch) | |
tree | 9690c768cb8942880c579b64ed3a73b131a09157 /net | |
parent | ae7245cbf27ee6b6423bc363cbe01c93e57befda (diff) |
mac80211: tkip.c use kernel-provided infrastructure
Use kernel-provided bit rotation and unaligned access infrastructure rather
than opencoding it.
Some minor spacing adjustments as well.
Signed-off-by: Harvey Harrison <harvey.harrison@gmail.com>
Cc: "John W. Linville" <linville@tuxdriver.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/tkip.c | 145 |
1 files changed, 46 insertions, 99 deletions
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c index 09093da24af6..a7c3febc5a45 100644 --- a/net/mac80211/tkip.c +++ b/net/mac80211/tkip.c | |||
@@ -8,23 +8,22 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
11 | #include <linux/bitops.h> | ||
11 | #include <linux/types.h> | 12 | #include <linux/types.h> |
12 | #include <linux/netdevice.h> | 13 | #include <linux/netdevice.h> |
14 | #include <asm/unaligned.h> | ||
13 | 15 | ||
14 | #include <net/mac80211.h> | 16 | #include <net/mac80211.h> |
15 | #include "key.h" | 17 | #include "key.h" |
16 | #include "tkip.h" | 18 | #include "tkip.h" |
17 | #include "wep.h" | 19 | #include "wep.h" |
18 | 20 | ||
19 | |||
20 | /* TKIP key mixing functions */ | ||
21 | |||
22 | |||
23 | #define PHASE1_LOOP_COUNT 8 | 21 | #define PHASE1_LOOP_COUNT 8 |
24 | 22 | ||
25 | 23 | /* | |
26 | /* 2-byte by 2-byte subset of the full AES S-box table; second part of this | 24 | * 2-byte by 2-byte subset of the full AES S-box table; second part of this |
27 | * table is identical to first part but byte-swapped */ | 25 | * table is identical to first part but byte-swapped |
26 | */ | ||
28 | static const u16 tkip_sbox[256] = | 27 | static const u16 tkip_sbox[256] = |
29 | { | 28 | { |
30 | 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, | 29 | 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, |
@@ -61,53 +60,13 @@ static const u16 tkip_sbox[256] = | |||
61 | 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, | 60 | 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, |
62 | }; | 61 | }; |
63 | 62 | ||
64 | 63 | static u16 tkipS(u16 val) | |
65 | static inline u16 Mk16(u8 x, u8 y) | ||
66 | { | ||
67 | return ((u16) x << 8) | (u16) y; | ||
68 | } | ||
69 | |||
70 | |||
71 | static inline u8 Hi8(u16 v) | ||
72 | { | ||
73 | return v >> 8; | ||
74 | } | ||
75 | |||
76 | |||
77 | static inline u8 Lo8(u16 v) | ||
78 | { | ||
79 | return v & 0xff; | ||
80 | } | ||
81 | |||
82 | |||
83 | static inline u16 Hi16(u32 v) | ||
84 | { | ||
85 | return v >> 16; | ||
86 | } | ||
87 | |||
88 | |||
89 | static inline u16 Lo16(u32 v) | ||
90 | { | ||
91 | return v & 0xffff; | ||
92 | } | ||
93 | |||
94 | |||
95 | static inline u16 RotR1(u16 v) | ||
96 | { | 64 | { |
97 | return (v >> 1) | ((v & 0x0001) << 15); | 65 | return tkip_sbox[val & 0xff] ^ swab16(tkip_sbox[val >> 8]); |
98 | } | ||
99 | |||
100 | |||
101 | static inline u16 tkip_S(u16 val) | ||
102 | { | ||
103 | u16 a = tkip_sbox[Hi8(val)]; | ||
104 | |||
105 | return tkip_sbox[Lo8(val)] ^ Hi8(a) ^ (Lo8(a) << 8); | ||
106 | } | 66 | } |
107 | 67 | ||
108 | 68 | /* | |
109 | 69 | * P1K := Phase1(TA, TK, TSC) | |
110 | /* P1K := Phase1(TA, TK, TSC) | ||
111 | * TA = transmitter address (48 bits) | 70 | * TA = transmitter address (48 bits) |
112 | * TK = dot11DefaultKeyValue or dot11KeyMappingValue (128 bits) | 71 | * TK = dot11DefaultKeyValue or dot11KeyMappingValue (128 bits) |
113 | * TSC = TKIP sequence counter (48 bits, only 32 msb bits used) | 72 | * TSC = TKIP sequence counter (48 bits, only 32 msb bits used) |
@@ -118,23 +77,22 @@ static void tkip_mixing_phase1(const u8 *ta, const u8 *tk, u32 tsc_IV32, | |||
118 | { | 77 | { |
119 | int i, j; | 78 | int i, j; |
120 | 79 | ||
121 | p1k[0] = Lo16(tsc_IV32); | 80 | p1k[0] = tsc_IV32 & 0xFFFF; |
122 | p1k[1] = Hi16(tsc_IV32); | 81 | p1k[1] = tsc_IV32 >> 16; |
123 | p1k[2] = Mk16(ta[1], ta[0]); | 82 | p1k[2] = get_unaligned_le16(ta + 0); |
124 | p1k[3] = Mk16(ta[3], ta[2]); | 83 | p1k[3] = get_unaligned_le16(ta + 2); |
125 | p1k[4] = Mk16(ta[5], ta[4]); | 84 | p1k[4] = get_unaligned_le16(ta + 4); |
126 | 85 | ||
127 | for (i = 0; i < PHASE1_LOOP_COUNT; i++) { | 86 | for (i = 0; i < PHASE1_LOOP_COUNT; i++) { |
128 | j = 2 * (i & 1); | 87 | j = 2 * (i & 1); |
129 | p1k[0] += tkip_S(p1k[4] ^ Mk16(tk[ 1 + j], tk[ 0 + j])); | 88 | p1k[0] += tkipS(p1k[4] ^ get_unaligned_le16(tk + 0 + j)); |
130 | p1k[1] += tkip_S(p1k[0] ^ Mk16(tk[ 5 + j], tk[ 4 + j])); | 89 | p1k[1] += tkipS(p1k[0] ^ get_unaligned_le16(tk + 4 + j)); |
131 | p1k[2] += tkip_S(p1k[1] ^ Mk16(tk[ 9 + j], tk[ 8 + j])); | 90 | p1k[2] += tkipS(p1k[1] ^ get_unaligned_le16(tk + 8 + j)); |
132 | p1k[3] += tkip_S(p1k[2] ^ Mk16(tk[13 + j], tk[12 + j])); | 91 | p1k[3] += tkipS(p1k[2] ^ get_unaligned_le16(tk + 12 + j)); |
133 | p1k[4] += tkip_S(p1k[3] ^ Mk16(tk[ 1 + j], tk[ 0 + j])) + i; | 92 | p1k[4] += tkipS(p1k[3] ^ get_unaligned_le16(tk + 0 + j)) + i; |
134 | } | 93 | } |
135 | } | 94 | } |
136 | 95 | ||
137 | |||
138 | static void tkip_mixing_phase2(const u16 *p1k, const u8 *tk, u16 tsc_IV16, | 96 | static void tkip_mixing_phase2(const u16 *p1k, const u8 *tk, u16 tsc_IV16, |
139 | u8 *rc4key) | 97 | u8 *rc4key) |
140 | { | 98 | { |
@@ -148,31 +106,29 @@ static void tkip_mixing_phase2(const u16 *p1k, const u8 *tk, u16 tsc_IV16, | |||
148 | ppk[4] = p1k[4]; | 106 | ppk[4] = p1k[4]; |
149 | ppk[5] = p1k[4] + tsc_IV16; | 107 | ppk[5] = p1k[4] + tsc_IV16; |
150 | 108 | ||
151 | ppk[0] += tkip_S(ppk[5] ^ Mk16(tk[ 1], tk[ 0])); | 109 | ppk[0] += tkipS(ppk[5] ^ get_unaligned_le16(tk + 0)); |
152 | ppk[1] += tkip_S(ppk[0] ^ Mk16(tk[ 3], tk[ 2])); | 110 | ppk[1] += tkipS(ppk[0] ^ get_unaligned_le16(tk + 2)); |
153 | ppk[2] += tkip_S(ppk[1] ^ Mk16(tk[ 5], tk[ 4])); | 111 | ppk[2] += tkipS(ppk[1] ^ get_unaligned_le16(tk + 4)); |
154 | ppk[3] += tkip_S(ppk[2] ^ Mk16(tk[ 7], tk[ 6])); | 112 | ppk[3] += tkipS(ppk[2] ^ get_unaligned_le16(tk + 6)); |
155 | ppk[4] += tkip_S(ppk[3] ^ Mk16(tk[ 9], tk[ 8])); | 113 | ppk[4] += tkipS(ppk[3] ^ get_unaligned_le16(tk + 8)); |
156 | ppk[5] += tkip_S(ppk[4] ^ Mk16(tk[11], tk[10])); | 114 | ppk[5] += tkipS(ppk[4] ^ get_unaligned_le16(tk + 10)); |
157 | ppk[0] += RotR1(ppk[5] ^ Mk16(tk[13], tk[12])); | 115 | ppk[0] += ror16(ppk[5] ^ get_unaligned_le16(tk + 12), 1); |
158 | ppk[1] += RotR1(ppk[0] ^ Mk16(tk[15], tk[14])); | 116 | ppk[1] += ror16(ppk[0] ^ get_unaligned_le16(tk + 14), 1); |
159 | ppk[2] += RotR1(ppk[1]); | 117 | ppk[2] += ror16(ppk[1], 1); |
160 | ppk[3] += RotR1(ppk[2]); | 118 | ppk[3] += ror16(ppk[2], 1); |
161 | ppk[4] += RotR1(ppk[3]); | 119 | ppk[4] += ror16(ppk[3], 1); |
162 | ppk[5] += RotR1(ppk[4]); | 120 | ppk[5] += ror16(ppk[4], 1); |
163 | 121 | ||
164 | rc4key[0] = Hi8(tsc_IV16); | 122 | rc4key[0] = tsc_IV16 >> 8; |
165 | rc4key[1] = (Hi8(tsc_IV16) | 0x20) & 0x7f; | 123 | rc4key[1] = ((tsc_IV16 >> 8) | 0x20) & 0x7f; |
166 | rc4key[2] = Lo8(tsc_IV16); | 124 | rc4key[2] = tsc_IV16 & 0xFF; |
167 | rc4key[3] = Lo8((ppk[5] ^ Mk16(tk[1], tk[0])) >> 1); | 125 | rc4key[3] = ((ppk[5] ^ get_unaligned_le16(tk)) >> 1) & 0xFF; |
168 | 126 | ||
169 | for (i = 0; i < 6; i++) { | 127 | rc4key += 4; |
170 | rc4key[4 + 2 * i] = Lo8(ppk[i]); | 128 | for (i = 0; i < 6; i++) |
171 | rc4key[5 + 2 * i] = Hi8(ppk[i]); | 129 | put_unaligned_le16(ppk[i], rc4key + 2 * i); |
172 | } | ||
173 | } | 130 | } |
174 | 131 | ||
175 | |||
176 | /* Add TKIP IV and Ext. IV at @pos. @iv0, @iv1, and @iv2 are the first octets | 132 | /* Add TKIP IV and Ext. IV at @pos. @iv0, @iv1, and @iv2 are the first octets |
177 | * of the IV. Returns pointer to the octet following IVs (i.e., beginning of | 133 | * of the IV. Returns pointer to the octet following IVs (i.e., beginning of |
178 | * the packet payload). */ | 134 | * the packet payload). */ |
@@ -183,14 +139,10 @@ u8 * ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, | |||
183 | *pos++ = iv1; | 139 | *pos++ = iv1; |
184 | *pos++ = iv2; | 140 | *pos++ = iv2; |
185 | *pos++ = (key->conf.keyidx << 6) | (1 << 5) /* Ext IV */; | 141 | *pos++ = (key->conf.keyidx << 6) | (1 << 5) /* Ext IV */; |
186 | *pos++ = key->u.tkip.iv32 & 0xff; | 142 | put_unaligned_le32(key->u.tkip.iv32, pos); |
187 | *pos++ = (key->u.tkip.iv32 >> 8) & 0xff; | 143 | return pos + 4; |
188 | *pos++ = (key->u.tkip.iv32 >> 16) & 0xff; | ||
189 | *pos++ = (key->u.tkip.iv32 >> 24) & 0xff; | ||
190 | return pos; | ||
191 | } | 144 | } |
192 | 145 | ||
193 | |||
194 | void ieee80211_tkip_gen_phase1key(struct ieee80211_key *key, u8 *ta, | 146 | void ieee80211_tkip_gen_phase1key(struct ieee80211_key *key, u8 *ta, |
195 | u16 *phase1key) | 147 | u16 *phase1key) |
196 | { | 148 | { |
@@ -228,10 +180,8 @@ void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, | |||
228 | u16 iv16; | 180 | u16 iv16; |
229 | u32 iv32; | 181 | u32 iv32; |
230 | 182 | ||
231 | iv16 = data[hdr_len] << 8; | 183 | iv16 = data[hdr_len + 2] | (data[hdr_len] << 8); |
232 | iv16 += data[hdr_len + 2]; | 184 | iv32 = get_unaligned_le32(data + hdr_len + 4); |
233 | iv32 = data[hdr_len + 4] | (data[hdr_len + 5] << 8) | | ||
234 | (data[hdr_len + 6] << 16) | (data[hdr_len + 7] << 24); | ||
235 | 185 | ||
236 | #ifdef CONFIG_TKIP_DEBUG | 186 | #ifdef CONFIG_TKIP_DEBUG |
237 | printk(KERN_DEBUG "TKIP encrypt: iv16 = 0x%04x, iv32 = 0x%08x\n", | 187 | printk(KERN_DEBUG "TKIP encrypt: iv16 = 0x%04x, iv32 = 0x%08x\n", |
@@ -281,7 +231,6 @@ void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm, | |||
281 | ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len); | 231 | ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len); |
282 | } | 232 | } |
283 | 233 | ||
284 | |||
285 | /* Decrypt packet payload with TKIP using @key. @pos is a pointer to the | 234 | /* Decrypt packet payload with TKIP using @key. @pos is a pointer to the |
286 | * beginning of the buffer containing IEEE 802.11 header payload, i.e., | 235 | * beginning of the buffer containing IEEE 802.11 header payload, i.e., |
287 | * including IV, Ext. IV, real data, Michael MIC, ICV. @payload_len is the | 236 | * including IV, Ext. IV, real data, Michael MIC, ICV. @payload_len is the |
@@ -302,7 +251,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
302 | 251 | ||
303 | iv16 = (pos[0] << 8) | pos[2]; | 252 | iv16 = (pos[0] << 8) | pos[2]; |
304 | keyid = pos[3]; | 253 | keyid = pos[3]; |
305 | iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24); | 254 | iv32 = get_unaligned_le32(pos + 4); |
306 | pos += 8; | 255 | pos += 8; |
307 | #ifdef CONFIG_TKIP_DEBUG | 256 | #ifdef CONFIG_TKIP_DEBUG |
308 | { | 257 | { |
@@ -409,5 +358,3 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
409 | 358 | ||
410 | return res; | 359 | return res; |
411 | } | 360 | } |
412 | |||
413 | |||